diff --git a/.github/workflows/x86_64-apple-darwin-compiler.yml b/.github/workflows/x86_64-apple-darwin-compiler.yml
deleted file mode 100644
index 4691534d6..000000000
--- a/.github/workflows/x86_64-apple-darwin-compiler.yml
+++ /dev/null
@@ -1,81 +0,0 @@
-name: x86_64-apple-darwin compiler
-
-on: push
-
-env:
-  EPOCH: 0
-  FIREFLY_BUILD_TYPE: static
-  LLVM_LINK_LLVM_DYLIB: ON
-  TOOLCHAIN: nightly-2022-07-12
-
-jobs:
-  compiler:
-    if: ${{ false }} # disabled
-    runs-on: macos-12
-
-    steps:
-      - uses: actions/checkout@v2
-      - name: Install Rust
-        uses: actions-rs/toolchain@v1
-        with:
-          toolchain: ${{ env.TOOLCHAIN }}
-          override: true
-      - name: Cache Cargo
-        uses: actions/cache@v2
-        with:
-          path: |
-            ~/.cargo/registry
-            ~/.cargo/git
-          key: ${{ github.workflow }}-${{ github.job }}-toolchain-${{ env.TOOLCHAIN }}-cargo-${{ hashFiles('**/Cargo.lock') }}
-      - name: Install cargo-make
-        uses: actions-rs/cargo@v1
-        with:
-          command: install
-          args: cargo-make
-      - name: Cache LLVM
-        id: cache-llvm
-        uses: actions/cache@v2
-        with:
-          path: ~/.local/share/llvm/firefly
-          key: firefly-15.0.0-dev_2022-07-22-apple-darwin21.5.0
-      - name: Install LLVM
-        if: steps.cache-llvm.outputs.cache-hit != 'true'
-        run: |
-          mkdir -p ~/.local/share/llvm
-          pushd ~/.local/share/llvm
-          wget https://github.com/lumen/llvm-project/releases/download/firefly-15.0.0-dev_2022-07-22/clang+llvm-15.0.0-x86_64-apple-darwin21.5.0.tar.gz
-          tar xvfz clang+llvm-15.0.0-x86_64-apple-darwin21.5.0.tar.gz
-          mv clang+llvm-15.0.0-x86_64-apple-darwin21.5.0 firefly
-          popd
-      - name: Set LLVM_PREFIX
-        run: echo "LLVM_PREFIX=$HOME/.local/share/llvm/firefly" >> $GITHUB_ENV
-      - name: Install Ninja
-        run: brew install ninja
-      - name: Build Compiler
-        uses: actions-rs/cargo@v1
-        with:
-          command: make
-          args: firefly
-      - name: Add Compiler To Path
-        run: |
-          if [ -n "${GITHUB_PATH}" ]; then
-            echo "$PWD/bin" >> $GITHUB_PATH
-          else
-            echo "::add-path::${PWD}/bin"
-          fi
-      - name: Run baseline tests
-        uses: actions-rs/cargo@v1
-        with:
-          command: make
-          args: test-lit
-      - name: Run firefly_otp integration tests
-        uses: actions-rs/cargo@v1
-        with:
-          command: make
-          args: |
-            test --package firefly_otp lib:: -- --skip firefly::otp
-      - name: Run spawn-chain tests
-        uses: actions-rs/cargo@v1
-        with:
-          command: make
-          args: test-spawn-chain
diff --git a/.github/workflows/x86_64-apple-darwin-firefly-otp.yml b/.github/workflows/x86_64-apple-darwin-firefly-otp.yml
index ca2b30120..748f345ae 100644
--- a/.github/workflows/x86_64-apple-darwin-firefly-otp.yml
+++ b/.github/workflows/x86_64-apple-darwin-firefly-otp.yml
@@ -60,7 +60,7 @@ jobs:
           cd otp
           echo "ERL_TOP=$PWD" >> $GITHUB_ENV
           git remote add origin https://github.com/lumen/otp
-          git fetch --no-tags --prune --progress --depth=1 origin +ca83f680aab717fe65634247d16f18a8cbfc6d8d:refs/remotes/origin/firefly
+          git fetch --no-tags --prune --progress --depth=1 origin +f97de7a99692cb08b5e27d17e86d92707ad16eed:refs/remotes/origin/firefly
           git checkout --progress --force -B firefly refs/remotes/origin/firefly
       - name: firefly/otp autoconf
         run: |
@@ -77,4 +77,4 @@ jobs:
         with:
           command: make
           args: |
-            test -- --package firefly_otp firefly::otp::
+            test --package firefly_otp firefly::otp::
diff --git a/.github/workflows/x86_64-apple-darwin-libraries.yml b/.github/workflows/x86_64-apple-darwin-libraries.yml
deleted file mode 100644
index 9a47c6967..000000000
--- a/.github/workflows/x86_64-apple-darwin-libraries.yml
+++ /dev/null
@@ -1,75 +0,0 @@
-name: x86_64-apple-darwin Libraries
-
-on: push
-
-env:
-  TOOLCHAIN: nightly-2022-07-12
-
-jobs:
-  libraries:
-    if: ${{ false }} # disabled
-    runs-on: macos-12
-
-    steps:
-      - uses: actions/checkout@v2
-      - name: Install nightly-2022-07-12
-        uses: actions-rs/toolchain@v1
-        with:
-          toolchain: ${{ env.TOOLCHAIN }}
-          override: true
-      - name: Cache Cargo
-        uses: actions/cache@v2
-        with:
-          path: |
-            ~/.cargo/registry
-            ~/.cargo/git
-          key: ${{ github.workflow }}-${{ github.job }}-toolchain-${{ env.TOOLCHAIN }}-cargo-${{ hashFiles('**/Cargo.lock') }}
-      - name: Install cargo-make
-        uses: actions-rs/cargo@v1
-        with:
-          command: install
-          args: cargo-make
-      - name: Cache LLVM
-        id: cache-llvm
-        uses: actions/cache@v2
-        with:
-          path: ~/.local/share/llvm/firefly
-          key: firefly-15.0.0-dev_2022-07-22-apple-darwin21.5.0
-      - name: Install LLVM
-        if: steps.cache-llvm.outputs.cache-hit != 'true'
-        run: |
-          mkdir -p ~/.local/share/llvm
-          pushd ~/.local/share/llvm
-          wget https://github.com/lumen/llvm-project/releases/download/firefly-15.0.0-dev_2022-07-22/clang+llvm-15.0.0-x86_64-apple-darwin21.5.0.tar.gz
-          tar xvfz clang+llvm-15.0.0-x86_64-apple-darwin21.5.0.tar.gz
-          mv clang+llvm-15.0.0-x86_64-apple-darwin21.5.0 firefly
-          popd
-      - name: Set LLVM_PREFIX
-        run: echo "LLVM_PREFIX=$HOME/.local/share/llvm/firefly" >> $GITHUB_ENV
-      - name: Install Ninja
-        run: brew install ninja
-      - name: firefly_arena
-        uses: actions-rs/cargo@v1
-        with:
-          command: make
-          args: test -- --package firefly_arena
-      - name: firefly_alloc
-        uses: actions-rs/cargo@v1
-        with:
-          command: make
-          args: test -- --package firefly_alloc
-      - name: firefly_binary
-        uses: actions-rs/cargo@v1
-        with:
-          command: make
-          args: test -- --package firefly_binary
-      - name: firefly_system
-        uses: actions-rs/cargo@v1
-        with:
-          command: make
-          args: test -- --package firefly_system
-      - name: firefly_rt
-        uses: actions-rs/cargo@v1
-        with:
-          command: make
-          args: test -- --package firefly_rt
diff --git a/.github/workflows/x86_64-apple-darwin-runtime_full.yml b/.github/workflows/x86_64-apple-darwin-runtime_full.yml
deleted file mode 100644
index 2b69e506f..000000000
--- a/.github/workflows/x86_64-apple-darwin-runtime_full.yml
+++ /dev/null
@@ -1,67 +0,0 @@
-name: x86_64-apple-darwin Runtime Full
-
-on: push
-
-env:
-  TOOLCHAIN: nightly-2022-07-12
-
-jobs:
-  runtime:
-    if: ${{ false }} # disable
-    runs-on: macos-12
-
-    steps:
-      - uses: actions/checkout@v2
-      - name: Install nightly-2022-07-12
-        uses: actions-rs/toolchain@v1
-        with:
-          toolchain: ${{ env.TOOLCHAIN }}
-          override: true
-      - name: Cache Cargo
-        uses: actions/cache@v2
-        with:
-          path: |
-            ~/.cargo/registry
-            ~/.cargo/git
-          key: ${{ github.workflow }}-${{ github.job }}-toolchain-${{ env.TOOLCHAIN }}-cargo-${{ hashFiles('**/Cargo.lock') }}
-      - name: Install cargo-make
-        uses: actions-rs/cargo@v1
-        with:
-          command: install
-          args: cargo-make
-      - name: Cache LLVM
-        id: cache-llvm
-        uses: actions/cache@v2
-        with:
-          path: ~/.local/share/llvm/firefly
-          key: firefly-15.0.0-dev_2022-07-22-apple-darwin21.5.0
-      - name: Install LLVM
-        if: steps.cache-llvm.outputs.cache-hit != 'true'
-        run: |
-          mkdir -p ~/.local/share/llvm
-          pushd ~/.local/share/llvm
-          wget https://github.com/lumen/llvm-project/releases/download/firefly-15.0.0-dev_2022-07-22/clang+llvm-15.0.0-x86_64-apple-darwin21.5.0.tar.gz
-          tar xvfz clang+llvm-15.0.0-x86_64-apple-darwin21.5.0.tar.gz
-          mv clang+llvm-15.0.0-x86_64-apple-darwin21.5.0 firefly
-          popd
-      - name: Set LLVM_PREFIX
-        run: echo "LLVM_PREFIX=$HOME/.local/share/llvm/firefly" >> $GITHUB_ENV
-      - name: Install Ninja
-        run: brew install ninja
-      - name: Build Compiler
-        uses: actions-rs/cargo@v1
-        with:
-          command: make
-          args: firefly
-      - name: Run firefly_rt_full tests
-        uses: actions-rs/cargo@v1
-        with:
-          command: make
-          args: |
-            test -- --package firefly_rt_full
-      - name: Run firefly_otp tests with runtime_full
-        uses: actions-rs/cargo@v1
-        with:
-          command: make
-          args: |
-            test -- --package firefly_otp -- --skip lib:: --skip firefly::otp
diff --git a/.github/workflows/x86_64-unknown-linux-gnu-compiler.yml b/.github/workflows/x86_64-unknown-linux-gnu-compiler.yml
deleted file mode 100644
index 206ceff78..000000000
--- a/.github/workflows/x86_64-unknown-linux-gnu-compiler.yml
+++ /dev/null
@@ -1,73 +0,0 @@
-name: x86_64-unknown-linux-gnu compiler
-
-on:
-  push:
-    paths-ignore:
-    - '*.md'
-
-env:
-  TOOLCHAIN: nightly-2022-08-08
-  LLVM_RELEASE: firefly-15.0.0-dev_2022-08-27
-  LLVM_LINK_LLVM_DYLIB: ON
-  FIREFLY_BUILD_TYPE: static
-
-jobs:
-  compiler:
-    runs-on: ubuntu-latest
-
-    steps:
-      - uses: actions/checkout@v2
-      - name: Setup Env
-        run: |
-          echo "$(whoami)"
-          if [ -z "${XDG_DATA_HOME}" ]; then
-            sudo mkdir -p $HOME/.local/share/llvm
-            sudo chown -R runner $HOME/.local/share/llvm
-            echo "XDG_DATA_HOME=$HOME/.local/share" >> $GITHUB_ENV
-          fi
-          echo "$PWD/bin" >> $GITHUB_PATH
-      - name: Install Ninja
-        run: |
-          wget "https://github.com/ninja-build/ninja/releases/download/v1.9.0/ninja-linux.zip"
-          unzip ninja-linux.zip -d /usr/local/bin
-          rm ninja-linux.zip
-      - name: Install LLVM
-        run: |
-          mkdir -p "$XDG_DATA_HOME/llvm/firefly"
-          cd "$XDG_DATA_HOME/llvm/firefly"
-          wget "https://github.com/getfirefly/llvm-project/releases/download/${LLVM_RELEASE}/clang+llvm-15.0.0-x86_64-linux-gnu.tar.gz"
-          tar -xz --strip-components 1 -f clang+llvm-15.0.0-x86_64-linux-gnu.tar.gz
-          rm clang+llvm-15.0.0-x86_64-linux-gnu.tar.gz
-          cd -
-      - name: Install Toolchain
-        run: |
-          rustup toolchain install ${TOOLCHAIN}
-          rustup default ${TOOLCHAIN}
-      - name: Cache Cargo
-        uses: actions/cache@v2
-        with:
-          path: |
-            ~/.cargo/registry
-            ~/.cargo/git
-          key: ${{ github.workflow }}-${{ github.job }}-toolchain-${{ env.TOOLCHAIN }}-cargo-${{ hashFiles('**/Cargo.lock') }}
-      - name: Install cargo-make
-        uses: actions-rs/cargo@v1
-        with:
-          toolchain: ${{ env.TOOLCHAIN }}
-          command: install
-          args: cargo-make
-      - name: Build Compiler
-        uses: actions-rs/cargo@v1
-        env:
-          CC: clang
-          CXX: clang++
-        with:
-          toolchain: ${{ env.TOOLCHAIN }}
-          command: make
-          args: firefly
-      - name: Run lit tests
-        uses: actions-rs/cargo@v1
-        with:
-          toolchain: ${{ env.TOOLCHAIN }}
-          command: make
-          args: test-lit
diff --git a/.github/workflows/x86_64-unknown-linux-gnu-firefly-otp.yml b/.github/workflows/x86_64-unknown-linux-gnu-firefly-otp.yml
deleted file mode 100644
index 6dd12c21c..000000000
--- a/.github/workflows/x86_64-unknown-linux-gnu-firefly-otp.yml
+++ /dev/null
@@ -1,50 +0,0 @@
-name: x86_64-unknown-linux-gnu firefly/otp
-
-on: push
-
-env:
-  TOOLCHAIN: nightly-2022-07-12
-
-jobs:
-  firefly-otp:
-    if: ${{ false }} # disable
-    runs-on: ubuntu-latest
-    container: kronicdeth/lumen-development@sha256:2809805464d685940b58765a634fa23a5fd1a62c65710cfa43a8791cd50fbecd
-
-    steps:
-      - uses: actions/checkout@v2
-      - name: Cache Cargo
-        uses: actions/cache@v2
-        with:
-          path: |
-            ~/.cargo/registry
-            ~/.cargo/git
-          key: ${{ github.workflow }}-${{ github.job }}-toolchain-${{ env.TOOLCHAIN }}-cargo-${{ hashFiles('**/Cargo.lock') }}
-      - name: Build Compiler
-        uses: actions-rs/cargo@v1
-        with:
-          command: make
-          args: firefly
-      - name: firefly/otp Checkout
-        run: |
-          cd ..
-          git init otp
-          cd otp
-          echo "ERL_TOP=$PWD" >> $GITHUB_ENV
-          git remote add origin https://github.com/firefly/otp
-          git fetch --no-tags --prune --progress --depth=1 origin +ca83f680aab717fe65634247d16f18a8cbfc6d8d:refs/remotes/origin/firefly
-          git checkout --progress --force -B firefly refs/remotes/origin/firefly
-      - name: firefly/otp autoconf
-        run: |
-          cd ../otp
-          ./otp_build autoconf
-      - name: firefly/otp configure
-        run: |
-          cd ../otp
-          ./configure
-      - name: Test compiling firefly/otp against firefly_otp
-        uses: actions-rs/cargo@v1
-        with:
-          command: make
-          args: |
-            test -- --package firefly_otp firefly::otp::
diff --git a/.github/workflows/x86_64-unknown-linux-gnu-libraries.yml b/.github/workflows/x86_64-unknown-linux-gnu-libraries.yml
deleted file mode 100644
index aaa0177d3..000000000
--- a/.github/workflows/x86_64-unknown-linux-gnu-libraries.yml
+++ /dev/null
@@ -1,67 +0,0 @@
-name: x86_64-unknown-linux-gnu Libraries
-
-on: push
-
-env:
-  TOOLCHAIN: nightly-2022-07-12
-
-jobs:
-  formatted:
-    if: ${{ false }} # disable
-    runs-on: ubuntu-latest
-    container: kronicdeth/lumen-development@sha256:2809805464d685940b58765a634fa23a5fd1a62c65710cfa43a8791cd50fbecd
-
-    steps:
-      - uses: actions/checkout@v2
-      - name: Cache Cargo
-        uses: actions/cache@v2
-        with:
-          path: |
-            ~/.cargo/registry
-            ~/.cargo/git
-          key: ${{ github.workflow }}-${{ github.job }}-toolchain-${{ env.TOOLCHAIN }}-cargo-${{ hashFiles('**/Cargo.lock') }}
-      - name: Check Formatted
-        uses: actions-rs/cargo@v1
-        with:
-          command: make
-          args: check-format
-
-  libraries:
-    if: ${{ false }} # disable
-    runs-on: ubuntu-latest
-    container: kronicdeth/lumen-development@sha256:2809805464d685940b58765a634fa23a5fd1a62c65710cfa43a8791cd50fbecd
-
-    steps:
-      - uses: actions/checkout@v2
-      - name: Cache Cargo
-        uses: actions/cache@v2
-        with:
-          path: |
-            ~/.cargo/registry
-            ~/.cargo/git
-          key: ${{ github.workflow }}-${{ github.job }}-cargo-${{ hashFiles('**/Cargo.lock') }}
-      - name: firefly_arena
-        uses: actions-rs/cargo@v1
-        with:
-          command: make
-          args: test -- --package firefly_arena
-      - name: firefly_alloc
-        uses: actions-rs/cargo@v1
-        with:
-          command: make
-          args: test -- --package firefly_alloc
-      - name: firefly_binary
-        uses: actions-rs/cargo@v1
-        with:
-          command: make
-          args: test -- --package firefly_binary
-      - name: firefly_system
-        uses: actions-rs/cargo@v1
-        with:
-          command: make
-          args: test -- --package firefly_system
-      - name: firefly_rt
-        uses: actions-rs/cargo@v1
-        with:
-          command: make
-          args: test -- --package firefly_rt
diff --git a/.github/workflows/x86_64-unknown-linux-gnu-runtime_full.yml b/.github/workflows/x86_64-unknown-linux-gnu-runtime_full.yml
deleted file mode 100644
index 4416019b1..000000000
--- a/.github/workflows/x86_64-unknown-linux-gnu-runtime_full.yml
+++ /dev/null
@@ -1,39 +0,0 @@
-name: x86_64-unknown-linux-gnu Runtime Full
-
-on: push
-
-env:
-  TOOLCHAIN: nightly-2022-07-12
-
-jobs:
-  runtime:
-    if: ${{ false }} # disable
-    runs-on: ubuntu-latest
-    container: kronicdeth/lumen-development@sha256:2809805464d685940b58765a634fa23a5fd1a62c65710cfa43a8791cd50fbecd
-
-    steps:
-      - uses: actions/checkout@v2
-      - name: Cache Cargo
-        uses: actions/cache@v2
-        with:
-          path: |
-            ~/.cargo/registry
-            ~/.cargo/git
-          key: ${{ github.workflow }}-${{ github.job }}-toolchain-${{ env.TOOLCHAIN }}-cargo-${{ hashFiles('**/Cargo.lock') }}
-      - name: Build Compiler
-        uses: actions-rs/cargo@v1
-        with:
-          command: make
-          args: firefly
-      - name: Run firefly_rt_full tests
-        uses: actions-rs/cargo@v1
-        with:
-          command: make
-          args: |
-            test -- --package firefly_rt_full
-      - name: Run firefly_otp tests with runtime_full
-        uses: actions-rs/cargo@v1
-        with:
-          command: make
-          args: |
-            test -- --package firefly_otp -- --skip lib:: --skip firefly::otp
diff --git a/Cargo.lock b/Cargo.lock
index a73d4e0af..0827742d1 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -41,20 +41,20 @@ checksum = "e8fd72866655d1904d6b0997d0b07ba561047d070fbe29de039031c641b61217"
 
 [[package]]
 name = "ahash"
-version = "0.7.6"
+version = "0.7.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
+checksum = "43bb833f0bf979d8475d38fbf09ed3b8a55e1885fe93ad3f93239fc6a4f17b98"
 dependencies = [
- "getrandom 0.2.7",
+ "getrandom 0.2.1",
  "once_cell",
  "version_check",
 ]
 
 [[package]]
 name = "aho-corasick"
-version = "0.7.18"
+version = "0.7.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
+checksum = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86"
 dependencies = [
  "memchr",
 ]
@@ -70,9 +70,9 @@ dependencies = [
 
 [[package]]
 name = "anyhow"
-version = "1.0.62"
+version = "1.0.32"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1485d4d2cc45e7b201ee3767015c96faa5904387c9d87c6efdd0fb511f12d305"
+checksum = "6b602bfe940d21c130f3895acd65221e8a61270debe89d628b9cb4e3ccb8569b"
 
 [[package]]
 name = "archery"
@@ -83,6 +83,12 @@ dependencies = [
  "static_assertions",
 ]
 
+[[package]]
+name = "arrayvec"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
+
 [[package]]
 name = "ascii-canvas"
 version = "3.0.0"
@@ -103,10 +109,10 @@ dependencies = [
 ]
 
 [[package]]
-name = "async-task"
-version = "4.3.0"
+name = "atomic-option"
+version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524"
+checksum = "0db678acb667b525ac40a324fc5f7d3390e29239b31c7327bb8157f5b4fff593"
 
 [[package]]
 name = "atty"
@@ -121,9 +127,15 @@ dependencies = [
 
 [[package]]
 name = "autocfg"
-version = "1.1.0"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
+
+[[package]]
+name = "autocfg"
+version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
+checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
 
 [[package]]
 name = "backtrace"
@@ -142,24 +154,24 @@ dependencies = [
 
 [[package]]
 name = "beef"
-version = "0.5.2"
+version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1"
+checksum = "bed554bd50246729a1ec158d08aa3235d1b69d94ad120ebe187e28894787e736"
 
 [[package]]
 name = "bit-set"
-version = "0.5.3"
+version = "0.5.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1"
+checksum = "6e11e16035ea35e4e5997b393eacbf6f63983188f7a2ad25bfb13465f5ad59de"
 dependencies = [
  "bit-vec",
 ]
 
 [[package]]
 name = "bit-vec"
-version = "0.6.3"
+version = "0.6.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
+checksum = "5f0dc55f2d8a1a85650ac47858bb001b4c0dd73d79e3c455a842925e68d29cd3"
 
 [[package]]
 name = "bitflags"
@@ -175,20 +187,21 @@ checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d"
 
 [[package]]
 name = "bus"
-version = "2.3.0"
+version = "2.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "80cb4625f5b60155ff1018c9d4ce2e38bf5ae3e5780dfab9fa68bb44a6b751e2"
+checksum = "f1e66e1779f5b1440f1a58220ba3b3ded4427175f0a9fb8d7066521f8b4e8f2b"
 dependencies = [
- "crossbeam-channel 0.5.6",
+ "atomic-option",
+ "crossbeam-channel",
  "num_cpus",
- "parking_lot_core 0.9.3",
+ "parking_lot_core 0.7.2",
 ]
 
 [[package]]
 name = "byteorder"
-version = "1.4.3"
+version = "1.3.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
+checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
 
 [[package]]
 name = "cc"
@@ -223,11 +236,20 @@ dependencies = [
  "vec_map",
 ]
 
+[[package]]
+name = "cloudabi"
+version = "0.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
+dependencies = [
+ "bitflags",
+]
+
 [[package]]
 name = "cmake"
-version = "0.1.48"
+version = "0.1.46"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8ad8cef104ac57b68b89df3208164d228503abbdce70f6880ffa3d970e7443a"
+checksum = "b7b858541263efe664aead4a5209a4ae5c5d2811167d4ed4ee0944503f8d2089"
 dependencies = [
  "cc",
 ]
@@ -253,17 +275,17 @@ dependencies = [
 
 [[package]]
 name = "cranelift-entity"
-version = "0.81.2"
+version = "0.81.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d84f8e8a408071d67f479a00c6d3da965b1f9b4b240b7e7e27edb1a34401b3cd"
+checksum = "1268a50b7cbbfee8514d417fc031cedd9965b15fa9e5ed1d4bc16de86f76765e"
 
 [[package]]
 name = "crc32fast"
-version = "1.3.2"
+version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
+checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"
 dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if 0.1.10",
 ]
 
 [[package]]
@@ -273,41 +295,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "69323bff1fb41c635347b8ead484a5ca6c3f11914d784170b158d8449ab07f8e"
 dependencies = [
  "cfg-if 0.1.10",
- "crossbeam-channel 0.4.4",
+ "crossbeam-channel",
  "crossbeam-deque",
  "crossbeam-epoch",
  "crossbeam-queue",
- "crossbeam-utils 0.7.2",
-]
-
-[[package]]
-name = "crossbeam-channel"
-version = "0.4.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87"
-dependencies = [
- "crossbeam-utils 0.7.2",
- "maybe-uninit",
+ "crossbeam-utils",
 ]
 
 [[package]]
 name = "crossbeam-channel"
-version = "0.5.6"
+version = "0.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521"
+checksum = "09ee0cc8804d5393478d743b035099520087a5186f3b93fa58cec08fa62407b6"
 dependencies = [
- "cfg-if 1.0.0",
- "crossbeam-utils 0.8.11",
+ "cfg-if 0.1.10",
+ "crossbeam-utils",
 ]
 
 [[package]]
 name = "crossbeam-deque"
-version = "0.7.4"
+version = "0.7.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c20ff29ded3204c5106278a81a38f4b482636ed4fa1e6cfbeef193291beb29ed"
+checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285"
 dependencies = [
  "crossbeam-epoch",
- "crossbeam-utils 0.7.2",
+ "crossbeam-utils",
  "maybe-uninit",
 ]
 
@@ -317,9 +329,9 @@ version = "0.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace"
 dependencies = [
- "autocfg",
+ "autocfg 1.0.0",
  "cfg-if 0.1.10",
- "crossbeam-utils 0.7.2",
+ "crossbeam-utils",
  "lazy_static",
  "maybe-uninit",
  "memoffset",
@@ -333,7 +345,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570"
 dependencies = [
  "cfg-if 0.1.10",
- "crossbeam-utils 0.7.2",
+ "crossbeam-utils",
  "maybe-uninit",
 ]
 
@@ -343,21 +355,11 @@ version = "0.7.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
 dependencies = [
- "autocfg",
+ "autocfg 1.0.0",
  "cfg-if 0.1.10",
  "lazy_static",
 ]
 
-[[package]]
-name = "crossbeam-utils"
-version = "0.8.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc"
-dependencies = [
- "cfg-if 1.0.0",
- "once_cell",
-]
-
 [[package]]
 name = "crunchy"
 version = "0.2.2"
@@ -366,9 +368,9 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
 
 [[package]]
 name = "ctor"
-version = "0.1.23"
+version = "0.1.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cdffe87e1d521a10f9696f833fe502293ea446d7f256c06128293a4119bdf4cb"
+checksum = "39858aa5bac06462d4dd4b9164848eb81ffc4aa5c479746393598fd193afa227"
 dependencies = [
  "quote",
  "syn",
@@ -386,9 +388,9 @@ dependencies = [
 
 [[package]]
 name = "diff"
-version = "0.1.13"
+version = "0.1.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
+checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499"
 
 [[package]]
 name = "dirs"
@@ -433,18 +435,18 @@ dependencies = [
 
 [[package]]
 name = "dlmalloc"
-version = "0.2.4"
+version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "203540e710bfadb90e5e29930baf5d10270cec1f43ab34f46f78b147b2de715a"
+checksum = "332570860c2edf2d57914987bf9e24835425f75825086b6ba7d1e6a3e4f1f254"
 dependencies = [
  "libc",
 ]
 
 [[package]]
 name = "either"
-version = "1.8.0"
+version = "1.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
+checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
 
 [[package]]
 name = "ena"
@@ -492,9 +494,9 @@ dependencies = [
 
 [[package]]
 name = "fastrand"
-version = "1.8.0"
+version = "1.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499"
+checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf"
 dependencies = [
  "instant",
 ]
@@ -550,7 +552,7 @@ version = "0.1.0"
 dependencies = [
  "anyhow",
  "half",
- "num-bigint 0.4.3",
+ "num-bigint 0.4.2",
  "num-traits",
  "paste",
  "static_assertions",
@@ -579,7 +581,7 @@ dependencies = [
  "fxhash",
  "libc",
  "log",
- "num-bigint 0.4.3",
+ "num-bigint 0.4.2",
  "tempfile",
  "thiserror",
 ]
@@ -589,7 +591,7 @@ name = "firefly_compiler"
 version = "0.1.0"
 dependencies = [
  "anyhow",
- "async-task 1.3.1",
+ "async-task",
  "clap",
  "crossbeam",
  "firefly_codegen",
@@ -611,7 +613,7 @@ dependencies = [
  "lazy_static",
  "log",
  "num_cpus",
- "parking_lot 0.11.2",
+ "parking_lot 0.11.1",
  "rand 0.7.3",
  "salsa",
  "salsa-macros",
@@ -720,9 +722,34 @@ name = "firefly_number"
 version = "0.1.0"
 dependencies = [
  "half",
- "num-bigint 0.4.3",
+ "num-bigint 0.4.2",
  "num-integer",
  "num-traits",
+ "thiserror-no-std",
+]
+
+[[package]]
+name = "firefly_otp"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "firefly_alloc",
+ "firefly_number",
+ "firefly_rt",
+ "firefly_rt_tiny",
+ "hashbrown 0.12.0",
+ "lazy_static",
+ "libc",
+ "native_implemented",
+ "num-bigint 0.4.2",
+ "num-traits",
+ "panic-control",
+ "process_control",
+ "proptest",
+ "radix_fmt",
+ "strip-ansi-escapes",
+ "thiserror",
+ "web-sys",
 ]
 
 [[package]]
@@ -752,7 +779,7 @@ dependencies = [
  "fxhash",
  "log",
  "memmap",
- "parking_lot 0.11.2",
+ "parking_lot 0.11.1",
 ]
 
 [[package]]
@@ -768,9 +795,9 @@ dependencies = [
  "firefly_binary",
  "firefly_number",
  "firefly_system",
- "hashbrown 0.12.3",
+ "hashbrown 0.12.0",
  "lazy_static",
- "num-bigint 0.4.3",
+ "num-bigint 0.4.2",
  "num-traits",
  "paste",
  "rpds 0.11.0",
@@ -778,6 +805,8 @@ dependencies = [
  "seq-macro",
  "static_assertions",
  "termcolor",
+ "thiserror",
+ "thiserror-no-std",
  "toml",
 ]
 
@@ -799,27 +828,6 @@ dependencies = [
  "smallvec",
 ]
 
-[[package]]
-name = "firefly_rt_tiny_async"
-version = "0.1.0"
-dependencies = [
- "anyhow",
- "async-task 4.3.0",
- "bus",
- "dirs",
- "firefly_alloc",
- "firefly_arena",
- "firefly_binary",
- "firefly_crt",
- "firefly_number",
- "firefly_rt",
- "flume",
- "futures",
- "libc",
- "signal-hook",
- "smallvec",
-]
-
 [[package]]
 name = "firefly_session"
 version = "0.1.0"
@@ -952,7 +960,7 @@ dependencies = [
  "dlmalloc",
  "lazy_static",
  "libc",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.0",
  "winapi",
 ]
 
@@ -978,22 +986,9 @@ dependencies = [
 
 [[package]]
 name = "fixedbitset"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
-
-[[package]]
-name = "flume"
-version = "0.10.14"
+version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577"
-dependencies = [
- "futures-core",
- "futures-sink",
- "nanorand",
- "pin-project",
- "spin 0.9.4",
-]
+checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d"
 
 [[package]]
 name = "fnv"
@@ -1001,11 +996,17 @@ version = "1.0.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
 
+[[package]]
+name = "fuchsia-cprng"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
+
 [[package]]
 name = "futures"
-version = "0.3.23"
+version = "0.3.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab30e97ab6aacfe635fad58f22c2bb06c8b685f7421eb1e064a729e2a5f481fa"
+checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e"
 dependencies = [
  "futures-channel",
  "futures-core",
@@ -1018,9 +1019,9 @@ dependencies = [
 
 [[package]]
 name = "futures-channel"
-version = "0.3.23"
+version = "0.3.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2bfc52cbddcfd745bf1740338492bb0bd83d76c67b445f91c5fb29fae29ecaa1"
+checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010"
 dependencies = [
  "futures-core",
  "futures-sink",
@@ -1028,15 +1029,15 @@ dependencies = [
 
 [[package]]
 name = "futures-core"
-version = "0.3.23"
+version = "0.3.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2acedae88d38235936c3922476b10fced7b2b68136f5e3c03c2d5be348a1115"
+checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3"
 
 [[package]]
 name = "futures-executor"
-version = "0.3.23"
+version = "0.3.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d11aa21b5b587a64682c0094c2bdd4df0076c5324961a40cc3abd7f37930528"
+checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6"
 dependencies = [
  "futures-core",
  "futures-task",
@@ -1045,15 +1046,15 @@ dependencies = [
 
 [[package]]
 name = "futures-io"
-version = "0.3.23"
+version = "0.3.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93a66fc6d035a26a3ae255a6d2bca35eda63ae4c5512bef54449113f7a1228e5"
+checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b"
 
 [[package]]
 name = "futures-macro"
-version = "0.3.23"
+version = "0.3.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0db9cce532b0eae2ccf2766ab246f114b56b9cf6d445e00c2549fbc100ca045d"
+checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1062,21 +1063,21 @@ dependencies = [
 
 [[package]]
 name = "futures-sink"
-version = "0.3.23"
+version = "0.3.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca0bae1fe9752cf7fd9b0064c674ae63f97b37bc714d745cbde0afb7ec4e6765"
+checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868"
 
 [[package]]
 name = "futures-task"
-version = "0.3.23"
+version = "0.3.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "842fc63b931f4056a24d59de13fb1272134ce261816e063e634ad0c15cdc5306"
+checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a"
 
 [[package]]
 name = "futures-util"
-version = "0.3.23"
+version = "0.3.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0828a5471e340229c11c77ca80017937ce3c58cb788a17e5f1c2d5c485a9577"
+checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a"
 dependencies = [
  "futures-channel",
  "futures-core",
@@ -1101,26 +1102,24 @@ dependencies = [
 
 [[package]]
 name = "getrandom"
-version = "0.1.16"
+version = "0.1.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
+checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
 dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if 0.1.10",
  "libc",
  "wasi 0.9.0+wasi-snapshot-preview1",
 ]
 
 [[package]]
 name = "getrandom"
-version = "0.2.7"
+version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
+checksum = "4060f4657be78b8e766215b02b18a2e862d83745545de804638e2b545e81aee6"
 dependencies = [
  "cfg-if 1.0.0",
- "js-sys",
  "libc",
- "wasi 0.11.0+wasi-snapshot-preview1",
- "wasm-bindgen",
+ "wasi 0.10.1+wasi-snapshot-preview1",
 ]
 
 [[package]]
@@ -1137,47 +1136,52 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
 
 [[package]]
 name = "half"
-version = "2.1.0"
+version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ad6a9459c9c30b177b925162351f97e7d967c7ea8bab3b8352805327daf45554"
+checksum = "c207b0ee023c7fce79daf01828163aaf53a1ddd0be8b1ef9541da7d41f6fa63a"
 dependencies = [
- "crunchy",
  "num-traits",
 ]
 
 [[package]]
 name = "hashbrown"
-version = "0.8.2"
+version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e91b62f79061a0bc2e046024cb7ba44b08419ed238ecbd9adbd787434b9e8c25"
+checksum = "34f595585f103464d8d2f6e9864682d74c1601fed5e07d62b1c9058dba8246fb"
 dependencies = [
  "ahash 0.3.8",
- "autocfg",
+ "autocfg 1.0.0",
 ]
 
 [[package]]
 name = "hashbrown"
-version = "0.12.3"
+version = "0.11.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
+
+[[package]]
+name = "hashbrown"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8c21d40587b92fa6a6c6e3c1bdbf87d75511db5672f9c93175574b3a00df1758"
 dependencies = [
- "ahash 0.7.6",
+ "ahash 0.7.4",
 ]
 
 [[package]]
 name = "heck"
-version = "0.3.3"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
+checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
 dependencies = [
  "unicode-segmentation",
 ]
 
 [[package]]
 name = "hermit-abi"
-version = "0.1.19"
+version = "0.1.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
+checksum = "3deed196b6e7f9e44a2ae8d94225d80302d81208b1bb673fd21fe634645c85a9"
 dependencies = [
  "libc",
 ]
@@ -1205,37 +1209,34 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
 
 [[package]]
 name = "indexmap"
-version = "1.9.1"
+version = "1.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
+checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5"
 dependencies = [
- "autocfg",
- "hashbrown 0.12.3",
+ "autocfg 1.0.0",
+ "hashbrown 0.11.2",
 ]
 
 [[package]]
 name = "instant"
-version = "0.1.12"
+version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
-dependencies = [
- "cfg-if 1.0.0",
-]
+checksum = "5b141fdc7836c525d4d594027d318c84161ca17aaf8113ab1f81ab93ae897485"
 
 [[package]]
 name = "intrusive-collections"
-version = "0.9.4"
+version = "0.9.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bfe531a7789d7120f3e17d4f3f2cd95f54418ba7354f60b7b622b6644a07888a"
+checksum = "fb484b70a4ebad7f571bf84e9cd06b5bfb6a7e4db0c36e13dd1570c6b449c10d"
 dependencies = [
  "memoffset",
 ]
 
 [[package]]
 name = "itertools"
-version = "0.10.3"
+version = "0.10.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
+checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf"
 dependencies = [
  "either",
 ]
@@ -1251,9 +1252,9 @@ dependencies = [
 
 [[package]]
 name = "lalrpop"
-version = "0.19.8"
+version = "0.19.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b30455341b0e18f276fa64540aff54deafb54c589de6aca68659c63dd2d5d823"
+checksum = "b15174f1c529af5bf1283c3bc0058266b483a67156f79589fab2a25e23cf8988"
 dependencies = [
  "ascii-canvas",
  "atty",
@@ -1274,9 +1275,9 @@ dependencies = [
 
 [[package]]
 name = "lalrpop-util"
-version = "0.19.8"
+version = "0.19.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bcf796c978e9b4d983414f4caedc9273aa33ee214c5b887bd55fde84c85d2dc4"
+checksum = "d3e58cce361efcc90ba8a0a5f982c741ff86b603495bb15a998412e957dcd278"
 dependencies = [
  "regex",
 ]
@@ -1287,14 +1288,14 @@ version = "1.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
 dependencies = [
- "spin 0.5.2",
+ "spin",
 ]
 
 [[package]]
 name = "libc"
-version = "0.2.132"
+version = "0.2.120"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5"
+checksum = "ad5c14e80759d0939d013e6ca49930e59fc53dd8e5009132f76240c179380c09"
 
 [[package]]
 name = "libflate"
@@ -1310,43 +1311,42 @@ dependencies = [
 
 [[package]]
 name = "libm"
-version = "0.2.5"
+version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "292a948cd991e376cf75541fe5b97a1081d713c618b4f1b9500f8844e49eb565"
+checksum = "33a33a362ce288760ec6a508b94caaec573ae7d3bbbd91b87aa0bad4456839db"
 
 [[package]]
 name = "lock_api"
-version = "0.4.7"
+version = "0.4.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53"
+checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b"
 dependencies = [
- "autocfg",
  "scopeguard",
 ]
 
 [[package]]
 name = "log"
-version = "0.4.17"
+version = "0.4.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
+checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
 dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if 0.1.10",
 ]
 
 [[package]]
 name = "logos"
-version = "0.12.1"
+version = "0.12.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf8b031682c67a8e3d5446840f9573eb7fe26efe7ec8d195c9ac4c0647c502f1"
+checksum = "427e2abca5be13136da9afdbf874e6b34ad9001dd70f2b103b083a85daa7b345"
 dependencies = [
  "logos-derive",
 ]
 
 [[package]]
 name = "logos-derive"
-version = "0.12.1"
+version = "0.12.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1d849148dbaf9661a6151d1ca82b13bb4c4c128146a88d05253b38d4e2f496c"
+checksum = "56a7d287fd2ac3f75b11f19a1c8a874a7d55744bd91f7a1b3e7cf87d4343c36d"
 dependencies = [
  "beef",
  "fnv",
@@ -1354,6 +1354,7 @@ dependencies = [
  "quote",
  "regex-syntax",
  "syn",
+ "utf8-ranges",
 ]
 
 [[package]]
@@ -1380,29 +1381,30 @@ dependencies = [
 
 [[package]]
 name = "memoffset"
-version = "0.5.6"
+version = "0.5.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa"
+checksum = "c198b026e1bbf08a937e94c6c60f9ec4a2267f5b0d2eec9c1b21b061ce2be55f"
 dependencies = [
- "autocfg",
+ "autocfg 1.0.0",
 ]
 
 [[package]]
 name = "miniz_oxide"
-version = "0.5.3"
+version = "0.5.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc"
+checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34"
 dependencies = [
  "adler",
 ]
 
 [[package]]
-name = "nanorand"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3"
+name = "native_implemented"
+version = "0.1.0"
 dependencies = [
- "getrandom 0.2.7",
+ "proc-macro-crate",
+ "proc-macro2",
+ "quote",
+ "syn",
 ]
 
 [[package]]
@@ -1431,18 +1433,18 @@ version = "0.2.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304"
 dependencies = [
- "autocfg",
+ "autocfg 1.0.0",
  "num-integer",
  "num-traits",
 ]
 
 [[package]]
 name = "num-bigint"
-version = "0.4.3"
+version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f"
+checksum = "74e768dff5fb39a41b3bcd30bb25cf989706c90d028d1ad71971987aa309d535"
 dependencies = [
- "autocfg",
+ "autocfg 1.0.0",
  "num-integer",
  "num-traits",
 ]
@@ -1453,27 +1455,27 @@ version = "0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95"
 dependencies = [
- "autocfg",
+ "autocfg 1.0.0",
  "num-traits",
 ]
 
 [[package]]
 name = "num-integer"
-version = "0.1.45"
+version = "0.1.43"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
+checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b"
 dependencies = [
- "autocfg",
+ "autocfg 1.0.0",
  "num-traits",
 ]
 
 [[package]]
 name = "num-iter"
-version = "0.1.43"
+version = "0.1.41"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252"
+checksum = "7a6e6b7c748f995c4c29c5f5ae0248536e04a5739927c74ec0fa564805094b9f"
 dependencies = [
- "autocfg",
+ "autocfg 1.0.0",
  "num-integer",
  "num-traits",
 ]
@@ -1484,7 +1486,7 @@ version = "0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef"
 dependencies = [
- "autocfg",
+ "autocfg 1.0.0",
  "num-bigint 0.2.6",
  "num-integer",
  "num-traits",
@@ -1492,11 +1494,11 @@ dependencies = [
 
 [[package]]
 name = "num-traits"
-version = "0.2.15"
+version = "0.2.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
+checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
 dependencies = [
- "autocfg",
+ "autocfg 1.0.0",
  "libm",
 ]
 
@@ -1527,18 +1529,18 @@ checksum = "074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e"
 
 [[package]]
 name = "os_type"
-version = "2.4.0"
+version = "2.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3df761f6470298359f84fcfb60d86db02acc22c251c37265c07a3d1057d2389"
+checksum = "7edc011af0ae98b7f88cf7e4a83b70a54a75d2b8cb013d6efd02e5956207e9eb"
 dependencies = [
  "regex",
 ]
 
 [[package]]
 name = "output_vt100"
-version = "0.1.3"
+version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "628223faebab4e3e40667ee0b2336d34a5b960ff60ea743ddfdbcf7770bcfb66"
+checksum = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9"
 dependencies = [
  "winapi",
 ]
@@ -1552,65 +1554,85 @@ dependencies = [
  "unwind",
 ]
 
+[[package]]
+name = "panic-control"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "159973aebc43b4640619042b3bf160e3b6348000a949e37c0806ae6acc79d6c7"
+
 [[package]]
 name = "parking_lot"
-version = "0.11.2"
+version = "0.11.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
+checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb"
 dependencies = [
  "instant",
  "lock_api",
- "parking_lot_core 0.8.5",
+ "parking_lot_core 0.8.3",
 ]
 
 [[package]]
 name = "parking_lot"
-version = "0.12.1"
+version = "0.12.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
+checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58"
 dependencies = [
  "lock_api",
- "parking_lot_core 0.9.3",
+ "parking_lot_core 0.9.1",
 ]
 
 [[package]]
 name = "parking_lot_core"
-version = "0.8.5"
+version = "0.7.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216"
+checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3"
+dependencies = [
+ "cfg-if 0.1.10",
+ "cloudabi",
+ "libc",
+ "redox_syscall 0.1.57",
+ "smallvec",
+ "winapi",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018"
 dependencies = [
  "cfg-if 1.0.0",
  "instant",
  "libc",
- "redox_syscall",
+ "redox_syscall 0.2.11",
  "smallvec",
  "winapi",
 ]
 
 [[package]]
 name = "parking_lot_core"
-version = "0.9.3"
+version = "0.9.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929"
+checksum = "28141e0cc4143da2443301914478dc976a61ffdb3f043058310c70df2fed8954"
 dependencies = [
  "cfg-if 1.0.0",
  "libc",
- "redox_syscall",
+ "redox_syscall 0.2.11",
  "smallvec",
- "windows-sys",
+ "windows-sys 0.32.0",
 ]
 
 [[package]]
 name = "paste"
-version = "1.0.8"
+version = "1.0.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9423e2b32f7a043629287a536f21951e8c6a82482d0acb1eeebfc90bc2225b22"
+checksum = "0744126afe1a6dd7f394cb50a716dbe086cb06e255e53d8d0185d82828358fb5"
 
 [[package]]
 name = "petgraph"
-version = "0.6.2"
+version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e6d5014253a1331579ce62aa67443b4a658c5e7dd03d4bc6d302b94474888143"
+checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7"
 dependencies = [
  "fixedbitset",
  "indexmap",
@@ -1618,9 +1640,9 @@ dependencies = [
 
 [[package]]
 name = "phf_shared"
-version = "0.10.0"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096"
+checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7"
 dependencies = [
  "siphasher",
 ]
@@ -1631,31 +1653,11 @@ version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "db8bcd96cb740d03149cbad5518db9fd87126a10ab519c011893b1754134c468"
 
-[[package]]
-name = "pin-project"
-version = "1.0.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc"
-dependencies = [
- "pin-project-internal",
-]
-
-[[package]]
-name = "pin-project-internal"
-version = "1.0.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
 [[package]]
 name = "pin-project-lite"
-version = "0.2.9"
+version = "0.2.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
+checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c"
 
 [[package]]
 name = "pin-utils"
@@ -1665,9 +1667,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
 
 [[package]]
 name = "ppv-lite86"
-version = "0.2.16"
+version = "0.2.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
+checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea"
 
 [[package]]
 name = "precomputed-hash"
@@ -1677,9 +1679,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
 
 [[package]]
 name = "pretty_assertions"
-version = "1.2.1"
+version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c89f989ac94207d048d92db058e4f6ec7342b0971fc58d1271ca148b799b3563"
+checksum = "57c038cb5319b9c704bf9c227c261d275bfec0ad438118a2787ce47944fb228b"
 dependencies = [
  "ansi_term",
  "ctor",
@@ -1687,36 +1689,109 @@ dependencies = [
  "output_vt100",
 ]
 
+[[package]]
+name = "proc-macro-crate"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eda0fc3b0fb7c975631757e14d9049da17374063edb6ebbcbc54d880d4fe94e9"
+dependencies = [
+ "once_cell",
+ "thiserror",
+ "toml",
+]
+
 [[package]]
 name = "proc-macro2"
-version = "1.0.43"
+version = "1.0.36"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab"
+checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
 dependencies = [
- "unicode-ident",
+ "unicode-xid",
 ]
 
+[[package]]
+name = "process_control"
+version = "3.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1cb5bbabc4567bc85bc86d667f7ef1c5060280037269232b248cef94fc7654bd"
+dependencies = [
+ "libc",
+ "signal-hook",
+ "windows-sys 0.36.1",
+]
+
+[[package]]
+name = "proptest"
+version = "0.9.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "01c477819b845fe023d33583ebf10c9f62518c8d79a0960ba5c36d6ac8a55a5b"
+dependencies = [
+ "bit-set",
+ "bitflags",
+ "byteorder",
+ "lazy_static",
+ "num-traits",
+ "quick-error",
+ "rand 0.6.5",
+ "rand_chacha 0.1.1",
+ "rand_xorshift",
+ "regex-syntax",
+ "rusty-fork",
+ "tempfile",
+]
+
+[[package]]
+name = "quick-error"
+version = "1.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
+
 [[package]]
 name = "quote"
-version = "1.0.21"
+version = "1.0.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
+checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
 dependencies = [
  "proc-macro2",
 ]
 
+[[package]]
+name = "radix_fmt"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ce082a9940a7ace2ad4a8b7d0b1eac6aa378895f18be598230c5f2284ac05426"
+
+[[package]]
+name = "rand"
+version = "0.6.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
+dependencies = [
+ "autocfg 0.1.7",
+ "libc",
+ "rand_chacha 0.1.1",
+ "rand_core 0.4.2",
+ "rand_hc 0.1.0",
+ "rand_isaac",
+ "rand_jitter",
+ "rand_os",
+ "rand_pcg 0.1.2",
+ "rand_xorshift",
+ "winapi",
+]
+
 [[package]]
 name = "rand"
 version = "0.7.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
 dependencies = [
- "getrandom 0.1.16",
+ "getrandom 0.1.14",
  "libc",
  "rand_chacha 0.2.2",
  "rand_core 0.5.1",
- "rand_hc",
- "rand_pcg",
+ "rand_hc 0.2.0",
+ "rand_pcg 0.2.1",
 ]
 
 [[package]]
@@ -1730,6 +1805,16 @@ dependencies = [
  "rand_core 0.6.3",
 ]
 
+[[package]]
+name = "rand_chacha"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
+dependencies = [
+ "autocfg 0.1.7",
+ "rand_core 0.3.1",
+]
+
 [[package]]
 name = "rand_chacha"
 version = "0.2.2"
@@ -1750,13 +1835,28 @@ dependencies = [
  "rand_core 0.6.3",
 ]
 
+[[package]]
+name = "rand_core"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
+dependencies = [
+ "rand_core 0.4.2",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
+
 [[package]]
 name = "rand_core"
 version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
 dependencies = [
- "getrandom 0.1.16",
+ "getrandom 0.1.14",
 ]
 
 [[package]]
@@ -1765,7 +1865,16 @@ version = "0.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
 dependencies = [
- "getrandom 0.2.7",
+ "getrandom 0.2.1",
+]
+
+[[package]]
+name = "rand_hc"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
+dependencies = [
+ "rand_core 0.3.1",
 ]
 
 [[package]]
@@ -1777,6 +1886,50 @@ dependencies = [
  "rand_core 0.5.1",
 ]
 
+[[package]]
+name = "rand_isaac"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
+dependencies = [
+ "rand_core 0.3.1",
+]
+
+[[package]]
+name = "rand_jitter"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"
+dependencies = [
+ "libc",
+ "rand_core 0.4.2",
+ "winapi",
+]
+
+[[package]]
+name = "rand_os"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
+dependencies = [
+ "cloudabi",
+ "fuchsia-cprng",
+ "libc",
+ "rand_core 0.4.2",
+ "rdrand",
+ "winapi",
+]
+
+[[package]]
+name = "rand_pcg"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
+dependencies = [
+ "autocfg 0.1.7",
+ "rand_core 0.4.2",
+]
+
 [[package]]
 name = "rand_pcg"
 version = "0.2.1"
@@ -1786,42 +1939,66 @@ dependencies = [
  "rand_core 0.5.1",
 ]
 
+[[package]]
+name = "rand_xorshift"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
+dependencies = [
+ "rand_core 0.3.1",
+]
+
+[[package]]
+name = "rdrand"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
+dependencies = [
+ "rand_core 0.3.1",
+]
+
+[[package]]
+name = "redox_syscall"
+version = "0.1.57"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
+
 [[package]]
 name = "redox_syscall"
-version = "0.2.16"
+version = "0.2.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
+checksum = "8380fe0152551244f0747b1bf41737e0f8a74f97a14ccefd1148187271634f3c"
 dependencies = [
  "bitflags",
 ]
 
 [[package]]
 name = "redox_users"
-version = "0.4.3"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
+checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64"
 dependencies = [
- "getrandom 0.2.7",
- "redox_syscall",
- "thiserror",
+ "getrandom 0.2.1",
+ "redox_syscall 0.2.11",
 ]
 
 [[package]]
 name = "regex"
-version = "1.6.0"
+version = "1.3.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
+checksum = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6"
 dependencies = [
  "aho-corasick",
  "memchr",
  "regex-syntax",
+ "thread_local",
 ]
 
 [[package]]
 name = "regex-syntax"
-version = "0.6.27"
+version = "0.6.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
+checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8"
 
 [[package]]
 name = "remove_dir_all"
@@ -1834,9 +2011,9 @@ dependencies = [
 
 [[package]]
 name = "rle-decode-fast"
-version = "1.0.3"
+version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3582f63211428f83597b51b2ddb88e2a91a9d52d12831f9d08f5e624e8977422"
+checksum = "cabe4fa914dec5870285fa7f71f602645da47c486e68486d2b4ceb4a343e90ac"
 
 [[package]]
 name = "rpds"
@@ -1858,9 +2035,9 @@ dependencies = [
 
 [[package]]
 name = "rustc-demangle"
-version = "0.1.21"
+version = "0.1.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
+checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
 
 [[package]]
 name = "rustc-hash"
@@ -1870,9 +2047,26 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
 
 [[package]]
 name = "rustversion"
-version = "1.0.9"
+version = "1.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8"
+checksum = "b9bdc5e856e51e685846fb6c13a1f5e5432946c2c90501bdc76a1319f19e29da"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "rusty-fork"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3dd93264e10c577503e926bd1430193eeb5d21b059148910082245309b424fae"
+dependencies = [
+ "fnv",
+ "quick-error",
+ "tempfile",
+ "wait-timeout",
+]
 
 [[package]]
 name = "salsa"
@@ -1880,11 +2074,11 @@ version = "0.14.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d4ca1c656054666a642affbbc86ab95ed7541125a89f032483d34ee56c0f5390"
 dependencies = [
- "crossbeam-utils 0.7.2",
+ "crossbeam-utils",
  "indexmap",
  "lock_api",
  "log",
- "parking_lot 0.11.2",
+ "parking_lot 0.11.1",
  "rand 0.7.3",
  "rustc-hash",
  "salsa-macros",
@@ -1920,21 +2114,21 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
 
 [[package]]
 name = "seq-macro"
-version = "0.3.1"
+version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0772c5c30e1a0d91f6834f8e545c69281c099dfa9a3ac58d96a9fd629c8d4898"
+checksum = "70d9841243dbc9928f5fed7946d2862292eebd823d96e13e556924d3db0120d2"
 
 [[package]]
 name = "serde"
-version = "1.0.144"
+version = "1.0.114"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860"
+checksum = "5317f7588f0a5078ee60ef675ef96735a1442132dc645eb1d12c018620ed8cd3"
 
 [[package]]
 name = "serde_derive"
-version = "1.0.144"
+version = "1.0.114"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00"
+checksum = "2a0be94b04690fbaed37cddffc5c134bf537c8e3329d53e982fe04c374978f8e"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1943,9 +2137,9 @@ dependencies = [
 
 [[package]]
 name = "signal-hook"
-version = "0.3.14"
+version = "0.3.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a253b5e89e2698464fc26b545c9edceb338e18a89effeeecfea192c3025be29d"
+checksum = "647c97df271007dcea485bb74ffdb57f2e683f1306c854f468a0c244badabf2d"
 dependencies = [
  "libc",
  "signal-hook-registry",
@@ -1962,18 +2156,15 @@ dependencies = [
 
 [[package]]
 name = "siphasher"
-version = "0.3.10"
+version = "0.3.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de"
+checksum = "533494a8f9b724d33625ab53c6c4800f7cc445895924a8ef649222dcb76e938b"
 
 [[package]]
 name = "slab"
-version = "0.4.7"
+version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef"
-dependencies = [
- "autocfg",
-]
+checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
 
 [[package]]
 name = "smallvec"
@@ -1987,21 +2178,12 @@ version = "0.5.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
 
-[[package]]
-name = "spin"
-version = "0.9.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09"
-dependencies = [
- "lock_api",
-]
-
 [[package]]
 name = "stackmaps"
 version = "0.1.0"
 dependencies = [
  "cfg-if 0.1.10",
- "hashbrown 0.8.2",
+ "hashbrown 0.8.1",
  "lazy_static",
 ]
 
@@ -2013,17 +2195,26 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
 
 [[package]]
 name = "string_cache"
-version = "0.8.4"
+version = "0.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "213494b7a2b503146286049378ce02b482200519accc31872ee8be91fa820a08"
+checksum = "923f0f39b6267d37d23ce71ae7235602134b250ace715dd2c90421998ddac0c6"
 dependencies = [
+ "lazy_static",
  "new_debug_unreachable",
- "once_cell",
- "parking_lot 0.12.1",
+ "parking_lot 0.11.1",
  "phf_shared",
  "precomputed-hash",
 ]
 
+[[package]]
+name = "strip-ansi-escapes"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "011cbb39cf7c1f62871aea3cc46e5817b0937b49e9447370c93cacbe93a766d8"
+dependencies = [
+ "vte",
+]
+
 [[package]]
 name = "strsim"
 version = "0.8.0"
@@ -2038,20 +2229,20 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
 
 [[package]]
 name = "syn"
-version = "1.0.99"
+version = "1.0.88"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13"
+checksum = "ebd69e719f31e88618baa1eaa6ee2de5c9a1c004f1e9ecdb58e8352a13f20a01"
 dependencies = [
  "proc-macro2",
  "quote",
- "unicode-ident",
+ "unicode-xid",
 ]
 
 [[package]]
 name = "synstructure"
-version = "0.12.6"
+version = "0.12.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
+checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -2074,7 +2265,7 @@ dependencies = [
  "cfg-if 1.0.0",
  "fastrand",
  "libc",
- "redox_syscall",
+ "redox_syscall 0.2.11",
  "remove_dir_all",
  "winapi",
 ]
@@ -2110,24 +2301,53 @@ dependencies = [
 
 [[package]]
 name = "thiserror"
-version = "1.0.32"
+version = "1.0.30"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f5f6586b7f764adc0231f4c79be7b920e766bb2f3e51b3661cdb263828f19994"
+checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417"
 dependencies = [
  "thiserror-impl",
 ]
 
 [[package]]
 name = "thiserror-impl"
-version = "1.0.32"
+version = "1.0.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "thiserror-impl-no-std"
+version = "2.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "12bafc5b54507e0149cdf1b145a5d80ab80a90bcd9275df43d4fff68460f6c21"
+checksum = "58e6318948b519ba6dc2b442a6d0b904ebfb8d411a3ad3e07843615a72249758"
 dependencies = [
  "proc-macro2",
  "quote",
  "syn",
 ]
 
+[[package]]
+name = "thiserror-no-std"
+version = "2.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a3ad459d94dd517257cc96add8a43190ee620011bb6e6cdc82dafd97dfafafea"
+dependencies = [
+ "thiserror-impl-no-std",
+]
+
+[[package]]
+name = "thread_local"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
+dependencies = [
+ "lazy_static",
+]
+
 [[package]]
 name = "tiny-keccak"
 version = "2.0.2"
@@ -2139,37 +2359,31 @@ dependencies = [
 
 [[package]]
 name = "toml"
-version = "0.5.9"
+version = "0.5.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7"
+checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a"
 dependencies = [
  "indexmap",
  "serde",
 ]
 
-[[package]]
-name = "unicode-ident"
-version = "1.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf"
-
 [[package]]
 name = "unicode-segmentation"
-version = "1.9.0"
+version = "1.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99"
+checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
 
 [[package]]
 name = "unicode-width"
-version = "0.1.9"
+version = "0.1.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
+checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
 
 [[package]]
 name = "unicode-xid"
-version = "0.2.3"
+version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04"
+checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
 
 [[package]]
 name = "unwind"
@@ -2180,13 +2394,25 @@ dependencies = [
  "libc",
 ]
 
+[[package]]
+name = "utf8-ranges"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4ae116fef2b7fea257ed6440d3cfcff7f190865f170cdad00bb6465bf18ecba"
+
+[[package]]
+name = "utf8parse"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "936e4b492acfd135421d8dca4b1aa80a7bfc26e702ef3af710e0752684df5372"
+
 [[package]]
 name = "uuid"
-version = "0.8.2"
+version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
+checksum = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11"
 dependencies = [
- "getrandom 0.2.7",
+ "rand 0.7.3",
 ]
 
 [[package]]
@@ -2201,11 +2427,41 @@ version = "0.9.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
 
+[[package]]
+name = "vte"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6cbce692ab4ca2f1f3047fcf732430249c0e971bfdd2b234cf2c47ad93af5983"
+dependencies = [
+ "arrayvec",
+ "utf8parse",
+ "vte_generate_state_changes",
+]
+
+[[package]]
+name = "vte_generate_state_changes"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d257817081c7dffcdbab24b9e62d2def62e2ff7d00b1c20062551e6cccc145ff"
+dependencies = [
+ "proc-macro2",
+ "quote",
+]
+
+[[package]]
+name = "wait-timeout"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6"
+dependencies = [
+ "libc",
+]
+
 [[package]]
 name = "walkdir"
-version = "2.3.2"
+version = "2.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
+checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d"
 dependencies = [
  "same-file",
  "winapi",
@@ -2220,9 +2476,9 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
 
 [[package]]
 name = "wasi"
-version = "0.11.0+wasi-snapshot-preview1"
+version = "0.10.1+wasi-snapshot-preview1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+checksum = "93c6c3420963c5c64bca373b25e77acb562081b9bb4dd5bb864187742186cea9"
 
 [[package]]
 name = "wasm-bindgen"
@@ -2278,15 +2534,24 @@ version = "0.2.82"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a"
 
+[[package]]
+name = "web-sys"
+version = "0.3.59"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed055ab27f941423197eb86b2035720b1a3ce40504df082cac2ecc6ed73335a1"
+dependencies = [
+ "js-sys",
+ "wasm-bindgen",
+]
+
 [[package]]
 name = "which"
-version = "4.2.5"
+version = "4.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae"
+checksum = "87c14ef7e1b8b8ecfc75d5eca37949410046e66f15d185c01d70824f1f8111ef"
 dependencies = [
- "either",
- "lazy_static",
  "libc",
+ "thiserror",
 ]
 
 [[package]]
@@ -2320,43 +2585,86 @@ version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 
+[[package]]
+name = "windows-sys"
+version = "0.32.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3df6e476185f92a12c072be4a189a0210dcdcf512a1891d6dff9edb874deadc6"
+dependencies = [
+ "windows_aarch64_msvc 0.32.0",
+ "windows_i686_gnu 0.32.0",
+ "windows_i686_msvc 0.32.0",
+ "windows_x86_64_gnu 0.32.0",
+ "windows_x86_64_msvc 0.32.0",
+]
+
 [[package]]
 name = "windows-sys"
 version = "0.36.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
 dependencies = [
- "windows_aarch64_msvc",
- "windows_i686_gnu",
- "windows_i686_msvc",
- "windows_x86_64_gnu",
- "windows_x86_64_msvc",
+ "windows_aarch64_msvc 0.36.1",
+ "windows_i686_gnu 0.36.1",
+ "windows_i686_msvc 0.36.1",
+ "windows_x86_64_gnu 0.36.1",
+ "windows_x86_64_msvc 0.36.1",
 ]
 
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.32.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8e92753b1c443191654ec532f14c199742964a061be25d77d7a96f09db20bf5"
+
 [[package]]
 name = "windows_aarch64_msvc"
 version = "0.36.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
 
+[[package]]
+name = "windows_i686_gnu"
+version = "0.32.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a711c68811799e017b6038e0922cb27a5e2f43a2ddb609fe0b6f3eeda9de615"
+
 [[package]]
 name = "windows_i686_gnu"
 version = "0.36.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
 
+[[package]]
+name = "windows_i686_msvc"
+version = "0.32.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "146c11bb1a02615db74680b32a68e2d61f553cc24c4eb5b4ca10311740e44172"
+
 [[package]]
 name = "windows_i686_msvc"
 version = "0.36.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
 
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.32.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c912b12f7454c6620635bbff3450962753834be2a594819bd5e945af18ec64bc"
+
 [[package]]
 name = "windows_x86_64_gnu"
 version = "0.36.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
 
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.32.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "504a2476202769977a040c6364301a3f65d0cc9e3fb08600b2bda150a0488316"
+
 [[package]]
 name = "windows_x86_64_msvc"
 version = "0.36.1"
diff --git a/Cargo.toml b/Cargo.toml
index 23e87a584..6b006a673 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,14 +1,15 @@
 [workspace]
 
-members = [ 
-  "compiler/*", 
-  "firefly", 
+members = [
+  "compiler/*",
+  "firefly",
   "library/*",
+  "native_implemented/otp",
   "runtimes/*",
 ]
 
-default-members = [ 
-  "firefly" 
+default-members = [
+  "firefly"
 ]
 
 exclude = [
diff --git a/compiler/codegen/build.rs b/compiler/codegen/build.rs
index 5e9d79d6e..6c1331d31 100644
--- a/compiler/codegen/build.rs
+++ b/compiler/codegen/build.rs
@@ -65,7 +65,8 @@ fn main() {
         .arg(&libstd_rlib)
         .stdout(Stdio::piped());
     let symbols = output(nm_cmd);
-    // Find the first line containing the mangled symbol for std::rt::lang_start_internal, and postprocess it
+    // Find the first line containing the mangled symbol for std::rt::lang_start_internal, and
+    // postprocess it
     let lang_start_symbol = symbols
         .lines()
         .map(|line| line.trim())
diff --git a/compiler/codegen/src/linker/mod.rs b/compiler/codegen/src/linker/mod.rs
index b5a7991ce..07e02c8e6 100644
--- a/compiler/codegen/src/linker/mod.rs
+++ b/compiler/codegen/src/linker/mod.rs
@@ -308,7 +308,8 @@ impl<'a> GccLinker<'a> {
             arg.push(plugin_path);
             self.linker_arg(&arg);
         }
-        // NOTE: We previously short-circuit returned if no plugin path was set due to an error from the linker
+        // NOTE: We previously short-circuit returned if no plugin path was set due to an error from
+        // the linker
 
         let opt_level = match self.options.opt_level {
             OptLevel::No => "O0",
diff --git a/compiler/codegen/src/passes/ssa_to_mlir/builder/function.rs b/compiler/codegen/src/passes/ssa_to_mlir/builder/function.rs
index bbda3e2f0..808ccc132 100644
--- a/compiler/codegen/src/passes/ssa_to_mlir/builder/function.rs
+++ b/compiler/codegen/src/passes/ssa_to_mlir/builder/function.rs
@@ -1387,8 +1387,9 @@ impl<'m> ModuleBuilder<'m> {
                     .base()
             }
             Opcode::EnterIndirect => {
-                // This is an indirect call, not in tail position, but the callee is known statically
-                // to be a fun, so we can skip the overhead of erlang:apply/3
+                // This is an indirect call, not in tail position, but the callee is known
+                // statically to be a fun, so we can skip the overhead of
+                // erlang:apply/3
                 let mlir_op = builder.build_enter_indirect(loc, callee, mapped_args.as_slice());
                 mlir_op.set_attribute_by_name("tail", builder.get_unit_attr());
                 mlir_op.set_attribute_by_name("musttail", builder.get_unit_attr());
diff --git a/compiler/codegen/src/passes/ssa_to_mlir/builder/mod.rs b/compiler/codegen/src/passes/ssa_to_mlir/builder/mod.rs
index f0f2ce05a..4d597d83d 100644
--- a/compiler/codegen/src/passes/ssa_to_mlir/builder/mod.rs
+++ b/compiler/codegen/src/passes/ssa_to_mlir/builder/mod.rs
@@ -90,13 +90,15 @@ impl<'m> ModuleBuilder<'m> {
             current_block: mlir::Block::default(),
             atoms,
             symbols: HashSet::new(),
-            // For both of these maps, we know that most functions will contain a fair number of blocks
-            // and values, so we allocate enough capacity to accomodate the size of small/medium functions
-            // (probably, this is estimated). Benchmarking in the future should be used to dial this in.
+            // For both of these maps, we know that most functions will contain a fair number of
+            // blocks and values, so we allocate enough capacity to accomodate the size
+            // of small/medium functions (probably, this is estimated). Benchmarking in
+            // the future should be used to dial this in.
             //
-            // NOTE: The size of the keys in these maps is u32, and the values are usize, and there may be
-            // some additional overhead for each map entry, so we should try and pick sizes that will result
-            // in power-of-two sizes for the allocator to make the most of the allocations
+            // NOTE: The size of the keys in these maps is u32, and the values are usize, and there
+            // may be some additional overhead for each map entry, so we should try and
+            // pick sizes that will result in power-of-two sizes for the allocator to
+            // make the most of the allocations
             blocks: HashMap::with_capacity(64),
             values: HashMap::with_capacity(64),
         }
@@ -211,7 +213,8 @@ impl<'m> ModuleBuilder<'m> {
                         .get_flat_symbol_ref_attr_by_name("firefly_eh_personality"),
                 );
                 //TODO: Need to re-enable when garbage collector lowering is implemented
-                //func.set_attribute_by_name("garbageCollector", self.builder.get_string_attr("erlang"));
+                //func.set_attribute_by_name("garbageCollector",
+                // self.builder.get_string_attr("erlang"));
             }
 
             // Register with the dispatch table for this module if public
diff --git a/compiler/diagnostics/src/filename.rs b/compiler/diagnostics/src/filename.rs
index 0aabad615..110dba2fe 100644
--- a/compiler/diagnostics/src/filename.rs
+++ b/compiler/diagnostics/src/filename.rs
@@ -103,8 +103,9 @@ impl FileName {
 
     /// Tries to return this filename as a `&str`, avoiding any allocations
     ///
-    /// This will only return None if the filename is a path which requires lossy conversion to unicode.
-    /// See `to_string` if you want an infallible conversion to a Rust string, albeit at the cost of an allocation
+    /// This will only return None if the filename is a path which requires lossy conversion to
+    /// unicode. See `to_string` if you want an infallible conversion to a Rust string, albeit
+    /// at the cost of an allocation
     pub fn as_str(&self) -> Option<&str> {
         match self {
             FileName::Real(ref path) => path.to_str(),
diff --git a/compiler/driver/src/lib.rs b/compiler/driver/src/lib.rs
index f3c28ef2f..427aff88c 100644
--- a/compiler/driver/src/lib.rs
+++ b/compiler/driver/src/lib.rs
@@ -25,14 +25,16 @@ pub const FIREFLY_COMMIT_DATE: &'static str = env!("FIREFLY_COMMIT_DATE");
 
 /// Runs the compiler using the provided working directory, args iterator, and default emitter
 ///
-/// Returns the exit code for the compiler if successful (in some cases it is non-zero), otherwise an error
+/// Returns the exit code for the compiler if successful (in some cases it is non-zero), otherwise
+/// an error
 pub fn run_compiler(cwd: PathBuf, args: impl Iterator<Item = OsString>) -> anyhow::Result<i32> {
     run_compiler_with_emitter(cwd, args, None)
 }
 
 /// Runs the compiler using the provided working directory, args iterator, and emittter
 ///
-/// Returns the exit code for the compiler if successful (in some cases it is non-zero), otherwise an error
+/// Returns the exit code for the compiler if successful (in some cases it is non-zero), otherwise
+/// an error
 pub fn run_compiler_with_emitter(
     cwd: PathBuf,
     args: impl Iterator<Item = OsString>,
diff --git a/compiler/driver/src/parser/query_groups.rs b/compiler/driver/src/parser/query_groups.rs
index 91fb82328..434f881be 100644
--- a/compiler/driver/src/parser/query_groups.rs
+++ b/compiler/driver/src/parser/query_groups.rs
@@ -95,7 +95,8 @@ pub trait Parser: CompilerOutput {
     /// If the input is a .mlir file, this will parse directly to an mlir module, otherwise,
     /// higher-level sources (i.e. .erl/.core) will be parsed and then lowered to mlir.
     ///
-    /// If an error occurred during parsing or lowering of the module, the result will be Err(ErrorReported).
+    /// If an error occurred during parsing or lowering of the module, the result will be
+    /// Err(ErrorReported).
     #[salsa::invoke(queries::input_mlir)]
     fn input_mlir(
         &self,
diff --git a/compiler/llvm/src/builder.rs b/compiler/llvm/src/builder.rs
index 5253b6fad..8b885d460 100644
--- a/compiler/llvm/src/builder.rs
+++ b/compiler/llvm/src/builder.rs
@@ -242,7 +242,7 @@ impl<'ctx> ModuleBuilder<'ctx> {
     pub fn get_struct_type(&self, name: Option<&str>, field_types: &[TypeBase]) -> StructType {
         if let Some(name) = name {
             self.context
-                .get_named_struct_type(name, field_types, /*packed=*/ false)
+                .get_named_struct_type(name, field_types, /* packed= */ false)
         } else {
             self.context.get_struct_type(field_types)
         }
@@ -253,7 +253,8 @@ impl<'ctx> ModuleBuilder<'ctx> {
         PointerType::new(ty, 0)
     }
 
-    /// Returns a type corresponding to a function with the given return value and argument types, optionally variadic
+    /// Returns a type corresponding to a function with the given return value and argument types,
+    /// optionally variadic
     pub fn get_function_type<T: Type>(
         &self,
         ret: T,
@@ -263,7 +264,8 @@ impl<'ctx> ModuleBuilder<'ctx> {
         FunctionType::new(ret, params, variadic)
     }
 
-    /// A helper function which returns a function type consisting of all terms, with the given number of arguments
+    /// A helper function which returns a function type consisting of all terms, with the given
+    /// number of arguments
     pub fn get_erlang_function_type(&self, arity: u8) -> FunctionType {
         let term_type = self.get_term_type().base();
         let arity = arity as usize;
@@ -303,7 +305,8 @@ impl<'ctx> ModuleBuilder<'ctx> {
         unsafe { LLVMSetCurrentDebugLocation2(*self.builder, loc) }
     }
 
-    /// Sets the debug location for the given instruction using the builder's current debug location metadata
+    /// Sets the debug location for the given instruction using the builder's current debug location
+    /// metadata
     pub fn set_debug_location<I: Instruction>(&self, inst: I) {
         extern "C" {
             fn LLVMSetInstDebugLocation(builder: Builder, inst: ValueBase);
@@ -448,11 +451,11 @@ impl<'ctx> ModuleBuilder<'ctx> {
     }
 
     pub fn build_constant_int(&self, ty: IntegerType, value: i64) -> ConstantInt {
-        ConstantInt::get(ty, value as u64, /*sext=*/ true)
+        ConstantInt::get(ty, value as u64, /* sext= */ true)
     }
 
     pub fn build_constant_uint(&self, ty: IntegerType, value: u64) -> ConstantInt {
-        ConstantInt::get(ty, value, /*sext=*/ false)
+        ConstantInt::get(ty, value, /* sext= */ false)
     }
 
     pub fn build_constant_array<T: Type>(&self, ty: T, values: &[ConstantValue]) -> ConstantArray {
@@ -505,7 +508,7 @@ impl<'ctx> ModuleBuilder<'ctx> {
         index: u64,
     ) -> ConstantExpr {
         let index_ty = self.context.get_i32_type();
-        let index = ConstantInt::get(index_ty, index, /*sext=*/ false);
+        let index = ConstantInt::get(index_ty, index, /* sext= */ false);
         ConstantExpr::extract_value(agg, &[index.into()])
     }
 
@@ -652,7 +655,7 @@ impl<'ctx> ModuleBuilder<'ctx> {
         }
 
         unsafe {
-            LLVMBuildSwitch(*self.builder, value, default, /*hint=*/ 10)
+            LLVMBuildSwitch(*self.builder, value, default, /* hint= */ 10)
         }
     }
 
@@ -687,7 +690,8 @@ impl<'ctx> ModuleBuilder<'ctx> {
 
     /// Builds a call instruction with a callee value that may or may not be a function reference
     ///
-    /// The primary difference with `build_invoke` is that this requires providing the type of the callee
+    /// The primary difference with `build_invoke` is that this requires providing the type of the
+    /// callee
     pub fn build_call_indirect(
         &self,
         callee: ValueBase,
@@ -741,7 +745,8 @@ impl<'ctx> ModuleBuilder<'ctx> {
 
     /// Builds an invoke instruction with a callee value that may or may not be a function reference
     ///
-    /// The primary difference with `build_invoke` is that this requires providing the type of the callee
+    /// The primary difference with `build_invoke` is that this requires providing the type of the
+    /// callee
     pub fn build_invoke_indirect(
         &self,
         callee: ValueBase,
@@ -814,9 +819,9 @@ impl<'ctx> ModuleBuilder<'ctx> {
     }
 
     /// When inserted at the beginning of a block, it marks the block as a catch or cleanup handler
-    /// for a matching `invoke` instruction. When the callee of an invoke unwinds, the landingpad, if
-    /// matching, will be visited. Unwinding can be resumed via `resume` from within a landingpad or its
-    /// successor blocks.
+    /// for a matching `invoke` instruction. When the callee of an invoke unwinds, the landingpad,
+    /// if matching, will be visited. Unwinding can be resumed via `resume` from within a
+    /// landingpad or its successor blocks.
     ///
     /// NOTE: This instruction _must_ be the first instruction in its containing block
     ///
@@ -837,21 +842,21 @@ impl<'ctx> ModuleBuilder<'ctx> {
                 *self.builder,
                 ty.base(),
                 ValueBase::null(),
-                /*hint=*/ 2,
+                /* hint= */ 2,
                 UNNAMED,
             )
         }
     }
 
-    /// When inserted at the beginning of a block, it marks the block as a landing pad for the unwinder
-    /// It acts as the dispatcher across one or more catch handlers, and like invoke, can indicate what
-    /// to do if the handler unwinds.
+    /// When inserted at the beginning of a block, it marks the block as a landing pad for the
+    /// unwinder It acts as the dispatcher across one or more catch handlers, and like invoke,
+    /// can indicate what to do if the handler unwinds.
     ///
     /// NOTE: This instruction _must_ be the first instruction in its containing block
     ///
     /// This is part of the set of new exception handling instructions, and are generic across MSVC
-    /// structured exception handling and Itanium C++ exceptions. It is a strict superset of the older
-    /// instruction set.
+    /// structured exception handling and Itanium C++ exceptions. It is a strict superset of the
+    /// older instruction set.
     pub fn build_catchswitch(
         &self,
         parent: Option<&Funclet>,
@@ -870,15 +875,16 @@ impl<'ctx> ModuleBuilder<'ctx> {
         let unwind = unwind.unwrap_or_else(Block::null);
         let parent = parent.map(|f| f.pad()).unwrap_or_else(ValueBase::null);
         unsafe {
-            LLVMBuildCatchSwitch(*self.builder, parent, unwind, /*hint=*/ 5, UNNAMED)
+            LLVMBuildCatchSwitch(*self.builder, parent, unwind, /* hint= */ 5, UNNAMED)
         }
     }
 
-    /// Like `landingpad`, this instruction indicates that its containing block is a catch handler for
-    /// a corresponding `catchswitch` instruction. A catchpad will not be visited unless the in-flight
-    /// exception matches the given arguments. The arguments correspond to whatever information the
-    /// personality routine requires to know if this is an appropriate handler for the exception. In
-    /// practice this tends to be a pointer to a global containing a tag string, e.g. `i8** @_ZTIi`.
+    /// Like `landingpad`, this instruction indicates that its containing block is a catch handler
+    /// for a corresponding `catchswitch` instruction. A catchpad will not be visited unless the
+    /// in-flight exception matches the given arguments. The arguments correspond to whatever
+    /// information the personality routine requires to know if this is an appropriate handler
+    /// for the exception. In practice this tends to be a pointer to a global containing a tag
+    /// string, e.g. `i8** @_ZTIi`.
     ///
     /// Control must exit a catchpad via a `catchret`, it must not resume normal execution, unwind,
     /// or return using `ret`, or the behavior is undefined.
@@ -902,15 +908,16 @@ impl<'ctx> ModuleBuilder<'ctx> {
         unsafe { LLVMBuildCatchPad(*self.builder, catchswitch.base(), argv, argc, UNNAMED) }
     }
 
-    /// Similar to `catchpad`, except it is used for the cleanup phase of the unwinder, i.e. it doesn't
-    /// resume normal execution, but instead performs some cleanup action and then resumes the unwinder.
+    /// Similar to `catchpad`, except it is used for the cleanup phase of the unwinder, i.e. it
+    /// doesn't resume normal execution, but instead performs some cleanup action and then
+    /// resumes the unwinder.
     ///
-    /// Unlike `catchpad` however, `cleanuppad` doesn't require a `catchswitch` as its parent, as it can
-    /// occur in the unwind destination for an invoke directly in cases where the exception isn't handled
-    /// but cleanup is required.
+    /// Unlike `catchpad` however, `cleanuppad` doesn't require a `catchswitch` as its parent, as it
+    /// can occur in the unwind destination for an invoke directly in cases where the exception
+    /// isn't handled but cleanup is required.
     ///
-    /// Control must exit a cleanuppad via a `cleanupret`, it must not unwind or return using `ret`, or
-    /// the behavior is undefined.
+    /// Control must exit a cleanuppad via a `cleanupret`, it must not unwind or return using `ret`,
+    /// or the behavior is undefined.
     ///
     /// NOTE: This instruction _must_ be the first instruction in its containing block
     ///
@@ -1018,7 +1025,8 @@ impl<'ctx> ModuleBuilder<'ctx> {
         }
     }
 
-    // TODO: It would be nice if we could make this more type safe and limit the value to one implementing Pointer
+    // TODO: It would be nice if we could make this more type safe and limit the value to one
+    // implementing Pointer
     pub fn build_load<V: Value, T: Type>(&self, ty: T, ptr: V) -> LoadInst {
         extern "C" {
             fn LLVMBuildLoad2(
@@ -1032,7 +1040,8 @@ impl<'ctx> ModuleBuilder<'ctx> {
         unsafe { LLVMBuildLoad2(*self.builder, ty.base(), ptr.base(), UNNAMED) }
     }
 
-    // TODO: It would be nice if we could make this more type safe and limit the pointer value to one implementing Pointer
+    // TODO: It would be nice if we could make this more type safe and limit the pointer value to
+    // one implementing Pointer
     pub fn build_store<P: Value, V: Value>(&self, ptr: P, value: V) -> StoreInst {
         extern "C" {
             fn LLVMBuildStore(builder: Builder, value: ValueBase, ptr: ValueBase) -> StoreInst;
@@ -1040,7 +1049,8 @@ impl<'ctx> ModuleBuilder<'ctx> {
         unsafe { LLVMBuildStore(*self.builder, value.base(), ptr.base()) }
     }
 
-    /// Given a pointer to a struct of the given type, produces a value which is a pointer to the `n`th field of the struct
+    /// Given a pointer to a struct of the given type, produces a value which is a pointer to the
+    /// `n`th field of the struct
     pub fn build_struct_gep<P: Value>(&self, ty: StructType, ptr: P, n: usize) -> ValueBase {
         extern "C" {
             fn LLVMBuildStructGEP2(
@@ -1054,21 +1064,24 @@ impl<'ctx> ModuleBuilder<'ctx> {
         }
 
         let index_ty = self.get_i32_type();
-        let indices = &[ConstantInt::get(index_ty, n as u64, /*sext=*/ false).base()];
+        let indices = &[ConstantInt::get(index_ty, n as u64, /* sext= */ false).base()];
         unsafe { LLVMBuildStructGEP2(*self.builder, ty, ptr.base(), indices.as_ptr(), 1, UNNAMED) }
     }
 
-    /// Builds a `getelementptr` instruction that will produce a poison value if any of the following
-    /// constraints are violated:
+    /// Builds a `getelementptr` instruction that will produce a poison value if any of the
+    /// following constraints are violated:
     ///
     /// * The base pointer is an address within the memory bounds of an allocated object
-    /// * If the index value must be truncated due to being a larger type, the signed value must be preserved
+    /// * If the index value must be truncated due to being a larger type, the signed value must be
+    ///   preserved
     /// * Multiplication of the index by the type size does not wrap (in the signed sense, e.g. nsw)
     /// * The successive addition of offsets (without adding the base address) does not wrap
-    /// * The successive addition of the current address (interpreted as an unsigned number) and an offset,
-    /// interpreted as a signed number, does not wrap the unsigned address space, and remains in bounds of the
-    /// allocated object
-    /// * In cases where the base is a vector of pointers, these rules apply to each of the computations element-wise
+    /// * The successive addition of the current address (interpreted as an unsigned number) and an
+    ///   offset,
+    /// interpreted as a signed number, does not wrap the unsigned address space, and remains in
+    /// bounds of the allocated object
+    /// * In cases where the base is a vector of pointers, these rules apply to each of the
+    ///   computations element-wise
     pub fn build_inbounds_gep<V: Value, T: Type>(
         &self,
         ty: T,
@@ -1163,7 +1176,8 @@ impl<'ctx> ModuleBuilder<'ctx> {
         }
     }
 
-    /// Gets a reference to a global variable with the given name, _if_ it has a definition, otherwise returns None
+    /// Gets a reference to a global variable with the given name, _if_ it has a definition,
+    /// otherwise returns None
     pub fn get_defined_value<S: Into<StringRef>>(&self, name: S) -> Option<GlobalVariable> {
         self.module
             .get_global(name)
diff --git a/compiler/llvm/src/debuginfo.rs b/compiler/llvm/src/debuginfo.rs
index 1490c49ae..9f99f2070 100644
--- a/compiler/llvm/src/debuginfo.rs
+++ b/compiler/llvm/src/debuginfo.rs
@@ -292,7 +292,8 @@ impl<'m> DebugInfoBuilder<'m> {
         }
     }
 
-    /// Construct a builder for the given module, and do not allow for unresolved nodes attached to the module
+    /// Construct a builder for the given module, and do not allow for unresolved nodes attached to
+    /// the module
     pub fn new_strict(module: &'m mut OwnedModule, options: &Options) -> Self {
         extern "C" {
             fn LLVMCreateDIBuilderDisallowUnresolved(module: Module) -> *const LlvmDiBuilder;
diff --git a/compiler/llvm/src/ir/attributes.rs b/compiler/llvm/src/ir/attributes.rs
index f62e4fbcc..b778634fb 100644
--- a/compiler/llvm/src/ir/attributes.rs
+++ b/compiler/llvm/src/ir/attributes.rs
@@ -257,11 +257,15 @@ impl EnumAttribute {
     /// The value is optional for most enum attributes, but a handful accept or require a value:
     ///
     /// * alignment (indicates that the pointer or vector of pointers has the specified alignment)
-    /// * allocsize (indicates the annotated function will always return at least the given number of bytes or null)
-    /// * dereferenceable (indicates that the parameter/return pointer is dereferenceable with the given number of bytes)
-    /// * dereferenceable_or_null (indicates the parameter/return pointer is either null or dereferenceable to N bytes)
+    /// * allocsize (indicates the annotated function will always return at least the given number
+    ///   of bytes or null)
+    /// * dereferenceable (indicates that the parameter/return pointer is dereferenceable with the
+    ///   given number of bytes)
+    /// * dereferenceable_or_null (indicates the parameter/return pointer is either null or
+    ///   dereferenceable to N bytes)
     /// * alignstack (specifies the desired alignment, power of two)
-    /// * uwtable (if value is given, specifies what kind of unwind tables to generate, 1 = sync/normal, 2 = async/instruction precise)
+    /// * uwtable (if value is given, specifies what kind of unwind tables to generate, 1 =
+    ///   sync/normal, 2 = async/instruction precise)
     /// * vscale_range (the minimum vscale value for the given function, must be greater than 0)
     pub fn new(context: Context, kind: AttributeKind, value: Option<u64>) -> Self {
         extern "C" {
@@ -306,7 +310,8 @@ impl EnumAttribute {
     }
 }
 
-/// Represents an known attribute defined in LLVM's attribute kind enumeration that has a type parameter
+/// Represents an known attribute defined in LLVM's attribute kind enumeration that has a type
+/// parameter
 #[repr(transparent)]
 #[derive(Copy, Clone)]
 pub struct TypeAttribute(AttributeBase);
diff --git a/compiler/llvm/src/ir/instructions.rs b/compiler/llvm/src/ir/instructions.rs
index a1e64064b..422c7c0b6 100644
--- a/compiler/llvm/src/ir/instructions.rs
+++ b/compiler/llvm/src/ir/instructions.rs
@@ -609,7 +609,8 @@ impl TryFrom<ValueBase> for CatchPadInst {
     }
 }
 
-/// Represents the SEH exception handling intrinsic for setting up a basic block as a cleanup handler
+/// Represents the SEH exception handling intrinsic for setting up a basic block as a cleanup
+/// handler
 #[repr(transparent)]
 #[derive(Copy)]
 pub struct CleanupPadInst(ValueBase);
diff --git a/compiler/llvm/src/ir/module.rs b/compiler/llvm/src/ir/module.rs
index 09ebf0d0a..6dd1c5a68 100644
--- a/compiler/llvm/src/ir/module.rs
+++ b/compiler/llvm/src/ir/module.rs
@@ -316,7 +316,8 @@ impl Module {
     }
 
     pub fn verify(self) -> anyhow::Result<()> {
-        // 0 = print to stderr + abort, 1 = print to stderr + return true, 2 = no output, return true
+        // 0 = print to stderr + abort, 1 = print to stderr + return true, 2 = no output, return
+        // true
         const ON_VERIFY_FAILED_RETURN_STATUS: u32 = 2;
 
         extern "C" {
@@ -410,7 +411,8 @@ impl Module {
         }
     }
 
-    /// Generate textual target-specific assembly from this module using the given TargetMachine, writing it to the given file
+    /// Generate textual target-specific assembly from this module using the given TargetMachine,
+    /// writing it to the given file
     ///
     /// The assembly generated by this function is generally written to files with a `.s` extension.
     pub fn emit_asm(
diff --git a/compiler/llvm/src/ir/value.rs b/compiler/llvm/src/ir/value.rs
index 76b0f6fce..27cdc6184 100644
--- a/compiler/llvm/src/ir/value.rs
+++ b/compiler/llvm/src/ir/value.rs
@@ -40,7 +40,8 @@ pub enum ValueKind {
 
 /// This trait is meant to represent the llvm::Value class
 ///
-/// In LLVM, most things inherit from llvm::Value at some point, so this provides a lot of shared functionality
+/// In LLVM, most things inherit from llvm::Value at some point, so this provides a lot of shared
+/// functionality
 pub trait Value {
     /// Get the string name of this value
     fn name(&self) -> StringRef {
@@ -202,7 +203,8 @@ impl fmt::Display for ValueBase {
     }
 }
 
-/// Represents a value of aggregate type (i.e. struct or array, vectors are not considered aggregates)
+/// Represents a value of aggregate type (i.e. struct or array, vectors are not considered
+/// aggregates)
 pub trait Aggregate: Value {}
 
 /// Represents a value of pointer type
diff --git a/compiler/llvm/src/lib.rs b/compiler/llvm/src/lib.rs
index ed17ce956..62fd6ba60 100644
--- a/compiler/llvm/src/lib.rs
+++ b/compiler/llvm/src/lib.rs
@@ -38,7 +38,13 @@ pub fn version() -> String {
         fn LLVMFireflyVersionMinor() -> u32;
     }
 
-    unsafe { format!("{}.{}", LLVMFireflyVersionMajor(), LLVMFireflyVersionMinor()) }
+    unsafe {
+        format!(
+            "{}.{}",
+            LLVMFireflyVersionMajor(),
+            LLVMFireflyVersionMinor()
+        )
+    }
 }
 
 /// Performs one-time initialization of LLVM
diff --git a/compiler/llvm/src/support/memory.rs b/compiler/llvm/src/support/memory.rs
index 75038a298..7fa37688f 100644
--- a/compiler/llvm/src/support/memory.rs
+++ b/compiler/llvm/src/support/memory.rs
@@ -59,7 +59,8 @@ impl fmt::Pointer for Buffer {
     }
 }
 
-/// Represents a memory buffer which borrows from some other data, so its lifetime is bound to that data
+/// Represents a memory buffer which borrows from some other data, so its lifetime is bound to that
+/// data
 #[repr(transparent)]
 pub struct MemoryBuffer<'a> {
     buffer: Buffer,
@@ -138,7 +139,8 @@ impl<'a> ToOwned for MemoryBuffer<'a> {
 
 /// Represents an owned memory buffer
 ///
-/// Creating one of these requires reading a file into memory, or copying data from some other source.
+/// Creating one of these requires reading a file into memory, or copying data from some other
+/// source.
 ///
 /// When an owned memory buffer is dropped, its underlying memory is freed
 #[repr(transparent)]
diff --git a/compiler/llvm/src/support/stringref.rs b/compiler/llvm/src/support/stringref.rs
index bf858daf8..01926c56b 100644
--- a/compiler/llvm/src/support/stringref.rs
+++ b/compiler/llvm/src/support/stringref.rs
@@ -109,8 +109,8 @@ impl StringRef {
     /// This is equivalent to `CStr::from_ptr`, but allows you to avoid the extra song and dance
     /// in places where you are frequently working with these types of strings.
     ///
-    /// NOTE: This is entirely unsafe, if you pass a pointer to a string that is not null-terminated,
-    /// it _will_ go wrong, so make sure you know what you're doing.
+    /// NOTE: This is entirely unsafe, if you pass a pointer to a string that is not
+    /// null-terminated, it _will_ go wrong, so make sure you know what you're doing.
     pub unsafe fn from_ptr(s: *const std::os::raw::c_char) -> Self {
         CStr::from_ptr(s).into()
     }
diff --git a/compiler/llvm/src/target.rs b/compiler/llvm/src/target.rs
index 40c9417d2..84883c3ae 100644
--- a/compiler/llvm/src/target.rs
+++ b/compiler/llvm/src/target.rs
@@ -93,7 +93,8 @@ pub fn host_cpu_features() -> OwnedStringRef {
 ///
 /// See firefly_target for the default features defined for each supported target
 ///
-/// In addition to those defaults, manually-specified target features can be enabled via compiler flags
+/// In addition to those defaults, manually-specified target features can be enabled via compiler
+/// flags
 pub fn llvm_target_features(options: &Options) -> impl Iterator<Item = &str> {
     const FIREFLY_SPECIFIC_FEATURES: &[&str] = &["crt-static"];
 
diff --git a/compiler/macros/src/bif.rs b/compiler/macros/src/bif.rs
index a1d897771..7fe4a789f 100644
--- a/compiler/macros/src/bif.rs
+++ b/compiler/macros/src/bif.rs
@@ -273,7 +273,8 @@ fn define_bif_internal(spec: BifSpec, is_guard: bool) -> TokenStream {
     TokenStream::from(quoted)
 }
 
-/// Convert some common Erlang type names to their equivalent representation as a firefly_syntax_ssa::Type variant
+/// Convert some common Erlang type names to their equivalent representation as a
+/// firefly_syntax_ssa::Type variant
 fn erlang_types_to_core_type_enum(pair: Pair<Ident, Token![,]>) -> Pair<Expr, Token![,]> {
     let (ident, punct) = pair.into_tuple();
     let expr = erlang_type_to_core_type_enum(ident.clone());
@@ -321,7 +322,8 @@ fn erlang_type_to_core_type_enum(ident: Ident) -> Expr {
     }
 }
 
-/// Convert the given string to a path representing the instantiation of a firefly_syntax_ssa::Type variant
+/// Convert the given string to a path representing the instantiation of a firefly_syntax_ssa::Type
+/// variant
 fn core_enum_variant(name: &str, span: Span) -> Expr {
     use syn::PathArguments;
 
diff --git a/compiler/mlir/src/dialect/cir.rs b/compiler/mlir/src/dialect/cir.rs
index d3f926f72..d97e8cda5 100644
--- a/compiler/mlir/src/dialect/cir.rs
+++ b/compiler/mlir/src/dialect/cir.rs
@@ -12,7 +12,8 @@ use crate::support::StringRef;
 
 /// Primary builder for the CIR dialect
 ///
-/// Wraps mlir::OpBuilder and provides functionality for constructing dialect operations, types, and attributes
+/// Wraps mlir::OpBuilder and provides functionality for constructing dialect operations, types, and
+/// attributes
 #[derive(Copy, Clone)]
 pub struct CirBuilder<'a, B: OpBuilder> {
     builder: &'a B,
@@ -2630,7 +2631,8 @@ impl<'a> SwitchBuilder<'a> {
 
     /// Extends the switch with a default case
     ///
-    /// NOTE: A default case is required, and must be provided prior to `build`, or creation will fail
+    /// NOTE: A default case is required, and must be provided prior to `build`, or creation will
+    /// fail
     pub fn with_default(&mut self, dest: Block, operands: &[ValueBase]) -> &mut Self {
         if self.default.is_null() {
             self.default = dest;
@@ -2719,7 +2721,7 @@ impl Operation for IfOp {
 impl<'a, B: OpBuilder> CirBuilder<'a, B> {
     #[inline]
     pub fn build_if<V: Value>(&self, loc: Location, cond: V, results: &[TypeBase]) -> IfOp {
-        self.build_if_else(loc, cond, results, /*with_else=*/ false)
+        self.build_if_else(loc, cond, results, /* with_else= */ false)
     }
 
     #[inline]
@@ -2801,10 +2803,10 @@ impl<'a, B: OpBuilder> CirBuilder<'a, B> {
 
 /// This op is used to support multiple blocks in a region nested within IfOp/ForOp
 ///
-/// Both of the ops mentioned only permit a single block in their regions, but since more complex control flow
-/// is commonly needed in the body of an if/for expression, it is necessary to use this op which can contain
-/// arbitrarily many blocks in its one region. It accepts no operands, but operations within are able to access
-/// all SSA values that dominate it directly.
+/// Both of the ops mentioned only permit a single block in their regions, but since more complex
+/// control flow is commonly needed in the body of an if/for expression, it is necessary to use this
+/// op which can contain arbitrarily many blocks in its one region. It accepts no operands, but
+/// operations within are able to access all SSA values that dominate it directly.
 #[repr(transparent)]
 #[derive(Copy, Clone)]
 pub struct ExecuteRegionOp(OperationBase);
diff --git a/compiler/mlir/src/dialect/llvm.rs b/compiler/mlir/src/dialect/llvm.rs
index ddb5ba4bd..ddf871c92 100644
--- a/compiler/mlir/src/dialect/llvm.rs
+++ b/compiler/mlir/src/dialect/llvm.rs
@@ -12,7 +12,8 @@ use crate::{Type, TypeBase, ValueBase};
 
 /// Primary builder for the LLVM dialect
 ///
-/// Wraps mlir::OpBuilder and provides functionality for constructing dialect operations, types, and attributes
+/// Wraps mlir::OpBuilder and provides functionality for constructing dialect operations, types, and
+/// attributes
 #[derive(Copy, Clone)]
 pub struct LlvmBuilder<'a, B: OpBuilder> {
     builder: &'a B,
@@ -161,7 +162,7 @@ impl StructType {
                 context,
                 fields.len(),
                 fields.as_ptr(),
-                /*packed=*/ false,
+                /* packed= */ false,
             )
         }
     }
@@ -172,7 +173,7 @@ impl StructType {
                 context,
                 fields.len(),
                 fields.as_ptr(),
-                /*packed=*/ true,
+                /* packed= */ true,
             )
         }
     }
diff --git a/compiler/mlir/src/ir/affine_map.rs b/compiler/mlir/src/ir/affine_map.rs
index cba2c0dc0..472e05187 100644
--- a/compiler/mlir/src/ir/affine_map.rs
+++ b/compiler/mlir/src/ir/affine_map.rs
@@ -41,7 +41,8 @@ impl AffineMap {
     }
 
     /// Creates an identity affine map on the most minor dimensions.
-    /// This function will panic if the number of dimensions is greater or equal to the number of results
+    /// This function will panic if the number of dimensions is greater or equal to the number of
+    /// results
     pub fn get_minor_identity(context: Context, dims: usize, results: usize) -> Self {
         assert!(
             dims < results,
diff --git a/compiler/mlir/src/ir/context.rs b/compiler/mlir/src/ir/context.rs
index 363778c4f..f69d849e1 100644
--- a/compiler/mlir/src/ir/context.rs
+++ b/compiler/mlir/src/ir/context.rs
@@ -156,7 +156,8 @@ impl OwnedContext {
         let scf_dialect = DialectHandle::get(DialectType::SCF).unwrap();
         let cir_dialect = DialectHandle::get(DialectType::CIR).unwrap();
 
-        // LLVM requires special registration as its LLVM IR translation interface needs registering as well
+        // LLVM requires special registration as its LLVM IR translation interface needs registering
+        // as well
         unsafe {
             mlir_context_register_llvm_dialect_translation(context);
         }
diff --git a/compiler/mlir/src/ir/mod.rs b/compiler/mlir/src/ir/mod.rs
index ba6c677cc..9bbf21412 100644
--- a/compiler/mlir/src/ir/mod.rs
+++ b/compiler/mlir/src/ir/mod.rs
@@ -162,8 +162,8 @@ pub trait Builder {
 
     /// Get a type corresponding to a memref with the given element type, shape and address space.
     ///
-    /// This is slightly different than the one returned by `get_memref_type`, as it has no affine maps, i.e.
-    /// it represents a default row-major contiguous memref.
+    /// This is slightly different than the one returned by `get_memref_type`, as it has no affine
+    /// maps, i.e. it represents a default row-major contiguous memref.
     fn get_contiguous_memref_type<T: Type>(
         element_type: T,
         shape: &[u64],
@@ -172,7 +172,8 @@ pub trait Builder {
         MemRefType::get_contiguous(element_type, shape, addrspace)
     }
 
-    /// Get a type corresponding to a memref of dynamic rank, with the given element type and address space.
+    /// Get a type corresponding to a memref of dynamic rank, with the given element type and
+    /// address space.
     fn get_unranked_memref<T: Type>(element_type: T, addrspace: AddressSpace) -> MemRefType {
         MemRefType::get_unranked(element_type, addrspace)
     }
@@ -318,7 +319,8 @@ pub trait Builder {
         AffineMap::get_multi_dim_identity(self.context(), dims)
     }
     /// Gets an identity affine map on the most minor dimensions.
-    /// This function will panic if the number of dimensions is greater or equal to the number of results
+    /// This function will panic if the number of dimensions is greater or equal to the number of
+    /// results
     fn get_minor_identity_affine_map(&self, dims: usize, results: usize) -> AffineMap {
         AffineMap::get_minor_identity(self.context(), dims, results)
     }
diff --git a/compiler/mlir/src/ir/symbols.rs b/compiler/mlir/src/ir/symbols.rs
index 51d8e1cf7..7d249aa7d 100644
--- a/compiler/mlir/src/ir/symbols.rs
+++ b/compiler/mlir/src/ir/symbols.rs
@@ -137,7 +137,8 @@ impl SymbolTable {
     ///
     /// This does not traverse into nested symbol tables.
     ///
-    /// Will fail atomically if there are any unknown operations that may be potential symbol tables.
+    /// Will fail atomically if there are any unknown operations that may be potential symbol
+    /// tables.
     pub fn replace_all_uses<O: Operation, S: Into<StringRef>>(from: O, old: S, new: S) -> bool {
         let result = unsafe {
             mlir_symbol_table_replace_all_symbol_uses(old.into(), new.into(), from.base())
diff --git a/compiler/mlir/src/ir/types.rs b/compiler/mlir/src/ir/types.rs
index 29d2b0c6b..927ef8eb3 100644
--- a/compiler/mlir/src/ir/types.rs
+++ b/compiler/mlir/src/ir/types.rs
@@ -492,11 +492,12 @@ impl AddressSpace {
 /// Represents the built-in MLIR MemRef and UnrankedMemRef types
 ///
 /// A MemRef is a type representing a region of memory of a specific size and shape.
-/// The layout can be dynamic or static, of unknown, single or multi-dimensional rank, contiguous or sparse.
+/// The layout can be dynamic or static, of unknown, single or multi-dimensional rank, contiguous or
+/// sparse.
 ///
 /// MemRefs have a specific fixed element type, i.e. they aren't meant to represent things like
-/// heterogenous tuples, but rather vectors/tensors/arrays of a specific type. In MLIR they are generally
-/// used with numeric types to solve for common ML tasks.
+/// heterogenous tuples, but rather vectors/tensors/arrays of a specific type. In MLIR they are
+/// generally used with numeric types to solve for common ML tasks.
 #[repr(transparent)]
 #[derive(Copy, Clone)]
 pub struct MemRefType(TypeBase);
@@ -552,7 +553,8 @@ impl MemRefType {
         unsafe { mlir_type_isa_unranked_memref(self.0) }
     }
 
-    /// Returns an attribute that implements MemRefLayoutAttrInterface, typically an AffineMapAttr, but not always
+    /// Returns an attribute that implements MemRefLayoutAttrInterface, typically an AffineMapAttr,
+    /// but not always
     pub fn layout(self) -> AttributeBase {
         unsafe { mlir_memref_type_get_layout(self) }
     }
diff --git a/compiler/mlir/src/pass/manager.rs b/compiler/mlir/src/pass/manager.rs
index 8f78887b8..5aa0517de 100644
--- a/compiler/mlir/src/pass/manager.rs
+++ b/compiler/mlir/src/pass/manager.rs
@@ -55,7 +55,7 @@ impl PassManagerBase {
             mlir_pass_manager_enable_crash_reproducer_generation(
                 self,
                 output_file.try_into().unwrap(),
-                /*local_reproducer=*/ true,
+                /* local_reproducer= */ true,
             );
         }
     }
diff --git a/compiler/mlir/src/pass/mod.rs b/compiler/mlir/src/pass/mod.rs
index 760ddc296..2ac5ed889 100644
--- a/compiler/mlir/src/pass/mod.rs
+++ b/compiler/mlir/src/pass/mod.rs
@@ -18,7 +18,8 @@ pub trait Pass {
     /// Returns an opaque borrowed reference to the pass for use in FFI
     fn base(&self) -> PassBase;
 
-    /// Consumes this pass and returns an opaque handle representing the pass for use by a pass manager
+    /// Consumes this pass and returns an opaque handle representing the pass for use by a pass
+    /// manager
     fn to_owned(self) -> OwnedPass;
 }
 
@@ -78,7 +79,8 @@ impl Drop for OwnedPass {
 
 /// Register all MLIR built-in passes
 ///
-/// NOTE: You should prefer to register passes individually, but this can be useful for dev/debugging
+/// NOTE: You should prefer to register passes individually, but this can be useful for
+/// dev/debugging
 pub fn register_all_passes() {
     extern "C" {
         #[link_name = "mlirRegisterAllPasses"]
diff --git a/compiler/panic/src/gcc.rs b/compiler/panic/src/gcc.rs
index 2059f4fb2..ea51a2caf 100644
--- a/compiler/panic/src/gcc.rs
+++ b/compiler/panic/src/gcc.rs
@@ -379,7 +379,10 @@ pub mod eh_frame_registry {
     }
 
     #[no_mangle]
-    pub unsafe extern "C" fn firefly_eh_register_frames(eh_frame_begin: *const u8, object: *mut u8) {
+    pub unsafe extern "C" fn firefly_eh_register_frames(
+        eh_frame_begin: *const u8,
+        object: *mut u8,
+    ) {
         __register_frame_info(eh_frame_begin, object);
     }
 
diff --git a/compiler/pass/src/lib.rs b/compiler/pass/src/lib.rs
index 318e60690..1fbed9a1c 100644
--- a/compiler/pass/src/lib.rs
+++ b/compiler/pass/src/lib.rs
@@ -5,7 +5,6 @@
 //! * Construct a pass pipeline that chains passes, taking as input the first passes input type,
 //! and outputing the last passes' output type. With this, you can represent lowering through
 //! various intermediate representations using a single pass pipeline.
-//!
 // This feature is only used for tests, and can be removed with minimal refactoring,
 // but I'm in a rush and we're using nightly right now anyway
 #![feature(box_patterns)]
@@ -13,11 +12,14 @@
 
 /// This trait represents anything that can be run as a pass.
 ///
-/// Passes operate on an input value, and return either the same type, or a new type, depending on the nature of the pass.
+/// Passes operate on an input value, and return either the same type, or a new type, depending on
+/// the nature of the pass.
 ///
-/// Implementations may represent a single pass, or an arbitrary number of passes that will be run as a single unit.
+/// Implementations may represent a single pass, or an arbitrary number of passes that will be run
+/// as a single unit.
 ///
-/// Functions are valid implementations of `Pass` as long as their signature is `fn<I, O>(I) -> Result<O, ()>`.
+/// Functions are valid implementations of `Pass` as long as their signature is `fn<I, O>(I) ->
+/// Result<O, ()>`.
 pub trait Pass {
     type Input<'a>;
     type Output<'a>;
diff --git a/compiler/session/src/config/app.rs b/compiler/session/src/config/app.rs
index 05f6d16a0..aae0e3361 100644
--- a/compiler/session/src/config/app.rs
+++ b/compiler/session/src/config/app.rs
@@ -429,8 +429,8 @@ fn parse_app<S: AsRef<str>>(source: S) -> anyhow::Result<App> {
 ///
 /// A resource file can contain comments, and one or more terms, each terminated with '.'
 ///
-/// An application resource file is a special case though, in that it should only contain a single item,
-/// but we let the caller handle that
+/// An application resource file is a special case though, in that it should only contain a single
+/// item, but we let the caller handle that
 fn parse_root(lexer: &mut Lexer<'_>) -> anyhow::Result<Vec<Spanned<Term>>> {
     let mut contents = Vec::with_capacity(1);
     loop {
diff --git a/compiler/session/src/config/options.rs b/compiler/session/src/config/options.rs
index d131b7184..39347344d 100644
--- a/compiler/session/src/config/options.rs
+++ b/compiler/session/src/config/options.rs
@@ -496,7 +496,9 @@ impl Options {
 
     /// Returns `true` if there will be an output file generated.
     pub fn will_create_output_file(&self) -> bool {
-        !(self.debugging_opts.parse_only || self.debugging_opts.analyze_only) // The file is just being parsed/analyzed
+        !(self.debugging_opts.parse_only || self.debugging_opts.analyze_only) // The file is just
+                                                                              // being parsed/
+                                                                              // analyzed
     }
 
     /// Returns a list of directories where target-specific tool binaries are located.
diff --git a/compiler/session/src/config/options/debugging.rs b/compiler/session/src/config/options/debugging.rs
index c47cb4ce0..0fd51fb79 100644
--- a/compiler/session/src/config/options/debugging.rs
+++ b/compiler/session/src/config/options/debugging.rs
@@ -115,7 +115,7 @@ pub struct DebuggingOptions {
      *
      *     split  = sections which do not require reloation are split out and ignored (default)
      *     single = sections which do not require relocation are ignored
-     **/
+     */
     #[option(
         takes_value(true),
         value_name("KIND"),
diff --git a/compiler/session/src/config/options/parse.rs b/compiler/session/src/config/options/parse.rs
index f3d8988f7..786096c23 100644
--- a/compiler/session/src/config/options/parse.rs
+++ b/compiler/session/src/config/options/parse.rs
@@ -200,7 +200,7 @@ impl ParseOption for ColorArg {
     }
 }
 
-pub(in crate) fn invalid_value(info: &OptionInfo, description: &str) -> clap::Error {
+pub(crate) fn invalid_value(info: &OptionInfo, description: &str) -> clap::Error {
     clap::Error {
         kind: ErrorKind::InvalidValue,
         message: description.to_string(),
@@ -208,7 +208,7 @@ pub(in crate) fn invalid_value(info: &OptionInfo, description: &str) -> clap::Er
     }
 }
 
-pub(in crate) fn required_option_missing(info: &OptionInfo) -> clap::Error {
+pub(crate) fn required_option_missing(info: &OptionInfo) -> clap::Error {
     clap::Error {
         kind: ErrorKind::MissingRequiredArgument,
         message: format!("required argument was not provided"),
diff --git a/compiler/syntax_base/src/bifs.rs b/compiler/syntax_base/src/bifs.rs
index bde04c651..36369fa65 100644
--- a/compiler/syntax_base/src/bifs.rs
+++ b/compiler/syntax_base/src/bifs.rs
@@ -7,8 +7,8 @@
 ///! NOTE: The types are not perfectly accurate, as currently we don't try to fully represent
 ///! type specs, however we do make an attempt to be as precise as possible with the accuracy
 ///! we do have. In the future we'll hopefully be able to make the type information not only
-///! richer, but context-sensitive for those situations in which the polymorphism of a given BIF
-///! is dependent on constant inputs which we can reason about relatively easily
+///! richer, but context-sensitive for those situations in which the polymorphism of a given
+/// BIF ! is dependent on constant inputs which we can reason about relatively easily
 use std::collections::BTreeMap;
 
 use firefly_compiler_macros::{bif, guard_bif};
diff --git a/compiler/syntax_base/src/functions.rs b/compiler/syntax_base/src/functions.rs
index 3cfba48ad..63ec89620 100644
--- a/compiler/syntax_base/src/functions.rs
+++ b/compiler/syntax_base/src/functions.rs
@@ -422,7 +422,8 @@ impl fmt::Display for Visibility {
     }
 }
 impl Visibility {
-    /// Returns true if this function is imported from another module or the standard library prelude
+    /// Returns true if this function is imported from another module or the standard library
+    /// prelude
     #[inline(always)]
     pub fn is_imported(&self) -> bool {
         self.contains(Self::IMPORTED)
@@ -508,10 +509,10 @@ pub enum CallConv {
 /// i.e. the visibility flags encode information about the signature relative to that module
 /// specifically, not all modules.
 ///
-/// Signatures can be compared for equality, but when doing so, all of the module-specific contextual
-/// information is ignored, and only the function name (i.e. MFA) is considered. The signature types
-/// are ignored, as type information is only used for optimization, and in many cases we may not have
-/// complete type information anyway.
+/// Signatures can be compared for equality, but when doing so, all of the module-specific
+/// contextual information is ignored, and only the function name (i.e. MFA) is considered. The
+/// signature types are ignored, as type information is only used for optimization, and in many
+/// cases we may not have complete type information anyway.
 #[derive(Debug, Clone)]
 pub struct Signature {
     pub visibility: Visibility,
diff --git a/compiler/syntax_base/src/lib.rs b/compiler/syntax_base/src/lib.rs
index 6c781a86f..c85733a85 100644
--- a/compiler/syntax_base/src/lib.rs
+++ b/compiler/syntax_base/src/lib.rs
@@ -28,7 +28,8 @@ use std::collections::{BTreeMap, BTreeSet, HashSet};
 use firefly_diagnostics::{SourceSpan, Span};
 use firefly_intern::{Ident, Symbol};
 
-/// This structure contains metadata representing an OTP application gathered during parsing and semantic analysis.
+/// This structure contains metadata representing an OTP application gathered during parsing and
+/// semantic analysis.
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ApplicationMetadata {
     pub name: Symbol,
@@ -56,9 +57,9 @@ impl ApplicationMetadata {
     }
 }
 
-/// This structure contains metadata about a module gathered during initial parsing and semantic analysis,
-/// which comes in handy during later stages of compilation where we can reason about the set of all
-/// reachable modules
+/// This structure contains metadata about a module gathered during initial parsing and semantic
+/// analysis, which comes in handy during later stages of compilation where we can reason about the
+/// set of all reachable modules
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ModuleMetadata {
     pub name: Ident,
@@ -67,9 +68,9 @@ pub struct ModuleMetadata {
     pub deprecations: BTreeMap<FunctionName, Deprecation>,
 }
 
-/// This structure holds module-specific compiler options and configuration; it is passed through all phases of
-/// compilation alongside its associated module, and is a superset of options in CompilerSettings
-/// where applicable
+/// This structure holds module-specific compiler options and configuration; it is passed through
+/// all phases of compilation alongside its associated module, and is a superset of options in
+/// CompilerSettings where applicable
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub struct CompileOptions {
     // Used to override the filename used in errors/warnings
diff --git a/compiler/syntax_base/src/types.rs b/compiler/syntax_base/src/types.rs
index 4777fbfbe..c45920635 100644
--- a/compiler/syntax_base/src/types.rs
+++ b/compiler/syntax_base/src/types.rs
@@ -226,7 +226,8 @@ impl TermType {
         }
     }
 
-    /// If we have a binary arithemtic operation, what is the type of the result based on the type of the operands?
+    /// If we have a binary arithemtic operation, what is the type of the result based on the type
+    /// of the operands?
     pub fn coerce_to_numeric_with(&self, other: Self) -> Self {
         let this = self.coerce_to_numeric();
         let other = other.coerce_to_numeric();
@@ -345,19 +346,21 @@ impl PartialOrd for TermType {
 /// internal runtime types which are used with primop instructions.
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub enum Type {
-    // This type is used to indicate that the type of an instruction is dynamic or unable to be typed
+    // This type is used to indicate that the type of an instruction is dynamic or unable to be
+    // typed
     Unknown,
     // This type is used to indicate an instruction that produces no results, and thus has no type
     Invalid,
-    // Primitive types are used for some instructions which are low-level and do not directly produce
-    // values which are used as terms, or are castable to term (e.g. integers)
+    // Primitive types are used for some instructions which are low-level and do not directly
+    // produce values which are used as terms, or are castable to term (e.g. integers)
     Primitive(PrimitiveType),
-    // Term types are associated with values which correspond to syntax-level operations and are expected
-    // to be used with runtime BIFs (built-in functions)
+    // Term types are associated with values which correspond to syntax-level operations and are
+    // expected to be used with runtime BIFs (built-in functions)
     Term(TermType),
     // Represents a function type that is calling-convention agnostic
     Function(FunctionType),
-    // This type is equivalent to Rust's Never/! type, i.e. it indicates that a function never returns
+    // This type is equivalent to Rust's Never/! type, i.e. it indicates that a function never
+    // returns
     NoReturn,
     // This type maps to ErlangException in firefly_rt
     Exception,
diff --git a/compiler/syntax_core/src/ir/internal.rs b/compiler/syntax_core/src/ir/internal.rs
index aaf257aa9..2982c1f85 100644
--- a/compiler/syntax_core/src/ir/internal.rs
+++ b/compiler/syntax_core/src/ir/internal.rs
@@ -800,7 +800,8 @@ pub enum IQualifier {
     Filter(IFilter),
 }
 
-/// This struct is used to represent the internal state of a generator expression while it is being transformed
+/// This struct is used to represent the internal state of a generator expression while it is being
+/// transformed
 #[derive(Debug, Clone, Spanned)]
 pub struct IGen {
     #[span]
@@ -826,7 +827,8 @@ pub struct IGen {
 }
 annotated!(IGen);
 
-/// A filter is one of two types of expressions that act as qualifiers in a commprehension, the other is a generator
+/// A filter is one of two types of expressions that act as qualifiers in a commprehension, the
+/// other is a generator
 #[derive(Debug, Clone, Spanned)]
 pub struct IFilter {
     #[span]
diff --git a/compiler/syntax_core/src/passes/annotate.rs b/compiler/syntax_core/src/passes/annotate.rs
index 7328fb3c3..ac0791825 100644
--- a/compiler/syntax_core/src/passes/annotate.rs
+++ b/compiler/syntax_core/src/passes/annotate.rs
@@ -1024,7 +1024,6 @@ impl AnnotateVariableUsage {
     /// compilation in Core Erlang, there is a need to rename all
     /// shadowing variables to avoid changing the semantics of the Erlang
     /// program.
-    ///
     fn rename_shadowing_clauses(
         &mut self,
         mut clauses: Vec<IClause>,
diff --git a/compiler/syntax_core/src/passes/known.rs b/compiler/syntax_core/src/passes/known.rs
index 1b7a9c030..9de389ae8 100644
--- a/compiler/syntax_core/src/passes/known.rs
+++ b/compiler/syntax_core/src/passes/known.rs
@@ -78,7 +78,6 @@ use firefly_intern::Ident;
 /// To correctly rewrite fun bodies, we will need to keep addtional
 /// information in a record so that we can remove `X` from the known
 /// variables when rewriting the body of the fun.
-///
 #[derive(Clone, Default)]
 pub struct Known {
     base: Vector<RedBlackTreeSet<Ident>>,
diff --git a/compiler/syntax_erl/src/ast/expr.rs b/compiler/syntax_erl/src/ast/expr.rs
index 0b964a2ac..beb698698 100644
--- a/compiler/syntax_erl/src/ast/expr.rs
+++ b/compiler/syntax_erl/src/ast/expr.rs
@@ -978,7 +978,8 @@ impl PartialEq for BinaryComprehension {
     }
 }
 
-/// A generator is one of two types of expressions that act as qualifiers in a commprehension, the other is a filter
+/// A generator is one of two types of expressions that act as qualifiers in a commprehension, the
+/// other is a filter
 #[derive(Debug, Clone, Spanned)]
 pub struct Generator {
     #[span]
diff --git a/compiler/syntax_erl/src/ast/functions.rs b/compiler/syntax_erl/src/ast/functions.rs
index bff2c33c0..22b6b12df 100644
--- a/compiler/syntax_erl/src/ast/functions.rs
+++ b/compiler/syntax_erl/src/ast/functions.rs
@@ -167,7 +167,8 @@ pub struct RecursiveFun {
     // Name is only set when an anonymous function is assigned a name by a compiler pass
     // Immediately after parsing, it is always None
     pub name: Option<Ident>,
-    // The self_name is the name bound to the function within its body, which allows the function to call itself
+    // The self_name is the name bound to the function within its body, which allows the function
+    // to call itself
     pub self_name: Ident,
     pub arity: u8,
     pub clauses: Vec<(Name, Clause)>,
diff --git a/compiler/syntax_erl/src/ast/module.rs b/compiler/syntax_erl/src/ast/module.rs
index 57662700e..26df6d808 100644
--- a/compiler/syntax_erl/src/ast/module.rs
+++ b/compiler/syntax_erl/src/ast/module.rs
@@ -141,7 +141,8 @@ impl Module {
         }
     }
 
-    /// Called by the parser for Erlang Abstract Format, which relies on us detecting the module name in the given forms
+    /// Called by the parser for Erlang Abstract Format, which relies on us detecting the module
+    /// name in the given forms
     pub fn new_from_pp(
         reporter: &Reporter,
         codemap: Arc<CodeMap>,
@@ -158,7 +159,6 @@ impl Module {
     /// parsed, in other words this is the last function called when parsing a module.
     ///
     /// As a result, this function performs initial semantic analysis of the module.
-    ///
     pub fn new_with_forms(
         reporter: &Reporter,
         _codemap: Arc<CodeMap>,
diff --git a/compiler/syntax_erl/src/evaluator.rs b/compiler/syntax_erl/src/evaluator.rs
index 34f6cdd49..bb88abd23 100644
--- a/compiler/syntax_erl/src/evaluator.rs
+++ b/compiler/syntax_erl/src/evaluator.rs
@@ -334,7 +334,8 @@ pub fn eval_expr(
                         .as_proper_list()
                         .map_err(|_| EvalError::InvalidConstExpression { span })?;
 
-                    // For each element in the right-hand list, remove the first occurrance in the left-hand list
+                    // For each element in the right-hand list, remove the first occurrance in the
+                    // left-hand list
                     for element in rs.drain(..) {
                         if let Some(idx) = ls.iter().position(|l| l.eq(&element)) {
                             ls.remove(idx);
diff --git a/compiler/syntax_erl/src/features.rs b/compiler/syntax_erl/src/features.rs
index b01002c49..a3395735a 100644
--- a/compiler/syntax_erl/src/features.rs
+++ b/compiler/syntax_erl/src/features.rs
@@ -26,7 +26,8 @@ lazy_static! {
     };
 }
 
-/// Describes a selectable feature, corresponding to the BEAM compiler's functionality of the same name
+/// Describes a selectable feature, corresponding to the BEAM compiler's functionality of the same
+/// name
 #[derive(Debug, Copy, Clone)]
 pub struct Feature {
     pub name: Symbol,
diff --git a/compiler/syntax_erl/src/passes/sema/functions.rs b/compiler/syntax_erl/src/passes/sema/functions.rs
index 386e9535c..d7f6ff92f 100644
--- a/compiler/syntax_erl/src/passes/sema/functions.rs
+++ b/compiler/syntax_erl/src/passes/sema/functions.rs
@@ -82,7 +82,8 @@ impl VisitMut<bool> for IsNifVisitor {
         }
     }
 
-    // As an optimization we can skip over patterns, since the calls we're looking for will only occur in a non-pattern context
+    // As an optimization we can skip over patterns, since the calls we're looking for will only
+    // occur in a non-pattern context
     fn visit_mut_pattern(&mut self, _pattern: &mut Expr) -> ControlFlow<bool> {
         ControlFlow::Continue(())
     }
@@ -95,8 +96,9 @@ impl VisitMut<bool> for IsNifVisitor {
         ControlFlow::Continue(())
     }
 
-    // The call to nif_error should exist near the entry of the function, so we can skip certain expression types
-    // which we know the call to nif_error/2 will not be in, or which are not going to be present in a nif stub
+    // The call to nif_error should exist near the entry of the function, so we can skip certain
+    // expression types which we know the call to nif_error/2 will not be in, or which are not
+    // going to be present in a nif stub
     fn visit_mut_expr(&mut self, expr: &mut Expr) -> ControlFlow<bool> {
         match expr {
             Expr::Begin(ref mut begin) => self.visit_mut_begin(begin),
diff --git a/compiler/syntax_erl/src/passes/sema/inject.rs b/compiler/syntax_erl/src/passes/sema/inject.rs
index 9e1a6d80e..92d545e2a 100644
--- a/compiler/syntax_erl/src/passes/sema/inject.rs
+++ b/compiler/syntax_erl/src/passes/sema/inject.rs
@@ -105,7 +105,8 @@ impl Pass for DefinePseudoLocals {
             ast_lit_cons!(ast_lit_tuple_with_span!(nif.span(), fname, arity), tail)
         });
 
-        // Define module_info/0 which contains a proplist with keys: module, attributes, compile, exports, md5 and native
+        // Define module_info/0 which contains a proplist with keys: module, attributes, compile,
+        // exports, md5 and native
         let mod_info_0_list = ast_lit_list!(
             ast_lit_tuple!(
                 ast_lit_atom!(symbols::Module),
@@ -137,7 +138,8 @@ impl Pass for DefinePseudoLocals {
         };
         define_function(module, mod_info_0);
 
-        // Define module_info/1 which contains accepts the following keys: module, attributes, compile, exports, functions, nifs, md5 and native
+        // Define module_info/1 which contains accepts the following keys: module, attributes,
+        // compile, exports, functions, nifs, md5 and native
         let mod_info_1 = Function {
             span: SourceSpan::UNKNOWN,
             name: ident!(module_info),
diff --git a/compiler/syntax_erl/src/passes/sema/verify.rs b/compiler/syntax_erl/src/passes/sema/verify.rs
index 6e756354c..630b9f407 100644
--- a/compiler/syntax_erl/src/passes/sema/verify.rs
+++ b/compiler/syntax_erl/src/passes/sema/verify.rs
@@ -107,7 +107,8 @@ impl Pass for VerifyOnLoadFunctions {
     }
 }
 
-/// Like `VerifyExports`, but for `-nifs`; ensures all NIF declarations have a corresponding definition.
+/// Like `VerifyExports`, but for `-nifs`; ensures all NIF declarations have a corresponding
+/// definition.
 pub struct VerifyNifs {
     reporter: Reporter,
 }
@@ -182,14 +183,16 @@ impl Pass for VerifyTypeSpecs {
     }
 }
 
-/// Verifies that the callee of local function calls is defined or imported, or is dynamic and thus not statically analyzable
+/// Verifies that the callee of local function calls is defined or imported, or is dynamic and thus
+/// not statically analyzable
 ///
 /// Additionally, checks if the callee is known to be deprecated and raises appropriate diagnostics.
 ///
-/// NOTE: We could extend this analysis to cover calls to other modules, since at the point this analysis is run, we have
-/// access to the entire set of modules that was provided to the compiler, however this does not account for cases in which
-/// we're only compiling a library and thus only a subset of the modules is known - we could make such analysis optional and
-/// only perform it when the full set of modules is known.
+/// NOTE: We could extend this analysis to cover calls to other modules, since at the point this
+/// analysis is run, we have access to the entire set of modules that was provided to the compiler,
+/// however this does not account for cases in which we're only compiling a library and thus only a
+/// subset of the modules is known - we could make such analysis optional and only perform it when
+/// the full set of modules is known.
 pub struct VerifyCalls<'app> {
     reporter: Reporter,
     app: &'app ApplicationMetadata,
diff --git a/compiler/syntax_erl/src/passes/transforms/expand_records.rs b/compiler/syntax_erl/src/passes/transforms/expand_records.rs
index 892a99d26..7bce0bda1 100644
--- a/compiler/syntax_erl/src/passes/transforms/expand_records.rs
+++ b/compiler/syntax_erl/src/passes/transforms/expand_records.rs
@@ -260,7 +260,8 @@ impl<'m> ExpandRecordsVisitor<'m> {
                     Ident::with_empty_span(symbols::Underscore).into(),
                 ));
             } else {
-                // This is a constructor, so use the default expression, then the default initializer, or the atom 'undefined' if neither are present
+                // This is a constructor, so use the default expression, then the default
+                // initializer, or the atom 'undefined' if neither are present
                 match record.default.as_ref() {
                     Some(box default_expr) => elements.push(default_expr.clone()),
                     None => match defined.value.as_ref() {
@@ -411,7 +412,8 @@ impl<'m> ExpandRecordsVisitor<'m> {
         // Generate vars for use in the pattern match phase
         let bound_var = self.next_var(Some(span));
         let catch_all_var = self.next_var(Some(span));
-        // Expand the updates to a sequence of nested setelement calls such that they evaluate in the correct order
+        // Expand the updates to a sequence of nested setelement calls such that they evaluate in
+        // the correct order
         let expanded_updates = record_update
             .updates
             .iter()
@@ -446,7 +448,8 @@ impl<'m> ExpandRecordsVisitor<'m> {
                     }))
                 },
             )?;
-        // Generate an empty pattern, i.e. all wildcards, that validates the input is a tuple of the appropriate type/shape
+        // Generate an empty pattern, i.e. all wildcards, that validates the input is a tuple of the
+        // appropriate type/shape
         let tuple_pattern = self.expand_record(&Record {
             span,
             name,
diff --git a/compiler/syntax_erl/src/passes/translate/ast_to_core.rs b/compiler/syntax_erl/src/passes/translate/ast_to_core.rs
index bf7799060..039c67ded 100644
--- a/compiler/syntax_erl/src/passes/translate/ast_to_core.rs
+++ b/compiler/syntax_erl/src/passes/translate/ast_to_core.rs
@@ -79,7 +79,8 @@ use anyhow::bail;
 
 const COLLAPSE_MAX_SIZE_SEGMENT: usize = 1024;
 
-/// This pass transforms an AST function into its Core IR form for further analysis and eventual lowering to Kernel IR
+/// This pass transforms an AST function into its Core IR form for further analysis and eventual
+/// lowering to Kernel IR
 ///
 /// This pass performs numerous small transformations to normalize the structure of the AST
 pub struct AstToCore {
@@ -467,7 +468,8 @@ impl TranslateAst {
                 Ok(IExpr::Alias(alias))
             }
             (p1, p2) => {
-                // Aliases between binaries are not allowed, so the only legal patterns that remain are data patterns.
+                // Aliases between binaries are not allowed, so the only legal patterns that remain
+                // are data patterns.
                 if !p1.is_data() {
                     self.reporter.show_error(
                         "invalid alias pattern",
@@ -1684,8 +1686,8 @@ impl TranslateAst {
         ))
     }
 
-    /// This is the implementation of the TQ translation scheme as described in _The Implementation of Functional Programming Languages_,
-    /// Simon Peyton Jones, et al. pp 127-138
+    /// This is the implementation of the TQ translation scheme as described in _The Implementation
+    /// of Functional Programming Languages_, Simon Peyton Jones, et al. pp 127-138
     fn lc_tq(
         &mut self,
         span: SourceSpan,
@@ -2038,8 +2040,8 @@ impl TranslateAst {
         match filter.filter {
             FilterType::Match(pre, arg) => {
                 // The filter is an expression, it is compiled to a case of degree 1 with 3 clauses,
-                // one accumulating, one skipping, and the final one throwing {case_clause, Value} where Value
-                // is the result of the filter and is not a boolean
+                // one accumulating, one skipping, and the final one throwing {case_clause, Value}
+                // where Value is the result of the filter and is not a boolean
                 let fail_pat = IExpr::Var(self.context_mut().next_var(Some(span)));
                 let fail = fail_clause(
                     span,
@@ -2140,17 +2142,15 @@ impl TranslateAst {
     fn generator(&mut self, gen: ast::Generator, guards: Vec<ast::Expr>) -> anyhow::Result<IGen> {
         // Generators are abstracted as sextuplets:
         //  - acc_pat is the accumulator pattern, e.g. [Pat|Tail] for Pat <- Expr.
-        //  - acc_guard is the list of guards immediately following the current
-        //    generator in the qualifier list input.
-        //  - skip_pat is the skip pattern, e.g. <<X,_:X,Tail/bitstring>> for
-        //    <<X,1:X>> <= Expr.
-        //  - tail is the variable used in AccPat and SkipPat bound to the rest of the
-        //    generator input.
-        //  - tail_pat is the tail pattern, respectively [] and <<_/bitstring>> for list
-        //    and bit string generators.
-        //  - arg is a pair {Pre,Arg} where Pre is the list of expressions to be
-        //    inserted before the comprehension function and Arg is the expression
-        //    that it should be passed.
+        //  - acc_guard is the list of guards immediately following the current generator in the
+        //    qualifier list input.
+        //  - skip_pat is the skip pattern, e.g. <<X,_:X,Tail/bitstring>> for <<X,1:X>> <= Expr.
+        //  - tail is the variable used in AccPat and SkipPat bound to the rest of the generator
+        //    input.
+        //  - tail_pat is the tail pattern, respectively [] and <<_/bitstring>> for list and bit
+        //    string generators.
+        //  - arg is a pair {Pre,Arg} where Pre is the list of expressions to be inserted before the
+        //    comprehension function and Arg is the expression that it should be passed.
         //
         match gen.ty {
             ast::GeneratorType::Default => {
@@ -2326,7 +2326,8 @@ impl TranslateAst {
         let mut out = Vec::new();
         for mut segment in segments.drain(..) {
             if segment.value.is_var() {
-                // We must keep the names of existing variables to ensure that patterns such as `<<Size, X:Size>>` will work.
+                // We must keep the names of existing variables to ensure that patterns such as
+                // `<<Size, X:Size>>` will work.
                 out.push(segment);
             } else {
                 // Replace literal or expression with a variable (whose value will be ignored)
@@ -2676,7 +2677,8 @@ impl TranslateAst {
                 // sized. The annotation will be used by the runtime system to
                 // provide extended error information if construction of the
                 // binary fails.
-                // let anno = Annotations::from(vec![(symbols::Segment, lit_tuple!(span, lit_int!(span, line), lit_int!(span, column)))])
+                // let anno = Annotations::from(vec![(symbols::Segment, lit_tuple!(span,
+                // lit_int!(span, line), lit_int!(span, column)))])
                 let bs = IBitstring {
                     span,
                     annotations: Annotations::default(),
@@ -3163,7 +3165,6 @@ fn sanitize(expr: ast::Expr) -> ast::Expr {
 ///  or expression using 'or' or 'xor' cannot be transformed in this
 ///  way (such expressions are the reason for adding the is_boolean/1
 ///  test in the first place).
-///
 fn unforce(expr: &IExpr, mut pre: Vec<IExpr>, bools: Vec<IExpr>) -> Vec<IExpr> {
     if bools.is_empty() {
         bools
@@ -3581,7 +3582,8 @@ fn verify_suitable_fields(elements: &[ast::BinaryElement]) -> Result<(), ()> {
                 if bits_limit >= size {
                     continue;
                 }
-                // More than about half of the field size will be filled out with zeros - not acceptable
+                // More than about half of the field size will be filled out with zeros - not
+                // acceptable
                 return Err(());
             }
             _ => return Err(()),
diff --git a/compiler/syntax_kernel/src/passes/translate/core_to_kernel/mod.rs b/compiler/syntax_kernel/src/passes/translate/core_to_kernel/mod.rs
index abf405279..36b093423 100644
--- a/compiler/syntax_kernel/src/passes/translate/core_to_kernel/mod.rs
+++ b/compiler/syntax_kernel/src/passes/translate/core_to_kernel/mod.rs
@@ -76,7 +76,8 @@ pub enum ExprError {
     BadSegmentSize(SourceSpan),
 }
 
-/// This pass transforms a Core IR function into its Kernel IR form for further analysis and eventual lowering to SSA IR
+/// This pass transforms a Core IR function into its Kernel IR form for further analysis and
+/// eventual lowering to SSA IR
 pub struct CoreToKernel {
     reporter: Reporter,
 }
@@ -525,7 +526,8 @@ impl TranslateCore {
             }) => {
                 match call_type(&module, &function, args.as_slice()) {
                     CallType::Error => {
-                        // Invalid module/function, must rewrite as a call to apply/3 and let it fail at runtime
+                        // Invalid module/function, must rewrite as a call to apply/3 and let it
+                        // fail at runtime
                         let argv = make_clist(args);
                         let mut mfa = Vec::with_capacity(3);
                         mfa.push(module);
@@ -704,7 +706,8 @@ impl TranslateCore {
         }
     }
 
-    /// Implement letrec in the traditional way as a local function for each definition in the letrec
+    /// Implement letrec in the traditional way as a local function for each definition in the
+    /// letrec
     fn letrec_local_function(
         &mut self,
         span: SourceSpan,
@@ -1385,7 +1388,6 @@ impl TranslateCore {
     ///  have a normalized view of literal integers, allowing us to generate
     ///  more literals and group more clauses. Those integers may be "squeezed"
     ///  later into the largest integer possible.
-    ///
     fn build_bin_seg(
         &mut self,
         span: SourceSpan,
@@ -3146,8 +3148,8 @@ impl TranslateCore {
             // variables). The transformation works like this:
             //
             // 1. Rewrite the function signature to expect a closure as an extra trailing argument
-            // 2. Inject the unpack_env primop in the function entry for each free variable to extract
-            // it from the closure argument
+            // 2. Inject the unpack_env primop in the function entry for each free variable to
+            // extract it from the closure argument
             for (
                 name,
                 IFun {
@@ -3158,7 +3160,8 @@ impl TranslateCore {
                 },
             ) in lr.defs.drain(..)
             {
-                // Perform the usual rewrite, then wrap the body to contain the unpack_env instructions
+                // Perform the usual rewrite, then wrap the body to contain the unpack_env
+                // instructions
                 let (body, _) = self.ubody(body, Brk::Return)?;
                 let (name, body) = if free_vars.is_empty() {
                     let name = FunctionName::new_local(name.name(), vars.len() as u8);
@@ -3189,8 +3192,9 @@ impl TranslateCore {
     ) -> Expr {
         assert_ne!(free.len(), 0);
 
-        // We create a chained series of calls to unpack_env/2, in reverse, with appropriate rets for each free variable
-        // This will result in the correct sequence of instructions when lowered
+        // We create a chained series of calls to unpack_env/2, in reverse, with appropriate rets
+        // for each free variable This will result in the correct sequence of instructions
+        // when lowered
         let env_arity = free.len();
         let mut body = body;
         for i in (0..env_arity).rev() {
diff --git a/compiler/syntax_kernel/src/passes/translate/kernel_to_ssa/mod.rs b/compiler/syntax_kernel/src/passes/translate/kernel_to_ssa/mod.rs
index 12a57cc66..347375a3d 100644
--- a/compiler/syntax_kernel/src/passes/translate/kernel_to_ssa/mod.rs
+++ b/compiler/syntax_kernel/src/passes/translate/kernel_to_ssa/mod.rs
@@ -76,7 +76,8 @@ impl Pass for KernelToSsa {
             functions.push((id, signature));
         }
 
-        // For every function in the module, run a function-local pass which produces the function body
+        // For every function in the module, run a function-local pass which produces the function
+        // body
         for (i, function) in module.functions.drain(..).enumerate() {
             let (id, sig) = functions.get(i).unwrap();
             let mut pass = LowerFunctionToSsa {
@@ -688,7 +689,8 @@ impl<'m> LowerFunctionToSsa<'m> {
         let tuple = builder.ins().cast(tuple, ty, span);
         // Fetch the tag element of the tuple
         let elem = builder.ins().get_element_imm(tuple, 0, span);
-        // Compare the fetched tag to the expected tag, branching to the fail block if there is a mismatch
+        // Compare the fetched tag to the expected tag, branching to the fail block if there is a
+        // mismatch
         let tag = builder.ins().atom(tag, span);
         let has_tag = builder.ins().eq_exact(elem, tag, span);
         builder.ins().br_unless(has_tag, fail, &[], span);
@@ -778,14 +780,17 @@ impl<'m> LowerFunctionToSsa<'m> {
                         // Indirect callee
                         let is_closure = v.has_annotation(symbols::Closure);
                         let callee = self.ssa_value(builder, v)?;
-                        // Optimize the case where we know that the callee is a fun that we just created
+                        // Optimize the case where we know that the callee is a fun that we just
+                        // created
                         let mut args = self.ssa_values(builder, call.args)?;
                         if is_closure {
-                            // The callee is known statically to be a fun, so we can use the optimized call path
+                            // The callee is known statically to be a fun, so we can use the
+                            // optimized call path
                             builder.ins().call_indirect(callee, args.as_slice(), span)
                         } else {
-                            // The callee is either not a fun at all, or we are unable to verify, use the safe path by
-                            // converting this to a call to apply/2
+                            // The callee is either not a fun at all, or we are unable to verify,
+                            // use the safe path by converting this to a
+                            // call to apply/2
                             let apply2 = FunctionName::new(symbols::Erlang, symbols::Apply, 2);
                             let apply2 = self.module.get_or_register_builtin(apply2);
                             let argv = args.drain(..).rfold(builder.ins().nil(span), |tail, hd| {
@@ -898,11 +903,12 @@ impl<'m> LowerFunctionToSsa<'m> {
                 // Optimize the case where we know that the callee is a fun that we just created
                 let mut args = self.ssa_values(builder, call.args)?;
                 if is_closure {
-                    // The callee is known statically to be a fun, so we can use the optimized call path
+                    // The callee is known statically to be a fun, so we can use the optimized call
+                    // path
                     builder.ins().enter_indirect(callee, args.as_slice(), span)
                 } else {
-                    // The callee is either not a fun at all, or we are unable to verify, use the safe path by
-                    // converting this to a call to apply/2
+                    // The callee is either not a fun at all, or we are unable to verify, use the
+                    // safe path by converting this to a call to apply/2
                     let apply2 = FunctionName::new(symbols::Erlang, symbols::Apply, 2);
                     let apply2 = self.module.get_or_register_builtin(apply2);
                     let argv = args.drain(..).rfold(builder.ins().nil(span), |tail, hd| {
@@ -984,7 +990,8 @@ impl<'m> LowerFunctionToSsa<'m> {
                 Ok(())
             }
             _ => {
-                // This bif is fallible, and may have side effects, so must be treated like a standard call
+                // This bif is fallible, and may have side effects, so must be treated like a
+                // standard call
                 let callee = self.module.get_or_register_builtin(bif.op);
                 let args = self.ssa_values(builder, bif.args)?;
                 let inst = builder.ins().call(callee, args.as_slice(), span);
@@ -1073,7 +1080,8 @@ impl<'m> LowerFunctionToSsa<'m> {
         let span = bif.span();
         match (bif.op.function, bif.args.as_slice()) {
             (symbols::MakeFun, [KExpr::Local(local), ..]) => {
-                // make_fun/2 requires special handling to convert to its corresponding core instruction
+                // make_fun/2 requires special handling to convert to its corresponding core
+                // instruction
                 let callee = builder
                     .get_callee(local.item)
                     .expect("undefined local function reference");
@@ -1137,7 +1145,8 @@ impl<'m> LowerFunctionToSsa<'m> {
             }
             (symbols::RemoveMessage | symbols::RecvNext, _) => {
                 let callee = self.module.get_or_register_builtin(bif.op);
-                // These ops have no arguments and no results, i.e. they are not fallible, but do have a side effect on the process mailbox
+                // These ops have no arguments and no results, i.e. they are not fallible, but do
+                // have a side effect on the process mailbox
                 assert_eq!(bif.ret.len(), 0);
                 assert_eq!(bif.args.len(), 0);
                 builder.ins().call(callee, &[], span);
@@ -1146,8 +1155,9 @@ impl<'m> LowerFunctionToSsa<'m> {
             (symbols::RecvPeekMessage, _) => {
                 let callee = self.module.get_or_register_builtin(bif.op);
                 assert_eq!(bif.ret.len(), 2);
-                // This op has a multi-value result. The first is a boolean indicating whether a message was available,
-                // the second is the message itself, or NONE, depending on whether or not a message was available
+                // This op has a multi-value result. The first is a boolean indicating whether a
+                // message was available, the second is the message itself, or NONE,
+                // depending on whether or not a message was available
                 let args = self.ssa_values(builder, bif.args)?;
                 let inst = builder.ins().call(callee, args.as_slice(), span);
                 let (msg_available, msg) = {
@@ -1165,16 +1175,17 @@ impl<'m> LowerFunctionToSsa<'m> {
                 let callee = self.module.get_or_register_builtin(bif.op);
                 assert!(bif.args.len() <= 1);
                 assert_eq!(bif.ret.len(), 1);
-                // This op has a complex multi-value result that can produce branches in three directions:
+                // This op has a complex multi-value result that can produce branches in three
+                // directions:
                 //
-                // The first result is a boolean (like in the Erlang calling convention) that indicates whether the timeout
-                // argument itself was valid.
+                // The first result is a boolean (like in the Erlang calling convention) that
+                // indicates whether the timeout argument itself was valid.
                 //
-                // If the timeout was valid, then the second result is a boolean term indicating whether or not the timeout
-                // expired.
+                // If the timeout was valid, then the second result is a boolean term indicating
+                // whether or not the timeout expired.
                 //
-                // If the timeout was invalid, then the second result is an exception, which should then be raised based on
-                // the current failure context
+                // If the timeout was invalid, then the second result is an exception, which should
+                // then be raised based on the current failure context
                 let inst = builder.ins().call(callee, &[], span);
                 let (is_err, result) = {
                     let results = builder.inst_results(inst);
@@ -1216,7 +1227,8 @@ impl<'m> LowerFunctionToSsa<'m> {
                 builder.define_var(bif.ret[0].as_var().map(|v| v.name()).unwrap(), trace);
                 Ok(())
             }
-            // The nif_start instruction is simply a marker for now, we don't have any reason to emit it to SSA
+            // The nif_start instruction is simply a marker for now, we don't have any reason to
+            // emit it to SSA
             (symbols::NifStart, _) => {
                 assert_eq!(
                     bif.args.len(),
@@ -1236,7 +1248,8 @@ impl<'m> LowerFunctionToSsa<'m> {
                 let error1 = FunctionName::new(symbols::Erlang, symbols::Error, 1);
                 let callee = self.module.get_or_register_builtin(error1);
                 // If this is a function or case clause error, the arity is dynamic, but we need
-                // to convert the argument list into an appropriate form for calling erlang:match_fail/2
+                // to convert the argument list into an appropriate form for calling
+                // erlang:match_fail/2
                 let (is_err, exception) = match bif.args[0].as_atom() {
                     Some(symbols::FunctionClause) => {
                         let mut args = self.ssa_values(builder, bif.args)?;
@@ -1325,7 +1338,8 @@ impl<'m> LowerFunctionToSsa<'m> {
                     }
                     FailContext::Catch(blk) => {
                         // This is a match failure or thrown exception in the presence of a local
-                        // handler, so we can jump straight to the handler with the exception that was constructed
+                        // handler, so we can jump straight to the handler with the exception that
+                        // was constructed
                         builder.ins().br(blk, &[exception], span);
                         Ok(())
                     }
@@ -1365,7 +1379,8 @@ impl<'m> LowerFunctionToSsa<'m> {
                     }
                     FailContext::Catch(blk) => {
                         // This is a match failure or thrown exception in the presence of a local
-                        // handler, so we can jump straight to the handler with the exception that was constructed
+                        // handler, so we can jump straight to the handler with the exception that
+                        // was constructed
                         builder.ins().br(blk, &[exception], span);
                         Ok(())
                     }
@@ -1511,39 +1526,45 @@ impl<'m> LowerFunctionToSsa<'m> {
         let handler_block = builder.create_block();
         let exception = builder.append_block_param(handler_block, Type::Exception, span);
 
-        // The result block is where the fork in control is rejoined, it receives a single block argument which is
-        // either the normal return value, or the caught/wrapped exception value
+        // The result block is where the fork in control is rejoined, it receives a single block
+        // argument which is either the normal return value, or the caught/wrapped exception
+        // value
         let result_block = builder.create_block();
         let result = builder.append_block_param(result_block, Type::Term(TermType::Any), span);
         builder.define_var(ret, result);
 
         // The exit block handles wrapping exit/error reasons in the {'EXIT', Reason} tuple
-        // It receives a single block argument which corresponds to `Reason` in the previous sentence.
+        // It receives a single block argument which corresponds to `Reason` in the previous
+        // sentence.
         let exit_block = builder.create_block();
         let exit_reason = builder.append_block_param(exit_block, Type::Term(TermType::Any), span);
 
         builder.switch_to_block(handler_block);
         let class = builder.ins().exception_class(exception, span);
         let reason = builder.ins().exception_reason(exception, span);
-        // Throws are the most common, and require no special handling, so we jump straight to the result block for them
+        // Throws are the most common, and require no special handling, so we jump straight to the
+        // result block for them
         let is_throw = builder
             .ins()
             .eq_exact_imm(class, symbols::Throw.into(), span);
         builder.ins().br_if(is_throw, result_block, &[reason], span);
-        // Exits are the next simplest, as we just wrap the reason in a tuple, so we jump straight to the exit block
+        // Exits are the next simplest, as we just wrap the reason in a tuple, so we jump straight
+        // to the exit block
         let is_exit = builder
             .ins()
             .eq_exact_imm(class, symbols::Exit.into(), span);
         builder.ins().br_if(is_exit, exit_block, &[reason], span);
         // Errors are handled in the landing pad directly
         let trace = builder.ins().exception_trace(exception, span);
-        // We have to construct a new error reason, and then jump to the exit block to wrap it in the exit tuple
+        // We have to construct a new error reason, and then jump to the exit block to wrap it in
+        // the exit tuple
         let error_reason = builder.ins().tuple_imm(2, span);
         let error_reason = builder.ins().set_element_mut(error_reason, 0, reason, span);
         let error_reason = builder.ins().set_element_mut(error_reason, 1, trace, span);
         builder.ins().br(exit_block, &[error_reason], span);
 
-        // In the exit block, we need just to construct the {'EXIT', Reason} tuple, and then jump to the result block
+        // In the exit block, we need just to construct the {'EXIT', Reason} tuple, and then jump to
+        // the result block
         builder.switch_to_block(exit_block);
         let wrapped_reason = builder.ins().tuple_imm(2, span);
         let wrapped_reason =
diff --git a/compiler/syntax_pp/src/parser/mod.rs b/compiler/syntax_pp/src/parser/mod.rs
index 6251793d2..59b40d899 100644
--- a/compiler/syntax_pp/src/parser/mod.rs
+++ b/compiler/syntax_pp/src/parser/mod.rs
@@ -35,13 +35,13 @@ pub(crate) mod grammar {
 }
 
 use firefly_beam::beam::AbstractCode;
-use firefly_diagnostics::{ToDiagnostic, Diagnostic, Label, Reporter, SourceSpan};
+use firefly_diagnostics::{Diagnostic, Label, Reporter, SourceSpan, ToDiagnostic};
 use firefly_parser::{Parse, Parser, Scanner, Source};
 
 use crate::ast::{self, Form};
 
 /// Parses forms from the given AbstractCode object
-pub from_abstract_code(code: &AbstractCode) -> anyhow::Result<Form> {
+pub fn from_abstract_code(code: &AbstractCode) -> anyhow::Result<Form> {
     use firefly_beam::serialization::etf::pattern::VarList;
 
     let (_, form) = code
@@ -61,11 +61,7 @@ impl Parse for ast::Root {
         ParseError::RootFileError { source, path }
     }
 
-    fn parse<S>(
-        _parser: &Parser<Self::Config>,
-        reporter: Reporter,
-        source: S,
-    ) -> Result<Self, ()>
+    fn parse<S>(_parser: &Parser<Self::Config>, reporter: Reporter, source: S) -> Result<Self, ()>
     where
         S: Source,
     {
diff --git a/compiler/syntax_ssa/src/ir/dataflow.rs b/compiler/syntax_ssa/src/ir/dataflow.rs
index 8c26c84e3..744166e7c 100644
--- a/compiler/syntax_ssa/src/ir/dataflow.rs
+++ b/compiler/syntax_ssa/src/ir/dataflow.rs
@@ -48,7 +48,8 @@ impl DataFlowGraph {
         Ref::map(self.signatures.borrow(), |sigs| sigs.get(callee).unwrap())
     }
 
-    /// Looks up the concrete function for the given MFA (module of None indicates that it is a local or imported function)
+    /// Looks up the concrete function for the given MFA (module of None indicates that it is a
+    /// local or imported function)
     pub fn get_callee(&self, mfa: FunctionName) -> Option<FuncRef> {
         self.callees.borrow().get(&mfa).copied()
     }
@@ -141,7 +142,8 @@ impl DataFlowGraph {
         self.results[inst].clear(&mut self.value_lists);
         let opcode = self.insts[inst].opcode();
         if let Some(fdata) = self.call_signature(inst) {
-            // Tail calls are equivalent to return, they don't have results that are materialized as values
+            // Tail calls are equivalent to return, they don't have results that are materialized as
+            // values
             if opcode == Opcode::Enter || opcode == Opcode::EnterIndirect {
                 return 0;
             }
@@ -165,21 +167,24 @@ impl DataFlowGraph {
                     self.append_result(inst, ty);
                     2
                 }
-                // Initializing a binary match is a fallible operation that produces a match context when successful
+                // Initializing a binary match is a fallible operation that produces a match context
+                // when successful
                 Opcode::BitsMatchStart => {
                     self.append_result(inst, Type::Primitive(PrimitiveType::I1));
                     self.append_result(inst, Type::Term(TermType::Any));
                     2
                 }
-                // Binary matches produce three results, an error flag, the matched value, and the rest of the binary
+                // Binary matches produce three results, an error flag, the matched value, and the
+                // rest of the binary
                 Opcode::BitsMatch => {
                     self.append_result(inst, Type::Primitive(PrimitiveType::I1));
                     self.append_result(inst, ty);
                     self.append_result(inst, Type::Term(TermType::Any));
                     3
                 }
-                // This is an optimized form of BitsMatch that skips extraction of the term to be matched and just
-                // advances the position in the underlying match context
+                // This is an optimized form of BitsMatch that skips extraction of the term to be
+                // matched and just advances the position in the underlying match
+                // context
                 Opcode::BitsMatchSkip => {
                     self.append_result(inst, Type::Primitive(PrimitiveType::I1));
                     self.append_result(inst, Type::Term(TermType::Any));
@@ -188,7 +193,8 @@ impl DataFlowGraph {
                 // Binary construction produces two results, an error flag and the new binary value
                 Opcode::BitsPush => {
                     self.append_result(inst, Type::Primitive(PrimitiveType::I1));
-                    // This value is either the none term or an exception, depending on the is_err flag
+                    // This value is either the none term or an exception, depending on the is_err
+                    // flag
                     self.append_result(inst, Type::Term(TermType::Any));
                     2
                 }
diff --git a/compiler/syntax_ssa/src/ir/instructions.rs b/compiler/syntax_ssa/src/ir/instructions.rs
index d1662de98..577f6baf0 100644
--- a/compiler/syntax_ssa/src/ir/instructions.rs
+++ b/compiler/syntax_ssa/src/ir/instructions.rs
@@ -406,9 +406,11 @@ impl Opcode {
             Self::Tuple => 1,
             // Getting a tuple element takes the tuple and the index of the element
             Self::GetElement => 2,
-            // Setting a tuple element takes two value arguments, the tuple, and the element, the index is immediate
+            // Setting a tuple element takes two value arguments, the tuple, and the element, the
+            // index is immediate
             Self::SetElement | Self::SetElementMut => 2,
-            // Cons constructors/concat/subtract take two arguments, the head and tail elements/lists
+            // Cons constructors/concat/subtract take two arguments, the head and tail
+            // elements/lists
             Self::Cons | Self::ListConcat | Self::ListSubtract => 2,
             // Creating a fun only requires the callee, the environment is variable-sized
             Self::MakeFun => 0,
@@ -430,7 +432,8 @@ impl Opcode {
             Self::RecvNext | Self::RecvPeek | Self::RecvPop | Self::RecvWait | Self::RecvDone => 1,
             // These exception primops expect the exception value
             Self::ExceptionClass | Self::ExceptionReason | Self::ExceptionTrace => 1,
-            // These primops expect either no arguments, an immediate or a value, so the number is not fixed
+            // These primops expect either no arguments, an immediate or a value, so the number is
+            // not fixed
             Self::BitsMatchStart | Self::NifStart => 0,
             // Raising errors requires the class, the error value, and the stacktrace
             Self::Raise => 3,
diff --git a/compiler/syntax_ssa/src/ir/layout.rs b/compiler/syntax_ssa/src/ir/layout.rs
index c4e17e5e6..ac81a31bf 100644
--- a/compiler/syntax_ssa/src/ir/layout.rs
+++ b/compiler/syntax_ssa/src/ir/layout.rs
@@ -2,9 +2,9 @@ use std::ops::{Index, IndexMut};
 use std::ptr::NonNull;
 
 use cranelift_entity::EntityRef;
+use firefly_arena::TypedArena;
 use intrusive_collections::linked_list::{Cursor, CursorMut, LinkedList};
 use intrusive_collections::{intrusive_adapter, LinkedListLink, UnsafeRef};
-use firefly_arena::TypedArena;
 
 /// This struct holds the data for each node in an ArenaMap/OrderedArenaMap
 #[derive(Clone)]
@@ -44,22 +44,25 @@ intrusive_adapter!(pub LayoutAdapter<K, V> = UnsafeRef<LayoutNode<K, V>>: Layout
 ///
 /// # Pros
 ///
-/// * Once allocated, values stored in the map have a stable location, this can be useful for when you
+/// * Once allocated, values stored in the map have a stable location, this can be useful for when
+///   you
 /// expect to store elements of the map in an intrusive collection.
-/// * Keys can be more efficiently sized, i.e. rather than pointers/usize keys, you can choose arbitrarily
+/// * Keys can be more efficiently sized, i.e. rather than pointers/usize keys, you can choose
+///   arbitrarily
 /// small bitwidths, as long as there is sufficient keyspace for your use case.
-/// * Attempt to keep data in the map as contiguous in memory as possible. This is again useful for when
-/// the data is also linked into an intrusive collection, like a linked list, where traversing the list
-/// will end up visiting many of the nodes in the map. If each node was its own Box, this would cause
-/// thrashing of the cache - ArenaMap sidesteps this by allocating values in chunks of memory that are
-/// friendlier to the cache.
+/// * Attempt to keep data in the map as contiguous in memory as possible. This is again useful for
+///   when
+/// the data is also linked into an intrusive collection, like a linked list, where traversing the
+/// list will end up visiting many of the nodes in the map. If each node was its own Box, this would
+/// cause thrashing of the cache - ArenaMap sidesteps this by allocating values in chunks of memory
+/// that are friendlier to the cache.
 ///
 /// # Cons
 ///
 /// * Memory allocated for data stored in the map is not released until the map is dropped. This is
-/// a tradeoff made to ensure that the data has a stable location in memory, but the flip side of that
-/// is increased memory usage for maps that stick around for a long time. In our case, these maps are
-/// relatively short-lived, so it isn't a problem in practice.
+/// a tradeoff made to ensure that the data has a stable location in memory, but the flip side of
+/// that is increased memory usage for maps that stick around for a long time. In our case, these
+/// maps are relatively short-lived, so it isn't a problem in practice.
 /// * It doesn't provide as rich of an API as HashMap and friends
 pub struct ArenaMap<K: EntityRef, V: Clone> {
     keys: Vec<Option<NonNull<V>>>,
@@ -195,16 +198,18 @@ impl<K: EntityRef, V: Clone> IndexMut<K> for ArenaMap<K, V> {
 /// OrderedArenaMap is an extension of ArenaMap that provides for arbitrary ordering of keys/values
 ///
 /// This is done using an intrusive linked list alongside an ArenaMap. The list is used to link one
-/// key/value pair to the next, so any ordering you wish to implement is possible. This is particularly
-/// useful for layout of blocks in a function, or instructions within blocks, as you can precisely position
-/// them relative to other blocks/instructions.
+/// key/value pair to the next, so any ordering you wish to implement is possible. This is
+/// particularly useful for layout of blocks in a function, or instructions within blocks, as you
+/// can precisely position them relative to other blocks/instructions.
 ///
 /// Because the linked list is intrusive, it is virtually free in terms of space, but comes with the
-/// standard overhead for traversals. That said, there are a couple of niceties that give it good overall
-/// performance:
+/// standard overhead for traversals. That said, there are a couple of niceties that give it good
+/// overall performance:
 ///
-/// * It is a doubly-linked list, so you can traverse equally efficiently front-to-back or back-to-front,
-/// * It has O(1) indexing; given a key, we can directly obtain a reference to a node, and with that,
+/// * It is a doubly-linked list, so you can traverse equally efficiently front-to-back or
+///   back-to-front,
+/// * It has O(1) indexing; given a key, we can directly obtain a reference to a node, and with
+///   that,
 /// obtain a cursor over the list starting at that node.
 pub struct OrderedArenaMap<K: EntityRef, V: Clone> {
     list: LinkedList<LayoutAdapter<K, V>>,
@@ -267,7 +272,8 @@ impl<K: EntityRef, V: Clone> OrderedArenaMap<K, V> {
         self.map.get(key).map(|data| data.value())
     }
 
-    /// Returns a mutable reference to the value associated with the given key, if present and linked
+    /// Returns a mutable reference to the value associated with the given key, if present and
+    /// linked
     pub fn get_mut(&mut self, key: K) -> Option<&mut V> {
         self.map.get_mut(key).map(|data| data.value_mut())
     }
@@ -278,7 +284,8 @@ impl<K: EntityRef, V: Clone> OrderedArenaMap<K, V> {
         self.map.alloc_key()
     }
 
-    /// Used with `create` when ready to associate data with the allocated key, linking it in to the end of the list
+    /// Used with `create` when ready to associate data with the allocated key, linking it in to the
+    /// end of the list
     pub fn append(&mut self, key: K, value: V) {
         debug_assert!(!self.contains(key));
         let data = self.alloc_node(key, value);
@@ -353,8 +360,8 @@ impl<K: EntityRef, V: Clone> OrderedArenaMap<K, V> {
         unsafe { self.list.cursor_from_ptr(ptr) }
     }
 
-    /// Returns a cursor which can be used to traverse the map mutably, in order (front to back), starting
-    /// at the key given.
+    /// Returns a cursor which can be used to traverse the map mutably, in order (front to back),
+    /// starting at the key given.
     pub fn cursor_mut_at(&mut self, key: K) -> CursorMut<'_, LayoutAdapter<K, V>> {
         let ptr = &self.map[key] as *const LayoutNode<K, V>;
         unsafe { self.list.cursor_mut_from_ptr(ptr) }
diff --git a/compiler/syntax_ssa/src/ir/module.rs b/compiler/syntax_ssa/src/ir/module.rs
index 1b0e0c0f7..72a7652f6 100644
--- a/compiler/syntax_ssa/src/ir/module.rs
+++ b/compiler/syntax_ssa/src/ir/module.rs
@@ -25,12 +25,14 @@ pub struct Module {
     pub name: Ident,
     /// This is the list of functions defined in this module
     pub functions: Vec<Function>,
-    /// This map associates known functions (locals, builtins, imports, or externals) to a reference value
+    /// This map associates known functions (locals, builtins, imports, or externals) to a
+    /// reference value
     pub signatures: Rc<RefCell<PrimaryMap<FuncRef, Signature>>>,
-    /// This map provides a quick way to look up function references given an MFA, useful when lowering
+    /// This map provides a quick way to look up function references given an MFA, useful when
+    /// lowering
     pub callees: Rc<RefCell<BTreeMap<FunctionName, FuncRef>>>,
-    /// This map provides a quick way to look up function references for native functions which do not
-    /// use our naming convention
+    /// This map provides a quick way to look up function references for native functions which do
+    /// not use our naming convention
     pub natives: Rc<RefCell<BTreeMap<Symbol, FuncRef>>>,
     /// This pool contains de-duplicated constant values/data used in the current module
     pub constants: Rc<RefCell<ConstantPool>>,
@@ -115,7 +117,8 @@ impl Module {
 
     /// Imports a function from another module into scope as if defined in the current module
     ///
-    /// The returned reference may be modified to refer to another function if a shadowing declaration is created later
+    /// The returned reference may be modified to refer to another function if a shadowing
+    /// declaration is created later
     pub fn import_function(&mut self, mut signature: Signature) -> FuncRef {
         assert!(
             signature.module != self.name.name,
@@ -270,17 +273,20 @@ impl Module {
         Ref::map(self.signatures.borrow(), |sigs| sigs.get(callee).unwrap())
     }
 
-    /// Looks up the concrete function for the given MFA (module of None indicates that it is a local or imported function)
+    /// Looks up the concrete function for the given MFA (module of None indicates that it is a
+    /// local or imported function)
     pub fn get_callee(&self, mfa: FunctionName) -> Option<FuncRef> {
         self.callees.borrow().get(&mfa).copied()
     }
 
-    /// Returns a reference to the definition of the given funcref, if it refers to a local definition
+    /// Returns a reference to the definition of the given funcref, if it refers to a local
+    /// definition
     pub fn get_function(&self, id: FuncRef) -> Option<&Function> {
         self.functions.iter().find(|f| f.id == id)
     }
 
-    /// Returns a mutable reference to the definition of the given funcref, if it refers to a local definition
+    /// Returns a mutable reference to the definition of the given funcref, if it refers to a local
+    /// definition
     pub fn get_function_mut(&mut self, id: FuncRef) -> Option<&mut Function> {
         self.functions.iter_mut().find(|f| f.id == id)
     }
diff --git a/compiler/target/src/spec.rs b/compiler/target/src/spec.rs
index 7418ba0b1..5943d5064 100644
--- a/compiler/target/src/spec.rs
+++ b/compiler/target/src/spec.rs
@@ -607,16 +607,18 @@ pub struct TargetOptions {
     pub os: Cow<'static, str>,
     /// Environment name to use for conditional compilation. Defaults to "".
     pub env: Cow<'static, str>,
-    /// ABI name to distinguish multiple ABIs on the same OS and architecture, e.g. "eabihf". Defaults to "".
+    /// ABI name to distinguish multiple ABIs on the same OS and architecture, e.g. "eabihf".
+    /// Defaults to "".
     pub abi: Cow<'static, str>,
     /// Vendor name to use for conditional compilation. Defaults to "unknown".
     pub vendor: Cow<'static, str>,
-    /// Default linker flavor used if `-C linker-flavor` or `-C linker` are not passed on the command line.
-    /// Defaults to `LinkerFlavor::Gcc`.
+    /// Default linker flavor used if `-C linker-flavor` or `-C linker` are not passed on the
+    /// command line. Defaults to `LinkerFlavor::Gcc`.
     pub linker_flavor: LinkerFlavor,
     /// Linker to invoke
     pub linker: Option<Cow<'static, str>>,
-    /// LLD flavor used if `lld` (or `firefly-lld`) is specified as a linker without clarifying its flavor
+    /// LLD flavor used if `lld` (or `firefly-lld`) is specified as a linker without clarifying its
+    /// flavor
     pub lld_flavor: LldFlavor,
 
     /// Linker arguments that are passed *before* any user-defined libraries.
@@ -716,8 +718,8 @@ pub struct TargetOptions {
     pub is_like_windows: bool,
     /// Whether the target is like MSVC.
     /// This is a combination of several more specific properties represented as a single flag:
-    ///   - The target has all the properties from `is_like_windows`
-    ///     (for in-tree targets "is_like_msvc ⇒ is_like_windows" is ensured by a unit test),
+    ///   - The target has all the properties from `is_like_windows` (for in-tree targets
+    ///     "is_like_msvc ⇒ is_like_windows" is ensured by a unit test),
     ///   - has some MSVC-specific Windows ABI properties,
     ///   - uses a link.exe-like linker,
     ///   - uses CodeView/PDB for debuginfo and natvis for its visualization,
diff --git a/compiler/target/src/spec/crt_objects.rs b/compiler/target/src/spec/crt_objects.rs
index e7d045604..a4b20e972 100644
--- a/compiler/target/src/spec/crt_objects.rs
+++ b/compiler/target/src/spec/crt_objects.rs
@@ -5,16 +5,20 @@
 //! The `crtx` ones are generally distributed with libc and the `begin/end` ones with gcc.
 //! See <https://dev.gentoo.org/~vapier/crt.txt> for some more details.
 //!
-//! | Pre-link CRT objects | glibc                  | musl                   | bionic           | mingw             | wasi         |
+//! | Pre-link CRT objects | glibc                  | musl                   | bionic           |
+//! mingw             | wasi         |
 //! |----------------------|------------------------|------------------------|------------------|-------------------|--------------|
-//! | dynamic-nopic-exe    | crt1, crti, crtbegin   | crt1, crti, crtbegin   | crtbegin_dynamic | crt2, crtbegin    | crt1         |
-//! | dynamic-pic-exe      | Scrt1, crti, crtbeginS | Scrt1, crti, crtbeginS | crtbegin_dynamic | crt2, crtbegin    | crt1         |
-//! | static-nopic-exe     | crt1, crti, crtbeginT  | crt1, crti, crtbegin   | crtbegin_static  | crt2, crtbegin    | crt1         |
-//! | static-pic-exe       | rcrt1, crti, crtbeginS | rcrt1, crti, crtbeginS | crtbegin_dynamic | crt2, crtbegin    | crt1         |
-//! | dynamic-dylib        | crti, crtbeginS        | crti, crtbeginS        | crtbegin_so      | dllcrt2, crtbegin | -            |
-//! | static-dylib (gcc)   | crti, crtbeginT        | crti, crtbeginS        | crtbegin_so      | dllcrt2, crtbegin | -            |
-//! | static-dylib (clang) | crti, crtbeginT        | N/A                    | crtbegin_static  | dllcrt2, crtbegin | -            |
-//! | wasi-reactor-exe     | N/A                    | N/A                    | N/A              | N/A               | crt1-reactor |
+//! | dynamic-nopic-exe    | crt1, crti, crtbegin   | crt1, crti, crtbegin   | crtbegin_dynamic |
+//! crt2, crtbegin    | crt1         | | dynamic-pic-exe      | Scrt1, crti, crtbeginS | Scrt1,
+//! crti, crtbeginS | crtbegin_dynamic | crt2, crtbegin    | crt1         | | static-nopic-exe     |
+//! crt1, crti, crtbeginT  | crt1, crti, crtbegin   | crtbegin_static  | crt2, crtbegin    | crt1
+//! | | static-pic-exe       | rcrt1, crti, crtbeginS | rcrt1, crti, crtbeginS | crtbegin_dynamic |
+//! crt2, crtbegin    | crt1         | | dynamic-dylib        | crti, crtbeginS        | crti,
+//! crtbeginS        | crtbegin_so      | dllcrt2, crtbegin | -            | | static-dylib (gcc)
+//! | crti, crtbeginT        | crti, crtbeginS        | crtbegin_so      | dllcrt2, crtbegin | -
+//! | | static-dylib (clang) | crti, crtbeginT        | N/A                    | crtbegin_static  |
+//! dllcrt2, crtbegin | -            | | wasi-reactor-exe     | N/A                    | N/A
+//! | N/A              | N/A               | crt1-reactor |
 //!
 //! | Post-link CRT objects | glibc         | musl          | bionic         | mingw  | wasi |
 //! |-----------------------|---------------|---------------|----------------|--------|------|
diff --git a/compiler/unwind/src/lib.rs b/compiler/unwind/src/lib.rs
index 970aa109d..1a2428e34 100644
--- a/compiler/unwind/src/lib.rs
+++ b/compiler/unwind/src/lib.rs
@@ -35,7 +35,12 @@ cfg_if::cfg_if! {
 }
 
 #[cfg(target_env = "musl")]
-#[link(name = "unwind", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))]
+#[link(
+    name = "unwind",
+    kind = "static",
+    modifiers = "-bundle",
+    cfg(target_feature = "crt-static")
+)]
 #[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))]
 extern "C" {}
 
diff --git a/compiler/util/src/emit.rs b/compiler/util/src/emit.rs
index d111455b7..9c511105a 100644
--- a/compiler/util/src/emit.rs
+++ b/compiler/util/src/emit.rs
@@ -1,4 +1,4 @@
-/// A type is emittable when there is a canonical textual/binary representation 
+/// A type is emittable when there is a canonical textual/binary representation
 /// which can be written to a file with a well-known file type.
 ///
 /// Examples of this relevant to Firefly are:
@@ -13,7 +13,6 @@
 /// * Static Libraries, which have a canonical binary format with the `.a` extension
 /// * Dynamic Libraries, which have a canonical binary format with a platform-specific extension
 /// * Executables, which have a canonical binary format with platform-specific extension
-///
 pub trait Emit {
     /// Returns the extension to which this object is associated
     ///
diff --git a/liblumen_alloc/Cargo.toml b/liblumen_alloc/Cargo.toml
index c3062b995..4991f70e1 100644
--- a/liblumen_alloc/Cargo.toml
+++ b/liblumen_alloc/Cargo.toml
@@ -16,7 +16,6 @@ cfg-if = "1.0"
 dashmap = "5.2"
 heapless = "0.7"
 lazy_static = "1.4"
-liblumen_core = { path = "../library/core" }
 liblumen_arena = { path = "../library/arena"}
 liblumen_alloc_macros = { path = "../liblumen_alloc_macros" }
 liblumen_term = { path = "../compiler/term" }
diff --git a/library/alloc/src/gc/boxed/gcbox.rs b/library/alloc/src/gc/boxed/gcbox.rs
index 9d8900cb5..9880f17ec 100644
--- a/library/alloc/src/gc/boxed/gcbox.rs
+++ b/library/alloc/src/gc/boxed/gcbox.rs
@@ -154,9 +154,9 @@ where
     ///
     /// In our case, we have opaque pointers on process heaps that are always allocated via GcBox,
     /// and we need to be able to cast them back to their original types efficiently. To do so, we
-    /// use a combination of this function, a jump table of type ids, and subsequent unchecked casts.
-    /// This allows for efficient pointer casts while ensuring we don't improperly cast a pointer to
-    /// the wrong type.
+    /// use a combination of this function, a jump table of type ids, and subsequent unchecked
+    /// casts. This allows for efficient pointer casts while ensuring we don't improperly cast a
+    /// pointer to the wrong type.
     pub unsafe fn type_id(raw: *mut ()) -> TypeId {
         debug_assert!(!raw.is_null());
         let header = &*header(raw);
diff --git a/library/alloc/src/heap/mod.rs b/library/alloc/src/heap/mod.rs
index 0423de073..f63e085b5 100644
--- a/library/alloc/src/heap/mod.rs
+++ b/library/alloc/src/heap/mod.rs
@@ -18,7 +18,6 @@ use core::ptr::NonNull;
 /// roots, we can trace references of those objects, determine whether or not they are allocated
 /// in a specific heap, and from there, decide what to do with them. See `GcBox` for the container
 /// type we use to allocate on `Heap` implementations, and how tracing works.
-///
 pub trait Heap: Allocator {
     /// Returns the address of the first addressable byte of the heap.
     ///
@@ -29,8 +28,8 @@ pub trait Heap: Allocator {
     ///
     /// On a new heap, this will return the same address as `heap_start`.
     /// If a heap was perfectly filled, this would return the same address as `heap_end`.
-    /// On a heap with at least one allocation, this will return the address of the first byte following
-    /// the last allocation.
+    /// On a heap with at least one allocation, this will return the address of the first byte
+    /// following the last allocation.
     fn heap_top(&self) -> *mut u8;
 
     /// Returns the address `heap_end` in the exclusive range `heap_start..heap_end`, i.e. it is
@@ -49,16 +48,16 @@ pub trait Heap: Allocator {
         (self.heap_start() as *const u8)..(self.heap_end() as *const u8)
     }
 
-    /// Returns the location on this heap where a garbage collection cycle last stopped, if this heap
-    /// is generational, and at least one collection has occurred.
+    /// Returns the location on this heap where a garbage collection cycle last stopped, if this
+    /// heap is generational, and at least one collection has occurred.
     ///
     /// Defaults to `None`.
     ///
     /// Implementations should override this function if they are generational, and should return a
-    /// pointer value that is somewhere in the range `heap_start..heap_end` and divides the heap into
-    /// two regions: mature and immature allocations. In other words, any allocation below the high
-    /// water mark is considered a mature allocation that has survived at least one collection cycle,
-    /// and is thus more likely to survive subsequent collections.
+    /// pointer value that is somewhere in the range `heap_start..heap_end` and divides the heap
+    /// into two regions: mature and immature allocations. In other words, any allocation below
+    /// the high water mark is considered a mature allocation that has survived at least one
+    /// collection cycle, and is thus more likely to survive subsequent collections.
     #[inline]
     fn high_water_mark(&self) -> Option<NonNull<u8>> {
         None
@@ -66,8 +65,8 @@ pub trait Heap: Allocator {
 
     /// Returns the total size in bytes of the addressable heap
     ///
-    /// NOTE: The allocation backing this heap may actually be larger than this size, it only reflects
-    /// how large the heap appears to be to consumers of this trait.
+    /// NOTE: The allocation backing this heap may actually be larger than this size, it only
+    /// reflects how large the heap appears to be to consumers of this trait.
     #[inline]
     fn heap_size(&self) -> usize {
         unsafe { self.heap_end().offset_from(self.heap_start()) as usize }
diff --git a/library/alloc/src/heap/semispace.rs b/library/alloc/src/heap/semispace.rs
index a0463c7af..9b339ebd1 100644
--- a/library/alloc/src/heap/semispace.rs
+++ b/library/alloc/src/heap/semispace.rs
@@ -31,18 +31,19 @@ use super::{GenerationalHeap, Heap};
 ///
 /// 2. The first minor GC cycle occurs. During this cycle, a new immature heap is allocated,
 /// and live values reachable from the root set will be moved to the new heap. A high water mark
-/// will be set, indicating where the heap was at when the cycle ended. The old immature heap is freed.
+/// will be set, indicating where the heap was at when the cycle ended. The old immature heap is
+/// freed.
 ///
 /// 3. The second minor GC cycle occurs. During this cycle, a new immature heap is allocated, but
-/// additionally, a mature heap is allocated with enough space to hold the old immature heap, replacing
-/// the initial empty mature heap. Objects in the mature region of the immature heap (i.e. allocations
-/// below the high-water mark) are moved to the mature heap. Objects above the high water mark are moved
-/// to the new immature heap.
+/// additionally, a mature heap is allocated with enough space to hold the old immature heap,
+/// replacing the initial empty mature heap. Objects in the mature region of the immature heap (i.e.
+/// allocations below the high-water mark) are moved to the mature heap. Objects above the high
+/// water mark are moved to the new immature heap.
 ///
-/// 4. During this phase, some number of minor GC cycles will occur, until the mature heap fills up and
-/// needs to grow. When this happens, a major GC cycle occurs. During a major GC cycle, a new mature heap
-/// is allocated and live matured objects from both heaps are swept into the new mature heap. The old mature
-/// heap becomes the new immature heap, and the old immature heap is freed.
+/// 4. During this phase, some number of minor GC cycles will occur, until the mature heap fills up
+/// and needs to grow. When this happens, a major GC cycle occurs. During a major GC cycle, a new
+/// mature heap is allocated and live matured objects from both heaps are swept into the new mature
+/// heap. The old mature heap becomes the new immature heap, and the old immature heap is freed.
 #[derive(Debug)]
 pub struct SemispaceHeap<A, B>
 where
diff --git a/library/alloc/src/mmap.rs b/library/alloc/src/mmap.rs
index 73d48ed4b..624e4050e 100644
--- a/library/alloc/src/mmap.rs
+++ b/library/alloc/src/mmap.rs
@@ -1,4 +1,5 @@
-// This module provides the fallback implementation of mmap primitives on platforms which do not provide them
+// This module provides the fallback implementation of mmap primitives on platforms which do not
+// provide them
 #[cfg(any(target_arch = "wasm32", target_arch = "wasm64"))]
 mod fallback {
     use alloc::alloc::{AllocError, Layout};
@@ -24,7 +25,8 @@ mod fallback {
         sys::alloc::allocate(layout).map(|ptr| ptr.cast())
     }
 
-    /// Remaps a mapping given a pointer to the mapping, the layout which created it, and the new size
+    /// Remaps a mapping given a pointer to the mapping, the layout which created it, and the new
+    /// size
     #[inline]
     pub unsafe fn remap(
         ptr: *mut u8,
@@ -73,7 +75,8 @@ mod real {
         sys::mmap::map_stack(pages)
     }
 
-    /// Remaps a mapping given a pointer to the mapping, the layout which created it, and the new size
+    /// Remaps a mapping given a pointer to the mapping, the layout which created it, and the new
+    /// size
     #[inline]
     pub unsafe fn remap(
         ptr: *mut u8,
diff --git a/library/alloc/src/rc/mod.rs b/library/alloc/src/rc/mod.rs
index f40604fd0..0740487c8 100644
--- a/library/alloc/src/rc/mod.rs
+++ b/library/alloc/src/rc/mod.rs
@@ -69,9 +69,9 @@ where
     ///
     /// In our case, we have opaque pointers on process heaps that are always allocated via Rc,
     /// and we need to be able to cast them back to their original types efficiently. To do so, we
-    /// use a combination of this function, a jump table of type ids, and subsequent unchecked casts.
-    /// This allows for efficient pointer casts while ensuring we don't improperly cast a pointer to
-    /// the wrong type.
+    /// use a combination of this function, a jump table of type ids, and subsequent unchecked
+    /// casts. This allows for efficient pointer casts while ensuring we don't improperly cast a
+    /// pointer to the wrong type.
     #[inline]
     pub unsafe fn type_id(raw: *mut ()) -> TypeId {
         Rc::<T>::type_id(raw)
@@ -337,9 +337,9 @@ where
     ///
     /// In our case, we have opaque pointers on process heaps that are always allocated via Rc,
     /// and we need to be able to cast them back to their original types efficiently. To do so, we
-    /// use a combination of this function, a jump table of type ids, and subsequent unchecked casts.
-    /// This allows for efficient pointer casts while ensuring we don't improperly cast a pointer to
-    /// the wrong type.
+    /// use a combination of this function, a jump table of type ids, and subsequent unchecked
+    /// casts. This allows for efficient pointer casts while ensuring we don't improperly cast a
+    /// pointer to the wrong type.
     pub unsafe fn type_id(raw: *mut ()) -> TypeId {
         debug_assert!(!raw.is_null());
         let header = &*header(raw);
@@ -444,10 +444,11 @@ where
     /// Makes a mutable reference into the given `Rc`.
     ///
     /// If there are other `Rc` pointers to the same allocation, then this function will
-    /// clone the underlying data to a new allocation to ensure unique ownership, i.e. clone-on-write.
+    /// clone the underlying data to a new allocation to ensure unique ownership, i.e.
+    /// clone-on-write.
     ///
-    /// See `get_mut` for a non-cloning version of this, with the tradeoff that it can only be used on
-    /// unique references.
+    /// See `get_mut` for a non-cloning version of this, with the tradeoff that it can only be used
+    /// on unique references.
     pub fn make_mut(this: &mut Self) -> &mut T {
         if this.is_unique() {
             unsafe { Self::get_mut_unchecked(this) }
diff --git a/library/alloc/src/utils.rs b/library/alloc/src/utils.rs
index 0c3dc0781..8b11d5eb2 100644
--- a/library/alloc/src/utils.rs
+++ b/library/alloc/src/utils.rs
@@ -136,10 +136,11 @@ pub fn ensure_aligned<T: ?Sized>(ptr: *mut T, align: usize) -> (*mut T, usize) {
     (aligned, offset)
 }
 
-/// Returns the effective alignment of `ptr`, i.e. the largest power of two that is a divisor of `ptr`
+/// Returns the effective alignment of `ptr`, i.e. the largest power of two that is a divisor of
+/// `ptr`
 ///
-/// NOTE: This may return unusually high alignments if the address happens to be sitting at the boundary
-/// of a large address with mostly zeros.
+/// NOTE: This may return unusually high alignments if the address happens to be sitting at the
+/// boundary of a large address with mostly zeros.
 #[inline(always)]
 pub fn effective_alignment<T: ?Sized>(ptr: *const T) -> usize {
     1usize << (ptr as *const () as usize).trailing_zeros()
diff --git a/library/binary/src/bitvec.rs b/library/binary/src/bitvec.rs
index 975bf2447..0dcda0cd6 100644
--- a/library/binary/src/bitvec.rs
+++ b/library/binary/src/bitvec.rs
@@ -304,7 +304,8 @@ impl<A: Allocator> BitVec<A> {
     /// Used to push a bit when the current position is NOT byte-aligned
     unsafe fn push_bit_slow(&mut self, bit: bool) {
         // First, we need to rewrite the current partial byte with bits from `byte`
-        // Then, we need to shift the remaining bits of `byte` left and write that as a new partial byte
+        // Then, we need to shift the remaining bits of `byte` left and write that as a new partial
+        // byte
         let ptr = self.data.as_mut_ptr();
         let partial_byte = ptr.add(self.pos);
 
@@ -355,7 +356,8 @@ impl<A: Allocator> BitVec<A> {
     #[cold]
     unsafe fn push_byte_slow(&mut self, byte: u8) {
         // First, we need to rewrite the current partial byte with bits from `byte`
-        // Then, we need to shift the remaining bits of `byte` left and write that as a new partial byte
+        // Then, we need to shift the remaining bits of `byte` left and write that as a new partial
+        // byte
         let ptr = self.data.as_mut_ptr();
         let partial_byte = ptr.add(self.pos);
 
@@ -372,7 +374,8 @@ impl<A: Allocator> BitVec<A> {
         // We shift our position forward one byte, the bit offset remains unchanged
         self.pos += 1;
 
-        // Mask out the remaining bits and shift them left by the bit offset to form the new partial byte
+        // Mask out the remaining bits and shift them left by the bit offset to form the new partial
+        // byte
         *ptr.add(self.pos) = byte << (8 - offset);
     }
 
@@ -484,8 +487,9 @@ impl<A: Allocator> BitVec<A> {
             self.push_bytes(bytes);
             // Calculate the number of remaining bits to write
             let remaining_bits = size - available;
-            // If after pushing the bits that were available, we are aligned on a byte boundary, it vastly
-            // simplifies writing the padding bytes and handling the trailing bits
+            // If after pushing the bits that were available, we are aligned on a byte boundary, it
+            // vastly simplifies writing the padding bytes and handling the trailing
+            // bits
             if self.bit_offset == 0 {
                 // Recalculate the number of trailing bits
                 let trailing_bits = (remaining_bits % 8) as u8;
@@ -539,12 +543,14 @@ impl<A: Allocator> BitVec<A> {
         let byte_size = size / 8;
         let trailing_bits = (size % 8) as u8;
 
-        // If the number of bits requested fits in a single byte, we can proceed directly to handling the final byte
+        // If the number of bits requested fits in a single byte, we can proceed directly to
+        // handling the final byte
         if byte_size == 0 {
             return unsafe { self.push_partial_byte(bytes[0], trailing_bits) };
         }
 
-        // If the number of bits requested is an evenly divisble number of bytes, we can delegate to push_bytes
+        // If the number of bits requested is an evenly divisble number of bytes, we can delegate to
+        // push_bytes
         if trailing_bits == 0 {
             return self.push_bytes(&bytes[0..byte_size]);
         }
@@ -591,8 +597,9 @@ impl<A: Allocator> BitVec<A> {
             self.bit_offset = size;
             return;
         }
-        // Otherwise, mask out the bits for the partial byte and shift them into position, then write the filled partial byte
-        // The inverse of this mask will extract the trailing bits
+        // Otherwise, mask out the bits for the partial byte and shift them into position, then
+        // write the filled partial byte The inverse of this mask will extract the trailing
+        // bits
         let mask = u8::MAX << offset_shift;
         let partial_byte = partial_byte & mask;
         *ptr = partial_byte | (byte >> offset);
@@ -653,7 +660,8 @@ impl<A: Allocator> Ord for BitVec<A> {
 impl<A: Allocator, T: ?Sized + Bitstring> PartialOrd<T> for BitVec<A> {
     // We order bitstrings lexicographically
     fn partial_cmp(&self, other: &T) -> Option<core::cmp::Ordering> {
-        // Aligned binaries can be compared using the optimal built-in slice comparisons in the standard lib
+        // Aligned binaries can be compared using the optimal built-in slice comparisons in the
+        // standard lib
         if self.is_binary() && other.is_aligned() && other.is_binary() {
             unsafe {
                 let x = self.as_bytes_unchecked();
@@ -1233,7 +1241,8 @@ mod test {
     fn bitvec_integration_test() {
         // We're aiming to test that we can create the following bitstring:
         //
-        //     <<0xdeadbeef::big-integer-size(4)-unit(8), 2::integer-size(1)-unit(8), 5::integer-size(4)-unit(8), "hello"::binary>>
+        //     <<0xdeadbeef::big-integer-size(4)-unit(8), 2::integer-size(1)-unit(8),
+        // 5::integer-size(4)-unit(8), "hello"::binary>>
         //
         // Which should be equivalent to the following 14 hex-encoded bytes:
         //
diff --git a/library/binary/src/flags.rs b/library/binary/src/flags.rs
index 623da673e..0815f1d2a 100644
--- a/library/binary/src/flags.rs
+++ b/library/binary/src/flags.rs
@@ -1,3 +1,4 @@
+use alloc::format;
 use core::fmt;
 use core::str::FromStr;
 
diff --git a/library/binary/src/lib.rs b/library/binary/src/lib.rs
index 144586c91..986124d8c 100644
--- a/library/binary/src/lib.rs
+++ b/library/binary/src/lib.rs
@@ -39,20 +39,23 @@ pub use self::traits::{Aligned, Binary, Bitstring, FromEndianBytes, ToEndianByte
 
 /// Represents how bytes of a value are laid out in memory:
 ///
-/// Big-endian systems store the most-significant byte at the lowest memory address, and the least-significant
-/// byte at the highest memory address.
+/// Big-endian systems store the most-significant byte at the lowest memory address, and the
+/// least-significant byte at the highest memory address.
 ///
-/// Little-endian systems store the least-significant byte at the lowest memory address, and the most-significant
-/// byte at the highest memory address.
+/// Little-endian systems store the least-significant byte at the lowest memory address, and the
+/// most-significant byte at the highest memory address.
 ///
-/// When thinking about values like memory addresses or integers, we tend to think about the textual representation,
-/// as this is most often what we are presented with when printing them or viewing them in a debugger, and it can be
-/// a useful mental model too, however it can be a bit confusing to read them and reason about endianness.
+/// When thinking about values like memory addresses or integers, we tend to think about the textual
+/// representation, as this is most often what we are presented with when printing them or viewing
+/// them in a debugger, and it can be a useful mental model too, however it can be a bit confusing
+/// to read them and reason about endianness.
 ///
 /// This is because, generally, when we visualize memory the following rules are used:
 ///
-/// * Bytes of memory are printed left-to-right, i.e. the left is the lowest memory address, and increases as you read towards the right.
-/// * Bits of a byte are the opposite; the most-significant bits appear first, decreasing to the least-significant.
+/// * Bytes of memory are printed left-to-right, i.e. the left is the lowest memory address, and
+///   increases as you read towards the right.
+/// * Bits of a byte are the opposite; the most-significant bits appear first, decreasing to the
+///   least-significant.
 ///
 /// So lets apply that to an example, a 16-bit integer 64542, as viewed on a little-endian machine:
 ///
@@ -61,27 +64,30 @@ pub use self::traits::{Aligned, Binary, Bitstring, FromEndianBytes, ToEndianByte
 /// * 0b1111110000011110 (little-endian binary)
 /// * 0b0001111011111100 (big-endian binary)
 ///
-/// Well that's confusing, The bytes appear to be backwards! The little-endian version has the most-significant bits in the least-significant
-/// byte, and the big-endian version has the least-significant bits in the most-significant byte. What's going on here?
+/// Well that's confusing, The bytes appear to be backwards! The little-endian version has the
+/// most-significant bits in the least-significant byte, and the big-endian version has the
+/// least-significant bits in the most-significant byte. What's going on here?
 ///
 /// What I find helps with this is to use the following rules instead:
 ///
 /// * Define `origin` as the right-most byte in the sequence
 /// * Read bytes starting from the origin, i.e. right-to-left
 /// * Read bits within a byte left-to-right as normal (i.e. most-significant bit is on the left)
-/// * Endianness determines how to read the bytes from the origin; big-endian has the most-significant byte at the origin,
+/// * Endianness determines how to read the bytes from the origin; big-endian has the
+///   most-significant byte at the origin,
 /// and little-endian has the least-significant byte at the origin
 ///
-/// If we apply those rules to the previous examples, we can see that the textual representation makes more sense now.
-/// The little-endian hex is read starting with the least-significant byte 0x1e, followed by 0xfc; while the big-endian
-/// integer is read starting with the most-significant byte 0xfc, followed by 0x1e.
-///
-/// But this can make calculating the value from the text representation a bit awkward still, is there a trick for that?
-/// The answer is to normalize out the endianness, so that we can always read a value from most-significant bytes (and bits)
-/// left-to-right. When the native endianness matches the endianness of the value (i.e. little-endian value on little-endian
-/// machine, or big-endian value on big-endian machine), this is already the case. When reading a value with non-native endianness
-/// though, we need to swap the order of the bytes first.
+/// If we apply those rules to the previous examples, we can see that the textual representation
+/// makes more sense now. The little-endian hex is read starting with the least-significant byte
+/// 0x1e, followed by 0xfc; while the big-endian integer is read starting with the most-significant
+/// byte 0xfc, followed by 0x1e.
 ///
+/// But this can make calculating the value from the text representation a bit awkward still, is
+/// there a trick for that? The answer is to normalize out the endianness, so that we can always
+/// read a value from most-significant bytes (and bits) left-to-right. When the native endianness
+/// matches the endianness of the value (i.e. little-endian value on little-endian machine, or
+/// big-endian value on big-endian machine), this is already the case. When reading a value with
+/// non-native endianness though, we need to swap the order of the bytes first.
 #[repr(u8)]
 #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub enum Endianness {
diff --git a/library/binary/src/select.rs b/library/binary/src/select.rs
index 5caee4b97..2bffe42cd 100644
--- a/library/binary/src/select.rs
+++ b/library/binary/src/select.rs
@@ -158,7 +158,6 @@ pub enum Selection<'a> {
     /// require both a leading and trailing partial byte:
     ///
     ///     Selection::Bitstring(0b00001111, &[0b11111111], Some(0b10000000))
-    ///
     Bitstring(MaybePartialByte, &'a [u8], Option<MaybePartialByte>),
 }
 impl<'a> Selection<'a> {
@@ -188,15 +187,17 @@ impl<'a> Selection<'a> {
     /// The result of this function (whether successful or not) is the `Selection` enum, see its
     /// documentation for details on its variants.
     ///
-    /// When `Err(selection)` is returned, there were insufficient bits in the buffer to fulfill the request,
-    /// or the request was out of bounds. The selection contained within will hold what was able to be selected
-    /// from the available bits. This can be used to implement APIs that select as many bits as are available
-    /// without having to calculate in advance the exact number of bits to ask for.
+    /// When `Err(selection)` is returned, there were insufficient bits in the buffer to fulfill the
+    /// request, or the request was out of bounds. The selection contained within will hold what
+    /// was able to be selected from the available bits. This can be used to implement APIs that
+    /// select as many bits as are available without having to calculate in advance the exact
+    /// number of bits to ask for.
     ///
-    /// NOTE: While you can use this function to perform the equivalent of a simple slicing operation (e.g. `&data[offset..len]`),
-    /// it is recommended that you use slicing directly when you know the bounds and are working with aligned, binary data. This
-    /// function does a lot of work to validate the selection and handle various combinations of offsets and non-binary sizes, so
-    /// it is more efficient to slice directly when possible.
+    /// NOTE: While you can use this function to perform the equivalent of a simple slicing
+    /// operation (e.g. `&data[offset..len]`), it is recommended that you use slicing directly
+    /// when you know the bounds and are working with aligned, binary data. This function does a
+    /// lot of work to validate the selection and handle various combinations of offsets and
+    /// non-binary sizes, so it is more efficient to slice directly when possible.
     pub fn new(
         data: &'a [u8],
         byte_offset: usize,
@@ -284,7 +285,8 @@ impl<'a> Selection<'a> {
                 if is_binary {
                     return Err(Self::AlignedBinary(&data[byte_offset..]));
                 } else if selectable > 8 {
-                    // The selectable region forms an aligned bitstring, so we have a trailing partial byte
+                    // The selectable region forms an aligned bitstring, so we have a trailing
+                    // partial byte
                     let last_index = (selectable / 8) + byte_offset;
                     let byte = unsafe { *data.get_unchecked(last_index + 1) };
                     let mask = bitmask_be(selectable_trailing_bits);
@@ -301,7 +303,8 @@ impl<'a> Selection<'a> {
                     )));
                 }
             } else if is_binary {
-                // The selectable region forms an unaligned binary, so we have both leading and trailing partial bytes
+                // The selectable region forms an unaligned binary, so we have both leading and
+                // trailing partial bytes
 
                 // Handle the case where the selected bits can be packed into a single byte
                 let leading_bits = 8 - bit_offset;
@@ -328,7 +331,8 @@ impl<'a> Selection<'a> {
                     MaybePartialByte::new(last & last_mask, trailing_bits),
                 ));
             } else {
-                // The selectable region forms an unaligned bitstring, so we have a leading partial byte, and potentially a trailing partial byte
+                // The selectable region forms an unaligned bitstring, so we have a leading partial
+                // byte, and potentially a trailing partial byte
 
                 // Handle the case where the selected bits can be packed into a single byte
                 let leading_bits = 8 - bit_offset;
@@ -352,7 +356,8 @@ impl<'a> Selection<'a> {
                     return Err(Self::Byte(MaybePartialByte::new(byte, selectable as u8)));
                 }
 
-                // If the remaining selectable bits ends on a byte boundary, then we don't have a trailing partial byte
+                // If the remaining selectable bits ends on a byte boundary, then we don't have a
+                // trailing partial byte
                 let first_mask = bitmask_le(leading_bits);
                 let first = (first & first_mask) << bit_offset;
                 if selectable_trailing_bits == 0 {
@@ -374,23 +379,26 @@ impl<'a> Selection<'a> {
             }
         }
 
-        // At this point we've classified the request and the underlying buffer, and we know that the request
-        // is non-empty and definitely fits, all we need to do is handle the various flavors of selection just
-        // like we did above, except with more accuracy as we can calculate precise ranges
+        // At this point we've classified the request and the underlying buffer, and we know that
+        // the request is non-empty and definitely fits, all we need to do is handle the
+        // various flavors of selection just like we did above, except with more accuracy as
+        // we can calculate precise ranges
         if is_aligned {
-            // We've already handled the case where the selection is aligned and binary, so we have the following cases to handle:
+            // We've already handled the case where the selection is aligned and binary, so we have
+            // the following cases to handle:
             //
             // * aligned, non-binary size, binary buffer size
             // * aligned, non-binary size, non-binary buffer size
             assert!(!is_binary);
             // At this point, if the buffer is non-binary, the request requires bits from the last
-            // addressable byte which is a partial byte. If this were not the case, `is_buffer_binary`
-            // would be true.
+            // addressable byte which is a partial byte. If this were not the case,
+            // `is_buffer_binary` would be true.
             //
-            // As a result, it must be the case that the number of trailing bits is less than or equal
-            // to the number of addressable bits in the last byte.
+            // As a result, it must be the case that the number of trailing bits is less than or
+            // equal to the number of addressable bits in the last byte.
             assert!(is_buffer_binary || trailing_bits <= selectable_trailing_bits);
-            // The last byte is partial, but we must also handle the case where the request fits in a single byte
+            // The last byte is partial, but we must also handle the case where the request fits in
+            // a single byte
             let mask = bitmask_be(trailing_bits);
             if n < 8 {
                 let byte = unsafe { *data.get_unchecked(byte_offset) };
@@ -755,7 +763,8 @@ impl<'a> Selection<'a> {
                             )
                         }
                     } else {
-                        // The new offset starts in the trailing byte, and there must be a trailing byte here
+                        // The new offset starts in the trailing byte, and there must be a trailing
+                        // byte here
                         let r = maybe_r.unwrap();
                         let leading_byte_len = bytes.len();
                         let leading_bit_len = leading_byte_len * 8;
@@ -770,10 +779,11 @@ impl<'a> Selection<'a> {
         }
     }
 
-    /// Produces a new selection that represents selecting the first `n` bits of the current selection
+    /// Produces a new selection that represents selecting the first `n` bits of the current
+    /// selection
     ///
-    /// This returns `Result<Selection, Selection>`, where `Err` indicates that `n` bits were not available,
-    /// but provides the best selection available from the remaining data.
+    /// This returns `Result<Selection, Selection>`, where `Err` indicates that `n` bits were not
+    /// available, but provides the best selection available from the remaining data.
     pub fn take(&self, n: usize) -> Result<Self, Self> {
         if n == 0 {
             return Ok(Self::Empty);
@@ -803,7 +813,8 @@ impl<'a> Selection<'a> {
                     let last_index = n / 8;
                     Ok(Self::AlignedBinary(&bytes[..last_index]))
                 } else if n > 8 {
-                    // We're going to produce an aligned bitstring, so we will have a trailing partial byte
+                    // We're going to produce an aligned bitstring, so we will have a trailing
+                    // partial byte
                     let last_index = n / 8;
                     let mask = bitmask_be(trailing_bits);
                     let last = unsafe { *bytes.get_unchecked(last_index) } & mask;
@@ -893,7 +904,8 @@ impl<'a> Selection<'a> {
                         ))
                     }
                 } else {
-                    // We're going to produce a single byte, containing some or all of the bits from `r`
+                    // We're going to produce a single byte, containing some or all of the bits from
+                    // `r`
                     let consumed_trailing_bits = (n - bytes_bit_len) as u8;
                     let mask = bitmask_be(consumed_trailing_bits);
                     let byte = r.byte() & mask;
@@ -1021,7 +1033,8 @@ impl<'a> Bitstring for Selection<'a> {
         BitsIter::new(*self)
     }
 
-    /// Returns the selected bytes as a string reference, if the data is binary, aligned, and valid UTF-8.
+    /// Returns the selected bytes as a string reference, if the data is binary, aligned, and valid
+    /// UTF-8.
     ///
     /// For unaligned binaries or bitstrings, returns `None`. See `to_str` for an alternative
     /// available to unaligned binaries.
@@ -1072,7 +1085,8 @@ impl<'a> Ord for Selection<'a> {
 impl<'a, T: Bitstring> PartialOrd<T> for Selection<'a> {
     // We order bitstrings lexicographically
     fn partial_cmp(&self, other: &T) -> Option<core::cmp::Ordering> {
-        // Aligned binaries can be compared using the optimal built-in slice comparisons in the standard lib
+        // Aligned binaries can be compared using the optimal built-in slice comparisons in the
+        // standard lib
         if self.is_aligned() && other.is_aligned() && self.is_binary() && other.is_binary() {
             let bytes = unsafe { self.as_bytes_unchecked() };
             return Some(bytes.cmp(unsafe { other.as_bytes_unchecked() }));
@@ -1215,9 +1229,9 @@ mod tests {
 
     #[test]
     fn selection_test_byte() {
-        // This selection is artifically constrained to 8 bits, so the request should produce a single byte
-        // Since the offset is 1, the result is that the value 1 in the second byte is shifted left and becomes
-        // the value 2
+        // This selection is artifically constrained to 8 bits, so the request should produce a
+        // single byte Since the offset is 1, the result is that the value 1 in the second
+        // byte is shifted left and becomes the value 2
         let selection = Selection::new(TEN, 0, 1, Some(9), 8);
         assert_selection!(selection, Ok(Selection::Byte(2u8.into())));
 
@@ -1226,8 +1240,8 @@ mod tests {
         let selection = Selection::new(buf, 0, 4, None, 8);
         assert_selection!(selection, Ok(Selection::Byte(u8::MAX.into())));
 
-        // This selection is for 8 bits with 4 bytes of underlying available, so cannot possibly succeed,
-        // but the fallback selection is 4 bits from the end
+        // This selection is for 8 bits with 4 bytes of underlying available, so cannot possibly
+        // succeed, but the fallback selection is 4 bits from the end
         let buf = &[u8::MAX, u8::MAX, u8::MAX];
         let selection = Selection::new(buf, 2, 4, None, 8);
         assert_selection!(
@@ -1241,7 +1255,8 @@ mod tests {
             Ok(Selection::Byte(MaybePartialByte::new(0b11111100, 6)))
         );
 
-        // Selecting beyond the selectable range, when the available range spans across two bytes produces a byte
+        // Selecting beyond the selectable range, when the available range spans across two bytes
+        // produces a byte
         let selection = Selection::new(buf, 1, 7, Some(21), 24);
         assert_selection!(
             selection,
@@ -1251,7 +1266,8 @@ mod tests {
 
     #[test]
     fn selection_test_aligned_binary() {
-        // Selecting all of a byte slice is equivalent to that slice (aligned, binary by construction)
+        // Selecting all of a byte slice is equivalent to that slice (aligned, binary by
+        // construction)
         let selection = ExactSelection(Selection::all(TEN));
         assert_eq!(selection, Selection::AlignedBinary(TEN));
 
@@ -1271,7 +1287,8 @@ mod tests {
 
     #[test]
     fn selection_test_aligned_bitstring() {
-        // Selecting a subset of bits containing at least one partial byte, from an aligned binary, produces an aligned bitstring
+        // Selecting a subset of bits containing at least one partial byte, from an aligned binary,
+        // produces an aligned bitstring
         let buf = &[u8::MAX, u8::MAX, u8::MAX];
         let selection = Selection::new(buf, 0, 0, None, 14);
         assert_selection!(
@@ -1287,7 +1304,8 @@ mod tests {
             Ok(Selection::Byte(MaybePartialByte::new(0b11111110, 7)))
         );
 
-        // Selecting beyond the selectable range, when the selectable range constitutes an aligned bitstring, produces an aligned bitstring
+        // Selecting beyond the selectable range, when the selectable range constitutes an aligned
+        // bitstring, produces an aligned bitstring
         let selection = Selection::new(buf, 1, 0, Some(23), 24);
         assert_selection!(
             selection,
@@ -1300,7 +1318,8 @@ mod tests {
 
     #[test]
     fn selection_test_binary() {
-        // Selecting a byte-divisible number of bits from any non-byte aligned offset produces a binary selection
+        // Selecting a byte-divisible number of bits from any non-byte aligned offset produces a
+        // binary selection
         let selection = Selection::new(TEN, 0, 1, None, 2 * 8);
         assert_selection!(
             selection,
@@ -1321,8 +1340,8 @@ mod tests {
             ))
         );
 
-        // Selecting beyond the selectable range when the selectable range constitutes an unaligned binary, produces
-        // an unaligned binary selection
+        // Selecting beyond the selectable range when the selectable range constitutes an unaligned
+        // binary, produces an unaligned binary selection
         let selection = Selection::new(TEN, 0, 1, Some(17), 24);
         assert_selection!(
             selection,
@@ -1336,7 +1355,8 @@ mod tests {
 
     #[test]
     fn selection_test_bitstring() {
-        // Selecting any number of bits (> 8, non-byte-divisible) when unaligned, produces an unaligned bitstring
+        // Selecting any number of bits (> 8, non-byte-divisible) when unaligned, produces an
+        // unaligned bitstring
         let buf = &[u8::MAX, u8::MAX, u8::MAX];
         let selection = Selection::new(buf, 0, 3, None, 17);
         assert_selection!(
@@ -1348,7 +1368,8 @@ mod tests {
             ))
         );
 
-        // Selecting beyond the selectable range when the selectable range constitutes an unaligned bitstring, produces an unaligned bitstring
+        // Selecting beyond the selectable range when the selectable range constitutes an unaligned
+        // bitstring, produces an unaligned bitstring
         let selection = Selection::new(buf, 0, 3, None, 27);
         assert_selection!(
             selection,
@@ -1359,7 +1380,8 @@ mod tests {
             ))
         );
 
-        // Selecting a number of bits from an unaligned bit that ends on a byte boundary produces a bitstring
+        // Selecting a number of bits from an unaligned bit that ends on a byte boundary produces a
+        // bitstring
         let selection = Selection::new(buf, 0, 7, None, 9);
         assert_selection!(
             selection,
@@ -1480,7 +1502,8 @@ mod tests {
     fn selection_test_shrink_front() {
         let selection = Selection::all(HELLO);
 
-        // Shrinking an aligned binary by a number of bits divisible into bytes produces an aligned binary
+        // Shrinking an aligned binary by a number of bits divisible into bytes produces an aligned
+        // binary
         let selection = selection.shrink_front(8);
         assert_eq!(
             ExactSelection(selection),
@@ -1498,8 +1521,8 @@ mod tests {
             ))
         );
 
-        // Shrinking an unaligned bitstring by a number of bits that ends on a byte boundary produces
-        // an aligned binary
+        // Shrinking an unaligned bitstring by a number of bits that ends on a byte boundary
+        // produces an aligned binary
         let selection2 = selection.shrink_front(7);
         assert_eq!(
             ExactSelection(selection2),
@@ -1560,7 +1583,8 @@ mod tests {
             Ok(Selection::Byte(MaybePartialByte::new(0b01101000, 7)))
         );
 
-        // Taking a non-binary number of bits from an aligned selection produces an aligned bitstring
+        // Taking a non-binary number of bits from an aligned selection produces an aligned
+        // bitstring
         let selection3 = selection.take(9);
         assert_selection!(
             selection3,
diff --git a/library/binary/src/spec.rs b/library/binary/src/spec.rs
index 40e918f61..53cc18b53 100644
--- a/library/binary/src/spec.rs
+++ b/library/binary/src/spec.rs
@@ -2,10 +2,11 @@ use static_assertions::assert_eq_size;
 
 use crate::Endianness;
 
-/// Represents a binary segment constructor/match specification, e.g. `<<42:8/signed-little-integer>>`
+/// Represents a binary segment constructor/match specification, e.g.
+/// `<<42:8/signed-little-integer>>`
 ///
-/// The size and layout of this type is relied upon by our compiler. It can be represented as a single i64
-/// value, and has a layout equivalent to the following struct:
+/// The size and layout of this type is relied upon by our compiler. It can be represented as a
+/// single i64 value, and has a layout equivalent to the following struct:
 ///
 /// ```rust,ignore
 /// #[repr(C)]
diff --git a/library/binary/src/traits.rs b/library/binary/src/traits.rs
index d6eec4287..b49c40270 100644
--- a/library/binary/src/traits.rs
+++ b/library/binary/src/traits.rs
@@ -132,7 +132,8 @@ pub trait Bitstring: fmt::Debug {
 
     /// Attempts to access the underlying data as a `str`
     ///
-    /// Returns `None` if the bitstring is not aligned and binary, and if the data is not valid UTF-8
+    /// Returns `None` if the bitstring is not aligned and binary, and if the data is not valid
+    /// UTF-8
     ///
     /// If the encoding is known to be UTF-8, this operation can be very efficient,
     /// otherwise, the data must be examined for validity first, which is linear
@@ -376,7 +377,8 @@ impl Bitstring for String {
     }
 }
 
-/// This trait provides common behavior for all types which are always composed of aligned and binary data.
+/// This trait provides common behavior for all types which are always composed of aligned and
+/// binary data.
 pub trait Binary: Bitstring {
     /// Returns the set of flags that apply to this binary
     fn flags(&self) -> BinaryFlags;
@@ -568,11 +570,12 @@ impl Aligned for str {}
 impl Aligned for String {}
 impl Aligned for Vec<u8> {}
 
-/// A trait that represents the ability to obtain the byte representation of a endianness-sensitive value,
-/// namely numerics.
+/// A trait that represents the ability to obtain the byte representation of a endianness-sensitive
+/// value, namely numerics.
 ///
-/// This trait can only be implemented on Copy types, and is expected to return an array of bytes of the exact
-/// size as the type being converted. This matches how the methods on the standard library numeric types work.
+/// This trait can only be implemented on Copy types, and is expected to return an array of bytes of
+/// the exact size as the type being converted. This matches how the methods on the standard library
+/// numeric types work.
 pub trait ToEndianBytes<const N: usize>: Copy {
     /// Converts this value to bytes in big-endian order
     ///
diff --git a/library/number/Cargo.toml b/library/number/Cargo.toml
index 52dd138de..b5e3768ad 100644
--- a/library/number/Cargo.toml
+++ b/library/number/Cargo.toml
@@ -5,6 +5,9 @@ authors = ["Hans Elias B. Josephsen <me@hansihe.com>", "Paul Schoenfelder <pauls
 edition = "2021"
 license = "MIT OR Apache-2.0"
 
+[dependencies]
+thiserror-no-std  = "2.0"
+
 [dependencies.num-integer]
 version = "0.1"
 default-features = false
diff --git a/library/number/src/float.rs b/library/number/src/float.rs
index 88645eb47..d0c2d1e52 100644
--- a/library/number/src/float.rs
+++ b/library/number/src/float.rs
@@ -35,13 +35,14 @@ impl fmt::Display for FloatError {
     }
 }
 
-/// This is a wrapper around an f64 value that ensures the value is a valid Erlang float, i.e. it cannot be +/- infinity.
+/// This is a wrapper around an f64 value that ensures the value is a valid Erlang float, i.e. it
+/// cannot be +/- infinity.
 #[derive(Copy, Clone)]
 #[repr(transparent)]
 pub struct Float(f64);
 impl Float {
-    const I64_UPPER_BOUNDARY: f64 = (1i64 << f64::MANTISSA_DIGITS) as f64;
-    const I64_LOWER_BOUNDARY: f64 = (-1i64 << f64::MANTISSA_DIGITS) as f64;
+    pub const I64_UPPER_BOUNDARY: f64 = (1i64 << f64::MANTISSA_DIGITS) as f64;
+    pub const I64_LOWER_BOUNDARY: f64 = (-1i64 << f64::MANTISSA_DIGITS) as f64;
 
     pub fn new(float: f64) -> Result<Float, FloatError> {
         FloatError::from_category(float.classify())?;
diff --git a/library/number/src/integer.rs b/library/number/src/integer.rs
index 81f5a7c3b..c8d1a420a 100644
--- a/library/number/src/integer.rs
+++ b/library/number/src/integer.rs
@@ -7,6 +7,7 @@ use core::str::FromStr;
 pub use num_bigint::ToBigInt;
 pub use num_traits::{FromPrimitive, Signed, ToPrimitive, Zero};
 
+use thiserror_no_std::Error;
 use num_bigint::{BigInt, ParseBigIntError};
 
 use crate::{DivisionError, Float, FloatError, ShiftError};
@@ -973,22 +974,46 @@ impl From<i16> for Integer {
         Self::Small(i.into())
     }
 }
+impl From<i32> for Integer {
+    #[inline(always)]
+    fn from(i: i32) -> Self {
+        Self::Small(i.into())
+    }
+}
 impl From<i64> for Integer {
     #[inline(always)]
     fn from(i: i64) -> Self {
         Self::new(i)
     }
 }
+impl From<i128> for Integer {
+    #[inline(always)]
+    fn from(i: i128) -> Self {
+        match i.to_i64() {
+            Some(n) if n <= Self::MAX_SMALL || n >= Self::MIN_SMALL => Self::Small(n),
+            Some(_) | None => Self::Big(i.into())
+        }
+    }
+}
+impl From<isize> for Integer {
+    #[inline(always)]
+    fn from(i: isize) -> Self {
+        unsafe { Integer::from_isize(i).unwrap_unchecked() }
+    }
+}
 impl From<u64> for Integer {
     #[inline(always)]
     fn from(i: u64) -> Self {
         unsafe { Integer::from_u64(i).unwrap_unchecked() }
     }
 }
-impl From<i32> for Integer {
+impl From<u128> for Integer {
     #[inline(always)]
-    fn from(i: i32) -> Self {
-        Self::Small(i.into())
+    fn from(i: u128) -> Self {
+        match i.to_i64() {
+            Some(n) if n <= Self::MAX_SMALL || n >= Self::MIN_SMALL => Self::Small(n),
+            Some(_) | None => Self::Big(i.into())
+        }
     }
 }
 impl From<usize> for Integer {
@@ -1012,30 +1037,40 @@ impl From<BigInt> for Integer {
         }
     }
 }
+
+/// This error type is used to indicate that a value cannot be converted to an integer
+#[derive(Error, Debug)]
+pub enum TryIntoIntegerError {
+    #[error("invalid integer conversion: wrong type")]
+    Type,
+    #[error("invalid integer conversion: value out of range")]
+    OutOfRange,
+}
+
 impl TryInto<u8> for Integer {
-    type Error = ();
+    type Error = TryIntoIntegerError;
     fn try_into(self) -> Result<u8, Self::Error> {
         match self {
-            Self::Small(i) => i.try_into().map_err(|_| ()),
-            Self::Big(_) => Err(()),
+            Self::Small(i) => i.try_into().map_err(|_| TryIntoIntegerError::OutOfRange),
+            Self::Big(_) => Err(TryIntoIntegerError::OutOfRange),
         }
     }
 }
 impl TryInto<i64> for Integer {
-    type Error = ();
+    type Error = TryIntoIntegerError;
     fn try_into(self) -> Result<i64, Self::Error> {
         match self {
             Self::Small(i) => Ok(i),
-            Self::Big(i) => i.to_i64().ok_or(()),
+            Self::Big(i) => i.to_i64().ok_or(TryIntoIntegerError::OutOfRange),
         }
     }
 }
 impl TryInto<usize> for Integer {
-    type Error = ();
+    type Error = TryIntoIntegerError;
     fn try_into(self) -> Result<usize, Self::Error> {
         match self {
-            Self::Small(i) => i.try_into().map_err(|_| ()),
-            Self::Big(i) => i.to_usize().ok_or(()),
+            Self::Small(i) => i.try_into().map_err(|_| TryIntoIntegerError::OutOfRange),
+            Self::Big(i) => i.to_usize().ok_or(TryIntoIntegerError::OutOfRange),
         }
     }
 }
diff --git a/library/number/src/lib.rs b/library/number/src/lib.rs
index 7a0805e3a..5ce6d45fd 100644
--- a/library/number/src/lib.rs
+++ b/library/number/src/lib.rs
@@ -10,7 +10,7 @@ mod bigint_to_float;
 pub use bigint_to_float::bigint_to_double;
 
 mod integer;
-pub use integer::Integer;
+pub use integer::{Integer, TryIntoIntegerError};
 
 mod float;
 pub use float::{f16, Float, FloatError};
@@ -34,3 +34,4 @@ pub struct InvalidArithmeticError;
 /// This occurs when a shift operand is invalid/too large
 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
 pub struct ShiftError;
+
diff --git a/library/number/src/number.rs b/library/number/src/number.rs
index 1e8fa985f..a58ff5efd 100644
--- a/library/number/src/number.rs
+++ b/library/number/src/number.rs
@@ -97,6 +97,11 @@ impl From<i64> for Number {
         Self::Integer(i.into())
     }
 }
+impl From<u64> for Number {
+    fn from(i: u64) -> Self {
+        Self::Integer(i.into())
+    }
+}
 impl From<usize> for Number {
     fn from(i: usize) -> Self {
         Self::Integer(i.into())
diff --git a/library/rt/Cargo.toml b/library/rt/Cargo.toml
index ec3864605..3d3181d95 100644
--- a/library/rt/Cargo.toml
+++ b/library/rt/Cargo.toml
@@ -8,8 +8,8 @@ edition = "2021"
 
 [features]
 default = ["std"]
-std = ["anyhow/std", "backtrace/std", "num-bigint/std", "rpds/std", "termcolor", "firefly_binary/std", "firefly_alloc/std"]
-no_std = ["lazy_static/spin_no_std"]
+std = ["anyhow/std", "backtrace/std", "num-bigint/std", "rpds/std", "termcolor", "thiserror", "firefly_binary/std", "firefly_alloc/std"]
+no_std = ["lazy_static/spin_no_std", "thiserror-no-std"]
 
 [dependencies]
 cfg-if = "1.0"
@@ -30,7 +30,7 @@ version = "1.0"
 default-features = false
 
 [dependencies.backtrace]
-version = "0.3"
+version = "0.3.66"
 default-features = false
 
 [dependencies.num-bigint]
@@ -46,8 +46,16 @@ features = ["i128"]
 version = "0.11"
 default-features = false
 
+[dependencies.thiserror]
+version = "1.0"
+optional = true
+
+[dependencies.thiserror-no-std]
+version = "2.0"
+optional = true
+
 [dependencies.termcolor]
-version = "1.1"
+version = "1.1.3"
 optional = true
 
 [build-dependencies]
diff --git a/library/rt/src/backtrace/symbolication.rs b/library/rt/src/backtrace/symbolication.rs
index 3655ba4f5..a0b2237c9 100644
--- a/library/rt/src/backtrace/symbolication.rs
+++ b/library/rt/src/backtrace/symbolication.rs
@@ -360,10 +360,10 @@ where
             builder.push(arg.into())?;
         }
         let arglist: OpaqueTerm = builder.finish().unwrap().into();
-        Tuple::from_slice(&[module, function, arglist, locs], alloc)?
+        Tuple::from_opaque_term_slice(&[module, function, arglist, locs], alloc)?
     } else {
         let arity: OpaqueTerm = Term::Int(mfa.arity as i64).into();
-        Tuple::from_slice(&[module, function, arity, locs], alloc)?
+        Tuple::from_opaque_term_slice(&[module, function, arity, locs], alloc)?
     };
 
     Ok(frame.into())
@@ -382,12 +382,12 @@ where
     let line_key = atoms::Line.into();
     let file = if let Some(f) = filename {
         let filename = to_trimmed_charlist(f, alloc).unwrap_or(OpaqueTerm::NIL);
-        Tuple::from_slice(&[file_key, filename], alloc)?
+        Tuple::from_opaque_term_slice(&[file_key, filename], alloc)?
     } else {
-        Tuple::from_slice(&[file_key, OpaqueTerm::NIL], alloc)?
+        Tuple::from_opaque_term_slice(&[file_key, OpaqueTerm::NIL], alloc)?
     };
     let line = Term::Int(line.unwrap_or_default().try_into().unwrap());
-    let line = Tuple::from_slice(&[line_key, line.into()], alloc)?;
+    let line = Tuple::from_opaque_term_slice(&[line_key, line.into()], alloc)?;
 
     let mut builder = ListBuilder::new(alloc);
     builder.push(line.into())?;
diff --git a/library/rt/src/backtrace/trace.rs b/library/rt/src/backtrace/trace.rs
index 9fa4566bb..c39c64f68 100644
--- a/library/rt/src/backtrace/trace.rs
+++ b/library/rt/src/backtrace/trace.rs
@@ -315,7 +315,7 @@ impl Trace {
         }
 
         // Then construct the stacktrace term from the frames we just built up
-        let list = Cons::from_slice(erlang_frames.as_slice(), heap)?
+        let list = Cons::from_slice_in(erlang_frames.as_slice(), heap)?
             .map(Term::Cons)
             .unwrap_or(Term::Nil);
 
diff --git a/library/rt/src/cmp/exact_eq.rs b/library/rt/src/cmp/exact_eq.rs
index 4b27a0d51..461d17e76 100644
--- a/library/rt/src/cmp/exact_eq.rs
+++ b/library/rt/src/cmp/exact_eq.rs
@@ -5,8 +5,9 @@
 ///! This trait extends the notion of equality provided by `Eq` to cover the distinction
 ///! between the non-strict (`==` and `/=`), and strict (`=:=` and `=/=`) equality operators.
 ///!
-///! ExactEq has a default implemention for all `Eq` implementors. However, for types which distinguish
-///! between strict/non-strict equality, this trait should be specialized on those types.
+///! ExactEq has a default implemention for all `Eq` implementors. However, for types which
+/// distinguish ! between strict/non-strict equality, this trait should be specialized on those
+/// types.
 use alloc::alloc::Allocator;
 use alloc::boxed::Box;
 use alloc::vec::Vec;
diff --git a/library/rt/src/function/apply/dynamic/windows.rs b/library/rt/src/function/apply/dynamic/windows.rs
index e69de29bb..8b1378917 100644
--- a/library/rt/src/function/apply/dynamic/windows.rs
+++ b/library/rt/src/function/apply/dynamic/windows.rs
@@ -0,0 +1 @@
+
diff --git a/library/rt/src/function/mfa.rs b/library/rt/src/function/mfa.rs
index 4723b0062..d3ab91c2d 100644
--- a/library/rt/src/function/mfa.rs
+++ b/library/rt/src/function/mfa.rs
@@ -5,6 +5,8 @@ use crate::term::Atom;
 
 use super::FunctionSymbol;
 
+pub type Arity = u8;
+
 /// This struct is a subset of `FunctionSymbol` that is used to more
 /// generally represent module/function/arity information for any function
 /// whether defined or not.
@@ -12,7 +14,7 @@ use super::FunctionSymbol;
 pub struct ModuleFunctionArity {
     pub module: Atom,
     pub function: Atom,
-    pub arity: u8,
+    pub arity: Arity,
 }
 impl ModuleFunctionArity {
     pub fn new(module: Atom, function: Atom, arity: usize) -> Self {
diff --git a/library/rt/src/function/mod.rs b/library/rt/src/function/mod.rs
index 6df31da1f..e0336d8c8 100644
--- a/library/rt/src/function/mod.rs
+++ b/library/rt/src/function/mod.rs
@@ -2,7 +2,7 @@ mod apply;
 mod mfa;
 
 pub use self::apply::*;
-pub use self::mfa::ModuleFunctionArity;
+pub use self::mfa::{Arity, ModuleFunctionArity};
 
 use core::convert::Infallible;
 use core::fmt;
@@ -141,7 +141,7 @@ impl<T, E> ErlangResult<T, E> {
         debug_assert!(self.is_err());
         match self {
             // SAFETY: the safety contract must be upheld by the caller.
-            Self::Ok(_) => unsafe { core::hint::unreachable_unchecked() },
+            Self::Ok(_) => core::hint::unreachable_unchecked(),
             Self::Err(e) => e,
         }
     }
@@ -211,7 +211,7 @@ pub struct FunctionSymbol {
     /// Function name atom
     pub function: Atom,
     /// The arity of the function
-    pub arity: u8,
+    pub arity: Arity,
     /// An opaque pointer to the function
     ///
     /// To call the function, it is necessary to transmute this
diff --git a/library/rt/src/intrinsics.rs b/library/rt/src/intrinsics.rs
index e38e27cfb..23de76a96 100644
--- a/library/rt/src/intrinsics.rs
+++ b/library/rt/src/intrinsics.rs
@@ -2,25 +2,29 @@ use crate::cmp::ExactEq;
 use crate::function::ErlangResult;
 use crate::term::{OpaqueTerm, Term, TermType};
 
-/// This is an intrinsic expected by the compiler to be defined as part of the runtime, and is used for runtime type checking
+/// This is an intrinsic expected by the compiler to be defined as part of the runtime, and is used
+/// for runtime type checking
 #[export_name = "__firefly_builtin_typeof"]
 pub extern "C" fn r#typeof(value: OpaqueTerm) -> TermType {
     value.r#typeof()
 }
 
-/// This is an intrinsic expected by the compiler to be defined as part of the runtime, and is used for runtime type checking
+/// This is an intrinsic expected by the compiler to be defined as part of the runtime, and is used
+/// for runtime type checking
 #[export_name = "__firefly_builtin_is_atom"]
 pub extern "C" fn is_atom(value: OpaqueTerm) -> bool {
     value.is_atom()
 }
 
-/// This is an intrinsic expected by the compiler to be defined as part of the runtime, and is used for runtime type checking
+/// This is an intrinsic expected by the compiler to be defined as part of the runtime, and is used
+/// for runtime type checking
 #[export_name = "__firefly_builtin_is_number"]
 pub extern "C" fn is_number(value: OpaqueTerm) -> bool {
     value.is_number()
 }
 
-/// This is an intrinsic expected by the compiler to be defined as part of the runtime, and is used for runtime type checking
+/// This is an intrinsic expected by the compiler to be defined as part of the runtime, and is used
+/// for runtime type checking
 #[export_name = "__firefly_builtin_is_tuple"]
 pub extern "C" fn is_tuple(value: OpaqueTerm) -> ErlangResult<u32, u32> {
     match value.into() {
diff --git a/library/rt/src/lib.rs b/library/rt/src/lib.rs
index fb6ae00fd..6ba38413a 100644
--- a/library/rt/src/lib.rs
+++ b/library/rt/src/lib.rs
@@ -58,3 +58,4 @@ pub mod function;
 pub mod intrinsics;
 pub mod process;
 pub mod term;
+pub mod time;
diff --git a/library/rt/src/process/mod.rs b/library/rt/src/process/mod.rs
index 048746956..ebadf0b7a 100644
--- a/library/rt/src/process/mod.rs
+++ b/library/rt/src/process/mod.rs
@@ -2,14 +2,18 @@ mod heap;
 mod stack;
 
 use alloc::alloc::{AllocError, Allocator, Layout};
+
 use core::cell::UnsafeCell;
+use core::fmt::{self, Debug};
 use core::ptr::NonNull;
 
+use firefly_alloc::gc::GcBox;
 use firefly_alloc::heap::Heap;
+use firefly_number::Integer;
 
 use crate::error::ErlangException;
 use crate::function::ModuleFunctionArity;
-use crate::term::ProcessId;
+use crate::term::{OpaqueTerm, Pid, ProcessId, Term, Tuple};
 
 pub use self::heap::ProcessHeap;
 pub use self::stack::ProcessStack;
@@ -62,6 +66,45 @@ impl Process {
         self.pid
     }
 
+    pub fn local_pid(&self) -> Pid {
+        Pid::Local { id: self.pid }
+    }
+
+    pub fn pid_term(&self) -> Result<Term, AllocError> {
+        Ok(Term::Pid(GcBox::new_in(self.local_pid(), self)?))
+    }
+
+    pub fn integer<I: Into<Integer>>(&self, integer: I) -> Result<Term, AllocError> {
+        Term::integer_in(integer, self)
+    }
+
+    pub fn list_from_slice(&self, slice: &[Term]) -> Result<Term, AllocError> {
+        Term::list_from_slice_in(slice, self)
+    }
+
+    pub fn improper_list_from_slice(&self, slice: &[Term], last: Term) -> Result<Term, AllocError> {
+        Term::improper_list_from_slice_in(slice, last, self)
+    }
+
+    pub fn improper_list_from_iter<'a, I>(
+        &self,
+        iter: I,
+        last: Term,
+    ) -> Result<Term, AllocError>
+        where
+            I: DoubleEndedIterator + Iterator<Item = &'a Term>,
+    {
+       Term::improper_list_from_iter_in(iter, last, self)
+    }
+
+    pub fn tuple_term_from_term_slice(&self, slice: &[Term]) -> Result<Term, AllocError> {
+        Tuple::from_term_slice(slice, self).map(From::from)
+    }
+
+    pub fn tuple_opaque_term_from_opaque_term_slice(&self, slice: &[OpaqueTerm]) -> Result<OpaqueTerm, AllocError> {
+        Tuple::from_opaque_term_slice(slice, self).map(From::from)
+    }
+
     pub fn status(&self) -> ProcessStatus {
         unsafe { self.status.get().read() }
     }
@@ -142,6 +185,12 @@ unsafe impl Allocator for Process {
     }
 }
 
+impl Debug for Process {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("Process").field("pid", &self.pid).finish()
+    }
+}
+
 impl Heap for Process {
     #[inline]
     fn heap_start(&self) -> *mut u8 {
diff --git a/library/rt/src/term/atom/atoms.rs b/library/rt/src/term/atom/atoms.rs
new file mode 100644
index 000000000..5cf2dc15b
--- /dev/null
+++ b/library/rt/src/term/atom/atoms.rs
@@ -0,0 +1,566 @@
+#![allow(nonstandard_style, non_upper_case_globals)]
+///! AUTOGENERATED by build.rs - do not modify this file
+use core::ptr::NonNull;
+use super::{Atom, AtomData};
+
+pub const False_VALUE: &'static [u8] = b"false";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_false"]
+#[linkage = "linkonce_odr"]
+pub static False_ATOM: AtomData = AtomData {
+    size: False_VALUE.len(),
+    ptr: False_VALUE.as_ptr(),
+};
+
+
+pub const True_VALUE: &'static [u8] = b"true";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_true"]
+#[linkage = "linkonce_odr"]
+pub static True_ATOM: AtomData = AtomData {
+    size: True_VALUE.len(),
+    ptr: True_VALUE.as_ptr(),
+};
+
+
+pub const Empty_VALUE: &'static [u8] = b"";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_"]
+#[linkage = "linkonce_odr"]
+pub static Empty_ATOM: AtomData = AtomData {
+    size: Empty_VALUE.len(),
+    ptr: Empty_VALUE.as_ptr(),
+};
+
+
+pub const Author_VALUE: &'static [u8] = b"author";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_author"]
+#[linkage = "linkonce_odr"]
+pub static Author_ATOM: AtomData = AtomData {
+    size: Author_VALUE.len(),
+    ptr: Author_VALUE.as_ptr(),
+};
+
+
+pub const Behaviour_VALUE: &'static [u8] = b"behaviour";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_behaviour"]
+#[linkage = "linkonce_odr"]
+pub static Behaviour_ATOM: AtomData = AtomData {
+    size: Behaviour_VALUE.len(),
+    ptr: Behaviour_VALUE.as_ptr(),
+};
+
+
+pub const Callback_VALUE: &'static [u8] = b"callback";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_callback"]
+#[linkage = "linkonce_odr"]
+pub static Callback_ATOM: AtomData = AtomData {
+    size: Callback_VALUE.len(),
+    ptr: Callback_VALUE.as_ptr(),
+};
+
+
+pub const Compile_VALUE: &'static [u8] = b"compile";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_compile"]
+#[linkage = "linkonce_odr"]
+pub static Compile_ATOM: AtomData = AtomData {
+    size: Compile_VALUE.len(),
+    ptr: Compile_VALUE.as_ptr(),
+};
+
+
+pub const Deprecated_VALUE: &'static [u8] = b"deprecated";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_deprecated"]
+#[linkage = "linkonce_odr"]
+pub static Deprecated_ATOM: AtomData = AtomData {
+    size: Deprecated_VALUE.len(),
+    ptr: Deprecated_VALUE.as_ptr(),
+};
+
+
+pub const Export_VALUE: &'static [u8] = b"export";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_export"]
+#[linkage = "linkonce_odr"]
+pub static Export_ATOM: AtomData = AtomData {
+    size: Export_VALUE.len(),
+    ptr: Export_VALUE.as_ptr(),
+};
+
+
+pub const File_VALUE: &'static [u8] = b"file";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_file"]
+#[linkage = "linkonce_odr"]
+pub static File_ATOM: AtomData = AtomData {
+    size: File_VALUE.len(),
+    ptr: File_VALUE.as_ptr(),
+};
+
+
+pub const Import_VALUE: &'static [u8] = b"import";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_import"]
+#[linkage = "linkonce_odr"]
+pub static Import_ATOM: AtomData = AtomData {
+    size: Import_VALUE.len(),
+    ptr: Import_VALUE.as_ptr(),
+};
+
+
+pub const Line_VALUE: &'static [u8] = b"line";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_line"]
+#[linkage = "linkonce_odr"]
+pub static Line_ATOM: AtomData = AtomData {
+    size: Line_VALUE.len(),
+    ptr: Line_VALUE.as_ptr(),
+};
+
+
+pub const Module_VALUE: &'static [u8] = b"module";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_module"]
+#[linkage = "linkonce_odr"]
+pub static Module_ATOM: AtomData = AtomData {
+    size: Module_VALUE.len(),
+    ptr: Module_VALUE.as_ptr(),
+};
+
+
+pub const Nifs_VALUE: &'static [u8] = b"nifs";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_nifs"]
+#[linkage = "linkonce_odr"]
+pub static Nifs_ATOM: AtomData = AtomData {
+    size: Nifs_VALUE.len(),
+    ptr: Nifs_VALUE.as_ptr(),
+};
+
+
+pub const OnLoad_VALUE: &'static [u8] = b"on_load";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_on_load"]
+#[linkage = "linkonce_odr"]
+pub static OnLoad_ATOM: AtomData = AtomData {
+    size: OnLoad_VALUE.len(),
+    ptr: OnLoad_VALUE.as_ptr(),
+};
+
+
+pub const Opaque_VALUE: &'static [u8] = b"opaque";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_opaque"]
+#[linkage = "linkonce_odr"]
+pub static Opaque_ATOM: AtomData = AtomData {
+    size: Opaque_VALUE.len(),
+    ptr: Opaque_VALUE.as_ptr(),
+};
+
+
+pub const Spec_VALUE: &'static [u8] = b"spec";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_spec"]
+#[linkage = "linkonce_odr"]
+pub static Spec_ATOM: AtomData = AtomData {
+    size: Spec_VALUE.len(),
+    ptr: Spec_VALUE.as_ptr(),
+};
+
+
+pub const Type_VALUE: &'static [u8] = b"type";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_type"]
+#[linkage = "linkonce_odr"]
+pub static Type_ATOM: AtomData = AtomData {
+    size: Type_VALUE.len(),
+    ptr: Type_VALUE.as_ptr(),
+};
+
+
+pub const Vsn_VALUE: &'static [u8] = b"vsn";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_vsn"]
+#[linkage = "linkonce_odr"]
+pub static Vsn_ATOM: AtomData = AtomData {
+    size: Vsn_VALUE.len(),
+    ptr: Vsn_VALUE.as_ptr(),
+};
+
+
+pub const Badarg_VALUE: &'static [u8] = b"badarg";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_badarg"]
+#[linkage = "linkonce_odr"]
+pub static Badarg_ATOM: AtomData = AtomData {
+    size: Badarg_VALUE.len(),
+    ptr: Badarg_VALUE.as_ptr(),
+};
+
+
+pub const Badrecord_VALUE: &'static [u8] = b"badrecord";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_badrecord"]
+#[linkage = "linkonce_odr"]
+pub static Badrecord_ATOM: AtomData = AtomData {
+    size: Badrecord_VALUE.len(),
+    ptr: Badrecord_VALUE.as_ptr(),
+};
+
+
+pub const Badmap_VALUE: &'static [u8] = b"badmap";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_badmap"]
+#[linkage = "linkonce_odr"]
+pub static Badmap_ATOM: AtomData = AtomData {
+    size: Badmap_VALUE.len(),
+    ptr: Badmap_VALUE.as_ptr(),
+};
+
+
+pub const Badmatch_VALUE: &'static [u8] = b"badmatch";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_badmatch"]
+#[linkage = "linkonce_odr"]
+pub static Badmatch_ATOM: AtomData = AtomData {
+    size: Badmatch_VALUE.len(),
+    ptr: Badmatch_VALUE.as_ptr(),
+};
+
+
+pub const BadFilter_VALUE: &'static [u8] = b"bad_filter";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_bad_filter"]
+#[linkage = "linkonce_odr"]
+pub static BadFilter_ATOM: AtomData = AtomData {
+    size: BadFilter_VALUE.len(),
+    ptr: BadFilter_VALUE.as_ptr(),
+};
+
+
+pub const BadGenerator_VALUE: &'static [u8] = b"bad_generator";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_bad_generator"]
+#[linkage = "linkonce_odr"]
+pub static BadGenerator_ATOM: AtomData = AtomData {
+    size: BadGenerator_VALUE.len(),
+    ptr: BadGenerator_VALUE.as_ptr(),
+};
+
+
+pub const BadValue_VALUE: &'static [u8] = b"bad_value";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_bad_value"]
+#[linkage = "linkonce_odr"]
+pub static BadValue_ATOM: AtomData = AtomData {
+    size: BadValue_VALUE.len(),
+    ptr: BadValue_VALUE.as_ptr(),
+};
+
+
+pub const BadSize_VALUE: &'static [u8] = b"bad_size";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_bad_size"]
+#[linkage = "linkonce_odr"]
+pub static BadSize_ATOM: AtomData = AtomData {
+    size: BadSize_VALUE.len(),
+    ptr: BadSize_VALUE.as_ptr(),
+};
+
+
+pub const CaseClause_VALUE: &'static [u8] = b"case_clause";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_case_clause"]
+#[linkage = "linkonce_odr"]
+pub static CaseClause_ATOM: AtomData = AtomData {
+    size: CaseClause_VALUE.len(),
+    ptr: CaseClause_VALUE.as_ptr(),
+};
+
+
+pub const Error_VALUE: &'static [u8] = b"error";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_error"]
+#[linkage = "linkonce_odr"]
+pub static Error_ATOM: AtomData = AtomData {
+    size: Error_VALUE.len(),
+    ptr: Error_VALUE.as_ptr(),
+};
+
+
+pub const Exit_VALUE: &'static [u8] = b"exit";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_exit"]
+#[linkage = "linkonce_odr"]
+pub static Exit_ATOM: AtomData = AtomData {
+    size: Exit_VALUE.len(),
+    ptr: Exit_VALUE.as_ptr(),
+};
+
+
+pub const FunctionClause_VALUE: &'static [u8] = b"function_clause";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_function_clause"]
+#[linkage = "linkonce_odr"]
+pub static FunctionClause_ATOM: AtomData = AtomData {
+    size: FunctionClause_VALUE.len(),
+    ptr: FunctionClause_VALUE.as_ptr(),
+};
+
+
+pub const IfClause_VALUE: &'static [u8] = b"if_clause";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_if_clause"]
+#[linkage = "linkonce_odr"]
+pub static IfClause_ATOM: AtomData = AtomData {
+    size: IfClause_VALUE.len(),
+    ptr: IfClause_VALUE.as_ptr(),
+};
+
+
+pub const NifError_VALUE: &'static [u8] = b"nif_error";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_nif_error"]
+#[linkage = "linkonce_odr"]
+pub static NifError_ATOM: AtomData = AtomData {
+    size: NifError_VALUE.len(),
+    ptr: NifError_VALUE.as_ptr(),
+};
+
+
+pub const Throw_VALUE: &'static [u8] = b"throw";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_throw"]
+#[linkage = "linkonce_odr"]
+pub static Throw_ATOM: AtomData = AtomData {
+    size: Throw_VALUE.len(),
+    ptr: Throw_VALUE.as_ptr(),
+};
+
+
+pub const TryClause_VALUE: &'static [u8] = b"try_clause";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_try_clause"]
+#[linkage = "linkonce_odr"]
+pub static TryClause_ATOM: AtomData = AtomData {
+    size: TryClause_VALUE.len(),
+    ptr: TryClause_VALUE.as_ptr(),
+};
+
+
+pub const Undef_VALUE: &'static [u8] = b"undef";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_undef"]
+#[linkage = "linkonce_odr"]
+pub static Undef_ATOM: AtomData = AtomData {
+    size: Undef_VALUE.len(),
+    ptr: Undef_VALUE.as_ptr(),
+};
+
+
+pub const Utf8_VALUE: &'static [u8] = b"utf8";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_utf8"]
+#[linkage = "linkonce_odr"]
+pub static Utf8_ATOM: AtomData = AtomData {
+    size: Utf8_VALUE.len(),
+    ptr: Utf8_VALUE.as_ptr(),
+};
+
+
+pub const Normal_VALUE: &'static [u8] = b"normal";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_normal"]
+#[linkage = "linkonce_odr"]
+pub static Normal_ATOM: AtomData = AtomData {
+    size: Normal_VALUE.len(),
+    ptr: Normal_VALUE.as_ptr(),
+};
+
+
+pub const Ok_VALUE: &'static [u8] = b"ok";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_ok"]
+#[linkage = "linkonce_odr"]
+pub static Ok_ATOM: AtomData = AtomData {
+    size: Ok_VALUE.len(),
+    ptr: Ok_VALUE.as_ptr(),
+};
+
+
+pub const Erlang_VALUE: &'static [u8] = b"erlang";
+
+#[cfg_attr(target_os = "macos", link_section = "__DATA,atoms")]
+#[cfg_attr(all(linux, not(target_os = "macos")), link_section = "__atoms")]
+#[export_name = "atom_erlang"]
+#[linkage = "linkonce_odr"]
+pub static Erlang_ATOM: AtomData = AtomData {
+    size: Erlang_VALUE.len(),
+    ptr: Erlang_VALUE.as_ptr(),
+};
+
+
+
+
+pub static False: Atom = Atom(unsafe { NonNull::new_unchecked(&False_ATOM as *const _ as *mut AtomData) });
+
+pub static True: Atom = Atom(unsafe { NonNull::new_unchecked(&True_ATOM as *const _ as *mut AtomData) });
+
+pub static Empty: Atom = Atom(unsafe { NonNull::new_unchecked(&Empty_ATOM as *const _ as *mut AtomData) });
+
+pub static Author: Atom = Atom(unsafe { NonNull::new_unchecked(&Author_ATOM as *const _ as *mut AtomData) });
+
+pub static Behaviour: Atom = Atom(unsafe { NonNull::new_unchecked(&Behaviour_ATOM as *const _ as *mut AtomData) });
+
+pub static Callback: Atom = Atom(unsafe { NonNull::new_unchecked(&Callback_ATOM as *const _ as *mut AtomData) });
+
+pub static Compile: Atom = Atom(unsafe { NonNull::new_unchecked(&Compile_ATOM as *const _ as *mut AtomData) });
+
+pub static Deprecated: Atom = Atom(unsafe { NonNull::new_unchecked(&Deprecated_ATOM as *const _ as *mut AtomData) });
+
+pub static Export: Atom = Atom(unsafe { NonNull::new_unchecked(&Export_ATOM as *const _ as *mut AtomData) });
+
+pub static File: Atom = Atom(unsafe { NonNull::new_unchecked(&File_ATOM as *const _ as *mut AtomData) });
+
+pub static Import: Atom = Atom(unsafe { NonNull::new_unchecked(&Import_ATOM as *const _ as *mut AtomData) });
+
+pub static Line: Atom = Atom(unsafe { NonNull::new_unchecked(&Line_ATOM as *const _ as *mut AtomData) });
+
+pub static Module: Atom = Atom(unsafe { NonNull::new_unchecked(&Module_ATOM as *const _ as *mut AtomData) });
+
+pub static Nifs: Atom = Atom(unsafe { NonNull::new_unchecked(&Nifs_ATOM as *const _ as *mut AtomData) });
+
+pub static OnLoad: Atom = Atom(unsafe { NonNull::new_unchecked(&OnLoad_ATOM as *const _ as *mut AtomData) });
+
+pub static Opaque: Atom = Atom(unsafe { NonNull::new_unchecked(&Opaque_ATOM as *const _ as *mut AtomData) });
+
+pub static Spec: Atom = Atom(unsafe { NonNull::new_unchecked(&Spec_ATOM as *const _ as *mut AtomData) });
+
+pub static Type: Atom = Atom(unsafe { NonNull::new_unchecked(&Type_ATOM as *const _ as *mut AtomData) });
+
+pub static Vsn: Atom = Atom(unsafe { NonNull::new_unchecked(&Vsn_ATOM as *const _ as *mut AtomData) });
+
+pub static Badarg: Atom = Atom(unsafe { NonNull::new_unchecked(&Badarg_ATOM as *const _ as *mut AtomData) });
+
+pub static Badrecord: Atom = Atom(unsafe { NonNull::new_unchecked(&Badrecord_ATOM as *const _ as *mut AtomData) });
+
+pub static Badmap: Atom = Atom(unsafe { NonNull::new_unchecked(&Badmap_ATOM as *const _ as *mut AtomData) });
+
+pub static Badmatch: Atom = Atom(unsafe { NonNull::new_unchecked(&Badmatch_ATOM as *const _ as *mut AtomData) });
+
+pub static BadFilter: Atom = Atom(unsafe { NonNull::new_unchecked(&BadFilter_ATOM as *const _ as *mut AtomData) });
+
+pub static BadGenerator: Atom = Atom(unsafe { NonNull::new_unchecked(&BadGenerator_ATOM as *const _ as *mut AtomData) });
+
+pub static BadValue: Atom = Atom(unsafe { NonNull::new_unchecked(&BadValue_ATOM as *const _ as *mut AtomData) });
+
+pub static BadSize: Atom = Atom(unsafe { NonNull::new_unchecked(&BadSize_ATOM as *const _ as *mut AtomData) });
+
+pub static CaseClause: Atom = Atom(unsafe { NonNull::new_unchecked(&CaseClause_ATOM as *const _ as *mut AtomData) });
+
+pub static Error: Atom = Atom(unsafe { NonNull::new_unchecked(&Error_ATOM as *const _ as *mut AtomData) });
+
+pub static Exit: Atom = Atom(unsafe { NonNull::new_unchecked(&Exit_ATOM as *const _ as *mut AtomData) });
+
+pub static FunctionClause: Atom = Atom(unsafe { NonNull::new_unchecked(&FunctionClause_ATOM as *const _ as *mut AtomData) });
+
+pub static IfClause: Atom = Atom(unsafe { NonNull::new_unchecked(&IfClause_ATOM as *const _ as *mut AtomData) });
+
+pub static NifError: Atom = Atom(unsafe { NonNull::new_unchecked(&NifError_ATOM as *const _ as *mut AtomData) });
+
+pub static Throw: Atom = Atom(unsafe { NonNull::new_unchecked(&Throw_ATOM as *const _ as *mut AtomData) });
+
+pub static TryClause: Atom = Atom(unsafe { NonNull::new_unchecked(&TryClause_ATOM as *const _ as *mut AtomData) });
+
+pub static Undef: Atom = Atom(unsafe { NonNull::new_unchecked(&Undef_ATOM as *const _ as *mut AtomData) });
+
+pub static Utf8: Atom = Atom(unsafe { NonNull::new_unchecked(&Utf8_ATOM as *const _ as *mut AtomData) });
+
+pub static Normal: Atom = Atom(unsafe { NonNull::new_unchecked(&Normal_ATOM as *const _ as *mut AtomData) });
+
+pub static Ok: Atom = Atom(unsafe { NonNull::new_unchecked(&Ok_ATOM as *const _ as *mut AtomData) });
+
+pub static Erlang: Atom = Atom(unsafe { NonNull::new_unchecked(&Erlang_ATOM as *const _ as *mut AtomData) });
diff --git a/library/rt/src/term/atom/atoms.toml b/library/rt/src/term/atom/atoms.toml
index 0224b6443..b246925da 100644
--- a/library/rt/src/term/atom/atoms.toml
+++ b/library/rt/src/term/atom/atoms.toml
@@ -22,26 +22,76 @@ type = {}
 vsn = {}
 
 [errors]
-badarg = {}
-badrecord = {}
-badmap = {}
-badmatch = {}
 bad_filter = {}
 bad_generator = {}
-bad_value = {}
 bad_size = {}
+bad_value = {}
+badarg = {}
+badarith = {}
+badmap = {}
+badmatch = {}
+badrecord = {}
 case_clause = {}
+down = { value = "DOWN" }
 error = {}
 exit = {}
 function_clause = {}
 if_clause = {}
+invalid = {}
 nif_error = {}
+noproc = { value ="noproc" }
+notsup = {}
 throw = {}
 try_clause = {}
+undefined =  {}
 
 [common]
 erlang = {}
 ok = {}
 undef = {}
-utf8 = {}
 normal = {}
+
+[encoding]
+latin1 = {}
+unicode = {}
+utf8 = {}
+
+[float_to_string]
+compact = {}
+
+[process_info]
+links = {}
+messages = {}
+monitored_by = {}
+monitors = {}
+process = {}
+registered_name = {}
+trap_exit = {}
+
+[otp]
+apply = {}
+
+[seq_trace]
+label = {}
+monotonic_timestamp = {}
+print = {}
+receive = {}
+send = {}
+serial = {}
+spawn = {}
+strict_monotonic_timestamp = {}
+timestamp = {}
+
+[timer]
+abs = {}
+cancel_timer = {}
+read_timer = {}
+
+[time_units]
+millisecond = {}
+second = {}
+seconds = {}
+
+[unique_integer]
+monotonic = {}
+positive = {}
diff --git a/library/rt/src/term/atom/mod.rs b/library/rt/src/term/atom/mod.rs
index bbf1c0c67..f325f0560 100644
--- a/library/rt/src/term/atom/mod.rs
+++ b/library/rt/src/term/atom/mod.rs
@@ -159,7 +159,8 @@ impl Atom {
 
     /// Gets the string value of this atom
     pub fn as_str(&self) -> &'static str {
-        // SAFETY: Atom contents are validated when creating the raw atom data, so converting back to str is safe
+        // SAFETY: Atom contents are validated when creating the raw atom data, so converting back
+        // to str is safe
         match self {
             &atoms::False => "false",
             &atoms::True => "true",
@@ -330,7 +331,8 @@ impl Hash for Atom {
     }
 }
 
-/// This is a helper which allows compiled code to convert a pointer to a C string value into an atom directly.
+/// This is a helper which allows compiled code to convert a pointer to a C string value into an
+/// atom directly.
 #[export_name = "__firefly_builtin_atom_from_cstr"]
 pub unsafe extern "C-unwind" fn atom_from_cstr(ptr: *const core::ffi::c_char) -> OpaqueTerm {
     let atom = Atom::from_raw_cstr(ptr);
diff --git a/library/rt/src/term/atom/table.rs b/library/rt/src/term/atom/table.rs
index 82f5b673f..7941d403d 100644
--- a/library/rt/src/term/atom/table.rs
+++ b/library/rt/src/term/atom/table.rs
@@ -81,9 +81,10 @@ pub unsafe extern "C-unwind" fn init(start: *const AtomData, end: *const AtomDat
     true
 }
 
-/// Like `get_data_or_insert`, but optimized for the case where the given atom value has static lifetime,
-/// and thus doesn't require allocating space for and cloning the value. This is faster in that regard, but
-/// still has all of the downsides that come with acquiring a write lock on the atom table.
+/// Like `get_data_or_insert`, but optimized for the case where the given atom value has static
+/// lifetime, and thus doesn't require allocating space for and cloning the value. This is faster in
+/// that regard, but still has all of the downsides that come with acquiring a write lock on the
+/// atom table.
 #[inline]
 pub(super) unsafe fn get_data_or_insert_static(
     name: &'static str,
@@ -91,12 +92,13 @@ pub(super) unsafe fn get_data_or_insert_static(
     ATOMS.write().get_data_or_insert_static(name)
 }
 
-/// Gets the atom with the given name from the global atom table, or inserts it as a new atom if not present.
+/// Gets the atom with the given name from the global atom table, or inserts it as a new atom if not
+/// present.
 ///
-/// This operation acquires a write lock on the atom table, which requires exclusive access. This means this
-/// operation must wait until all pre-existing readers/writers have released their locks, and will block all
-/// subsequent readers/writers until it has completed. Since this is relatively expensive, this should only
-/// be used when creating new atoms.
+/// This operation acquires a write lock on the atom table, which requires exclusive access. This
+/// means this operation must wait until all pre-existing readers/writers have released their locks,
+/// and will block all subsequent readers/writers until it has completed. Since this is relatively
+/// expensive, this should only be used when creating new atoms.
 #[inline]
 pub(super) unsafe fn get_data_or_insert(name: &str) -> Result<NonNull<AtomData>, AtomError> {
     ATOMS.write().get_data_or_insert(name)
@@ -118,11 +120,11 @@ struct AtomTable {
     arena: DroplessArena,
 }
 // By default, `NonNull<T>` is neither send nor sync, as such pointers may alias, however, in our
-// case, the pointers are to data which is pinned, 'static, read-only, and does not support interior mutability,
-// making such pointers trivially Send and Sync.
+// case, the pointers are to data which is pinned, 'static, read-only, and does not support interior
+// mutability, making such pointers trivially Send and Sync.
 //
-// Furthermore, to mutate the atom table (by adding new atoms), one has to acquire an exclusive write lock,
-// which guarantees that the table itself is also Send and Sync
+// Furthermore, to mutate the atom table (by adding new atoms), one has to acquire an exclusive
+// write lock, which guarantees that the table itself is also Send and Sync
 unsafe impl Send for AtomTable {}
 unsafe impl Sync for AtomTable {}
 impl Default for AtomTable {
@@ -196,7 +198,8 @@ impl AtomTable {
     }
 
     // This function is used to insert new atoms in the table during runtime
-    // SAFETY: `name` must have been checked as not existing while holding the current mutable reference.
+    // SAFETY: `name` must have been checked as not existing while holding the current mutable
+    // reference.
     unsafe fn insert(&mut self, name: &str) -> Result<NonNull<AtomData>, AtomError> {
         use core::intrinsics::unlikely;
 
diff --git a/library/rt/src/term/binary/mod.rs b/library/rt/src/term/binary/mod.rs
index 88f853412..c0d274bde 100644
--- a/library/rt/src/term/binary/mod.rs
+++ b/library/rt/src/term/binary/mod.rs
@@ -189,7 +189,8 @@ impl PartialOrd for BinaryData {
 impl<T: Bitstring> PartialOrd<T> for BinaryData {
     // We order bitstrings lexicographically
     fn partial_cmp(&self, other: &T) -> Option<core::cmp::Ordering> {
-        // Aligned binaries can be compared using the optimal built-in slice comparisons in the standard lib
+        // Aligned binaries can be compared using the optimal built-in slice comparisons in the
+        // standard lib
         if other.is_aligned() && other.is_binary() {
             return Some(self.data.cmp(unsafe { other.as_bytes_unchecked() }));
         }
diff --git a/library/rt/src/term/binary/slice.rs b/library/rt/src/term/binary/slice.rs
index 6170ca0b6..634f47d78 100644
--- a/library/rt/src/term/binary/slice.rs
+++ b/library/rt/src/term/binary/slice.rs
@@ -33,8 +33,8 @@ impl BitSlice {
     ///
     /// The caller must ensure that `data` is a slice of bytes owned by `owner`. As such, we can
     /// guarantee that changing the lifetime to 'static is safe, since the data will not be dropped
-    /// until the owning term has no more references. The garbage collector will take care of rewriting
-    /// the pointer should the data be moved by a GC cycle.
+    /// until the owning term has no more references. The garbage collector will take care of
+    /// rewriting the pointer should the data be moved by a GC cycle.
     #[inline]
     pub unsafe fn new(owner: OpaqueTerm, data: &[u8], bit_offset: u8, num_bits: usize) -> Self {
         let data = core::mem::transmute::<_, &'static [u8]>(data);
diff --git a/library/rt/src/term/closure.rs b/library/rt/src/term/closure.rs
index 0926ac924..f76d386e2 100644
--- a/library/rt/src/term/closure.rs
+++ b/library/rt/src/term/closure.rs
@@ -21,7 +21,8 @@ use super::{Atom, OpaqueTerm};
 /// in the argument list of the callee, which is a fat pointer to the Closure struct. This enables
 /// the callee to access the closed-over values from its environment.
 ///
-/// Function captures do not have the extra self argument, and always have an implicitly empty environment.
+/// Function captures do not have the extra self argument, and always have an implicitly empty
+/// environment.
 #[repr(C, align(16))]
 pub struct Closure {
     pub module: Atom,
@@ -50,15 +51,18 @@ impl fmt::Display for Closure {
 impl Closure {
     pub const TYPE_ID: TypeId = TypeId::of::<Closure>();
 
-    /// Allocates a new GcBox'd closure with the given name, callee, and environment, using the provided allocator
+    /// Allocates a new GcBox'd closure with the given name, callee, and environment, using the
+    /// provided allocator
     ///
     /// # Safety
     ///
-    /// This is a risky low-level operation, and is only safe if the following guarantees are upheld by the caller:
+    /// This is a risky low-level operation, and is only safe if the following guarantees are upheld
+    /// by the caller:
     ///
     /// * The callee pointer must point to an actual function
     /// * The callee must be guaranteed to outlive the closure itself
-    /// * The callee must expect to receive `arity` arguments in addition to the closure self argument
+    /// * The callee must expect to receive `arity` arguments in addition to the closure self
+    ///   argument
     pub fn new_in<A: Allocator>(
         module: Atom,
         name: Atom,
diff --git a/library/rt/src/term/index.rs b/library/rt/src/term/index.rs
index be52b6c75..d99622783 100644
--- a/library/rt/src/term/index.rs
+++ b/library/rt/src/term/index.rs
@@ -232,7 +232,7 @@ impl ops::Index<ops::RangeFull> for Tuple {
 
     #[inline]
     fn index(&self, index: ops::RangeFull) -> &Self::Output {
-        ops::Index::index(self.as_slice(), index)
+        ops::Index::index(self.as_opaque_term_slice(), index)
     }
 }
 
@@ -244,13 +244,13 @@ impl ops::Index<usize> for Tuple {
 
     #[inline]
     fn index(&self, index: usize) -> &Self::Output {
-        <usize as slice::SliceIndex<[OpaqueTerm]>>::index(index, self.as_slice())
+        <usize as slice::SliceIndex<[OpaqueTerm]>>::index(index, self.as_opaque_term_slice())
     }
 }
 impl ops::IndexMut<usize> for Tuple {
     #[inline]
     fn index_mut(&mut self, index: usize) -> &mut Self::Output {
-        <usize as slice::SliceIndex<[OpaqueTerm]>>::index_mut(index, self.as_mut_slice())
+        <usize as slice::SliceIndex<[OpaqueTerm]>>::index_mut(index, self.as_mut_opaque_term_slice())
     }
 }
 impl ops::Index<ops::RangeTo<usize>> for Tuple {
@@ -258,7 +258,7 @@ impl ops::Index<ops::RangeTo<usize>> for Tuple {
 
     #[inline]
     fn index(&self, index: ops::RangeTo<usize>) -> &Self::Output {
-        <ops::RangeTo<usize> as slice::SliceIndex<[OpaqueTerm]>>::index(index, self.as_slice())
+        <ops::RangeTo<usize> as slice::SliceIndex<[OpaqueTerm]>>::index(index, self.as_opaque_term_slice())
     }
 }
 impl ops::Index<ops::RangeFrom<usize>> for Tuple {
@@ -266,7 +266,7 @@ impl ops::Index<ops::RangeFrom<usize>> for Tuple {
 
     #[inline]
     fn index(&self, index: ops::RangeFrom<usize>) -> &Self::Output {
-        <ops::RangeFrom<usize> as slice::SliceIndex<[OpaqueTerm]>>::index(index, self.as_slice())
+        <ops::RangeFrom<usize> as slice::SliceIndex<[OpaqueTerm]>>::index(index, self.as_opaque_term_slice())
     }
 }
 
@@ -281,7 +281,7 @@ where
     #[inline]
     fn index(&self, index: I) -> &Self::Output {
         let uindex: usize = index.into();
-        ops::Index::index(self.as_slice(), uindex)
+        ops::Index::index(self.as_opaque_term_slice(), uindex)
     }
 }
 
@@ -292,7 +292,7 @@ where
     #[inline]
     fn index_mut(&mut self, index: I) -> &mut Self::Output {
         let uindex: usize = index.into();
-        ops::IndexMut::index_mut(self.as_mut_slice(), uindex)
+        ops::IndexMut::index_mut(self.as_mut_opaque_term_slice(), uindex)
     }
 }
 
@@ -305,7 +305,7 @@ where
     #[inline]
     fn index(&self, index: ops::RangeTo<I>) -> &Self::Output {
         let uindex: usize = index.end.into();
-        ops::Index::index(self.as_slice(), ops::RangeTo { end: uindex })
+        ops::Index::index(self.as_opaque_term_slice(), ops::RangeTo { end: uindex })
     }
 }
 
@@ -318,6 +318,6 @@ where
     #[inline]
     fn index(&self, index: ops::RangeFrom<I>) -> &Self::Output {
         let uindex: usize = index.start.into();
-        ops::Index::index(self.as_slice(), ops::RangeFrom { start: uindex })
+        ops::Index::index(self.as_opaque_term_slice(), ops::RangeFrom { start: uindex })
     }
 }
diff --git a/library/rt/src/term/list.rs b/library/rt/src/term/list.rs
index 47886f15f..ed29b81c0 100644
--- a/library/rt/src/term/list.rs
+++ b/library/rt/src/term/list.rs
@@ -51,8 +51,9 @@ impl Cons {
             .map(|ptr| ptr.cast())
     }
 
-    /// Constructs a list from the given slice, the output of which will be in the same order as the slice.
-    pub fn from_slice<H: Heap>(
+    /// Constructs a list from the given slice, the output of which will be in the same order as the
+    /// slice.
+    pub fn from_slice_in<H: Heap>(
         slice: &[Term],
         heap: H,
     ) -> Result<Option<NonNull<Cons>>, AllocError> {
@@ -62,6 +63,28 @@ impl Cons {
         }
         Ok(builder.finish())
     }
+
+    /// Constructs an improper list from the given slice, the output of which will be in the same order as the
+    /// slice.
+    pub fn improper_from_slice_in<H: Heap>(
+        slice: &[Term],
+        last: Term,
+        heap: H,
+    ) -> Result<Option<NonNull<Cons>>, AllocError> {
+        Self::improper_from_iter_in(slice.iter(), last, heap)
+    }
+
+    /// Constructs an improper list from the given iter, the output of which will be in the same order as the
+    /// iter.
+    pub fn improper_from_iter_in<'a, I, H>(iter: I, last: Term, heap: H) -> Result<Option<NonNull<Cons>>, AllocError> where I: DoubleEndedIterator + Iterator<Item = &'a Term>, H: Heap {
+        let mut builder = ListBuilder::new(&heap);
+        builder.push(last)?;
+        for value in iter.rev() {
+            builder.push(*value)?;
+        }
+        Ok(builder.finish())
+    }
+
     /// During garbage collection, when a list cell is moved to the new heap, a
     /// move marker is left in the original location. For a cons cell, the move
     /// marker sets the first word to None, and the second word to a pointer to
@@ -148,7 +171,8 @@ impl Cons {
 
     /// Traverses the list, constructing a String from each codepoint in the list
     ///
-    /// If the list is improper, or any element is not a valid latin1/utf8 codepoint, this function returns None
+    /// If the list is improper, or any element is not a valid latin1/utf8 codepoint, this function
+    /// returns None
     pub fn to_string(&self) -> Option<String> {
         let mut buffer = String::with_capacity(10);
         for result in self.iter() {
@@ -190,8 +214,8 @@ impl Cons {
     pub fn charlist_to_binary<H: Heap>(&self, heap: H) -> Result<Term, CharlistToBinaryError> {
         // We need to know whether or not the resulting binary should be allocated in `alloc`,
         // or on the global heap as a reference-counted binary. We also want to determine the target
-        // encoding. So we'll scan the list twice, once to gather the size in bytes + encoding, the second
-        // to write each byte to the allocated region.
+        // encoding. So we'll scan the list twice, once to gather the size in bytes + encoding, the
+        // second to write each byte to the allocated region.
         let (len, encoding) = self
             .get_charlist_size_and_encoding()
             .ok_or_else(|| CharlistToBinaryError::InvalidList)?;
@@ -252,9 +276,9 @@ impl Cons {
 
     /// Writes this charlist codepoint-by-codepoint to a buffer via the provided writer
     ///
-    /// By the time this has called, we should already have validated that the list is valid unicode codepoints,
-    /// and that the binary we've allocated has enough raw bytes to hold the contents of this charlist. This
-    /// should not be called directly otherwise.
+    /// By the time this has called, we should already have validated that the list is valid unicode
+    /// codepoints, and that the binary we've allocated has enough raw bytes to hold the
+    /// contents of this charlist. This should not be called directly otherwise.
     fn write_unicode_charlist_to_buffer<W: fmt::Write>(
         &self,
         writer: &mut W,
@@ -268,8 +292,8 @@ impl Cons {
         Ok(())
     }
 
-    /// Same as `write_unicode_charlist_to_buffer`, but for ASCII charlists, which is slightly more efficient
-    /// since we can skip the unicode conversion overhead.
+    /// Same as `write_unicode_charlist_to_buffer`, but for ASCII charlists, which is slightly more
+    /// efficient since we can skip the unicode conversion overhead.
     fn write_raw_charlist_to_buffer<A: Allocator>(
         &self,
         buf: &mut BitVec<A>,
@@ -281,8 +305,8 @@ impl Cons {
         Ok(())
     }
 
-    /// This function walks the entire list, calculating the total bytes required to hold all of the characters,
-    /// as well as what encoding is suitable for the charlist.
+    /// This function walks the entire list, calculating the total bytes required to hold all of the
+    /// characters, as well as what encoding is suitable for the charlist.
     ///
     /// If this list is not a charlist, or is an improper list, None is returned.
     fn get_charlist_size_and_encoding(&self) -> Option<(usize, Encoding)> {
@@ -299,11 +323,13 @@ impl Cons {
                                     len += len_utf8(codepoint);
                                 }
                                 None if codepoint > 255 => {
-                                    // Invalid UTF-8 codepoint and not a valid byte value, this isn't a charlist
+                                    // Invalid UTF-8 codepoint and not a valid byte value, this
+                                    // isn't a charlist
                                     return None;
                                 }
                                 None => {
-                                    // This is either a valid latin1 codepoint, or a plain byte, determine which,
+                                    // This is either a valid latin1 codepoint, or a plain byte,
+                                    // determine which,
                                     // as in both cases we need to update the encoding
                                     len += 1;
                                     if Encoding::is_latin1_byte(codepoint.try_into().unwrap()) {
diff --git a/library/rt/src/term/map.rs b/library/rt/src/term/map.rs
index efa506cde..753cf00a9 100644
--- a/library/rt/src/term/map.rs
+++ b/library/rt/src/term/map.rs
@@ -1,4 +1,5 @@
 use alloc::alloc::{AllocError, Allocator};
+use alloc::format;
 use alloc::vec::Vec;
 use core::any::TypeId;
 use core::fmt;
@@ -74,7 +75,8 @@ impl Map {
         Self { map }
     }
 
-    /// Create a map with the given allocator, initialized with key/value pairs from the given iterator
+    /// Create a map with the given allocator, initialized with key/value pairs from the given
+    /// iterator
     pub fn new_from_iter_in<A: Allocator, I: Iterator<Item = (Term, Term)>>(
         items: I,
         alloc: A,
@@ -110,7 +112,8 @@ impl Map {
         Ok(map)
     }
 
-    /// Create a map with the given allocator, initialized with key/value pairs from the given list term
+    /// Create a map with the given allocator, initialized with key/value pairs from the given list
+    /// term
     pub fn from_keyword_list_in<A: Allocator>(
         list: &Cons,
         alloc: A,
diff --git a/library/rt/src/term/mod.rs b/library/rt/src/term/mod.rs
index 2de773204..aa3f3ea35 100644
--- a/library/rt/src/term/mod.rs
+++ b/library/rt/src/term/mod.rs
@@ -27,16 +27,24 @@ pub use self::tuple::Tuple;
 pub use firefly_number::{BigInt, Float, Integer, Number};
 use firefly_number::{DivisionError, InvalidArithmeticError, Sign, ToPrimitive};
 
-use alloc::alloc::{AllocError, Layout};
+use alloc::alloc::{Allocator, AllocError, Layout};
+use alloc::format;
 use core::convert::AsRef;
 use core::fmt;
 use core::ptr::NonNull;
 
 use anyhow::anyhow;
+
+#[cfg(feature = "std")]
+use thiserror::Error;
+#[cfg(feature = "no_std")]
+use thiserror_no_std::Error;
+
 use firefly_alloc::fragment::HeapFragment;
 use firefly_alloc::gc::GcBox;
 use firefly_alloc::heap::Heap;
 use firefly_alloc::rc::{Rc, Weak};
+
 use firefly_binary::{Binary, Bitstring, Encoding};
 
 use crate::cmp::ExactEq;
@@ -128,7 +136,7 @@ impl Term {
                     Self::Tuple(ptr)
                 } else {
                     let tuple = unsafe { ptr.as_ref() };
-                    Self::Tuple(Tuple::from_slice(tuple.as_slice(), heap)?)
+                    Self::Tuple(Tuple::from_opaque_term_slice(tuple.as_opaque_term_slice(), heap)?)
                 }
             }
             Self::Map(boxed) => {
@@ -196,6 +204,96 @@ impl Term {
         Ok(cloned)
     }
 
+    pub fn list_from_slice_in<H: Heap>(slice: &[Term], heap: H) -> Result<Self, AllocError> {
+        Cons::from_slice_in(slice, heap)
+            .map(|non_null_cons| {
+                non_null_cons
+                    .map(Term::Cons)
+                    .unwrap_or(Term::Nil)
+            })
+    }
+
+    pub fn improper_list_from_slice_in<H: Heap>(slice: &[Term], last: Term, heap: H) -> Result<Self, AllocError> {
+        Cons::improper_from_slice_in(slice, last, heap)
+            .map(|non_null_cons| {
+                non_null_cons
+                    .map(Term::Cons)
+                    .unwrap_or(Term::Nil)
+            })
+    }
+
+    pub fn improper_list_from_iter_in<'a, I, H>(iter: I, last: Term, heap: H) -> Result<Self, AllocError> where I: DoubleEndedIterator + Iterator<Item = &'a Term>, H: Heap {
+        Cons::improper_from_iter_in(iter, last, heap)
+            .map(|non_null_cons| {
+                non_null_cons
+                    .map(Term::Cons)
+                    .unwrap_or(Term::Nil)
+            })
+    }
+
+    pub fn number_in<A: Allocator>(number: Number, allocator: &A) -> Result<Self, AllocError> {
+        match number {
+            Number::Float(float) => Ok(Self::Float(float)),
+            Number::Integer(integer) => Self::integer_in(integer, allocator)
+        }
+    }
+
+    pub fn integer_in<I: Into<Integer>, A: Allocator>(integer: I, allocator: A) -> Result<Self, AllocError> {
+        match integer.into() {
+            Integer::Small(small) => Ok(Self::Int(small)),
+            Integer::Big(big_int) => GcBox::new_in(big_int, allocator).map(Term::BigInt)
+        }
+    }
+
+    pub fn is_atom(&self) -> bool {
+        match self {
+            Self::Atom(..) => true,
+            _ => false
+        }
+    }
+
+    pub fn is_big_int(&self) -> bool {
+        match self {
+            Self::BigInt(..) => true,
+            _ => false
+        }
+    }
+
+    pub fn is_boolean(&self) -> bool {
+        match self {
+            Self::Atom(atom) => atom.is_boolean(),
+            _ => false
+        }
+    }
+
+    pub fn is_closure(&self) -> bool {
+        match self {
+            Self::Closure(..) => true,
+            _ => false
+        }
+    }
+
+    pub fn is_float(&self) -> bool {
+        match self {
+            Self::Float(..) => true,
+            _ => false
+        }
+    }
+
+    pub fn is_int(&self) -> bool {
+        match self {
+            Self::Int(..) => true,
+            _ => false
+        }
+    }
+
+    pub fn is_integer(&self) -> bool {
+        match self {
+            Self::Int(..) | Self::BigInt(..) => true,
+            _ => false
+        }
+    }
+
     pub fn is_none(&self) -> bool {
         match self {
             Self::None => true,
@@ -210,6 +308,51 @@ impl Term {
         }
     }
 
+    pub fn is_number(&self) -> bool {
+        match self {
+            Self::Int(..) | Self::BigInt(..) | Self::Float(..) => true,
+            _ => false
+        }
+    }
+
+    pub fn is_pid(&self) -> bool {
+        match self {
+            Self::Pid(..) => true,
+            _ => false
+        }
+    }
+
+    pub fn is_local_pid(&self) -> bool {
+        match self {
+            Self::Pid(gc_box_pid) => match gc_box_pid.as_ref() {
+                Pid::Local {..} => true,
+                _ => false
+            }
+            _ => false
+        }
+    }
+
+    pub fn is_map(&self) -> bool {
+        match self {
+            Self::Map(..) => true,
+            _ => false
+        }
+    }
+
+    pub fn is_reference(&self) -> bool {
+        match self {
+            Self::Reference(..) => true,
+            _ => false
+        }
+    }
+
+    pub fn is_tuple(&self) -> bool {
+        match self {
+            Self::Tuple(..) => true,
+            _ => false
+        }
+    }
+
     pub fn as_cons(&self) -> Option<&Cons> {
         match self {
             Self::Cons(ptr) => Some(unsafe { ptr.as_ref() }),
@@ -279,7 +422,7 @@ impl Term {
     }
 
     #[inline]
-    pub fn as_char(self) -> Result<char, ()> {
+    pub fn as_char(self) -> Result<char, TypeError> {
         self.try_into()
     }
 
@@ -480,119 +623,136 @@ impl From<&'static BinaryData> for Term {
         Self::ConstantBinary(term)
     }
 }
+/// This error type is used to indicate a type conversion error
+#[derive(Error, Debug)]
+#[error("invalid term type")]
+pub struct TypeError;
 impl TryInto<bool> for Term {
-    type Error = ();
+    type Error = TypeError;
     fn try_into(self) -> Result<bool, Self::Error> {
         match self {
             Self::Bool(b) => Ok(b),
             Self::Atom(a) if a.is_boolean() => Ok(a.as_boolean()),
-            _ => Err(()),
+            _ => Err(TypeError),
         }
     }
 }
 impl TryInto<Atom> for Term {
-    type Error = ();
+    type Error = TypeError;
     fn try_into(self) -> Result<Atom, Self::Error> {
         match self {
             Self::Atom(a) => Ok(a),
             Self::Bool(b) => Ok(b.into()),
-            _ => Err(()),
+            _ => Err(TypeError),
         }
     }
 }
 impl TryInto<char> for Term {
-    type Error = ();
+    type Error = TypeError;
     fn try_into(self) -> Result<char, Self::Error> {
         const MAX: i64 = char::MAX as u32 as i64;
 
         let i: i64 = self.try_into()?;
 
         if i >= 0 && i <= MAX {
-            (i as u32).try_into().map_err(|_| ())
+            (i as u32).try_into().map_err(|_| TypeError)
         } else {
-            Err(())
+            Err(TypeError)
+        }
+    }
+}
+impl TryInto<u8> for Term {
+    type Error = TypeError;
+    #[inline]
+    fn try_into(self) -> Result<u8, Self::Error> {
+        match self {
+            Self::Int(i) => match i.to_u8() {
+                Some(u) => Ok(u),
+                None => Err(TypeError)
+            }
+            _ => Err(TypeError)
         }
     }
 }
 impl TryInto<i64> for Term {
-    type Error = ();
+    type Error = TypeError;
     #[inline]
     fn try_into(self) -> Result<i64, Self::Error> {
         match self {
             Self::Int(i) => Ok(i),
             Self::BigInt(i) => match i.to_i64() {
                 Some(i) => Ok(i),
-                None => Err(()),
+                None => Err(TypeError),
             },
-            _ => Err(()),
+            _ => Err(TypeError),
         }
     }
 }
 impl TryInto<Integer> for Term {
-    type Error = ();
+    type Error = TypeError;
     #[inline]
     fn try_into(self) -> Result<Integer, Self::Error> {
         match self {
             Self::Int(i) => Ok(Integer::Small(i)),
             Self::BigInt(i) => Ok(Integer::Big((*i).clone())),
-            _ => Err(()),
+            _ => Err(TypeError),
         }
     }
 }
 impl TryInto<Number> for Term {
-    type Error = ();
+    type Error = TypeError;
     #[inline]
     fn try_into(self) -> Result<Number, Self::Error> {
         match self {
             Self::Int(i) => Ok(Number::Integer(Integer::Small(i))),
             Self::BigInt(i) => Ok(Number::Integer(Integer::Big((*i).clone()))),
             Self::Float(f) => Ok(Number::Float(f)),
-            _ => Err(()),
+            _ => Err(TypeError),
         }
     }
 }
 impl TryInto<NonNull<Cons>> for Term {
-    type Error = ();
+    type Error = TypeError;
     fn try_into(self) -> Result<NonNull<Cons>, Self::Error> {
         match self {
             Self::Cons(c) => Ok(c),
-            _ => Err(()),
+            _ => Err(TypeError),
         }
     }
 }
 impl TryInto<NonNull<Tuple>> for Term {
-    type Error = ();
+    type Error = TypeError;
     fn try_into(self) -> Result<NonNull<Tuple>, Self::Error> {
         match self {
             Self::Tuple(t) => Ok(t),
-            _ => Err(()),
+            _ => Err(TypeError),
         }
     }
 }
 impl TryInto<GcBox<BigInt>> for Term {
-    type Error = ();
+    type Error = TypeError;
     fn try_into(self) -> Result<GcBox<BigInt>, Self::Error> {
         match self {
             Self::BigInt(i) => Ok(i),
-            _ => Err(()),
+            _ => Err(TypeError),
         }
     }
 }
 impl TryInto<f64> for Term {
-    type Error = ();
+    type Error = TypeError;
     fn try_into(self) -> Result<f64, Self::Error> {
         match self {
             Self::Float(f) => Ok(f.into()),
-            _ => Err(()),
+            _ => Err(TypeError),
         }
     }
 }
 impl TryInto<Float> for Term {
-    type Error = ();
+    type Error = TypeError;
     fn try_into(self) -> Result<Float, Self::Error> {
         match self {
             Self::Float(f) => Ok(f),
-            _ => Err(()),
+            _ => Err(TypeError),
         }
     }
 }
@@ -852,9 +1012,10 @@ impl Ord for Term {
                     Ordering::Less
                 }
             }
-            // Numbers are smaller than all other terms, using whichever type has the highest precision.
-            // We need comparison order to preserve the ExactEq semantics, so equality between integers/floats
-            // is broken by sorting floats first due to their greater precision in most cases
+            // Numbers are smaller than all other terms, using whichever type has the highest
+            // precision. We need comparison order to preserve the ExactEq semantics, so
+            // equality between integers/floats is broken by sorting floats first due to
+            // their greater precision in most cases
             Self::Int(x) => match other {
                 Self::None => Ordering::Greater,
                 Self::Int(y) => x.cmp(y),
diff --git a/library/rt/src/term/opaque.rs b/library/rt/src/term/opaque.rs
index c21d49737..e826ef477 100644
--- a/library/rt/src/term/opaque.rs
+++ b/library/rt/src/term/opaque.rs
@@ -1,77 +1,84 @@
-///! The way we represent Erlang terms is somewhat similar to ERTS, but different in a number of material
-///! aspects:
+///! The way we represent Erlang terms is somewhat similar to ERTS, but different in a number
+/// of material ! aspects:
 ///!
-///! * We choose a smaller number of terms to represent as immediates, and modify which terms are immediates
-///! and what their ranges/representation are:
+///! * We choose a smaller number of terms to represent as immediates, and modify which terms
+/// are immediates ! and what their ranges/representation are:
 ///!    - Floats are immediate
 ///!    - Pid/Port are never immediate
 ///!    - SmallInteger is 51-bits wide
 ///!    - Pointers to Tuple/Cons can be type checked without dereferencing the pointer
-///! * Like ERTS, we special case cons cells for more efficient use of memory, but we use a more flexible scheme
-///! for boxed terms in general, allowing us to store any Rust type on a process heap. This scheme comes at a
-///! slight increase in memory usage for some terms, but lets us have an open set of types, as we don't have to
-///! define an encoding scheme for each type individually.
-///!
-///! In order to properly represent the breadth of Rust types using thin pointers, we use a special smart pointer
-///! type called `GcBox<T>` which makes use of the `ptr_metadata` feature to obtain the pointer metadata for a type
-///! and store it alongside the allocated data itself. This allows us to use thin pointers everywhere, but still use
-///! dynamically-sized types.
+///! * Like ERTS, we special case cons cells for more efficient use of memory, but we use a
+/// more flexible scheme ! for boxed terms in general, allowing us to store any Rust type on a
+/// process heap. This scheme comes at a ! slight increase in memory usage for some terms, but
+/// lets us have an open set of types, as we don't have to ! define an encoding scheme for each
+/// type individually. !
+///! In order to properly represent the breadth of Rust types using thin pointers, we use a
+/// special smart pointer ! type called `GcBox<T>` which makes use of the `ptr_metadata`
+/// feature to obtain the pointer metadata for a type ! and store it alongside the allocated
+/// data itself. This allows us to use thin pointers everywhere, but still use
+/// ! dynamically-sized types.
 ///!
 ///! # Encoding Scheme
 ///!
-///! We've chosen to use a NaN-boxing encoding scheme for immediates. In short, we can hide useful data in the shadow
-///! of floating-point NaNs. As a review, IEEE-764 double-precision floating-point values have the following representation
-///! in memory:
+///! We've chosen to use a NaN-boxing encoding scheme for immediates. In short, we can hide
+/// useful data in the shadow ! of floating-point NaNs. As a review, IEEE-764 double-precision
+/// floating-point values have the following representation ! in memory:
 ///!
 ///! `SEEEEEEEEEEEQMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM`
 ///!
 ///! * `S` is the sign bit
 ///! * `E` are the exponent bits (11 bits)
 ///! * `Q+M` are the mantissa bits (52 bits)
-///! * `Q` is used in conjunction with a NaN bit pattern to indicate whether the NaN is quiet or signaling (i.e. raises an exception)
-///!
+///! * `Q` is used in conjunction with a NaN bit pattern to indicate whether the NaN is quiet
+/// or signaling (i.e. raises an exception) !
 ///! In Rust, the following are some special-case bit patterns which are relevant:
 ///!
-///! * `0111111111111000000000000000000000000000000000000000000000000000` = NaN (canonical, sets the quiet bit)
-///! * `0111111111110000000000000000000000000000000000000000000000000000` = Infinity
-///! * `1111111111110000000000000000000000000000000000000000000000000000` = -Infinity
-///!
-///! Additionally, for NaN, it is only required that the canonical bits are set, the mantissa bits are ignored, which means they
-///! can be used.
-///!
-///! Furthermore, Erlang does not support NaN or the infinities, so those bit patterns can be used as well. In short, we have 52 bits to
-///! work with when a float is NaN, which is large enough to store a pointer; and since our pointers must be 8-byte aligned, we have
-///! an additional 4 bits for a limited tagging scheme. The only requirement is that we don't permit overlapping bit patterns for two
-///! different term types.
-///!
-///! Now that you understand the background, here is the encoding we use for different immediate values:
-///!
-///! * `Float` is any bit pattern which represents a valid, non-NaN floating-point value OR canonical NaN (i.e. has the quiet bit set).
-///! * `None` uses the canonical NaN pattern (i.e. has the quiet bit set)
-///! * `Nil` uses the Infinity bit pattern
-///! * `Integer` is any bit pattern with the highest 12-bits set to 1, including the bit pattern for -Infinity, which corresponds to the integer 0.
-///! Integers are 52-bits wide as a result.
-///!
-///! These remaining tags must use either the Infinity or canonical NaN bit pattern for their high bits, and must be combined with a unique tag
-///! in the lowest 4 bits, but no valid value of any type is allowed to overlap with the canonical NaN pattern, so care must be taken when assigning
-///! bits. Currently, pointer-like values use the Infinity pattern + tag bits, and null pointers are disallowed. Atoms use canonical NaN.
+///! * `0111111111111000000000000000000000000000000000000000000000000000` = NaN (canonical,
+/// sets the quiet bit) ! * `0111111111110000000000000000000000000000000000000000000000000000`
+/// = Infinity ! * `1111111111110000000000000000000000000000000000000000000000000000` =
+/// -Infinity !
+///! Additionally, for NaN, it is only required that the canonical bits are set, the mantissa
+/// bits are ignored, which means they ! can be used.
 ///!
-///! * `GcBox<T>` is indicated when the lowest 4 bits are zero (8-byte alignment), and that at least one of the other mantissa bits is non-zero.
-///! Tuple/Cons are never represented using `GcBox<T>`.
-///! * `Rc<T>` uses the tag 0x03, and requires that at least one of the other mantissa bits is non-zero. This overlaps with the tag scheme for the
-///! atom `true`, but is differentiated by the fact that `true` requires that all mantissa bits other than the tag are zero.
-///! * `*const T` (i.e. a pointer to a literal/constant) is the same scheme as `GcBox<T>`, but with the lowest 4 bits equal to 0x01. This allows differentiating
-///! between garbage-collected data and literals.
-///! * `Atom` is has one general encoding and two special marker values for booleans
-///!    * `false` is indicated when all mantissa bits equal to 0x02 (i.e. zero when the atom tag is masked out)
-///!    * `true` is indicated when all mantissa bits equal to 0x03 (i.e. one when the atom tag is masked out)
-///!    * Any other atom is indicated when the lowest 4 bits is equal to 0x02 and the remaining mantissa bits are non-zero. The value of the atom is a pointer
-///!    to AtomData, which is never garbage-collected.
-///! * `*mut Cons` is indicated when the lowest 4 bits are equal to 0x04 (or 0x05 for literals). When masked, the remaining value is a pointer to `Cons`
-///! * `*mut Tuple` is indicated when the lowest 4 bits are equal to 0x06 (or 0x07 for literals). When masked, the remainig value is a pointer to `usize`. Unlike
-///! `Cons`, `Tuple` is a dynamically-sized type, so the pointer given actually points to the metadata (a `usize` value) which can be used to construct
-///! the fat pointer `*mut Tuple` via `ptr::from_raw_parts_mut`
+///! Furthermore, Erlang does not support NaN or the infinities, so those bit patterns can be
+/// used as well. In short, we have 52 bits to ! work with when a float is NaN, which is large
+/// enough to store a pointer; and since our pointers must be 8-byte aligned, we have
+/// ! an additional 4 bits for a limited tagging scheme. The only requirement is that we don't
+/// permit overlapping bit patterns for two ! different term types.
 ///!
+///! Now that you understand the background, here is the encoding we use for different
+/// immediate values: !
+///! * `Float` is any bit pattern which represents a valid, non-NaN floating-point value OR
+/// canonical NaN (i.e. has the quiet bit set). ! * `None` uses the canonical NaN pattern (i.e.
+/// has the quiet bit set) ! * `Nil` uses the Infinity bit pattern
+///! * `Integer` is any bit pattern with the highest 12-bits set to 1, including the bit
+/// pattern for -Infinity, which corresponds to the integer 0. ! Integers are 52-bits wide as a
+/// result. !
+///! These remaining tags must use either the Infinity or canonical NaN bit pattern for their
+/// high bits, and must be combined with a unique tag ! in the lowest 4 bits, but no valid
+/// value of any type is allowed to overlap with the canonical NaN pattern, so care must be
+/// taken when assigning ! bits. Currently, pointer-like values use the Infinity pattern + tag
+/// bits, and null pointers are disallowed. Atoms use canonical NaN. !
+///! * `GcBox<T>` is indicated when the lowest 4 bits are zero (8-byte alignment), and that at
+/// least one of the other mantissa bits is non-zero. ! Tuple/Cons are never represented using
+/// `GcBox<T>`. ! * `Rc<T>` uses the tag 0x03, and requires that at least one of the other
+/// mantissa bits is non-zero. This overlaps with the tag scheme for the ! atom `true`, but is
+/// differentiated by the fact that `true` requires that all mantissa bits other than the tag
+/// are zero. ! * `*const T` (i.e. a pointer to a literal/constant) is the same scheme as
+/// `GcBox<T>`, but with the lowest 4 bits equal to 0x01. This allows differentiating ! between
+/// garbage-collected data and literals. ! * `Atom` is has one general encoding and two special
+/// marker values for booleans !    * `false` is indicated when all mantissa bits equal to 0x02
+/// (i.e. zero when the atom tag is masked out) !    * `true` is indicated when all mantissa
+/// bits equal to 0x03 (i.e. one when the atom tag is masked out) !    * Any other atom is
+/// indicated when the lowest 4 bits is equal to 0x02 and the remaining mantissa bits are
+/// non-zero. The value of the atom is a pointer !    to AtomData, which is never
+/// garbage-collected. ! * `*mut Cons` is indicated when the lowest 4 bits are equal to 0x04
+/// (or 0x05 for literals). When masked, the remaining value is a pointer to `Cons`
+/// ! * `*mut Tuple` is indicated when the lowest 4 bits are equal to 0x06 (or 0x07 for
+/// literals). When masked, the remainig value is a pointer to `usize`. Unlike
+/// ! `Cons`, `Tuple` is a dynamically-sized type, so the pointer given actually points to the
+/// metadata (a `usize` value) which can be used to construct ! the fat pointer `*mut Tuple`
+/// via `ptr::from_raw_parts_mut` !
 ///! All non-immediate terms are allocated/referenced via `GcBox<T>`.
 ///!
 use core::fmt;
@@ -89,7 +96,8 @@ use crate::function::ErlangResult;
 
 // Canonical NaN
 const NAN: u64 = unsafe { mem::transmute::<f64, u64>(f64::NAN) };
-// This value has only set the bit which is used to indicate quiet vs signaling NaN (or NaN vs Infinity in the case of Rust)
+// This value has only set the bit which is used to indicate quiet vs signaling NaN (or NaN vs
+// Infinity in the case of Rust)
 const QUIET_BIT: u64 = 1 << 51;
 // This value has the bit pattern used for the None term, which reuses the bit pattern for NaN
 const NONE: u64 = NAN;
@@ -98,35 +106,40 @@ const INFINITY: u64 = NAN & !QUIET_BIT;
 const NIL: u64 = INFINITY;
 // This value has only the sign bit set
 const SIGN_BIT: u64 = 1 << 63;
-// This value has all of the bits set which indicate an integer value. To get the actual integer value, you must mask out
-// the other bits and then sign-extend the result based on QUIET_BIT, which is the highest bit an integer value can set
+// This value has all of the bits set which indicate an integer value. To get the actual integer
+// value, you must mask out the other bits and then sign-extend the result based on QUIET_BIT, which
+// is the highest bit an integer value can set
 const INTEGER_TAG: u64 = INFINITY | SIGN_BIT;
 
-// This tag when used with pointers, indicates that the pointee is constant, i.e. not garbage-collected
+// This tag when used with pointers, indicates that the pointee is constant, i.e. not
+// garbage-collected
 const LITERAL_TAG: u64 = 0x01;
-// This tag is only ever set when the value is an atom, but is insufficient on its own to determine which type of atom
+// This tag is only ever set when the value is an atom, but is insufficient on its own to determine
+// which type of atom
 const ATOM_TAG: u64 = 0x02;
 // This constant is used to represent the boolean false value without any pointer to AtomData
 const FALSE: u64 = NAN | ATOM_TAG;
 // This constant is used to represent the boolean true value without any pointer to AtomData
 const TRUE: u64 = FALSE | 0x01;
-// This tag represents a unique combination of the lowest 4 bits indicating the value is a cons pointer
-// This tag can be combined with LITERAL_TAG to indicate the pointer is constant
+// This tag represents a unique combination of the lowest 4 bits indicating the value is a cons
+// pointer This tag can be combined with LITERAL_TAG to indicate the pointer is constant
 const CONS_TAG: u64 = 0x04;
 const CONS_LITERAL_TAG: u64 = CONS_TAG | LITERAL_TAG;
-// This tag represents a unique combination of the lowest 4 bits indicating the value is a tuple pointer
-// This tag can be combined with LITERAL_TAG to indicate the pointer is constant
+// This tag represents a unique combination of the lowest 4 bits indicating the value is a tuple
+// pointer This tag can be combined with LITERAL_TAG to indicate the pointer is constant
 const TUPLE_TAG: u64 = 0x06;
 const TUPLE_LITERAL_TAG: u64 = TUPLE_TAG | LITERAL_TAG;
 // This tag is used to mark a pointer allocated via Rc<T>
 const RC_TAG: u64 = 0x03;
 
-// This mask when applied to a u64 will produce a value that can be compared with the tags above for equality
+// This mask when applied to a u64 will produce a value that can be compared with the tags above for
+// equality
 const TAG_MASK: u64 = 0x07;
 // This mask when applied to a u64 will return only the bits which are part of the integer value
 // NOTE: The value that is produced requires sign-extension based on whether QUIET_BIT is set
 const INT_MASK: u64 = !INTEGER_TAG;
-// This mask when applied to a u64 will return a value which can be cast to pointer type and dereferenced
+// This mask when applied to a u64 will return a value which can be cast to pointer type and
+// dereferenced
 const PTR_MASK: u64 = !(SIGN_BIT | NAN | TAG_MASK);
 
 // This tag indicates a negative integer (i.e. it has our designated sign bit set)
@@ -176,12 +189,14 @@ pub enum TermType {
 /// Terms can be encoded as either immediate (i.e. the entire value is represented in the opaque
 /// term itself), or boxed (i.e. the value of the opaque term is a pointer to a value on the heap).
 ///
-/// Pointer values encoded in a term must always have at least 8-byte alignment on all supported platforms.
-/// This should be ensured by specifying the required minimum alignment on all concrete term types we define,
-/// but we also add some debug checks to protect against accidentally attempting to encode invalid pointers.
+/// Pointer values encoded in a term must always have at least 8-byte alignment on all supported
+/// platforms. This should be ensured by specifying the required minimum alignment on all concrete
+/// term types we define, but we also add some debug checks to protect against accidentally
+/// attempting to encode invalid pointers.
 ///
-/// The set of types given explicit type tags were selected such that the most commonly used types are the
-/// cheapest to type check and decode. In general, we believe the most used to be numbers, atoms, lists, and tuples.
+/// The set of types given explicit type tags were selected such that the most commonly used types
+/// are the cheapest to type check and decode. In general, we believe the most used to be numbers,
+/// atoms, lists, and tuples.
 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
 #[repr(transparent)]
 pub struct OpaqueTerm(u64);
@@ -245,8 +260,9 @@ impl OpaqueTerm {
                         // Currently, the only possible type which can be flagged as literal without
                         // any other identifying information is constant BinaryData.
                         //
-                        // If this ever changes, we will likely need to introduce some kind of header
-                        // to distinguish different types, as we are out of tag bits to use
+                        // If this ever changes, we will likely need to introduce some kind of
+                        // header to distinguish different types, as we are
+                        // out of tag bits to use
                         let ptr = value.as_ptr();
                         let flags_ptr: *const BinaryFlags = ptr.cast();
                         let size = (&*flags_ptr).size();
@@ -368,8 +384,8 @@ impl OpaqueTerm {
     pub fn is_box(self) -> bool {
         // The tag bits uniquely identify all boxed types, but only in conjunction with the hi tag
         match self.0 & TAG_MASK {
-            // The only special case is the tag for GcBox overlaps with Nil, but GcBox pointers cannot
-            // be null, so that's how we distinguish the two
+            // The only special case is the tag for GcBox overlaps with Nil, but GcBox pointers
+            // cannot be null, so that's how we distinguish the two
             0 => self.0 != NIL && self.0 & (NAN | SIGN_BIT) == INFINITY,
             LITERAL_TAG | RC_TAG | CONS_TAG | CONS_LITERAL_TAG | TUPLE_TAG | TUPLE_LITERAL_TAG => {
                 // All pointer types use Infinity for their hi tag
@@ -495,7 +511,8 @@ impl OpaqueTerm {
         }
     }
 
-    /// Like `erlang:size/1`, but returns the dynamic size of the given term, or 0 if it is not an unsized type
+    /// Like `erlang:size/1`, but returns the dynamic size of the given term, or 0 if it is not an
+    /// unsized type
     ///
     /// For tuples, this is the number of elements in the tuple.
     /// For closures, it is the number of elements in the closure environment.
@@ -565,8 +582,8 @@ impl OpaqueTerm {
 
     /// Extracts the integer value contained in this term.
     ///
-    /// This function is always memory safe, but if improperly used will cause weird results, so it is important
-    /// that you guard usages of this function with proper type checks.
+    /// This function is always memory safe, but if improperly used will cause weird results, so it
+    /// is important that you guard usages of this function with proper type checks.
     pub fn as_integer(self) -> i64 {
         const NEG: u64 = INTEGER_TAG | QUIET_BIT;
         // Extract the raw 51-bit signed integer
diff --git a/library/rt/src/term/pid.rs b/library/rt/src/term/pid.rs
index 498afe696..d24201ab1 100644
--- a/library/rt/src/term/pid.rs
+++ b/library/rt/src/term/pid.rs
@@ -71,6 +71,11 @@ impl TryFrom<Term> for Pid {
         }
     }
 }
+impl Default for Pid {
+    fn default() -> Self {
+        Self::Local { id: ProcessId::default() }
+    }
+}
 impl Display for Pid {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -115,11 +120,11 @@ impl PartialOrd for Pid {
 /// This struct represents a process identifier, without the node component.
 ///
 /// Local pids in the BEAM are designed to fit in an immediate, which limits their range to a value
-/// that can be expressed in a single 32-bit word. However, because external pids are always 64 bits,
-/// (both number and serial are given a full 32-bits), we choose to use 64-bits in both cases, storing
-/// the serial in the high 32-bits, and the number in the low 32 bits. We do still impose a restriction
-/// on the maximum value of local pids, for both number and serial, that is less than 32-bits, allowing
-/// us to detect overflow when calculating the next possibly-available id.
+/// that can be expressed in a single 32-bit word. However, because external pids are always 64
+/// bits, (both number and serial are given a full 32-bits), we choose to use 64-bits in both cases,
+/// storing the serial in the high 32-bits, and the number in the low 32 bits. We do still impose a
+/// restriction on the maximum value of local pids, for both number and serial, that is less than
+/// 32-bits, allowing us to detect overflow when calculating the next possibly-available id.
 #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[repr(transparent)]
 pub struct ProcessId(u64);
@@ -187,10 +192,10 @@ impl ProcessId {
     /// # Safety
     ///
     /// Process identifiers can roll over eventually, assuming the program runs long enough and
-    /// that processes are being regularly spawned. Once the pid space has been exhausted, calling this
-    /// function will produce a pid that starts over at its initial state. It is required that the scheduler
-    /// verify that a pid is unused by any live process before spawning a process with a pid returned by this
-    /// function.
+    /// that processes are being regularly spawned. Once the pid space has been exhausted, calling
+    /// this function will produce a pid that starts over at its initial state. It is required
+    /// that the scheduler verify that a pid is unused by any live process before spawning a
+    /// process with a pid returned by this function.
     pub fn next() -> Self {
         use core::sync::atomic::{AtomicU64, Ordering::SeqCst};
 
@@ -218,6 +223,12 @@ impl ProcessId {
     }
 }
 
+impl Default for ProcessId {
+    fn default() -> Self {
+        ProcessId::new(0, 0).unwrap()
+    }
+}
+
 // This has been extracted from ProcessId::next() to allow for testing various scenarios without
 // polluting the global pid counter.
 fn calculate_next_pid(x: u64) -> Option<u64> {
diff --git a/library/rt/src/term/tuple.rs b/library/rt/src/term/tuple.rs
index 58ddbb812..cba62b8e7 100644
--- a/library/rt/src/term/tuple.rs
+++ b/library/rt/src/term/tuple.rs
@@ -1,4 +1,5 @@
 use alloc::alloc::{AllocError, Allocator, Layout};
+use alloc::format;
 use core::any::TypeId;
 use core::convert::AsRef;
 use core::fmt::{self, Debug};
@@ -25,8 +26,9 @@ impl Tuple {
     /// # Safety
     ///
     /// It is not safe to use the pointer returned from this function without first initializing all
-    /// of the tuple elements with valid values. This function does not guarantee that the elements are
-    /// in any particular state, so use of the tuple without the initialization step is undefined behavior.
+    /// of the tuple elements with valid values. This function does not guarantee that the elements
+    /// are in any particular state, so use of the tuple without the initialization step is
+    /// undefined behavior.
     pub fn new_in<A: Allocator>(capacity: usize, alloc: A) -> Result<NonNull<Tuple>, AllocError> {
         let (layout, _elements_offset) = Layout::new::<usize>()
             .align_to(16)
@@ -46,19 +48,32 @@ impl Tuple {
 
     /// Creates a new tuple in the given allocator, from a slice of elements.
     ///
-    /// This is a safer alternative to `new_in`, and ensures that the resulting pointer is valid for use
-    /// right away.
-    pub fn from_slice<A: Allocator>(
+    /// This is a safer alternative to `new_in`, and ensures that the resulting pointer is valid for
+    /// use right away.
+    pub fn from_opaque_term_slice<A: Allocator>(
         slice: &[OpaqueTerm],
         alloc: A,
     ) -> Result<NonNull<Tuple>, AllocError> {
         unsafe {
             let mut tuple = Self::new_in(slice.len(), alloc)?;
-            tuple.as_mut().copy_from_slice(slice);
+            tuple.as_mut().copy_from_opaque_term_slice(slice);
             Ok(tuple)
         }
     }
 
+    pub fn from_term_slice<A: Allocator>(slice: &[Term], alloc: A) -> Result<NonNull<Tuple>, AllocError> {
+        unsafe {
+            let mut non_null_tuple = Self::new_in(slice.len(), alloc)?;
+            let mut tuple = non_null_tuple.as_mut();
+            for (i, term) in slice.iter().enumerate() {
+                let opaque_term: OpaqueTerm =  (*term).into();
+                tuple.elements[i] = opaque_term;
+            }
+
+            Ok(non_null_tuple)
+        }
+    }
+
     /// Gets the size of this tuple
     #[inline]
     pub fn len(&self) -> usize {
@@ -119,7 +134,7 @@ impl Tuple {
 
         let mut tuple = Self::new_in(self.len(), alloc)?;
         let t = unsafe { tuple.as_mut() };
-        t.copy_from_slice(self.as_slice());
+        t.copy_from_opaque_term_slice(self.as_opaque_term_slice());
 
         let element = t.elements.get_mut(index).unwrap();
         *element = value.into();
@@ -151,20 +166,20 @@ impl Tuple {
     /// Copies all of the elements from `slice` into this tuple
     ///
     /// NOTE: The slice and this tuple are asserted to be the same length
-    pub fn copy_from_slice(&mut self, slice: &[OpaqueTerm]) {
+    pub fn copy_from_opaque_term_slice(&mut self, slice: &[OpaqueTerm]) {
         assert_eq!(self.elements.len(), slice.len());
         self.elements.copy_from_slice(slice)
     }
 
     /// Get this tuple as a slice of raw elements
     #[inline]
-    pub fn as_slice(&self) -> &[OpaqueTerm] {
+    pub fn as_opaque_term_slice(&self) -> &[OpaqueTerm] {
         &self.elements
     }
 
     /// Get this tuple as a mutable slice of raw elements
     #[inline]
-    pub fn as_mut_slice(&mut self) -> &mut [OpaqueTerm] {
+    pub fn as_mut_opaque_term_slice(&mut self) -> &mut [OpaqueTerm] {
         &mut self.elements
     }
 
diff --git a/library/rt/src/time.rs b/library/rt/src/time.rs
new file mode 100644
index 000000000..4f00cd534
--- /dev/null
+++ b/library/rt/src/time.rs
@@ -0,0 +1,143 @@
+use core::fmt::{self, Display};
+use core::ops::{Add, Div, Mul, Rem, Sub};
+use core::time::Duration;
+
+use num_bigint::BigInt;
+use firefly_number::Number;
+
+// Must be at least a `u64` because `u32` is only ~49 days (`(1 << 32)`)
+/// A duration in milliseconds between `Monotonic` times.
+#[derive(Clone, Copy, Eq, Debug, PartialEq, PartialOrd)]
+pub struct Milliseconds(pub u64);
+
+impl Milliseconds {
+    pub const fn const_div(self, rhs: u64) -> Self {
+        Self(self.0 / rhs)
+    }
+
+    pub const fn as_u64(self) -> u64 {
+        self.0
+    }
+}
+
+impl Add<Milliseconds> for Milliseconds {
+    type Output = Milliseconds;
+
+    fn add(self, rhs: Milliseconds) -> Self::Output {
+        Self(self.0 + rhs.0)
+    }
+}
+
+impl Div<u64> for Milliseconds {
+    type Output = Milliseconds;
+
+    fn div(self, rhs: u64) -> Self::Output {
+        self.const_div(rhs)
+    }
+}
+
+impl Mul<u64> for Milliseconds {
+    type Output = Milliseconds;
+
+    fn mul(self, rhs: u64) -> Self::Output {
+        Self(self.0 * rhs)
+    }
+}
+
+impl From<Milliseconds> for BigInt {
+    fn from(milliseconds: Milliseconds) -> Self {
+        milliseconds.0.into()
+    }
+}
+
+impl From<Milliseconds> for u64 {
+    fn from(milliseconds: Milliseconds) -> Self {
+        milliseconds.0
+    }
+}
+
+impl From<Monotonic> for Milliseconds {
+    fn from(monotonic: Monotonic) -> Self {
+        Self(monotonic.0)
+    }
+}
+
+/// The absolute time
+#[derive(Clone, Copy, Eq, Debug, Ord, PartialEq, PartialOrd)]
+#[repr(transparent)]
+pub struct Monotonic(pub u64);
+impl Monotonic {
+    pub fn from_millis<T: Into<u64>>(to: T) -> Self {
+        Self(to.into())
+    }
+
+    pub fn checked_sub(&self, rhs: Self) -> Option<Milliseconds> {
+        self.0.checked_sub(rhs.0).map(Milliseconds)
+    }
+
+    pub fn round_down(&self, divisor: u64) -> Self {
+        Self((self.0 / divisor) * divisor)
+    }
+}
+impl PartialEq<u64> for Monotonic {
+    fn eq(&self, other: &u64) -> bool {
+        self.0.eq(other)
+    }
+}
+impl PartialOrd<u64> for Monotonic {
+    fn partial_cmp(&self, other: &u64) -> Option<std::cmp::Ordering> {
+        Some(self.0.cmp(other))
+    }
+}
+
+impl Add<Duration> for Monotonic {
+    type Output = Monotonic;
+
+    fn add(self, rhs: Duration) -> Self::Output {
+        Self(self.0 + (rhs.as_millis() as u64))
+    }
+}
+
+impl Add<Milliseconds> for Monotonic {
+    type Output = Monotonic;
+
+    fn add(self, rhs: Milliseconds) -> Self::Output {
+        Self(self.0 + rhs.0)
+    }
+}
+
+impl Display for Monotonic {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "{} ms", self.0)
+    }
+}
+
+impl Into<Number> for Monotonic {
+    fn into(self) -> Number {
+        self.0.into()
+    }
+}
+
+impl Rem<Milliseconds> for Monotonic {
+    type Output = Milliseconds;
+
+    fn rem(self, rhs: Milliseconds) -> Self::Output {
+        Milliseconds(self.0 % rhs.0)
+    }
+}
+
+impl Sub<Milliseconds> for Monotonic {
+    type Output = Monotonic;
+
+    fn sub(self, rhs: Milliseconds) -> Self::Output {
+        Self(self.0 - rhs.0)
+    }
+}
+
+impl Sub<Monotonic> for Monotonic {
+    type Output = Milliseconds;
+
+    fn sub(self, rhs: Monotonic) -> Self::Output {
+        Milliseconds(self.0 - rhs.0)
+    }
+}
diff --git a/native_implemented/macro/src/lib.rs b/native_implemented/macro/src/lib.rs
index 352ee1a9a..b337e8a89 100644
--- a/native_implemented/macro/src/lib.rs
+++ b/native_implemented/macro/src/lib.rs
@@ -18,30 +18,6 @@ use syn::{
     TypeReference,
 };
 
-#[proc_macro_attribute]
-pub fn label(_: TokenStream, result_token_stream: TokenStream) -> TokenStream {
-    let result_item_fn = parse_macro_input!(result_token_stream as ItemFn);
-
-    match Signatures::label(&result_item_fn) {
-        Ok(signatures) => {
-            let frame = frame_for_label();
-            let const_native = signatures.const_native();
-            let native_fn = signatures.native_fn();
-
-            let all_tokens = quote! {
-                #frame
-                #const_native
-
-                #native_fn
-                #result_item_fn
-            };
-
-            all_tokens.into()
-        }
-        Err(error) => error.to_compile_error().into(),
-    }
-}
-
 #[proc_macro_attribute]
 pub fn function(
     module_function_arity_token_stream: TokenStream,
@@ -54,10 +30,7 @@ pub fn function(
     match Signatures::entry_point(&result_item_fn, module_function_arity.arity) {
         Ok(signatures) => {
             let const_arity = signatures.const_arity();
-            let const_native = signatures.const_native();
             let const_closure_native = signatures.const_closure_native();
-            let frame = frame_for_entry_point();
-            let frame_for_native = frame_for_native();
             let function = module_function_arity.function();
             let function_symbol = function_symbol();
             let module_function_arity_fn = module_function_arity_fn();
@@ -66,11 +39,8 @@ pub fn function(
 
             let all_tokens = quote! {
                 #const_arity
-                #const_native
                 #const_closure_native
 
-                #frame
-                #frame_for_native
                 #function
                 #function_symbol
                 #module_function_arity_fn
@@ -98,36 +68,14 @@ fn fn_arg_to_ident(fn_arg: &FnArg) -> Ident {
     }
 }
 
-fn frame_for_entry_point() -> proc_macro2::TokenStream {
-    quote! {
-        pub fn frame() -> liblumen_alloc::erts::process::Frame {
-            frame_for_native(NATIVE)
-        }
-    }
-}
-
-fn frame_for_label() -> proc_macro2::TokenStream {
-    quote! {
-        pub fn frame() -> liblumen_alloc::erts::process::Frame {
-            super::frame_for_native(NATIVE)
-        }
-    }
-}
-
-fn frame_for_native() -> proc_macro2::TokenStream {
-    quote! {
-        pub fn frame_for_native(native: liblumen_alloc::erts::process::Native) -> liblumen_alloc::erts::process::Frame {
-            liblumen_alloc::erts::process::Frame::new(module_function_arity(), native)
-        }
-    }
-}
-
 fn function_symbol() -> proc_macro2::TokenStream {
     quote! {
-        pub fn function_symbol() -> liblumen_core::symbols::FunctionSymbol {
-            liblumen_core::symbols::FunctionSymbol {
-                module: super::module().name().as_ptr(),
-                function: function().name().as_ptr(),
+        use std::str::FromStr;
+
+        pub fn function_symbol() -> firefly_rt::function::FunctionSymbol {
+            firefly_rt::function::FunctionSymbol {
+                module: super::module().as_str().as_ptr(),
+                function: function().as_str().as_ptr(),
                 arity: ARITY,
                 ptr: native as *const std::ffi::c_void
             }
@@ -137,8 +85,8 @@ fn function_symbol() -> proc_macro2::TokenStream {
 
 fn module_function_arity_fn() -> proc_macro2::TokenStream {
     quote! {
-        pub fn module_function_arity() -> liblumen_alloc::erts::ModuleFunctionArity {
-            liblumen_alloc::erts::ModuleFunctionArity {
+        pub fn module_function_arity() -> firefly_rt::function::ModuleFunctionArity {
+            firefly_rt::function::ModuleFunctionArity {
                 module: super::module(),
                 function: function(),
                 arity: ARITY,
@@ -163,8 +111,8 @@ impl ModuleFunctionArity {
         let function = &self.function;
 
         quote! {
-            pub fn function() -> liblumen_alloc::erts::term::prelude::Atom {
-                liblumen_alloc::erts::term::prelude::Atom::from_str(#function)
+            pub fn function() -> firefly_rt::term::Atom {
+                firefly_rt::term::Atom::from_str(#function)
             }
         }
     }
@@ -506,132 +454,6 @@ impl Signatures {
         })
     }
 
-    pub fn label(result_item_fn: &ItemFn) -> std::result::Result<Self, Error> {
-        if result_item_fn.sig.ident != "result" {
-            return Err(Error::new(
-                result_item_fn.sig.ident.span(),
-                format!(
-                    "`{}` should be called `result` when using native_implemented_function macro",
-                    result_item_fn.sig.ident
-                ),
-            ));
-        }
-
-        let result_fn_arg_vec: Vec<FnArg> = result_item_fn
-            .sig
-            .inputs
-            .iter()
-            .map(|input| match input {
-                FnArg::Typed(PatType {
-                    pat: box Pat::Ident(PatIdent { .. }),
-                    ..
-                }) => input.clone(),
-                _ => unimplemented!(
-                    "result function is not expected to have argument like {:?}",
-                    input
-                ),
-            })
-            .collect();
-
-        let (process, native_fn_arg_vec) = match result_item_fn.sig.inputs.first().unwrap() {
-            FnArg::Typed(PatType { ty, .. }) => match **ty {
-                Type::Reference(TypeReference {
-                    elem:
-                        box Type::Path(TypePath {
-                            path: Path { ref segments, .. },
-                            ..
-                        }),
-                    ..
-                }) => {
-                    let PathSegment { ident, .. } = segments.last().unwrap();
-
-                    match ident.to_string().as_ref() {
-                        "Process" => (Process::Ref, result_fn_arg_vec[1..].to_vec()),
-                        s => unimplemented!(
-                            "Extracting result function process from reference ident like {:?}",
-                            s
-                        ),
-                    }
-                }
-                Type::Path(TypePath {
-                    path: Path { ref segments, .. },
-                    ..
-                }) => {
-                    let PathSegment { ident, arguments } = segments.last().unwrap();
-
-                    match ident.to_string().as_ref() {
-                            "Arc" => match arguments {
-                                PathArguments::AngleBracketed(AngleBracketedGenericArguments { args: punctuated_generic_arguments, .. }) => {
-                                    match punctuated_generic_arguments.len() {
-                                        1 => {
-                                            match punctuated_generic_arguments.first().unwrap() {
-                                                GenericArgument::Type(Type::Path(TypePath { path: Path { segments, .. }, .. })) => {
-                                                    let PathSegment { ident, .. } = segments.last().unwrap();
-
-                                                    match ident.to_string().as_ref() {
-                                                        "Process" => (Process::Arc, result_fn_arg_vec[1..].to_vec()),
-                                                        s => unimplemented!(
-                                                            "Extracting result function process from reference ident like {:?}",
-                                                            s
-                                                        ),
-                                                    }
-                                                }
-                                                generic_argument => unimplemented!("Extracting result function process from argument to Arc like {:?}", generic_argument)
-                                            }
-                                        }
-                                        n => unimplemented!("Extracting result function process from {:?} arguments to Arc like {:?}", n, punctuated_generic_arguments)
-                                    }
-                                }
-                                _ => unimplemented!("Extracting result function process from arguments to Arc like {:?}", arguments),
-                            }
-                            "Term" => (Process::None, result_fn_arg_vec),
-                            s => unimplemented!(
-                                "Extracting result function process from path ident like {:?}",
-                                s
-                            ),
-                        }
-                }
-                _ => unimplemented!("Extracting result function process from type like {:?}", ty),
-            },
-            input => unimplemented!(
-                "Extracting result function process from argument like {:?}",
-                input
-            ),
-        };
-
-        let return_type = match result_item_fn.sig.output {
-            syn::ReturnType::Type(
-                _,
-                box Type::Path(TypePath {
-                                   path: Path { ref segments, .. },
-                                   ..
-                               }),
-            ) => {
-                let PathSegment { ident, .. } = segments.last().unwrap();
-
-                match ident.to_string().as_ref() {
-                    "Result" => ReturnType::Result,
-                    "Term" => ReturnType::Term,
-                    _ => return Err(Error::new(ident.span(), "result function return type is neither Result nor Term"))
-                }
-            }
-            ref output => return Err(Error::new(
-                output.span(),
-                "result functions must return either liblumen_alloc::erts::exception::Result or liblumen_alloc::erts::term::Term"
-            )),
-        };
-
-        Ok(Self {
-            result: Result {
-                process,
-                return_type,
-            },
-            native: Native {
-                fn_arg_vec: native_fn_arg_vec,
-            },
-        })
-    }
-
     pub fn arity(&self) -> u8 {
         self.native.arity()
     }
@@ -640,15 +462,7 @@ impl Signatures {
         let arity = &self.arity();
 
         quote! {
-           pub const ARITY: liblumen_alloc::Arity = #arity;
-        }
-    }
-
-    fn const_native(&self) -> proc_macro2::TokenStream {
-        let native_variant = self.native_variant();
-
-        quote! {
-             pub const NATIVE: liblumen_alloc::erts::process::Native = #native_variant;
+           pub const ARITY: firefly_rt::function::Arity = #arity;
         }
     }
 
@@ -689,7 +503,7 @@ impl Signatures {
         };
 
         quote! {
-            pub extern "C-unwind" fn native(#(#native_fn_arg),*) -> liblumen_alloc::erts::process::ffi::ErlangResult {
+            pub extern "C-unwind" fn native(#(#native_fn_arg),*) -> firefly_rt::function::ErlangResult {
                 let arc_process = crate::runtime::process::current_process();
                 arc_process.reduce();
 
@@ -697,28 +511,4 @@ impl Signatures {
             }
         }
     }
-
-    fn native_variant(&self) -> proc_macro2::TokenStream {
-        match self.arity() {
-            0 => quote! {
-                liblumen_alloc::erts::process::Native::Zero(native)
-            },
-            1 => quote! {
-                liblumen_alloc::erts::process::Native::One(native)
-            },
-            2 => quote! {
-                liblumen_alloc::erts::process::Native::Two(native)
-            },
-            3 => quote! {
-                liblumen_alloc::erts::process::Native::Three(native)
-            },
-            4 => quote! {
-                liblumen_alloc::erts::process::Native::Four(native)
-            },
-            5 => quote! {
-                liblumen_alloc::erts::process::Native::Five(native)
-            },
-            arity => unimplemented!("Don't know how to convert arity ({}) to Native", arity),
-        }
-    }
 }
diff --git a/native_implemented/otp/Cargo.toml b/native_implemented/otp/Cargo.toml
index 1ea438f82..754f9bfbe 100644
--- a/native_implemented/otp/Cargo.toml
+++ b/native_implemented/otp/Cargo.toml
@@ -1,5 +1,5 @@
 [package]
-name = "liblumen_otp"
+name = "firefly_otp"
 version = "0.1.0"
 authors = ["Luke Imhoff <Kronic.Deth@gmail.com>"]
 edition = "2021"
@@ -10,10 +10,11 @@ crate-type = ["staticlib", "rlib"]
 
 [dependencies]
 anyhow = "1.0"
+firefly_alloc = { path = "../../library/alloc" }
+firefly_number = { path = "../../library/number" }
+firefly_rt = { path = "../../library/rt" }
+firefly_rt_tiny = { path = "../../runtimes/tiny" }
 lazy_static = "1.4"
-liblumen_alloc = { path = "../../liblumen_alloc" }
-liblumen_core = { path = "../../library/core" }
-lumen_rt_core = { path = "../../runtimes/core" }
 native_implemented = { path = "../macro" }
 num-bigint = "0.4"
 num-traits = "0.2"
@@ -36,8 +37,6 @@ features = ['console']
 
 [dev-dependencies]
 libc = "0.2"
-lumen_rt_full = { path = "../../runtimes/full" }
-lumen = { path = "../../lumen" }
 panic-control = "0.1.4"
 process_control = "3.3"
 # get rid of colors in backtraces for easier matching in integration tests
diff --git a/native_implemented/otp/src/binary.rs b/native_implemented/otp/src/binary.rs
index fdfcfbb1b..6d71b46d1 100644
--- a/native_implemented/otp/src/binary.rs
+++ b/native_implemented/otp/src/binary.rs
@@ -3,13 +3,14 @@ pub mod to_term;
 use std::backtrace::Backtrace;
 use std::convert::TryInto;
 use std::ops::Range;
+use std::ptr::NonNull;
 
 use anyhow::*;
 use thiserror::Error;
+use firefly_rt::error::ErlangException;
 
-use liblumen_alloc::erts::exception::{self, ArcError, Exception, InternalException};
-use liblumen_alloc::erts::term::prelude::*;
-use liblumen_alloc::Process;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Term, TypeError};
 
 pub struct PartRange {
     pub byte_offset: usize,
@@ -41,14 +42,14 @@ pub fn bin_to_list(
     position: Term,
     length: Term,
     process: &Process,
-) -> exception::Result<Term> {
+) -> Result<Term, NonNull<ErlangException>> {
     let position_usize: usize = position
         .try_into()
         .context("position must be non-negative")?;
     let length_isize: isize = length.try_into().context("length must be an integer")?;
 
-    match binary.decode().unwrap() {
-        TypedTerm::HeapBinary(heap_binary) => {
+    match binary {
+        Term::HeapBinary(heap_binary) => {
             let available_byte_count = heap_binary.full_byte_len();
             let part_range =
                 start_length_to_part_range(position_usize, length_isize, available_byte_count)?;
@@ -61,7 +62,7 @@ pub fn bin_to_list(
 
             Ok(list)
         }
-        TypedTerm::ProcBin(process_binary) => {
+        Term::RcBinary(process_binary) => {
             let available_byte_count = process_binary.full_byte_len();
             let part_range =
                 start_length_to_part_range(position_usize, length_isize, available_byte_count)?;
@@ -74,7 +75,7 @@ pub fn bin_to_list(
 
             Ok(list)
         }
-        TypedTerm::BinaryLiteral(process_binary) => {
+        Term::ConstantBinary(process_binary) => {
             let available_byte_count = process_binary.full_byte_len();
             let part_range =
                 start_length_to_part_range(position_usize, length_isize, available_byte_count)?;
@@ -87,7 +88,7 @@ pub fn bin_to_list(
 
             Ok(list)
         }
-        TypedTerm::SubBinary(subbinary) => {
+        Term::RefBinary(subbinary) => {
             let available_byte_count = subbinary.full_byte_len();
             let part_range =
                 start_length_to_part_range(position_usize, length_isize, available_byte_count)?;
@@ -113,7 +114,7 @@ pub fn bin_to_list(
 
                 let byte_term_vec: Vec<Term> = byte_iter.map(|byte| byte.into()).collect();
 
-                process.list_from_slice(&byte_term_vec)
+                process.list_from_slice(&byte_term_vec).unwrap()
             };
 
             Ok(list)
diff --git a/native_implemented/otp/src/binary/to_term.rs b/native_implemented/otp/src/binary/to_term.rs
index d8faf4aa3..b5bbf7276 100644
--- a/native_implemented/otp/src/binary/to_term.rs
+++ b/native_implemented/otp/src/binary/to_term.rs
@@ -1,8 +1,8 @@
-use std::convert::{TryFrom, TryInto};
+use std::convert::TryFrom;
 
 use anyhow::*;
-
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::{Atom, Term};
+use crate::proplist::TryPropListFromTermError;
 
 use crate::runtime::proplist::TryPropListFromTermError;
 
@@ -17,7 +17,7 @@ impl Options {
     fn put_option_term(&mut self, option: Term) -> anyhow::Result<&Options> {
         let atom: Atom = option.try_into().context(SUPPORTED_OPTIONS_CONTEXT)?;
 
-        match atom.name() {
+        match atom.as_str() {
             "safe" => {
                 self.existing = true;
 
@@ -43,11 +43,12 @@ impl TryFrom<Term> for Options {
         let mut options_term = term;
 
         loop {
-            match options_term.decode().unwrap() {
-                TypedTerm::Nil => return Ok(options),
-                TypedTerm::List(cons) => {
-                    options.put_option_term(cons.head)?;
-                    options_term = cons.tail;
+            match options_term {
+                Term::Nil => return Ok(options),
+                Term::Cons(non_null_cons) => {
+                    let cons = unsafe { non_null_cons.as_ref() };
+                    options.put_option_term(cons.head())?;
+                    options_term = cons.tail();
 
                     continue;
                 }
diff --git a/native_implemented/otp/src/erlang.rs b/native_implemented/otp/src/erlang.rs
index c21598388..95deefdc8 100644
--- a/native_implemented/otp/src/erlang.rs
+++ b/native_implemented/otp/src/erlang.rs
@@ -200,15 +200,17 @@ pub mod whereis_1;
 pub mod xor_2;
 
 use std::convert::TryInto;
+use std::ptr::NonNull;
 use std::sync::Arc;
 
 use anyhow::*;
 
-use liblumen_alloc::atom;
-use liblumen_alloc::erts::exception::{self, InternalResult};
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
-use liblumen_alloc::erts::time::{Milliseconds, Monotonic};
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::{atoms, Reference};
+use firefly_rt::term::atoms::Erlang;
+use firefly_rt::term::{Atom, Term};
+use firefly_rt::time::{Milliseconds, Monotonic};
 
 use crate::runtime::context::*;
 use crate::runtime::time::monotonic;
@@ -219,12 +221,11 @@ use crate::runtime::scheduler::SchedulerDependentAlloc;
 use crate::runtime::timer::{Destination, Format, SourceEvent};
 use crate::timer;
 use crate::timer::start::ReferenceFrame;
-use lumen_rt_core::context::term_is_not_non_negative_integer;
 
 pub const MAX_SHIFT: usize = std::mem::size_of::<isize>() * 8 - 1;
 
 pub fn module() -> Atom {
-    Atom::from_str("erlang")
+    atoms::Erlang
 }
 
 // Private
@@ -251,23 +252,27 @@ fn cancel_timer(
 
         if options.r#async {
             let cancel_timer_message =
-                process.tuple_from_slice(&[atom!("cancel_timer"), timer_reference, canceled_term]);
+                process.tuple_term_from_term_slice(&[atoms::CancelTimer.into(), timer_reference, canceled_term]);
             process.send_from_self(cancel_timer_message);
 
-            atom!("ok")
+            atoms::Ok
         } else {
             canceled_term
         }
     } else {
-        atom!("ok")
+        atoms::Ok
     };
 
     Ok(term)
 }
 
-fn is_record(term: Term, record_tag: Term, size: Option<Term>) -> exception::Result<Term> {
-    match term.decode()? {
-        TypedTerm::Tuple(tuple) => {
+fn is_record(
+    term: Term,
+    record_tag: Term,
+    size: Option<Term>,
+) -> Result<Term, NonNull<ErlangException>> {
+    match term {
+        Term::Tuple(tuple) => {
             let _: Atom = term_try_into_atom("record tag", record_tag)?;
 
             let len = tuple.len();
@@ -300,7 +305,7 @@ fn is_record(term: Term, record_tag: Term, size: Option<Term>) -> exception::Res
     }
 }
 
-fn size_try_to_usize(size: Term) -> exception::Result<usize> {
+fn size_try_to_usize(size: Term) -> Result<usize, NonNull<ErlangException>> {
     size.try_into()
         .with_context(|| format!("size ({}) must be a positive integer", size))
         .map_err(From::from)
@@ -327,10 +332,10 @@ fn read_timer(
 
     let term = if options.r#async {
         let read_timer_message =
-            process.tuple_from_slice(&[atom!("read_timer"), timer_reference, read_term]);
+            process.tuple_term_from_term_slice(&[atoms::ReadTimer.into(), timer_reference, read_term]);
         process.send_from_self(read_timer_message);
 
-        atom!("ok")
+        atoms::Ok
     } else {
         read_term
     };
@@ -360,9 +365,9 @@ fn start_timer(
                 .with_context(|| term_is_not_non_negative_integer("time", time))?,
         };
 
-        match destination.decode()? {
+        match destination {
             // Registered names are looked up at time of send
-            TypedTerm::Atom(destination_atom) => runtime::timer::start(
+            Term::Atom(destination_atom) => runtime::timer::start(
                 monotonic,
                 SourceEvent::Message {
                     destination: Destination::Name(destination_atom),
@@ -374,7 +379,7 @@ fn start_timer(
             .map_err(|error| error.into()),
             // PIDs are looked up at time of create.  If they don't exist, they still return a
             // LocalReference.
-            TypedTerm::Pid(destination_pid) => {
+            Term::Pid(destination_pid) => {
                 match pid_to_self_or_process(destination_pid, &arc_process) {
                     Some(pid_arc_process) => runtime::timer::start(
                         monotonic,
@@ -385,7 +390,7 @@ fn start_timer(
                         },
                         arc_process,
                     ),
-                    None => Ok(arc_process.next_reference()),
+                    None => Ok(arc_process.next_local_reference_term()),
                 }
                 .map_err(From::from)
             }
diff --git a/native_implemented/otp/src/erlang/abs_1.rs b/native_implemented/otp/src/erlang/abs_1.rs
index d596323df..ebdf837c6 100644
--- a/native_implemented/otp/src/erlang/abs_1.rs
+++ b/native_implemented/otp/src/erlang/abs_1.rs
@@ -1,51 +1,48 @@
 use std::cmp::Ordering;
+use std::ptr::NonNull;
 
 use anyhow::*;
 use num_bigint::BigInt;
 use num_traits::Zero;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Term, TypeError};
 
 #[native_implemented::function(erlang:abs/1)]
-fn result(process: &Process, number: Term) -> exception::Result<Term> {
-    match number.decode()? {
-        TypedTerm::SmallInteger(small_integer) => {
+fn result(process: &Process, number: Term) -> Result<Term, NonNull<ErlangException>> {
+    match number {
+        Term::Int(small_integer) => {
             let i: isize = small_integer.into();
 
             let abs_number = if i < 0 {
                 let positive = -i;
-                process.integer(positive)
+                process.integer(positive).unwrap()
             } else {
                 number
             };
 
             Ok(abs_number)
         }
-        TypedTerm::BigInteger(big_integer) => {
+        Term::BigInt(big_integer) => {
             let big_int: &BigInt = big_integer.as_ref().into();
             let zero_big_int: &BigInt = &Zero::zero();
 
             let abs_number: Term = if big_int < zero_big_int {
                 let positive_big_int: BigInt = -1 * big_int;
 
-                process.integer(positive_big_int)
+                process.integer(positive_big_int).unwrap()
             } else {
                 number
             };
 
             Ok(abs_number)
         }
-        TypedTerm::Float(float) => {
+        Term::Float(float) => {
             let f: f64 = float.into();
 
             let abs_number = match f.partial_cmp(&0.0).unwrap() {
-                Ordering::Less => {
-                    let positive_f = f.abs();
-
-                    process.float(positive_f)
-                }
+                Ordering::Less => f.abs().into(),
                 _ => number,
             };
 
diff --git a/native_implemented/otp/src/erlang/add_2.rs b/native_implemented/otp/src/erlang/add_2.rs
index 48d37aad8..1d3c3da9a 100644
--- a/native_implemented/otp/src/erlang/add_2.rs
+++ b/native_implemented/otp/src/erlang/add_2.rs
@@ -1,9 +1,15 @@
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use std::ptr::NonNull;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 /// `+/2` infix operator
 #[native_implemented::function(erlang:+/2)]
-pub fn result(process: &Process, augend: Term, addend: Term) -> exception::Result<Term> {
+pub fn result(
+    process: &Process,
+    augend: Term,
+    addend: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     number_infix_operator!(augend, addend, process, checked_add, +)
 }
diff --git a/native_implemented/otp/src/erlang/and_2.rs b/native_implemented/otp/src/erlang/and_2.rs
index 306854f07..ba60aeaf2 100644
--- a/native_implemented/otp/src/erlang/and_2.rs
+++ b/native_implemented/otp/src/erlang/and_2.rs
@@ -1,11 +1,13 @@
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::term::prelude::Term;
+use std::ptr::NonNull;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::Term;
 
 /// `and/2` infix operator.
 ///
 /// **NOTE: NOT SHORT-CIRCUITING!**  Use `andalso/2` for short-circuiting, but it doesn't enforce
 /// that `right` is boolean.
 #[native_implemented::function(erlang:and/2)]
-fn result(left_boolean: Term, right_boolean: Term) -> exception::Result<Term> {
+fn result(left_boolean: Term, right_boolean: Term) -> Result<Term, NonNull<ErlangException>> {
     boolean_infix_operator!(left_boolean, right_boolean, &)
 }
diff --git a/native_implemented/otp/src/erlang/andalso_2.rs b/native_implemented/otp/src/erlang/andalso_2.rs
index ba617b09f..545442f98 100644
--- a/native_implemented/otp/src/erlang/andalso_2.rs
+++ b/native_implemented/otp/src/erlang/andalso_2.rs
@@ -1,16 +1,17 @@
 use std::convert::TryInto;
+use std::ptr::NonNull;
 
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::Term;
 
 /// `andalso/2` infix operator.
 ///
 /// Short-circuiting, but doesn't enforce `right` is boolean.  If you need to enforce `boolean` for
 /// both operands, use `and_2`.
 #[native_implemented::function(erlang:andalso/2)]
-fn result(boolean: Term, term: Term) -> exception::Result<Term> {
+fn result(boolean: Term, term: Term) -> Result<Term, NonNull<ErlangException>> {
     let boolean_bool: bool = boolean.try_into().context("left must be a bool")?;
 
     if boolean_bool {
diff --git a/native_implemented/otp/src/erlang/append_element_2.rs b/native_implemented/otp/src/erlang/append_element_2.rs
index d445e3285..3b81b2688 100644
--- a/native_implemented/otp/src/erlang/append_element_2.rs
+++ b/native_implemented/otp/src/erlang/append_element_2.rs
@@ -1,14 +1,16 @@
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use std::ptr::NonNull;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:append_element/2)]
-fn result(process: &Process, tuple: Term, element: Term) -> exception::Result<Term> {
+fn result(process: &Process, tuple: Term, element: Term) -> Result<Term, NonNull<ErlangException>> {
     let internal = term_try_into_tuple!(tuple)?;
     let mut new_elements_vec: Vec<Term> = Vec::with_capacity(internal.len() + 1);
     new_elements_vec.extend_from_slice(&internal[..]);
     new_elements_vec.push(element);
-    let new_tuple = process.tuple_from_slice(&new_elements_vec);
+    let new_tuple = process.tuple_term_from_term_slice(&new_elements_vec);
 
     Ok(new_tuple)
 }
diff --git a/native_implemented/otp/src/erlang/apply.rs b/native_implemented/otp/src/erlang/apply.rs
index 347bbe575..19b153d8c 100644
--- a/native_implemented/otp/src/erlang/apply.rs
+++ b/native_implemented/otp/src/erlang/apply.rs
@@ -1,15 +1,17 @@
+use std::ptr::NonNull;
+
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::{Term, TypeError};
 
 use crate::runtime::context::term_is_not_type;
 
-pub fn arguments_term_to_vec(arguments: Term) -> exception::Result<Vec<Term>> {
+pub fn arguments_term_to_vec(arguments: Term) -> Result<Vec<Term>, NonNull<ErlangException>> {
     let mut argument_vec: Vec<Term> = Vec::new();
 
-    match arguments.decode().unwrap() {
-        TypedTerm::List(arguments_boxed_cons) => {
+    match arguments {
+        Term::Cons(arguments_boxed_cons) => {
             for result in arguments_boxed_cons.iter() {
                 match result {
                     Ok(element) => argument_vec.push(element),
@@ -27,7 +29,7 @@ pub fn arguments_term_to_vec(arguments: Term) -> exception::Result<Vec<Term>> {
 
             Ok(argument_vec)
         }
-        TypedTerm::Nil => Ok(argument_vec),
+        Term::Nil => Ok(argument_vec),
         _ => Err(TypeError)
             .context(term_is_not_type(
                 "arguments",
diff --git a/native_implemented/otp/src/erlang/apply_2.rs b/native_implemented/otp/src/erlang/apply_2.rs
index 9274dbc11..2a56c61ee 100644
--- a/native_implemented/otp/src/erlang/apply_2.rs
+++ b/native_implemented/otp/src/erlang/apply_2.rs
@@ -2,12 +2,13 @@ use std::ptr::NonNull;
 
 use anyhow::*;
 
-use liblumen_alloc::erts::exception::{self, badarity, Exception};
-use liblumen_alloc::erts::process::ffi::ErlangResult;
-use liblumen_alloc::erts::process::{trace::Trace, FrameWithArguments, Process};
-use liblumen_alloc::erts::process::{Frame, Native};
-use liblumen_alloc::erts::term::prelude::*;
-use liblumen_alloc::{Arity, ModuleFunctionArity};
+use firefly_rt::backtrace::Trace;
+use firefly_rt::error::ErlangException;
+use firefly_rt::function::{Arity, ErlangResult, ModuleFunctionArity};
+use firefly_rt::process::Process;
+use firefly_rt::term::{atoms, Closure, Term, TypeError};
+
+use crate::runtime;
 
 extern "Rust" {
     #[link_name = "lumen_rt_apply_2"]
@@ -19,7 +20,7 @@ extern "Rust" {
 
 #[export_name = "erlang:apply/2"]
 pub extern "C-unwind" fn apply_2(function: Term, arguments: Term) -> ErlangResult {
-    let arc_process = crate::runtime::process::current_process();
+    let arc_process = runtime::process::current_process();
     match apply_2_impl(&arc_process, function, arguments) {
         Ok(result) => result,
         Err(exception) => arc_process.return_status(Err(exception)),
@@ -30,7 +31,7 @@ fn apply_2_impl(
     process: &Process,
     function: Term,
     arguments: Term,
-) -> exception::Result<ErlangResult> {
+) -> Result<ErlangResult, NonNull<ErlangException>> {
     let function_boxed_closure: Boxed<Closure> = function
         .try_into()
         .with_context(|| format!("function ({}) is not a function", function))?;
@@ -64,12 +65,12 @@ fn apply_2_impl(
     }
 }
 
-fn argument_list_to_vec(list: Term) -> exception::Result<Vec<Term>> {
+fn argument_list_to_vec(list: Term) -> Result<Vec<Term>, NonNull<ErlangException>> {
     let mut vec = Vec::new();
 
-    match list.decode()? {
-        TypedTerm::Nil => Ok(vec),
-        TypedTerm::List(boxed_cons) => {
+    match list {
+        Term::Nil => Ok(vec),
+        Term::Cons(boxed_cons) => {
             for result in boxed_cons.into_iter() {
                 match result {
                     Ok(element) => vec.push(element),
@@ -89,18 +90,10 @@ fn argument_list_to_vec(list: Term) -> exception::Result<Vec<Term>> {
     }
 }
 
-pub fn frame() -> Frame {
-    frame_for_native(NATIVE)
-}
-
-pub fn frame_for_native(native: Native) -> Frame {
-    Frame::new(module_function_arity(), native)
-}
-
 pub fn module_function_arity() -> ModuleFunctionArity {
     ModuleFunctionArity {
-        module: Atom::from_str("erlang"),
-        function: Atom::from_str("apply"),
+        module: atoms::Erlang,
+        function: atoms::Apply,
         arity: ARITY,
     }
 }
@@ -110,6 +103,5 @@ pub fn frame_with_arguments(function: Term, arguments: Term) -> FrameWithArgumen
 }
 
 pub const ARITY: Arity = 2;
-pub const NATIVE: Native = Native::Two(apply_2);
 pub const CLOSURE_NATIVE: Option<NonNull<std::ffi::c_void>> =
     Some(unsafe { NonNull::new_unchecked(apply_2 as *mut std::ffi::c_void) });
diff --git a/native_implemented/otp/src/erlang/apply_3.rs b/native_implemented/otp/src/erlang/apply_3.rs
index 533b67d54..ad93ba45c 100644
--- a/native_implemented/otp/src/erlang/apply_3.rs
+++ b/native_implemented/otp/src/erlang/apply_3.rs
@@ -1,14 +1,11 @@
 use std::ptr::NonNull;
 
 use anyhow::*;
+use firefly_rt::backtrace::Trace;
+use firefly_rt::error::ErlangException;
 
-use liblumen_alloc::erts::apply::{find_symbol, DynamicCallee};
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::ffi::ErlangResult;
-use liblumen_alloc::erts::process::trace::Trace;
-use liblumen_alloc::erts::process::{Frame, Native};
-use liblumen_alloc::erts::term::prelude::*;
-use liblumen_alloc::{Arity, ModuleFunctionArity};
+use firefly_rt::function::{Arity, DynamicCallee, ErlangResult, find_symbol, ModuleFunctionArity};
+use firefly_rt::term::{atoms, Term};
 
 use crate::erlang::apply::arguments_term_to_vec;
 
@@ -29,7 +26,7 @@ pub extern "C-unwind" fn apply_3(module: Term, function: Term, arguments: Term)
         Err(exception) => arc_process.return_status(Err(exception)),
     }
 }
-fn apply_3_impl(module: Term, function: Term, arguments: Term) -> exception::Result<ErlangResult> {
+fn apply_3_impl(module: Term, function: Term, arguments: Term) -> Result<ErlangResult, NonNull<ErlangException>> {
     let module_atom = term_try_into_atom!(module)?;
     let function_atom = term_try_into_atom!(function)?;
     let argument_vec = arguments_term_to_vec(arguments)?;
@@ -51,8 +48,8 @@ fn apply_3_impl(module: Term, function: Term, arguments: Term) -> exception::Res
                 Some(
                     anyhow!(
                         "{}:{}/{} is not exported",
-                        module_atom.name(),
-                        function_atom.name(),
+                        module_atom.as_str(),
+                        function_atom.as_str(),
                         arity
                     )
                     .into(),
@@ -73,13 +70,12 @@ pub fn frame_for_native(native: Native) -> Frame {
 
 pub fn module_function_arity() -> ModuleFunctionArity {
     ModuleFunctionArity {
-        module: Atom::from_str("erlang"),
-        function: Atom::from_str("apply"),
+        module: atoms::Erlang,
+        function: atoms::Apply,
         arity: ARITY,
     }
 }
 
 pub const ARITY: Arity = 3;
-pub const NATIVE: Native = Native::Three(apply_3);
 pub const CLOSURE_NATIVE: Option<NonNull<std::ffi::c_void>> =
     Some(unsafe { NonNull::new_unchecked(apply_3 as *mut std::ffi::c_void) });
diff --git a/native_implemented/otp/src/erlang/are_equal_after_conversion_2.rs b/native_implemented/otp/src/erlang/are_equal_after_conversion_2.rs
index 3b681e24f..d8541064e 100644
--- a/native_implemented/otp/src/erlang/are_equal_after_conversion_2.rs
+++ b/native_implemented/otp/src/erlang/are_equal_after_conversion_2.rs
@@ -1,7 +1,7 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::term::Term;
 
 /// `==/2` infix operator.  Unlike `=:=`, converts between floats and integers.
 #[native_implemented::function(erlang:==/2)]
diff --git a/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test.rs b/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test.rs
index 144c492c2..a2ebf5682 100644
--- a/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test.rs
+++ b/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test.rs
@@ -13,16 +13,14 @@ mod with_small_integer_left;
 mod with_subbinary_left;
 mod with_tuple_left;
 
-use std::convert::TryInto;
 use std::ptr::NonNull;
 
 use proptest::arbitrary::any;
 use proptest::prop_assert_eq;
-use proptest::strategy::{Just, Strategy};
+use proptest::strategy::Just;
 use proptest::test_runner::{Config, TestRunner};
 
-use liblumen_alloc::erts::process::alloc::TermAlloc;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::{Integer, Term};
 
 use crate::erlang::are_equal_after_conversion_2::result;
 use crate::test::strategy;
diff --git a/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_atom_left.rs b/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_atom_left.rs
index 24e248f5e..6c1d13627 100644
--- a/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_atom_left.rs
+++ b/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_atom_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_atom_returns_false() {
     run!(
diff --git a/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_big_integer_left.rs b/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_big_integer_left.rs
index a5831f0de..02a1bfc9a 100644
--- a/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_big_integer_left.rs
+++ b/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_big_integer_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_big_integer_or_float_returns_false() {
     run!(
@@ -10,7 +8,7 @@ fn without_big_integer_or_float_returns_false() {
                 strategy::term::integer::big(arc_process.clone()),
                 strategy::term(arc_process.clone())
                     .prop_filter("Right must not be a big integer or float", |v| {
-                        !(v.is_boxed_bigint() || v.is_boxed_float())
+                        !(v.is_boxed_bigint() || v.is_float())
                     }),
             )
         },
@@ -61,7 +59,7 @@ fn with_same_value_float_right_returns_true() {
             run!(
                 |arc_process| {
                     (Just(arc_process.clone()), strategy).prop_map(|(arc_process, i)| {
-                        (arc_process.integer(i), arc_process.float(i as f64))
+                        (arc_process.integer(i).unwrap(), (i as f64).into())
                     })
                 },
                 |(left, right)| {
@@ -82,7 +80,7 @@ fn with_different_value_float_right_returns_false() {
             run!(
                 |arc_process| {
                     (Just(arc_process.clone()), strategy).prop_map(|(arc_process, i)| {
-                        (arc_process.integer(i + 1), arc_process.float(i as f64))
+                        (arc_process.integer(i + 1).unwrap(), (i as f64).into())
                     })
                 },
                 |(left, right)| {
diff --git a/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_empty_list_left.rs b/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_empty_list_left.rs
index 5c46e3ff8..a62896c36 100644
--- a/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_empty_list_left.rs
+++ b/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_empty_list_left.rs
@@ -1,13 +1,11 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_empty_list_returns_false() {
     run!(
         |arc_process| {
             (
-                Just(Term::NIL),
+                Just(Term::Nil),
                 strategy::term(arc_process.clone())
                     .prop_filter("Right must not be empty list", |v| !v.is_nil()),
             )
@@ -22,5 +20,5 @@ fn without_empty_list_returns_false() {
 
 #[test]
 fn with_empty_list_right_returns_true() {
-    assert_eq!(result(Term::NIL, Term::NIL), true.into());
+    assert_eq!(result(Term::Nil, Term::Nil), true.into());
 }
diff --git a/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_external_pid_left.rs b/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_external_pid_left.rs
index a5f4013b1..a155b5b08 100644
--- a/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_external_pid_left.rs
+++ b/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_external_pid_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_external_pid_left_returns_false() {
     run!(
diff --git a/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_float_left.rs b/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_float_left.rs
index 418a6da4f..cacc022f4 100644
--- a/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_float_left.rs
+++ b/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_float_left.rs
@@ -1,13 +1,11 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_small_integer_or_big_integer_or_float_returns_false() {
     run!(
         |arc_process| {
             (
-                strategy::term::float(arc_process.clone()),
+                strategy::term::float(),
                 strategy::term(arc_process.clone())
                     .prop_filter("Right must not be a number", |v| !v.is_number()),
             )
@@ -23,7 +21,7 @@ fn without_small_integer_or_big_integer_or_float_returns_false() {
 #[test]
 fn with_same_float_returns_true() {
     run!(
-        |arc_process| strategy::term::float(arc_process.clone()),
+        |arc_process| strategy::term::float(),
         |operand| {
             prop_assert_eq!(result(operand, operand), true.into());
 
@@ -39,7 +37,7 @@ fn with_same_value_float_right_returns_true() {
             (Just(arc_process.clone()), any::<f64>()).prop_map(|(arc_process, f)| {
                 let mut heap = arc_process.acquire_heap();
 
-                (heap.float(f).unwrap(), heap.float(f).unwrap())
+                (heap.into().unwrap(), heap.into().unwrap())
             })
         },
         |(left, right)| {
@@ -55,8 +53,8 @@ fn with_different_float_right_returns_false() {
     run!(
         |arc_process| {
             (
-                strategy::term::float(arc_process.clone()),
-                strategy::term::float(arc_process.clone()),
+                strategy::term::float(),
+                strategy::term::float(),
             )
                 .prop_filter("Right and left must be different", |(left, right)| {
                     left != right
@@ -81,7 +79,7 @@ fn with_same_value_small_integer_right_returns_true() {
                 .prop_map(|(arc_process, i)| {
                     let mut heap = arc_process.acquire_heap();
 
-                    (heap.float(i as f64).unwrap(), heap.integer(i).unwrap())
+                    (heap.into().unwrap(), heap.integer(i).unwrap())
                 })
         },
         |(left, right)| {
@@ -103,7 +101,7 @@ fn with_different_value_small_integer_right_returns_false() {
                 .prop_map(|(arc_process, i)| {
                     let mut heap = arc_process.acquire_heap();
 
-                    (heap.float(i as f64).unwrap(), heap.integer(i + 1).unwrap())
+                    (heap.into().unwrap(), heap.integer(i + 1).unwrap())
                 })
         },
         |(left, right)| {
@@ -123,7 +121,7 @@ fn with_same_value_big_integer_right_returns_true() {
                     (Just(arc_process.clone()), strategy.clone()).prop_map(|(arc_process, i)| {
                         let mut heap = arc_process.acquire_heap();
 
-                        (heap.float(i as f64).unwrap(), heap.integer(i).unwrap())
+                        (heap.into().unwrap(), heap.integer(i).unwrap())
                     })
                 },
                 |(left, right)| {
@@ -146,7 +144,7 @@ fn with_different_value_big_integer_right_returns_false() {
                     (Just(arc_process.clone()), strategy.clone()).prop_map(|(arc_process, i)| {
                         let mut heap = arc_process.acquire_heap();
 
-                        (heap.float(i as f64).unwrap(), heap.integer(i + 1).unwrap())
+                        (heap.into().unwrap(), heap.integer(i + 1).unwrap())
                     })
                 },
                 |(left, right)| {
diff --git a/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_function_left.rs b/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_function_left.rs
index cac039292..946663eb0 100644
--- a/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_function_left.rs
+++ b/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_function_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_function_right_returns_false() {
     run!(
@@ -9,7 +7,7 @@ fn without_function_right_returns_false() {
             (
                 strategy::term::is_function(arc_process.clone()),
                 strategy::term(arc_process.clone())
-                    .prop_filter("Right must not be function", |v| !v.is_boxed_function()),
+                    .prop_filter("Right must not be function", |v| !v.is_closure()),
             )
         },
         |(left, right)| {
diff --git a/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_heap_binary_left.rs b/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_heap_binary_left.rs
index b9a4a1497..d92e3b783 100644
--- a/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_heap_binary_left.rs
+++ b/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_heap_binary_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_binary_right_returns_false() {
     run!(
diff --git a/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_list_left.rs b/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_list_left.rs
index 4a16f041d..c83084afe 100644
--- a/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_list_left.rs
+++ b/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_list_left.rs
@@ -1,7 +1,6 @@
 use super::*;
 
 use proptest::collection::SizeRange;
-use proptest::strategy::Strategy;
 
 use crate::test::strategy::NON_EMPTY_RANGE_INCLUSIVE;
 
@@ -47,14 +46,14 @@ fn with_same_value_list_right_returns_true() {
 
                     match vec.len() {
                         1 => (
-                            heap.list_from_slice(&vec)
+                            Term::list_from_slice_in(&vec, heap).unwrap()
                                 .unwrap()
                                 .map(|l| l.into())
-                                .unwrap_or(Term::NIL),
-                            heap.list_from_slice(&vec)
+                                .unwrap_or(Term::Nil),
+                            Term::list_from_slice_in(&vec, heap).unwrap()
                                 .unwrap()
                                 .map(|l| l.into())
-                                .unwrap_or(Term::NIL),
+                                .unwrap_or(Term::Nil),
                         ),
                         len => {
                             let last_index = len - 1;
@@ -63,11 +62,11 @@ fn with_same_value_list_right_returns_true() {
                                 heap.improper_list_from_slice(&vec[0..last_index], vec[last_index])
                                     .unwrap()
                                     .map(|l| l.into())
-                                    .unwrap_or(Term::NIL),
+                                    .unwrap_or(Term::Nil),
                                 heap.improper_list_from_slice(&vec[0..last_index], vec[last_index])
                                     .unwrap()
                                     .map(|l| l.into())
-                                    .unwrap_or(Term::NIL),
+                                    .unwrap_or(Term::Nil),
                             )
                         }
                     }
diff --git a/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_local_pid_left.rs b/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_local_pid_left.rs
index 4bc223c2e..39478aaa4 100644
--- a/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_local_pid_left.rs
+++ b/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_local_pid_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_local_pid_right_returns_false() {
     run!(
diff --git a/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_local_reference_left.rs b/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_local_reference_left.rs
index f2182005e..305eaaf05 100644
--- a/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_local_reference_left.rs
+++ b/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_local_reference_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_local_reference_right_returns_false() {
     run!(
diff --git a/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_map_left.rs b/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_map_left.rs
index 21660c41e..b2aeb7c7a 100644
--- a/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_map_left.rs
+++ b/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_map_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_map_right_returns_false() {
     run!(
@@ -9,7 +7,7 @@ fn without_map_right_returns_false() {
             (
                 strategy::term::map(arc_process.clone()),
                 strategy::term(arc_process.clone())
-                    .prop_filter("Right cannot be a map", |right| !right.is_boxed_map()),
+                    .prop_filter("Right cannot be a map", |right| !right.is_map()),
             )
         },
         |(left, right)| {
diff --git a/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_small_integer_left.rs b/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_small_integer_left.rs
index ada2030bc..711ed2d99 100644
--- a/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_small_integer_left.rs
+++ b/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_small_integer_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_small_integer_or_float_returns_false() {
     run!(
@@ -10,7 +8,7 @@ fn without_small_integer_or_float_returns_false() {
                 strategy::term::integer::small(arc_process.clone()),
                 strategy::term(arc_process.clone())
                     .prop_filter("Right must not be a small integer or float", |v| {
-                        !(v.is_smallint() || v.is_boxed_float())
+                        !(v.is_smallint() || v.is_float())
                     }),
             )
         },
@@ -40,7 +38,7 @@ fn with_same_value_small_integer_right_returns_true() {
         |arc_process| {
             (
                 Just(arc_process.clone()),
-                SmallInteger::MIN_VALUE..SmallInteger::MAX_VALUE,
+                Integer::MIN_SMALL..Integer::MAX_SMALL,
             )
                 .prop_map(|(arc_process, i)| {
                     let mut heap = arc_process.acquire_heap();
@@ -62,7 +60,7 @@ fn with_different_small_integer_right_returns_false() {
         |arc_process| {
             (
                 Just(arc_process.clone()),
-                SmallInteger::MIN_VALUE..SmallInteger::MAX_VALUE,
+                Integer::MIN_SMALL..Integer::MAX_SMALL,
             )
                 .prop_map(|(arc_process, i)| {
                     let mut heap = arc_process.acquire_heap();
@@ -89,7 +87,7 @@ fn with_same_value_float_right_returns_true() {
                 .prop_map(|(arc_process, i)| {
                     let mut heap = arc_process.acquire_heap();
 
-                    (heap.integer(i).unwrap(), heap.float(i as f64).unwrap())
+                    (heap.integer(i).unwrap(), heap.into().unwrap())
                 })
         },
         |(left, right)| {
@@ -115,7 +113,7 @@ fn with_different_value_float_right_returns_false() {
 
                     (
                         heap.integer(i).unwrap(),
-                        heap.float((i + diff) as f64).unwrap(),
+                        ((i + diff) as f64).into(),
                     )
                 })
         },
diff --git a/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_subbinary_left.rs b/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_subbinary_left.rs
index c5946c373..29227d678 100644
--- a/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_subbinary_left.rs
+++ b/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_subbinary_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_bitstring_right_returns_false() {
     run!(
diff --git a/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_tuple_left.rs b/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_tuple_left.rs
index d64e43a09..3040498cf 100644
--- a/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_tuple_left.rs
+++ b/native_implemented/otp/src/erlang/are_equal_after_conversion_2/test/with_tuple_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_tuple_right_returns_false() {
     run!(
@@ -9,7 +7,7 @@ fn without_tuple_right_returns_false() {
             (
                 strategy::term::tuple(arc_process.clone()),
                 strategy::term(arc_process.clone())
-                    .prop_filter("Right must not be tuple", |v| !v.is_boxed_tuple()),
+                    .prop_filter("Right must not be tuple", |v| !v.is_tuple()),
             )
         },
         |(left, right)| {
@@ -47,8 +45,8 @@ fn with_same_value_tuple_right_returns_true() {
                     let mut heap = arc_process.acquire_heap();
 
                     (
-                        heap.tuple_from_slice(&vec).unwrap(),
-                        heap.tuple_from_slice(&vec).unwrap(),
+                        heap.tuple_term_from_term_slice(&vec).unwrap(),
+                        heap.tuple_term_from_term_slice(&vec).unwrap(),
                     )
                 })
         },
diff --git a/native_implemented/otp/src/erlang/are_exactly_equal_2.rs b/native_implemented/otp/src/erlang/are_exactly_equal_2.rs
index 7ade8c38e..37a699f31 100644
--- a/native_implemented/otp/src/erlang/are_exactly_equal_2.rs
+++ b/native_implemented/otp/src/erlang/are_exactly_equal_2.rs
@@ -1,12 +1,12 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 /// `=:=/2` infix operator.  Unlike `==`, does not convert between floats and integers.
 #[native_implemented::function(erlang:=:=/2)]
 pub fn result(left: Term, right: Term) -> Term {
-    let left = left.decode().unwrap();
-    let right = right.decode().unwrap();
+    let left = left;
+    let right = right;
     left.exact_eq(&right).into()
 }
diff --git a/native_implemented/otp/src/erlang/are_exactly_equal_2/test.rs b/native_implemented/otp/src/erlang/are_exactly_equal_2/test.rs
index 6cee57415..84d8b53bb 100644
--- a/native_implemented/otp/src/erlang/are_exactly_equal_2/test.rs
+++ b/native_implemented/otp/src/erlang/are_exactly_equal_2/test.rs
@@ -13,7 +13,6 @@ mod with_small_integer_left;
 mod with_subbinary_left;
 mod with_tuple_left;
 
-use std::convert::TryInto;
 use std::ptr::NonNull;
 
 use proptest::arbitrary::any;
@@ -21,7 +20,7 @@ use proptest::prop_assert_eq;
 use proptest::strategy::Just;
 use proptest::test_runner::{Config, TestRunner};
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::{Integer, Term};
 
 use crate::erlang::are_exactly_equal_2::result;
 use crate::test::strategy;
diff --git a/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_atom_left.rs b/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_atom_left.rs
index 24e248f5e..6c1d13627 100644
--- a/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_atom_left.rs
+++ b/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_atom_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_atom_returns_false() {
     run!(
diff --git a/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_big_integer_left.rs b/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_big_integer_left.rs
index 2206d82e8..f7d7c4375 100644
--- a/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_big_integer_left.rs
+++ b/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_big_integer_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_big_integer_returns_false() {
     run!(
diff --git a/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_empty_list_left.rs b/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_empty_list_left.rs
index 5c46e3ff8..a62896c36 100644
--- a/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_empty_list_left.rs
+++ b/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_empty_list_left.rs
@@ -1,13 +1,11 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_empty_list_returns_false() {
     run!(
         |arc_process| {
             (
-                Just(Term::NIL),
+                Just(Term::Nil),
                 strategy::term(arc_process.clone())
                     .prop_filter("Right must not be empty list", |v| !v.is_nil()),
             )
@@ -22,5 +20,5 @@ fn without_empty_list_returns_false() {
 
 #[test]
 fn with_empty_list_right_returns_true() {
-    assert_eq!(result(Term::NIL, Term::NIL), true.into());
+    assert_eq!(result(Term::Nil, Term::Nil), true.into());
 }
diff --git a/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_external_pid_left.rs b/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_external_pid_left.rs
index d150bfd83..fc928b984 100644
--- a/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_external_pid_left.rs
+++ b/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_external_pid_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_external_pid_left_returns_false() {
     run!(
diff --git a/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_float_left.rs b/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_float_left.rs
index 58a33fbfe..4abf386e3 100644
--- a/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_float_left.rs
+++ b/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_float_left.rs
@@ -1,13 +1,11 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_float_returns_false() {
     run!(
         |arc_process| {
             (
-                strategy::term::float(arc_process.clone()),
+                strategy::term::float(),
                 strategy::term(arc_process.clone())
                     .prop_filter("Right must not be a float", |v| !v.is_float()),
             )
@@ -24,7 +22,7 @@ fn without_float_returns_false() {
 fn with_same_float_returns_true() {
     with_process_arc(|arc_process| {
         TestRunner::new(Config::with_source_file(file!()))
-            .run(&strategy::term::float(arc_process.clone()), |operand| {
+            .run(&strategy::term::float(), |operand| {
                 prop_assert_eq!(result(operand, operand), true.into());
 
                 Ok(())
@@ -38,7 +36,7 @@ fn with_same_value_float_right_returns_true() {
     run!(
         |arc_process| {
             (Just(arc_process.clone()), any::<f64>())
-                .prop_map(|(arc_process, f)| (arc_process.float(f), arc_process.float(f)))
+                .prop_map(|(_, f)| (f.into(), f.into()))
         },
         |(left, right)| {
             prop_assert_eq!(result(left, right), true.into());
@@ -52,8 +50,8 @@ fn with_same_value_float_right_returns_true() {
 fn with_different_float_right_returns_false() {
     run!(
         |arc_process| {
-            (Just(arc_process.clone()), any::<f64>()).prop_map(|(arc_process, f)| {
-                (arc_process.float(f), arc_process.float(f / 2.0 + 1.0))
+            (Just(arc_process.clone()), any::<f64>()).prop_map(|(_, f)| {
+                (f.into(), f.into())
             })
         },
         |(left, right)| {
diff --git a/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_function_left.rs b/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_function_left.rs
index 0d2353c43..c2c070445 100644
--- a/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_function_left.rs
+++ b/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_function_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_function_right_returns_false() {
     run!(
@@ -9,7 +7,7 @@ fn without_function_right_returns_false() {
             (
                 strategy::term::is_function(arc_process.clone()),
                 strategy::term(arc_process.clone())
-                    .prop_filter("Right must not be function", |v| !v.is_boxed_function()),
+                    .prop_filter("Right must not be function", |v| !v.is_closure()),
             )
         },
         |(left, right)| {
diff --git a/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_heap_binary_left.rs b/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_heap_binary_left.rs
index 1fbd4399e..cf6305dc4 100644
--- a/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_heap_binary_left.rs
+++ b/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_heap_binary_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_bitstring_right_returns_false() {
     run!(
diff --git a/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_list_left.rs b/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_list_left.rs
index 5f793ef34..a72ea87d0 100644
--- a/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_list_left.rs
+++ b/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_list_left.rs
@@ -1,7 +1,6 @@
 use super::*;
 
 use proptest::collection::SizeRange;
-use proptest::strategy::Strategy;
 
 use crate::test::strategy::NON_EMPTY_RANGE_INCLUSIVE;
 
@@ -44,8 +43,8 @@ fn with_same_value_list_right_returns_true() {
             proptest::collection::vec(strategy::term(arc_process.clone()), size_range).prop_map(
                 move |vec| match vec.len() {
                     1 => (
-                        arc_process.list_from_slice(&vec),
-                        arc_process.list_from_slice(&vec),
+                        arc_process.list_from_slice(&vec).unwrap(),
+                        arc_process.list_from_slice(&vec).unwrap(),
                     ),
                     len => {
                         let last_index = len - 1;
diff --git a/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_local_pid_left.rs b/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_local_pid_left.rs
index ad6158b20..5c7b80388 100644
--- a/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_local_pid_left.rs
+++ b/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_local_pid_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_local_pid_right_returns_false() {
     run!(
diff --git a/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_local_reference_left.rs b/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_local_reference_left.rs
index 96529e2a5..d04deb73d 100644
--- a/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_local_reference_left.rs
+++ b/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_local_reference_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_local_reference_right_returns_false() {
     run!(
diff --git a/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_map_left.rs b/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_map_left.rs
index 184da185f..7d1283466 100644
--- a/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_map_left.rs
+++ b/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_map_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_map_right_returns_false() {
     run!(
@@ -9,7 +7,7 @@ fn without_map_right_returns_false() {
             (
                 strategy::term::map(arc_process.clone()),
                 strategy::term(arc_process.clone())
-                    .prop_filter("Right cannot be a map", |right| !right.is_boxed_map()),
+                    .prop_filter("Right cannot be a map", |right| !right.is_map()),
             )
         },
         |(left, right)| {
diff --git a/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_small_integer_left.rs b/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_small_integer_left.rs
index 91f866d36..26ae1df71 100644
--- a/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_small_integer_left.rs
+++ b/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_small_integer_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_small_integer_returns_false() {
     run!(
@@ -36,8 +34,8 @@ fn with_same_small_integer_right_returns_true() {
 fn with_same_value_small_integer_right_returns_true() {
     run!(
         |arc_process| {
-            (SmallInteger::MIN_VALUE..SmallInteger::MAX_VALUE)
-                .prop_map(move |i| (arc_process.integer(i), arc_process.integer(i)))
+            (Integer::MIN_SMALL..Integer::MAX_SMALL)
+                .prop_map(move |i| (arc_process.integer(i).unwrap(), arc_process.integer(i).unwrap()))
         },
         |(left, right)| {
             prop_assert_eq!(result(left, right), true.into());
@@ -51,8 +49,8 @@ fn with_same_value_small_integer_right_returns_true() {
 fn with_different_small_integer_right_returns_false() {
     run!(
         |arc_process| {
-            (SmallInteger::MIN_VALUE..SmallInteger::MAX_VALUE)
-                .prop_map(move |i| (arc_process.integer(i), arc_process.integer(i + 1)))
+            (Integer::MIN_SMALL..Integer::MAX_SMALL)
+                .prop_map(move |i| (arc_process.integer(i).unwrap(), arc_process.integer(i + 1).unwrap()))
         },
         |(left, right)| {
             prop_assert_eq!(result(left, right), false.into());
diff --git a/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_subbinary_left.rs b/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_subbinary_left.rs
index 32cf1d4b1..943f892ec 100644
--- a/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_subbinary_left.rs
+++ b/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_subbinary_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_bitstring_right_returns_false() {
     run!(
diff --git a/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_tuple_left.rs b/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_tuple_left.rs
index bdd9c111b..492cd6698 100644
--- a/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_tuple_left.rs
+++ b/native_implemented/otp/src/erlang/are_exactly_equal_2/test/with_tuple_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_tuple_right_returns_false() {
     run!(
@@ -9,7 +7,7 @@ fn without_tuple_right_returns_false() {
             (
                 strategy::term::tuple(arc_process.clone()),
                 strategy::term(arc_process.clone())
-                    .prop_filter("Right must not be tuple", |v| !v.is_boxed_tuple()),
+                    .prop_filter("Right must not be tuple", |v| !v.is_tuple()),
             )
         },
         |(left, right)| {
@@ -40,8 +38,8 @@ fn with_same_value_tuple_right_returns_true() {
             proptest::collection::vec(strategy::term(arc_process.clone()), strategy::size_range())
                 .prop_map(move |vec| {
                     (
-                        arc_process.tuple_from_slice(&vec),
-                        arc_process.tuple_from_slice(&vec),
+                        arc_process.tuple_term_from_term_slice(&vec),
+                        arc_process.tuple_term_from_term_slice(&vec),
                     )
                 })
         },
diff --git a/native_implemented/otp/src/erlang/are_exactly_not_equal_2.rs b/native_implemented/otp/src/erlang/are_exactly_not_equal_2.rs
index 848018421..1863668b4 100644
--- a/native_implemented/otp/src/erlang/are_exactly_not_equal_2.rs
+++ b/native_implemented/otp/src/erlang/are_exactly_not_equal_2.rs
@@ -1,12 +1,12 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 /// `=/=/2` infix operator.  Unlike `!=`, does not convert between floats and integers.
 #[native_implemented::function(erlang:=/=/2)]
 pub fn result(left: Term, right: Term) -> Term {
-    let left = left.decode().unwrap();
-    let right = right.decode().unwrap();
+    let left = left;
+    let right = right;
     left.exact_ne(&right).into()
 }
diff --git a/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test.rs b/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test.rs
index 25c668611..10eadfc3e 100644
--- a/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test.rs
+++ b/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test.rs
@@ -13,16 +13,14 @@ mod with_small_integer_left;
 mod with_subbinary_left;
 mod with_tuple_left;
 
-use std::convert::TryInto;
 use std::ptr::NonNull;
 
 use proptest::arbitrary::any;
 use proptest::prop_assert_eq;
-use proptest::strategy::Just;
+use proptest::strategy::{Just, Strategy};
 use proptest::test_runner::{Config, TestRunner};
 
-use liblumen_alloc::erts::process::alloc::TermAlloc;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::{Integer, Term};
 
 use crate::erlang::are_exactly_not_equal_2::result;
 use crate::test::strategy;
diff --git a/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_atom_left.rs b/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_atom_left.rs
index c4f4c55a6..9a397b292 100644
--- a/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_atom_left.rs
+++ b/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_atom_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_atom_returns_true() {
     run!(
diff --git a/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_big_integer_left.rs b/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_big_integer_left.rs
index d434a4d43..5f33b0ab4 100644
--- a/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_big_integer_left.rs
+++ b/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_big_integer_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_big_integer_returns_true() {
     run!(
diff --git a/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_empty_list_left.rs b/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_empty_list_left.rs
index dfa4144a7..8960f5baa 100644
--- a/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_empty_list_left.rs
+++ b/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_empty_list_left.rs
@@ -1,13 +1,11 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_empty_list_returns_true() {
     run!(
         |arc_process| {
             (
-                Just(Term::NIL),
+                Just(Term::Nil),
                 strategy::term(arc_process.clone())
                     .prop_filter("Right must not be empty list", |v| !v.is_nil()),
             )
@@ -22,5 +20,5 @@ fn without_empty_list_returns_true() {
 
 #[test]
 fn with_empty_list_right_returns_false() {
-    assert_eq!(result(Term::NIL, Term::NIL), false.into());
+    assert_eq!(result(Term::Nil, Term::Nil), false.into());
 }
diff --git a/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_external_pid_left.rs b/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_external_pid_left.rs
index a1edd1dfe..5fe793884 100644
--- a/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_external_pid_left.rs
+++ b/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_external_pid_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_external_pid_left_returns_true() {
     run!(
diff --git a/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_float_left.rs b/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_float_left.rs
index 374321bdc..5c19147e6 100644
--- a/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_float_left.rs
+++ b/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_float_left.rs
@@ -1,15 +1,13 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_float_returns_true() {
     run!(
         |arc_process| {
             (
-                strategy::term::float(arc_process.clone()),
+                strategy::term::float(),
                 strategy::term(arc_process.clone())
-                    .prop_filter("Right must not be a float", |v| !v.is_boxed_float()),
+                    .prop_filter("Right must not be a float", |v| !v.is_float()),
             )
         },
         |(left, right)| {
@@ -24,7 +22,7 @@ fn without_float_returns_true() {
 fn with_same_float_returns_false() {
     with_process_arc(|arc_process| {
         TestRunner::new(Config::with_source_file(file!()))
-            .run(&strategy::term::float(arc_process.clone()), |operand| {
+            .run(&strategy::term::float(), |operand| {
                 prop_assert_eq!(result(operand, operand), false.into());
 
                 Ok(())
@@ -38,7 +36,7 @@ fn with_same_value_float_right_returns_false() {
     run!(
         |arc_process| {
             (Just(arc_process.clone()), any::<f64>())
-                .prop_map(|(arc_process, f)| (arc_process.float(f), arc_process.float(f)))
+                .prop_map(|(arc_process, f)| (f.into(), f.into()))
         },
         |(left, right)| {
             prop_assert_eq!(result(left.into(), right.into()), false.into());
@@ -53,7 +51,7 @@ fn with_different_float_right_returns_true() {
     run!(
         |arc_process| {
             (Just(arc_process.clone()), any::<f64>()).prop_map(|(arc_process, f)| {
-                (arc_process.float(f), arc_process.float(f / 2.0 + 1.0))
+                (f.into(), (f / 2.0 + 1.0).into())
             })
         },
         |(left, right)| {
diff --git a/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_function_left.rs b/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_function_left.rs
index 0a9f72018..c5892fbb0 100644
--- a/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_function_left.rs
+++ b/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_function_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_function_right_returns_true() {
     run!(
@@ -9,7 +7,7 @@ fn without_function_right_returns_true() {
             (
                 strategy::term::is_function(arc_process.clone()),
                 strategy::term(arc_process.clone())
-                    .prop_filter("Right must not be function", |v| !v.is_boxed_function()),
+                    .prop_filter("Right must not be function", |v| !v.is_closure()),
             )
         },
         |(left, right)| {
diff --git a/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_heap_binary_left.rs b/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_heap_binary_left.rs
index 2f41b53c7..32e83ca50 100644
--- a/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_heap_binary_left.rs
+++ b/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_heap_binary_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_binary_right_returns_true() {
     run!(
diff --git a/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_list_left.rs b/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_list_left.rs
index 17a1a4809..17656094c 100644
--- a/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_list_left.rs
+++ b/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_list_left.rs
@@ -1,7 +1,6 @@
 use super::*;
 
 use proptest::collection::SizeRange;
-use proptest::strategy::Strategy;
 
 use crate::test::strategy::NON_EMPTY_RANGE_INCLUSIVE;
 
@@ -44,8 +43,8 @@ fn with_same_value_list_right_returns_false() {
             proptest::collection::vec(strategy::term(arc_process.clone()), size_range).prop_map(
                 move |vec| match vec.len() {
                     1 => (
-                        arc_process.list_from_slice(&vec),
-                        arc_process.list_from_slice(&vec),
+                        arc_process.list_from_slice(&vec).unwrap(),
+                        arc_process.list_from_slice(&vec).unwrap(),
                     ),
                     len => {
                         let last_index = len - 1;
diff --git a/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_local_pid_left.rs b/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_local_pid_left.rs
index 4c351cf88..d15f9edfb 100644
--- a/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_local_pid_left.rs
+++ b/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_local_pid_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_local_pid_right_returns_true() {
     run!(
diff --git a/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_local_reference_left.rs b/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_local_reference_left.rs
index c71407ca7..db84353db 100644
--- a/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_local_reference_left.rs
+++ b/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_local_reference_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_local_reference_right_returns_true() {
     run!(
diff --git a/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_map_left.rs b/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_map_left.rs
index af55a02ff..34c192bcf 100644
--- a/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_map_left.rs
+++ b/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_map_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_map_right_returns_true() {
     run!(
@@ -9,7 +7,7 @@ fn without_map_right_returns_true() {
             (
                 strategy::term::map(arc_process.clone()),
                 strategy::term(arc_process.clone())
-                    .prop_filter("Right cannot be a map", |right| !right.is_boxed_map()),
+                    .prop_filter("Right cannot be a map", |right| !right.is_map()),
             )
         },
         |(left, right)| {
diff --git a/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_small_integer_left.rs b/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_small_integer_left.rs
index 97f22fe75..187b65e36 100644
--- a/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_small_integer_left.rs
+++ b/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_small_integer_left.rs
@@ -1,6 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
 
 #[test]
 fn without_small_integer_returns_true() {
@@ -36,7 +35,7 @@ fn with_same_small_integer_right_returns_false() {
 fn with_same_value_small_integer_right_returns_false() {
     run!(
         |arc_process| {
-            (SmallInteger::MIN_VALUE..SmallInteger::MAX_VALUE).prop_map(move |i| {
+            (Integer::MIN_SMALL..Integer::MAX_SMALL).prop_map(move |i| {
                 let mut heap = arc_process.acquire_heap();
 
                 (heap.integer(i).unwrap(), heap.integer(i).unwrap())
@@ -54,7 +53,7 @@ fn with_same_value_small_integer_right_returns_false() {
 fn with_different_small_integer_right_returns_true() {
     run!(
         |arc_process| {
-            (SmallInteger::MIN_VALUE..SmallInteger::MAX_VALUE).prop_map(move |i| {
+            (Integer::MIN_SMALL..Integer::MAX_SMALL).prop_map(move |i| {
                 let mut heap = arc_process.acquire_heap();
 
                 (heap.integer(i).unwrap(), heap.integer(i + 1).unwrap())
diff --git a/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_subbinary_left.rs b/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_subbinary_left.rs
index cdb3df62a..47f9b975c 100644
--- a/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_subbinary_left.rs
+++ b/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_subbinary_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_bitstring_right_returns_true() {
     run!(
diff --git a/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_tuple_left.rs b/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_tuple_left.rs
index 700c090a4..eed1773eb 100644
--- a/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_tuple_left.rs
+++ b/native_implemented/otp/src/erlang/are_exactly_not_equal_2/test/with_tuple_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_tuple_right_returns_true() {
     run!(
@@ -9,7 +7,7 @@ fn without_tuple_right_returns_true() {
             (
                 strategy::term::tuple(arc_process.clone()),
                 strategy::term(arc_process.clone())
-                    .prop_filter("Right must not be tuple", |v| !v.is_boxed_tuple()),
+                    .prop_filter("Right must not be tuple", |v| !v.is_tuple()),
             )
         },
         |(left, right)| {
@@ -42,8 +40,8 @@ fn with_same_value_tuple_right_returns_false() {
                     let mut heap = arc_process.acquire_heap();
 
                     (
-                        heap.tuple_from_slice(&vec).unwrap(),
-                        heap.tuple_from_slice(&vec).unwrap(),
+                        heap.tuple_term_from_term_slice(&vec).unwrap(),
+                        heap.tuple_term_from_term_slice(&vec).unwrap(),
                     )
                 })
         },
diff --git a/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2.rs b/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2.rs
index 8f0642674..de01d38c0 100644
--- a/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2.rs
+++ b/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2.rs
@@ -1,7 +1,7 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::term::Term;
 
 /// `/=/2` infix operator.  Unlike `=/=`, converts between floats and integers.
 #[native_implemented::function(erlang:/=/2)]
diff --git a/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test.rs b/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test.rs
index 77798ddcb..71e387b42 100644
--- a/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test.rs
+++ b/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test.rs
@@ -13,7 +13,6 @@ mod with_small_integer_left;
 mod with_subbinary_left;
 mod with_tuple_left;
 
-use std::convert::TryInto;
 use std::ptr::NonNull;
 
 use proptest::arbitrary::any;
@@ -21,8 +20,7 @@ use proptest::prop_assert_eq;
 use proptest::strategy::Just;
 use proptest::test_runner::{Config, TestRunner};
 
-use liblumen_alloc::erts::process::alloc::TermAlloc;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::{Integer, Term};
 
 use crate::erlang::are_not_equal_after_conversion_2::result;
 use crate::test::strategy;
diff --git a/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_atom_left.rs b/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_atom_left.rs
index c4f4c55a6..9a397b292 100644
--- a/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_atom_left.rs
+++ b/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_atom_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_atom_returns_true() {
     run!(
diff --git a/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_big_integer_left.rs b/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_big_integer_left.rs
index f957bf61f..7b1e56437 100644
--- a/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_big_integer_left.rs
+++ b/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_big_integer_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_big_integer_or_float_returns_true() {
     run!(
@@ -10,7 +8,7 @@ fn without_big_integer_or_float_returns_true() {
                 strategy::term::integer::big(arc_process.clone()),
                 strategy::term(arc_process.clone())
                     .prop_filter("Right must not be a big integer or float", |v| {
-                        !(v.is_boxed_bigint() || v.is_boxed_float())
+                        !(v.is_boxed_bigint() || v.is_float())
                     }),
             )
         },
@@ -61,7 +59,7 @@ fn with_same_value_float_right_returns_false() {
             run!(
                 |arc_process| {
                     (Just(arc_process.clone()), strategy).prop_map(|(arc_process, i)| {
-                        (arc_process.integer(i), arc_process.float(i as f64))
+                        (arc_process.integer(i).unwrap(), (i as f64).into())
                     })
                 },
                 |(left, right)| {
@@ -82,7 +80,7 @@ fn with_different_value_float_right_returns_true() {
             run!(
                 |arc_process| {
                     (Just(arc_process.clone()), strategy).prop_map(|(arc_process, i)| {
-                        (arc_process.integer(i + 1), arc_process.float(i as f64))
+                        (arc_process.integer(i + 1).unwrap(), (i as f64).into())
                     })
                 },
                 |(left, right)| {
diff --git a/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_empty_list_left.rs b/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_empty_list_left.rs
index dfa4144a7..8960f5baa 100644
--- a/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_empty_list_left.rs
+++ b/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_empty_list_left.rs
@@ -1,13 +1,11 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_empty_list_returns_true() {
     run!(
         |arc_process| {
             (
-                Just(Term::NIL),
+                Just(Term::Nil),
                 strategy::term(arc_process.clone())
                     .prop_filter("Right must not be empty list", |v| !v.is_nil()),
             )
@@ -22,5 +20,5 @@ fn without_empty_list_returns_true() {
 
 #[test]
 fn with_empty_list_right_returns_false() {
-    assert_eq!(result(Term::NIL, Term::NIL), false.into());
+    assert_eq!(result(Term::Nil, Term::Nil), false.into());
 }
diff --git a/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_external_pid_left.rs b/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_external_pid_left.rs
index a1edd1dfe..5fe793884 100644
--- a/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_external_pid_left.rs
+++ b/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_external_pid_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_external_pid_left_returns_true() {
     run!(
diff --git a/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_float_left.rs b/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_float_left.rs
index c297f3d39..df50d6b8b 100644
--- a/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_float_left.rs
+++ b/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_float_left.rs
@@ -1,13 +1,11 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_small_integer_or_big_integer_or_float_returns_true() {
     run!(
         |arc_process| {
             (
-                strategy::term::float(arc_process.clone()),
+                strategy::term::float(),
                 strategy::term(arc_process.clone())
                     .prop_filter("Right must not be a number", |v| !v.is_number()),
             )
@@ -24,7 +22,7 @@ fn without_small_integer_or_big_integer_or_float_returns_true() {
 fn with_same_float_returns_false() {
     with_process_arc(|arc_process| {
         TestRunner::new(Config::with_source_file(file!()))
-            .run(&strategy::term::float(arc_process.clone()), |operand| {
+            .run(&strategy::term::float(), |operand| {
                 prop_assert_eq!(result(operand, operand), false.into());
 
                 Ok(())
@@ -38,7 +36,7 @@ fn with_same_value_float_right_returns_false() {
     run!(
         |arc_process| {
             (Just(arc_process.clone()), any::<f64>())
-                .prop_map(|(arc_process, f)| (arc_process.float(f), arc_process.float(f)))
+                .prop_map(|(arc_process, f)| (f.into(), f.into()))
         },
         |(left, right)| {
             prop_assert_eq!(result(left.into(), right.into()), false.into());
@@ -53,8 +51,8 @@ fn with_different_float_right_returns_true() {
     run!(
         |arc_process| {
             (
-                strategy::term::float(arc_process.clone()),
-                strategy::term::float(arc_process.clone()),
+                strategy::term::float(),
+                strategy::term::float(),
             )
                 .prop_filter("Right and left must be different", |(left, right)| {
                     left != right
@@ -76,7 +74,7 @@ fn with_same_value_small_integer_right_returns_false() {
                 Just(arc_process.clone()),
                 strategy::term::small_integer_float_integral_i64(),
             )
-                .prop_map(|(arc_process, i)| (arc_process.float(i as f64), arc_process.integer(i)))
+                .prop_map(|(arc_process, i)| ((i as f64).into(), arc_process.integer(i).unwrap()))
         },
         |(left, right)| {
             prop_assert_eq!(result(left.into(), right), false.into());
@@ -95,7 +93,7 @@ fn with_different_value_small_integer_right_returns_true() {
                 strategy::term::small_integer_float_integral_i64(),
             )
                 .prop_map(|(arc_process, i)| {
-                    (arc_process.float(i as f64), arc_process.integer(i + 1))
+                    ((i as f64).into(), arc_process.integer(i + 1).unwrap())
                 })
         },
         |(left, right)| {
@@ -113,7 +111,7 @@ fn with_same_value_big_integer_right_returns_false() {
             run!(
                 |arc_process| {
                     (Just(arc_process.clone()), strategy).prop_map(|(arc_process, i)| {
-                        (arc_process.float(i as f64), arc_process.integer(i))
+                        ((i as f64).into(), arc_process.integer(i).unwrap())
                     })
                 },
                 |(left, right)| {
@@ -134,7 +132,7 @@ fn with_different_value_big_integer_right_returns_true() {
             run!(
                 |arc_process| {
                     (Just(arc_process.clone()), strategy).prop_map(|(arc_process, i)| {
-                        (arc_process.float(i as f64), arc_process.integer(i + 1))
+                        ((i as f64).into(), arc_process.integer(i + 1).unwrap())
                     })
                 },
                 |(left, right)| {
diff --git a/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_function_left.rs b/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_function_left.rs
index 0a9f72018..60786ba2c 100644
--- a/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_function_left.rs
+++ b/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_function_left.rs
@@ -9,7 +9,7 @@ fn without_function_right_returns_true() {
             (
                 strategy::term::is_function(arc_process.clone()),
                 strategy::term(arc_process.clone())
-                    .prop_filter("Right must not be function", |v| !v.is_boxed_function()),
+                    .prop_filter("Right must not be function", |v| !v.is_closure()),
             )
         },
         |(left, right)| {
diff --git a/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_heap_binary_left.rs b/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_heap_binary_left.rs
index 2f41b53c7..32e83ca50 100644
--- a/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_heap_binary_left.rs
+++ b/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_heap_binary_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_binary_right_returns_true() {
     run!(
diff --git a/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_list_left.rs b/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_list_left.rs
index 171954b13..f408e0852 100644
--- a/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_list_left.rs
+++ b/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_list_left.rs
@@ -1,7 +1,6 @@
 use super::*;
 
 use proptest::collection::SizeRange;
-use proptest::strategy::Strategy;
 
 use crate::test::strategy::NON_EMPTY_RANGE_INCLUSIVE;
 
@@ -44,8 +43,8 @@ fn with_same_value_list_right_returns_false() {
             proptest::collection::vec(strategy::term(arc_process.clone()), size_range).prop_map(
                 move |vec| match vec.len() {
                     1 => (
-                        arc_process.list_from_slice(&vec),
-                        arc_process.list_from_slice(&vec),
+                        arc_process.list_from_slice(&vec).unwrap(),
+                        arc_process.list_from_slice(&vec).unwrap(),
                     ),
                     len => {
                         let last_index = len - 1;
diff --git a/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_map_left.rs b/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_map_left.rs
index 15dd3a4ef..e55d0ed94 100644
--- a/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_map_left.rs
+++ b/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_map_left.rs
@@ -9,7 +9,7 @@ fn without_map_right_returns_true() {
             (
                 strategy::term::map(arc_process.clone()),
                 strategy::term(arc_process.clone())
-                    .prop_filter("Right cannot be a map", |right| !right.is_boxed_map()),
+                    .prop_filter("Right cannot be a map", |right| !right.is_map()),
             )
         },
         |(left, right)| {
diff --git a/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_small_integer_left.rs b/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_small_integer_left.rs
index 235054bfd..c250e780f 100644
--- a/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_small_integer_left.rs
+++ b/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_small_integer_left.rs
@@ -10,7 +10,7 @@ fn without_small_integer_or_float_returns_true() {
                 strategy::term::integer::small(arc_process.clone()),
                 strategy::term(arc_process.clone())
                     .prop_filter("Right must not be a small integer or float", |v| {
-                        !(v.is_smallint() || v.is_boxed_float())
+                        !(v.is_smallint() || v.is_float())
                     }),
             )
         },
@@ -38,7 +38,7 @@ fn with_same_small_integer_right_returns_false() {
 fn with_same_value_small_integer_right_returns_false() {
     run!(
         |arc_process| {
-            (SmallInteger::MIN_VALUE..SmallInteger::MAX_VALUE).prop_map(move |i| {
+            (Integer::MIN_SMALL..Integer::MAX_SMALL).prop_map(move |i| {
                 let mut heap = arc_process.acquire_heap();
 
                 (heap.integer(i).unwrap(), heap.integer(i).unwrap())
@@ -56,7 +56,7 @@ fn with_same_value_small_integer_right_returns_false() {
 fn with_different_small_integer_right_returns_true() {
     run!(
         |arc_process| {
-            (SmallInteger::MIN_VALUE..SmallInteger::MAX_VALUE).prop_map(move |i| {
+            (Integer::MIN_SMALL..Integer::MAX_SMALL).prop_map(move |i| {
                 let mut heap = arc_process.acquire_heap();
 
                 (heap.integer(i).unwrap(), heap.integer(i + 1).unwrap())
@@ -77,7 +77,7 @@ fn with_same_value_float_right_returns_false() {
             strategy::term::small_integer_float_integral_i64().prop_map(move |i| {
                 let mut heap = arc_process.acquire_heap();
 
-                (heap.integer(i).unwrap(), heap.float(i as f64).unwrap())
+                (heap.integer(i).unwrap(), heap.into().unwrap())
             })
         },
         |(left, right)| {
@@ -100,7 +100,7 @@ fn with_different_value_float_right_returns_true() {
 
                 (
                     heap.integer(i).unwrap(),
-                    heap.float((i + diff) as f64).unwrap(),
+                    ((i + diff) as f64).into(),
                 )
             })
         },
diff --git a/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_tuple_left.rs b/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_tuple_left.rs
index 700c090a4..eed1773eb 100644
--- a/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_tuple_left.rs
+++ b/native_implemented/otp/src/erlang/are_not_equal_after_conversion_2/test/with_tuple_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_tuple_right_returns_true() {
     run!(
@@ -9,7 +7,7 @@ fn without_tuple_right_returns_true() {
             (
                 strategy::term::tuple(arc_process.clone()),
                 strategy::term(arc_process.clone())
-                    .prop_filter("Right must not be tuple", |v| !v.is_boxed_tuple()),
+                    .prop_filter("Right must not be tuple", |v| !v.is_tuple()),
             )
         },
         |(left, right)| {
@@ -42,8 +40,8 @@ fn with_same_value_tuple_right_returns_false() {
                     let mut heap = arc_process.acquire_heap();
 
                     (
-                        heap.tuple_from_slice(&vec).unwrap(),
-                        heap.tuple_from_slice(&vec).unwrap(),
+                        heap.tuple_term_from_term_slice(&vec).unwrap(),
+                        heap.tuple_term_from_term_slice(&vec).unwrap(),
                     )
                 })
         },
diff --git a/native_implemented/otp/src/erlang/atom_to_binary_2.rs b/native_implemented/otp/src/erlang/atom_to_binary_2.rs
index 4b674803a..b448efcf3 100644
--- a/native_implemented/otp/src/erlang/atom_to_binary_2.rs
+++ b/native_implemented/otp/src/erlang/atom_to_binary_2.rs
@@ -1,15 +1,19 @@
 use std::convert::TryInto;
+use std::ptr::NonNull;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::string::Encoding;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:atom_to_binary/2)]
-pub fn result(process: &Process, atom: Term, encoding: Term) -> exception::Result<Term> {
+pub fn result(
+    process: &Process,
+    atom: Term,
+    encoding: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     let atom_atom = term_try_into_atom!(atom)?;
     let _: Encoding = encoding.try_into()?;
-    let binary = process.binary_from_str(atom_atom.name());
+    let binary = process.binary_from_str(atom_atom.as_str());
 
     Ok(binary)
 }
diff --git a/native_implemented/otp/src/erlang/atom_to_list_1.rs b/native_implemented/otp/src/erlang/atom_to_list_1.rs
index 75f32ae26..fff62329b 100644
--- a/native_implemented/otp/src/erlang/atom_to_list_1.rs
+++ b/native_implemented/otp/src/erlang/atom_to_list_1.rs
@@ -1,11 +1,13 @@
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use std::ptr::NonNull;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:atom_to_list/1)]
-pub fn result(process: &Process, atom: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, atom: Term) -> Result<Term, NonNull<ErlangException>> {
     let atom_atom = term_try_into_atom!(atom)?;
-    let chars = atom_atom.name().chars();
+    let chars = atom_atom.as_str().chars();
     let list = process.list_from_chars(chars);
 
     Ok(list)
diff --git a/native_implemented/otp/src/erlang/band_2.rs b/native_implemented/otp/src/erlang/band_2.rs
index d26ff1d3a..1556f0ba2 100644
--- a/native_implemented/otp/src/erlang/band_2.rs
+++ b/native_implemented/otp/src/erlang/band_2.rs
@@ -1,6 +1,6 @@
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 /// `band/2` infix operator.
 #[native_implemented::function(erlang:band/2)]
@@ -8,6 +8,6 @@ pub fn result(
     process: &Process,
     left_integer: Term,
     right_integer: Term,
-) -> exception::Result<Term> {
+) -> Result<Term, NonNull<ErlangException>> {
     bitwise_infix_operator!(left_integer, right_integer, process, bitand)
 }
diff --git a/native_implemented/otp/src/erlang/binary_part_2.rs b/native_implemented/otp/src/erlang/binary_part_2.rs
index 7253cf46d..0c044caaa 100644
--- a/native_implemented/otp/src/erlang/binary_part_2.rs
+++ b/native_implemented/otp/src/erlang/binary_part_2.rs
@@ -1,13 +1,19 @@
+use std::ptr::NonNull;
+
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang;
 
 #[native_implemented::function(erlang:binary_part/2)]
-pub fn result(process: &Process, binary: Term, start_length: Term) -> exception::Result<Term> {
+pub fn result(
+    process: &Process,
+    binary: Term,
+    start_length: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     let start_length_tuple = term_try_into_tuple!(start_length)?;
 
     if start_length_tuple.len() == 2 {
diff --git a/native_implemented/otp/src/erlang/binary_part_3.rs b/native_implemented/otp/src/erlang/binary_part_3.rs
index 9e5bd905f..68739c35f 100644
--- a/native_implemented/otp/src/erlang/binary_part_3.rs
+++ b/native_implemented/otp/src/erlang/binary_part_3.rs
@@ -2,12 +2,13 @@
 mod test;
 
 use std::convert::TryInto;
+use std::ptr::NonNull;
 
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Term, TypeError};
 
 use crate::binary::{start_length_to_part_range, PartRange};
 use crate::runtime::context::*;
@@ -18,14 +19,14 @@ pub fn result(
     binary: Term,
     start: Term,
     length: Term,
-) -> exception::Result<Term> {
+) -> Result<Term, NonNull<ErlangException>> {
     let start_usize: usize = start
         .try_into()
         .with_context(|| term_is_not_non_negative_integer("start", start))?;
     let length_isize = term_try_into_isize!(length)?;
 
-    match binary.decode().unwrap() {
-        TypedTerm::HeapBinary(heap_binary) => {
+    match binary {
+        Term::HeapBinary(heap_binary) => {
             let available_byte_count = heap_binary.full_byte_len();
             let PartRange {
                 byte_offset,
@@ -40,7 +41,7 @@ pub fn result(
 
             Ok(binary_part)
         }
-        TypedTerm::ProcBin(process_binary) => {
+        Term::RcBinary(process_binary) => {
             let available_byte_count = process_binary.full_byte_len();
             let PartRange {
                 byte_offset,
@@ -55,7 +56,7 @@ pub fn result(
 
             Ok(binary_part)
         }
-        TypedTerm::SubBinary(subbinary) => {
+        Term::RefBinary(subbinary) => {
             let PartRange {
                 byte_offset,
                 byte_len,
diff --git a/native_implemented/otp/src/erlang/binary_part_3/test.rs b/native_implemented/otp/src/erlang/binary_part_3/test.rs
index cc15e5358..48d0cdb56 100644
--- a/native_implemented/otp/src/erlang/binary_part_3/test.rs
+++ b/native_implemented/otp/src/erlang/binary_part_3/test.rs
@@ -1,14 +1,13 @@
 mod with_bitstring;
 
-use std::convert::TryInto;
 use std::sync::Arc;
 
 use proptest::strategy::Just;
 use proptest::test_runner::TestCaseResult;
 use proptest::{prop_assert, prop_assert_eq};
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::binary_part_3::result;
 
diff --git a/native_implemented/otp/src/erlang/binary_part_3/test/with_bitstring.rs b/native_implemented/otp/src/erlang/binary_part_3/test/with_bitstring.rs
index f8c613703..af028006c 100644
--- a/native_implemented/otp/src/erlang/binary_part_3/test/with_bitstring.rs
+++ b/native_implemented/otp/src/erlang/binary_part_3/test/with_bitstring.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 mod with_bit_count;
 // `without_bit_count` in integration tests
 // `without_integer_start_without_integer_length_errors_badarg` in integration tests
diff --git a/native_implemented/otp/src/erlang/binary_part_3/test/with_bitstring/with_bit_count.rs b/native_implemented/otp/src/erlang/binary_part_3/test/with_bitstring/with_bit_count.rs
index 2aa5b3cae..68753e219 100644
--- a/native_implemented/otp/src/erlang/binary_part_3/test/with_bitstring/with_bit_count.rs
+++ b/native_implemented/otp/src/erlang/binary_part_3/test/with_bitstring/with_bit_count.rs
@@ -39,8 +39,8 @@ fn with_positive_start_and_positive_length_returns_subbinary() {
                     (
                         arc_process.clone(),
                         binary,
-                        arc_process.integer(start),
-                        arc_process.integer(length),
+                        arc_process.integer(start).unwrap(),
+                        arc_process.integer(length).unwrap(),
                     )
                 })
         },
@@ -69,8 +69,8 @@ fn with_byte_count_start_and_negative_byte_count_length_returns_subbinary_withou
                     (
                         arc_process.clone(),
                         binary,
-                        arc_process.integer(byte_count),
-                        arc_process.integer(-(byte_count as isize)),
+                        arc_process.integer(byte_count).unwrap(),
+                        arc_process.integer(-(byte_count as isize).unwrap()),
                     )
                 })
         },
diff --git a/native_implemented/otp/src/erlang/binary_to_atom_2.rs b/native_implemented/otp/src/erlang/binary_to_atom_2.rs
index f30b2635c..e4764cf97 100644
--- a/native_implemented/otp/src/erlang/binary_to_atom_2.rs
+++ b/native_implemented/otp/src/erlang/binary_to_atom_2.rs
@@ -1,10 +1,10 @@
 use std::convert::TryInto;
+use std::ptr::NonNull;
 
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::string::Encoding;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::{Atom, Term};
 
 use crate::runtime::context::*;
 
@@ -32,26 +32,23 @@ macro_rules! maybe_aligned_maybe_binary_to_atom {
 }
 
 #[native_implemented::function(erlang:binary_to_atom / 2)]
-pub fn result(binary: Term, encoding: Term) -> exception::Result<Term> {
+pub fn result(binary: Term, encoding: Term) -> Result<Term, NonNull<ErlangException>> {
     let _: Encoding = encoding.try_into()?;
 
-    match binary.decode()? {
-        TypedTerm::HeapBinary(heap_binary) => bytes_to_atom(binary, heap_binary.as_bytes()),
-        TypedTerm::ProcBin(process_binary) => bytes_to_atom(binary, process_binary.as_bytes()),
-        TypedTerm::BinaryLiteral(binary_literal) => {
+    match binary {
+        Term::HeapBinary(heap_binary) => bytes_to_atom(binary, heap_binary.as_bytes()),
+        Term::RcBinary(process_binary) => bytes_to_atom(binary, process_binary.as_bytes()),
+        Term::ConstantBinary(binary_literal) => {
             bytes_to_atom(binary, binary_literal.as_bytes())
         }
-        TypedTerm::SubBinary(subbinary) => maybe_aligned_maybe_binary_to_atom!(binary, subbinary),
-        TypedTerm::MatchContext(match_context) => {
-            maybe_aligned_maybe_binary_to_atom!(binary, match_context)
-        }
+        Term::RefBinary(subbinary) => maybe_aligned_maybe_binary_to_atom!(binary, subbinary),
         _ => Err(TypeError)
             .with_context(|| term_is_not_binary("binary", binary))
             .map_err(From::from),
     }
 }
 
-fn bytes_to_atom(binary: Term, bytes: &[u8]) -> exception::Result<Term> {
+fn bytes_to_atom(binary: Term, bytes: &[u8]) -> Result<Term, NonNull<ErlangException>> {
     Atom::try_from_latin1_bytes(bytes)
         .with_context(|| format!("binary ({}) could not be converted to atom", binary))?
         .encode()
diff --git a/native_implemented/otp/src/erlang/binary_to_atom_2/test.rs b/native_implemented/otp/src/erlang/binary_to_atom_2/test.rs
index f31adea66..dcb42233f 100644
--- a/native_implemented/otp/src/erlang/binary_to_atom_2/test.rs
+++ b/native_implemented/otp/src/erlang/binary_to_atom_2/test.rs
@@ -1,6 +1,6 @@
 use proptest::prop_assert_eq;
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 use crate::erlang::binary_to_atom_2::result;
 use crate::test::strategy;
@@ -30,11 +30,11 @@ fn with_utf8_binary_with_encoding_returns_atom_with_binary_name() {
             )
         },
         |(binary, encoding)| {
-            let byte_vec: Vec<u8> = match binary.decode().unwrap() {
-                TypedTerm::HeapBinary(heap_binary) => heap_binary.as_bytes().to_vec(),
-                TypedTerm::SubBinary(subbinary) => subbinary.full_byte_iter().collect(),
-                TypedTerm::ProcBin(process_binary) => process_binary.as_bytes().to_vec(),
-                TypedTerm::BinaryLiteral(process_binary) => process_binary.as_bytes().to_vec(),
+            let byte_vec: Vec<u8> = match binary {
+                Term::HeapBinary(heap_binary) => heap_binary.as_bytes().to_vec(),
+                Term::RefBinary(subbinary) => subbinary.full_byte_iter().collect(),
+                Term::RcBinary(process_binary) => process_binary.as_bytes().to_vec(),
+                Term::ConstantBinary(process_binary) => process_binary.as_bytes().to_vec(),
                 typed_term => panic!("typed_term = {:?}", typed_term),
             };
 
diff --git a/native_implemented/otp/src/erlang/binary_to_existing_atom_2.rs b/native_implemented/otp/src/erlang/binary_to_existing_atom_2.rs
index a4644be03..18628e1a4 100644
--- a/native_implemented/otp/src/erlang/binary_to_existing_atom_2.rs
+++ b/native_implemented/otp/src/erlang/binary_to_existing_atom_2.rs
@@ -2,12 +2,12 @@
 mod test;
 
 use std::convert::TryInto;
+use std::ptr::NonNull;
 
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::string::Encoding;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::{Atom, Term, TypeError};
 
 use crate::runtime::context::*;
 
@@ -32,30 +32,27 @@ macro_rules! maybe_aligned_maybe_binary_to_atom {
 }
 
 #[native_implemented::function(erlang:binary_to_existing_atom/2)]
-pub fn result(binary: Term, encoding: Term) -> exception::Result<Term> {
+pub fn result(binary: Term, encoding: Term) -> Result<Term, NonNull<ErlangException>> {
     let _: Encoding = encoding.try_into()?;
 
-    match binary.decode()? {
-        TypedTerm::HeapBinary(heap_binary) => {
+    match binary {
+        Term::HeapBinary(heap_binary) => {
             bytes_to_existing_atom(binary, heap_binary.as_bytes())
         }
-        TypedTerm::ProcBin(process_binary) => {
+        Term::RcBinary(process_binary) => {
             bytes_to_existing_atom(binary, process_binary.as_bytes())
         }
-        TypedTerm::BinaryLiteral(binary_literal) => {
+        Term::ConstantBinary(binary_literal) => {
             bytes_to_existing_atom(binary, binary_literal.as_bytes())
         }
-        TypedTerm::SubBinary(subbinary) => maybe_aligned_maybe_binary_to_atom!(binary, subbinary),
-        TypedTerm::MatchContext(match_context) => {
-            maybe_aligned_maybe_binary_to_atom!(binary, match_context)
-        }
+        Term::RefBinary(subbinary) => maybe_aligned_maybe_binary_to_atom!(binary, subbinary),
         _ => Err(TypeError)
             .with_context(|| term_is_not_binary("binary", binary))
             .map_err(From::from),
     }
 }
 
-fn bytes_to_existing_atom(binary: Term, bytes: &[u8]) -> exception::Result<Term> {
+fn bytes_to_existing_atom(binary: Term, bytes: &[u8]) -> Result<Term, NonNull<ErlangException>> {
     Atom::try_from_latin1_bytes_existing(bytes)
         .with_context(|| format!("binary ({}) could not be converted to atom", binary))?
         .encode()
diff --git a/native_implemented/otp/src/erlang/binary_to_existing_atom_2/test.rs b/native_implemented/otp/src/erlang/binary_to_existing_atom_2/test.rs
index 3f4934d42..75991eead 100644
--- a/native_implemented/otp/src/erlang/binary_to_existing_atom_2/test.rs
+++ b/native_implemented/otp/src/erlang/binary_to_existing_atom_2/test.rs
@@ -1,6 +1,6 @@
 use proptest::prop_assert_eq;
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 use crate::erlang::binary_to_existing_atom_2::result;
 use crate::test::strategy;
@@ -55,11 +55,11 @@ fn with_utf8_binary_with_valid_encoding_with_existing_atom_returns_atom() {
             )
         },
         |(binary, encoding)| {
-            let byte_vec: Vec<u8> = match binary.decode().unwrap() {
-                TypedTerm::HeapBinary(heap_binary) => heap_binary.as_bytes().to_vec(),
-                TypedTerm::ProcBin(process_binary) => process_binary.as_bytes().to_vec(),
-                TypedTerm::BinaryLiteral(process_binary) => process_binary.as_bytes().to_vec(),
-                TypedTerm::SubBinary(subbinary) => subbinary.full_byte_iter().collect(),
+            let byte_vec: Vec<u8> = match binary {
+                Term::HeapBinary(heap_binary) => heap_binary.as_bytes().to_vec(),
+                Term::RcBinary(process_binary) => process_binary.as_bytes().to_vec(),
+                Term::ConstantBinary(process_binary) => process_binary.as_bytes().to_vec(),
+                Term::RefBinary(subbinary) => subbinary.full_byte_iter().collect(),
                 typed_term => panic!("typed_term = {:?}", typed_term),
             };
 
diff --git a/native_implemented/otp/src/erlang/binary_to_float_1.rs b/native_implemented/otp/src/erlang/binary_to_float_1.rs
index ee0f4a88f..64e01f47c 100644
--- a/native_implemented/otp/src/erlang/binary_to_float_1.rs
+++ b/native_implemented/otp/src/erlang/binary_to_float_1.rs
@@ -1,15 +1,17 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use std::ptr::NonNull;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::string_to_float::string_to_float;
 use crate::runtime::binary_to_string::binary_to_string;
 
 #[native_implemented::function(erlang:binary_to_float/1)]
-pub fn result(process: &Process, binary: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, binary: Term) -> Result<Term, NonNull<ErlangException>> {
     let string = binary_to_string(binary)?;
 
     string_to_float(process, "binary", binary, &string).map_err(From::from)
diff --git a/native_implemented/otp/src/erlang/binary_to_float_1/test.rs b/native_implemented/otp/src/erlang/binary_to_float_1/test.rs
index 70d0820a0..cd84914c5 100644
--- a/native_implemented/otp/src/erlang/binary_to_float_1/test.rs
+++ b/native_implemented/otp/src/erlang/binary_to_float_1/test.rs
@@ -1,6 +1,6 @@
 use proptest::arbitrary::any;
 use proptest::prop_assert_eq;
-use proptest::strategy::{Just, Strategy};
+use proptest::strategy::Just;
 
 use crate::erlang::binary_to_float_1::result;
 use crate::test::strategy;
@@ -50,7 +50,7 @@ fn with_binary_with_f64_returns_floats() {
             })
         },
         |(arc_process, f, binary)| {
-            prop_assert_eq!(result(&arc_process, binary), Ok(arc_process.float(f)));
+            prop_assert_eq!(result(&arc_process, binary), Ok(f.into()));
 
             Ok(())
         },
diff --git a/native_implemented/otp/src/erlang/binary_to_integer_1.rs b/native_implemented/otp/src/erlang/binary_to_integer_1.rs
index af66ddc99..6ea580281 100644
--- a/native_implemented/otp/src/erlang/binary_to_integer_1.rs
+++ b/native_implemented/otp/src/erlang/binary_to_integer_1.rs
@@ -1,15 +1,16 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use std::ptr::NonNull;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::string_to_integer::decimal_string_to_integer;
 use crate::runtime::binary_to_string::binary_to_string;
 
 #[native_implemented::function(erlang:binary_to_integer/1)]
-pub fn result(process: &Process, binary: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, binary: Term) -> Result<Term, NonNull<ErlangException>> {
     let string: String = binary_to_string(binary)?;
 
     decimal_string_to_integer(process, "binary", binary, &string).map_err(From::from)
diff --git a/native_implemented/otp/src/erlang/binary_to_integer_2.rs b/native_implemented/otp/src/erlang/binary_to_integer_2.rs
index 272964b46..bd7e6af67 100644
--- a/native_implemented/otp/src/erlang/binary_to_integer_2.rs
+++ b/native_implemented/otp/src/erlang/binary_to_integer_2.rs
@@ -1,15 +1,19 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::string_to_integer::base_string_to_integer;
 use crate::runtime::binary_to_string::binary_to_string;
 
 #[native_implemented::function(erlang:binary_to_integer/2)]
-pub fn result(process: &Process, binary: Term, base: Term) -> exception::Result<Term> {
+pub fn result(
+    process: &Process,
+    binary: Term,
+    base: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     let string: String = binary_to_string(binary)?;
 
     base_string_to_integer(process, base, "binary", binary, &string).map_err(From::from)
diff --git a/native_implemented/otp/src/erlang/binary_to_integer_2/test.rs b/native_implemented/otp/src/erlang/binary_to_integer_2/test.rs
index 235157456..3c4db4f81 100644
--- a/native_implemented/otp/src/erlang/binary_to_integer_2/test.rs
+++ b/native_implemented/otp/src/erlang/binary_to_integer_2/test.rs
@@ -1,4 +1,6 @@
-use proptest::strategy::{Just, Strategy};
+use proptest::strategy::Just;
+
+use firefly_rt::term::Term;
 
 use crate::erlang::binary_to_integer_2::result;
 use crate::test::strategy;
@@ -62,7 +64,7 @@ fn with_binary_without_integer_in_base_errors_badarg() {
                     (
                         Just(arc_process.clone()),
                         strategy::term::binary::containing_bytes(byte_vec, arc_process.clone()),
-                        Just(arc_process.integer(base)),
+                        Just(arc_process.integer(base).unwrap()),
                     )
                 },
             )
diff --git a/native_implemented/otp/src/erlang/binary_to_list_1.rs b/native_implemented/otp/src/erlang/binary_to_list_1.rs
index 7ff85863c..0cc36d08e 100644
--- a/native_implemented/otp/src/erlang/binary_to_list_1.rs
+++ b/native_implemented/otp/src/erlang/binary_to_list_1.rs
@@ -3,12 +3,12 @@ mod test;
 
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:binary_to_list/1)]
-pub fn result(process: &Process, binary: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, binary: Term) -> Result<Term, NonNull<ErlangException>> {
     let bytes = process
         .bytes_from_binary(binary)
         .with_context(|| format!("binary ({})", binary))?;
diff --git a/native_implemented/otp/src/erlang/binary_to_list_3.rs b/native_implemented/otp/src/erlang/binary_to_list_3.rs
index 746b23fcd..1f692ea74 100644
--- a/native_implemented/otp/src/erlang/binary_to_list_3.rs
+++ b/native_implemented/otp/src/erlang/binary_to_list_3.rs
@@ -2,12 +2,15 @@
 mod test;
 
 use std::convert::TryInto;
+use std::ptr::NonNull;
 
 use anyhow::*;
 
-use liblumen_alloc::erts::exception::{self, InternalResult};
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::{Term, TryIntoIntegerError};
+use firefly_number::TryIntoIntegerError;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::binary;
 
@@ -15,7 +18,12 @@ use crate::binary;
 /// [crate::binary::bin_to_list] instead. All functions in module [crate::binary]
 /// consistently use zero-based indexing.
 #[native_implemented::function(erlang:binary_to_list/3)]
-pub fn result(process: &Process, binary: Term, start: Term, stop: Term) -> exception::Result<Term> {
+pub fn result(
+    process: &Process,
+    binary: Term,
+    start: Term,
+    stop: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     let one_based_start_usize: usize = try_into_one_based("start", start)?;
     let one_based_stop_usize: usize = try_into_one_based("stop", stop)?;
 
@@ -28,7 +36,7 @@ pub fn result(process: &Process, binary: Term, start: Term, stop: Term) -> excep
         binary::bin_to_list(
             binary,
             process.integer(zero_based_start_usize),
-            process.integer(length_usize),
+            process.integer(length_usize).unwrap(),
             process,
         )
     } else {
diff --git a/native_implemented/otp/src/erlang/binary_to_list_3/test.rs b/native_implemented/otp/src/erlang/binary_to_list_3/test.rs
index 995d729d6..3203b6097 100644
--- a/native_implemented/otp/src/erlang/binary_to_list_3/test.rs
+++ b/native_implemented/otp/src/erlang/binary_to_list_3/test.rs
@@ -1,6 +1,6 @@
-use proptest::strategy::{Just, Strategy};
+use proptest::strategy::Just;
 
-use liblumen_alloc::erts::process::alloc::TermAlloc;
+use firefly_rt::term::Term;
 
 use crate::erlang::binary_to_list_3::result;
 use crate::test::strategy;
@@ -15,8 +15,8 @@ fn without_binary_errors_badarg() {
             )
         },
         |(arc_process, binary)| {
-            let start = arc_process.integer(1);
-            let stop = arc_process.integer(1);
+            let start = arc_process.integer(1).unwrap();
+            let stop = arc_process.integer(1).unwrap();
 
             prop_assert_badarg!(
                 result(&arc_process, binary, start, stop),
@@ -39,7 +39,7 @@ fn with_binary_without_integer_start_errors_badarg() {
             )
         },
         |(arc_process, binary, start)| {
-            let stop = arc_process.integer(1);
+            let stop = arc_process.integer(1).unwrap();
 
             prop_assert_badarg!(
                         result(&arc_process, binary, start, stop),
diff --git a/native_implemented/otp/src/erlang/binary_to_term_1.rs b/native_implemented/otp/src/erlang/binary_to_term_1.rs
index 74fee5d6c..7a32a6b97 100644
--- a/native_implemented/otp/src/erlang/binary_to_term_1.rs
+++ b/native_implemented/otp/src/erlang/binary_to_term_1.rs
@@ -1,13 +1,13 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::binary_to_term_2;
 
 #[native_implemented::function(erlang:binary_to_term/1)]
-pub fn result(process: &Process, binary: Term) -> exception::Result<Term> {
-    binary_to_term_2::result(process, binary, Term::NIL)
+pub fn result(process: &Process, binary: Term) -> Result<Term, NonNull<ErlangException>> {
+    binary_to_term_2::result(process, binary, Term::Nil)
 }
diff --git a/native_implemented/otp/src/erlang/binary_to_term_2.rs b/native_implemented/otp/src/erlang/binary_to_term_2.rs
index af06de6bd..1942b4b99 100644
--- a/native_implemented/otp/src/erlang/binary_to_term_2.rs
+++ b/native_implemented/otp/src/erlang/binary_to_term_2.rs
@@ -2,13 +2,15 @@
 mod test;
 
 use std::convert::TryInto;
+use std::ptr::NonNull;
 use std::u8;
 
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::*;
+use firefly_rt::term::{Term, TypeError};
 
 use crate::binary::to_term::Options;
 use crate::runtime::distribution::external_term_format::{term, version};
@@ -36,20 +38,21 @@ macro_rules! maybe_aligned_maybe_binary_try_into_term {
 }
 
 #[native_implemented::function(erlang:binary_to_term/2)]
-pub fn result(process: &Process, binary: Term, options: Term) -> exception::Result<Term> {
+pub fn result(
+    process: &Process,
+    binary: Term,
+    options: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     let options: Options = options.try_into()?;
 
-    match binary.decode()? {
-        TypedTerm::HeapBinary(heap_binary) => {
+    match binary {
+        Term::HeapBinary(heap_binary) => {
             versioned_tagged_bytes_try_into_term(process, &options, heap_binary.as_bytes())
         }
-        TypedTerm::MatchContext(match_context) => {
-            maybe_aligned_maybe_binary_try_into_term!(process, &options, binary, match_context)
-        }
-        TypedTerm::ProcBin(process_binary) => {
+        Term::RcBinary(process_binary) => {
             versioned_tagged_bytes_try_into_term(process, &options, process_binary.as_bytes())
         }
-        TypedTerm::SubBinary(subbinary) => {
+        Term::RefBinary(subbinary) => {
             maybe_aligned_maybe_binary_try_into_term!(process, &options, binary, subbinary)
         }
         _ => Err(TypeError)
@@ -62,16 +65,16 @@ fn versioned_tagged_bytes_try_into_term(
     process: &Process,
     options: &Options,
     bytes: &[u8],
-) -> exception::Result<Term> {
+) -> Result<Term, NonNull<ErlangException>> {
     let after_version_bytes = version::check(bytes)?;
     let (term, after_term_bytes) =
         term::decode_tagged(process, options.existing, after_version_bytes)?;
 
     let final_term = if options.used {
         let used_byte_len = bytes.len() - after_term_bytes.len();
-        let used = process.integer(used_byte_len);
+        let used = process.integer(used_byte_len).unwrap();
 
-        process.tuple_from_slice(&[term, used])
+        process.tuple_term_from_term_slice(&[term, used])
     } else {
         term
     };
diff --git a/native_implemented/otp/src/erlang/binary_to_term_2/test.rs b/native_implemented/otp/src/erlang/binary_to_term_2/test.rs
index 9416e07ca..68cf69fe3 100644
--- a/native_implemented/otp/src/erlang/binary_to_term_2/test.rs
+++ b/native_implemented/otp/src/erlang/binary_to_term_2/test.rs
@@ -2,8 +2,8 @@ mod with_safe;
 
 use proptest::strategy::Just;
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::{Atom, Term};
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::binary_to_term_2::result;
 use crate::test::strategy;
diff --git a/native_implemented/otp/src/erlang/binary_to_term_2/test/with_safe.rs b/native_implemented/otp/src/erlang/binary_to_term_2/test/with_safe.rs
index a453f9646..698805895 100644
--- a/native_implemented/otp/src/erlang/binary_to_term_2/test/with_safe.rs
+++ b/native_implemented/otp/src/erlang/binary_to_term_2/test/with_safe.rs
@@ -35,7 +35,7 @@ fn with_binary_encoding_small_atom_utf8_that_does_not_exist_errors_badarg() {
 }
 
 fn options(process: &Process) -> Term {
-    process.cons(Atom::str_to_term("safe"), Term::NIL)
+    process.cons(Atom::str_to_term("safe"), Term::Nil)
 }
 
 fn tried_to_convert_to_an_atom_that_doesnt_exist(byte_vec: Vec<u8>) {
diff --git a/native_implemented/otp/src/erlang/bit_size_1.rs b/native_implemented/otp/src/erlang/bit_size_1.rs
index 3401b3b98..18eb5ee06 100644
--- a/native_implemented/otp/src/erlang/bit_size_1.rs
+++ b/native_implemented/otp/src/erlang/bit_size_1.rs
@@ -1,25 +1,26 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
+use std::ptr::NonNull;
+
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Term, TypeError};
 
 #[native_implemented::function(erlang:bit_size/1)]
-pub fn result(process: &Process, bitstring: Term) -> exception::Result<Term> {
-    let option_total_bit_len = match bitstring.decode()? {
-        TypedTerm::BinaryLiteral(binary_literal) => Some(binary_literal.total_bit_len()),
-        TypedTerm::HeapBinary(heap_binary) => Some(heap_binary.total_bit_len()),
-        TypedTerm::ProcBin(process_binary) => Some(process_binary.total_bit_len()),
-        TypedTerm::SubBinary(subbinary) => Some(subbinary.total_bit_len()),
-        TypedTerm::MatchContext(match_context) => Some(match_context.total_bit_len()),
+pub fn result(process: &Process, bitstring: Term) -> Result<Term, NonNull<ErlangException>> {
+    let option_total_bit_len = match bitstring {
+        Term::ConstantBinary(binary_literal) => Some(binary_literal.total_bit_len()),
+        Term::HeapBinary(heap_binary) => Some(heap_binary.total_bit_len()),
+        Term::RcBinary(process_binary) => Some(process_binary.total_bit_len()),
+        Term::RefBinary(subbinary) => Some(subbinary.total_bit_len()),
         _ => None,
     };
 
     match option_total_bit_len {
-        Some(total_bit_len) => Ok(process.integer(total_bit_len)),
+        Some(total_bit_len) => Ok(process.integer(total_bit_len).unwrap()),
         None => Err(TypeError)
             .context(format!("bitstring ({}) is not a bitstring", bitstring))
             .map_err(From::from),
diff --git a/native_implemented/otp/src/erlang/bit_size_1/test.rs b/native_implemented/otp/src/erlang/bit_size_1/test.rs
index 2c6355b29..e93bd0ad3 100644
--- a/native_implemented/otp/src/erlang/bit_size_1/test.rs
+++ b/native_implemented/otp/src/erlang/bit_size_1/test.rs
@@ -1,10 +1,6 @@
-use std::convert::TryInto;
-
 use proptest::strategy::Just;
 use proptest::{prop_assert, prop_assert_eq};
 
-use liblumen_alloc::erts::term::prelude::*;
-
 use crate::erlang::bit_size_1::result;
 use crate::test::strategy;
 
diff --git a/native_implemented/otp/src/erlang/bitstring_to_list_1.rs b/native_implemented/otp/src/erlang/bitstring_to_list_1.rs
index 8a6522d5f..1d8342ec9 100644
--- a/native_implemented/otp/src/erlang/bitstring_to_list_1.rs
+++ b/native_implemented/otp/src/erlang/bitstring_to_list_1.rs
@@ -1,33 +1,35 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
+use std::ptr::NonNull;
+
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Term, TypeError};
 
 /// Returns a list of integers corresponding to the bytes of `bitstring`. If the number of bits in
 /// `bitstring` is not divisible by `8`, the last element of the list is a `bitstring` containing
 /// the remaining `1`-`7` bits.
 #[native_implemented::function(erlang:bitstring_to_list/1)]
-pub fn result(process: &Process, bitstring: Term) -> exception::Result<Term> {
-    match bitstring.decode().unwrap() {
-        TypedTerm::HeapBinary(heap_binary) => {
+pub fn result(process: &Process, bitstring: Term) -> Result<Term, NonNull<ErlangException>> {
+    match bitstring {
+        Term::HeapBinary(heap_binary) => {
             let byte_term_iter = heap_binary.as_bytes().iter().map(|byte| (*byte).into());
-            let last = Term::NIL;
+            let last = Term::Nil;
 
-            Ok(process.improper_list_from_iter(byte_term_iter, last))
+            Ok(process.improper_list_from_iter(byte_term_iter, last).unwrap())
         }
-        TypedTerm::ProcBin(process_binary) => {
+        Term::RcBinary(process_binary) => {
             let byte_term_iter = process_binary.as_bytes().iter().map(|byte| (*byte).into());
-            let last = Term::NIL;
+            let last = Term::Nil;
 
-            Ok(process.improper_list_from_iter(byte_term_iter, last))
+            Ok(process.improper_list_from_iter(byte_term_iter, last).unwrap())
         }
-        TypedTerm::SubBinary(subbinary) => {
+        Term::RefBinary(subbinary) => {
             let last = if subbinary.is_binary() {
-                Term::NIL
+                Term::Nil
             } else {
                 let partial_byte_subbinary = process.subbinary_from_original(
                     subbinary.original(),
@@ -37,13 +39,13 @@ pub fn result(process: &Process, bitstring: Term) -> exception::Result<Term> {
                     subbinary.partial_byte_bit_len(),
                 );
 
-                process.cons(partial_byte_subbinary, Term::NIL)
+                process.cons(partial_byte_subbinary, Term::Nil)
             };
 
             let byte_term_vec: Vec<Term> =
                 subbinary.full_byte_iter().map(|byte| byte.into()).collect();
 
-            Ok(process.improper_list_from_slice(&byte_term_vec, last))
+            Ok(process.improper_list_from_slice(&byte_term_vec, last).unwrap())
         }
         _ => Err(TypeError)
             .context(format!("bitstring ({}) is not a bitstring", bitstring))
diff --git a/native_implemented/otp/src/erlang/bitstring_to_list_1/test.rs b/native_implemented/otp/src/erlang/bitstring_to_list_1/test.rs
index 3e54cd0ba..98932e734 100644
--- a/native_implemented/otp/src/erlang/bitstring_to_list_1/test.rs
+++ b/native_implemented/otp/src/erlang/bitstring_to_list_1/test.rs
@@ -1,10 +1,8 @@
-use std::convert::TryInto;
-
 use proptest::prop_assert_eq;
-use proptest::strategy::{Just, Strategy};
+use proptest::strategy::Just;
 use proptest::test_runner::{Config, TestRunner};
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 use crate::erlang::bitstring_to_list_1::result;
 use crate::test::strategy;
@@ -24,17 +22,17 @@ fn with_heap_binary_returns_list_of_integer() {
                     // not using an iterator because that would too closely match the code under
                     // test
                     match byte_vec.len() {
-                        0 => Term::NIL,
-                        1 => arc_process.cons(arc_process.integer(byte_vec[0]), Term::NIL),
+                        0 => Term::Nil,
+                        1 => arc_process.cons(arc_process.integer(byte_vec[0]).unwrap(), Term::Nil),
                         2 => arc_process.cons(
-                            arc_process.integer(byte_vec[0]),
-                            arc_process.cons(arc_process.integer(byte_vec[1]), Term::NIL),
+                            arc_process.integer(byte_vec[0]).unwrap(),
+                            arc_process.cons(arc_process.integer(byte_vec[1]).unwrap(), Term::Nil),
                         ),
                         3 => arc_process.cons(
-                            arc_process.integer(byte_vec[0]),
+                            arc_process.integer(byte_vec[0]).unwrap(),
                             arc_process.cons(
-                                arc_process.integer(byte_vec[1]),
-                                arc_process.cons(arc_process.integer(byte_vec[2]), Term::NIL),
+                                arc_process.integer(byte_vec[1]).unwrap(),
+                                arc_process.cons(arc_process.integer(byte_vec[2]).unwrap(), Term::Nil),
                             ),
                         ),
                         len => unimplemented!("len = {:?}", len),
@@ -69,17 +67,17 @@ fn with_subbinary_without_bit_count_returns_list_of_integer() {
                     // not using an iterator because that would too closely match the code under
                     // test
                     let list = match byte_vec.len() {
-                        0 => Term::NIL,
-                        1 => arc_process.cons(arc_process.integer(byte_vec[0]), Term::NIL),
+                        0 => Term::Nil,
+                        1 => arc_process.cons(arc_process.integer(byte_vec[0]).unwrap(), Term::Nil),
                         2 => arc_process.cons(
-                            arc_process.integer(byte_vec[0]),
-                            arc_process.cons(arc_process.integer(byte_vec[1]), Term::NIL),
+                            arc_process.integer(byte_vec[0]).unwrap(),
+                            arc_process.cons(arc_process.integer(byte_vec[1]).unwrap(), Term::Nil),
                         ),
                         3 => arc_process.cons(
-                            arc_process.integer(byte_vec[0]),
+                            arc_process.integer(byte_vec[0]).unwrap(),
                             arc_process.cons(
-                                arc_process.integer(byte_vec[1]),
-                                arc_process.cons(arc_process.integer(byte_vec[2]), Term::NIL),
+                                arc_process.integer(byte_vec[1]).unwrap(),
+                                arc_process.cons(arc_process.integer(byte_vec[2]).unwrap(), Term::Nil),
                             ),
                         ),
                         len => unimplemented!("len = {:?}", len),
@@ -127,25 +125,25 @@ fn with_subbinary_with_bit_count_returns_list_of_integer_with_bitstring_for_bit_
             // not using an iterator because that would too closely match the code under
             // test
             let list = match byte_vec.len() {
-                0 => arc_process.cons(bits_subbinary, Term::NIL),
+                0 => arc_process.cons(bits_subbinary, Term::Nil),
                 1 => arc_process.cons(
-                    arc_process.integer(byte_vec[0]),
-                    arc_process.cons(bits_subbinary, Term::NIL),
+                    arc_process.integer(byte_vec[0]).unwrap(),
+                    arc_process.cons(bits_subbinary, Term::Nil),
                 ),
                 2 => arc_process.cons(
-                    arc_process.integer(byte_vec[0]),
+                    arc_process.integer(byte_vec[0]).unwrap(),
                     arc_process.cons(
-                        arc_process.integer(byte_vec[1]),
-                        arc_process.cons(bits_subbinary, Term::NIL),
+                        arc_process.integer(byte_vec[1]).unwrap(),
+                        arc_process.cons(bits_subbinary, Term::Nil),
                     ),
                 ),
                 3 => arc_process.cons(
-                    arc_process.integer(byte_vec[0]),
+                    arc_process.integer(byte_vec[0]).unwrap(),
                     arc_process.cons(
-                        arc_process.integer(byte_vec[1]),
+                        arc_process.integer(byte_vec[1]).unwrap(),
                         arc_process.cons(
-                            arc_process.integer(byte_vec[2]),
-                            arc_process.cons(bits_subbinary, Term::NIL),
+                            arc_process.integer(byte_vec[2]).unwrap(),
+                            arc_process.cons(bits_subbinary, Term::Nil),
                         ),
                     ),
                 ),
diff --git a/native_implemented/otp/src/erlang/bnot_1.rs b/native_implemented/otp/src/erlang/bnot_1.rs
index f51a525b9..4b046dc70 100644
--- a/native_implemented/otp/src/erlang/bnot_1.rs
+++ b/native_implemented/otp/src/erlang/bnot_1.rs
@@ -1,26 +1,28 @@
+use std::ptr::NonNull;
+
 use anyhow::*;
 use num_bigint::BigInt;
+use firefly_rt::backtrace::Trace;
 
-use liblumen_alloc::erts::exception::{self, *};
-use liblumen_alloc::erts::process::trace::Trace;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::Term;
 
 /// `bnot/1` prefix operator.
 #[native_implemented::function(erlang:bnot/1)]
-pub fn result(process: &Process, integer: Term) -> exception::Result<Term> {
-    match integer.decode().unwrap() {
-        TypedTerm::SmallInteger(small_integer) => {
+pub fn result(process: &Process, integer: Term) -> Result<Term, NonNull<ErlangException>> {
+    match integer {
+        Term::Int(small_integer) => {
             let integer_isize: isize = small_integer.into();
             let output = !integer_isize;
-            let output_term = process.integer(output);
+            let output_term = process.integer(output).unwrap();
 
             Ok(output_term)
         }
-        TypedTerm::BigInteger(big_integer) => {
+        Term::BigInt(big_integer) => {
             let big_int: &BigInt = big_integer.as_ref().into();
             let output_big_int = !big_int;
-            let output_term = process.integer(output_big_int);
+            let output_term = process.integer(output_big_int).unwrap();
 
             Ok(output_term)
         }
diff --git a/native_implemented/otp/src/erlang/bor_2.rs b/native_implemented/otp/src/erlang/bor_2.rs
index becf14dbb..6876e1ff4 100644
--- a/native_implemented/otp/src/erlang/bor_2.rs
+++ b/native_implemented/otp/src/erlang/bor_2.rs
@@ -1,6 +1,6 @@
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 /// `bor/2` infix operator.
 #[native_implemented::function(erlang:bor/2)]
@@ -8,6 +8,6 @@ pub fn result(
     process: &Process,
     left_integer: Term,
     right_integer: Term,
-) -> exception::Result<Term> {
+) -> Result<Term, NonNull<ErlangException>> {
     bitwise_infix_operator!(left_integer, right_integer, process, bitor)
 }
diff --git a/native_implemented/otp/src/erlang/bsl_2.rs b/native_implemented/otp/src/erlang/bsl_2.rs
index 2fd7d4c42..7d27b344f 100644
--- a/native_implemented/otp/src/erlang/bsl_2.rs
+++ b/native_implemented/otp/src/erlang/bsl_2.rs
@@ -1,9 +1,13 @@
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 /// `bsl/2` infix operator.
 #[native_implemented::function(erlang:bsl/2)]
-pub fn result(process: &Process, integer: Term, shift: Term) -> exception::Result<Term> {
+pub fn result(
+    process: &Process,
+    integer: Term,
+    shift: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     bitshift_infix_operator!(integer, shift, process, <<, >>)
 }
diff --git a/native_implemented/otp/src/erlang/bsr_2.rs b/native_implemented/otp/src/erlang/bsr_2.rs
index f956445e2..6c82f986b 100644
--- a/native_implemented/otp/src/erlang/bsr_2.rs
+++ b/native_implemented/otp/src/erlang/bsr_2.rs
@@ -1,9 +1,13 @@
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 /// `bsr/2` infix operator.
 #[native_implemented::function(erlang:bsr/2)]
-pub fn result(process: &Process, integer: Term, shift: Term) -> exception::Result<Term> {
+pub fn result(
+    process: &Process,
+    integer: Term,
+    shift: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     bitshift_infix_operator!(integer, shift, process, >>, <<)
 }
diff --git a/native_implemented/otp/src/erlang/bxor_2.rs b/native_implemented/otp/src/erlang/bxor_2.rs
index 67f629e17..6b13600e8 100644
--- a/native_implemented/otp/src/erlang/bxor_2.rs
+++ b/native_implemented/otp/src/erlang/bxor_2.rs
@@ -1,6 +1,6 @@
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 /// `bxor/2` infix operator.
 #[native_implemented::function(erlang:bxor/2)]
@@ -8,6 +8,6 @@ pub fn result(
     process: &Process,
     left_integer: Term,
     right_integer: Term,
-) -> exception::Result<Term> {
+) -> Result<Term, NonNull<ErlangException>> {
     bitwise_infix_operator!(left_integer, right_integer, process, bitxor)
 }
diff --git a/native_implemented/otp/src/erlang/byte_size_1.rs b/native_implemented/otp/src/erlang/byte_size_1.rs
index 3d6d09987..1fba1280c 100644
--- a/native_implemented/otp/src/erlang/byte_size_1.rs
+++ b/native_implemented/otp/src/erlang/byte_size_1.rs
@@ -1,23 +1,25 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
+use std::ptr::NonNull;
+
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Term, TypeError};
 
 #[native_implemented::function(erlang:byte_size/1)]
-pub fn result(process: &Process, bitstring: Term) -> exception::Result<Term> {
-    let option_total_byte_len = match bitstring.decode().unwrap() {
-        TypedTerm::HeapBinary(heap_binary) => Some(heap_binary.total_byte_len()),
-        TypedTerm::ProcBin(process_binary) => Some(process_binary.total_byte_len()),
-        TypedTerm::SubBinary(subbinary) => Some(subbinary.total_byte_len()),
+pub fn result(process: &Process, bitstring: Term) -> Result<Term, NonNull<ErlangException>> {
+    let option_total_byte_len = match bitstring {
+        Term::HeapBinary(heap_binary) => Some(heap_binary.total_byte_len()),
+        Term::RcBinary(process_binary) => Some(process_binary.total_byte_len()),
+        Term::RefBinary(subbinary) => Some(subbinary.total_byte_len()),
         _ => None,
     };
 
     match option_total_byte_len {
-        Some(total_byte_len) => Ok(process.integer(total_byte_len)),
+        Some(total_byte_len) => Ok(process.integer(total_byte_len).unwrap()),
         None => Err(TypeError)
             .context(format!("bitstring ({}) is not a bitstring", bitstring))
             .map_err(From::from),
diff --git a/native_implemented/otp/src/erlang/byte_size_1/test.rs b/native_implemented/otp/src/erlang/byte_size_1/test.rs
index 8ef9fe987..6e33fd380 100644
--- a/native_implemented/otp/src/erlang/byte_size_1/test.rs
+++ b/native_implemented/otp/src/erlang/byte_size_1/test.rs
@@ -1,5 +1,7 @@
 use proptest::prop_assert_eq;
-use proptest::strategy::{Just, Strategy};
+use proptest::strategy::Just;
+
+use firefly_rt::term::Term;
 
 use crate::erlang::byte_size_1::result;
 use crate::test::strategy;
@@ -24,7 +26,7 @@ fn with_heap_binary_is_byte_count() {
         |(arc_process, byte_count, bitstring)| {
             prop_assert_eq!(
                 result(&arc_process, bitstring),
-                Ok(arc_process.integer(byte_count))
+                Ok(arc_process.integer(byte_count).unwrap())
             );
 
             Ok(())
@@ -52,7 +54,7 @@ fn with_subbinary_without_bit_count_is_byte_count() {
         |(arc_process, byte_count, bitstring)| {
             prop_assert_eq!(
                 result(&arc_process, bitstring),
-                Ok(arc_process.integer(byte_count))
+                Ok(arc_process.integer(byte_count).unwrap())
             );
 
             Ok(())
@@ -85,7 +87,7 @@ fn with_subbinary_with_bit_count_is_byte_count_plus_one() {
         |(arc_process, byte_count, bitstring)| {
             prop_assert_eq!(
                 result(&arc_process, bitstring),
-                Ok(arc_process.integer(byte_count + 1))
+                Ok(arc_process.integer(byte_count + 1).unwrap())
             );
 
             Ok(())
diff --git a/native_implemented/otp/src/erlang/cancel_timer_1.rs b/native_implemented/otp/src/erlang/cancel_timer_1.rs
index 2967c2311..2fdd34d5c 100644
--- a/native_implemented/otp/src/erlang/cancel_timer_1.rs
+++ b/native_implemented/otp/src/erlang/cancel_timer_1.rs
@@ -1,10 +1,10 @@
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::cancel_timer;
 
 #[native_implemented::function(erlang:cancel_timer/1)]
-pub fn result(process: &Process, timer_reference: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, timer_reference: Term) -> Result<Term, NonNull<ErlangException>> {
     cancel_timer(timer_reference, Default::default(), process).map_err(From::from)
 }
diff --git a/native_implemented/otp/src/erlang/cancel_timer_2.rs b/native_implemented/otp/src/erlang/cancel_timer_2.rs
index e14dee71c..31f3f82e8 100644
--- a/native_implemented/otp/src/erlang/cancel_timer_2.rs
+++ b/native_implemented/otp/src/erlang/cancel_timer_2.rs
@@ -1,14 +1,18 @@
 use std::convert::TryInto;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::cancel_timer;
 use crate::timer;
 
 #[native_implemented::function(erlang:cancel_timer/2)]
-pub fn result(process: &Process, timer_reference: Term, options: Term) -> exception::Result<Term> {
+pub fn result(
+    process: &Process,
+    timer_reference: Term,
+    options: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     let cancel_timer_options: timer::cancel::Options = options.try_into()?;
 
     cancel_timer(timer_reference, cancel_timer_options, process).map_err(From::from)
diff --git a/native_implemented/otp/src/erlang/charlist_to_string.rs b/native_implemented/otp/src/erlang/charlist_to_string.rs
index 2280f399f..c51a7147a 100644
--- a/native_implemented/otp/src/erlang/charlist_to_string.rs
+++ b/native_implemented/otp/src/erlang/charlist_to_string.rs
@@ -1,14 +1,15 @@
 use std::convert::TryInto;
+use std::ptr::NonNull;
 
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::{Term, TypeError};
 
-pub fn charlist_to_string(list: Term) -> exception::Result<String> {
-    match list.decode()? {
-        TypedTerm::Nil => Ok("".to_string()),
-        TypedTerm::List(boxed_cons) => boxed_cons.try_into().map_err(From::from),
+pub fn charlist_to_string(list: Term) -> Result<String, NonNull<ErlangException>> {
+    match list {
+        Term::Nil => Ok("".to_string()),
+        Term::Cons(boxed_cons) => boxed_cons.try_into().map_err(From::from),
         _ => Err(TypeError)
             .context(format!("list ({}) is not a a list", list))
             .map_err(From::from),
diff --git a/native_implemented/otp/src/erlang/concatenate_2.rs b/native_implemented/otp/src/erlang/concatenate_2.rs
index 4e7a6c651..e38f60525 100644
--- a/native_implemented/otp/src/erlang/concatenate_2.rs
+++ b/native_implemented/otp/src/erlang/concatenate_2.rs
@@ -1,15 +1,16 @@
+use std::ptr::NonNull;
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::{ImproperList, Term, TypeError};
 
 /// `++/2`
 #[native_implemented::function(erlang:++/2)]
-pub fn result(process: &Process, list: Term, term: Term) -> exception::Result<Term> {
-    match list.decode().unwrap() {
-        TypedTerm::Nil => Ok(term),
-        TypedTerm::List(cons) => match cons
+pub fn result(process: &Process, list: Term, term: Term) -> Result<Term, NonNull<ErlangException>> {
+    match list {
+        Term::Nil => Ok(term),
+        Term::Cons(cons) => match cons
             .into_iter()
             .collect::<std::result::Result<Vec<Term>, _>>()
         {
diff --git a/native_implemented/otp/src/erlang/convert_time_unit_3.rs b/native_implemented/otp/src/erlang/convert_time_unit_3.rs
index 481cfff61..4d9e83cad 100644
--- a/native_implemented/otp/src/erlang/convert_time_unit_3.rs
+++ b/native_implemented/otp/src/erlang/convert_time_unit_3.rs
@@ -3,9 +3,9 @@ use std::convert::TryInto;
 use anyhow::*;
 use num_bigint::BigInt;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::runtime::time;
 
@@ -15,14 +15,14 @@ pub fn result(
     time: Term,
     from_unit: Term,
     to_unit: Term,
-) -> exception::Result<Term> {
+) -> Result<Term, NonNull<ErlangException>> {
     let time_big_int: BigInt = time
         .try_into()
         .with_context(|| format!("time ({}) must be an integer", time))?;
     let from_unit_unit = term_try_into_time_unit!(from_unit)?;
     let to_unit_unit = term_try_into_time_unit!(to_unit)?;
     let converted_big_int = time::convert(time_big_int, from_unit_unit, to_unit_unit);
-    let converted_term = process.integer(converted_big_int);
+    let converted_term = process.integer(converted_big_int).unwrap();
 
     Ok(converted_term)
 }
diff --git a/native_implemented/otp/src/erlang/date_0.rs b/native_implemented/otp/src/erlang/date_0.rs
index f2350fd72..c0ad611a4 100644
--- a/native_implemented/otp/src/erlang/date_0.rs
+++ b/native_implemented/otp/src/erlang/date_0.rs
@@ -1,14 +1,15 @@
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
+
 use crate::runtime::time::datetime;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
 
 #[native_implemented::function(erlang:date/0)]
 pub fn result(process: &Process) -> Term {
     let date: [usize; 3] = datetime::local_date();
 
-    process.tuple_from_slice(&[
-        process.integer(date[0]),
-        process.integer(date[1]),
-        process.integer(date[2]),
+    process.tuple_term_from_term_slice(&[
+        process.integer(date[0]).unwrap(),
+        process.integer(date[1]).unwrap(),
+        process.integer(date[2]).unwrap(),
     ])
 }
diff --git a/native_implemented/otp/src/erlang/delete_element_2.rs b/native_implemented/otp/src/erlang/delete_element_2.rs
index 84b8977b8..e706aa863 100644
--- a/native_implemented/otp/src/erlang/delete_element_2.rs
+++ b/native_implemented/otp/src/erlang/delete_element_2.rs
@@ -1,16 +1,23 @@
 use std::convert::TryInto;
+use std::ptr::NonNull;
 
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_number::TryIntoIntegerError;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::{OneBasedIndex, Term};
 
 use crate::runtime::context::*;
 
 /// `delete_element/2`
 #[native_implemented::function(erlang:delete_element/2)]
-pub fn result(process: &Process, index: Term, tuple: Term) -> exception::Result<Term> {
+pub fn result(
+    process: &Process,
+    index: Term,
+    tuple: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     let initial_inner_tuple = term_try_into_tuple!(tuple)?;
     let initial_len = initial_inner_tuple.len();
 
@@ -23,7 +30,7 @@ pub fn result(process: &Process, index: Term, tuple: Term) -> exception::Result<
         if index_zero_based < initial_len {
             let mut new_elements_vec = initial_inner_tuple[..].to_vec();
             new_elements_vec.remove(index_zero_based);
-            let smaller_tuple = process.tuple_from_slice(&new_elements_vec);
+            let smaller_tuple = process.tuple_term_from_term_slice(&new_elements_vec).unwrap();
 
             Ok(smaller_tuple)
         } else {
diff --git a/native_implemented/otp/src/erlang/demonitor_1.rs b/native_implemented/otp/src/erlang/demonitor_1.rs
index 16a4b3135..37f12f57e 100644
--- a/native_implemented/otp/src/erlang/demonitor_1.rs
+++ b/native_implemented/otp/src/erlang/demonitor_1.rs
@@ -1,11 +1,13 @@
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use std::ptr::NonNull;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::demonitor_2::demonitor;
 
 #[native_implemented::function(erlang:demonitor/1)]
-pub fn result(process: &Process, reference: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, reference: Term) -> Result<Term, NonNull<ErlangException>> {
     let reference_reference = term_try_into_local_reference!(reference)?;
 
     demonitor(process, &reference_reference, Default::default())
diff --git a/native_implemented/otp/src/erlang/demonitor_2.rs b/native_implemented/otp/src/erlang/demonitor_2.rs
index b49982ceb..d297fda2c 100644
--- a/native_implemented/otp/src/erlang/demonitor_2.rs
+++ b/native_implemented/otp/src/erlang/demonitor_2.rs
@@ -1,10 +1,11 @@
 mod options;
 
 use std::convert::TryInto;
+use std::ptr::NonNull;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Reference, Term};
 
 use crate::runtime::process::monitor::is_down;
 use crate::runtime::registry::pid_to_process;
@@ -12,7 +13,11 @@ use crate::runtime::registry::pid_to_process;
 use crate::erlang::demonitor_2::options::Options;
 
 #[native_implemented::function(erlang:demonitor/2)]
-pub fn result(process: &Process, reference: Term, options: Term) -> exception::Result<Term> {
+pub fn result(
+    process: &Process,
+    reference: Term,
+    options: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     let reference_reference = term_try_into_local_reference!(reference)?;
     let options_options: Options = options.try_into()?;
 
@@ -25,7 +30,7 @@ pub(in crate::erlang) fn demonitor(
     monitoring_process: &Process,
     reference: &Reference,
     Options { flush, info }: Options,
-) -> exception::Result<Term> {
+) -> Result<Term, NonNull<ErlangException>> {
     match monitoring_process.demonitor(reference) {
         Some(monitored_pid) => {
             match pid_to_process(&monitored_pid) {
diff --git a/native_implemented/otp/src/erlang/demonitor_2/options.rs b/native_implemented/otp/src/erlang/demonitor_2/options.rs
index 29b907a2e..c31e43ccf 100644
--- a/native_implemented/otp/src/erlang/demonitor_2/options.rs
+++ b/native_implemented/otp/src/erlang/demonitor_2/options.rs
@@ -2,7 +2,8 @@ use std::convert::{TryFrom, TryInto};
 
 use anyhow::*;
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::*;
+use firefly_rt::term::Term;
 
 use crate::runtime::proplist::TryPropListFromTermError;
 
@@ -19,7 +20,7 @@ impl Options {
             .try_into()
             .map_err(|_| TryPropListFromTermError::PropertyType)?;
 
-        match option_atom.name() {
+        match option_atom.as_str() {
             "flush" => {
                 self.flush = true;
 
@@ -52,13 +53,14 @@ impl TryFrom<Term> for Options {
         let mut options_term = term;
 
         loop {
-            match options_term.decode().unwrap() {
-                TypedTerm::Nil => return Ok(options),
-                TypedTerm::List(cons) => {
+            match options_term {
+                Term::Nil => return Ok(options),
+                Term::Cons(non_null_cons) => {
+                    let cons = unsafe { non_null_cons.as_ref() };
                     options
-                        .put_option_term(cons.head)
+                        .put_option_term(cons.head())
                         .context(SUPPORTED_OPTIONS_CONTEXT)?;
-                    options_term = cons.tail;
+                    options_term = cons.tail();
 
                     continue;
                 }
diff --git a/native_implemented/otp/src/erlang/display_1.rs b/native_implemented/otp/src/erlang/display_1.rs
index f58425806..ba963eb94 100644
--- a/native_implemented/otp/src/erlang/display_1.rs
+++ b/native_implemented/otp/src/erlang/display_1.rs
@@ -1,5 +1,5 @@
-use liblumen_alloc::atom;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::*;
+use firefly_rt::term::{atoms, Term};
 
 use crate::runtime;
 
@@ -7,5 +7,5 @@ use crate::runtime;
 pub fn result(term: Term) -> Term {
     runtime::sys::io::puts(&format!("{}", term));
 
-    atom!("ok")
+    atoms::Ok.into()
 }
diff --git a/native_implemented/otp/src/erlang/div_2.rs b/native_implemented/otp/src/erlang/div_2.rs
index e9525473b..72fb31310 100644
--- a/native_implemented/otp/src/erlang/div_2.rs
+++ b/native_implemented/otp/src/erlang/div_2.rs
@@ -1,9 +1,15 @@
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use std::ptr::NonNull;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 /// `div/2` infix operator.  Integer division.
 #[native_implemented::function(erlang:div/2)]
-pub fn result(process: &Process, dividend: Term, divisor: Term) -> exception::Result<Term> {
+pub fn result(
+    process: &Process,
+    dividend: Term,
+    divisor: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     integer_infix_operator!(dividend, divisor, process, /)
 }
diff --git a/native_implemented/otp/src/erlang/divide_2.rs b/native_implemented/otp/src/erlang/divide_2.rs
index 8a9202b99..b72166a88 100644
--- a/native_implemented/otp/src/erlang/divide_2.rs
+++ b/native_implemented/otp/src/erlang/divide_2.rs
@@ -5,15 +5,17 @@ use std::convert::TryInto;
 
 use anyhow::*;
 
-use liblumen_alloc::erts::exception::{self, *};
-use liblumen_alloc::erts::process::trace::Trace;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 /// `//2` infix operator.  Unlike `+/2`, `-/2` and `*/2` always promotes to `float` returns the
 /// `float`.
 #[native_implemented::function(erlang:/ /2)]
-pub fn result(process: &Process, dividend: Term, divisor: Term) -> exception::Result<Term> {
+pub fn result(
+    process: &Process,
+    dividend: Term,
+    divisor: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     let dividend_f64: f64 = dividend.try_into().map_err(|_| {
         badarith(
             Trace::capture(),
@@ -35,7 +37,7 @@ pub fn result(process: &Process, dividend: Term, divisor: Term) -> exception::Re
         .into())
     } else {
         let quotient_f64 = dividend_f64 / divisor_f64;
-        let quotient_term = process.float(quotient_f64);
+        let quotient_term = quotient_f64.into();
 
         Ok(quotient_term)
     }
diff --git a/native_implemented/otp/src/erlang/divide_2/test.rs b/native_implemented/otp/src/erlang/divide_2/test.rs
index 18bc6eb03..1509236c8 100644
--- a/native_implemented/otp/src/erlang/divide_2/test.rs
+++ b/native_implemented/otp/src/erlang/divide_2/test.rs
@@ -1,10 +1,10 @@
 use std::sync::Arc;
 
 use proptest::prop_assert;
-use proptest::strategy::{BoxedStrategy, Just, Strategy};
+use proptest::strategy::{BoxedStrategy, Just};
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::divide_2::result;
 use crate::test::strategy;
@@ -37,13 +37,13 @@ fn with_number_dividend_without_zero_number_divisor_returns_float() {
 fn number_is_not_zero(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
     strategy::term::is_number(arc_process)
         .prop_filter("Number must not be zero", |number| {
-            match number.decode().unwrap() {
-                TypedTerm::SmallInteger(small_integer) => {
+            match number {
+                Term::Int(small_integer) => {
                     let i: isize = small_integer.into();
 
                     i != 0
                 }
-                TypedTerm::Float(float) => {
+                Term::Float(float) => {
                     let f: f64 = float.into();
 
                     f != 0.0
diff --git a/native_implemented/otp/src/erlang/element_2.rs b/native_implemented/otp/src/erlang/element_2.rs
index 2c433b0e3..af8618a2b 100644
--- a/native_implemented/otp/src/erlang/element_2.rs
+++ b/native_implemented/otp/src/erlang/element_2.rs
@@ -1,13 +1,15 @@
+use std::ptr::NonNull;
+
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::Term;
 
 use crate::runtime::context::*;
 
 /// `element/2`
 #[native_implemented::function(erlang:element/2)]
-pub fn result(index: Term, tuple: Term) -> exception::Result<Term> {
+pub fn result(index: Term, tuple: Term) -> Result<Term, NonNull<ErlangException>> {
     let tuple_tuple = term_try_into_tuple!(tuple)?;
     let one_based_index = term_try_into_one_based_index(index)?;
 
diff --git a/native_implemented/otp/src/erlang/erase_0.rs b/native_implemented/otp/src/erlang/erase_0.rs
index dd43a37fc..139174783 100644
--- a/native_implemented/otp/src/erlang/erase_0.rs
+++ b/native_implemented/otp/src/erlang/erase_0.rs
@@ -1,5 +1,5 @@
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:erase/0)]
 pub fn result(process: &Process) -> Term {
diff --git a/native_implemented/otp/src/erlang/erase_1.rs b/native_implemented/otp/src/erlang/erase_1.rs
index 558eb5e06..180f852a5 100644
--- a/native_implemented/otp/src/erlang/erase_1.rs
+++ b/native_implemented/otp/src/erlang/erase_1.rs
@@ -1,5 +1,5 @@
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:erase/1)]
 pub fn result(process: &Process, key: Term) -> Term {
diff --git a/native_implemented/otp/src/erlang/error_1.rs b/native_implemented/otp/src/erlang/error_1.rs
index d7d604d36..195a0d47e 100644
--- a/native_implemented/otp/src/erlang/error_1.rs
+++ b/native_implemented/otp/src/erlang/error_1.rs
@@ -1,11 +1,13 @@
+use std::ptr::NonNull;
+
 use anyhow::*;
 
-use liblumen_alloc::erts::exception::{self, error};
-use liblumen_alloc::erts::process::trace::Trace;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::backtrace::Trace;
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:error/1)]
-pub fn result(reason: Term) -> exception::Result<Term> {
+pub fn result(reason: Term) -> Result<Term, NonNull<ErlangException>> {
     Err(error(
         reason,
         None,
diff --git a/native_implemented/otp/src/erlang/error_2.rs b/native_implemented/otp/src/erlang/error_2.rs
index bb6dc1cfd..19b267229 100644
--- a/native_implemented/otp/src/erlang/error_2.rs
+++ b/native_implemented/otp/src/erlang/error_2.rs
@@ -1,17 +1,14 @@
+use std::ptr::NonNull;
+
 use anyhow::*;
+use firefly_rt::backtrace::Trace;
 
-use liblumen_alloc::error;
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::trace::Trace;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::function::ErlangResult;
+use firefly_rt::term::{atoms, Term};
 
 #[native_implemented::function(erlang:error/2)]
-pub fn result(reason: Term, arguments: Term) -> exception::Result<Term> {
-    Err(error!(
-        reason,
-        arguments,
-        Trace::capture(),
-        anyhow!("explicit error from Erlang").into()
-    )
-    .into())
+pub fn result(reason: Term, arguments: Term) -> Result<Term, NonNull<ErlangException>> {
+    let err = ErlangException::new_with_meta(atoms::Error, reason, arguments, Trace::capture());
+    Err(unsafe { NonNull::new_unchecked(Box::into_raw(err)) })
 }
diff --git a/native_implemented/otp/src/erlang/exit_1.rs b/native_implemented/otp/src/erlang/exit_1.rs
index 4405ef76b..39f32710c 100644
--- a/native_implemented/otp/src/erlang/exit_1.rs
+++ b/native_implemented/otp/src/erlang/exit_1.rs
@@ -1,16 +1,11 @@
-use anyhow::*;
+use std::ptr::NonNull;
+use firefly_rt::backtrace::Trace;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::trace::Trace;
-use liblumen_alloc::erts::term::prelude::Term;
-use liblumen_alloc::exit;
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::{atoms, Term};
 
 #[native_implemented::function(erlang:exit/1)]
-fn result(reason: Term) -> exception::Result<Term> {
-    Err(exit!(
-        reason,
-        Trace::capture(),
-        anyhow!("explicit exit from Erlang").into()
-    )
-    .into())
+fn result(reason: Term) -> Result<Term, NonNull<ErlangException>> {
+    let err = ErlangException::new(atoms::Exit, reason.into(), Trace::capture());
+    Err(unsafe { NonNull::new_unchecked(Box::into_raw(err)) })
 }
diff --git a/native_implemented/otp/src/erlang/float_1.rs b/native_implemented/otp/src/erlang/float_1.rs
index 28bddf5e0..70fd933b9 100644
--- a/native_implemented/otp/src/erlang/float_1.rs
+++ b/native_implemented/otp/src/erlang/float_1.rs
@@ -1,20 +1,21 @@
 use std::convert::TryInto;
+use std::ptr::NonNull;
 
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:float/1)]
-pub fn result(process: &Process, number: Term) -> exception::Result<Term> {
-    if number.is_boxed_float() {
+pub fn result(process: &Process, number: Term) -> Result<Term, NonNull<ErlangException>> {
+    if number.is_float() {
         Ok(number)
     } else {
         let f: f64 = number
             .try_into()
             .with_context(|| term_is_not_number!(number))?;
 
-        Ok(process.float(f))
+        Ok(f.into())
     }
 }
diff --git a/native_implemented/otp/src/erlang/float_to_binary_1.rs b/native_implemented/otp/src/erlang/float_to_binary_1.rs
index 1214ddb4c..20756814a 100644
--- a/native_implemented/otp/src/erlang/float_to_binary_1.rs
+++ b/native_implemented/otp/src/erlang/float_to_binary_1.rs
@@ -1,14 +1,14 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::float_to_string::float_to_string;
 
 #[native_implemented::function(erlang:float_to_binary/1)]
-pub fn result(process: &Process, float: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, float: Term) -> Result<Term, NonNull<ErlangException>> {
     float_to_string(float, Default::default())
         .map_err(|error| error.into())
         .map(|string| process.binary_from_str(&string))
diff --git a/native_implemented/otp/src/erlang/float_to_binary_1/test/with_float.rs b/native_implemented/otp/src/erlang/float_to_binary_1/test/with_float.rs
index a2a7b72dc..8d7e1fee1 100644
--- a/native_implemented/otp/src/erlang/float_to_binary_1/test/with_float.rs
+++ b/native_implemented/otp/src/erlang/float_to_binary_1/test/with_float.rs
@@ -9,7 +9,7 @@ use crate::erlang::binary_to_float_1;
 fn is_dual_of_binary_to_float_1() {
     with_process_arc(|arc_process| {
         TestRunner::new(Config::with_source_file(file!()))
-            .run(&strategy::term::float(arc_process.clone()), |float| {
+            .run(&strategy::term::float(), |float| {
                 let result_binary = result(&arc_process, float);
 
                 prop_assert!(result_binary.is_ok());
diff --git a/native_implemented/otp/src/erlang/float_to_binary_2.rs b/native_implemented/otp/src/erlang/float_to_binary_2.rs
index 30594eb90..ba493ca82 100644
--- a/native_implemented/otp/src/erlang/float_to_binary_2.rs
+++ b/native_implemented/otp/src/erlang/float_to_binary_2.rs
@@ -3,14 +3,18 @@ mod test;
 
 use std::convert::TryInto;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::float_to_string::{float_to_string, Options};
 
 #[native_implemented::function(erlang:float_to_binary/2)]
-pub fn result(process: &Process, float: Term, options: Term) -> exception::Result<Term> {
+pub fn result(
+    process: &Process,
+    float: Term,
+    options: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     let options_options: Options = options.try_into()?;
 
     float_to_string(float, options_options)
diff --git a/native_implemented/otp/src/erlang/float_to_binary_2/test.rs b/native_implemented/otp/src/erlang/float_to_binary_2/test.rs
index cb3d6a61b..28a6419c7 100644
--- a/native_implemented/otp/src/erlang/float_to_binary_2/test.rs
+++ b/native_implemented/otp/src/erlang/float_to_binary_2/test.rs
@@ -4,9 +4,8 @@ use proptest::strategy::Just;
 use proptest::test_runner::{Config, TestRunner};
 use proptest::{prop_assert, prop_assert_eq};
 
-use liblumen_alloc::atom;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::{atoms, Term};
 
 use crate::erlang::float_to_binary_2::result;
 use crate::test::with_process_arc;
diff --git a/native_implemented/otp/src/erlang/float_to_binary_2/test/with_float.rs b/native_implemented/otp/src/erlang/float_to_binary_2/test/with_float.rs
index 0eb367e1b..43c978bfc 100644
--- a/native_implemented/otp/src/erlang/float_to_binary_2/test/with_float.rs
+++ b/native_implemented/otp/src/erlang/float_to_binary_2/test/with_float.rs
@@ -11,12 +11,12 @@ fn without_proper_list_options_errors_badarg() {
         |arc_process| {
             (
                 Just(arc_process.clone()),
-                strategy::term::float(arc_process.clone()),
+                strategy::term::float(),
                 strategy::term::is_not_list(arc_process.clone()),
             )
         },
         |(arc_process, float, tail)| {
-            let options = arc_process.improper_list_from_slice(&[atom!("compact")], tail);
+            let options = arc_process.improper_list_from_slice(&[atoms::Compact.into()], tail);
 
             prop_assert_badarg!(result(&arc_process, float, options), "improper list");
 
diff --git a/native_implemented/otp/src/erlang/float_to_binary_2/test/with_float/with_empty_list_options.rs b/native_implemented/otp/src/erlang/float_to_binary_2/test/with_float/with_empty_list_options.rs
index 55063d9c3..7fe4c490e 100644
--- a/native_implemented/otp/src/erlang/float_to_binary_2/test/with_float/with_empty_list_options.rs
+++ b/native_implemented/otp/src/erlang/float_to_binary_2/test/with_float/with_empty_list_options.rs
@@ -7,7 +7,7 @@ use super::*;
 fn is_dual_of_binary_to_float_1() {
     with_process_arc(|arc_process| {
         TestRunner::new(Config::with_source_file(file!()))
-            .run(&strategy::term::float(arc_process.clone()), |float| {
+            .run(&strategy::term::float(), |float| {
                 let result_binary = result(&arc_process, float, options(&arc_process));
 
                 prop_assert!(result_binary.is_ok());
@@ -23,5 +23,5 @@ fn is_dual_of_binary_to_float_1() {
 }
 
 fn options(_: &Process) -> Term {
-    Term::NIL
+    Term::Nil
 }
diff --git a/native_implemented/otp/src/erlang/float_to_binary_2/test/with_float/with_proper_list_options/with_scientific.rs b/native_implemented/otp/src/erlang/float_to_binary_2/test/with_float/with_proper_list_options/with_scientific.rs
index d80c06f48..9b0babffc 100644
--- a/native_implemented/otp/src/erlang/float_to_binary_2/test/with_float/with_proper_list_options/with_scientific.rs
+++ b/native_implemented/otp/src/erlang/float_to_binary_2/test/with_float/with_proper_list_options/with_scientific.rs
@@ -4,8 +4,7 @@ use std::sync::Arc;
 
 use proptest::strategy::{BoxedStrategy, Just, Strategy};
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
 
 use crate::runtime::binary_to_string::binary_to_string;
 
@@ -70,17 +69,17 @@ fn exponent_is_at_least_2_digits() {
 
 fn digits(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
     (Just(arc_process.clone()), 0..=249)
-        .prop_map(|(arc_process, u)| arc_process.integer(u))
+        .prop_map(|(arc_process, u)| arc_process.integer(u).unwrap())
         .boxed()
 }
 
 fn strategy(arc_process: Arc<Process>) -> impl Strategy<Value = (Arc<Process>, Term, Term)> {
     (
         Just(arc_process.clone()),
-        super::strategy::term::float(arc_process.clone()),
+        super::strategy::term::float(),
         (Just(arc_process.clone()), digits(arc_process.clone())).prop_map(
             |(arc_process, digits)| {
-                arc_process.list_from_slice(&[arc_process.tuple_from_slice(&[tag(), digits])])
+                arc_process.list_from_slice(&[arc_process.tuple_term_from_term_slice(&[tag(), digits])]).unwrap()
             },
         ),
     )
diff --git a/native_implemented/otp/src/erlang/float_to_list_1.rs b/native_implemented/otp/src/erlang/float_to_list_1.rs
index 7db9685fe..bb477471a 100644
--- a/native_implemented/otp/src/erlang/float_to_list_1.rs
+++ b/native_implemented/otp/src/erlang/float_to_list_1.rs
@@ -1,14 +1,14 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::float_to_string::float_to_string;
 
 #[native_implemented::function(erlang:float_to_list/1)]
-pub fn result(process: &Process, float: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, float: Term) -> Result<Term, NonNull<ErlangException>> {
     float_to_string(float, Default::default())
         .map_err(|error| error.into())
         .map(|string| process.charlist_from_str(&string))
diff --git a/native_implemented/otp/src/erlang/float_to_list_1/test/with_float.rs b/native_implemented/otp/src/erlang/float_to_list_1/test/with_float.rs
index 556d6f238..162be8edd 100644
--- a/native_implemented/otp/src/erlang/float_to_list_1/test/with_float.rs
+++ b/native_implemented/otp/src/erlang/float_to_list_1/test/with_float.rs
@@ -9,7 +9,7 @@ use crate::erlang::list_to_float_1;
 fn is_dual_of_list_to_float_1() {
     with_process_arc(|arc_process| {
         TestRunner::new(Config::with_source_file(file!()))
-            .run(&strategy::term::float(arc_process.clone()), |float| {
+            .run(&strategy::term::float(), |float| {
                 let result_list = result(&arc_process, float);
 
                 prop_assert!(result_list.is_ok());
diff --git a/native_implemented/otp/src/erlang/float_to_list_2.rs b/native_implemented/otp/src/erlang/float_to_list_2.rs
index 452c09cdb..cfa98b24f 100644
--- a/native_implemented/otp/src/erlang/float_to_list_2.rs
+++ b/native_implemented/otp/src/erlang/float_to_list_2.rs
@@ -3,14 +3,18 @@ mod test;
 
 use std::convert::TryInto;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::float_to_string::{float_to_string, Options};
 
 #[native_implemented::function(erlang:float_to_list/2)]
-pub fn result(process: &Process, float: Term, options: Term) -> exception::Result<Term> {
+pub fn result(
+    process: &Process,
+    float: Term,
+    options: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     let options_options: Options = options.try_into()?;
 
     float_to_string(float, options_options)
diff --git a/native_implemented/otp/src/erlang/float_to_list_2/test.rs b/native_implemented/otp/src/erlang/float_to_list_2/test.rs
index 52f0a160d..1a36f3b45 100644
--- a/native_implemented/otp/src/erlang/float_to_list_2/test.rs
+++ b/native_implemented/otp/src/erlang/float_to_list_2/test.rs
@@ -4,8 +4,8 @@ use proptest::strategy::Just;
 use proptest::test_runner::{Config, TestRunner};
 use proptest::{prop_assert, prop_assert_eq};
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::float_to_list_2::result;
 use crate::test::strategy;
diff --git a/native_implemented/otp/src/erlang/float_to_list_2/test/with_float.rs b/native_implemented/otp/src/erlang/float_to_list_2/test/with_float.rs
index 1bdbee650..93edee945 100644
--- a/native_implemented/otp/src/erlang/float_to_list_2/test/with_float.rs
+++ b/native_implemented/otp/src/erlang/float_to_list_2/test/with_float.rs
@@ -9,7 +9,7 @@ fn without_proper_list_options_errors_badarg() {
         |arc_process| {
             (
                 Just(arc_process.clone()),
-                strategy::term::float(arc_process.clone()),
+                strategy::term::float(),
                 strategy::term::is_not_proper_list(arc_process.clone()),
             )
         },
diff --git a/native_implemented/otp/src/erlang/float_to_list_2/test/with_float/with_empty_list_options.rs b/native_implemented/otp/src/erlang/float_to_list_2/test/with_float/with_empty_list_options.rs
index c44786b32..acf1da05f 100644
--- a/native_implemented/otp/src/erlang/float_to_list_2/test/with_float/with_empty_list_options.rs
+++ b/native_implemented/otp/src/erlang/float_to_list_2/test/with_float/with_empty_list_options.rs
@@ -9,7 +9,7 @@ use crate::erlang::list_to_float_1;
 fn is_dual_of_list_to_float_1() {
     with_process_arc(|arc_process| {
         TestRunner::new(Config::with_source_file(file!()))
-            .run(&strategy::term::float(arc_process.clone()), |float| {
+            .run(&strategy::term::float(), |float| {
                 let result_list = result(&arc_process, float, options(&arc_process));
 
                 prop_assert!(result_list.is_ok());
@@ -25,5 +25,5 @@ fn is_dual_of_list_to_float_1() {
 }
 
 pub fn options(_: &Process) -> Term {
-    Term::NIL
+    Term::Nil
 }
diff --git a/native_implemented/otp/src/erlang/float_to_list_2/test/with_float/with_proper_list_options/with_scientific.rs b/native_implemented/otp/src/erlang/float_to_list_2/test/with_float/with_proper_list_options/with_scientific.rs
index 23c6ee99c..a34607f6e 100644
--- a/native_implemented/otp/src/erlang/float_to_list_2/test/with_float/with_proper_list_options/with_scientific.rs
+++ b/native_implemented/otp/src/erlang/float_to_list_2/test/with_float/with_proper_list_options/with_scientific.rs
@@ -2,10 +2,9 @@ use super::*;
 
 use std::sync::Arc;
 
-use proptest::strategy::{BoxedStrategy, Just, Strategy};
+use proptest::strategy::{BoxedStrategy, Just};
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
 
 use crate::erlang::charlist_to_string::charlist_to_string;
 
@@ -18,9 +17,9 @@ fn always_includes_e() {
         |arc_process| {
             (
                 Just(arc_process.clone()),
-                strategy::term::float(arc_process.clone()),
+                strategy::term::float(),
                 digits(arc_process.clone()).prop_map(move |digits| {
-                    arc_process.list_from_slice(&[arc_process.tuple_from_slice(&[tag(), digits])])
+                    arc_process.list_from_slice(&[arc_process.tuple_term_from_term_slice(&[tag(), digits])]).unwrap()
                 }),
             )
         },
@@ -45,9 +44,9 @@ fn always_includes_sign_of_exponent() {
         |arc_process| {
             (
                 Just(arc_process.clone()),
-                strategy::term::float(arc_process.clone()),
+                strategy::term::float(),
                 digits(arc_process.clone()).prop_map(move |digits| {
-                    arc_process.list_from_slice(&[arc_process.tuple_from_slice(&[tag(), digits])])
+                    arc_process.list_from_slice(&[arc_process.tuple_term_from_term_slice(&[tag(), digits])]).unwrap()
                 }),
             )
         },
@@ -77,9 +76,9 @@ fn exponent_is_at_least_2_digits() {
         |arc_process| {
             (
                 Just(arc_process.clone()),
-                strategy::term::float(arc_process.clone()),
+                strategy::term::float(),
                 digits(arc_process.clone()).prop_map(move |digits| {
-                    arc_process.list_from_slice(&[arc_process.tuple_from_slice(&[tag(), digits])])
+                    arc_process.list_from_slice(&[arc_process.tuple_term_from_term_slice(&[tag(), digits])]).unwrap()
                 }),
             )
         },
@@ -103,7 +102,7 @@ fn exponent_is_at_least_2_digits() {
 
 fn digits(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
     (Just(arc_process.clone()), 0..=249)
-        .prop_map(|(arc_process, u)| arc_process.integer(u))
+        .prop_map(|(arc_process, u)| arc_process.integer(u).unwrap())
         .boxed()
 }
 
diff --git a/native_implemented/otp/src/erlang/float_to_string.rs b/native_implemented/otp/src/erlang/float_to_string.rs
index 411b05cac..fbc814fca 100644
--- a/native_implemented/otp/src/erlang/float_to_string.rs
+++ b/native_implemented/otp/src/erlang/float_to_string.rs
@@ -4,16 +4,15 @@ mod scientific_digits;
 use std::convert::{TryFrom, TryInto};
 
 use anyhow::Context;
+use decimal_digits::DecimalDigits;
+use firefly_rt::error::ErlangException;
+use scientific_digits::ScientificDigits;
 
-use liblumen_alloc::erts::exception::{self, InternalResult};
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::{Atom, Term, TypeError};
 
 use crate::runtime::proplist::TryPropListFromTermError;
 
-use decimal_digits::DecimalDigits;
-use scientific_digits::ScientificDigits;
-
-pub fn float_to_string(float: Term, options: Options) -> exception::Result<String> {
+pub fn float_to_string(float: Term, options: Options) -> Result<String, NonNull<ErlangException>> {
     // `TryInto<f64> for Term` will convert integer terms to f64 too, which we don't want
     let float_f64: f64 = float_term_to_f64(float)?;
 
@@ -79,8 +78,8 @@ impl TryFrom<Term> for Options {
 // Private
 
 fn float_term_to_f64(float_term: Term) -> InternalResult<f64> {
-    match float_term.decode()? {
-        TypedTerm::Float(float) => Ok(float.into()),
+    match float_term {
+        Term::Float(float) => Ok(float.into()),
         _ => Err(TypeError)
             .context(format!("float ({}) is not a float", float_term))
             .map_err(From::from),
@@ -143,8 +142,8 @@ struct OptionsBuilder {
 
 impl OptionsBuilder {
     fn put_option_term(&mut self, option: Term) -> Result<&OptionsBuilder, anyhow::Error> {
-        match option.decode().unwrap() {
-            TypedTerm::Atom(atom) => match atom.name() {
+        match option {
+            Term::Atom(atom) => match atom.as_str() {
                 "compact" => {
                     self.compact = true;
 
@@ -152,13 +151,13 @@ impl OptionsBuilder {
                 }
                 name => Err(TryAtomFromTermError(name)).context("supported atom option is compact"),
             },
-            TypedTerm::Tuple(tuple) => {
+            Term::Tuple(tuple) => {
                 if tuple.len() == 2 {
                     let atom: Atom = tuple[0]
                         .try_into()
                         .map_err(|_| TryPropListFromTermError::KeywordKeyType)?;
 
-                    match atom.name() {
+                    match atom.as_str() {
                         "decimals" => {
                             let decimal_digits = tuple[1]
                                 .try_into()
@@ -206,13 +205,14 @@ impl TryFrom<Term> for OptionsBuilder {
         let mut options_term = term;
 
         loop {
-            match options_term.decode().unwrap() {
-                TypedTerm::Nil => break,
-                TypedTerm::List(cons) => {
+            match options_term {
+                Term::Nil => break,
+                Term::Cons(non_null_cons) => {
+                    let cons = unsafe { non_null_cons.as_ref() };
                     options_builder
-                        .put_option_term(cons.head)
+                        .put_option_term(cons.head())
                         .context(SUPPORTED_OPTIONS_CONTEXT)?;
-                    options_term = cons.tail;
+                    options_term = cons.tail();
 
                     continue;
                 }
diff --git a/native_implemented/otp/src/erlang/float_to_string/decimal_digits.rs b/native_implemented/otp/src/erlang/float_to_string/decimal_digits.rs
index 14b2211c8..b891fc391 100644
--- a/native_implemented/otp/src/erlang/float_to_string/decimal_digits.rs
+++ b/native_implemented/otp/src/erlang/float_to_string/decimal_digits.rs
@@ -1,6 +1,8 @@
 use std::convert::{TryFrom, TryInto};
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_number::TryIntoIntegerError;
+
+use firefly_rt::term::Term;
 
 // > {decimals, Decimals :: 0..253}
 pub struct DecimalDigits(u8);
diff --git a/native_implemented/otp/src/erlang/float_to_string/scientific_digits.rs b/native_implemented/otp/src/erlang/float_to_string/scientific_digits.rs
index 17280b186..b1c5119e5 100644
--- a/native_implemented/otp/src/erlang/float_to_string/scientific_digits.rs
+++ b/native_implemented/otp/src/erlang/float_to_string/scientific_digits.rs
@@ -1,6 +1,7 @@
 use std::convert::{TryFrom, TryInto};
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_number::TryIntoIntegerError;
+use firefly_rt::term::Term;
 
 pub struct ScientificDigits(u8);
 
diff --git a/native_implemented/otp/src/erlang/function_exported_3.rs b/native_implemented/otp/src/erlang/function_exported_3.rs
index 9100b804c..4efbe3ab6 100644
--- a/native_implemented/otp/src/erlang/function_exported_3.rs
+++ b/native_implemented/otp/src/erlang/function_exported_3.rs
@@ -6,16 +6,16 @@
 //! ```
 
 use std::convert::TryInto;
+use std::ptr::NonNull;
 
 use anyhow::*;
 
-use liblumen_alloc::erts::apply::find_symbol;
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::term::prelude::{Atom, Term};
-use liblumen_alloc::{Arity, ModuleFunctionArity};
+use firefly_rt::error::ErlangException;
+use firefly_rt::function::{Arity, find_symbol, ModuleFunctionArity};
+use firefly_rt::term::{Atom, Term};
 
 #[native_implemented::function(erlang:function_exported/3)]
-pub fn result(module: Term, function: Term, arity: Term) -> exception::Result<Term> {
+pub fn result(module: Term, function: Term, arity: Term) -> Result<Term, NonNull<ErlangException>> {
     let module_atom: Atom = module.try_into().context("module must be an atom")?;
     let function_atom: Atom = function.try_into().context("function must be an atom")?;
     let arity_arity: Arity = arity.try_into().context("arity must be in 0-255")?;
diff --git a/native_implemented/otp/src/erlang/get_0.rs b/native_implemented/otp/src/erlang/get_0.rs
index 3d0e7bfbb..25c01717e 100644
--- a/native_implemented/otp/src/erlang/get_0.rs
+++ b/native_implemented/otp/src/erlang/get_0.rs
@@ -1,5 +1,5 @@
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:get/0)]
 pub fn result(process: &Process) -> Term {
diff --git a/native_implemented/otp/src/erlang/get_1.rs b/native_implemented/otp/src/erlang/get_1.rs
index 8693409ad..5adca508a 100644
--- a/native_implemented/otp/src/erlang/get_1.rs
+++ b/native_implemented/otp/src/erlang/get_1.rs
@@ -1,5 +1,5 @@
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:get/1)]
 pub fn result(process: &Process, key: Term) -> Term {
diff --git a/native_implemented/otp/src/erlang/get_keys_0.rs b/native_implemented/otp/src/erlang/get_keys_0.rs
index 7f5ffb5bd..6c2c7a162 100644
--- a/native_implemented/otp/src/erlang/get_keys_0.rs
+++ b/native_implemented/otp/src/erlang/get_keys_0.rs
@@ -1,5 +1,5 @@
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:get_keys/0)]
 pub fn result(process: &Process) -> Term {
diff --git a/native_implemented/otp/src/erlang/get_keys_1.rs b/native_implemented/otp/src/erlang/get_keys_1.rs
index 67caa7387..bdb5f4dad 100644
--- a/native_implemented/otp/src/erlang/get_keys_1.rs
+++ b/native_implemented/otp/src/erlang/get_keys_1.rs
@@ -1,5 +1,5 @@
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:get_keys/1)]
 pub fn result(process: &Process, value: Term) -> Term {
diff --git a/native_implemented/otp/src/erlang/get_stacktrace_0.rs b/native_implemented/otp/src/erlang/get_stacktrace_0.rs
index 416ea3d5c..a60bb1325 100644
--- a/native_implemented/otp/src/erlang/get_stacktrace_0.rs
+++ b/native_implemented/otp/src/erlang/get_stacktrace_0.rs
@@ -10,13 +10,13 @@
 #[cfg(test)]
 mod test;
 
-use liblumen_alloc::erts::process::{Process, Status};
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::process::{Process, ProcessStatus};
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:get_stacktrace/0)]
 pub fn result(process: &Process) -> Term {
-    match *process.status.read() {
-        Status::RuntimeException(ref exc) => exc.stacktrace().as_term().unwrap(),
-        _ => Term::NIL,
+    match process.status() {
+        ProcessStatus::Errored(ref erlang_exception) => erlang_exception.trace().as_term().unwrap(),
+        _ => Term::Nil,
     }
 }
diff --git a/native_implemented/otp/src/erlang/get_stacktrace_0/test.rs b/native_implemented/otp/src/erlang/get_stacktrace_0/test.rs
index 36a15dce9..19088da44 100644
--- a/native_implemented/otp/src/erlang/get_stacktrace_0/test.rs
+++ b/native_implemented/otp/src/erlang/get_stacktrace_0/test.rs
@@ -1,6 +1,6 @@
 mod with_exception;
 
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::term::{atoms, Term};
 
 use crate::erlang::get_stacktrace_0::result;
 use crate::test::with_process;
@@ -8,6 +8,6 @@ use crate::test::with_process;
 #[test]
 fn without_exception_returns_empty_list() {
     with_process(|process| {
-        assert_eq!(result(process), Term::NIL);
+        assert_eq!(result(process), Term::Nil);
     });
 }
diff --git a/native_implemented/otp/src/erlang/get_stacktrace_0/test/with_exception.rs b/native_implemented/otp/src/erlang/get_stacktrace_0/test/with_exception.rs
index 99d53b62f..63151b984 100644
--- a/native_implemented/otp/src/erlang/get_stacktrace_0/test/with_exception.rs
+++ b/native_implemented/otp/src/erlang/get_stacktrace_0/test/with_exception.rs
@@ -1,10 +1,6 @@
+use firefly_rt::term::Atom;
 use super::*;
 
-use anyhow::*;
-
-use liblumen_alloc::erts::process::trace::Trace;
-use liblumen_alloc::{atom, exit};
-
 #[test]
 fn without_stacktrace_returns_empty_list() {
     with_process(|process| {
@@ -14,33 +10,33 @@ fn without_stacktrace_returns_empty_list() {
             anyhow!("Test").into()
         ));
 
-        assert_eq!(result(process), Term::NIL);
+        assert_eq!(result(process), Term::Nil);
     });
 }
 
 #[test]
 fn with_stacktrace_returns_stacktrace() {
     with_process(|process| {
-        let module = atom!("module");
-        let function = atom!("function");
+        let module = Atom::str_to_term("module").into();
+        let function = Atom::str_to_term("function").into();
         let arity = 0.into();
 
-        let file_key = atom!("file");
+        let file_key = atoms::File.into();
         let file_value = process.charlist_from_str("path.ex");
-        let file_tuple = process.tuple_from_slice(&[file_key, file_value]);
+        let file_tuple = process.tuple_term_from_term_slice(&[file_key, file_value]);
 
-        let line_key = atom!("line");
+        let line_key = atoms::Line.into();
         let line_value = 1.into();
-        let line_tuple = process.tuple_from_slice(&[line_key, line_value]);
+        let line_tuple = process.tuple_term_from_term_slice(&[line_key, line_value]);
 
-        let location = process.list_from_slice(&[file_tuple, line_tuple]);
+        let location = Term::list_from_slice_in(&[file_tuple, line_tuple], proces);
 
-        let stack_item = process.tuple_from_slice(&[module, function, arity, location]);
+        let stack_item = process.tuple_term_from_term_slice(&[module, function, arity, location]);
 
         let stacktrace = process.list_from_slice(&[stack_item]);
 
         let arc_trace = Trace::from_term(stacktrace);
-        process.exception(exit!(atom!("reason"), arc_trace));
+        process.exception(exit!(Atom::str_to_term("reason").into(), arc_trace));
 
         assert_eq!(result(process), stacktrace);
     })
diff --git a/native_implemented/otp/src/erlang/group_leader_0.rs b/native_implemented/otp/src/erlang/group_leader_0.rs
index 9edbbdfbe..70ac7e498 100644
--- a/native_implemented/otp/src/erlang/group_leader_0.rs
+++ b/native_implemented/otp/src/erlang/group_leader_0.rs
@@ -1,8 +1,8 @@
 #[cfg(test)]
 mod test;
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:group_leader/0)]
 pub fn result(process: &Process) -> Term {
diff --git a/native_implemented/otp/src/erlang/group_leader_2.rs b/native_implemented/otp/src/erlang/group_leader_2.rs
index cf8f43edb..272e5cc09 100644
--- a/native_implemented/otp/src/erlang/group_leader_2.rs
+++ b/native_implemented/otp/src/erlang/group_leader_2.rs
@@ -1,11 +1,13 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
+use std::ptr::NonNull;
+
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Pid, Term};
 
 use crate::runtime::registry::pid_to_process;
 
@@ -16,7 +18,11 @@ macro_rules! is_not_alive {
 }
 
 #[native_implemented::function(erlang:group_leader/2)]
-pub fn result(process: &Process, group_leader: Term, pid: Term) -> exception::Result<Term> {
+pub fn result(
+    process: &Process,
+    group_leader: Term,
+    pid: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     let group_leader_pid: Pid = term_try_into_local_pid!(group_leader)?;
 
     if (group_leader_pid == process.pid()) || pid_to_process(&group_leader_pid).is_some() {
@@ -41,6 +47,6 @@ pub fn result(process: &Process, group_leader: Term, pid: Term) -> exception::Re
     }
 }
 
-fn is_not_alive(name: &'static str, value: Term) -> exception::Result<Term> {
+fn is_not_alive(name: &'static str, value: Term) -> Result<Term, NonNull<ErlangException>> {
     Err(anyhow!("{} ({}) is not alive", name, value)).map_err(From::from)
 }
diff --git a/native_implemented/otp/src/erlang/group_leader_2/test/with_group_leader_pid.rs b/native_implemented/otp/src/erlang/group_leader_2/test/with_group_leader_pid.rs
index 392ed196e..adbae0124 100644
--- a/native_implemented/otp/src/erlang/group_leader_2/test/with_group_leader_pid.rs
+++ b/native_implemented/otp/src/erlang/group_leader_2/test/with_group_leader_pid.rs
@@ -13,7 +13,7 @@ fn without_pid_pid_returns_badarg() {
             )
         },
         |(arc_process, group_leader_arc_process, pid)| {
-            let group_leader = group_leader_arc_process.pid_term();
+            let group_leader = group_leader_arc_process.pid_term().unwrap();
 
             prop_assert_is_not_local_pid!(result(&arc_process, group_leader, pid), pid);
 
diff --git a/native_implemented/otp/src/erlang/group_leader_2/test/with_group_leader_pid/with_pid_pid/with_group_leader_alive/with_other_group_leader.rs b/native_implemented/otp/src/erlang/group_leader_2/test/with_group_leader_pid/with_pid_pid/with_group_leader_alive/with_other_group_leader.rs
index 5c2c065c3..39d1dc70a 100644
--- a/native_implemented/otp/src/erlang/group_leader_2/test/with_group_leader_pid/with_pid_pid/with_group_leader_alive/with_other_group_leader.rs
+++ b/native_implemented/otp/src/erlang/group_leader_2/test/with_group_leader_pid/with_pid_pid/with_group_leader_alive/with_other_group_leader.rs
@@ -13,7 +13,7 @@ fn without_pid_alive_returns_badarg() {
             )
         },
         |(arc_process, group_leader_arc_process, pid)| {
-            let group_leader = group_leader_arc_process.pid_term();
+            let group_leader = group_leader_arc_process.pid_term().unwrap();
 
             prop_assert_badarg!(
                 result(&arc_process, group_leader, pid),
diff --git a/native_implemented/otp/src/erlang/group_leader_2/test/with_group_leader_pid/with_pid_pid/with_group_leader_alive/with_other_group_leader/with_pid_alive.rs b/native_implemented/otp/src/erlang/group_leader_2/test/with_group_leader_pid/with_pid_pid/with_group_leader_alive/with_other_group_leader/with_pid_alive.rs
index 9c12f3f89..d1c97112f 100644
--- a/native_implemented/otp/src/erlang/group_leader_2/test/with_group_leader_pid/with_pid_pid/with_group_leader_alive/with_other_group_leader/with_pid_alive.rs
+++ b/native_implemented/otp/src/erlang/group_leader_2/test/with_group_leader_pid/with_pid_pid/with_group_leader_alive/with_other_group_leader/with_pid_alive.rs
@@ -9,7 +9,7 @@ fn with_self_pid_sets_group_leader() {
             (
                 Just(arc_process.clone()),
                 strategy::process(),
-                Just(arc_process.pid_term()),
+                Just(arc_process.pid_term().unwrap()),
             )
         },
         |(arc_process, group_leader_arc_pid, pid)| {
diff --git a/native_implemented/otp/src/erlang/group_leader_2/test/with_group_leader_pid/with_pid_pid/with_group_leader_alive/with_other_group_leader/with_pid_alive/without_self_pid.rs b/native_implemented/otp/src/erlang/group_leader_2/test/with_group_leader_pid/with_pid_pid/with_group_leader_alive/with_other_group_leader/with_pid_alive/without_self_pid.rs
index 69fbbc829..604f31f16 100644
--- a/native_implemented/otp/src/erlang/group_leader_2/test/with_group_leader_pid/with_pid_pid/with_group_leader_alive/with_other_group_leader/with_pid_alive/without_self_pid.rs
+++ b/native_implemented/otp/src/erlang/group_leader_2/test/with_group_leader_pid/with_pid_pid/with_group_leader_alive/with_other_group_leader/with_pid_alive/without_self_pid.rs
@@ -11,8 +11,8 @@ fn with_different_group_leader_and_pid_sets_group_leader() {
             )
         },
         |(arc_process, group_leader_arc_process, pid_arc_process)| {
-            let group_leader = group_leader_arc_process.pid_term();
-            let pid = pid_arc_process.pid_term();
+            let group_leader = group_leader_arc_process.pid_term().unwrap();
+            let pid = pid_arc_process.pid_term().unwrap();
 
             prop_assert_eq!(result(&arc_process, group_leader, pid), Ok(true.into()));
             prop_assert_eq!(group_leader_0::result(&pid_arc_process), group_leader);
@@ -27,7 +27,7 @@ fn with_same_group_leader_and_pid_sets_group_leader() {
     run!(
         |arc_process| { (Just(arc_process.clone()), strategy::process()) },
         |(arc_process, group_leader_and_pid_arc_process)| {
-            let group_leader = group_leader_and_pid_arc_process.pid_term();
+            let group_leader = group_leader_and_pid_arc_process.pid_term().unwrap();
             let pid = group_leader;
 
             prop_assert_eq!(result(&arc_process, group_leader, pid), Ok(true.into()));
diff --git a/native_implemented/otp/src/erlang/group_leader_2/test/with_group_leader_pid/with_pid_pid/with_group_leader_alive/with_self_group_leader/with_pid_alive.rs b/native_implemented/otp/src/erlang/group_leader_2/test/with_group_leader_pid/with_pid_pid/with_group_leader_alive/with_self_group_leader/with_pid_alive.rs
index 513e25e6a..e94263f2e 100644
--- a/native_implemented/otp/src/erlang/group_leader_2/test/with_group_leader_pid/with_pid_pid/with_group_leader_alive/with_self_group_leader/with_pid_alive.rs
+++ b/native_implemented/otp/src/erlang/group_leader_2/test/with_group_leader_pid/with_pid_pid/with_group_leader_alive/with_self_group_leader/with_pid_alive.rs
@@ -3,8 +3,8 @@ use super::*;
 #[test]
 fn with_self_pid_sets_group_leader() {
     with_process(|process| {
-        let group_leader = process.pid_term();
-        let pid = process.pid_term();
+        let group_leader = process.pid_term().unwrap();
+        let pid = process.pid_term().unwrap();
 
         assert_eq!(result(process, group_leader, pid), Ok(true.into()));
         assert_eq!(group_leader_0::result(process), group_leader);
diff --git a/native_implemented/otp/src/erlang/hd_1.rs b/native_implemented/otp/src/erlang/hd_1.rs
index d595267ae..d15160f7a 100644
--- a/native_implemented/otp/src/erlang/hd_1.rs
+++ b/native_implemented/otp/src/erlang/hd_1.rs
@@ -1,8 +1,10 @@
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::term::prelude::*;
+use std::ptr::NonNull;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::{Cons, Term};
 
 #[native_implemented::function(erlang:hd/1)]
-pub fn result(list: Term) -> exception::Result<Term> {
+pub fn result(list: Term) -> Result<Term, NonNull<ErlangException>> {
     let cons: Boxed<Cons> = term_try_into_non_empty_list!(list)?;
 
     Ok(cons.head)
diff --git a/native_implemented/otp/src/erlang/insert_element_3.rs b/native_implemented/otp/src/erlang/insert_element_3.rs
index 2a6702ee3..59147669e 100644
--- a/native_implemented/otp/src/erlang/insert_element_3.rs
+++ b/native_implemented/otp/src/erlang/insert_element_3.rs
@@ -1,11 +1,13 @@
 use std::convert::TryInto;
+use std::ptr::NonNull;
 
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::index::OneBasedIndex;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_number::TryIntoIntegerError;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::{OneBasedIndex, Term};
 
 use crate::runtime::context::*;
 
@@ -15,7 +17,7 @@ pub fn result(
     index: Term,
     tuple: Term,
     element: Term,
-) -> exception::Result<Term> {
+) -> Result<Term, NonNull<ErlangException>> {
     let initial_inner_tuple = term_try_into_tuple!(tuple)?;
     let length = initial_inner_tuple.len();
     let index_one_based: OneBasedIndex = index
@@ -32,7 +34,7 @@ pub fn result(
             final_element_vec.push(element);
         };
 
-        let final_tuple = process.tuple_from_slice(&final_element_vec);
+        let final_tuple = process.tuple_term_from_term_slice(&final_element_vec);
 
         Ok(final_tuple)
     } else {
diff --git a/native_implemented/otp/src/erlang/integer_to_binary_1.rs b/native_implemented/otp/src/erlang/integer_to_binary_1.rs
index 4e6461278..3102ad153 100644
--- a/native_implemented/otp/src/erlang/integer_to_binary_1.rs
+++ b/native_implemented/otp/src/erlang/integer_to_binary_1.rs
@@ -1,14 +1,14 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::runtime::integer_to_string::decimal_integer_to_string;
 
 #[native_implemented::function(erlang:integer_to_binary/1)]
-pub fn result(process: &Process, integer: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, integer: Term) -> Result<Term, NonNull<ErlangException>> {
     let string = decimal_integer_to_string(integer)?;
     let binary = process.binary_from_str(&string);
 
diff --git a/native_implemented/otp/src/erlang/integer_to_binary_2.rs b/native_implemented/otp/src/erlang/integer_to_binary_2.rs
index f47a3bc6b..3d19396a2 100644
--- a/native_implemented/otp/src/erlang/integer_to_binary_2.rs
+++ b/native_implemented/otp/src/erlang/integer_to_binary_2.rs
@@ -1,14 +1,18 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::runtime::integer_to_string::base_integer_to_string;
 
 #[native_implemented::function(erlang:integer_to_binary/2)]
-pub fn result(process: &Process, integer: Term, base: Term) -> exception::Result<Term> {
+pub fn result(
+    process: &Process,
+    integer: Term,
+    base: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     let string = base_integer_to_string(base, integer)?;
     let binary = process.binary_from_str(&string);
 
diff --git a/native_implemented/otp/src/erlang/integer_to_binary_2/test.rs b/native_implemented/otp/src/erlang/integer_to_binary_2/test.rs
index b7a594f5b..057e1ac16 100644
--- a/native_implemented/otp/src/erlang/integer_to_binary_2/test.rs
+++ b/native_implemented/otp/src/erlang/integer_to_binary_2/test.rs
@@ -3,8 +3,6 @@ mod with_integer_integer;
 use proptest::strategy::Just;
 use proptest::{prop_assert, prop_assert_eq};
 
-use liblumen_alloc::erts::term::prelude::*;
-
 use crate::erlang::integer_to_binary_2::result;
 use crate::test::strategy;
 
diff --git a/native_implemented/otp/src/erlang/integer_to_binary_2/test/with_integer_integer.rs b/native_implemented/otp/src/erlang/integer_to_binary_2/test/with_integer_integer.rs
index e9cd09ef7..e393dd1ed 100644
--- a/native_implemented/otp/src/erlang/integer_to_binary_2/test/with_integer_integer.rs
+++ b/native_implemented/otp/src/erlang/integer_to_binary_2/test/with_integer_integer.rs
@@ -2,6 +2,8 @@ use super::*;
 
 use proptest::arbitrary::any;
 
+use firefly_rt::term::Term;
+
 use crate::erlang::binary_to_integer_2;
 use crate::runtime::binary_to_string::binary_to_string;
 
@@ -21,8 +23,8 @@ fn with_base_base_returns_binary() {
             )
         },
         |(arc_process, integer_isize, base_u8)| {
-            let integer = arc_process.integer(integer_isize);
-            let base = arc_process.integer(base_u8);
+            let integer = arc_process.integer(integer_isize).unwrap();
+            let base = arc_process.integer(base_u8).unwrap();
 
             let result = result(&arc_process, integer, base);
 
@@ -49,16 +51,16 @@ fn with_negative_integer_returns_binary_in_base_with_negative_sign_in_front_of_n
             )
         },
         |(arc_process, negative_isize, base_u8)| {
-            let base = arc_process.integer(base_u8);
+            let base = arc_process.integer(base_u8).unwrap();
 
             let positive_isize = -1 * negative_isize;
-            let positive_integer = arc_process.integer(positive_isize);
+            let positive_integer = arc_process.integer(positive_isize).unwrap();
             let positive_binary = result(&arc_process, positive_integer, base).unwrap();
             let positive_string: String = binary_to_string(positive_binary).unwrap();
             let expected_negative_string = format!("-{}", positive_string);
             let expected_negative_binary = arc_process.binary_from_str(&expected_negative_string);
 
-            let negative_integer = arc_process.integer(negative_isize);
+            let negative_integer = arc_process.integer(negative_isize).unwrap();
 
             let result = result(&arc_process, negative_integer, base);
 
diff --git a/native_implemented/otp/src/erlang/integer_to_list_1.rs b/native_implemented/otp/src/erlang/integer_to_list_1.rs
index 6b1b19f34..9d882bb1e 100644
--- a/native_implemented/otp/src/erlang/integer_to_list_1.rs
+++ b/native_implemented/otp/src/erlang/integer_to_list_1.rs
@@ -1,14 +1,14 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::runtime::integer_to_string::decimal_integer_to_string;
 
 #[native_implemented::function(erlang:integer_to_list/1)]
-pub fn result(process: &Process, integer: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, integer: Term) -> Result<Term, NonNull<ErlangException>> {
     let string = decimal_integer_to_string(integer)?;
     let charlist = process.charlist_from_str(&string);
 
diff --git a/native_implemented/otp/src/erlang/integer_to_list_2.rs b/native_implemented/otp/src/erlang/integer_to_list_2.rs
index 71557f5dc..4b7614a51 100644
--- a/native_implemented/otp/src/erlang/integer_to_list_2.rs
+++ b/native_implemented/otp/src/erlang/integer_to_list_2.rs
@@ -1,14 +1,18 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::runtime::integer_to_string::base_integer_to_string;
 
 #[native_implemented::function(erlang:integer_to_list/2)]
-pub fn result(process: &Process, integer: Term, base: Term) -> exception::Result<Term> {
+pub fn result(
+    process: &Process,
+    integer: Term,
+    base: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     let string = base_integer_to_string(base, integer)?;
     let charlist = process.charlist_from_str(&string);
 
diff --git a/native_implemented/otp/src/erlang/integer_to_list_2/test.rs b/native_implemented/otp/src/erlang/integer_to_list_2/test.rs
index 34f8f756c..64e75e60f 100644
--- a/native_implemented/otp/src/erlang/integer_to_list_2/test.rs
+++ b/native_implemented/otp/src/erlang/integer_to_list_2/test.rs
@@ -1,10 +1,13 @@
 mod with_integer_integer;
 
 use proptest::{prop_assert, prop_assert_eq};
+use proptest::arbitrary::any;
+use proptest::strategy::Just;
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 use crate::erlang::integer_to_list_2::result;
+use crate::erlang::list_to_string::list_to_string;
 use crate::test::strategy;
 
 #[test]
diff --git a/native_implemented/otp/src/erlang/integer_to_list_2/test/with_integer_integer.rs b/native_implemented/otp/src/erlang/integer_to_list_2/test/with_integer_integer.rs
index 9681f8a88..6696e17dd 100644
--- a/native_implemented/otp/src/erlang/integer_to_list_2/test/with_integer_integer.rs
+++ b/native_implemented/otp/src/erlang/integer_to_list_2/test/with_integer_integer.rs
@@ -1,8 +1,5 @@
 use super::*;
 
-use crate::erlang::list_to_string::list_to_string;
-use proptest::arbitrary::any;
-use proptest::strategy::{Just, Strategy};
 
 #[test]
 fn without_base_base_errors_badarg() {
@@ -20,8 +17,8 @@ fn with_base_base_returns_list() {
             )
         },
         |(arc_process, integer_isize, base_u8)| {
-            let integer = arc_process.integer(integer_isize);
-            let base = arc_process.integer(base_u8);
+            let integer = arc_process.integer(integer_isize).unwrap();
+            let base = arc_process.integer(base_u8).unwrap();
 
             let result = result(&arc_process, integer, base);
 
@@ -54,16 +51,16 @@ fn with_negative_integer_returns_list_in_base_with_negative_sign_in_front_of_non
                 })
         },
         |(arc_process, negative_isize, base_u8)| {
-            let base = arc_process.integer(base_u8);
+            let base = arc_process.integer(base_u8).unwrap();
 
             let positive_isize = -1 * negative_isize;
-            let positive_integer = arc_process.integer(positive_isize);
+            let positive_integer = arc_process.integer(positive_isize).unwrap();
             let positive_list = result(&arc_process, positive_integer, base).unwrap();
             let positive_string: String = list_to_string(positive_list).unwrap();
             let expected_negative_string = format!("-{}", positive_string);
             let expected_negative_list = arc_process.charlist_from_str(&expected_negative_string);
 
-            let negative_integer = arc_process.integer(negative_isize);
+            let negative_integer = arc_process.integer(negative_isize).unwrap();
 
             let result = result(&arc_process, negative_integer, base);
 
diff --git a/native_implemented/otp/src/erlang/iolist_or_binary.rs b/native_implemented/otp/src/erlang/iolist_or_binary.rs
index 4dc74bb6b..debbfb993 100644
--- a/native_implemented/otp/src/erlang/iolist_or_binary.rs
+++ b/native_implemented/otp/src/erlang/iolist_or_binary.rs
@@ -1,10 +1,11 @@
 use std::convert::TryInto;
+use std::ptr::NonNull;
 
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::runtime::context::{r#type, term_is_not_type};
 
@@ -27,16 +28,15 @@ pub fn element_type_context(iolist_or_binary: Term, element: Term) -> String {
 pub fn result(
     process: &Process,
     iolist_or_binary: Term,
-    try_into: fn(&Process, Term) -> exception::Result<Term>,
-) -> exception::Result<Term> {
-    match iolist_or_binary.decode()? {
-        TypedTerm::Nil
-        | TypedTerm::List(_)
-        | TypedTerm::BinaryLiteral(_)
-        | TypedTerm::HeapBinary(_)
-        | TypedTerm::MatchContext(_)
-        | TypedTerm::ProcBin(_)
-        | TypedTerm::SubBinary(_) => try_into(process, iolist_or_binary),
+    try_into: fn(&Process, Term) -> Result<Term, NonNull<ErlangException>>,
+) -> Result<Term, NonNull<ErlangException>> {
+    match iolist_or_binary {
+        Term::Nil
+        | Term::Cons(_)
+        | Term::ConstantBinary(_)
+        | Term::HeapBinary(_)
+        | Term::RcBinary(_)
+        | Term::RefBinary(_) => try_into(process, iolist_or_binary),
         _ => Err(TypeError)
             .context(term_is_not_type(
                 "iolist_or_binary",
@@ -47,26 +47,31 @@ pub fn result(
     }
 }
 
-pub fn to_binary(process: &Process, name: &'static str, value: Term) -> exception::Result<Term> {
+pub fn to_binary(
+    process: &Process,
+    name: &'static str,
+    value: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     let mut byte_vec: Vec<u8> = Vec::new();
     let mut stack: Vec<Term> = vec![value];
 
     while let Some(top) = stack.pop() {
-        match top.decode()? {
-            TypedTerm::SmallInteger(small_integer) => {
+        match top {
+            Term::Int(small_integer) => {
                 let top_byte = small_integer
                     .try_into()
                     .with_context(|| element_context(name, value, top))?;
 
                 byte_vec.push(top_byte);
             }
-            TypedTerm::Nil => (),
-            TypedTerm::List(boxed_cons) => {
+            Term::Nil => (),
+            Term::Cons(non_null_cons) => {
+                let cons = unsafe { non_null_cons.as_ref() };
                 // @type iolist :: maybe_improper_list(byte() | binary() | iolist(),
                 // binary() | []) means that `byte()` isn't allowed
                 // for `tail`s unlike `head`.
 
-                let tail = boxed_cons.tail;
+                let tail = cons.tail();
                 let result_u8: Result<u8, _> = tail.try_into();
 
                 match result_u8 {
@@ -81,12 +86,12 @@ pub fn to_binary(process: &Process, name: &'static str, value: Term) -> exceptio
                     Err(_) => stack.push(tail),
                 };
 
-                stack.push(boxed_cons.head);
+                stack.push(cons.head());
             }
-            TypedTerm::HeapBinary(heap_binary) => {
+            Term::HeapBinary(heap_binary) => {
                 byte_vec.extend_from_slice(heap_binary.as_bytes());
             }
-            TypedTerm::SubBinary(subbinary) => {
+            Term::RefBinary(subbinary) => {
                 if subbinary.is_binary() {
                     if subbinary.is_aligned() {
                         byte_vec.extend(unsafe { subbinary.as_bytes_unchecked() });
@@ -99,7 +104,7 @@ pub fn to_binary(process: &Process, name: &'static str, value: Term) -> exceptio
                         .map_err(From::from);
                 }
             }
-            TypedTerm::ProcBin(procbin) => {
+            Term::RcBinary(procbin) => {
                 byte_vec.extend_from_slice(procbin.as_bytes());
             }
             _ => {
diff --git a/native_implemented/otp/src/erlang/iolist_size_1.rs b/native_implemented/otp/src/erlang/iolist_size_1.rs
index 4acfc6feb..118c17175 100644
--- a/native_implemented/otp/src/erlang/iolist_size_1.rs
+++ b/native_implemented/otp/src/erlang/iolist_size_1.rs
@@ -2,41 +2,46 @@
 mod test;
 
 use std::convert::TryInto;
+use std::ptr::NonNull;
 
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::iolist_or_binary::{self, *};
 
 /// Returns the size, in bytes, of the binary that would be result from iolist_to_binary/1
 #[native_implemented::function(erlang:iolist_size/1)]
-pub fn result(process: &Process, iolist_or_binary: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, iolist_or_binary: Term) -> Result<Term, NonNull<ErlangException>> {
     iolist_or_binary::result(process, iolist_or_binary, iolist_or_binary_size)
 }
 
-fn iolist_or_binary_size(process: &Process, iolist_or_binary: Term) -> exception::Result<Term> {
+fn iolist_or_binary_size(
+    process: &Process,
+    iolist_or_binary: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     let mut size: usize = 0;
     let mut stack: Vec<Term> = vec![iolist_or_binary];
 
     while let Some(top) = stack.pop() {
-        match top.decode()? {
-            TypedTerm::SmallInteger(small_integer) => {
+        match top {
+            Term::Int(small_integer) => {
                 let _: u8 = small_integer
                     .try_into()
                     .with_context(|| element_type_context(iolist_or_binary, top))?;
 
                 size += 1;
             }
-            TypedTerm::Nil => (),
-            TypedTerm::List(boxed_cons) => {
+            Term::Nil => (),
+            Term::Cons(non_null_cons) => {
+                let cons = unsafe { non_null_cons.as_ref() };
                 // @type iolist :: maybe_improper_list(byte() | binary() | iolist(),
                 // binary() | []) means that `byte()` isn't allowed
                 // for `tail`s unlike `head`.
 
-                let tail = boxed_cons.tail;
+                let tail = cons.tail();
                 let result_u8: Result<u8, _> = tail.try_into();
 
                 match result_u8 {
@@ -51,20 +56,11 @@ fn iolist_or_binary_size(process: &Process, iolist_or_binary: Term) -> exception
                     Err(_) => stack.push(tail),
                 };
 
-                stack.push(boxed_cons.head);
+                stack.push(cons.head());
             }
-            TypedTerm::HeapBinary(heap_binary) => size += heap_binary.full_byte_len(),
-            TypedTerm::MatchContext(match_context) => {
-                if match_context.is_binary() {
-                    size += match_context.full_byte_len();
-                } else {
-                    return Err(NotABinary)
-                        .context(element_not_a_binary_context(iolist_or_binary, top))
-                        .map_err(From::from);
-                }
-            }
-            TypedTerm::ProcBin(proc_bin) => size += proc_bin.total_byte_len(),
-            TypedTerm::SubBinary(subbinary) => {
+            Term::HeapBinary(heap_binary) => size += heap_binary.full_byte_len(),
+            Term::RcBinary(proc_bin) => size += proc_bin.total_byte_len(),
+            Term::RefBinary(subbinary) => {
                 if subbinary.is_binary() {
                     size += subbinary.full_byte_len();
                 } else {
@@ -81,5 +77,5 @@ fn iolist_or_binary_size(process: &Process, iolist_or_binary: Term) -> exception
         }
     }
 
-    Ok(process.integer(size))
+    Ok(process.integer(size).unwrap())
 }
diff --git a/native_implemented/otp/src/erlang/iolist_size_1/test.rs b/native_implemented/otp/src/erlang/iolist_size_1/test.rs
index 5df9b7fc1..98097df6a 100644
--- a/native_implemented/otp/src/erlang/iolist_size_1/test.rs
+++ b/native_implemented/otp/src/erlang/iolist_size_1/test.rs
@@ -3,8 +3,8 @@ use std::sync::Arc;
 use proptest::strategy::{BoxedStrategy, Just, Strategy};
 use proptest::{prop_assert, prop_oneof};
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::iolist_size_1::result;
 use crate::test::strategy::term::*;
@@ -44,7 +44,7 @@ fn with_iolist_or_binary_returns_non_negative_integer() {
             let size = result.unwrap();
 
             prop_assert!(size.is_integer());
-            prop_assert!(size >= arc_process.integer(0));
+            prop_assert!(size >= arc_process.integer(0).unwrap());
 
             Ok(())
         }
@@ -57,11 +57,11 @@ fn with_iolist_or_binary_returns_non_negative_integer() {
 fn otp_doctest() {
     with_process(|process| {
         let iolist = process.improper_list_from_slice(
-            &[process.integer(1), process.integer(2)],
+            &[process.integer(1).unwrap(), process.integer(2).unwrap()],
             process.binary_from_bytes(&[3, 4]),
         );
 
-        assert_eq!(result(process, iolist), Ok(process.integer(4)))
+        assert_eq!(result(process, iolist), Ok(process.integer(4).unwrap()))
     });
 }
 
@@ -83,14 +83,14 @@ fn with_iolist_returns_size() {
         let iolist = process.improper_list_from_slice(
             &[
                 bin1,
-                process.integer(1),
-                process.list_from_slice(&[process.integer(2), process.integer(3), bin2]),
-                process.integer(4),
+                process.integer(1).unwrap(),
+                process.list_from_slice(&[process.integer(2).unwrap(), process.integer(3).unwrap(), bin2]).unwrap(),
+                process.integer(4).unwrap(),
             ],
             bin3,
         );
 
-        assert_eq!(result(process, iolist), Ok(process.integer(10)))
+        assert_eq!(result(process, iolist), Ok(process.integer(10).unwrap()))
     });
 }
 
@@ -99,7 +99,7 @@ fn with_binary_returns_size() {
     with_process(|process| {
         let bin = process.binary_from_bytes(&[1, 2, 3]);
 
-        assert_eq!(result(process, bin), Ok(process.integer(3)))
+        assert_eq!(result(process, bin), Ok(process.integer(3).unwrap()))
     });
 }
 
@@ -114,7 +114,7 @@ fn with_subbinary_in_list_returns_size() {
             0,
         )]);
 
-        assert_eq!(result(process, iolist), Ok(process.integer(3)))
+        assert_eq!(result(process, iolist), Ok(process.integer(3).unwrap()))
     });
 }
 
@@ -129,7 +129,7 @@ fn with_subbinary_returns_size() {
             0,
         );
 
-        assert_eq!(result(process, iolist), Ok(process.integer(3)))
+        assert_eq!(result(process, iolist), Ok(process.integer(3).unwrap()))
     });
 }
 
@@ -140,16 +140,16 @@ fn with_procbin_returns_size() {
         let procbin = process.binary_from_bytes(&bytes);
         // We expect this to be a procbin, since it's > 64 bytes. Make sure it is.
         assert!(procbin.is_boxed_procbin());
-        let iolist = process.list_from_slice(&[procbin]);
+        let iolist = process.list_from_slice(&[procbin]).unwrap();
 
-        assert_eq!(result(process, iolist), Ok(process.integer(65)))
+        assert_eq!(result(process, iolist), Ok(process.integer(65).unwrap()))
     });
 }
 
 #[test]
 fn with_improper_list_smallint_tail_errors_badarg() {
     with_process(|process| {
-        let tail = process.integer(42);
+        let tail = process.integer(42).unwrap();
         let iolist =
             process.improper_list_from_slice(&[process.binary_from_bytes(&[1, 2, 3])], tail);
 
@@ -171,7 +171,7 @@ pub fn is_not_list_or_bitstring(arc_process: Arc<Process>) -> BoxedStrategy<Term
         integer::big(arc_process.clone()),
         local_reference(arc_process.clone()),
         is_function(arc_process.clone()),
-        float(arc_process.clone()),
+        float(),
         // TODO `Export`
         // TODO `ReferenceCountedBinary`
         pid::external(arc_process.clone()),
diff --git a/native_implemented/otp/src/erlang/iolist_to_binary_1.rs b/native_implemented/otp/src/erlang/iolist_to_binary_1.rs
index e2ba2a192..bf84a398f 100644
--- a/native_implemented/otp/src/erlang/iolist_to_binary_1.rs
+++ b/native_implemented/otp/src/erlang/iolist_to_binary_1.rs
@@ -1,19 +1,21 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use std::ptr::NonNull;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang;
 
 /// Returns a binary that is made from the integers and binaries given in iolist
 #[native_implemented::function(erlang:iolist_to_binary/1)]
-pub fn result(process: &Process, iolist_or_binary: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, iolist_or_binary: Term) -> Result<Term, NonNull<ErlangException>> {
     erlang::list_to_binary_1::result(
         process,
         if iolist_or_binary.is_binary() {
-            process.list_from_slice(&[iolist_or_binary])
+            process.list_from_slice(&[iolist_or_binary]).unwrap()
         } else {
             iolist_or_binary
         },
diff --git a/native_implemented/otp/src/erlang/iolist_to_binary_1/test.rs b/native_implemented/otp/src/erlang/iolist_to_binary_1/test.rs
index 52124faad..f34f5e430 100644
--- a/native_implemented/otp/src/erlang/iolist_to_binary_1/test.rs
+++ b/native_implemented/otp/src/erlang/iolist_to_binary_1/test.rs
@@ -1,7 +1,7 @@
 use proptest::prop_assert;
 use proptest::strategy::Just;
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::{Atom, Term};
 
 use crate::erlang::iolist_to_binary_1::result;
 use crate::test::strategy::term::is_iolist_or_binary;
@@ -43,9 +43,9 @@ fn otp_doctest_returns_binary() {
         let iolist = process.improper_list_from_slice(
             &[
                 bin1,
-                process.integer(1),
-                process.list_from_slice(&[process.integer(2), process.integer(3), bin2]),
-                process.integer(4),
+                process.integer(1).unwrap(),
+                process.list_from_slice(&[process.integer(2).unwrap(), process.integer(3).unwrap(), bin2]).unwrap(),
+                process.integer(4).unwrap(),
             ],
             bin3,
         );
@@ -76,7 +76,7 @@ fn with_procbin_in_list_returns_binary() {
         let procbin = process.binary_from_bytes(&bytes);
         // We expect this to be a procbin, since it's > 64 bytes. Make sure it is.
         assert!(procbin.is_boxed_procbin());
-        let iolist = process.list_from_slice(&[procbin]);
+        let iolist = process.list_from_slice(&[procbin]).unwrap();
 
         assert_eq!(
             result(process, iolist),
@@ -124,7 +124,7 @@ fn with_subbinary_returns_binary() {
 #[test]
 fn with_improper_list_smallint_tail_errors_badarg() {
     with_process(|process| {
-        let tail = process.integer(42);
+        let tail = process.integer(42).unwrap();
         let iolist = process.improper_list_from_slice(
             &[process.subbinary_from_original(
                 process.binary_from_bytes(&[1, 2, 3, 4, 5]),
@@ -148,7 +148,7 @@ fn with_improper_list_smallint_tail_errors_badarg() {
 fn with_atom_in_iolist_errors_badarg() {
     with_process(|process| {
         let element = Atom::str_to_term("foo");
-        let iolist = process.list_from_slice(&[element]);
+        let iolist = process.list_from_slice(&[element]).unwrap();
 
         assert_badarg!(
             result(process, iolist),
diff --git a/native_implemented/otp/src/erlang/iolist_to_iovec_1.rs b/native_implemented/otp/src/erlang/iolist_to_iovec_1.rs
index cf6d39e80..c9e6cbbe9 100644
--- a/native_implemented/otp/src/erlang/iolist_to_iovec_1.rs
+++ b/native_implemented/otp/src/erlang/iolist_to_iovec_1.rs
@@ -1,23 +1,25 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use std::ptr::NonNull;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::iolist_or_binary;
 
 /// Returns a binary that is made from the integers and binaries given in iolist
 #[native_implemented::function(erlang:iolist_to_iovec/1)]
-pub fn result(process: &Process, iolist_or_binary: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, iolist_or_binary: Term) -> Result<Term, NonNull<ErlangException>> {
     iolist_or_binary::result(process, iolist_or_binary, iolist_or_binary_to_iovec)
 }
 
 pub fn iolist_or_binary_to_iovec(
     process: &Process,
     iolist_or_binary: Term,
-) -> exception::Result<Term> {
+) -> Result<Term, NonNull<ErlangException>> {
     let binary = iolist_or_binary::to_binary(process, "iolist_or_binary", iolist_or_binary)?;
 
-    Ok(process.list_from_slice(&[binary]))
+    Ok(process.list_from_slice(&[binary])).unwrap()
 }
diff --git a/native_implemented/otp/src/erlang/iolist_to_iovec_1/test.rs b/native_implemented/otp/src/erlang/iolist_to_iovec_1/test.rs
index dd81272d7..c153a7858 100644
--- a/native_implemented/otp/src/erlang/iolist_to_iovec_1/test.rs
+++ b/native_implemented/otp/src/erlang/iolist_to_iovec_1/test.rs
@@ -1,9 +1,7 @@
-use std::convert::TryInto;
-
 use proptest::strategy::Just;
 use proptest::{prop_assert, prop_assert_eq};
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 use crate::erlang::iolist_to_iovec_1::result;
 use crate::test::strategy::term::is_iolist_or_binary;
@@ -71,7 +69,7 @@ fn with_binary_returns_binary_in_list() {
 
         assert_eq!(
             result(process, bin),
-            Ok(process.list_from_slice(&[process.binary_from_bytes(&[1, 2, 3])]))
+            Ok(process.list_from_slice(&[process.binary_from_bytes(&[1, 2, 3])]).unwrap())
         )
     });
 }
@@ -83,11 +81,11 @@ fn with_procbin_in_list_returns_list() {
         let procbin = process.binary_from_bytes(&bytes);
         // We expect this to be a procbin, since it's > 64 bytes. Make sure it is.
         assert!(procbin.is_boxed_procbin());
-        let iolist = process.list_from_slice(&[procbin]);
+        let iolist = process.list_from_slice(&[procbin]).unwrap();
 
         assert_eq!(
             result(process, iolist),
-            Ok(process.list_from_slice(&[process.binary_from_bytes(&bytes)]))
+            Ok(process.list_from_slice(&[process.binary_from_bytes(&bytes)])).unwrap()
         )
     });
 }
@@ -105,7 +103,7 @@ fn with_subbinary_in_list_returns_list() {
 
         assert_eq!(
             result(process, iolist),
-            Ok(process.list_from_slice(&[process.binary_from_bytes(&[2, 3, 4])]))
+            Ok(process.list_from_slice(&[process.binary_from_bytes(&[2, 3, 4])]).unwrap())
         )
     });
 }
@@ -123,7 +121,7 @@ fn with_subbinary_returns_list() {
 
         assert_eq!(
             result(process, iolist),
-            Ok(process.list_from_slice(&[process.binary_from_bytes(&[2, 3, 4])]))
+            Ok(process.list_from_slice(&[process.binary_from_bytes(&[2, 3, 4])]).unwrap())
         )
     });
 }
@@ -131,7 +129,7 @@ fn with_subbinary_returns_list() {
 #[test]
 fn with_improper_list_smallint_tail_errors_badarg() {
     with_process(|process| {
-        let tail = process.integer(42);
+        let tail = process.integer(42).unwrap();
         let iolist_or_binary =
             process.improper_list_from_slice(&[process.binary_from_bytes(&[1, 2, 3])], tail);
 
@@ -150,7 +148,7 @@ fn with_improper_list_smallint_tail_errors_badarg() {
 fn with_atom_in_iolist_errors_badarg() {
     with_process(|process| {
         let element = Atom::str_to_term("foo");
-        let iolist_or_binary = process.list_from_slice(&[element]);
+        let iolist_or_binary = process.list_from_slice(&[element]).unwrap();
 
         assert_badarg!(
             result(process, iolist_or_binary),
diff --git a/native_implemented/otp/src/erlang/is_alive_0.rs b/native_implemented/otp/src/erlang/is_alive_0.rs
index c56e8f953..fbc5504fb 100644
--- a/native_implemented/otp/src/erlang/is_alive_0.rs
+++ b/native_implemented/otp/src/erlang/is_alive_0.rs
@@ -1,4 +1,4 @@
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::term::Term;
 
 /// Distribution is not supported at this time.  Always returns `false`.
 #[native_implemented::function(erlang:is_alive/0)]
diff --git a/native_implemented/otp/src/erlang/is_atom_1.rs b/native_implemented/otp/src/erlang/is_atom_1.rs
index 4b4a38447..51643e64c 100644
--- a/native_implemented/otp/src/erlang/is_atom_1.rs
+++ b/native_implemented/otp/src/erlang/is_atom_1.rs
@@ -1,4 +1,4 @@
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:is_atom/1)]
 pub fn result(term: Term) -> Term {
diff --git a/native_implemented/otp/src/erlang/is_binary_1.rs b/native_implemented/otp/src/erlang/is_binary_1.rs
index eef14ea32..5427e7bd3 100644
--- a/native_implemented/otp/src/erlang/is_binary_1.rs
+++ b/native_implemented/otp/src/erlang/is_binary_1.rs
@@ -1,4 +1,4 @@
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:is_binary/1)]
 pub fn result(term: Term) -> Term {
diff --git a/native_implemented/otp/src/erlang/is_bitstring_1.rs b/native_implemented/otp/src/erlang/is_bitstring_1.rs
index 43bdea983..a0e29ca36 100644
--- a/native_implemented/otp/src/erlang/is_bitstring_1.rs
+++ b/native_implemented/otp/src/erlang/is_bitstring_1.rs
@@ -1,7 +1,7 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:is_bitstring/1)]
 pub fn result(term: Term) -> Term {
diff --git a/native_implemented/otp/src/erlang/is_boolean_1.rs b/native_implemented/otp/src/erlang/is_boolean_1.rs
index f5cefec3c..99d316f27 100644
--- a/native_implemented/otp/src/erlang/is_boolean_1.rs
+++ b/native_implemented/otp/src/erlang/is_boolean_1.rs
@@ -1,4 +1,4 @@
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:is_boolean/1)]
 pub fn result(term: Term) -> Term {
diff --git a/native_implemented/otp/src/erlang/is_equal_or_less_than_2.rs b/native_implemented/otp/src/erlang/is_equal_or_less_than_2.rs
index 9a9f4e882..bfd73de8b 100644
--- a/native_implemented/otp/src/erlang/is_equal_or_less_than_2.rs
+++ b/native_implemented/otp/src/erlang/is_equal_or_less_than_2.rs
@@ -1,7 +1,7 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::term::Term;
 
 /// `=</2` infix operator.  Floats and integers are converted.
 ///
diff --git a/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test.rs b/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test.rs
index 55cc19b57..e293bf824 100644
--- a/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test.rs
+++ b/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test.rs
@@ -18,8 +18,8 @@ use proptest::prop_assert_eq;
 use proptest::strategy::BoxedStrategy;
 use proptest::test_runner::{Config, TestRunner};
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Atom, Integer, Term};
 
 use crate::erlang::is_equal_or_less_than_2::result;
 use crate::test::{external_arc_node, strategy};
diff --git a/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_atom_left.rs b/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_atom_left.rs
index fa6892a31..d927a88b8 100644
--- a/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_atom_left.rs
+++ b/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_atom_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn with_number_returns_false() {
     run!(
diff --git a/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_big_integer_left.rs b/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_big_integer_left.rs
index 2be048f99..92407cd6e 100644
--- a/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_big_integer_left.rs
+++ b/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_big_integer_left.rs
@@ -2,14 +2,14 @@ use super::*;
 
 #[test]
 fn with_lesser_small_integer_right_returns_false() {
-    is_equal_or_less_than(|_, process| process.integer(0), false)
+    is_equal_or_less_than(|_, process| process.integer(0).unwrap(), false)
 }
 
 #[test]
 fn with_greater_small_integer_right_returns_true() {
     super::is_equal_or_less_than(
-        |process| process.integer(SmallInteger::MIN_VALUE - 1),
-        |_, process| process.integer(SmallInteger::MIN_VALUE),
+        |process| process.integer(Integer::MIN_SMALL - 1).unwrap(),
+        |_, process| process.integer(Integer::MIN_SMALL).unwrap(),
         true,
     );
 }
@@ -17,7 +17,7 @@ fn with_greater_small_integer_right_returns_true() {
 #[test]
 fn with_lesser_big_integer_right_returns_false() {
     is_equal_or_less_than(
-        |_, process| process.integer(SmallInteger::MIN_VALUE - 1),
+        |_, process| process.integer(Integer::MIN_SMALL - 1).unwrap(),
         false,
     )
 }
@@ -25,7 +25,7 @@ fn with_lesser_big_integer_right_returns_false() {
 #[test]
 fn with_same_value_big_integer_right_returns_true() {
     is_equal_or_less_than(
-        |_, process| process.integer(SmallInteger::MAX_VALUE + 1),
+        |_, process| process.integer(Integer::MAX_SMALL + 1).unwrap(),
         true,
     )
 }
@@ -33,21 +33,21 @@ fn with_same_value_big_integer_right_returns_true() {
 #[test]
 fn with_greater_big_integer_right_returns_true() {
     is_equal_or_less_than(
-        |_, process| process.integer(SmallInteger::MAX_VALUE + 2),
+        |_, process| process.integer(Integer::MAX_SMALL + 2).unwrap(),
         true,
     )
 }
 
 #[test]
 fn with_lesser_float_right_returns_false() {
-    is_equal_or_less_than(|_, process| process.float(1.0), false)
+    is_equal_or_less_than(|_, process| 1.0.into(), false)
 }
 
 #[test]
 fn with_greater_float_right_returns_true() {
     super::is_equal_or_less_than(
-        |process| process.integer(SmallInteger::MIN_VALUE - 1),
-        |_, process| process.float(1.0),
+        |process| process.integer(Integer::MIN_SMALL - 1).unwrap(),
+        |_, process| 1.0.into(),
         true,
     );
 }
@@ -74,7 +74,7 @@ where
     R: FnOnce(Term, &Process) -> Term,
 {
     super::is_equal_or_less_than(
-        |process| process.integer(SmallInteger::MAX_VALUE + 1),
+        |process| process.integer(Integer::MAX_SMALL + 1).unwrap(),
         right,
         expected,
     );
diff --git a/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_empty_list_left.rs b/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_empty_list_left.rs
index b20cfd99c..12f4474ce 100644
--- a/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_empty_list_left.rs
+++ b/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_empty_list_left.rs
@@ -1,7 +1,6 @@
 use super::*;
 
 use proptest::prop_oneof;
-use proptest::strategy::Strategy;
 
 #[test]
 fn without_list_or_bitstring_returns_false() {
@@ -13,7 +12,7 @@ fn without_list_or_bitstring_returns_false() {
                 })
         },
         |right| {
-            let left = Term::NIL;
+            let left = Term::Nil;
 
             prop_assert_eq!(result(left, right), false.into());
 
@@ -29,7 +28,7 @@ fn with_list_or_bitstring_right_returns_true() {
             &strategy::process()
                 .prop_flat_map(|arc_process| list_or_bitstring(arc_process.clone())),
             |right| {
-                let left = Term::NIL;
+                let left = Term::Nil;
 
                 prop_assert_eq!(result(left, right), true.into());
 
diff --git a/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_float_left.rs b/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_float_left.rs
index ebe77346a..ea20f4553 100644
--- a/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_float_left.rs
+++ b/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_float_left.rs
@@ -2,23 +2,23 @@ use super::*;
 
 #[test]
 fn with_lesser_small_integer_right_returns_false() {
-    is_equal_or_less_than(|_, process| process.integer(-1), false)
+    is_equal_or_less_than(|_, process| process.integer(-1).unwrap(), false)
 }
 
 #[test]
 fn with_equal_small_integer_right_returns_true() {
-    is_equal_or_less_than(|_, process| process.integer(1), true)
+    is_equal_or_less_than(|_, process| process.integer(1).unwrap(), true)
 }
 
 #[test]
 fn with_greater_small_integer_right_returns_true() {
-    is_equal_or_less_than(|_, process| process.integer(2), true)
+    is_equal_or_less_than(|_, process| process.integer(2).unwrap(), true)
 }
 
 #[test]
 fn with_lesser_big_integer_right_returns_false() {
     is_equal_or_less_than(
-        |_, process| process.integer(SmallInteger::MIN_VALUE - 1),
+        |_, process| process.integer(Integer::MIN_SMALL - 1).unwrap(),
         false,
     )
 }
@@ -26,24 +26,24 @@ fn with_lesser_big_integer_right_returns_false() {
 #[test]
 fn with_greater_big_integer_right_returns_true() {
     is_equal_or_less_than(
-        |_, process| process.integer(SmallInteger::MAX_VALUE + 1),
+        |_, process| process.integer(Integer::MAX_SMALL + 1).unwrap(),
         true,
     )
 }
 
 #[test]
 fn with_lesser_float_right_returns_false() {
-    is_equal_or_less_than(|_, process| process.float(-1.0), false)
+    is_equal_or_less_than(|_, process| -1.0.into(), false)
 }
 
 #[test]
 fn with_equal_float_right_returns_true() {
-    is_equal_or_less_than(|_, process| process.float(1.0), true)
+    is_equal_or_less_than(|_, process| 1.0.into(), true)
 }
 
 #[test]
 fn with_greater_float_right_returns_true() {
-    is_equal_or_less_than(|_, process| process.float(2.0), true)
+    is_equal_or_less_than(|_, process| 2.0.into(), true)
 }
 
 #[test]
@@ -51,7 +51,7 @@ fn without_number_returns_true() {
     run!(
         |arc_process| {
             (
-                strategy::term::float(arc_process.clone()),
+                strategy::term::float(),
                 strategy::term::is_not_number(arc_process.clone()),
             )
         },
@@ -67,5 +67,5 @@ fn is_equal_or_less_than<R>(right: R, expected: bool)
 where
     R: FnOnce(Term, &Process) -> Term,
 {
-    super::is_equal_or_less_than(|process| process.float(1.0), right, expected);
+    super::is_equal_or_less_than(|process| 1.0.into(), right, expected);
 }
diff --git a/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_heap_binary_left.rs b/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_heap_binary_left.rs
index 4cf798193..f4a7e3566 100644
--- a/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_heap_binary_left.rs
+++ b/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_heap_binary_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn with_number_atom_reference_function_port_pid_tuple_map_or_list_returns_false() {
     run!(
@@ -13,10 +11,10 @@ fn with_number_atom_reference_function_port_pid_tuple_map_or_list_returns_false(
                             right.is_number() ||
                                 right.is_atom() ||
                                 right.is_reference() ||
-                                right.is_boxed_function() ||
+                                right.is_closure() ||
                                 right.is_port() ||
                                 right.is_pid() ||
-                                right.is_boxed_tuple() ||
+                                right.is_tuple() ||
                                 right.is_list()
                         }),
                 )
diff --git a/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_list_left.rs b/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_list_left.rs
index df0d55ec1..cd31041ea 100644
--- a/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_list_left.rs
+++ b/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_list_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_list_or_bitstring_returns_false() {
     run!(
@@ -24,13 +22,13 @@ fn without_list_or_bitstring_returns_false() {
 
 #[test]
 fn with_empty_list_right_returns_false() {
-    is_equal_or_less_than(|_, _| Term::NIL, false);
+    is_equal_or_less_than(|_, _| Term::Nil, false);
 }
 
 #[test]
 fn with_lesser_list_right_returns_false() {
     is_equal_or_less_than(
-        |_, process| process.cons(process.integer(0), process.integer(0)),
+        |_, process| process.cons(process.integer(0).unwrap(), process.integer(0).unwrap()),
         false,
     );
 }
@@ -43,7 +41,7 @@ fn with_same_list_right_returns_true() {
 #[test]
 fn with_same_value_list_right_returns_true() {
     is_equal_or_less_than(
-        |_, process| process.cons(process.integer(0), process.integer(1)),
+        |_, process| process.cons(process.integer(0).unwrap(), process.integer(1).unwrap()),
         true,
     );
 }
@@ -51,7 +49,7 @@ fn with_same_value_list_right_returns_true() {
 #[test]
 fn with_greater_list_right_returns_true() {
     is_equal_or_less_than(
-        |_, process| process.cons(process.integer(0), process.integer(2)),
+        |_, process| process.cons(process.integer(0).unwrap(), process.integer(2).unwrap()),
         true,
     );
 }
@@ -78,7 +76,7 @@ where
     R: FnOnce(Term, &Process) -> Term,
 {
     super::is_equal_or_less_than(
-        |process| process.cons(process.integer(0), process.integer(1)),
+        |process| process.cons(process.integer(0).unwrap(), process.integer(1).unwrap()),
         right,
         expected,
     );
diff --git a/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_map_left.rs b/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_map_left.rs
index 96a47ca10..a6222846c 100644
--- a/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_map_left.rs
+++ b/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_map_left.rs
@@ -20,7 +20,7 @@ fn with_number_atom_reference_function_port_pid_or_tuple_returns_false() {
 #[test]
 fn with_smaller_map_right_returns_false() {
     is_equal_or_less_than(
-        |_, process| process.map_from_slice(&[(Atom::str_to_term("a"), process.integer(1))]),
+        |_, process| process.map_from_slice(&[(Atom::str_to_term("a"), process.integer(1).unwrap())]),
         false,
     );
 }
@@ -30,8 +30,8 @@ fn with_same_size_map_with_lesser_keys_returns_false() {
     is_equal_or_less_than(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("a"), process.integer(2)),
-                (Atom::str_to_term("b"), process.integer(3)),
+                (Atom::str_to_term("a"), process.integer(2).unwrap()),
+                (Atom::str_to_term("b"), process.integer(3).unwrap()),
             ])
         },
         false,
@@ -43,8 +43,8 @@ fn with_same_size_map_with_same_keys_with_lesser_values_returns_false() {
     is_equal_or_less_than(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("b"), process.integer(2)),
-                (Atom::str_to_term("c"), process.integer(2)),
+                (Atom::str_to_term("b"), process.integer(2).unwrap()),
+                (Atom::str_to_term("c"), process.integer(2).unwrap()),
             ])
         },
         false,
@@ -56,8 +56,8 @@ fn with_same_value_map_returns_true() {
     is_equal_or_less_than(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("b"), process.integer(2)),
-                (Atom::str_to_term("c"), process.integer(3)),
+                (Atom::str_to_term("b"), process.integer(2).unwrap()),
+                (Atom::str_to_term("c"), process.integer(3).unwrap()),
             ])
         },
         true,
@@ -69,8 +69,8 @@ fn with_same_size_map_with_same_keys_with_greater_values_returns_true() {
     is_equal_or_less_than(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("b"), process.integer(3)),
-                (Atom::str_to_term("c"), process.integer(4)),
+                (Atom::str_to_term("b"), process.integer(3).unwrap()),
+                (Atom::str_to_term("c"), process.integer(4).unwrap()),
             ])
         },
         true,
@@ -82,8 +82,8 @@ fn with_same_size_map_with_greater_keys_returns_true() {
     is_equal_or_less_than(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("c"), process.integer(2)),
-                (Atom::str_to_term("d"), process.integer(3)),
+                (Atom::str_to_term("c"), process.integer(2).unwrap()),
+                (Atom::str_to_term("d"), process.integer(3).unwrap()),
             ])
         },
         true,
@@ -95,9 +95,9 @@ fn with_greater_size_map_returns_true() {
     is_equal_or_less_than(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("a"), process.integer(1)),
-                (Atom::str_to_term("b"), process.integer(2)),
-                (Atom::str_to_term("c"), process.integer(3)),
+                (Atom::str_to_term("a"), process.integer(1).unwrap()),
+                (Atom::str_to_term("b"), process.integer(2).unwrap()),
+                (Atom::str_to_term("c"), process.integer(3).unwrap()),
             ])
         },
         true,
@@ -133,8 +133,8 @@ where
     super::is_equal_or_less_than(
         |process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("b"), process.integer(2)),
-                (Atom::str_to_term("c"), process.integer(3)),
+                (Atom::str_to_term("b"), process.integer(2).unwrap()),
+                (Atom::str_to_term("c"), process.integer(3).unwrap()),
             ])
         },
         right,
diff --git a/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_small_integer_left.rs b/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_small_integer_left.rs
index 90e0e70dc..9d1186ced 100644
--- a/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_small_integer_left.rs
+++ b/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_small_integer_left.rs
@@ -2,7 +2,7 @@ use super::*;
 
 #[test]
 fn with_lesser_small_integer_right_returns_false() {
-    is_equal_or_less_than(|_, process| process.integer(-1), false);
+    is_equal_or_less_than(|_, process| process.integer(-1).unwrap(), false);
 }
 
 #[test]
@@ -12,18 +12,18 @@ fn with_same_small_integer_right_returns_true() {
 
 #[test]
 fn with_same_value_small_integer_right_returns_true() {
-    is_equal_or_less_than(|_, process| process.integer(0), true);
+    is_equal_or_less_than(|_, process| process.integer(0).unwrap(), true);
 }
 
 #[test]
 fn with_greater_small_integer_right_returns_true() {
-    is_equal_or_less_than(|_, process| process.integer(1), true);
+    is_equal_or_less_than(|_, process| process.integer(1).unwrap(), true);
 }
 
 #[test]
 fn with_lesser_big_integer_right_returns_false() {
     is_equal_or_less_than(
-        |_, process| process.integer(SmallInteger::MIN_VALUE - 1),
+        |_, process| process.integer(Integer::MIN_SMALL - 1).unwrap(),
         false,
     )
 }
@@ -31,24 +31,24 @@ fn with_lesser_big_integer_right_returns_false() {
 #[test]
 fn with_greater_big_integer_right_returns_true() {
     is_equal_or_less_than(
-        |_, process| process.integer(SmallInteger::MAX_VALUE + 1),
+        |_, process| process.integer(Integer::MAX_SMALL + 1).unwrap(),
         true,
     )
 }
 
 #[test]
 fn with_lesser_float_right_returns_false() {
-    is_equal_or_less_than(|_, process| process.float(-1.0), false)
+    is_equal_or_less_than(|_, process| -1.0.into(), false)
 }
 
 #[test]
 fn with_same_value_float_right_returns_true() {
-    is_equal_or_less_than(|_, process| process.float(0.0), true)
+    is_equal_or_less_than(|_, process| 0.0.into(), true)
 }
 
 #[test]
 fn with_greater_float_right_returns_true() {
-    is_equal_or_less_than(|_, process| process.float(1.0), true)
+    is_equal_or_less_than(|_, process| 1.0.into(), true)
 }
 
 #[test]
@@ -72,5 +72,5 @@ fn is_equal_or_less_than<R>(right: R, expected: bool)
 where
     R: FnOnce(Term, &Process) -> Term,
 {
-    super::is_equal_or_less_than(|process| process.integer(0), right, expected);
+    super::is_equal_or_less_than(|process| process.integer(0).unwrap(), right, expected);
 }
diff --git a/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_subbinary_left.rs b/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_subbinary_left.rs
index 8a5389113..f229f4999 100644
--- a/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_subbinary_left.rs
+++ b/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_subbinary_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn with_number_atom_reference_function_port_pid_tuple_map_or_list_returns_false() {
     run!(
@@ -15,10 +13,10 @@ fn with_number_atom_reference_function_port_pid_tuple_map_or_list_returns_false(
                                 right.is_number() ||
                                     right.is_atom() ||
                                     right.is_reference() ||
-                                    right.is_boxed_function() ||
+                                    right.is_closure() ||
                                     right.is_port() ||
                                     right.is_pid() ||
-                                    right.is_boxed_tuple() ||
+                                    right.is_tuple() ||
                                     right.is_list()
                             }),
                 )
diff --git a/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_tuple_left.rs b/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_tuple_left.rs
index c42450a08..d07049f89 100644
--- a/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_tuple_left.rs
+++ b/native_implemented/otp/src/erlang/is_equal_or_less_than_2/test/with_tuple_left.rs
@@ -20,7 +20,7 @@ fn with_number_atom_reference_function_port_or_pid_returns_false() {
 #[test]
 fn with_smaller_tuple_right_returns_false() {
     is_equal_or_less_than(
-        |_, process| process.tuple_from_slice(&[process.integer(1)]),
+        |_, process| process.tuple_term_from_term_slice(&[process.integer(1).unwrap()]),
         false,
     );
 }
@@ -28,7 +28,7 @@ fn with_smaller_tuple_right_returns_false() {
 #[test]
 fn with_same_size_tuple_with_lesser_elements_returns_false() {
     is_equal_or_less_than(
-        |_, process| process.tuple_from_slice(&[process.integer(1), process.integer(1)]),
+        |_, process| process.tuple_term_from_term_slice(&[process.integer(1).unwrap(), process.integer(1).unwrap()]),
         false,
     );
 }
@@ -36,7 +36,7 @@ fn with_same_size_tuple_with_lesser_elements_returns_false() {
 #[test]
 fn with_same_value_tuple_returns_true() {
     is_equal_or_less_than(
-        |_, process| process.tuple_from_slice(&[process.integer(1), process.integer(2)]),
+        |_, process| process.tuple_term_from_term_slice(&[process.integer(1).unwrap(), process.integer(2).unwrap()]),
         true,
     );
 }
@@ -44,7 +44,7 @@ fn with_same_value_tuple_returns_true() {
 #[test]
 fn with_same_size_tuple_with_greater_elements_returns_true() {
     is_equal_or_less_than(
-        |_, process| process.tuple_from_slice(&[process.integer(1), process.integer(3)]),
+        |_, process| process.tuple_term_from_term_slice(&[process.integer(1).unwrap(), process.integer(3).unwrap()]),
         true,
     );
 }
@@ -53,7 +53,7 @@ fn with_same_size_tuple_with_greater_elements_returns_true() {
 fn with_greater_size_tuple_returns_true() {
     is_equal_or_less_than(
         |_, process| {
-            process.tuple_from_slice(&[process.integer(1), process.integer(2), process.integer(3)])
+            process.tuple_term_from_term_slice(&[process.integer(1).unwrap(), process.integer(2).unwrap(), process.integer(3).unwrap()])
         },
         true,
     );
@@ -81,7 +81,7 @@ where
     R: FnOnce(Term, &Process) -> Term,
 {
     super::is_equal_or_less_than(
-        |process| process.tuple_from_slice(&[process.integer(1), process.integer(2)]),
+        |process| process.tuple_term_from_term_slice(&[process.integer(1).unwrap(), process.integer(2).unwrap()]),
         right,
         expected,
     );
diff --git a/native_implemented/otp/src/erlang/is_float_1.rs b/native_implemented/otp/src/erlang/is_float_1.rs
index 365d972e6..c75015aae 100644
--- a/native_implemented/otp/src/erlang/is_float_1.rs
+++ b/native_implemented/otp/src/erlang/is_float_1.rs
@@ -1,6 +1,6 @@
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:is_float/1)]
 pub fn result(term: Term) -> Term {
-    term.is_boxed_float().into()
+    term.is_float().into()
 }
diff --git a/native_implemented/otp/src/erlang/is_function_1.rs b/native_implemented/otp/src/erlang/is_function_1.rs
index c450ad120..faff390ac 100644
--- a/native_implemented/otp/src/erlang/is_function_1.rs
+++ b/native_implemented/otp/src/erlang/is_function_1.rs
@@ -1,9 +1,9 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:is_function/1)]
 pub fn result(term: Term) -> Term {
-    term.is_boxed_function().into()
+    term.is_closure().into()
 }
diff --git a/native_implemented/otp/src/erlang/is_function_1/test.rs b/native_implemented/otp/src/erlang/is_function_1/test.rs
index dceb7f746..123dae01b 100644
--- a/native_implemented/otp/src/erlang/is_function_1/test.rs
+++ b/native_implemented/otp/src/erlang/is_function_1/test.rs
@@ -8,7 +8,7 @@ use crate::test::with_process_arc;
 #[test]
 fn without_function_returns_false() {
     run!(
-        |arc_process| strategy::term::is_not_function(arc_process.clone()),
+        |arc_process| strategy::term::is_not_closure(arc_process.clone()),
         |term| {
             prop_assert_eq!(result(term), false.into());
 
diff --git a/native_implemented/otp/src/erlang/is_function_2.rs b/native_implemented/otp/src/erlang/is_function_2.rs
index 50c02799a..71d72acf3 100644
--- a/native_implemented/otp/src/erlang/is_function_2.rs
+++ b/native_implemented/otp/src/erlang/is_function_2.rs
@@ -1,14 +1,16 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::term::prelude::*;
+use std::ptr::NonNull;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::Term;
 
 use crate::runtime::context::*;
 
 #[native_implemented::function(erlang:is_function/2)]
-fn result(term: Term, arity: Term) -> exception::Result<Term> {
+fn result(term: Term, arity: Term) -> Result<Term, NonNull<ErlangException>> {
     let arity_arity = term_try_into_arity(arity)?;
 
-    Ok(term.decode()?.is_function_with_arity(arity_arity).into())
+    Ok(term.is_function_with_arity(arity_arity).into())
 }
diff --git a/native_implemented/otp/src/erlang/is_function_2/test.rs b/native_implemented/otp/src/erlang/is_function_2/test.rs
index 5466b494d..d5b1a04d6 100644
--- a/native_implemented/otp/src/erlang/is_function_2/test.rs
+++ b/native_implemented/otp/src/erlang/is_function_2/test.rs
@@ -1,7 +1,8 @@
 mod with_function;
 
 use proptest::prop_assert_eq;
-use proptest::strategy::Strategy;
+
+use firefly_rt::term::Term;
 
 use crate::erlang::is_function_2::result;
 use crate::test::strategy;
@@ -11,7 +12,7 @@ fn without_function_returns_false() {
     run!(
         |arc_process| {
             (
-                strategy::term::is_not_function(arc_process.clone()),
+                strategy::term::is_not_closure(arc_process.clone()),
                 strategy::term::function::arity(arc_process.clone()),
             )
         },
diff --git a/native_implemented/otp/src/erlang/is_function_2/test/with_function/with_non_negative_arity.rs b/native_implemented/otp/src/erlang/is_function_2/test/with_function/with_non_negative_arity.rs
index 3d263ac8a..7a993093a 100644
--- a/native_implemented/otp/src/erlang/is_function_2/test/with_function/with_non_negative_arity.rs
+++ b/native_implemented/otp/src/erlang/is_function_2/test/with_function/with_non_negative_arity.rs
@@ -18,7 +18,7 @@ fn without_function_arity_returns_false() {
                                 "Guard arity must be different than function arity",
                                 |(_, guard_arity_u8, arity_u8)| guard_arity_u8 != arity_u8,
                             )
-                            .prop_map(|(arc_process, u, _)| arc_process.integer(u)),
+                            .prop_map(|(arc_process, u, _)| arc_process.integer(u).unwrap()),
                     )
                 })
         },
@@ -44,7 +44,7 @@ fn with_function_arity_returns_true() {
                             arc_process.clone(),
                             arity_usize as u8,
                         ),
-                        Just(arc_process.integer(arity_usize)),
+                        Just(arc_process.integer(arity_usize).unwrap()),
                     )
                 })
         },
diff --git a/native_implemented/otp/src/erlang/is_greater_than_2.rs b/native_implemented/otp/src/erlang/is_greater_than_2.rs
index 5b936c467..e8c7788c0 100644
--- a/native_implemented/otp/src/erlang/is_greater_than_2.rs
+++ b/native_implemented/otp/src/erlang/is_greater_than_2.rs
@@ -1,7 +1,7 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::term::Term;
 
 /// `>/2` infix operator.  Floats and integers are converted.
 #[native_implemented::function(erlang:>/2)]
diff --git a/native_implemented/otp/src/erlang/is_greater_than_2/test.rs b/native_implemented/otp/src/erlang/is_greater_than_2/test.rs
index 5c0d1e005..70c046aa4 100644
--- a/native_implemented/otp/src/erlang/is_greater_than_2/test.rs
+++ b/native_implemented/otp/src/erlang/is_greater_than_2/test.rs
@@ -18,8 +18,8 @@ use proptest::prop_assert_eq;
 use proptest::strategy::BoxedStrategy;
 use proptest::test_runner::{Config, TestRunner};
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Integer, Term};
 
 use crate::erlang::is_greater_than_2::result;
 use crate::test::{external_arc_node, strategy};
diff --git a/native_implemented/otp/src/erlang/is_greater_than_2/test/with_atom_left.rs b/native_implemented/otp/src/erlang/is_greater_than_2/test/with_atom_left.rs
index 9347e5948..993b06c79 100644
--- a/native_implemented/otp/src/erlang/is_greater_than_2/test/with_atom_left.rs
+++ b/native_implemented/otp/src/erlang/is_greater_than_2/test/with_atom_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn with_number_returns_true() {
     run!(
diff --git a/native_implemented/otp/src/erlang/is_greater_than_2/test/with_big_integer_left.rs b/native_implemented/otp/src/erlang/is_greater_than_2/test/with_big_integer_left.rs
index e4b48da0a..972c2c3cf 100644
--- a/native_implemented/otp/src/erlang/is_greater_than_2/test/with_big_integer_left.rs
+++ b/native_implemented/otp/src/erlang/is_greater_than_2/test/with_big_integer_left.rs
@@ -2,14 +2,14 @@ use super::*;
 
 #[test]
 fn with_greater_small_integer_right_returns_true() {
-    is_greater_than(|_, process| process.integer(0), true)
+    is_greater_than(|_, process| process.integer(0).unwrap(), true)
 }
 
 #[test]
 fn with_greater_small_integer_right_returns_false() {
     super::is_greater_than(
-        |process| process.integer(SmallInteger::MIN_VALUE - 1),
-        |_, process| process.integer(SmallInteger::MIN_VALUE),
+        |process| process.integer(Integer::MIN_SMALL - 1).unwrap(),
+        |_, process| process.integer(Integer::MIN_SMALL).unwrap(),
         false,
     );
 }
@@ -17,7 +17,7 @@ fn with_greater_small_integer_right_returns_false() {
 #[test]
 fn with_greater_big_integer_right_returns_true() {
     is_greater_than(
-        |_, process| process.integer(SmallInteger::MIN_VALUE - 1),
+        |_, process| process.integer(Integer::MIN_SMALL - 1).unwrap(),
         true,
     )
 }
@@ -25,7 +25,7 @@ fn with_greater_big_integer_right_returns_true() {
 #[test]
 fn with_same_value_big_integer_right_returns_false() {
     is_greater_than(
-        |_, process| process.integer(SmallInteger::MAX_VALUE + 1),
+        |_, process| process.integer(Integer::MAX_SMALL + 1).unwrap(),
         false,
     )
 }
@@ -33,21 +33,21 @@ fn with_same_value_big_integer_right_returns_false() {
 #[test]
 fn with_greater_big_integer_right_returns_false() {
     is_greater_than(
-        |_, process| process.integer(SmallInteger::MAX_VALUE + 2),
+        |_, process| process.integer(Integer::MAX_SMALL + 2).unwrap(),
         false,
     )
 }
 
 #[test]
 fn with_greater_float_right_returns_true() {
-    is_greater_than(|_, process| process.float(1.0), true)
+    is_greater_than(|_, process| 1.0.into(), true)
 }
 
 #[test]
 fn with_greater_float_right_returns_false() {
     super::is_greater_than(
-        |process| process.integer(SmallInteger::MIN_VALUE - 1),
-        |_, process| process.float(1.0),
+        |process| process.integer(Integer::MIN_SMALL - 1).unwrap(),
+        |_, process| 1.0.into(),
         false,
     );
 }
@@ -74,7 +74,7 @@ where
     R: FnOnce(Term, &Process) -> Term,
 {
     super::is_greater_than(
-        |process| process.integer(SmallInteger::MAX_VALUE + 1),
+        |process| process.integer(Integer::MAX_SMALL + 1).unwrap(),
         right,
         expected,
     );
diff --git a/native_implemented/otp/src/erlang/is_greater_than_2/test/with_empty_list_left.rs b/native_implemented/otp/src/erlang/is_greater_than_2/test/with_empty_list_left.rs
index 3095bba6c..4affed529 100644
--- a/native_implemented/otp/src/erlang/is_greater_than_2/test/with_empty_list_left.rs
+++ b/native_implemented/otp/src/erlang/is_greater_than_2/test/with_empty_list_left.rs
@@ -1,7 +1,6 @@
 use super::*;
 
 use proptest::prop_oneof;
-use proptest::strategy::Strategy;
 
 #[test]
 fn without_list_or_bitstring_returns_true() {
@@ -13,7 +12,7 @@ fn without_list_or_bitstring_returns_true() {
                 })
         },
         |right| {
-            let left = Term::NIL;
+            let left = Term::Nil;
 
             prop_assert_eq!(result(left, right), true.into());
 
@@ -32,7 +31,7 @@ fn with_non_empty_list_or_bitstring_right_returns_false() {
             ]
         },
         |right| {
-            let left = Term::NIL;
+            let left = Term::Nil;
 
             prop_assert_eq!(result(left, right), false.into());
 
diff --git a/native_implemented/otp/src/erlang/is_greater_than_2/test/with_float_left.rs b/native_implemented/otp/src/erlang/is_greater_than_2/test/with_float_left.rs
index dff034c9b..53fcf36f4 100644
--- a/native_implemented/otp/src/erlang/is_greater_than_2/test/with_float_left.rs
+++ b/native_implemented/otp/src/erlang/is_greater_than_2/test/with_float_left.rs
@@ -2,18 +2,18 @@ use super::*;
 
 #[test]
 fn with_greater_small_integer_right_returns_true() {
-    is_greater_than(|_, process| process.integer(-1), true)
+    is_greater_than(|_, process| process.integer(-1).unwrap(), true)
 }
 
 #[test]
 fn with_greater_small_integer_right_returns_false() {
-    is_greater_than(|_, process| process.integer(1), false)
+    is_greater_than(|_, process| process.integer(1).unwrap(), false)
 }
 
 #[test]
 fn with_greater_big_integer_right_returns_true() {
     is_greater_than(
-        |_, process| process.integer(SmallInteger::MIN_VALUE - 1),
+        |_, process| process.integer(Integer::MIN_SMALL - 1).unwrap(),
         true,
     )
 }
@@ -21,19 +21,19 @@ fn with_greater_big_integer_right_returns_true() {
 #[test]
 fn with_greater_big_integer_right_returns_false() {
     is_greater_than(
-        |_, process| process.integer(SmallInteger::MAX_VALUE + 1),
+        |_, process| process.integer(Integer::MAX_SMALL + 1).unwrap(),
         false,
     )
 }
 
 #[test]
 fn with_greater_float_right_returns_true() {
-    is_greater_than(|_, process| process.float(-1.0), true)
+    is_greater_than(|_, process| -1.0.into(), true)
 }
 
 #[test]
 fn with_greater_float_right_returns_false() {
-    is_greater_than(|_, process| process.float(1.0), false)
+    is_greater_than(|_, process| 1.0.into(), false)
 }
 
 #[test]
@@ -41,7 +41,7 @@ fn without_number_returns_false() {
     run!(
         |arc_process| {
             (
-                strategy::term::float(arc_process.clone()),
+                strategy::term::float(),
                 strategy::term::is_not_number(arc_process.clone()),
             )
         },
@@ -57,5 +57,5 @@ fn is_greater_than<R>(right: R, expected: bool)
 where
     R: FnOnce(Term, &Process) -> Term,
 {
-    super::is_greater_than(|process| process.float(1.0), right, expected);
+    super::is_greater_than(|process| 1.0.into(), right, expected);
 }
diff --git a/native_implemented/otp/src/erlang/is_greater_than_2/test/with_heap_binary_left.rs b/native_implemented/otp/src/erlang/is_greater_than_2/test/with_heap_binary_left.rs
index 887a21a4f..41e61dced 100644
--- a/native_implemented/otp/src/erlang/is_greater_than_2/test/with_heap_binary_left.rs
+++ b/native_implemented/otp/src/erlang/is_greater_than_2/test/with_heap_binary_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn with_number_atom_reference_function_port_pid_tuple_map_or_list_returns_true() {
     run!(
@@ -14,10 +12,10 @@ fn with_number_atom_reference_function_port_pid_tuple_map_or_list_returns_true()
                             right.is_number()
                                 || right.is_atom()
                                 || right.is_reference()
-                                || right.is_boxed_function()
+                                || right.is_closure()
                                 || right.is_port()
                                 || right.is_pid()
-                                || right.is_boxed_tuple()
+                                || right.is_tuple()
                                 || right.is_list()
                         }),
                 )
diff --git a/native_implemented/otp/src/erlang/is_greater_than_2/test/with_list_left.rs b/native_implemented/otp/src/erlang/is_greater_than_2/test/with_list_left.rs
index 5dfba5076..d69c17c23 100644
--- a/native_implemented/otp/src/erlang/is_greater_than_2/test/with_list_left.rs
+++ b/native_implemented/otp/src/erlang/is_greater_than_2/test/with_list_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_list_or_bitstring_returns_true() {
     run!(
@@ -24,13 +22,13 @@ fn without_list_or_bitstring_returns_true() {
 
 #[test]
 fn with_empty_list_right_returns_true() {
-    is_greater_than(|_, _| Term::NIL, true);
+    is_greater_than(|_, _| Term::Nil, true);
 }
 
 #[test]
 fn with_greater_list_right_returns_true() {
     is_greater_than(
-        |_, process| process.cons(process.integer(0), process.integer(0)),
+        |_, process| process.cons(process.integer(0).unwrap(), process.integer(0).unwrap()),
         true,
     );
 }
@@ -43,7 +41,7 @@ fn with_same_list_right_returns_false() {
 #[test]
 fn with_same_value_list_right_returns_false() {
     is_greater_than(
-        |_, process| process.cons(process.integer(0), process.integer(1)),
+        |_, process| process.cons(process.integer(0).unwrap(), process.integer(1).unwrap()),
         false,
     );
 }
@@ -51,7 +49,7 @@ fn with_same_value_list_right_returns_false() {
 #[test]
 fn with_greater_list_right_returns_false() {
     is_greater_than(
-        |_, process| process.cons(process.integer(0), process.integer(2)),
+        |_, process| process.cons(process.integer(0).unwrap(), process.integer(2).unwrap()),
         false,
     );
 }
@@ -78,7 +76,7 @@ where
     R: FnOnce(Term, &Process) -> Term,
 {
     super::is_greater_than(
-        |process| process.cons(process.integer(0), process.integer(1)),
+        |process| process.cons(process.integer(0).unwrap(), process.integer(1).unwrap()),
         right,
         expected,
     );
diff --git a/native_implemented/otp/src/erlang/is_greater_than_2/test/with_map_left.rs b/native_implemented/otp/src/erlang/is_greater_than_2/test/with_map_left.rs
index fbf96f4c3..d20ae0e18 100644
--- a/native_implemented/otp/src/erlang/is_greater_than_2/test/with_map_left.rs
+++ b/native_implemented/otp/src/erlang/is_greater_than_2/test/with_map_left.rs
@@ -20,7 +20,7 @@ fn with_number_atom_reference_function_port_pid_or_tuple_returns_true() {
 #[test]
 fn with_smaller_map_right_returns_true() {
     is_greater_than(
-        |_, process| process.map_from_slice(&[(Atom::str_to_term("a"), process.integer(1))]),
+        |_, process| process.map_from_slice(&[(Atom::str_to_term("a"), process.integer(1).unwrap())]),
         true,
     );
 }
@@ -30,8 +30,8 @@ fn with_same_size_map_with_greater_keys_returns_true() {
     is_greater_than(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("a"), process.integer(2)),
-                (Atom::str_to_term("b"), process.integer(3)),
+                (Atom::str_to_term("a"), process.integer(2).unwrap()),
+                (Atom::str_to_term("b"), process.integer(3).unwrap()),
             ])
         },
         true,
@@ -43,8 +43,8 @@ fn with_same_size_map_with_same_keys_with_greater_values_returns_true() {
     is_greater_than(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("b"), process.integer(2)),
-                (Atom::str_to_term("c"), process.integer(2)),
+                (Atom::str_to_term("b"), process.integer(2).unwrap()),
+                (Atom::str_to_term("c"), process.integer(2).unwrap()),
             ])
         },
         true,
@@ -61,8 +61,8 @@ fn with_same_value_map_returns_false() {
     is_greater_than(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("b"), process.integer(2)),
-                (Atom::str_to_term("c"), process.integer(3)),
+                (Atom::str_to_term("b"), process.integer(2).unwrap()),
+                (Atom::str_to_term("c"), process.integer(3).unwrap()),
             ])
         },
         false,
@@ -74,8 +74,8 @@ fn with_same_size_map_with_same_keys_with_greater_values_returns_false() {
     is_greater_than(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("b"), process.integer(3)),
-                (Atom::str_to_term("c"), process.integer(4)),
+                (Atom::str_to_term("b"), process.integer(3).unwrap()),
+                (Atom::str_to_term("c"), process.integer(4).unwrap()),
             ])
         },
         false,
@@ -87,8 +87,8 @@ fn with_same_size_map_with_greater_keys_returns_false() {
     is_greater_than(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("c"), process.integer(2)),
-                (Atom::str_to_term("d"), process.integer(3)),
+                (Atom::str_to_term("c"), process.integer(2).unwrap()),
+                (Atom::str_to_term("d"), process.integer(3).unwrap()),
             ])
         },
         false,
@@ -100,9 +100,9 @@ fn with_greater_size_map_returns_false() {
     is_greater_than(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("a"), process.integer(1)),
-                (Atom::str_to_term("b"), process.integer(2)),
-                (Atom::str_to_term("c"), process.integer(3)),
+                (Atom::str_to_term("a"), process.integer(1).unwrap()),
+                (Atom::str_to_term("b"), process.integer(2).unwrap()),
+                (Atom::str_to_term("c"), process.integer(3).unwrap()),
             ])
         },
         false,
@@ -133,8 +133,8 @@ where
     super::is_greater_than(
         |process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("b"), process.integer(2)),
-                (Atom::str_to_term("c"), process.integer(3)),
+                (Atom::str_to_term("b"), process.integer(2).unwrap()),
+                (Atom::str_to_term("c"), process.integer(3).unwrap()),
             ])
         },
         right,
diff --git a/native_implemented/otp/src/erlang/is_greater_than_2/test/with_small_integer_left.rs b/native_implemented/otp/src/erlang/is_greater_than_2/test/with_small_integer_left.rs
index 7738c9fe5..c95c0d91f 100644
--- a/native_implemented/otp/src/erlang/is_greater_than_2/test/with_small_integer_left.rs
+++ b/native_implemented/otp/src/erlang/is_greater_than_2/test/with_small_integer_left.rs
@@ -2,7 +2,7 @@ use super::*;
 
 #[test]
 fn with_greater_small_integer_right_returns_true() {
-    is_greater_than(|_, process| process.integer(-1), true);
+    is_greater_than(|_, process| process.integer(-1).unwrap(), true);
 }
 
 #[test]
@@ -12,18 +12,18 @@ fn with_same_small_integer_right_returns_false() {
 
 #[test]
 fn with_same_value_small_integer_right_returns_false() {
-    is_greater_than(|_, process| process.integer(0), false);
+    is_greater_than(|_, process| process.integer(0).unwrap(), false);
 }
 
 #[test]
 fn with_greater_small_integer_right_returns_false() {
-    is_greater_than(|_, process| process.integer(1), false);
+    is_greater_than(|_, process| process.integer(1).unwrap(), false);
 }
 
 #[test]
 fn with_greater_big_integer_right_returns_true() {
     is_greater_than(
-        |_, process| process.integer(SmallInteger::MIN_VALUE - 1),
+        |_, process| process.integer(Integer::MIN_SMALL - 1).unwrap(),
         true,
     )
 }
@@ -31,24 +31,24 @@ fn with_greater_big_integer_right_returns_true() {
 #[test]
 fn with_greater_big_integer_right_returns_false() {
     is_greater_than(
-        |_, process| process.integer(SmallInteger::MAX_VALUE + 1),
+        |_, process| process.integer(Integer::MAX_SMALL + 1).unwrap(),
         false,
     )
 }
 
 #[test]
 fn with_greater_float_right_returns_true() {
-    is_greater_than(|_, process| process.float(-1.0), true)
+    is_greater_than(|_, process| -1.0.into(), true)
 }
 
 #[test]
 fn with_same_value_float_right_returns_false() {
-    is_greater_than(|_, process| process.float(1.0), false)
+    is_greater_than(|_, process| 1.0.into(), false)
 }
 
 #[test]
 fn with_greater_float_right_returns_false() {
-    is_greater_than(|_, process| process.float(1.0), false)
+    is_greater_than(|_, process| 1.0.into(), false)
 }
 
 #[test]
@@ -72,5 +72,5 @@ fn is_greater_than<R>(right: R, expected: bool)
 where
     R: FnOnce(Term, &Process) -> Term,
 {
-    super::is_greater_than(|process| process.integer(0), right, expected);
+    super::is_greater_than(|process| process.integer(0).unwrap(), right, expected);
 }
diff --git a/native_implemented/otp/src/erlang/is_greater_than_2/test/with_subbinary_left.rs b/native_implemented/otp/src/erlang/is_greater_than_2/test/with_subbinary_left.rs
index 5caf0239c..5baf32580 100644
--- a/native_implemented/otp/src/erlang/is_greater_than_2/test/with_subbinary_left.rs
+++ b/native_implemented/otp/src/erlang/is_greater_than_2/test/with_subbinary_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn with_number_atom_reference_function_port_pid_tuple_map_or_list_returns_true() {
     run!(
@@ -14,10 +12,10 @@ fn with_number_atom_reference_function_port_pid_tuple_map_or_list_returns_true()
                             right.is_number()
                                 || right.is_atom()
                                 || right.is_reference()
-                                || right.is_boxed_function()
+                                || right.is_closure()
                                 || right.is_port()
                                 || right.is_pid()
-                                || right.is_boxed_tuple()
+                                || right.is_tuple()
                                 || right.is_list()
                         }),
                 )
diff --git a/native_implemented/otp/src/erlang/is_greater_than_2/test/with_tuple_left.rs b/native_implemented/otp/src/erlang/is_greater_than_2/test/with_tuple_left.rs
index cd72b83a5..86eead51d 100644
--- a/native_implemented/otp/src/erlang/is_greater_than_2/test/with_tuple_left.rs
+++ b/native_implemented/otp/src/erlang/is_greater_than_2/test/with_tuple_left.rs
@@ -20,7 +20,7 @@ fn with_number_atom_reference_function_port_or_pid_returns_true() {
 #[test]
 fn with_smaller_tuple_right_returns_true() {
     is_greater_than(
-        |_, process| process.tuple_from_slice(&[process.integer(1)]),
+        |_, process| process.tuple_term_from_term_slice(&[process.integer(1).unwrap()]),
         true,
     );
 }
@@ -28,7 +28,7 @@ fn with_smaller_tuple_right_returns_true() {
 #[test]
 fn with_same_size_tuple_with_greater_elements_returns_true() {
     is_greater_than(
-        |_, process| process.tuple_from_slice(&[process.integer(1), process.integer(1)]),
+        |_, process| process.tuple_term_from_term_slice(&[process.integer(1).unwrap(), process.integer(1).unwrap()]),
         true,
     );
 }
@@ -41,7 +41,7 @@ fn with_same_tuple_returns_false() {
 #[test]
 fn with_same_value_tuple_returns_false() {
     is_greater_than(
-        |_, process| process.tuple_from_slice(&[process.integer(1), process.integer(2)]),
+        |_, process| process.tuple_term_from_term_slice(&[process.integer(1).unwrap(), process.integer(2).unwrap()]),
         false,
     );
 }
@@ -49,7 +49,7 @@ fn with_same_value_tuple_returns_false() {
 #[test]
 fn with_same_size_tuple_with_greater_elements_returns_false() {
     is_greater_than(
-        |_, process| process.tuple_from_slice(&[process.integer(1), process.integer(3)]),
+        |_, process| process.tuple_term_from_term_slice(&[process.integer(1).unwrap(), process.integer(3).unwrap()]),
         false,
     );
 }
@@ -58,7 +58,7 @@ fn with_same_size_tuple_with_greater_elements_returns_false() {
 fn with_greater_size_tuple_returns_false() {
     is_greater_than(
         |_, process| {
-            process.tuple_from_slice(&[process.integer(1), process.integer(2), process.integer(3)])
+            process.tuple_term_from_term_slice(&[process.integer(1).unwrap(), process.integer(2).unwrap(), process.integer(3).unwrap()])
         },
         false,
     );
@@ -86,7 +86,7 @@ where
     R: FnOnce(Term, &Process) -> Term,
 {
     super::is_greater_than(
-        |process| process.tuple_from_slice(&[process.integer(1), process.integer(2)]),
+        |process| process.tuple_term_from_term_slice(&[process.integer(1).unwrap(), process.integer(2).unwrap()]),
         right,
         expected,
     );
diff --git a/native_implemented/otp/src/erlang/is_greater_than_or_equal_2.rs b/native_implemented/otp/src/erlang/is_greater_than_or_equal_2.rs
index 0c8f376c7..e953cbb06 100644
--- a/native_implemented/otp/src/erlang/is_greater_than_or_equal_2.rs
+++ b/native_implemented/otp/src/erlang/is_greater_than_or_equal_2.rs
@@ -1,7 +1,7 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::term::Term;
 
 /// `>=/2` infix operator.  Floats and integers are converted.
 #[native_implemented::function(erlang:>=/2)]
diff --git a/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test.rs b/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test.rs
index ff01f32ac..e79a0450d 100644
--- a/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test.rs
+++ b/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test.rs
@@ -15,8 +15,8 @@ mod with_tuple_left;
 use proptest::prop_assert_eq;
 use proptest::test_runner::{Config, TestRunner};
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Atom, Integer, Term};
 
 use crate::erlang::is_greater_than_or_equal_2::result;
 use crate::test::{external_arc_node, strategy};
diff --git a/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_atom_left.rs b/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_atom_left.rs
index 0000983cb..c4ed9814d 100644
--- a/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_atom_left.rs
+++ b/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_atom_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn with_number_returns_true() {
     run!(
diff --git a/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_big_integer_left.rs b/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_big_integer_left.rs
index cfe180599..e71578935 100644
--- a/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_big_integer_left.rs
+++ b/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_big_integer_left.rs
@@ -2,14 +2,14 @@ use super::*;
 
 #[test]
 fn with_greater_small_integer_right_returns_true() {
-    is_greater_than_or_equal(|_, process| process.integer(0), true)
+    is_greater_than_or_equal(|_, process| process.integer(0).unwrap(), true)
 }
 
 #[test]
 fn with_greater_small_integer_right_returns_false() {
     super::is_greater_than_or_equal(
-        |process| process.integer(SmallInteger::MIN_VALUE - 1),
-        |_, process| process.integer(SmallInteger::MIN_VALUE),
+        |process| process.integer(Integer::MIN_SMALL - 1).unwrap(),
+        |_, process| process.integer(Integer::MIN_SMALL).unwrap(),
         false,
     );
 }
@@ -17,7 +17,7 @@ fn with_greater_small_integer_right_returns_false() {
 #[test]
 fn with_greater_big_integer_right_returns_true() {
     is_greater_than_or_equal(
-        |_, process| process.integer(SmallInteger::MIN_VALUE - 1),
+        |_, process| process.integer(Integer::MIN_SMALL - 1).unwrap(),
         true,
     )
 }
@@ -25,7 +25,7 @@ fn with_greater_big_integer_right_returns_true() {
 #[test]
 fn with_same_value_big_integer_right_returns_true() {
     is_greater_than_or_equal(
-        |_, process| process.integer(SmallInteger::MAX_VALUE + 1),
+        |_, process| process.integer(Integer::MAX_SMALL + 1).unwrap(),
         true,
     )
 }
@@ -33,21 +33,21 @@ fn with_same_value_big_integer_right_returns_true() {
 #[test]
 fn with_greater_big_integer_right_returns_false() {
     is_greater_than_or_equal(
-        |_, process| process.integer(SmallInteger::MAX_VALUE + 2),
+        |_, process| process.integer(Integer::MAX_SMALL + 2).unwrap(),
         false,
     )
 }
 
 #[test]
 fn with_greater_float_right_returns_true() {
-    is_greater_than_or_equal(|_, process| process.float(1.0), true)
+    is_greater_than_or_equal(|_, process| 1.0.into(), true)
 }
 
 #[test]
 fn with_greater_float_right_returns_false() {
     super::is_greater_than_or_equal(
-        |process| process.integer(SmallInteger::MIN_VALUE - 1),
-        |_, process| process.float(1.0),
+        |process| process.integer(Integer::MIN_SMALL - 1).unwrap(),
+        |_, process| 1.0.into(),
         false,
     );
 }
@@ -74,7 +74,7 @@ where
     R: FnOnce(Term, &Process) -> Term,
 {
     super::is_greater_than_or_equal(
-        |process| process.integer(SmallInteger::MAX_VALUE + 1),
+        |process| process.integer(Integer::MAX_SMALL + 1).unwrap(),
         right,
         expected,
     );
diff --git a/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_empty_list_left.rs b/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_empty_list_left.rs
index d5a5ad196..ea7dec171 100644
--- a/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_empty_list_left.rs
+++ b/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_empty_list_left.rs
@@ -1,7 +1,6 @@
 use super::*;
 
 use proptest::prop_oneof;
-use proptest::strategy::Strategy;
 
 #[test]
 fn without_non_empty_list_or_bitstring_returns_true() {
@@ -13,7 +12,7 @@ fn without_non_empty_list_or_bitstring_returns_true() {
                 })
         },
         |right| {
-            let left = Term::NIL;
+            let left = Term::Nil;
 
             prop_assert_eq!(result(left, right), true.into());
 
@@ -32,7 +31,7 @@ fn with_non_empty_list_or_bitstring_right_returns_false() {
             ]
         },
         |right| {
-            let left = Term::NIL;
+            let left = Term::Nil;
 
             prop_assert_eq!(result(left, right), false.into());
 
diff --git a/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_float_left.rs b/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_float_left.rs
index f56284d11..da59f4267 100644
--- a/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_float_left.rs
+++ b/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_float_left.rs
@@ -2,23 +2,23 @@ use super::*;
 
 #[test]
 fn with_greater_small_integer_right_returns_true() {
-    is_greater_than_or_equal(|_, process| process.integer(-1), true)
+    is_greater_than_or_equal(|_, process| process.integer(-1).unwrap(), true)
 }
 
 #[test]
 fn with_equal_small_integer_right_returns_false() {
-    is_greater_than_or_equal(|_, process| process.integer(1), true)
+    is_greater_than_or_equal(|_, process| process.integer(1).unwrap(), true)
 }
 
 #[test]
 fn with_greater_small_integer_right_returns_false() {
-    is_greater_than_or_equal(|_, process| process.integer(2), false)
+    is_greater_than_or_equal(|_, process| process.integer(2).unwrap(), false)
 }
 
 #[test]
 fn with_lesser_big_integer_right_returns_true() {
     is_greater_than_or_equal(
-        |_, process| process.integer(SmallInteger::MIN_VALUE - 1),
+        |_, process| process.integer(Integer::MIN_SMALL - 1).unwrap(),
         true,
     )
 }
@@ -26,19 +26,19 @@ fn with_lesser_big_integer_right_returns_true() {
 #[test]
 fn with_greater_big_integer_right_returns_false() {
     is_greater_than_or_equal(
-        |_, process| process.integer(SmallInteger::MAX_VALUE + 1),
+        |_, process| process.integer(Integer::MAX_SMALL + 1).unwrap(),
         false,
     )
 }
 
 #[test]
 fn with_greater_float_right_returns_true() {
-    is_greater_than_or_equal(|_, process| process.float(-1.0), true)
+    is_greater_than_or_equal(|_, process| -1.0.into(), true)
 }
 
 #[test]
 fn with_greater_float_right_returns_false() {
-    is_greater_than_or_equal(|_, process| process.float(2.0), false)
+    is_greater_than_or_equal(|_, process| 2.0.into(), false)
 }
 
 #[test]
@@ -46,7 +46,7 @@ fn without_number_returns_false() {
     run!(
         |arc_process| {
             (
-                strategy::term::float(arc_process.clone()),
+                strategy::term::float(),
                 strategy::term::is_not_number(arc_process.clone()),
             )
         },
@@ -62,5 +62,5 @@ fn is_greater_than_or_equal<R>(right: R, expected: bool)
 where
     R: FnOnce(Term, &Process) -> Term,
 {
-    super::is_greater_than_or_equal(|process| process.float(1.0), right, expected);
+    super::is_greater_than_or_equal(|process| 1.0.into(), right, expected);
 }
diff --git a/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_heap_binary_left.rs b/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_heap_binary_left.rs
index a85c50603..6472ba788 100644
--- a/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_heap_binary_left.rs
+++ b/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_heap_binary_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn with_number_atom_reference_function_port_pid_tuple_map_or_list_returns_true() {
     run!(
@@ -14,10 +12,10 @@ fn with_number_atom_reference_function_port_pid_tuple_map_or_list_returns_true()
                             right.is_number()
                                 || right.is_atom()
                                 || right.is_reference()
-                                || right.is_boxed_function()
+                                || right.is_closure()
                                 || right.is_port()
                                 || right.is_pid()
-                                || right.is_boxed_tuple()
+                                || right.is_tuple()
                                 || right.is_list()
                         }),
                 )
diff --git a/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_list_left.rs b/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_list_left.rs
index f0a757353..2ad0d4c21 100644
--- a/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_list_left.rs
+++ b/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_list_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_list_or_bitstring_returns_true() {
     run!(
@@ -24,13 +22,13 @@ fn without_list_or_bitstring_returns_true() {
 
 #[test]
 fn with_empty_list_right_returns_true() {
-    is_greater_than_or_equal(|_, _| Term::NIL, true);
+    is_greater_than_or_equal(|_, _| Term::Nil, true);
 }
 
 #[test]
 fn with_greater_list_right_returns_true() {
     is_greater_than_or_equal(
-        |_, process| process.cons(process.integer(0), process.integer(0)),
+        |_, process| process.cons(process.integer(0).unwrap(), process.integer(0).unwrap()),
         true,
     );
 }
@@ -38,7 +36,7 @@ fn with_greater_list_right_returns_true() {
 #[test]
 fn with_same_value_list_right_returns_true() {
     is_greater_than_or_equal(
-        |_, process| process.cons(process.integer(0), process.integer(1)),
+        |_, process| process.cons(process.integer(0).unwrap(), process.integer(1).unwrap()),
         true,
     );
 }
@@ -46,7 +44,7 @@ fn with_same_value_list_right_returns_true() {
 #[test]
 fn with_greater_list_right_returns_false() {
     is_greater_than_or_equal(
-        |_, process| process.cons(process.integer(0), process.integer(2)),
+        |_, process| process.cons(process.integer(0).unwrap(), process.integer(2).unwrap()),
         false,
     );
 }
@@ -73,7 +71,7 @@ where
     R: FnOnce(Term, &Process) -> Term,
 {
     super::is_greater_than_or_equal(
-        |process| process.cons(process.integer(0), process.integer(1)),
+        |process| process.cons(process.integer(0).unwrap(), process.integer(1).unwrap()),
         right,
         expected,
     );
diff --git a/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_map_left.rs b/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_map_left.rs
index 054a2b14a..e6b066fce 100644
--- a/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_map_left.rs
+++ b/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_map_left.rs
@@ -22,7 +22,7 @@ fn with_number_atom_reference_function_port_pid_or_tuple_returns_true() {
 #[test]
 fn with_smaller_map_right_returns_true() {
     is_greater_than_or_equal(
-        |_, process| process.map_from_slice(&[(Atom::str_to_term("a"), process.integer(1))]),
+        |_, process| process.map_from_slice(&[(Atom::str_to_term("a"), process.integer(1).unwrap())]),
         true,
     );
 }
@@ -32,8 +32,8 @@ fn with_same_size_map_with_greater_keys_returns_true() {
     is_greater_than_or_equal(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("a"), process.integer(2)),
-                (Atom::str_to_term("b"), process.integer(3)),
+                (Atom::str_to_term("a"), process.integer(2).unwrap()),
+                (Atom::str_to_term("b"), process.integer(3).unwrap()),
             ])
         },
         true,
@@ -45,8 +45,8 @@ fn with_same_size_map_with_same_keys_with_greater_values_returns_true() {
     is_greater_than_or_equal(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("b"), process.integer(2)),
-                (Atom::str_to_term("c"), process.integer(2)),
+                (Atom::str_to_term("b"), process.integer(2).unwrap()),
+                (Atom::str_to_term("c"), process.integer(2).unwrap()),
             ])
         },
         true,
@@ -58,8 +58,8 @@ fn with_same_value_map_returns_true() {
     is_greater_than_or_equal(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("b"), process.integer(2)),
-                (Atom::str_to_term("c"), process.integer(3)),
+                (Atom::str_to_term("b"), process.integer(2).unwrap()),
+                (Atom::str_to_term("c"), process.integer(3).unwrap()),
             ])
         },
         true,
@@ -71,8 +71,8 @@ fn with_same_size_map_with_same_keys_with_greater_values_returns_false() {
     is_greater_than_or_equal(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("b"), process.integer(3)),
-                (Atom::str_to_term("c"), process.integer(4)),
+                (Atom::str_to_term("b"), process.integer(3).unwrap()),
+                (Atom::str_to_term("c"), process.integer(4).unwrap()),
             ])
         },
         false,
@@ -84,8 +84,8 @@ fn with_same_size_map_with_greater_keys_returns_false() {
     is_greater_than_or_equal(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("c"), process.integer(2)),
-                (Atom::str_to_term("d"), process.integer(3)),
+                (Atom::str_to_term("c"), process.integer(2).unwrap()),
+                (Atom::str_to_term("d"), process.integer(3).unwrap()),
             ])
         },
         false,
@@ -97,9 +97,9 @@ fn with_greater_size_map_returns_false() {
     is_greater_than_or_equal(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("a"), process.integer(1)),
-                (Atom::str_to_term("b"), process.integer(2)),
-                (Atom::str_to_term("c"), process.integer(3)),
+                (Atom::str_to_term("a"), process.integer(1).unwrap()),
+                (Atom::str_to_term("b"), process.integer(2).unwrap()),
+                (Atom::str_to_term("c"), process.integer(3).unwrap()),
             ])
         },
         false,
@@ -130,8 +130,8 @@ where
     super::is_greater_than_or_equal(
         |process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("b"), process.integer(2)),
-                (Atom::str_to_term("c"), process.integer(3)),
+                (Atom::str_to_term("b"), process.integer(2).unwrap()),
+                (Atom::str_to_term("c"), process.integer(3).unwrap()),
             ])
         },
         right,
diff --git a/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_small_integer_left.rs b/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_small_integer_left.rs
index ef122da9e..8c6303edb 100644
--- a/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_small_integer_left.rs
+++ b/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_small_integer_left.rs
@@ -2,23 +2,23 @@ use super::*;
 
 #[test]
 fn with_greater_small_integer_right_returns_true() {
-    is_greater_than_or_equal(|_, process| process.integer(-1), true);
+    is_greater_than_or_equal(|_, process| process.integer(-1).unwrap(), true);
 }
 
 #[test]
 fn with_same_value_small_integer_right_returns_true() {
-    is_greater_than_or_equal(|_, process| process.integer(0), true);
+    is_greater_than_or_equal(|_, process| process.integer(0).unwrap(), true);
 }
 
 #[test]
 fn with_greater_small_integer_right_returns_false() {
-    is_greater_than_or_equal(|_, process| process.integer(1), false);
+    is_greater_than_or_equal(|_, process| process.integer(1).unwrap(), false);
 }
 
 #[test]
 fn with_greater_big_integer_right_returns_true() {
     is_greater_than_or_equal(
-        |_, process| process.integer(SmallInteger::MIN_VALUE - 1),
+        |_, process| process.integer(Integer::MIN_SMALL - 1).unwrap(),
         true,
     )
 }
@@ -26,24 +26,24 @@ fn with_greater_big_integer_right_returns_true() {
 #[test]
 fn with_greater_big_integer_right_returns_false() {
     is_greater_than_or_equal(
-        |_, process| process.integer(SmallInteger::MAX_VALUE + 1),
+        |_, process| process.integer(Integer::MAX_SMALL + 1).unwrap(),
         false,
     )
 }
 
 #[test]
 fn with_greater_float_right_returns_true() {
-    is_greater_than_or_equal(|_, process| process.float(-1.0), true)
+    is_greater_than_or_equal(|_, process| -1.0.into(), true)
 }
 
 #[test]
 fn with_same_value_float_right_returns_true() {
-    is_greater_than_or_equal(|_, process| process.float(0.0), true)
+    is_greater_than_or_equal(|_, process| 0.0.into(), true)
 }
 
 #[test]
 fn with_greater_float_right_returns_false() {
-    is_greater_than_or_equal(|_, process| process.float(1.0), false)
+    is_greater_than_or_equal(|_, process| 1.0.into(), false)
 }
 
 #[test]
@@ -67,5 +67,5 @@ fn is_greater_than_or_equal<R>(right: R, expected: bool)
 where
     R: FnOnce(Term, &Process) -> Term,
 {
-    super::is_greater_than_or_equal(|process| process.integer(0), right, expected);
+    super::is_greater_than_or_equal(|process| process.integer(0).unwrap(), right, expected);
 }
diff --git a/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_subbinary_left.rs b/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_subbinary_left.rs
index 6460364a7..8edc7d153 100644
--- a/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_subbinary_left.rs
+++ b/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_subbinary_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn with_number_atom_reference_function_port_pid_tuple_map_or_list_returns_true() {
     run!(
@@ -14,10 +12,10 @@ fn with_number_atom_reference_function_port_pid_tuple_map_or_list_returns_true()
                             right.is_number()
                                 || right.is_atom()
                                 || right.is_reference()
-                                || right.is_boxed_function()
+                                || right.is_closure()
                                 || right.is_port()
                                 || right.is_pid()
-                                || right.is_boxed_tuple()
+                                || right.is_tuple()
                                 || right.is_list()
                         }),
                 )
diff --git a/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_tuple_left.rs b/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_tuple_left.rs
index f8e4abe8f..fc693f699 100644
--- a/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_tuple_left.rs
+++ b/native_implemented/otp/src/erlang/is_greater_than_or_equal_2/test/with_tuple_left.rs
@@ -20,7 +20,7 @@ fn with_number_atom_reference_function_port_or_pid_returns_true() {
 #[test]
 fn with_smaller_tuple_right_returns_true() {
     is_greater_than_or_equal(
-        |_, process| process.tuple_from_slice(&[process.integer(1)]),
+        |_, process| process.tuple_term_from_term_slice(&[process.integer(1).unwrap()]),
         true,
     );
 }
@@ -28,7 +28,7 @@ fn with_smaller_tuple_right_returns_true() {
 #[test]
 fn with_same_size_tuple_with_greater_elements_returns_true() {
     is_greater_than_or_equal(
-        |_, process| process.tuple_from_slice(&[process.integer(1), process.integer(1)]),
+        |_, process| process.tuple_term_from_term_slice(&[process.integer(1).unwrap(), process.integer(1).unwrap()]),
         true,
     );
 }
@@ -36,7 +36,7 @@ fn with_same_size_tuple_with_greater_elements_returns_true() {
 #[test]
 fn with_same_value_tuple_returns_true() {
     is_greater_than_or_equal(
-        |_, process| process.tuple_from_slice(&[process.integer(1), process.integer(2)]),
+        |_, process| process.tuple_term_from_term_slice(&[process.integer(1).unwrap(), process.integer(2).unwrap()]),
         true,
     );
 }
@@ -44,7 +44,7 @@ fn with_same_value_tuple_returns_true() {
 #[test]
 fn with_same_size_tuple_with_greater_elements_returns_false() {
     is_greater_than_or_equal(
-        |_, process| process.tuple_from_slice(&[process.integer(1), process.integer(3)]),
+        |_, process| process.tuple_term_from_term_slice(&[process.integer(1).unwrap(), process.integer(3).unwrap()]),
         false,
     );
 }
@@ -53,7 +53,7 @@ fn with_same_size_tuple_with_greater_elements_returns_false() {
 fn with_greater_size_tuple_returns_false() {
     is_greater_than_or_equal(
         |_, process| {
-            process.tuple_from_slice(&[process.integer(1), process.integer(2), process.integer(3)])
+            process.tuple_term_from_term_slice(&[process.integer(1).unwrap(), process.integer(2).unwrap(), process.integer(3).unwrap()])
         },
         false,
     );
@@ -81,7 +81,7 @@ where
     R: FnOnce(Term, &Process) -> Term,
 {
     super::is_greater_than_or_equal(
-        |process| process.tuple_from_slice(&[process.integer(1), process.integer(2)]),
+        |process| process.tuple_term_from_term_slice(&[process.integer(1).unwrap(), process.integer(2).unwrap()]),
         right,
         expected,
     );
diff --git a/native_implemented/otp/src/erlang/is_integer_1.rs b/native_implemented/otp/src/erlang/is_integer_1.rs
index 8bdc40715..7c23d2a80 100644
--- a/native_implemented/otp/src/erlang/is_integer_1.rs
+++ b/native_implemented/otp/src/erlang/is_integer_1.rs
@@ -1,4 +1,4 @@
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:is_integer/1)]
 pub fn result(term: Term) -> Term {
diff --git a/native_implemented/otp/src/erlang/is_less_than_2.rs b/native_implemented/otp/src/erlang/is_less_than_2.rs
index 8bc394db4..ffbed959d 100644
--- a/native_implemented/otp/src/erlang/is_less_than_2.rs
+++ b/native_implemented/otp/src/erlang/is_less_than_2.rs
@@ -1,7 +1,7 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::term::Term;
 
 /// `</2` infix operator.  Floats and integers are converted.
 #[native_implemented::function(erlang:</2)]
diff --git a/native_implemented/otp/src/erlang/is_less_than_2/test.rs b/native_implemented/otp/src/erlang/is_less_than_2/test.rs
index 9b47b2c68..7619eb41b 100644
--- a/native_implemented/otp/src/erlang/is_less_than_2/test.rs
+++ b/native_implemented/otp/src/erlang/is_less_than_2/test.rs
@@ -15,8 +15,8 @@ mod with_tuple_left;
 use proptest::prop_assert_eq;
 use proptest::test_runner::{Config, TestRunner};
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Atom, Integer, Term};
 
 use crate::erlang::is_less_than_2::result;
 use crate::test::{external_arc_node, strategy};
diff --git a/native_implemented/otp/src/erlang/is_less_than_2/test/with_atom_left.rs b/native_implemented/otp/src/erlang/is_less_than_2/test/with_atom_left.rs
index f9e621e3c..3bf8dae19 100644
--- a/native_implemented/otp/src/erlang/is_less_than_2/test/with_atom_left.rs
+++ b/native_implemented/otp/src/erlang/is_less_than_2/test/with_atom_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn with_number_returns_false() {
     run!(
diff --git a/native_implemented/otp/src/erlang/is_less_than_2/test/with_big_integer_left.rs b/native_implemented/otp/src/erlang/is_less_than_2/test/with_big_integer_left.rs
index 9bbf54b43..81d0879d7 100644
--- a/native_implemented/otp/src/erlang/is_less_than_2/test/with_big_integer_left.rs
+++ b/native_implemented/otp/src/erlang/is_less_than_2/test/with_big_integer_left.rs
@@ -2,14 +2,14 @@ use super::*;
 
 #[test]
 fn with_lesser_small_integer_right_returns_false() {
-    is_less_than(|_, process| process.integer(0), false)
+    is_less_than(|_, process| process.integer(0).unwrap(), false)
 }
 
 #[test]
 fn with_greater_small_integer_right_returns_true() {
     super::is_less_than(
-        |process| process.integer(SmallInteger::MIN_VALUE - 1),
-        |_, process| process.integer(SmallInteger::MIN_VALUE),
+        |process| process.integer(Integer::MIN_SMALL - 1).unwrap(),
+        |_, process| process.integer(Integer::MIN_SMALL).unwrap(),
         true,
     );
 }
@@ -17,7 +17,7 @@ fn with_greater_small_integer_right_returns_true() {
 #[test]
 fn with_lesser_big_integer_right_returns_false() {
     is_less_than(
-        |_, process| process.integer(SmallInteger::MIN_VALUE - 1),
+        |_, process| process.integer(Integer::MIN_SMALL - 1).unwrap(),
         false,
     )
 }
@@ -25,7 +25,7 @@ fn with_lesser_big_integer_right_returns_false() {
 #[test]
 fn with_same_value_big_integer_right_returns_false() {
     is_less_than(
-        |_, process| process.integer(SmallInteger::MAX_VALUE + 1),
+        |_, process| process.integer(Integer::MAX_SMALL + 1).unwrap(),
         false,
     )
 }
@@ -33,21 +33,21 @@ fn with_same_value_big_integer_right_returns_false() {
 #[test]
 fn with_greater_big_integer_right_returns_true() {
     is_less_than(
-        |_, process| process.integer(SmallInteger::MAX_VALUE + 2),
+        |_, process| process.integer(Integer::MAX_SMALL + 2).unwrap(),
         true,
     )
 }
 
 #[test]
 fn with_lesser_float_right_returns_false() {
-    is_less_than(|_, process| process.float(1.0), false)
+    is_less_than(|_, process| 1.0.into(), false)
 }
 
 #[test]
 fn with_greater_float_right_returns_true() {
     super::is_less_than(
-        |process| process.integer(SmallInteger::MIN_VALUE - 1),
-        |_, process| process.float(1.0),
+        |process| process.integer(Integer::MIN_SMALL - 1).unwrap(),
+        |_, process| 1.0.into(),
         true,
     );
 }
@@ -74,7 +74,7 @@ where
     R: FnOnce(Term, &Process) -> Term,
 {
     super::is_less_than(
-        |process| process.integer(SmallInteger::MAX_VALUE + 1),
+        |process| process.integer(Integer::MAX_SMALL + 1).unwrap(),
         right,
         expected,
     );
diff --git a/native_implemented/otp/src/erlang/is_less_than_2/test/with_empty_list_left.rs b/native_implemented/otp/src/erlang/is_less_than_2/test/with_empty_list_left.rs
index dbf36d9f6..fac3336c5 100644
--- a/native_implemented/otp/src/erlang/is_less_than_2/test/with_empty_list_left.rs
+++ b/native_implemented/otp/src/erlang/is_less_than_2/test/with_empty_list_left.rs
@@ -1,7 +1,6 @@
 use super::*;
 
 use proptest::prop_oneof;
-use proptest::strategy::Strategy;
 
 #[test]
 fn without_non_empty_list_or_bitstring_returns_false() {
@@ -13,7 +12,7 @@ fn without_non_empty_list_or_bitstring_returns_false() {
                 })
         },
         |right| {
-            let left = Term::NIL;
+            let left = Term::Nil;
 
             prop_assert_eq!(result(left, right), false.into());
 
@@ -32,7 +31,7 @@ fn with_non_empty_list_or_bitstring_right_returns_true() {
             ]
         },
         |right| {
-            let left = Term::NIL;
+            let left = Term::Nil;
 
             prop_assert_eq!(result(left, right), true.into());
 
diff --git a/native_implemented/otp/src/erlang/is_less_than_2/test/with_float_left.rs b/native_implemented/otp/src/erlang/is_less_than_2/test/with_float_left.rs
index f263fecb6..50878fc0c 100644
--- a/native_implemented/otp/src/erlang/is_less_than_2/test/with_float_left.rs
+++ b/native_implemented/otp/src/erlang/is_less_than_2/test/with_float_left.rs
@@ -2,18 +2,18 @@ use super::*;
 
 #[test]
 fn with_lesser_small_integer_right_returns_false() {
-    is_less_than(|_, process| process.integer(-1), false)
+    is_less_than(|_, process| process.integer(-1).unwrap(), false)
 }
 
 #[test]
 fn with_greater_small_integer_right_returns_true() {
-    is_less_than(|_, process| process.integer(2), true)
+    is_less_than(|_, process| process.integer(2).unwrap(), true)
 }
 
 #[test]
 fn with_lesser_big_integer_right_returns_false() {
     is_less_than(
-        |_, process| process.integer(SmallInteger::MIN_VALUE - 1),
+        |_, process| process.integer(Integer::MIN_SMALL - 1).unwrap(),
         false,
     )
 }
@@ -21,19 +21,19 @@ fn with_lesser_big_integer_right_returns_false() {
 #[test]
 fn with_greater_big_integer_right_returns_true() {
     is_less_than(
-        |_, process| process.integer(SmallInteger::MAX_VALUE + 1),
+        |_, process| process.integer(Integer::MAX_SMALL + 1).unwrap(),
         true,
     )
 }
 
 #[test]
 fn with_lesser_float_right_returns_false() {
-    is_less_than(|_, process| process.float(-1.0), false)
+    is_less_than(|_, process| -1.0.into(), false)
 }
 
 #[test]
 fn with_greater_float_right_returns_true() {
-    is_less_than(|_, process| process.float(1.1), true)
+    is_less_than(|_, process| 1.1.into(), true)
 }
 
 #[test]
@@ -41,7 +41,7 @@ fn without_number_returns_true() {
     run!(
         |arc_process| {
             (
-                strategy::term::float(arc_process.clone()),
+                strategy::term::float(),
                 strategy::term::is_not_number(arc_process.clone()),
             )
         },
@@ -57,5 +57,5 @@ fn is_less_than<R>(right: R, expected: bool)
 where
     R: FnOnce(Term, &Process) -> Term,
 {
-    super::is_less_than(|process| process.float(1.0), right, expected);
+    super::is_less_than(|process| 1.0.into(), right, expected);
 }
diff --git a/native_implemented/otp/src/erlang/is_less_than_2/test/with_heap_binary_left.rs b/native_implemented/otp/src/erlang/is_less_than_2/test/with_heap_binary_left.rs
index 6974d3b09..0fad7e4cb 100644
--- a/native_implemented/otp/src/erlang/is_less_than_2/test/with_heap_binary_left.rs
+++ b/native_implemented/otp/src/erlang/is_less_than_2/test/with_heap_binary_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn with_number_atom_reference_function_port_pid_tuple_map_or_list_returns_false() {
     run!(
@@ -14,10 +12,10 @@ fn with_number_atom_reference_function_port_pid_tuple_map_or_list_returns_false(
                             right.is_number()
                                 || right.is_atom()
                                 || right.is_reference()
-                                || right.is_boxed_function()
+                                || right.is_closure()
                                 || right.is_port()
                                 || right.is_pid()
-                                || right.is_boxed_tuple()
+                                || right.is_tuple()
                                 || right.is_list()
                         }),
                 )
diff --git a/native_implemented/otp/src/erlang/is_less_than_2/test/with_list_left.rs b/native_implemented/otp/src/erlang/is_less_than_2/test/with_list_left.rs
index e0fa1626f..852bbaa45 100644
--- a/native_implemented/otp/src/erlang/is_less_than_2/test/with_list_left.rs
+++ b/native_implemented/otp/src/erlang/is_less_than_2/test/with_list_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_list_or_bitstring_returns_false() {
     run!(
@@ -24,13 +22,13 @@ fn without_list_or_bitstring_returns_false() {
 
 #[test]
 fn with_empty_list_right_returns_false() {
-    is_less_than(|_, _| Term::NIL, false);
+    is_less_than(|_, _| Term::Nil, false);
 }
 
 #[test]
 fn with_lesser_list_right_returns_false() {
     is_less_than(
-        |_, process| process.cons(process.integer(0), process.integer(0)),
+        |_, process| process.cons(process.integer(0).unwrap(), process.integer(0).unwrap()),
         false,
     );
 }
@@ -43,7 +41,7 @@ fn with_same_list_right_returns_false() {
 #[test]
 fn with_same_value_list_right_returns_false() {
     is_less_than(
-        |_, process| process.cons(process.integer(0), process.integer(1)),
+        |_, process| process.cons(process.integer(0).unwrap(), process.integer(1).unwrap()),
         false,
     );
 }
@@ -51,7 +49,7 @@ fn with_same_value_list_right_returns_false() {
 #[test]
 fn with_greater_list_right_returns_true() {
     is_less_than(
-        |_, process| process.cons(process.integer(0), process.integer(2)),
+        |_, process| process.cons(process.integer(0).unwrap(), process.integer(2).unwrap()),
         true,
     );
 }
@@ -78,7 +76,7 @@ where
     R: FnOnce(Term, &Process) -> Term,
 {
     super::is_less_than(
-        |process| process.cons(process.integer(0), process.integer(1)),
+        |process| process.cons(process.integer(0).unwrap(), process.integer(1).unwrap()),
         right,
         expected,
     );
diff --git a/native_implemented/otp/src/erlang/is_less_than_2/test/with_map_left.rs b/native_implemented/otp/src/erlang/is_less_than_2/test/with_map_left.rs
index 267ea8af1..d344c0883 100644
--- a/native_implemented/otp/src/erlang/is_less_than_2/test/with_map_left.rs
+++ b/native_implemented/otp/src/erlang/is_less_than_2/test/with_map_left.rs
@@ -20,7 +20,7 @@ fn with_number_atom_reference_function_port_pid_or_tuple_returns_false() {
 #[test]
 fn with_smaller_map_right_returns_false() {
     is_less_than(
-        |_, process| process.map_from_slice(&[(Atom::str_to_term("a"), process.integer(1))]),
+        |_, process| process.map_from_slice(&[(Atom::str_to_term("a"), process.integer(1).unwrap())]),
         false,
     );
 }
@@ -30,8 +30,8 @@ fn with_same_size_map_with_lesser_keys_returns_false() {
     is_less_than(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("a"), process.integer(2)),
-                (Atom::str_to_term("b"), process.integer(3)),
+                (Atom::str_to_term("a"), process.integer(2).unwrap()),
+                (Atom::str_to_term("b"), process.integer(3).unwrap()),
             ])
         },
         false,
@@ -43,8 +43,8 @@ fn with_same_size_map_with_same_keys_with_lesser_values_returns_false() {
     is_less_than(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("b"), process.integer(2)),
-                (Atom::str_to_term("c"), process.integer(2)),
+                (Atom::str_to_term("b"), process.integer(2).unwrap()),
+                (Atom::str_to_term("c"), process.integer(2).unwrap()),
             ])
         },
         false,
@@ -56,8 +56,8 @@ fn with_same_value_map_returns_false() {
     is_less_than(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("b"), process.integer(2)),
-                (Atom::str_to_term("c"), process.integer(3)),
+                (Atom::str_to_term("b"), process.integer(2).unwrap()),
+                (Atom::str_to_term("c"), process.integer(3).unwrap()),
             ])
         },
         false,
@@ -69,8 +69,8 @@ fn with_same_size_map_with_same_keys_with_greater_values_returns_true() {
     is_less_than(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("b"), process.integer(3)),
-                (Atom::str_to_term("c"), process.integer(4)),
+                (Atom::str_to_term("b"), process.integer(3).unwrap()),
+                (Atom::str_to_term("c"), process.integer(4).unwrap()),
             ])
         },
         true,
@@ -82,8 +82,8 @@ fn with_same_size_map_with_greater_keys_returns_true() {
     is_less_than(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("c"), process.integer(2)),
-                (Atom::str_to_term("d"), process.integer(3)),
+                (Atom::str_to_term("c"), process.integer(2).unwrap()),
+                (Atom::str_to_term("d"), process.integer(3).unwrap()),
             ])
         },
         true,
@@ -95,9 +95,9 @@ fn with_greater_size_map_returns_true() {
     is_less_than(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("a"), process.integer(1)),
-                (Atom::str_to_term("b"), process.integer(2)),
-                (Atom::str_to_term("c"), process.integer(3)),
+                (Atom::str_to_term("a"), process.integer(1).unwrap()),
+                (Atom::str_to_term("b"), process.integer(2).unwrap()),
+                (Atom::str_to_term("c"), process.integer(3).unwrap()),
             ])
         },
         true,
@@ -133,8 +133,8 @@ where
     super::is_less_than(
         |process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("b"), process.integer(2)),
-                (Atom::str_to_term("c"), process.integer(3)),
+                (Atom::str_to_term("b"), process.integer(2).unwrap()),
+                (Atom::str_to_term("c"), process.integer(3).unwrap()),
             ])
         },
         right,
diff --git a/native_implemented/otp/src/erlang/is_less_than_2/test/with_small_integer_left.rs b/native_implemented/otp/src/erlang/is_less_than_2/test/with_small_integer_left.rs
index 58c717eb1..e838e3120 100644
--- a/native_implemented/otp/src/erlang/is_less_than_2/test/with_small_integer_left.rs
+++ b/native_implemented/otp/src/erlang/is_less_than_2/test/with_small_integer_left.rs
@@ -2,7 +2,7 @@ use super::*;
 
 #[test]
 fn with_lesser_small_integer_right_returns_false() {
-    is_less_than(|_, process| process.integer(-1), false);
+    is_less_than(|_, process| process.integer(-1).unwrap(), false);
 }
 
 #[test]
@@ -12,18 +12,18 @@ fn with_same_small_integer_right_returns_false() {
 
 #[test]
 fn with_same_value_small_integer_right_returns_false() {
-    is_less_than(|_, process| process.integer(0), false);
+    is_less_than(|_, process| process.integer(0).unwrap(), false);
 }
 
 #[test]
 fn with_greater_small_integer_right_returns_true() {
-    is_less_than(|_, process| process.integer(1), true);
+    is_less_than(|_, process| process.integer(1).unwrap(), true);
 }
 
 #[test]
 fn with_lesser_big_integer_right_returns_false() {
     is_less_than(
-        |_, process| process.integer(SmallInteger::MIN_VALUE - 1),
+        |_, process| process.integer(Integer::MIN_SMALL - 1).unwrap(),
         false,
     )
 }
@@ -31,24 +31,24 @@ fn with_lesser_big_integer_right_returns_false() {
 #[test]
 fn with_greater_big_integer_right_returns_true() {
     is_less_than(
-        |_, process| process.integer(SmallInteger::MAX_VALUE + 1),
+        |_, process| process.integer(Integer::MAX_SMALL + 1).unwrap(),
         true,
     )
 }
 
 #[test]
 fn with_lesser_float_right_returns_false() {
-    is_less_than(|_, process| process.float(-1.0), false)
+    is_less_than(|_, process| -1.0.into(), false)
 }
 
 #[test]
 fn with_same_value_float_right_returns_false() {
-    is_less_than(|_, process| process.float(0.0), false)
+    is_less_than(|_, process| 0.0.into(), false)
 }
 
 #[test]
 fn with_greater_float_right_returns_true() {
-    is_less_than(|_, process| process.float(1.0), true)
+    is_less_than(|_, process| 1.0.into(), true)
 }
 
 #[test]
@@ -72,5 +72,5 @@ fn is_less_than<R>(right: R, expected: bool)
 where
     R: FnOnce(Term, &Process) -> Term,
 {
-    super::is_less_than(|process| process.integer(0), right, expected);
+    super::is_less_than(|process| process.integer(0).unwrap(), right, expected);
 }
diff --git a/native_implemented/otp/src/erlang/is_less_than_2/test/with_subbinary_left.rs b/native_implemented/otp/src/erlang/is_less_than_2/test/with_subbinary_left.rs
index 50e9b3859..6fe2a1425 100644
--- a/native_implemented/otp/src/erlang/is_less_than_2/test/with_subbinary_left.rs
+++ b/native_implemented/otp/src/erlang/is_less_than_2/test/with_subbinary_left.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn with_number_atom_reference_function_port_pid_tuple_map_or_list_returns_false() {
     run!(
@@ -14,10 +12,10 @@ fn with_number_atom_reference_function_port_pid_tuple_map_or_list_returns_false(
                             right.is_number()
                                 || right.is_atom()
                                 || right.is_reference()
-                                || right.is_boxed_function()
+                                || right.is_closure()
                                 || right.is_port()
                                 || right.is_pid()
-                                || right.is_boxed_tuple()
+                                || right.is_tuple()
                                 || right.is_list()
                         }),
                 )
diff --git a/native_implemented/otp/src/erlang/is_less_than_2/test/with_tuple_left.rs b/native_implemented/otp/src/erlang/is_less_than_2/test/with_tuple_left.rs
index 49fa9890b..a6dae5754 100644
--- a/native_implemented/otp/src/erlang/is_less_than_2/test/with_tuple_left.rs
+++ b/native_implemented/otp/src/erlang/is_less_than_2/test/with_tuple_left.rs
@@ -20,7 +20,7 @@ fn with_number_atom_reference_function_port_or_pid_returns_false() {
 #[test]
 fn with_smaller_tuple_right_returns_false() {
     is_less_than(
-        |_, process| process.tuple_from_slice(&[process.integer(1)]),
+        |_, process| process.tuple_term_from_term_slice(&[process.integer(1).unwrap()]),
         false,
     );
 }
@@ -28,7 +28,7 @@ fn with_smaller_tuple_right_returns_false() {
 #[test]
 fn with_same_size_tuple_with_lesser_elements_returns_false() {
     is_less_than(
-        |_, process| process.tuple_from_slice(&[process.integer(1), process.integer(1)]),
+        |_, process| process.tuple_term_from_term_slice(&[process.integer(1).unwrap(), process.integer(1).unwrap()]),
         false,
     );
 }
@@ -41,7 +41,7 @@ fn with_same_tuple_returns_false() {
 #[test]
 fn with_same_value_tuple_returns_false() {
     is_less_than(
-        |_, process| process.tuple_from_slice(&[process.integer(1), process.integer(2)]),
+        |_, process| process.tuple_term_from_term_slice(&[process.integer(1).unwrap(), process.integer(2).unwrap()]),
         false,
     );
 }
@@ -49,7 +49,7 @@ fn with_same_value_tuple_returns_false() {
 #[test]
 fn with_same_size_tuple_with_greater_elements_returns_true() {
     is_less_than(
-        |_, process| process.tuple_from_slice(&[process.integer(1), process.integer(3)]),
+        |_, process| process.tuple_term_from_term_slice(&[process.integer(1).unwrap(), process.integer(3).unwrap()]),
         true,
     );
 }
@@ -58,7 +58,7 @@ fn with_same_size_tuple_with_greater_elements_returns_true() {
 fn with_greater_size_tuple_returns_true() {
     is_less_than(
         |_, process| {
-            process.tuple_from_slice(&[process.integer(1), process.integer(2), process.integer(3)])
+            process.tuple_term_from_term_slice(&[process.integer(1).unwrap(), process.integer(2).unwrap(), process.integer(3).unwrap()])
         },
         true,
     );
@@ -86,7 +86,7 @@ where
     R: FnOnce(Term, &Process) -> Term,
 {
     super::is_less_than(
-        |process| process.tuple_from_slice(&[process.integer(1), process.integer(2)]),
+        |process| process.tuple_term_from_term_slice(&[process.integer(1).unwrap(), process.integer(2).unwrap()]),
         right,
         expected,
     );
diff --git a/native_implemented/otp/src/erlang/is_list_1.rs b/native_implemented/otp/src/erlang/is_list_1.rs
index e7129d85a..ab8861324 100644
--- a/native_implemented/otp/src/erlang/is_list_1.rs
+++ b/native_implemented/otp/src/erlang/is_list_1.rs
@@ -1,4 +1,4 @@
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:is_list/1)]
 pub fn result(term: Term) -> Term {
diff --git a/native_implemented/otp/src/erlang/is_map_1.rs b/native_implemented/otp/src/erlang/is_map_1.rs
index 42da769f5..a3b7d1a64 100644
--- a/native_implemented/otp/src/erlang/is_map_1.rs
+++ b/native_implemented/otp/src/erlang/is_map_1.rs
@@ -1,6 +1,6 @@
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:is_map/1)]
 pub fn result(term: Term) -> Term {
-    term.is_boxed_map().into()
+    term.is_map().into()
 }
diff --git a/native_implemented/otp/src/erlang/is_map_key_2.rs b/native_implemented/otp/src/erlang/is_map_key_2.rs
index 767e7fc2b..2606f3919 100644
--- a/native_implemented/otp/src/erlang/is_map_key_2.rs
+++ b/native_implemented/otp/src/erlang/is_map_key_2.rs
@@ -1,6 +1,4 @@
-use liblumen_alloc::erts::process::Frame;
-use liblumen_alloc::erts::term::prelude::*;
-use liblumen_alloc::{Arity, ModuleFunctionArity};
+use firefly_rt::*;
 
 use crate::maps;
 
diff --git a/native_implemented/otp/src/erlang/is_number_1.rs b/native_implemented/otp/src/erlang/is_number_1.rs
index 5f87a9376..8100c1c5a 100644
--- a/native_implemented/otp/src/erlang/is_number_1.rs
+++ b/native_implemented/otp/src/erlang/is_number_1.rs
@@ -1,4 +1,4 @@
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:is_number/1)]
 pub fn result(term: Term) -> Term {
diff --git a/native_implemented/otp/src/erlang/is_pid_1.rs b/native_implemented/otp/src/erlang/is_pid_1.rs
index 90e78fc19..fe9b53970 100644
--- a/native_implemented/otp/src/erlang/is_pid_1.rs
+++ b/native_implemented/otp/src/erlang/is_pid_1.rs
@@ -1,4 +1,4 @@
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:is_pid/1)]
 pub fn result(term: Term) -> Term {
diff --git a/native_implemented/otp/src/erlang/is_process_alive_1.rs b/native_implemented/otp/src/erlang/is_process_alive_1.rs
index 842387032..429e346b7 100644
--- a/native_implemented/otp/src/erlang/is_process_alive_1.rs
+++ b/native_implemented/otp/src/erlang/is_process_alive_1.rs
@@ -1,15 +1,17 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use std::ptr::NonNull;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::runtime::registry::pid_to_process;
 
 #[native_implemented::function(erlang:is_process_alive/1)]
-pub fn result(process: &Process, pid: Term) -> exception::Result<Term> {
-    if pid == process.pid_term() {
+pub fn result(process: &Process, pid: Term) -> Result<Term, NonNull<ErlangException>> {
+    if pid == process.pid_term().unwrap() {
         Ok((!process.is_exiting()).into())
     } else {
         let pid_pid = term_try_into_local_pid!(pid)?;
diff --git a/native_implemented/otp/src/erlang/is_record_2.rs b/native_implemented/otp/src/erlang/is_record_2.rs
index 93aea5b49..d076ac373 100644
--- a/native_implemented/otp/src/erlang/is_record_2.rs
+++ b/native_implemented/otp/src/erlang/is_record_2.rs
@@ -1,12 +1,12 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::Term;
 
 use crate::erlang::is_record;
 
 #[native_implemented::function(erlang:is_record/2)]
-pub fn result(term: Term, record_tag: Term) -> exception::Result<Term> {
+pub fn result(term: Term, record_tag: Term) -> Result<Term, NonNull<ErlangException>> {
     is_record(term, record_tag, None)
 }
diff --git a/native_implemented/otp/src/erlang/is_record_2/test.rs b/native_implemented/otp/src/erlang/is_record_2/test.rs
index 1d0f0613c..973f76b6e 100644
--- a/native_implemented/otp/src/erlang/is_record_2/test.rs
+++ b/native_implemented/otp/src/erlang/is_record_2/test.rs
@@ -1,5 +1,5 @@
 use proptest::prop_assert_eq;
-use proptest::strategy::{Just, Strategy};
+use proptest::strategy::Just;
 use proptest::test_runner::{Config, TestRunner};
 
 use crate::erlang::is_record_2::result;
@@ -45,7 +45,7 @@ fn with_empty_tuple_with_atom_returns_false() {
     with_process_arc(|arc_process| {
         TestRunner::new(Config::with_source_file(file!()))
             .run(&strategy::term::atom(), |record_tag| {
-                let tuple = arc_process.tuple_from_slice(&[]);
+                let tuple = arc_process.tuple_term_from_term_slice(&[]);
 
                 prop_assert_eq!(result(tuple, record_tag), Ok(false.into()));
 
@@ -71,7 +71,7 @@ fn with_non_empty_tuple_without_atom_with_first_element_errors_badarg() {
                     tail_element_vec.insert(0, first_element);
 
                     (
-                        arc_process.tuple_from_slice(&tail_element_vec),
+                        arc_process.tuple_term_from_term_slice(&tail_element_vec),
                         first_element,
                     )
                 })
@@ -101,7 +101,7 @@ fn with_non_empty_tuple_with_atom_without_record_tag_returns_false() {
                     |(arc_process, first_element, mut tail_element_vec, atom)| {
                         tail_element_vec.insert(0, first_element);
 
-                        (arc_process.tuple_from_slice(&tail_element_vec), atom)
+                        (arc_process.tuple_term_from_term_slice(&tail_element_vec), atom)
                     },
                 )
         },
@@ -128,7 +128,7 @@ fn with_non_empty_tuple_with_atom_with_record_tag_returns_ok() {
                 .prop_map(|(arc_process, record_tag, mut tail_element_vec)| {
                     tail_element_vec.insert(0, record_tag);
 
-                    (arc_process.tuple_from_slice(&tail_element_vec), record_tag)
+                    (arc_process.tuple_term_from_term_slice(&tail_element_vec), record_tag)
                 })
         },
         |(tuple, record_tag)| {
diff --git a/native_implemented/otp/src/erlang/is_record_3.rs b/native_implemented/otp/src/erlang/is_record_3.rs
index a20841032..32e3525ba 100644
--- a/native_implemented/otp/src/erlang/is_record_3.rs
+++ b/native_implemented/otp/src/erlang/is_record_3.rs
@@ -1,12 +1,12 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::Term;
 
 use crate::erlang::is_record;
 
 #[native_implemented::function(erlang:is_record/3)]
-pub fn result(term: Term, record_tag: Term, size: Term) -> exception::Result<Term> {
+pub fn result(term: Term, record_tag: Term, size: Term) -> Result<Term, NonNull<ErlangException>> {
     is_record(term, record_tag, Some(size))
 }
diff --git a/native_implemented/otp/src/erlang/is_record_3/test.rs b/native_implemented/otp/src/erlang/is_record_3/test.rs
index 6050fd2be..53573683e 100644
--- a/native_implemented/otp/src/erlang/is_record_3/test.rs
+++ b/native_implemented/otp/src/erlang/is_record_3/test.rs
@@ -1,7 +1,7 @@
 use proptest::prop_assert_eq;
-use proptest::strategy::{Just, Strategy};
+use proptest::strategy::Just;
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 use crate::erlang::is_record_3::result;
 use crate::test::strategy;
@@ -56,7 +56,7 @@ fn with_empty_tuple_with_atom_without_non_negative_size_errors_badarg() {
                     .prop_filter_map(
                         "Size must not be a non-negative integer",
                         |(arc_process, size)| {
-                            if !(size.is_integer() && arc_process.integer(0) <= size) {
+                            if !(size.is_integer() && arc_process.integer(0).unwrap() <= size) {
                                 Some(size)
                             } else {
                                 None
@@ -66,7 +66,7 @@ fn with_empty_tuple_with_atom_without_non_negative_size_errors_badarg() {
             )
         },
         |(arc_process, record_tag, size)| {
-            let tuple = arc_process.tuple_from_slice(&[]);
+            let tuple = arc_process.tuple_term_from_term_slice(&[]);
 
             prop_assert_badarg!(
                 result(tuple, record_tag, size),
@@ -89,7 +89,7 @@ fn with_empty_tuple_with_atom_with_non_negative_size_returns_false() {
             )
         },
         |(arc_process, record_tag, size)| {
-            let tuple = arc_process.tuple_from_slice(&[]);
+            let tuple = arc_process.tuple_term_from_term_slice(&[]);
 
             prop_assert_eq!(result(tuple, record_tag, size), Ok(false.into()));
 
@@ -128,10 +128,10 @@ fn with_non_empty_tuple_without_record_tag_with_size_returns_false() {
                     |(arc_process, actual_record_tag, mut tail_element_vec, tested_record_tag)| {
                         tail_element_vec.insert(0, actual_record_tag);
 
-                        let size = arc_process.integer(tail_element_vec.len());
+                        let size = arc_process.integer(tail_element_vec.len()).unwrap();
 
                         (
-                            arc_process.tuple_from_slice(&tail_element_vec),
+                            arc_process.tuple_term_from_term_slice(&tail_element_vec),
                             tested_record_tag,
                             size,
                         )
@@ -160,10 +160,10 @@ fn with_non_empty_tuple_with_record_tag_without_size_returns_false() {
             )
                 .prop_flat_map(|(arc_process, record_tag, mut tail_element_vec)| {
                     tail_element_vec.insert(0, record_tag);
-                    let tuple_size = arc_process.integer(tail_element_vec.len());
+                    let tuple_size = arc_process.integer(tail_element_vec.len()).unwrap();
 
                     (
-                        Just(arc_process.tuple_from_slice(&tail_element_vec)),
+                        Just(arc_process.tuple_term_from_term_slice(&tail_element_vec)),
                         Just(record_tag),
                         strategy::term::integer::non_negative(arc_process.clone())
                             .prop_filter("Size cannot match tuple size", move |size| {
@@ -194,10 +194,10 @@ fn with_non_empty_tuple_with_record_tag_with_size_returns_true() {
             )
                 .prop_map(|(arc_process, record_tag, mut tail_element_vec)| {
                     tail_element_vec.insert(0, record_tag);
-                    let size = arc_process.integer(tail_element_vec.len());
+                    let size = arc_process.integer(tail_element_vec.len()).unwrap();
 
                     (
-                        arc_process.tuple_from_slice(&tail_element_vec),
+                        arc_process.tuple_term_from_term_slice(&tail_element_vec),
                         record_tag,
                         size,
                     )
diff --git a/native_implemented/otp/src/erlang/is_reference_1.rs b/native_implemented/otp/src/erlang/is_reference_1.rs
index 7d3e12ff2..6b1a54ef6 100644
--- a/native_implemented/otp/src/erlang/is_reference_1.rs
+++ b/native_implemented/otp/src/erlang/is_reference_1.rs
@@ -1,15 +1,9 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:is_reference/1)]
 pub fn result(term: Term) -> Term {
-    match term.decode().unwrap() {
-        TypedTerm::Reference(_) => true,
-        TypedTerm::ExternalReference(_) => true,
-        TypedTerm::ResourceReference(_) => true,
-        _ => false,
-    }
-    .into()
+    term.is_reference().into()
 }
diff --git a/native_implemented/otp/src/erlang/is_tuple_1.rs b/native_implemented/otp/src/erlang/is_tuple_1.rs
index 0782a6ac9..4f576463a 100644
--- a/native_implemented/otp/src/erlang/is_tuple_1.rs
+++ b/native_implemented/otp/src/erlang/is_tuple_1.rs
@@ -1,12 +1,9 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:is_tuple/1)]
 pub fn result(term: Term) -> Term {
-    match term.decode() {
-        Ok(TypedTerm::Tuple(_)) => true.into(),
-        _ => false.into(),
-    }
+    term.is_tuple().into()
 }
diff --git a/native_implemented/otp/src/erlang/length_1.rs b/native_implemented/otp/src/erlang/length_1.rs
index 81249dc7d..c34da08cc 100644
--- a/native_implemented/otp/src/erlang/length_1.rs
+++ b/native_implemented/otp/src/erlang/length_1.rs
@@ -1,18 +1,20 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
+use std::ptr::NonNull;
+
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:length/1)]
-pub fn result(process: &Process, list: Term) -> exception::Result<Term> {
-    match list.decode()? {
-        TypedTerm::Nil => Ok(0.into()),
-        TypedTerm::List(cons) => match cons.count() {
-            Some(count) => Ok(process.integer(count)),
+pub fn result(process: &Process, list: Term) -> Result<Term, NonNull<ErlangException>> {
+    match list {
+        Term::Nil => Ok(0.into()),
+        Term::Cons(cons) => match cons.count() {
+            Some(count) => Ok(process.integer(count).unwrap()),
             None => Err(ImproperListError).context(format!("list ({}) is improper", list)),
         },
         _ => Err(TypeError).context(format!("list ({}) is not a list", list)),
diff --git a/native_implemented/otp/src/erlang/length_1/test.rs b/native_implemented/otp/src/erlang/length_1/test.rs
index 669a90c43..56ad93063 100644
--- a/native_implemented/otp/src/erlang/length_1/test.rs
+++ b/native_implemented/otp/src/erlang/length_1/test.rs
@@ -1,9 +1,9 @@
 use proptest::collection::SizeRange;
 use proptest::prop_assert_eq;
-use proptest::strategy::{Just, Strategy};
+use proptest::strategy::Just;
 use proptest::test_runner::{Config, TestRunner};
 
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::term::Term;
 
 use crate::erlang::length_1::result;
 use crate::test::strategy;
@@ -28,8 +28,8 @@ fn without_list_errors_badarg() {
 #[test]
 fn with_empty_list_is_zero() {
     with_process(|process| {
-        let list = Term::NIL;
-        let zero_term = process.integer(0);
+        let list = Term::Nil;
+        let zero_term = process.integer(0).unwrap();
 
         assert_eq!(result(process, list), Ok(zero_term));
     });
@@ -68,7 +68,7 @@ fn with_non_empty_proper_list_is_number_of_elements() {
                 .prop_map(|(arc_process, element_vec)| {
                     (
                         arc_process.clone(),
-                        arc_process.list_from_slice(&element_vec),
+                        arc_process.list_from_slice(&element_vec).unwrap(),
                         element_vec.len(),
                     )
                 })
@@ -76,7 +76,7 @@ fn with_non_empty_proper_list_is_number_of_elements() {
         |(arc_process, list, element_count)| {
             prop_assert_eq!(
                 result(&arc_process, list),
-                Ok(arc_process.integer(element_count))
+                Ok(arc_process.integer(element_count).unwrap())
             );
 
             Ok(())
diff --git a/native_implemented/otp/src/erlang/link_1.rs b/native_implemented/otp/src/erlang/link_1.rs
index 87150d45e..fae668891 100644
--- a/native_implemented/otp/src/erlang/link_1.rs
+++ b/native_implemented/otp/src/erlang/link_1.rs
@@ -1,19 +1,21 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
+use std::ptr::NonNull;
+
 use anyhow::*;
 
-use liblumen_alloc::erts::exception::{self, error};
-use liblumen_alloc::erts::process::trace::Trace;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::backtrace::Trace;
+use firefly_rt::process::Process;
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::{Atom, Term};
 
 use crate::runtime::registry::pid_to_process;
 
 #[native_implemented::function(erlang:link/1)]
-fn result(process: &Process, pid_or_port: Term) -> exception::Result<Term> {
-    match pid_or_port.decode()? {
-        TypedTerm::Pid(pid) => {
+fn result(process: &Process, pid_or_port: Term) -> Result<Term, NonNull<ErlangException>> {
+    match pid_or_port {
+        Term::Pid(pid) => {
             if pid == process.pid() {
                 Ok(true.into())
             } else {
@@ -35,9 +37,7 @@ fn result(process: &Process, pid_or_port: Term) -> exception::Result<Term> {
                 }
             }
         }
-        TypedTerm::Port(_) => unimplemented!(),
-        TypedTerm::ExternalPid(_) => unimplemented!(),
-        TypedTerm::ExternalPort(_) => unimplemented!(),
+        Term::Port(_) => unimplemented!(),
         _ => Err(TypeError)
             .context(format!(
                 "pid_or_port ({}) is neither a pid nor a port",
diff --git a/native_implemented/otp/src/erlang/link_1/test.rs b/native_implemented/otp/src/erlang/link_1/test.rs
index 6ba357686..f9aea3e7a 100644
--- a/native_implemented/otp/src/erlang/link_1/test.rs
+++ b/native_implemented/otp/src/erlang/link_1/test.rs
@@ -2,12 +2,10 @@ mod with_local_pid;
 
 use anyhow::*;
 
-use proptest::strategy::{Just, Strategy};
+use proptest::strategy::Just;
 
-use liblumen_alloc::erts::exception::error;
-use liblumen_alloc::erts::process::trace::Trace;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::*;
 
 use crate::erlang::link_1::result;
 use crate::test::{strategy, with_process};
diff --git a/native_implemented/otp/src/erlang/list_to_atom_1.rs b/native_implemented/otp/src/erlang/list_to_atom_1.rs
index 096e4d9ea..b1f2648a9 100644
--- a/native_implemented/otp/src/erlang/list_to_atom_1.rs
+++ b/native_implemented/otp/src/erlang/list_to_atom_1.rs
@@ -1,15 +1,17 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
+use std::ptr::NonNull;
+
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::{Atom, Term};
 
 use crate::erlang::list_to_string::list_to_string;
 
 #[native_implemented::function(erlang:list_to_atom/1)]
-pub fn result(string: Term) -> exception::Result<Term> {
+pub fn result(string: Term) -> Result<Term, NonNull<ErlangException>> {
     list_to_string(string).and_then(|s| match Atom::try_from_str(s) {
         Ok(atom) => Ok(atom.encode()?),
         Err(atom_error) => Err(atom_error)
diff --git a/native_implemented/otp/src/erlang/list_to_atom_1/test.rs b/native_implemented/otp/src/erlang/list_to_atom_1/test.rs
index 640b14f64..a8c98628e 100644
--- a/native_implemented/otp/src/erlang/list_to_atom_1/test.rs
+++ b/native_implemented/otp/src/erlang/list_to_atom_1/test.rs
@@ -1,9 +1,9 @@
 use proptest::arbitrary::any;
 use proptest::prop_assert_eq;
-use proptest::strategy::{Just, Strategy};
+use proptest::strategy::Just;
 use proptest::test_runner::{Config, TestRunner};
 
-use liblumen_alloc::erts::term::prelude::{Atom, Term};
+use firefly_rt::term::{Atom, Term};
 
 use crate::erlang::list_to_atom_1::result;
 use crate::test::strategy;
@@ -24,7 +24,7 @@ fn without_list_errors_badarg() {
 
 #[test]
 fn with_empty_list_returns_empty_atom() {
-    assert_eq!(result(Term::NIL), Ok(Atom::str_to_term("")));
+    assert_eq!(result(Term::Nil), Ok(Atom::str_to_term("")));
 }
 
 #[test]
@@ -32,7 +32,7 @@ fn with_improper_list_errors_badarg() {
     with_process_arc(|arc_process| {
         TestRunner::new(Config::with_source_file(file!()))
             .run(&strategy::term::is_not_list(arc_process.clone()), |tail| {
-                let list = arc_process.cons(arc_process.integer('c'), tail);
+                let list = arc_process.cons(arc_process.integer('c').unwrap(), tail);
 
                 prop_assert_badarg!(result(list), format!("list ({}) is improper", list));
 
@@ -48,8 +48,8 @@ fn with_non_empty_proper_list_returns_atom() {
         |arc_process| {
             (Just(arc_process.clone()), any::<String>()).prop_map(|(arc_process, string)| {
                 let codepoint_terms: Vec<Term> =
-                    string.chars().map(|c| arc_process.integer(c)).collect();
-                let list = arc_process.list_from_slice(&codepoint_terms);
+                    string.chars().map(|c| arc_process.integer(c).unwrap()).collect();
+                let list = arc_process.list_from_slice(&codepoint_terms).unwrap();
 
                 (list, string)
             })
diff --git a/native_implemented/otp/src/erlang/list_to_binary_1.rs b/native_implemented/otp/src/erlang/list_to_binary_1.rs
index 36341a541..1735cec6e 100644
--- a/native_implemented/otp/src/erlang/list_to_binary_1.rs
+++ b/native_implemented/otp/src/erlang/list_to_binary_1.rs
@@ -1,18 +1,20 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
+use std::ptr::NonNull;
+
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::iolist_or_binary;
 
 #[native_implemented::function(erlang:list_to_binary/1)]
-pub fn result(process: &Process, iolist: Term) -> exception::Result<Term> {
-    match iolist.decode()? {
-        TypedTerm::Nil | TypedTerm::List(_) => {
+pub fn result(process: &Process, iolist: Term) -> Result<Term, NonNull<ErlangException>> {
+    match iolist {
+        Term::Nil | Term::Cons(_) => {
             iolist_or_binary::to_binary(process, "iolist", iolist)
         }
         _ => Err(TypeError)
diff --git a/native_implemented/otp/src/erlang/list_to_binary_1/test.rs b/native_implemented/otp/src/erlang/list_to_binary_1/test.rs
index 8c826d4b3..8ec9547c4 100644
--- a/native_implemented/otp/src/erlang/list_to_binary_1/test.rs
+++ b/native_implemented/otp/src/erlang/list_to_binary_1/test.rs
@@ -1,6 +1,5 @@
 mod with_list;
 
-use std::convert::TryInto;
 use std::sync::Arc;
 
 use proptest::arbitrary::any;
@@ -8,8 +7,8 @@ use proptest::strategy::{BoxedStrategy, Just, Strategy};
 use proptest::test_runner::{Config, TestRunner};
 use proptest::{prop_assert, prop_assert_eq, prop_oneof};
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::list_to_binary_1::result;
 use crate::test::strategy;
@@ -39,7 +38,7 @@ fn without_list_errors_badarg() {
 fn with_empty_list_returns_empty_binary() {
     with_process(|process| {
         assert_eq!(
-            result(process, Term::NIL),
+            result(process, Term::Nil),
             Ok(process.binary_from_bytes(&[]))
         );
     });
@@ -63,9 +62,9 @@ fn otp_doctest_returns_binary() {
         let iolist = process.improper_list_from_slice(
             &[
                 bin1,
-                process.integer(1),
-                process.list_from_slice(&[process.integer(2), process.integer(3), bin2]),
-                process.integer(4),
+                process.integer(1).unwrap(),
+                process.list_from_slice(&[process.integer(2).unwrap(), process.integer(3).unwrap(), bin2]).unwrap(),
+                process.integer(4).unwrap(),
             ],
             bin3,
         );
@@ -99,7 +98,7 @@ fn with_procbin_in_list_returns_binary() {
         let procbin = process.binary_from_bytes(&bytes);
         // We expect this to be a procbin, since it's > 64 bytes. Make sure it is.
         assert!(procbin.is_boxed_procbin());
-        let list = process.list_from_slice(&[procbin]);
+        let list = process.list_from_slice(&[procbin]).unwrap();
 
         assert_eq!(result(process, list), Ok(process.binary_from_bytes(&bytes)))
     });
@@ -107,7 +106,7 @@ fn with_procbin_in_list_returns_binary() {
 
 fn byte(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
     any::<u8>()
-        .prop_map(move |byte| arc_process.integer(byte))
+        .prop_map(move |byte| arc_process.integer(byte).unwrap())
         .boxed()
 }
 
@@ -139,7 +138,7 @@ fn recursive(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
 }
 
 fn tail(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
-    prop_oneof![strategy::term::is_binary(arc_process), Just(Term::NIL)].boxed()
+    prop_oneof![strategy::term::is_binary(arc_process), Just(Term::Nil)].boxed()
 }
 
 fn top(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
diff --git a/native_implemented/otp/src/erlang/list_to_binary_1/test/with_list.rs b/native_implemented/otp/src/erlang/list_to_binary_1/test/with_list.rs
index bc1afc900..970a73733 100644
--- a/native_implemented/otp/src/erlang/list_to_binary_1/test/with_list.rs
+++ b/native_implemented/otp/src/erlang/list_to_binary_1/test/with_list.rs
@@ -1,6 +1,6 @@
 use super::*;
 
-use proptest::strategy::{Just, Strategy};
+use proptest::strategy::Just;
 
 mod with_binary_subbinary;
 mod with_byte;
@@ -17,7 +17,7 @@ fn without_byte_binary_or_list_element_errors_badarg() {
                 .prop_map(|(arc_process, element)| {
                     (
                         arc_process.clone(),
-                        arc_process.cons(element, Term::NIL),
+                        arc_process.cons(element, Term::Nil),
                         element,
                     )
                 })
@@ -39,7 +39,7 @@ fn without_byte_binary_or_list_element_errors_badarg() {
 #[test]
 fn with_empty_list_element_returns_empty_binary() {
     with_process(|process| {
-        let iolist = process.cons(Term::NIL, Term::NIL);
+        let iolist = process.cons(Term::Nil, Term::Nil);
 
         assert_eq!(result(process, iolist), Ok(process.binary_from_bytes(&[])));
     })
@@ -55,7 +55,7 @@ fn with_subbinary_with_bit_count_errors_badarg() {
             )
         },
         |(arc_process, element)| {
-            let iolist = arc_process.list_from_slice(&[element]);
+            let iolist = arc_process.list_from_slice(&[element]).unwrap();
 
             prop_assert_badarg!(
                 result(&arc_process, iolist),
@@ -73,8 +73,8 @@ fn with_subbinary_with_bit_count_errors_badarg() {
 fn is_integer_is_not_byte(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
     prop_oneof![
         strategy::term::integer::negative(arc_process.clone()),
-        (Just(arc_process.clone()), (256..=SmallInteger::MAX_VALUE))
-            .prop_map(|(arc_process, i)| arc_process.integer(i)),
+        (Just(arc_process.clone()), (256..=Integer::MAX_SMALL))
+            .prop_map(|(arc_process, i)| arc_process.integer(i).unwrap()),
         strategy::term::integer::big::positive(arc_process)
     ]
     .boxed()
@@ -85,8 +85,8 @@ fn is_not_byte_binary_nor_list(arc_process: Arc<Process>) -> BoxedStrategy<Term>
         .prop_filter("Element must not be a binary or byte", move |element| {
             !(element.is_binary()
                 || (element.is_integer()
-                    && &arc_process.integer(0) <= element
-                    && element <= &arc_process.integer(256_isize))
+                    && &arc_process.integer(0).unwrap() <= element
+                    && element <= &arc_process.integer(256_isize).unwrap())
                 || element.is_list())
         })
         .boxed()
diff --git a/native_implemented/otp/src/erlang/list_to_binary_1/test/with_list/with_binary_subbinary.rs b/native_implemented/otp/src/erlang/list_to_binary_1/test/with_list/with_binary_subbinary.rs
index 914e4a3bb..c82ce6fea 100644
--- a/native_implemented/otp/src/erlang/list_to_binary_1/test/with_list/with_binary_subbinary.rs
+++ b/native_implemented/otp/src/erlang/list_to_binary_1/test/with_list/with_binary_subbinary.rs
@@ -39,7 +39,7 @@ fn with_empty_list_returns_binary_containing_subbinary_bytes() {
                     (
                         arc_process.clone(),
                         element,
-                        arc_process.cons(element, Term::NIL),
+                        arc_process.cons(element, Term::Nil),
                     )
                 })
         },
@@ -82,9 +82,9 @@ fn with_byte_errors_badarg() {
 fn with_list_without_byte_tail_returns_binary() {
     with(|head, process| {
         let tail_head_byte = 254;
-        let tail_head = process.integer(tail_head_byte);
+        let tail_head = process.integer(tail_head_byte).unwrap();
 
-        let tail_tail = Term::NIL;
+        let tail_tail = Term::Nil;
 
         let tail = process.cons(tail_head, tail_tail);
 
diff --git a/native_implemented/otp/src/erlang/list_to_binary_1/test/with_list/with_byte.rs b/native_implemented/otp/src/erlang/list_to_binary_1/test/with_list/with_byte.rs
index bf809cce4..d3e6b3af0 100644
--- a/native_implemented/otp/src/erlang/list_to_binary_1/test/with_list/with_byte.rs
+++ b/native_implemented/otp/src/erlang/list_to_binary_1/test/with_list/with_byte.rs
@@ -34,7 +34,7 @@ fn with_empty_list_returns_1_byte_binary() {
             (Just(arc_process.clone()), any::<u8>()).prop_map(|(arc_process, byte)| {
                 (
                     arc_process.clone(),
-                    arc_process.cons(arc_process.integer(byte), Term::NIL),
+                    arc_process.cons(arc_process.integer(byte).unwrap(), Term::Nil),
                     byte,
                 )
             })
@@ -76,9 +76,9 @@ fn with_byte_errors_badarg() {
 fn with_list_without_byte_tail_returns_binary() {
     with(|head_byte, head, process| {
         let tail_head_byte = 254;
-        let tail_head = process.integer(tail_head_byte);
+        let tail_head = process.integer(tail_head_byte).unwrap();
 
-        let tail_tail = Term::NIL;
+        let tail_tail = Term::Nil;
 
         let tail = process.cons(tail_head, tail_tail);
 
@@ -152,7 +152,7 @@ where
 {
     with_process(|process| {
         let head_byte: u8 = 0;
-        let head = process.integer(head_byte);
+        let head = process.integer(head_byte).unwrap();
 
         f(head_byte, head, &process);
     })
diff --git a/native_implemented/otp/src/erlang/list_to_binary_1/test/with_list/with_heap_binary.rs b/native_implemented/otp/src/erlang/list_to_binary_1/test/with_list/with_heap_binary.rs
index e50b805c3..cd9eaf9be 100644
--- a/native_implemented/otp/src/erlang/list_to_binary_1/test/with_list/with_heap_binary.rs
+++ b/native_implemented/otp/src/erlang/list_to_binary_1/test/with_list/with_heap_binary.rs
@@ -38,7 +38,7 @@ fn with_empty_list_returns_binary() {
                 .prop_map(|(arc_process, binary)| {
                     (
                         arc_process.clone(),
-                        arc_process.cons(binary, Term::NIL),
+                        arc_process.cons(binary, Term::Nil),
                         binary,
                     )
                 })
@@ -79,8 +79,8 @@ fn with_byte_errors_badarg() {
 fn with_list_without_byte_tail_returns_binary() {
     with(|head, process| {
         let tail_head_byte = 3;
-        let tail_head = process.integer(tail_head_byte);
-        let tail_tail = Term::NIL;
+        let tail_head = process.integer(tail_head_byte).unwrap();
+        let tail_tail = Term::Nil;
         let tail = process.cons(tail_head, tail_tail);
         let iolist = process.cons(head, tail);
 
diff --git a/native_implemented/otp/src/erlang/list_to_bitstring_1.rs b/native_implemented/otp/src/erlang/list_to_bitstring_1.rs
index 7137a04cd..b2ee457e8 100644
--- a/native_implemented/otp/src/erlang/list_to_bitstring_1.rs
+++ b/native_implemented/otp/src/erlang/list_to_bitstring_1.rs
@@ -2,25 +2,26 @@
 mod test;
 
 use std::convert::TryInto;
+use std::ptr::NonNull;
 
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:list_to_bitstring/1)]
-pub fn result(process: &Process, bitstring_list: Term) -> exception::Result<Term> {
-    match bitstring_list.decode()? {
-        TypedTerm::Nil | TypedTerm::List(_) => {
+pub fn result(process: &Process, bitstring_list: Term) -> Result<Term, NonNull<ErlangException>> {
+    match bitstring_list {
+        Term::Nil | Term::Cons(_) => {
             let mut byte_vec: Vec<u8> = Vec::new();
             let mut partial_byte_bit_count = 0;
             let mut partial_byte = 0;
             let mut stack: Vec<Term> = vec![bitstring_list];
 
             while let Some(top) = stack.pop() {
-                match top.decode()? {
-                    TypedTerm::SmallInteger(small_integer) => {
+                match top {
+                    Term::Int(small_integer) => {
                         let top_byte = small_integer
                             .try_into()
                             .context(element_context(bitstring_list, top))?;
@@ -34,14 +35,15 @@ pub fn result(process: &Process, bitstring_list: Term) -> exception::Result<Term
                             partial_byte = top_byte << (8 - partial_byte_bit_count);
                         }
                     }
-                    TypedTerm::Nil => (),
-                    TypedTerm::List(boxed_cons) => {
+                    Term::Nil => (),
+                    Term::Cons(non_null_cons) => {
+                        let cons = unsafe { non_null_cons.as_ref() };
                         // @type bitstring_list ::
                         //   maybe_improper_list(byte() | bitstring() | bitstring_list(),
                         //                       bitstring() | [])
                         // means that `byte()` isn't allowed for `tail`s unlike `head`.
 
-                        let tail = boxed_cons.tail;
+                        let tail = cons.tail();
                         let result_u8: Result<u8, _> = tail.try_into();
 
                         match result_u8 {
@@ -56,9 +58,9 @@ pub fn result(process: &Process, bitstring_list: Term) -> exception::Result<Term
                             Err(_) => stack.push(tail),
                         };
 
-                        stack.push(boxed_cons.head);
+                        stack.push(cons.head());
                     }
-                    TypedTerm::HeapBinary(heap_binary) => {
+                    Term::HeapBinary(heap_binary) => {
                         if partial_byte_bit_count == 0 {
                             byte_vec.extend_from_slice(heap_binary.as_bytes());
                         } else {
@@ -70,7 +72,7 @@ pub fn result(process: &Process, bitstring_list: Term) -> exception::Result<Term
                             }
                         }
                     }
-                    TypedTerm::SubBinary(subbinary) => {
+                    Term::RefBinary(subbinary) => {
                         if partial_byte_bit_count == 0 {
                             if subbinary.is_aligned() {
                                 byte_vec.extend(unsafe { subbinary.as_bytes_unchecked() });
diff --git a/native_implemented/otp/src/erlang/list_to_bitstring_1/test.rs b/native_implemented/otp/src/erlang/list_to_bitstring_1/test.rs
index 4209e52a6..ea124d3d2 100644
--- a/native_implemented/otp/src/erlang/list_to_bitstring_1/test.rs
+++ b/native_implemented/otp/src/erlang/list_to_bitstring_1/test.rs
@@ -7,8 +7,8 @@ use proptest::strategy::{BoxedStrategy, Just, Strategy};
 use proptest::test_runner::{Config, TestRunner};
 use proptest::{prop_assert, prop_assert_eq, prop_oneof};
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::list_to_bitstring_1::result;
 use crate::test::strategy;
@@ -34,7 +34,7 @@ fn without_list_errors_badarg() {
 fn with_empty_list_returns_empty_binary() {
     with_process(|process| {
         assert_eq!(
-            result(process, Term::NIL),
+            result(process, Term::Nil),
             Ok(process.binary_from_bytes(&[]))
         );
     });
@@ -58,9 +58,9 @@ fn otp_doctest_returns_binary() {
         let iolist = process.improper_list_from_slice(
             &[
                 bin1,
-                process.integer(1),
-                process.list_from_slice(&[process.integer(2), process.integer(3), bin2]),
-                process.integer(4),
+                process.integer(1).unwrap(),
+                process.list_from_slice(&[process.integer(2).unwrap(), process.integer(3).unwrap(), bin2]).unwrap(),
+                process.integer(4).unwrap(),
             ],
             bin3,
         );
@@ -90,7 +90,7 @@ fn with_recursive_lists_of_bitstrings_and_bytes_ending_in_bitstring_or_empty_lis
 
 fn byte(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
     any::<u8>()
-        .prop_map(move |byte| arc_process.integer(byte))
+        .prop_map(move |byte| arc_process.integer(byte).unwrap())
         .boxed()
 }
 
@@ -122,7 +122,7 @@ fn recursive(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
 }
 
 fn tail(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
-    prop_oneof![strategy::term::is_bitstring(arc_process), Just(Term::NIL)].boxed()
+    prop_oneof![strategy::term::is_bitstring(arc_process), Just(Term::Nil)].boxed()
 }
 
 fn top(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
diff --git a/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list.rs b/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list.rs
index cb308a486..b5776b62d 100644
--- a/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list.rs
+++ b/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list.rs
@@ -22,7 +22,7 @@ fn without_byte_bitstring_or_list_element_errors_badarg() {
                 .prop_map(|(arc_process, element)| {
                     (
                         arc_process.clone(),
-                        arc_process.cons(element, Term::NIL),
+                        arc_process.cons(element, Term::Nil),
                         element,
                     )
                 })
@@ -38,7 +38,7 @@ fn without_byte_bitstring_or_list_element_errors_badarg() {
 #[test]
 fn with_empty_list_returns_empty_binary() {
     with_process(|process| {
-        let iolist = process.cons(Term::NIL, Term::NIL);
+        let iolist = process.cons(Term::Nil, Term::Nil);
 
         assert_eq!(result(process, iolist), Ok(process.binary_from_bytes(&[])));
     })
@@ -56,8 +56,8 @@ fn is_not_byte_bitstring_nor_list(arc_process: Arc<Process>) -> BoxedStrategy<Te
         .prop_filter("Element must not be a binary or byte", move |element| {
             !(element.is_bitstring()
                 || (element.is_integer()
-                    && &arc_process.integer(0) <= element
-                    && element <= &arc_process.integer(256))
+                    && &arc_process.integer(0).unwrap() <= element
+                    && element <= &arc_process.integer(256).unwrap())
                 || element.is_list())
         })
         .boxed()
diff --git a/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_0_bit_subbinary.rs b/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_0_bit_subbinary.rs
index 2e51095ed..1027ef8b8 100644
--- a/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_0_bit_subbinary.rs
+++ b/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_0_bit_subbinary.rs
@@ -33,7 +33,7 @@ fn with_empty_list_returns_bitstring() {
                 strategy::term::binary::sub::with_bit_count(0, arc_process.clone()),
             )
                 .prop_map(|(arc_process, head)| {
-                    (arc_process.clone(), arc_process.cons(head, Term::NIL), head)
+                    (arc_process.clone(), arc_process.cons(head, Term::Nil), head)
                 })
         },
         |(arc_process, list, bitstring)| {
@@ -46,15 +46,15 @@ fn with_empty_list_returns_bitstring() {
 
 #[test]
 fn with_byte_errors_badarg() {
-    with_tail_errors_badarg(|process| process.integer(2));
+    with_tail_errors_badarg(|process| process.integer(2).unwrap());
 }
 
 #[test]
 fn with_proper_list_returns_binary() {
     with(|head, process| {
         let tail_head_byte = 2;
-        let tail_head = process.integer(tail_head_byte);
-        let tail_tail = Term::NIL;
+        let tail_head = process.integer(tail_head_byte).unwrap();
+        let tail_tail = Term::Nil;
         let tail = process.cons(tail_head, tail_tail);
 
         let iolist = process.cons(head, tail);
diff --git a/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_1_bit_subbinary.rs b/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_1_bit_subbinary.rs
index 7bc3b443f..ce7096374 100644
--- a/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_1_bit_subbinary.rs
+++ b/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_1_bit_subbinary.rs
@@ -33,7 +33,7 @@ fn with_empty_list_returns_bitstring() {
                 strategy::term::binary::sub::with_bit_count(1, arc_process.clone()),
             )
                 .prop_map(|(arc_process, head)| {
-                    (arc_process.clone(), arc_process.cons(head, Term::NIL), head)
+                    (arc_process.clone(), arc_process.cons(head, Term::Nil), head)
                 })
         },
         |(arc_process, list, bitstring)| {
@@ -46,14 +46,14 @@ fn with_empty_list_returns_bitstring() {
 
 #[test]
 fn with_byte_tail_errors_badarg() {
-    with_tail_errors_badarg(|process| process.integer(2))
+    with_tail_errors_badarg(|process| process.integer(2).unwrap())
 }
 
 #[test]
 fn with_proper_list_returns_binary() {
     with(|head, process| {
-        let tail_head = process.integer(254);
-        let tail_tail = Term::NIL;
+        let tail_head = process.integer(254).unwrap();
+        let tail_tail = Term::Nil;
         let tail = process.cons(tail_head, tail_tail);
 
         let iolist = process.cons(head, tail);
diff --git a/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_2_bit_subbinary.rs b/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_2_bit_subbinary.rs
index dc9ad2f3a..c65c7b847 100644
--- a/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_2_bit_subbinary.rs
+++ b/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_2_bit_subbinary.rs
@@ -33,7 +33,7 @@ fn with_empty_list_returns_bitstring() {
                 strategy::term::binary::sub::with_bit_count(2, arc_process.clone()),
             )
                 .prop_map(|(arc_process, head)| {
-                    (arc_process.clone(), arc_process.cons(head, Term::NIL), head)
+                    (arc_process.clone(), arc_process.cons(head, Term::Nil), head)
                 })
         },
         |(arc_process, list, bitstring)| {
@@ -46,14 +46,14 @@ fn with_empty_list_returns_bitstring() {
 
 #[test]
 fn with_byte_tail_errors_badarg() {
-    with_tail_errors_badarg(|process| process.integer(2))
+    with_tail_errors_badarg(|process| process.integer(2).unwrap())
 }
 
 #[test]
 fn with_proper_list_returns_binary() {
     with(|head, process| {
-        let tail_head = process.integer(254);
-        let tail_tail = Term::NIL;
+        let tail_head = process.integer(254).unwrap();
+        let tail_tail = Term::Nil;
         let tail = process.cons(tail_head, tail_tail);
 
         let iolist = process.cons(head, tail);
diff --git a/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_3_bit_subbinary.rs b/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_3_bit_subbinary.rs
index dbdd70652..23480b3cd 100644
--- a/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_3_bit_subbinary.rs
+++ b/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_3_bit_subbinary.rs
@@ -33,7 +33,7 @@ fn with_empty_list_returns_bitstring() {
                 strategy::term::binary::sub::with_bit_count(3, arc_process.clone()),
             )
                 .prop_map(|(arc_process, head)| {
-                    (arc_process.clone(), arc_process.cons(head, Term::NIL), head)
+                    (arc_process.clone(), arc_process.cons(head, Term::Nil), head)
                 })
         },
         |(arc_process, list, bitstring)| {
@@ -46,15 +46,15 @@ fn with_empty_list_returns_bitstring() {
 
 #[test]
 fn with_improper_list_returns_binary() {
-    with_tail_errors_badarg(|process| process.integer(253));
+    with_tail_errors_badarg(|process| process.integer(253).unwrap());
 }
 
 #[test]
 fn with_proper_list_returns_binary() {
     with(|head, process| {
         let tail_head_byte = 254;
-        let tail_head = process.integer(tail_head_byte);
-        let tail_tail = Term::NIL;
+        let tail_head = process.integer(tail_head_byte).unwrap();
+        let tail_tail = Term::Nil;
         let tail = process.cons(tail_head, tail_tail);
 
         let iolist = process.cons(head, tail);
diff --git a/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_4_bit_subbinary.rs b/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_4_bit_subbinary.rs
index 16482eeff..088adfd23 100644
--- a/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_4_bit_subbinary.rs
+++ b/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_4_bit_subbinary.rs
@@ -33,7 +33,7 @@ fn with_empty_list_returns_bitstring() {
                 strategy::term::binary::sub::with_bit_count(4, arc_process.clone()),
             )
                 .prop_map(|(arc_process, head)| {
-                    (arc_process.clone(), arc_process.cons(head, Term::NIL), head)
+                    (arc_process.clone(), arc_process.cons(head, Term::Nil), head)
                 })
         },
         |(arc_process, list, bitstring)| {
@@ -47,7 +47,7 @@ fn with_empty_list_returns_bitstring() {
 #[test]
 fn with_empty_list_returns_binary() {
     with(|head, process| {
-        let tail = Term::NIL;
+        let tail = Term::Nil;
         let iolist = process.cons(head, tail);
 
         assert_eq!(result(process, iolist), Ok(head));
@@ -56,15 +56,15 @@ fn with_empty_list_returns_binary() {
 
 #[test]
 fn with_byte_tail_errors_badarg() {
-    with_tail_errors_badarg(|process| process.integer(253));
+    with_tail_errors_badarg(|process| process.integer(253).unwrap());
 }
 
 #[test]
 fn with_proper_list_returns_binary() {
     with(|head, process| {
         let tail_head_byte = 254;
-        let tail_head = process.integer(tail_head_byte);
-        let tail_tail = Term::NIL;
+        let tail_head = process.integer(tail_head_byte).unwrap();
+        let tail_tail = Term::Nil;
         let tail = process.cons(tail_head, tail_tail);
 
         let iolist = process.cons(head, tail);
diff --git a/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_5_bit_subbinary.rs b/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_5_bit_subbinary.rs
index 3421d6624..004b5da8e 100644
--- a/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_5_bit_subbinary.rs
+++ b/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_5_bit_subbinary.rs
@@ -33,7 +33,7 @@ fn with_empty_list_returns_bitstring() {
                 strategy::term::binary::sub::with_bit_count(5, arc_process.clone()),
             )
                 .prop_map(|(arc_process, head)| {
-                    (arc_process.clone(), arc_process.cons(head, Term::NIL), head)
+                    (arc_process.clone(), arc_process.cons(head, Term::Nil), head)
                 })
         },
         |(arc_process, list, bitstring)| {
@@ -47,7 +47,7 @@ fn with_empty_list_returns_bitstring() {
 #[test]
 fn with_empty_list_returns_binary() {
     with(|head, process| {
-        let tail = Term::NIL;
+        let tail = Term::Nil;
         let iolist = process.cons(head, tail);
 
         assert_eq!(result(process, iolist), Ok(head));
@@ -56,15 +56,15 @@ fn with_empty_list_returns_binary() {
 
 #[test]
 fn with_byte_tail_errors_badarg() {
-    with_tail_errors_badarg(|process| process.integer(253));
+    with_tail_errors_badarg(|process| process.integer(253).unwrap());
 }
 
 #[test]
 fn with_proper_list_returns_binary() {
     with(|head, process| {
         let tail_head_byte = 254;
-        let tail_head = process.integer(tail_head_byte);
-        let tail_tail = Term::NIL;
+        let tail_head = process.integer(tail_head_byte).unwrap();
+        let tail_tail = Term::Nil;
         let tail = process.cons(tail_head, tail_tail);
 
         let iolist = process.cons(head, tail);
diff --git a/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_6_bit_subbinary.rs b/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_6_bit_subbinary.rs
index 3acb6c4b7..d9a4ce2e7 100644
--- a/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_6_bit_subbinary.rs
+++ b/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_6_bit_subbinary.rs
@@ -33,7 +33,7 @@ fn with_empty_list_returns_bitstring() {
                 strategy::term::binary::sub::with_bit_count(5, arc_process.clone()),
             )
                 .prop_map(|(arc_process, head)| {
-                    (arc_process.clone(), arc_process.cons(head, Term::NIL), head)
+                    (arc_process.clone(), arc_process.cons(head, Term::Nil), head)
                 })
         },
         |(arc_process, list, bitstring)| {
@@ -47,7 +47,7 @@ fn with_empty_list_returns_bitstring() {
 #[test]
 fn with_empty_list_returns_binary() {
     with(|head, process| {
-        let tail = Term::NIL;
+        let tail = Term::Nil;
         let iolist = process.cons(head, tail);
 
         assert_eq!(result(process, iolist), Ok(head));
@@ -56,15 +56,15 @@ fn with_empty_list_returns_binary() {
 
 #[test]
 fn with_byte_tail_errors_badarg() {
-    with_tail_errors_badarg(|process| process.integer(253));
+    with_tail_errors_badarg(|process| process.integer(253).unwrap());
 }
 
 #[test]
 fn with_proper_list_returns_binary() {
     with(|head, process| {
         let tail_head_byte = 254;
-        let tail_head = process.integer(tail_head_byte);
-        let tail_tail = Term::NIL;
+        let tail_head = process.integer(tail_head_byte).unwrap();
+        let tail_tail = Term::Nil;
         let tail = process.cons(tail_head, tail_tail);
 
         let iolist = process.cons(head, tail);
diff --git a/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_7_bit_subbinary.rs b/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_7_bit_subbinary.rs
index f11faefea..9baaffc0b 100644
--- a/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_7_bit_subbinary.rs
+++ b/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_7_bit_subbinary.rs
@@ -33,7 +33,7 @@ fn with_empty_list_returns_bitstring() {
                 strategy::term::binary::sub::with_bit_count(5, arc_process.clone()),
             )
                 .prop_map(|(arc_process, head)| {
-                    (arc_process.clone(), arc_process.cons(head, Term::NIL), head)
+                    (arc_process.clone(), arc_process.cons(head, Term::Nil), head)
                 })
         },
         |(arc_process, list, bitstring)| {
@@ -47,7 +47,7 @@ fn with_empty_list_returns_bitstring() {
 #[test]
 fn with_empty_list_returns_binary() {
     with(|head, process| {
-        let tail = Term::NIL;
+        let tail = Term::Nil;
         let iolist = process.cons(head, tail);
 
         assert_eq!(result(process, iolist), Ok(head));
@@ -56,15 +56,15 @@ fn with_empty_list_returns_binary() {
 
 #[test]
 fn with_byte_tail_errors_badarg() {
-    with_tail_errors_badarg(|process| process.integer(253));
+    with_tail_errors_badarg(|process| process.integer(253).unwrap());
 }
 
 #[test]
 fn with_proper_list_returns_binary() {
     with(|head, process| {
         let tail_head_byte = 254;
-        let tail_head = process.integer(tail_head_byte);
-        let tail_tail = Term::NIL;
+        let tail_head = process.integer(tail_head_byte).unwrap();
+        let tail_tail = Term::Nil;
         let tail = process.cons(tail_head, tail_tail);
 
         let iolist = process.cons(head, tail);
diff --git a/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_byte.rs b/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_byte.rs
index f3e0fb2a1..f4b844ad3 100644
--- a/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_byte.rs
+++ b/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_byte.rs
@@ -27,7 +27,7 @@ fn without_byte_bitstring_or_list_element_errors_badarg() {
 #[test]
 fn with_empty_list_returns_1_byte_binary() {
     with(|head_byte, head, process| {
-        let tail = Term::NIL;
+        let tail = Term::Nil;
         let iolist = process.cons(head, tail);
 
         assert_eq!(
@@ -39,15 +39,15 @@ fn with_empty_list_returns_1_byte_binary() {
 
 #[test]
 fn with_byte_tail_errors_badarg() {
-    with_tail_errors_badarg(|process| process.integer(2));
+    with_tail_errors_badarg(|process| process.integer(2).unwrap());
 }
 
 #[test]
 fn with_proper_list_returns_binary() {
     with(|_, head, process| {
         let tail_head_byte = 1;
-        let tail_head = process.integer(tail_head_byte);
-        let tail_tail = Term::NIL;
+        let tail_head = process.integer(tail_head_byte).unwrap();
+        let tail_tail = Term::Nil;
         let tail = process.cons(tail_head, tail_tail);
 
         let iolist = process.cons(head, tail);
@@ -204,7 +204,7 @@ where
 {
     with_process(|process| {
         let head_byte: u8 = 0;
-        let head = process.integer(head_byte);
+        let head = process.integer(head_byte).unwrap();
 
         f(head_byte, head, &process);
     })
diff --git a/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_heap_binary.rs b/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_heap_binary.rs
index a5ff4f162..c067edbd8 100644
--- a/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_heap_binary.rs
+++ b/native_implemented/otp/src/erlang/list_to_bitstring_1/test/with_list/with_heap_binary.rs
@@ -27,7 +27,7 @@ fn without_byte_bitstring_or_list_element_errors_badarg() {
 #[test]
 fn with_empty_list_returns_binary() {
     with(|head, process| {
-        let tail = Term::NIL;
+        let tail = Term::Nil;
         let iolist = process.cons(head, tail);
 
         assert_eq!(
@@ -39,15 +39,15 @@ fn with_empty_list_returns_binary() {
 
 #[test]
 fn with_byte_tail_errors_badarg() {
-    with_tail_errors_badarg(|process| process.integer(2));
+    with_tail_errors_badarg(|process| process.integer(2).unwrap());
 }
 
 #[test]
 fn with_proper_list_returns_binary() {
     with(|head, process| {
         let tail_head_byte = 2;
-        let tail_head = process.integer(tail_head_byte);
-        let tail_tail = Term::NIL;
+        let tail_head = process.integer(tail_head_byte).unwrap();
+        let tail_tail = Term::Nil;
         let tail = process.cons(tail_head, tail_tail);
 
         let iolist = process.cons(head, tail);
diff --git a/native_implemented/otp/src/erlang/list_to_existing_atom_1.rs b/native_implemented/otp/src/erlang/list_to_existing_atom_1.rs
index a52825dc9..dfe8e51c5 100644
--- a/native_implemented/otp/src/erlang/list_to_existing_atom_1.rs
+++ b/native_implemented/otp/src/erlang/list_to_existing_atom_1.rs
@@ -1,15 +1,17 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
+use std::ptr::NonNull;
+
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::{Atom, Term};
 
 use crate::erlang::list_to_string::list_to_string;
 
 #[native_implemented::function(erlang:list_to_existing_atom/1)]
-pub fn result(string: Term) -> exception::Result<Term> {
+pub fn result(string: Term) -> Result<Term, NonNull<ErlangException>> {
     let string_string = list_to_string(string)?;
     let atom = Atom::try_from_str_existing(string_string)
         .with_context(|| format!("string ({})", string))?;
diff --git a/native_implemented/otp/src/erlang/list_to_existing_atom_1/test.rs b/native_implemented/otp/src/erlang/list_to_existing_atom_1/test.rs
index c2273f38d..fdc0e21c4 100644
--- a/native_implemented/otp/src/erlang/list_to_existing_atom_1/test.rs
+++ b/native_implemented/otp/src/erlang/list_to_existing_atom_1/test.rs
@@ -1,8 +1,8 @@
 use proptest::arbitrary::any;
 use proptest::prop_assert_eq;
-use proptest::strategy::{Just, Strategy};
+use proptest::strategy::Just;
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::{Atom, Term};
 
 use crate::erlang::list_to_existing_atom_1::result;
 use crate::test::strategy;
@@ -21,7 +21,7 @@ fn without_list_errors_badarg() {
 
 #[test]
 fn with_empty_list() {
-    let list = Term::NIL;
+    let list = Term::Nil;
 
     // as `""` can only be entered into the global atom table, can't test with non-existing atom
     let existing_atom = Atom::str_to_term("");
@@ -37,7 +37,7 @@ fn with_improper_list_errors_badarg() {
                 Just(arc_process.clone()),
                 strategy::term::is_not_list(arc_process.clone()),
             )
-                .prop_map(|(arc_process, tail)| arc_process.cons(arc_process.integer('a'), tail))
+                .prop_map(|(arc_process, tail)| arc_process.cons(arc_process.integer('a').unwrap(), tail))
         },
         |list| {
             prop_assert_badarg!(result(list), format!("list ({}) is improper", list));
@@ -54,9 +54,9 @@ fn with_list_without_existing_atom_errors_badarg() {
             (Just(arc_process.clone()), any::<String>()).prop_map(|(arc_process, suffix)| {
                 let string = strategy::term::non_existent_atom(&suffix);
                 let codepoint_terms: Vec<Term> =
-                    string.chars().map(|c| arc_process.integer(c)).collect();
+                    string.chars().map(|c| arc_process.integer(c).unwrap()).collect();
 
-                arc_process.list_from_slice(&codepoint_terms)
+                arc_process.list_from_slice(&codepoint_terms).unwrap()
             })
         },
         |list| {
@@ -78,10 +78,10 @@ fn with_list_with_existing_atom_returns_atom() {
         |arc_process| {
             (Just(arc_process.clone()), any::<String>()).prop_map(|(arc_process, string)| {
                 let codepoint_terms: Vec<Term> =
-                    string.chars().map(|c| arc_process.integer(c)).collect();
+                    string.chars().map(|c| arc_process.integer(c).unwrap()).collect();
 
                 (
-                    arc_process.list_from_slice(&codepoint_terms),
+                    arc_process.list_from_slice(&codepoint_terms).unwrap(),
                     Atom::str_to_term(&string),
                 )
             })
diff --git a/native_implemented/otp/src/erlang/list_to_float_1.rs b/native_implemented/otp/src/erlang/list_to_float_1.rs
index 5c9f56e60..98b94c3e2 100644
--- a/native_implemented/otp/src/erlang/list_to_float_1.rs
+++ b/native_implemented/otp/src/erlang/list_to_float_1.rs
@@ -1,15 +1,15 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::charlist_to_string::charlist_to_string;
 use crate::erlang::string_to_float::string_to_float;
 
 #[native_implemented::function(erlang:list_to_float/1)]
-pub fn result(process: &Process, list: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, list: Term) -> Result<Term, NonNull<ErlangException>> {
     let string = charlist_to_string(list)?;
 
     string_to_float(process, "list", list, &string).map_err(From::from)
diff --git a/native_implemented/otp/src/erlang/list_to_float_1/test.rs b/native_implemented/otp/src/erlang/list_to_float_1/test.rs
index cee9a8345..0f9211caa 100644
--- a/native_implemented/otp/src/erlang/list_to_float_1/test.rs
+++ b/native_implemented/otp/src/erlang/list_to_float_1/test.rs
@@ -1,6 +1,6 @@
 use proptest::arbitrary::any;
 use proptest::prop_assert_eq;
-use proptest::strategy::{Just, Strategy};
+use proptest::strategy::Just;
 use proptest::test_runner::{Config, TestRunner};
 
 use crate::erlang::list_to_float_1::result;
@@ -56,7 +56,7 @@ fn with_list_with_f64_returns_floats() {
                 )
             }),
             |(arc_process, f, list)| {
-                prop_assert_eq!(result(&arc_process, list), Ok(arc_process.float(f)));
+                prop_assert_eq!(result(&arc_process, list), Ok(f.into()));
 
                 Ok(())
             },
diff --git a/native_implemented/otp/src/erlang/list_to_integer_1.rs b/native_implemented/otp/src/erlang/list_to_integer_1.rs
index 6412e3514..5631a9113 100644
--- a/native_implemented/otp/src/erlang/list_to_integer_1.rs
+++ b/native_implemented/otp/src/erlang/list_to_integer_1.rs
@@ -1,15 +1,15 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::list_to_string::list_to_string;
 use crate::erlang::string_to_integer::decimal_string_to_integer;
 
 #[native_implemented::function(erlang:list_to_integer/1)]
-pub fn result(process: &Process, list: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, list: Term) -> Result<Term, NonNull<ErlangException>> {
     let string: String = list_to_string(list)?;
 
     decimal_string_to_integer(process, "list", list, &string).map_err(From::from)
diff --git a/native_implemented/otp/src/erlang/list_to_integer_1/test.rs b/native_implemented/otp/src/erlang/list_to_integer_1/test.rs
index f3afb48bd..32448f0a3 100644
--- a/native_implemented/otp/src/erlang/list_to_integer_1/test.rs
+++ b/native_implemented/otp/src/erlang/list_to_integer_1/test.rs
@@ -1,9 +1,9 @@
 mod with_list;
 
-use proptest::strategy::{Just, Strategy};
+use proptest::strategy::Just;
 use proptest::{prop_assert, prop_assert_eq};
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 use crate::erlang::list_to_integer_1::result;
 use crate::test::strategy;
diff --git a/native_implemented/otp/src/erlang/list_to_integer_1/test/with_list.rs b/native_implemented/otp/src/erlang/list_to_integer_1/test/with_list.rs
index 1c7662a5c..bfaa2228e 100644
--- a/native_implemented/otp/src/erlang/list_to_integer_1/test/with_list.rs
+++ b/native_implemented/otp/src/erlang/list_to_integer_1/test/with_list.rs
@@ -1,9 +1,5 @@
 use super::*;
 
-use std::convert::TryInto;
-
-use liblumen_alloc::erts::term::prelude::SmallInteger;
-
 #[test]
 fn with_small_integer_returns_small_integer() {
     run!(
@@ -65,7 +61,7 @@ fn with_big_integer_returns_big_integer() {
             let term = result.unwrap();
 
             prop_assert!(term.is_boxed_bigint());
-            prop_assert_eq!(term, arc_process.integer(integer));
+            prop_assert_eq!(term, arc_process.integer(integer).unwrap());
 
             Ok(())
         },
diff --git a/native_implemented/otp/src/erlang/list_to_integer_2.rs b/native_implemented/otp/src/erlang/list_to_integer_2.rs
index 093267796..26e1991d8 100644
--- a/native_implemented/otp/src/erlang/list_to_integer_2.rs
+++ b/native_implemented/otp/src/erlang/list_to_integer_2.rs
@@ -1,15 +1,15 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::list_to_string::list_to_string;
 use crate::erlang::string_to_integer::base_string_to_integer;
 
 #[native_implemented::function(erlang:list_to_integer/2)]
-pub fn result(process: &Process, list: Term, base: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, list: Term, base: Term) -> Result<Term, NonNull<ErlangException>> {
     let string: String = list_to_string(list)?;
 
     base_string_to_integer(process, base, "list", list, &string).map_err(From::from)
diff --git a/native_implemented/otp/src/erlang/list_to_integer_2/test.rs b/native_implemented/otp/src/erlang/list_to_integer_2/test.rs
index 5e9840853..2c66a8947 100644
--- a/native_implemented/otp/src/erlang/list_to_integer_2/test.rs
+++ b/native_implemented/otp/src/erlang/list_to_integer_2/test.rs
@@ -1,9 +1,11 @@
 use proptest::arbitrary::any;
 use proptest::prop_assert_eq;
-use proptest::strategy::{Just, Strategy};
+use proptest::strategy::Just;
 
 use radix_fmt::radix;
 
+use firefly_rt::term::Term;
+
 use crate::erlang::list_to_integer_2::result;
 use crate::test::strategy;
 
@@ -71,14 +73,14 @@ fn with_list_with_integer_in_base_returns_integers() {
                         arc_process.clone(),
                         integer,
                         arc_process.charlist_from_str(&string),
-                        arc_process.integer(base),
+                        arc_process.integer(base).unwrap(),
                     )
                 })
         },
         |(arc_process, integer, list, base)| {
             prop_assert_eq!(
                 result(&arc_process, list, base),
-                Ok(arc_process.integer(integer))
+                Ok(arc_process.integer(integer).unwrap())
             );
 
             Ok(())
@@ -102,7 +104,7 @@ fn with_list_without_integer_in_base_errors_badarg() {
                 (
                     arc_process.clone(),
                     arc_process.charlist_from_str(&string),
-                    arc_process.integer(base),
+                    arc_process.integer(base).unwrap(),
                 )
             })
         },
diff --git a/native_implemented/otp/src/erlang/list_to_pid_1.rs b/native_implemented/otp/src/erlang/list_to_pid_1.rs
index 00ff54268..a23880ba8 100644
--- a/native_implemented/otp/src/erlang/list_to_pid_1.rs
+++ b/native_implemented/otp/src/erlang/list_to_pid_1.rs
@@ -2,19 +2,21 @@
 mod test;
 
 use std::convert::TryInto;
+use std::ptr::NonNull;
 
 use anyhow::*;
 
-use liblumen_alloc::erts::exception::{self, *};
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_number::TryIntoIntegerError;
 
-use crate::runtime::distribution::nodes::node;
+use firefly_rt::process::Process;
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::Term;
 
 use crate::runtime::distribution::nodes;
+use crate::runtime::distribution::nodes::node;
 
 #[native_implemented::function(erlang:list_to_pid/1)]
-pub fn result(process: &Process, string: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, string: Term) -> Result<Term, NonNull<ErlangException>> {
     let cons = term_try_into_non_empty_list!(string)?;
 
     let prefix_tail = skip_char(cons, '<').context("first character must be '<'")?;
diff --git a/native_implemented/otp/src/erlang/list_to_pid_1/test.rs b/native_implemented/otp/src/erlang/list_to_pid_1/test.rs
index 50c1d0751..fbc470c33 100644
--- a/native_implemented/otp/src/erlang/list_to_pid_1/test.rs
+++ b/native_implemented/otp/src/erlang/list_to_pid_1/test.rs
@@ -1,13 +1,11 @@
+use std::str::FromStr;
 use std::sync::Arc;
 
 use proptest::strategy::Just;
-
-use liblumen_alloc::erts::term::prelude::*;
-use liblumen_alloc::erts::Node;
-
-use crate::runtime::distribution::nodes;
+use firefly_rt::term::{Atom, Node, Pid};
 
 use crate::erlang::list_to_pid_1::result;
+use crate::runtime::distribution::nodes;
 use crate::test::strategy;
 use crate::test::with_process;
 
@@ -119,7 +117,7 @@ fn with_list_encoding_external_pid_without_known_node_errors_badarg() {
         );
 
         // MUST be a different `id` than other tests that insert the node.
-        let arc_node = Arc::new(Node::new(2, Atom::try_from_str("2@external").unwrap(), 0));
+        let arc_node = Arc::new(Node::new(2, Atom::from_str("2@external").unwrap(), 0));
 
         assert_badarg!(
             result(&process, process.charlist_from_str("<2.3.4>")),
diff --git a/native_implemented/otp/src/erlang/list_to_string.rs b/native_implemented/otp/src/erlang/list_to_string.rs
index 348b0336d..712a06dd7 100644
--- a/native_implemented/otp/src/erlang/list_to_string.rs
+++ b/native_implemented/otp/src/erlang/list_to_string.rs
@@ -2,13 +2,14 @@ use std::convert::TryInto;
 
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::*;
+use firefly_rt::term::Term;
 
-pub fn list_to_string(list: Term) -> exception::Result<String> {
-    match list.decode()? {
-        TypedTerm::Nil => Ok("".to_owned()),
-        TypedTerm::List(cons) => cons
+pub fn list_to_string(list: Term) -> Result<String, NonNull<ErlangException>> {
+    match list {
+        Term::Nil => Ok("".to_owned()),
+        Term::Cons(cons) => cons
             .into_iter()
             .map(|result| match result {
                 Ok(term) => {
@@ -25,7 +26,7 @@ pub fn list_to_string(list: Term) -> exception::Result<String> {
                     .context(format!("list ({}) is improper", list))
                     .map_err(From::from),
             })
-            .collect::<exception::Result<String>>(),
+            .collect::<Result<String, NonNull<ErlangException>>>(),
         _ => Err(TypeError)
             .context(format!("list ({}) is not a list", list))
             .map_err(From::from),
diff --git a/native_implemented/otp/src/erlang/list_to_tuple_1.rs b/native_implemented/otp/src/erlang/list_to_tuple_1.rs
index 98abb4753..42477ce9e 100644
--- a/native_implemented/otp/src/erlang/list_to_tuple_1.rs
+++ b/native_implemented/otp/src/erlang/list_to_tuple_1.rs
@@ -1,24 +1,26 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
+use std::ptr::NonNull;
+
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:list_to_tuple/1)]
-pub fn result(process: &Process, list: Term) -> exception::Result<Term> {
-    match list.decode().unwrap() {
-        TypedTerm::Nil => Ok(process.tuple_from_slice(&[])),
-        TypedTerm::List(cons) => {
+pub fn result(process: &Process, list: Term) -> Result<Term, NonNull<ErlangException>> {
+    match list {
+        Term::Nil => Ok(process.tuple_term_from_term_slice(&[])),
+        Term::Cons(cons) => {
             let vec: Vec<Term> = cons
                 .into_iter()
                 .collect::<std::result::Result<_, _>>()
                 .map_err(|_| ImproperListError)
                 .with_context(|| format!("list ({}) is improper", list))?;
 
-            Ok(process.tuple_from_slice(&vec))
+            Ok(process.tuple_term_from_term_slice(&vec))
         }
         _ => Err(TypeError)
             .context(format!("list ({}) is not a list", list))
diff --git a/native_implemented/otp/src/erlang/list_to_tuple_1/test.rs b/native_implemented/otp/src/erlang/list_to_tuple_1/test.rs
index 3159b96d6..ad52d5ecf 100644
--- a/native_implemented/otp/src/erlang/list_to_tuple_1/test.rs
+++ b/native_implemented/otp/src/erlang/list_to_tuple_1/test.rs
@@ -3,7 +3,7 @@ use proptest::prop_assert_eq;
 use proptest::strategy::{Just, Strategy};
 use proptest::test_runner::{Config, TestRunner};
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::{Atom, Term};
 
 use crate::erlang::list_to_tuple_1::result;
 use crate::test::strategy;
@@ -28,9 +28,9 @@ fn without_list_errors_badarg() {
 #[test]
 fn with_empty_list_returns_empty_tuple() {
     with_process(|process| {
-        let list = Term::NIL;
+        let list = Term::Nil;
 
-        assert_eq!(result(process, list), Ok(process.tuple_from_slice(&[])));
+        assert_eq!(result(process, list), Ok(process.tuple_term_from_term_slice(&[])));
     });
 }
 
@@ -43,8 +43,8 @@ fn with_non_empty_proper_list_returns_tuple() {
             .run(
                 &proptest::collection::vec(strategy::term(arc_process.clone()), size_range)
                     .prop_map(|vec| {
-                        let list = arc_process.list_from_slice(&vec);
-                        let tuple = arc_process.tuple_from_slice(&vec);
+                        let list = arc_process.list_from_slice(&vec).unwrap();
+                        let tuple = arc_process.tuple_term_from_term_slice(&vec);
 
                         (list, tuple)
                     }),
@@ -87,17 +87,17 @@ fn with_nested_list_returns_tuple_with_list_element() {
         let (second_element, list) = {
             let second_element = process.cons(
                 Atom::str_to_term("Ericsson_B"),
-                process.cons(process.integer(163), Term::NIL),
+                process.cons(process.integer(163).unwrap(), Term::Nil),
             );
 
-            let list = process.cons(first_element, process.cons(second_element, Term::NIL));
+            let list = process.cons(first_element, process.cons(second_element, Term::Nil));
 
             (second_element, list)
         };
 
         assert_eq!(
             result(process, list),
-            Ok(process.tuple_from_slice(&[first_element, second_element],))
+            Ok(process.tuple_term_from_term_slice(&[first_element, second_element],))
         );
     });
 }
diff --git a/native_implemented/otp/src/erlang/load_nif_2.rs b/native_implemented/otp/src/erlang/load_nif_2.rs
index 35ec42cf6..d95f1da1b 100644
--- a/native_implemented/otp/src/erlang/load_nif_2.rs
+++ b/native_implemented/otp/src/erlang/load_nif_2.rs
@@ -1,15 +1,14 @@
-use liblumen_alloc::atom;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::process::Process;
+use firefly_rt::term::{atoms, Term};
 
 #[native_implemented::function(erlang:load_nif/2)]
 pub fn result(process: &Process, _path: Term, _load_info: Term) -> Term {
-    let reason = atom!("notsup");
+    let reason: Term = atoms::Notsup.into();
     // Similar to the text used for HiPE compiled modules
     let text = process
         .list_from_chars("Calling load_nif from Lumen compiled modules not supported".chars());
-    let tag = atom!("error");
-    let value = process.tuple_from_slice(&[reason, text]);
+    let tag: Term = atoms::Error.into();
+    let value = process.tuple_term_from_term_slice(&[reason, text]);
 
-    process.tuple_from_slice(&[tag, value])
+    process.tuple_term_from_term_slice(&[tag, value])
 }
diff --git a/native_implemented/otp/src/erlang/localtime_0.rs b/native_implemented/otp/src/erlang/localtime_0.rs
index f12115633..cd47198df 100644
--- a/native_implemented/otp/src/erlang/localtime_0.rs
+++ b/native_implemented/otp/src/erlang/localtime_0.rs
@@ -1,24 +1,25 @@
 #[cfg(test)]
 mod test;
 
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
+
 use crate::runtime::time::datetime;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
 
 #[native_implemented::function(erlang:localtime/0)]
 pub fn result(process: &Process) -> Term {
     let now: [usize; 6] = datetime::local_now();
 
-    let date_tuple = process.tuple_from_slice(&[
-        process.integer(now[0]),
-        process.integer(now[1]),
-        process.integer(now[2]),
+    let date_tuple = process.tuple_term_from_term_slice(&[
+        process.integer(now[0]).unwrap(),
+        process.integer(now[1]).unwrap(),
+        process.integer(now[2]).unwrap(),
     ]);
-    let time_tuple = process.tuple_from_slice(&[
-        process.integer(now[3]),
-        process.integer(now[4]),
-        process.integer(now[5]),
+    let time_tuple = process.tuple_term_from_term_slice(&[
+        process.integer(now[3]).unwrap(),
+        process.integer(now[4]).unwrap(),
+        process.integer(now[5]).unwrap(),
     ]);
 
-    process.tuple_from_slice(&[date_tuple, time_tuple])
+    process.tuple_term_from_term_slice(&[date_tuple, time_tuple])
 }
diff --git a/native_implemented/otp/src/erlang/make_ref_0.rs b/native_implemented/otp/src/erlang/make_ref_0.rs
index 41c7992ae..2b05f205c 100644
--- a/native_implemented/otp/src/erlang/make_ref_0.rs
+++ b/native_implemented/otp/src/erlang/make_ref_0.rs
@@ -1,12 +1,15 @@
 #[cfg(test)]
 mod test;
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use std::ptr::NonNull;
 
-use crate::runtime::scheduler::SchedulerDependentAlloc;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
+
+use crate::runtime::scheduler::next_local_reference_term;
 
 #[native_implemented::function(erlang:make_ref/0)]
-pub fn result(process: &Process) -> Term {
-    process.next_reference()
+pub fn result(process: &Process) -> Result<Term, NonNull<ErlangException>> {
+    next_local_reference_term(process).map_err(ErlangException::from)
 }
diff --git a/native_implemented/otp/src/erlang/make_tuple_2.rs b/native_implemented/otp/src/erlang/make_tuple_2.rs
index f4109a7fd..b3c1e0132 100644
--- a/native_implemented/otp/src/erlang/make_tuple_2.rs
+++ b/native_implemented/otp/src/erlang/make_tuple_2.rs
@@ -1,19 +1,23 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::runtime::context::*;
 
 #[native_implemented::function(erlang:make_tuple/2)]
-pub fn result(process: &Process, arity: Term, initial_value: Term) -> exception::Result<Term> {
+pub fn result(
+    process: &Process,
+    arity: Term,
+    initial_value: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     // arity by definition is only 0-225, so `u8`, but ...
     let arity_u8: u8 = term_try_into_arity(arity)?;
     // ... everything else uses `usize`, so cast it back up
     let arity_usize: usize = arity_u8 as usize;
     let element_vec: Vec<Term> = std::iter::repeat(initial_value).take(arity_usize).collect();
 
-    Ok(process.tuple_from_slice(&element_vec))
+    Ok(process.tuple_term_from_term_slice(&element_vec))
 }
diff --git a/native_implemented/otp/src/erlang/make_tuple_2/test.rs b/native_implemented/otp/src/erlang/make_tuple_2/test.rs
index 20a0ac99d..20391d95a 100644
--- a/native_implemented/otp/src/erlang/make_tuple_2/test.rs
+++ b/native_implemented/otp/src/erlang/make_tuple_2/test.rs
@@ -1,9 +1,7 @@
-use std::convert::TryInto;
-
 use proptest::strategy::Just;
 use proptest::{prop_assert, prop_assert_eq};
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 use crate::erlang::make_tuple_2::result;
 use crate::test::strategy;
@@ -37,7 +35,7 @@ fn with_arity_returns_tuple_with_arity_copies_of_initial_value() {
             )
         },
         |(arc_process, arity_usize, initial_value)| {
-            let arity = arc_process.integer(arity_usize);
+            let arity = arc_process.integer(arity_usize).unwrap();
 
             let result = result(&arc_process, arity, initial_value);
 
@@ -47,14 +45,14 @@ fn with_arity_returns_tuple_with_arity_copies_of_initial_value() {
 
             prop_assert!(tuple_term.is_boxed());
 
-            let boxed_tuple: Result<Boxed<Tuple>, _> = tuple_term.try_into();
-            prop_assert!(boxed_tuple.is_ok());
+            let result_non_null_tuple: Result<NonNull<Tuple>, _> = tuple_term.try_into();
+            prop_assert!(result_non_null_tuple.is_ok());
 
-            let tuple = boxed_tuple.unwrap();
+            let non_null_tuple = result_non_null_tuple.unwrap();
 
-            prop_assert_eq!(tuple.len(), arity_usize);
+            prop_assert_eq!(non_null_tuple.len(), arity_usize);
 
-            for element in tuple.iter() {
+            for element in non_null_tuple.iter() {
                 prop_assert_eq!(element, &initial_value);
             }
 
diff --git a/native_implemented/otp/src/erlang/make_tuple_3.rs b/native_implemented/otp/src/erlang/make_tuple_3.rs
index d8c5c3afd..544f8db10 100644
--- a/native_implemented/otp/src/erlang/make_tuple_3.rs
+++ b/native_implemented/otp/src/erlang/make_tuple_3.rs
@@ -2,13 +2,13 @@
 mod test;
 
 use std::convert::TryInto;
+use std::ptr::NonNull;
 
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::alloc::TermAlloc;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::{OneBasedIndex, Term, Tuple};
 
 use crate::runtime::context::*;
 
@@ -18,7 +18,7 @@ pub fn result(
     arity: Term,
     default_value: Term,
     init_list: Term,
-) -> exception::Result<Term> {
+) -> Result<Term, NonNull<ErlangException>> {
     // arity by definition is only 0-225, so `u8`, but ...
     let arity_u8 = term_try_into_arity(arity)?;
     // ... everything else uses `usize`, so cast it back up
@@ -31,13 +31,13 @@ pub fn result(
         tuple.set_element(index, default_value).unwrap();
     }
 
-    match init_list.decode().unwrap() {
-        TypedTerm::Nil => Ok(tuple.encode()?),
-        TypedTerm::List(boxed_cons) => {
+    match init_list {
+        Term::Nil => Ok(tuple.encode()?),
+        Term::Cons(boxed_cons) => {
             for result in boxed_cons.into_iter() {
                 match result {
                     Ok(init) => {
-                        let init_boxed_tuple: Boxed<Tuple> = init.try_into().with_context(|| format!("init list ({}) element ({}) is not {{position :: pos_integer(), term()}}", init_list, init))?;
+                        let init_boxed_tuple: NonNull<Tuple> = init.try_into().with_context(|| format!("init list ({}) element ({}) is not {{position :: pos_integer(), term()}}", init_list, init))?;
 
                         if init_boxed_tuple.len() == 2 {
                             let position = init_boxed_tuple[0];
diff --git a/native_implemented/otp/src/erlang/make_tuple_3/test.rs b/native_implemented/otp/src/erlang/make_tuple_3/test.rs
index cf8321ef1..afa87d2ee 100644
--- a/native_implemented/otp/src/erlang/make_tuple_3/test.rs
+++ b/native_implemented/otp/src/erlang/make_tuple_3/test.rs
@@ -1,13 +1,12 @@
 mod with_arity;
 
-use std::convert::TryInto;
+use std::ptr::NonNull;
 
-use proptest::strategy::{Just, Strategy};
+use proptest::strategy::Just;
 use proptest::test_runner::{Config, TestRunner};
 use proptest::{prop_assert, prop_assert_eq};
 
-use liblumen_alloc::erts::term::prelude::*;
-use liblumen_alloc::fixnum;
+use firefly_rt::term::{Term, Tuple};
 
 use crate::erlang::make_tuple_3::result;
 use crate::test::strategy;
@@ -23,7 +22,7 @@ fn without_arity_errors_badarg() {
             )
         },
         |(arc_process, arity, default_value)| {
-            let init_list = Term::NIL;
+            let init_list = Term::Nil;
 
             prop_assert_is_not_arity!(result(&arc_process, arity, default_value, init_list), arity);
 
diff --git a/native_implemented/otp/src/erlang/make_tuple_3/test/with_arity.rs b/native_implemented/otp/src/erlang/make_tuple_3/test/with_arity.rs
index eb276e334..b71d3b763 100644
--- a/native_implemented/otp/src/erlang/make_tuple_3/test/with_arity.rs
+++ b/native_implemented/otp/src/erlang/make_tuple_3/test/with_arity.rs
@@ -15,9 +15,9 @@ fn without_proper_list_init_list_errors_badarg() {
             )
         },
         |(arc_process, arity_usize, default_value, element, tail)| {
-            let arity = arc_process.integer(arity_usize);
+            let arity = arc_process.integer(arity_usize).unwrap();
             let init_list = arc_process.cons(
-                arc_process.tuple_from_slice(&[arc_process.integer(1), element]),
+                arc_process.tuple_term_from_term_slice(&[arc_process.integer(1).unwrap(), element]),
                 tail,
             );
 
@@ -42,8 +42,8 @@ fn with_empty_list_init_list_returns_tuple_with_arity_copies_of_default_value()
             )
         },
         |(arc_process, arity_usize, default_value)| {
-            let arity = arc_process.integer(arity_usize);
-            let init_list = Term::NIL;
+            let arity = arc_process.integer(arity_usize).unwrap();
+            let init_list = Term::Nil;
 
             let result = result(&arc_process, arity, default_value, init_list);
 
@@ -53,13 +53,13 @@ fn with_empty_list_init_list_returns_tuple_with_arity_copies_of_default_value()
 
             prop_assert!(tuple_term.is_boxed());
 
-            let boxed_tuple: Result<Boxed<Tuple>, _> = tuple_term.try_into();
-            prop_assert!(boxed_tuple.is_ok());
+            let result_non_null_tuple: Result<NonNull<Tuple>, _> = tuple_term.try_into();
+            prop_assert!(result_non_null_tuple.is_ok());
 
-            let tuple = boxed_tuple.unwrap();
-            prop_assert_eq!(tuple.len(), arity_usize);
+            let non_null_tuple = result_non_null_tuple.unwrap();
+            prop_assert_eq!(non_null_tuple.len(), arity_usize);
 
-            for element in tuple.iter() {
+            for element in non_null_tuple.iter() {
                 prop_assert_eq!(element, &default_value);
             }
 
diff --git a/native_implemented/otp/src/erlang/make_tuple_3/test/with_arity/with_proper_list.rs b/native_implemented/otp/src/erlang/make_tuple_3/test/with_arity/with_proper_list.rs
index ed866a88a..b807de940 100644
--- a/native_implemented/otp/src/erlang/make_tuple_3/test/with_arity/with_proper_list.rs
+++ b/native_implemented/otp/src/erlang/make_tuple_3/test/with_arity/with_proper_list.rs
@@ -14,8 +14,8 @@ fn without_tuple_in_init_list_errors_badarg() {
             )
         },
         |(arc_process, arity_usize, default_value, element)| {
-            let arity = arc_process.integer(arity_usize);
-            let init_list = arc_process.list_from_slice(&[element]);
+            let arity = arc_process.integer(arity_usize).unwrap();
+            let init_list = arc_process.list_from_slice(&[element]).unwrap();
 
             prop_assert_badarg!(
                 result(&arc_process, arity, default_value, init_list),
diff --git a/native_implemented/otp/src/erlang/make_tuple_3/test/with_arity/with_proper_list/with_tuples_in_init_list.rs b/native_implemented/otp/src/erlang/make_tuple_3/test/with_arity/with_proper_list/with_tuples_in_init_list.rs
index 7a731e031..234f619c8 100644
--- a/native_implemented/otp/src/erlang/make_tuple_3/test/with_arity/with_proper_list/with_tuples_in_init_list.rs
+++ b/native_implemented/otp/src/erlang/make_tuple_3/test/with_arity/with_proper_list/with_tuples_in_init_list.rs
@@ -24,8 +24,8 @@ fn without_arity_2_errors_badarg() {
             )
         },
         |(arc_process, arity_usize, default_value, element)| {
-            let arity = arc_process.integer(arity_usize);
-            let init_list = arc_process.list_from_slice(&[element]);
+            let arity = arc_process.integer(arity_usize).unwrap();
+            let init_list = arc_process.list_from_slice(&[element]).unwrap();
 
             prop_assert_badarg!(
                 result(&arc_process, arity, default_value, init_list),
diff --git a/native_implemented/otp/src/erlang/make_tuple_3/test/with_arity/with_proper_list/with_tuples_in_init_list/with_arity_2.rs b/native_implemented/otp/src/erlang/make_tuple_3/test/with_arity/with_proper_list/with_tuples_in_init_list/with_arity_2.rs
index 3f92b538e..835a33514 100644
--- a/native_implemented/otp/src/erlang/make_tuple_3/test/with_arity/with_proper_list/with_tuples_in_init_list/with_arity_2.rs
+++ b/native_implemented/otp/src/erlang/make_tuple_3/test/with_arity/with_proper_list/with_tuples_in_init_list/with_arity_2.rs
@@ -18,9 +18,9 @@ fn without_positive_index_errors_badarg_because_indexes_are_one_based() {
             )
         },
         |(arc_process, arity_usize, default_value, position, element)| {
-            let arity = arc_process.integer(arity_usize);
-            let init = arc_process.tuple_from_slice(&[position, element]);
-            let init_list = arc_process.list_from_slice(&[init]);
+            let arity = arc_process.integer(arity_usize).unwrap();
+            let init = arc_process.tuple_term_from_term_slice(&[position, element]);
+            let init_list = arc_process.list_from_slice(&[init]).unwrap();
 
             let r = result(&arc_process, arity, default_value, init_list);
 
diff --git a/native_implemented/otp/src/erlang/make_tuple_3/test/with_arity/with_proper_list/with_tuples_in_init_list/with_arity_2/with_positive_index.rs b/native_implemented/otp/src/erlang/make_tuple_3/test/with_arity/with_proper_list/with_tuples_in_init_list/with_arity_2/with_positive_index.rs
index c45548f95..f7609faee 100644
--- a/native_implemented/otp/src/erlang/make_tuple_3/test/with_arity/with_proper_list/with_tuples_in_init_list/with_arity_2/with_positive_index.rs
+++ b/native_implemented/otp/src/erlang/make_tuple_3/test/with_arity/with_proper_list/with_tuples_in_init_list/with_arity_2/with_positive_index.rs
@@ -17,16 +17,16 @@ fn with_positive_index_greater_than_length_errors_badarg() {
                             arc_process.clone(),
                             len,
                             default_value,
-                            arc_process.integer(len + index_offset),
+                            arc_process.integer(len + index_offset).unwrap(),
                             index_element,
                         )
                     },
                 )
         },
         |(arc_process, arity_usize, default_value, position, element)| {
-            let arity = arc_process.integer(arity_usize);
-            let init = arc_process.tuple_from_slice(&[position, element]);
-            let init_list = arc_process.list_from_slice(&[init]);
+            let arity = arc_process.integer(arity_usize).unwrap();
+            let init = arc_process.tuple_term_from_term_slice(&[position, element]);
+            let init_list = arc_process.list_from_slice(&[init]).unwrap();
 
             prop_assert_badarg!(
                 result(&arc_process, arity, default_value, init_list),
@@ -61,10 +61,10 @@ fn with_positive_index_less_than_or_equal_to_length_replaces_default_value_at_in
                     )
                 }),
             |(arc_process, arity_usize, default_value, zero_based_index, init_list_element)| {
-                let arity = arc_process.integer(arity_usize);
-                let one_based_index = arc_process.integer(zero_based_index + 1);
+                let arity = arc_process.integer(arity_usize).unwrap();
+                let one_based_index = arc_process.integer(zero_based_index + 1).unwrap();
                 let init_list = arc_process.list_from_slice(&[
-                    arc_process.tuple_from_slice(&[one_based_index, init_list_element])
+                    arc_process.tuple_term_from_term_slice(&[one_based_index, init_list_element])
                 ]);
 
                 let result = result(&arc_process, arity, default_value, init_list);
@@ -75,14 +75,14 @@ fn with_positive_index_less_than_or_equal_to_length_replaces_default_value_at_in
 
                 prop_assert!(tuple_term.is_boxed());
 
-                let boxed_tuple: Result<Boxed<Tuple>, _> = tuple_term.try_into();
-                prop_assert!(boxed_tuple.is_ok());
+                let result_non_null_tuple: Result<NonNull<Tuple>, _> = tuple_term.try_into();
+                prop_assert!(result_non_null_tuple.is_ok());
 
-                let tuple = boxed_tuple.unwrap();
+                let non_null_tuple = result_non_null_tuple.unwrap();
 
-                prop_assert_eq!(tuple.len(), arity_usize);
+                prop_assert_eq!(non_null_tuple.len(), arity_usize);
 
-                for (index, element) in tuple.iter().enumerate() {
+                for (index, element) in non_null_tuple.iter().enumerate() {
                     if index == zero_based_index {
                         prop_assert_eq!(element, &init_list_element);
                     } else {
@@ -129,13 +129,13 @@ fn with_multiple_values_at_same_index_then_last_value_is_used() {
                 init_list_ignored_element,
                 init_list_used_element,
             )| {
-                let arity = arc_process.integer(arity_usize);
-                let init_list_one_base_index = arc_process.integer(init_list_zero_based_index + 1);
+                let arity = arc_process.integer(arity_usize).unwrap();
+                let init_list_one_base_index = arc_process.integer(init_list_zero_based_index + 1).unwrap();
                 let init_list = arc_process.list_from_slice(&[
                     arc_process
-                        .tuple_from_slice(&[init_list_one_base_index, init_list_ignored_element]),
+                        .tuple_term_from_term_slice(&[init_list_one_base_index, init_list_ignored_element]),
                     arc_process
-                        .tuple_from_slice(&[init_list_one_base_index, init_list_used_element]),
+                        .tuple_term_from_term_slice(&[init_list_one_base_index, init_list_used_element]),
                 ]);
 
                 let result = result(&arc_process, arity, default_value, init_list);
@@ -146,14 +146,14 @@ fn with_multiple_values_at_same_index_then_last_value_is_used() {
 
                 prop_assert!(tuple_term.is_boxed());
 
-                let boxed_tuple: Result<Boxed<Tuple>, _> = tuple_term.try_into();
-                prop_assert!(boxed_tuple.is_ok());
+                let result_non_null_tuple: Result<NonNull<Tuple>, _> = tuple_term.try_into();
+                prop_assert!(result_non_null_tuple.is_ok());
 
-                let tuple = boxed_tuple.unwrap();
+                let non_null_tuple = result_non_null_tuple.unwrap();
 
-                prop_assert_eq!(tuple.len(), arity_usize);
+                prop_assert_eq!(non_null_tuple.len(), arity_usize);
 
-                for (index, element) in tuple.iter().enumerate() {
+                for (index, element) in non_null_tuple.iter().enumerate() {
                     if index == init_list_zero_based_index {
                         prop_assert_eq!(element, &init_list_used_element);
                     } else {
diff --git a/native_implemented/otp/src/erlang/map_get_2.rs b/native_implemented/otp/src/erlang/map_get_2.rs
index 2ade89d3f..d1f5633ef 100644
--- a/native_implemented/otp/src/erlang/map_get_2.rs
+++ b/native_implemented/otp/src/erlang/map_get_2.rs
@@ -1,15 +1,17 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
+use std::ptr::NonNull;
+
 use anyhow::*;
 
-use liblumen_alloc::erts::exception::{self, *};
-use liblumen_alloc::erts::process::trace::Trace;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::backtrace::Trace;
+use firefly_rt::process::Process;
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:map_get/2)]
-pub fn result(process: &Process, key: Term, map: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, key: Term, map: Term) -> Result<Term, NonNull<ErlangException>> {
     let boxed_map = term_try_into_map_or_badmap!(process, map)?;
 
     match boxed_map.get(key) {
diff --git a/native_implemented/otp/src/erlang/map_get_2/test.rs b/native_implemented/otp/src/erlang/map_get_2/test.rs
index d09478006..9c83fffb5 100644
--- a/native_implemented/otp/src/erlang/map_get_2/test.rs
+++ b/native_implemented/otp/src/erlang/map_get_2/test.rs
@@ -1,5 +1,5 @@
 use proptest::prop_assert_eq;
-use proptest::strategy::{Just, Strategy};
+use proptest::strategy::Just;
 use proptest::test_runner::{Config, TestRunner};
 
 use crate::erlang::map_get_2::result;
diff --git a/native_implemented/otp/src/erlang/map_size_1.rs b/native_implemented/otp/src/erlang/map_size_1.rs
index 3cdab289e..f80792cf7 100644
--- a/native_implemented/otp/src/erlang/map_size_1.rs
+++ b/native_implemented/otp/src/erlang/map_size_1.rs
@@ -1,15 +1,17 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use std::ptr::NonNull;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:map_size/1)]
-pub fn result(process: &Process, map: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, map: Term) -> Result<Term, NonNull<ErlangException>> {
     let boxed_map = term_try_into_map_or_badmap!(process, map)?;
     let len = boxed_map.len();
-    let len_term = process.integer(len);
+    let len_term = process.integer(len).unwrap();
 
     Ok(len_term)
 }
diff --git a/native_implemented/otp/src/erlang/map_size_1/test.rs b/native_implemented/otp/src/erlang/map_size_1/test.rs
index 073ae0301..68488ea63 100644
--- a/native_implemented/otp/src/erlang/map_size_1/test.rs
+++ b/native_implemented/otp/src/erlang/map_size_1/test.rs
@@ -1,7 +1,7 @@
 use proptest::prop_assert_eq;
-use proptest::strategy::{Just, Strategy};
+use proptest::strategy::Just;
 
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::term::Term;
 
 use crate::erlang::map_size_1::result;
 use crate::test::strategy;
@@ -46,7 +46,7 @@ fn with_map_returns_number_of_entries() {
                     (
                         arc_process.clone(),
                         arc_process.map_from_slice(&entry_vec),
-                        arc_process.integer(entry_vec.len()),
+                        arc_process.integer(entry_vec.len().unwrap()),
                     )
                 })
         },
diff --git a/native_implemented/otp/src/erlang/max_2.rs b/native_implemented/otp/src/erlang/max_2.rs
index 44d0c4dd2..41c7096f8 100644
--- a/native_implemented/otp/src/erlang/max_2.rs
+++ b/native_implemented/otp/src/erlang/max_2.rs
@@ -1,7 +1,7 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::term::Term;
 
 /// `max/2`
 ///
diff --git a/native_implemented/otp/src/erlang/max_2/test.rs b/native_implemented/otp/src/erlang/max_2/test.rs
index 7a0988777..8d3940a5e 100644
--- a/native_implemented/otp/src/erlang/max_2/test.rs
+++ b/native_implemented/otp/src/erlang/max_2/test.rs
@@ -13,11 +13,10 @@ mod with_subbinary_first;
 mod with_tuple_first;
 
 use proptest::prop_assert_eq;
-use proptest::strategy::Strategy;
 use proptest::test_runner::{Config, TestRunner};
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Atom, Integer, Term};
 
 use crate::erlang::max_2::result;
 use crate::test::with_process;
diff --git a/native_implemented/otp/src/erlang/max_2/test/with_big_integer_first.rs b/native_implemented/otp/src/erlang/max_2/test/with_big_integer_first.rs
index bb399dde0..156393857 100644
--- a/native_implemented/otp/src/erlang/max_2/test/with_big_integer_first.rs
+++ b/native_implemented/otp/src/erlang/max_2/test/with_big_integer_first.rs
@@ -2,14 +2,14 @@ use super::*;
 
 #[test]
 fn with_lesser_small_integer_second_returns_first() {
-    max(|_, process| process.integer(0), First)
+    max(|_, process| process.integer(0).unwrap(), First)
 }
 
 #[test]
 fn with_greater_small_integer_second_returns_second() {
     super::max(
-        |process| process.integer(SmallInteger::MIN_VALUE - 1),
-        |_, process| process.integer(SmallInteger::MIN_VALUE),
+        |process| process.integer(Integer::MIN_SMALL - 1).unwrap(),
+        |_, process| process.integer(Integer::MIN_SMALL).unwrap(),
         Second,
     );
 }
@@ -17,7 +17,7 @@ fn with_greater_small_integer_second_returns_second() {
 #[test]
 fn with_lesser_big_integer_second_returns_first() {
     max(
-        |_, process| process.integer(SmallInteger::MIN_VALUE - 1),
+        |_, process| process.integer(Integer::MIN_SMALL - 1).unwrap(),
         First,
     )
 }
@@ -30,7 +30,7 @@ fn with_same_big_integer_second_returns_first() {
 #[test]
 fn with_same_value_big_integer_second_returns_first() {
     max(
-        |_, process| process.integer(SmallInteger::MAX_VALUE + 1),
+        |_, process| process.integer(Integer::MAX_SMALL + 1).unwrap(),
         First,
     )
 }
@@ -38,21 +38,21 @@ fn with_same_value_big_integer_second_returns_first() {
 #[test]
 fn with_greater_big_integer_second_returns_second() {
     max(
-        |_, process| process.integer(SmallInteger::MAX_VALUE + 2),
+        |_, process| process.integer(Integer::MAX_SMALL + 2).unwrap(),
         Second,
     )
 }
 
 #[test]
 fn with_lesser_float_second_returns_first() {
-    max(|_, process| process.float(1.0), First)
+    max(|_, process| 1.0.into(), First)
 }
 
 #[test]
 fn with_greater_float_second_returns_second() {
     super::max(
-        |process| process.integer(SmallInteger::MIN_VALUE - 1),
-        |_, process| process.float(1.0),
+        |process| process.integer(Integer::MIN_SMALL - 1).unwrap(),
+        |_, process| 1.0.into(),
         Second,
     );
 }
@@ -79,7 +79,7 @@ where
     R: FnOnce(Term, &Process) -> Term,
 {
     super::max(
-        |process| process.integer(SmallInteger::MAX_VALUE + 1),
+        |process| process.integer(Integer::MAX_SMALL + 1).unwrap(),
         second,
         which,
     );
diff --git a/native_implemented/otp/src/erlang/max_2/test/with_empty_list_first.rs b/native_implemented/otp/src/erlang/max_2/test/with_empty_list_first.rs
index 9b6405367..d090a6afb 100644
--- a/native_implemented/otp/src/erlang/max_2/test/with_empty_list_first.rs
+++ b/native_implemented/otp/src/erlang/max_2/test/with_empty_list_first.rs
@@ -1,7 +1,6 @@
 use super::*;
 
 use proptest::prop_oneof;
-use proptest::strategy::Strategy;
 
 #[test]
 fn without_non_empty_list_or_bitstring_second_returns_firsts() {
@@ -13,7 +12,7 @@ fn without_non_empty_list_or_bitstring_second_returns_firsts() {
                 })
         },
         |second| {
-            let first = Term::NIL;
+            let first = Term::Nil;
 
             prop_assert_eq!(result(first, second), first);
 
@@ -32,7 +31,7 @@ fn with_non_empty_list_or_bitstring_second_returns_second() {
             ]
         },
         |second| {
-            let first = Term::NIL;
+            let first = Term::Nil;
 
             prop_assert_eq!(result(first, second), second);
 
diff --git a/native_implemented/otp/src/erlang/max_2/test/with_float_first.rs b/native_implemented/otp/src/erlang/max_2/test/with_float_first.rs
index b8092f562..b874a6aad 100644
--- a/native_implemented/otp/src/erlang/max_2/test/with_float_first.rs
+++ b/native_implemented/otp/src/erlang/max_2/test/with_float_first.rs
@@ -2,18 +2,18 @@ use super::*;
 
 #[test]
 fn with_lesser_small_integer_second_returns_first() {
-    max(|_, process| process.integer(-1), First)
+    max(|_, process| process.integer(-1).unwrap(), First)
 }
 
 #[test]
 fn with_greater_small_integer_second_returns_second() {
-    max(|_, process| process.integer(2), Second)
+    max(|_, process| process.integer(2).unwrap(), Second)
 }
 
 #[test]
 fn with_lesser_big_integer_second_returns_first() {
     max(
-        |_, process| process.integer(SmallInteger::MIN_VALUE - 1),
+        |_, process| process.integer(Integer::MIN_SMALL - 1).unwrap(),
         First,
     )
 }
@@ -21,19 +21,19 @@ fn with_lesser_big_integer_second_returns_first() {
 #[test]
 fn with_greater_big_integer_second_returns_second() {
     max(
-        |_, process| process.integer(SmallInteger::MAX_VALUE + 1),
+        |_, process| process.integer(Integer::MAX_SMALL + 1).unwrap(),
         Second,
     )
 }
 
 #[test]
 fn with_lesser_float_second_returns_first() {
-    max(|_, process| process.float(-1.0), First)
+    max(|_, process| -1.0.into(), First)
 }
 
 #[test]
 fn with_greater_float_second_returns_second() {
-    max(|_, process| process.float(1.0), Second)
+    max(|_, process| 1.0.into(), Second)
 }
 
 #[test]
@@ -41,7 +41,7 @@ fn without_number_returns_second() {
     run!(
         |arc_process| {
             (
-                strategy::term::float(arc_process.clone()),
+                strategy::term::float(),
                 strategy::term::is_not_number(arc_process.clone()),
             )
         },
@@ -57,5 +57,5 @@ fn max<R>(second: R, which: FirstSecond)
 where
     R: FnOnce(Term, &Process) -> Term,
 {
-    super::max(|process| process.float(1.0), second, which);
+    super::max(|process| 1.0.into(), second, which);
 }
diff --git a/native_implemented/otp/src/erlang/max_2/test/with_heap_binary_first.rs b/native_implemented/otp/src/erlang/max_2/test/with_heap_binary_first.rs
index e63a8684b..4d4989756 100644
--- a/native_implemented/otp/src/erlang/max_2/test/with_heap_binary_first.rs
+++ b/native_implemented/otp/src/erlang/max_2/test/with_heap_binary_first.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn with_number_atom_reference_function_port_pid_tuple_map_or_list_returns_first() {
     run!(
@@ -14,10 +12,10 @@ fn with_number_atom_reference_function_port_pid_tuple_map_or_list_returns_first(
                             second.is_number()
                                 || second.is_atom()
                                 || second.is_reference()
-                                || second.is_boxed_function()
+                                || second.is_closure()
                                 || second.is_port()
                                 || second.is_pid()
-                                || second.is_boxed_tuple()
+                                || second.is_tuple()
                                 || second.is_list()
                         }),
                 )
diff --git a/native_implemented/otp/src/erlang/max_2/test/with_list_first.rs b/native_implemented/otp/src/erlang/max_2/test/with_list_first.rs
index f5d07007a..f33fcf680 100644
--- a/native_implemented/otp/src/erlang/max_2/test/with_list_first.rs
+++ b/native_implemented/otp/src/erlang/max_2/test/with_list_first.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_list_or_bitstring_second_returns_first() {
     run!(
@@ -24,13 +22,13 @@ fn without_list_or_bitstring_second_returns_first() {
 
 #[test]
 fn with_empty_list_second_returns_first() {
-    max(|_, _| Term::NIL, First);
+    max(|_, _| Term::Nil, First);
 }
 
 #[test]
 fn with_lesser_list_second_returns_first() {
     max(
-        |_, process| process.cons(process.integer(0), process.integer(0)),
+        |_, process| process.cons(process.integer(0).unwrap(), process.integer(0).unwrap()),
         First,
     );
 }
@@ -43,7 +41,7 @@ fn with_same_list_second_returns_first() {
 #[test]
 fn with_same_value_list_second_returns_first() {
     max(
-        |_, process| process.cons(process.integer(0), process.integer(1)),
+        |_, process| process.cons(process.integer(0).unwrap(), process.integer(1).unwrap()),
         First,
     );
 }
@@ -51,7 +49,7 @@ fn with_same_value_list_second_returns_first() {
 #[test]
 fn with_greater_list_second_returns_second() {
     max(
-        |_, process| process.cons(process.integer(0), process.integer(2)),
+        |_, process| process.cons(process.integer(0).unwrap(), process.integer(2).unwrap()),
         Second,
     );
 }
@@ -78,7 +76,7 @@ where
     R: FnOnce(Term, &Process) -> Term,
 {
     super::max(
-        |process| process.cons(process.integer(0), process.integer(1)),
+        |process| process.cons(process.integer(0).unwrap(), process.integer(1).unwrap()),
         second,
         which,
     );
diff --git a/native_implemented/otp/src/erlang/max_2/test/with_map_first.rs b/native_implemented/otp/src/erlang/max_2/test/with_map_first.rs
index 095930d67..38b0dbaed 100644
--- a/native_implemented/otp/src/erlang/max_2/test/with_map_first.rs
+++ b/native_implemented/otp/src/erlang/max_2/test/with_map_first.rs
@@ -20,7 +20,7 @@ fn with_number_atom_reference_function_port_pid_or_tuple_second_returns_first()
 #[test]
 fn with_smaller_map_second_returns_first() {
     max(
-        |_, process| process.map_from_slice(&[(Atom::str_to_term("a"), process.integer(1))]),
+        |_, process| process.map_from_slice(&[(Atom::str_to_term("a"), process.integer(1).unwrap())]),
         First,
     );
 }
@@ -30,8 +30,8 @@ fn with_same_size_map_with_lesser_keys_returns_first() {
     max(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("a"), process.integer(2)),
-                (Atom::str_to_term("b"), process.integer(3)),
+                (Atom::str_to_term("a"), process.integer(2).unwrap()),
+                (Atom::str_to_term("b"), process.integer(3).unwrap()),
             ])
         },
         First,
@@ -43,8 +43,8 @@ fn with_same_size_map_with_same_keys_with_lesser_values_returns_first() {
     max(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("b"), process.integer(2)),
-                (Atom::str_to_term("c"), process.integer(2)),
+                (Atom::str_to_term("b"), process.integer(2).unwrap()),
+                (Atom::str_to_term("c"), process.integer(2).unwrap()),
             ])
         },
         First,
@@ -61,8 +61,8 @@ fn with_same_value_map_returns_first() {
     max(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("b"), process.integer(2)),
-                (Atom::str_to_term("c"), process.integer(3)),
+                (Atom::str_to_term("b"), process.integer(2).unwrap()),
+                (Atom::str_to_term("c"), process.integer(3).unwrap()),
             ])
         },
         First,
@@ -74,8 +74,8 @@ fn with_same_size_map_with_same_keys_with_greater_values_returns_second() {
     max(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("b"), process.integer(3)),
-                (Atom::str_to_term("c"), process.integer(4)),
+                (Atom::str_to_term("b"), process.integer(3).unwrap()),
+                (Atom::str_to_term("c"), process.integer(4).unwrap()),
             ])
         },
         Second,
@@ -87,8 +87,8 @@ fn with_same_size_map_with_greater_keys_returns_second() {
     max(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("c"), process.integer(2)),
-                (Atom::str_to_term("d"), process.integer(3)),
+                (Atom::str_to_term("c"), process.integer(2).unwrap()),
+                (Atom::str_to_term("d"), process.integer(3).unwrap()),
             ])
         },
         Second,
@@ -100,9 +100,9 @@ fn with_greater_size_map_returns_second() {
     max(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("a"), process.integer(1)),
-                (Atom::str_to_term("b"), process.integer(2)),
-                (Atom::str_to_term("c"), process.integer(3)),
+                (Atom::str_to_term("a"), process.integer(1).unwrap()),
+                (Atom::str_to_term("b"), process.integer(2).unwrap()),
+                (Atom::str_to_term("c"), process.integer(3).unwrap()),
             ])
         },
         Second,
@@ -138,8 +138,8 @@ where
     super::max(
         |process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("b"), process.integer(2)),
-                (Atom::str_to_term("c"), process.integer(3)),
+                (Atom::str_to_term("b"), process.integer(2).unwrap()),
+                (Atom::str_to_term("c"), process.integer(3).unwrap()),
             ])
         },
         second,
diff --git a/native_implemented/otp/src/erlang/max_2/test/with_small_integer_first.rs b/native_implemented/otp/src/erlang/max_2/test/with_small_integer_first.rs
index 3b81cb072..9fd045334 100644
--- a/native_implemented/otp/src/erlang/max_2/test/with_small_integer_first.rs
+++ b/native_implemented/otp/src/erlang/max_2/test/with_small_integer_first.rs
@@ -2,7 +2,7 @@ use super::*;
 
 #[test]
 fn with_lesser_small_integer_second_returns_first() {
-    max(|_, process| process.integer(-1), First);
+    max(|_, process| process.integer(-1).unwrap(), First);
 }
 
 #[test]
@@ -12,18 +12,18 @@ fn with_same_small_integer_second_returns_first() {
 
 #[test]
 fn with_same_value_small_integer_second_returns_first() {
-    max(|_, process| process.integer(0), First);
+    max(|_, process| process.integer(0).unwrap(), First);
 }
 
 #[test]
 fn with_greater_small_integer_second_returns_second() {
-    max(|_, process| process.integer(1), Second);
+    max(|_, process| process.integer(1).unwrap(), Second);
 }
 
 #[test]
 fn with_lesser_big_integer_second_returns_first() {
     max(
-        |_, process| process.integer(SmallInteger::MIN_VALUE - 1),
+        |_, process| process.integer(Integer::MIN_SMALL - 1).unwrap(),
         First,
     )
 }
@@ -31,24 +31,24 @@ fn with_lesser_big_integer_second_returns_first() {
 #[test]
 fn with_greater_big_integer_second_returns_second() {
     max(
-        |_, process| process.integer(SmallInteger::MAX_VALUE + 1),
+        |_, process| process.integer(Integer::MAX_SMALL + 1).unwrap(),
         Second,
     )
 }
 
 #[test]
 fn with_lesser_float_second_returns_first() {
-    max(|_, process| process.float(-1.0), First)
+    max(|_, process| -1.0.into(), First)
 }
 
 #[test]
 fn with_same_value_float_second_returns_first() {
-    max(|_, process| process.float(0.0), First)
+    max(|_, process| 0.0.into(), First)
 }
 
 #[test]
 fn with_greater_float_second_returns_second() {
-    max(|_, process| process.float(1.0), Second)
+    max(|_, process| 1.0.into(), Second)
 }
 
 #[test]
@@ -72,5 +72,5 @@ fn max<R>(second: R, which: FirstSecond)
 where
     R: FnOnce(Term, &Process) -> Term,
 {
-    super::max(|process| process.integer(0), second, which);
+    super::max(|process| process.integer(0).unwrap(), second, which);
 }
diff --git a/native_implemented/otp/src/erlang/max_2/test/with_subbinary_first.rs b/native_implemented/otp/src/erlang/max_2/test/with_subbinary_first.rs
index f7c159285..af49165ab 100644
--- a/native_implemented/otp/src/erlang/max_2/test/with_subbinary_first.rs
+++ b/native_implemented/otp/src/erlang/max_2/test/with_subbinary_first.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn with_number_atom_reference_function_port_pid_tuple_map_or_list_second_returns_first() {
     run!(
@@ -14,10 +12,10 @@ fn with_number_atom_reference_function_port_pid_tuple_map_or_list_second_returns
                             second.is_number()
                                 || second.is_atom()
                                 || second.is_reference()
-                                || second.is_boxed_function()
+                                || second.is_closure()
                                 || second.is_port()
                                 || second.is_pid()
-                                || second.is_boxed_tuple()
+                                || second.is_tuple()
                                 || second.is_list()
                         }),
                 )
diff --git a/native_implemented/otp/src/erlang/max_2/test/with_tuple_first.rs b/native_implemented/otp/src/erlang/max_2/test/with_tuple_first.rs
index fd725a4ab..6c0edac1f 100644
--- a/native_implemented/otp/src/erlang/max_2/test/with_tuple_first.rs
+++ b/native_implemented/otp/src/erlang/max_2/test/with_tuple_first.rs
@@ -20,7 +20,7 @@ fn with_number_atom_reference_function_port_or_pid_returns_first() {
 #[test]
 fn with_smaller_tuple_second_returns_first() {
     max(
-        |_, process| process.tuple_from_slice(&[process.integer(1)]),
+        |_, process| process.tuple_term_from_term_slice(&[process.integer(1).unwrap()]),
         First,
     );
 }
@@ -28,7 +28,7 @@ fn with_smaller_tuple_second_returns_first() {
 #[test]
 fn with_same_size_tuple_with_lesser_elements_returns_first() {
     max(
-        |_, process| process.tuple_from_slice(&[process.integer(1), process.integer(1)]),
+        |_, process| process.tuple_term_from_term_slice(&[process.integer(1).unwrap(), process.integer(1).unwrap()]),
         First,
     );
 }
@@ -41,7 +41,7 @@ fn with_same_tuple_returns_first() {
 #[test]
 fn with_same_value_tuple_returns_first() {
     max(
-        |_, process| process.tuple_from_slice(&[process.integer(1), process.integer(2)]),
+        |_, process| process.tuple_term_from_term_slice(&[process.integer(1).unwrap(), process.integer(2).unwrap()]),
         First,
     );
 }
@@ -49,7 +49,7 @@ fn with_same_value_tuple_returns_first() {
 #[test]
 fn with_same_size_tuple_with_greater_elements_returns_second() {
     max(
-        |_, process| process.tuple_from_slice(&[process.integer(1), process.integer(3)]),
+        |_, process| process.tuple_term_from_term_slice(&[process.integer(1).unwrap(), process.integer(3).unwrap()]),
         Second,
     );
 }
@@ -58,7 +58,7 @@ fn with_same_size_tuple_with_greater_elements_returns_second() {
 fn with_greater_size_tuple_returns_second() {
     max(
         |_, process| {
-            process.tuple_from_slice(&[process.integer(1), process.integer(2), process.integer(3)])
+            process.tuple_term_from_term_slice(&[process.integer(1).unwrap(), process.integer(2).unwrap(), process.integer(3).unwrap()])
         },
         Second,
     );
@@ -86,7 +86,7 @@ where
     R: FnOnce(Term, &Process) -> Term,
 {
     super::max(
-        |process| process.tuple_from_slice(&[process.integer(1), process.integer(2)]),
+        |process| process.tuple_term_from_term_slice(&[process.integer(1).unwrap(), process.integer(2).unwrap()]),
         second,
         which,
     );
diff --git a/native_implemented/otp/src/erlang/min_2.rs b/native_implemented/otp/src/erlang/min_2.rs
index c57b1da84..192173ffb 100644
--- a/native_implemented/otp/src/erlang/min_2.rs
+++ b/native_implemented/otp/src/erlang/min_2.rs
@@ -1,7 +1,7 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::term::Term;
 
 /// `min/2`
 ///
diff --git a/native_implemented/otp/src/erlang/min_2/test.rs b/native_implemented/otp/src/erlang/min_2/test.rs
index 7498b4624..fd23b07b2 100644
--- a/native_implemented/otp/src/erlang/min_2/test.rs
+++ b/native_implemented/otp/src/erlang/min_2/test.rs
@@ -16,8 +16,8 @@ use proptest::prop_assert_eq;
 use proptest::strategy::Strategy;
 use proptest::test_runner::{Config, TestRunner};
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Atom, Integer, Term};
 
 use crate::erlang::min_2::result;
 use crate::test::with_process;
diff --git a/native_implemented/otp/src/erlang/min_2/test/with_big_integer_first.rs b/native_implemented/otp/src/erlang/min_2/test/with_big_integer_first.rs
index 2424b98ab..b501a1183 100644
--- a/native_implemented/otp/src/erlang/min_2/test/with_big_integer_first.rs
+++ b/native_implemented/otp/src/erlang/min_2/test/with_big_integer_first.rs
@@ -2,14 +2,14 @@ use super::*;
 
 #[test]
 fn with_lesser_small_integer_second_returns_second() {
-    min(|_, process| process.integer(0), Second)
+    min(|_, process| process.integer(0).unwrap(), Second)
 }
 
 #[test]
 fn with_greater_small_integer_second_returns_first() {
     super::min(
-        |process| process.integer(SmallInteger::MIN_VALUE - 1),
-        |_, process| process.integer(SmallInteger::MIN_VALUE),
+        |process| process.integer(Integer::MIN_SMALL - 1).unwrap(),
+        |_, process| process.integer(Integer::MIN_SMALL).unwrap(),
         First,
     );
 }
@@ -17,7 +17,7 @@ fn with_greater_small_integer_second_returns_first() {
 #[test]
 fn with_lesser_big_integer_second_returns_second() {
     min(
-        |_, process| process.integer(SmallInteger::MIN_VALUE - 1),
+        |_, process| process.integer(Integer::MIN_SMALL - 1).unwrap(),
         Second,
     )
 }
@@ -30,7 +30,7 @@ fn with_same_big_integer_second_returns_first() {
 #[test]
 fn with_same_value_big_integer_second_returns_first() {
     min(
-        |_, process| process.integer(SmallInteger::MAX_VALUE + 1),
+        |_, process| process.integer(Integer::MAX_SMALL + 1).unwrap(),
         First,
     )
 }
@@ -38,21 +38,21 @@ fn with_same_value_big_integer_second_returns_first() {
 #[test]
 fn with_greater_big_integer_second_returns_first() {
     min(
-        |_, process| process.integer(SmallInteger::MAX_VALUE + 2),
+        |_, process| process.integer(Integer::MAX_SMALL + 2).unwrap(),
         First,
     )
 }
 
 #[test]
 fn with_lesser_float_second_returns_second() {
-    min(|_, process| process.float(1.0), Second)
+    min(|_, process| 1.0.into(), Second)
 }
 
 #[test]
 fn with_greater_float_second_returns_first() {
     super::min(
-        |process| process.integer(SmallInteger::MIN_VALUE - 1),
-        |_, process| process.float(1.0),
+        |process| process.integer(Integer::MIN_SMALL - 1).unwrap(),
+        |_, process| 1.0.into(),
         First,
     );
 }
@@ -79,7 +79,7 @@ where
     R: FnOnce(Term, &Process) -> Term,
 {
     super::min(
-        |process| process.integer(SmallInteger::MAX_VALUE + 1),
+        |process| process.integer(Integer::MAX_SMALL + 1).unwrap(),
         second,
         which,
     );
diff --git a/native_implemented/otp/src/erlang/min_2/test/with_empty_list_first.rs b/native_implemented/otp/src/erlang/min_2/test/with_empty_list_first.rs
index 936f0a456..170d3ae1d 100644
--- a/native_implemented/otp/src/erlang/min_2/test/with_empty_list_first.rs
+++ b/native_implemented/otp/src/erlang/min_2/test/with_empty_list_first.rs
@@ -1,7 +1,6 @@
 use super::*;
 
 use proptest::prop_oneof;
-use proptest::strategy::Strategy;
 
 #[test]
 fn without_non_empty_list_or_bitstring_second_returns_second() {
@@ -13,7 +12,7 @@ fn without_non_empty_list_or_bitstring_second_returns_second() {
                 })
         },
         |second| {
-            let first = Term::NIL;
+            let first = Term::Nil;
 
             prop_assert_eq!(result(first, second), second);
 
@@ -32,7 +31,7 @@ fn with_non_empty_list_or_bitstring_second_returns_first() {
             ]
         },
         |second| {
-            let first = Term::NIL;
+            let first = Term::Nil;
 
             prop_assert_eq!(result(first, second), first);
 
diff --git a/native_implemented/otp/src/erlang/min_2/test/with_float_first.rs b/native_implemented/otp/src/erlang/min_2/test/with_float_first.rs
index 8ce7f8be1..83ec70a6a 100644
--- a/native_implemented/otp/src/erlang/min_2/test/with_float_first.rs
+++ b/native_implemented/otp/src/erlang/min_2/test/with_float_first.rs
@@ -2,18 +2,18 @@ use super::*;
 
 #[test]
 fn with_lesser_small_integer_second_returns_second() {
-    min(|_, process| process.integer(-1), Second)
+    min(|_, process| process.integer(-1).unwrap(), Second)
 }
 
 #[test]
 fn with_greater_small_integer_second_returns_first() {
-    min(|_, process| process.integer(2), First)
+    min(|_, process| process.integer(2).unwrap(), First)
 }
 
 #[test]
 fn with_lesser_big_integer_second_returns_second() {
     min(
-        |_, process| process.integer(SmallInteger::MIN_VALUE - 1),
+        |_, process| process.integer(Integer::MIN_SMALL - 1).unwrap(),
         Second,
     )
 }
@@ -21,19 +21,19 @@ fn with_lesser_big_integer_second_returns_second() {
 #[test]
 fn with_greater_big_integer_second_returns_first() {
     min(
-        |_, process| process.integer(SmallInteger::MAX_VALUE + 1),
+        |_, process| process.integer(Integer::MAX_SMALL + 1).unwrap(),
         First,
     )
 }
 
 #[test]
 fn with_lesser_float_second_returns_second() {
-    min(|_, process| process.float(-1.0), Second)
+    min(|_, process| -1.0.into(), Second)
 }
 
 #[test]
 fn with_greater_float_second_returns_first() {
-    min(|_, process| process.float(1.0), First)
+    min(|_, process| 1.0.into(), First)
 }
 
 #[test]
@@ -41,7 +41,7 @@ fn without_number_returns_first() {
     run!(
         |arc_process| {
             (
-                strategy::term::float(arc_process.clone()),
+                strategy::term::float(),
                 strategy::term::is_not_number(arc_process.clone()),
             )
         },
@@ -57,5 +57,5 @@ fn min<R>(second: R, which: FirstSecond)
 where
     R: FnOnce(Term, &Process) -> Term,
 {
-    super::min(|process| process.float(1.0), second, which);
+    super::min(|process| 1.0.into(), second, which);
 }
diff --git a/native_implemented/otp/src/erlang/min_2/test/with_heap_binary_first.rs b/native_implemented/otp/src/erlang/min_2/test/with_heap_binary_first.rs
index 8ab1cde59..730ab7c5f 100644
--- a/native_implemented/otp/src/erlang/min_2/test/with_heap_binary_first.rs
+++ b/native_implemented/otp/src/erlang/min_2/test/with_heap_binary_first.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn with_number_atom_reference_function_port_pid_tuple_map_or_list_returns_second() {
     run!(
@@ -14,10 +12,10 @@ fn with_number_atom_reference_function_port_pid_tuple_map_or_list_returns_second
                             second.is_number()
                                 || second.is_atom()
                                 || second.is_reference()
-                                || second.is_boxed_function()
+                                || second.is_closure()
                                 || second.is_port()
                                 || second.is_pid()
-                                || second.is_boxed_tuple()
+                                || second.is_tuple()
                                 || second.is_list()
                         }),
                 )
diff --git a/native_implemented/otp/src/erlang/min_2/test/with_list_first.rs b/native_implemented/otp/src/erlang/min_2/test/with_list_first.rs
index 66fb31d9b..c9fc18f9d 100644
--- a/native_implemented/otp/src/erlang/min_2/test/with_list_first.rs
+++ b/native_implemented/otp/src/erlang/min_2/test/with_list_first.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn without_list_or_bitstring_second_returns_second() {
     run!(
@@ -24,13 +22,13 @@ fn without_list_or_bitstring_second_returns_second() {
 
 #[test]
 fn with_empty_list_second_returns_second() {
-    min(|_, _| Term::NIL, Second);
+    min(|_, _| Term::Nil, Second);
 }
 
 #[test]
 fn with_lesser_list_second_returns_second() {
     min(
-        |_, process| process.cons(process.integer(0), process.integer(0)),
+        |_, process| process.cons(process.integer(0).unwrap(), process.integer(0).unwrap()),
         Second,
     );
 }
@@ -43,7 +41,7 @@ fn with_same_list_second_returns_first() {
 #[test]
 fn with_same_value_list_second_returns_first() {
     min(
-        |_, process| process.cons(process.integer(0), process.integer(1)),
+        |_, process| process.cons(process.integer(0).unwrap(), process.integer(1).unwrap()),
         First,
     );
 }
@@ -51,7 +49,7 @@ fn with_same_value_list_second_returns_first() {
 #[test]
 fn with_greater_list_second_returns_first() {
     min(
-        |_, process| process.cons(process.integer(0), process.integer(2)),
+        |_, process| process.cons(process.integer(0).unwrap(), process.integer(2).unwrap()),
         First,
     );
 }
@@ -78,7 +76,7 @@ where
     R: FnOnce(Term, &Process) -> Term,
 {
     super::min(
-        |process| process.cons(process.integer(0), process.integer(1)),
+        |process| process.cons(process.integer(0).unwrap(), process.integer(1).unwrap()),
         second,
         which,
     );
diff --git a/native_implemented/otp/src/erlang/min_2/test/with_map_first.rs b/native_implemented/otp/src/erlang/min_2/test/with_map_first.rs
index 66511bc78..88c75c4f8 100644
--- a/native_implemented/otp/src/erlang/min_2/test/with_map_first.rs
+++ b/native_implemented/otp/src/erlang/min_2/test/with_map_first.rs
@@ -20,7 +20,7 @@ fn with_number_atom_reference_function_port_pid_or_tuple_second_returns_second()
 #[test]
 fn with_smaller_map_second_returns_second() {
     min(
-        |_, process| process.map_from_slice(&[(Atom::str_to_term("a"), process.integer(1))]),
+        |_, process| process.map_from_slice(&[(Atom::str_to_term("a"), process.integer(1).unwrap())]),
         Second,
     );
 }
@@ -30,8 +30,8 @@ fn with_same_size_map_with_lesser_keys_returns_second() {
     min(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("a"), process.integer(2)),
-                (Atom::str_to_term("b"), process.integer(3)),
+                (Atom::str_to_term("a"), process.integer(2).unwrap()),
+                (Atom::str_to_term("b"), process.integer(3).unwrap()),
             ])
         },
         Second,
@@ -43,8 +43,8 @@ fn with_same_size_map_with_same_keys_with_lesser_values_returns_second() {
     min(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("b"), process.integer(2)),
-                (Atom::str_to_term("c"), process.integer(2)),
+                (Atom::str_to_term("b"), process.integer(2).unwrap()),
+                (Atom::str_to_term("c"), process.integer(2).unwrap()),
             ])
         },
         Second,
@@ -61,8 +61,8 @@ fn with_same_value_map_returns_first() {
     min(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("b"), process.integer(2)),
-                (Atom::str_to_term("c"), process.integer(3)),
+                (Atom::str_to_term("b"), process.integer(2).unwrap()),
+                (Atom::str_to_term("c"), process.integer(3).unwrap()),
             ])
         },
         First,
@@ -74,8 +74,8 @@ fn with_same_size_map_with_same_keys_with_greater_values_returns_first() {
     min(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("b"), process.integer(3)),
-                (Atom::str_to_term("c"), process.integer(4)),
+                (Atom::str_to_term("b"), process.integer(3).unwrap()),
+                (Atom::str_to_term("c"), process.integer(4).unwrap()),
             ])
         },
         First,
@@ -87,8 +87,8 @@ fn with_same_size_map_with_greater_keys_returns_first() {
     min(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("c"), process.integer(2)),
-                (Atom::str_to_term("d"), process.integer(3)),
+                (Atom::str_to_term("c"), process.integer(2).unwrap()),
+                (Atom::str_to_term("d"), process.integer(3).unwrap()),
             ])
         },
         First,
@@ -100,9 +100,9 @@ fn with_greater_size_map_returns_first() {
     min(
         |_, process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("a"), process.integer(1)),
-                (Atom::str_to_term("b"), process.integer(2)),
-                (Atom::str_to_term("c"), process.integer(3)),
+                (Atom::str_to_term("a"), process.integer(1).unwrap()),
+                (Atom::str_to_term("b"), process.integer(2).unwrap()),
+                (Atom::str_to_term("c"), process.integer(3).unwrap()),
             ])
         },
         First,
@@ -133,8 +133,8 @@ where
     super::min(
         |process| {
             process.map_from_slice(&[
-                (Atom::str_to_term("b"), process.integer(2)),
-                (Atom::str_to_term("c"), process.integer(3)),
+                (Atom::str_to_term("b"), process.integer(2).unwrap()),
+                (Atom::str_to_term("c"), process.integer(3).unwrap()),
             ])
         },
         second,
diff --git a/native_implemented/otp/src/erlang/min_2/test/with_small_integer_first.rs b/native_implemented/otp/src/erlang/min_2/test/with_small_integer_first.rs
index abc087e74..8896be4e5 100644
--- a/native_implemented/otp/src/erlang/min_2/test/with_small_integer_first.rs
+++ b/native_implemented/otp/src/erlang/min_2/test/with_small_integer_first.rs
@@ -2,7 +2,7 @@ use super::*;
 
 #[test]
 fn with_lesser_small_integer_second_returns_second() {
-    min(|_, process| process.integer(-1), Second);
+    min(|_, process| process.integer(-1).unwrap(), Second);
 }
 
 #[test]
@@ -12,18 +12,18 @@ fn with_same_small_integer_second_returns_first() {
 
 #[test]
 fn with_same_value_small_integer_second_returns_first() {
-    min(|_, process| process.integer(0), First);
+    min(|_, process| process.integer(0).unwrap(), First);
 }
 
 #[test]
 fn with_greater_small_integer_second_returns_first() {
-    min(|_, process| process.integer(1), First);
+    min(|_, process| process.integer(1).unwrap(), First);
 }
 
 #[test]
 fn with_lesser_big_integer_second_returns_second() {
     min(
-        |_, process| process.integer(SmallInteger::MIN_VALUE - 1),
+        |_, process| process.integer(Integer::MIN_SMALL - 1).unwrap(),
         Second,
     )
 }
@@ -31,24 +31,24 @@ fn with_lesser_big_integer_second_returns_second() {
 #[test]
 fn with_greater_big_integer_second_returns_first() {
     min(
-        |_, process| process.integer(SmallInteger::MAX_VALUE + 1),
+        |_, process| process.integer(Integer::MAX_SMALL + 1).unwrap(),
         First,
     )
 }
 
 #[test]
 fn with_lesser_float_second_returns_second() {
-    min(|_, process| process.float(-1.0), Second)
+    min(|_, process| -1.0.into(), Second)
 }
 
 #[test]
 fn with_same_value_float_second_returns_first() {
-    min(|_, process| process.float(0.0), First)
+    min(|_, process| 0.0.into(), First)
 }
 
 #[test]
 fn with_greater_float_second_returns_first() {
-    min(|_, process| process.float(1.0), First)
+    min(|_, process| 1.0.into(), First)
 }
 
 #[test]
@@ -72,5 +72,5 @@ fn min<R>(second: R, which: FirstSecond)
 where
     R: FnOnce(Term, &Process) -> Term,
 {
-    super::min(|process| process.integer(0), second, which);
+    super::min(|process| process.integer(0).unwrap(), second, which);
 }
diff --git a/native_implemented/otp/src/erlang/min_2/test/with_subbinary_first.rs b/native_implemented/otp/src/erlang/min_2/test/with_subbinary_first.rs
index abd98a744..ae1d27459 100644
--- a/native_implemented/otp/src/erlang/min_2/test/with_subbinary_first.rs
+++ b/native_implemented/otp/src/erlang/min_2/test/with_subbinary_first.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn with_number_atom_reference_function_port_pid_tuple_map_or_list_second_returns_second() {
     run!(
@@ -14,10 +12,10 @@ fn with_number_atom_reference_function_port_pid_tuple_map_or_list_second_returns
                             second.is_number()
                                 || second.is_atom()
                                 || second.is_reference()
-                                || second.is_boxed_function()
+                                || second.is_closure()
                                 || second.is_port()
                                 || second.is_pid()
-                                || second.is_boxed_tuple()
+                                || second.is_tuple()
                                 || second.is_list()
                         }),
                 )
diff --git a/native_implemented/otp/src/erlang/min_2/test/with_tuple_first.rs b/native_implemented/otp/src/erlang/min_2/test/with_tuple_first.rs
index be82a9be3..999fe99ea 100644
--- a/native_implemented/otp/src/erlang/min_2/test/with_tuple_first.rs
+++ b/native_implemented/otp/src/erlang/min_2/test/with_tuple_first.rs
@@ -20,7 +20,7 @@ fn with_number_atom_reference_function_port_or_pid_returns_second() {
 #[test]
 fn with_smaller_tuple_second_returns_second() {
     min(
-        |_, process| process.tuple_from_slice(&[process.integer(1)]),
+        |_, process| process.tuple_term_from_term_slice(&[process.integer(1).unwrap()]),
         Second,
     );
 }
@@ -28,7 +28,7 @@ fn with_smaller_tuple_second_returns_second() {
 #[test]
 fn with_same_size_tuple_with_lesser_elements_returns_second() {
     min(
-        |_, process| process.tuple_from_slice(&[process.integer(1), process.integer(1)]),
+        |_, process| process.tuple_term_from_term_slice(&[process.integer(1).unwrap(), process.integer(1).unwrap()]),
         Second,
     );
 }
@@ -41,7 +41,7 @@ fn with_same_tuple_returns_first() {
 #[test]
 fn with_same_value_tuple_returns_first() {
     min(
-        |_, process| process.tuple_from_slice(&[process.integer(1), process.integer(2)]),
+        |_, process| process.tuple_term_from_term_slice(&[process.integer(1).unwrap(), process.integer(2).unwrap()]),
         First,
     );
 }
@@ -49,7 +49,7 @@ fn with_same_value_tuple_returns_first() {
 #[test]
 fn with_same_size_tuple_with_greater_elements_returns_first() {
     min(
-        |_, process| process.tuple_from_slice(&[process.integer(1), process.integer(3)]),
+        |_, process| process.tuple_term_from_term_slice(&[process.integer(1).unwrap(), process.integer(3).unwrap()]),
         First,
     );
 }
@@ -58,7 +58,7 @@ fn with_same_size_tuple_with_greater_elements_returns_first() {
 fn with_greater_size_tuple_returns_first() {
     min(
         |_, process| {
-            process.tuple_from_slice(&[process.integer(1), process.integer(2), process.integer(3)])
+            process.tuple_term_from_term_slice(&[process.integer(1).unwrap(), process.integer(2).unwrap(), process.integer(3).unwrap()])
         },
         First,
     );
@@ -86,7 +86,7 @@ where
     R: FnOnce(Term, &Process) -> Term,
 {
     super::min(
-        |process| process.tuple_from_slice(&[process.integer(1), process.integer(2)]),
+        |process| process.tuple_term_from_term_slice(&[process.integer(1).unwrap(), process.integer(2).unwrap()]),
         second,
         which,
     );
diff --git a/native_implemented/otp/src/erlang/module_loaded_1.rs b/native_implemented/otp/src/erlang/module_loaded_1.rs
index 3a34e36f5..5f026c000 100644
--- a/native_implemented/otp/src/erlang/module_loaded_1.rs
+++ b/native_implemented/otp/src/erlang/module_loaded_1.rs
@@ -1,9 +1,11 @@
-use liblumen_alloc::erts::apply::module_loaded;
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::term::prelude::*;
+use std::ptr::NonNull;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::function::module_loaded;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:module_loaded/1)]
-pub fn result(module: Term) -> exception::Result<Term> {
+pub fn result(module: Term) -> Result<Term, NonNull<ErlangException>> {
     let module_atom = term_try_into_atom!(module)?;
 
     Ok(module_loaded(module_atom).into())
diff --git a/native_implemented/otp/src/erlang/monitor_2.rs b/native_implemented/otp/src/erlang/monitor_2.rs
index 4f762c646..740656c68 100644
--- a/native_implemented/otp/src/erlang/monitor_2.rs
+++ b/native_implemented/otp/src/erlang/monitor_2.rs
@@ -2,13 +2,13 @@
 mod test;
 
 use std::convert::TryInto;
+use std::ptr::NonNull;
 
 use anyhow::*;
 
-use liblumen_alloc::atom;
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::{Monitor, Process};
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Atom, atoms, Pid, Reference, Term, Tuple};
 
 use crate::erlang::node_0;
 use crate::runtime::context::*;
@@ -18,10 +18,14 @@ use crate::runtime::{process, registry};
 const TYPE_CONTEXT: &str = "supported types are :port, :process, or :time_offset";
 
 #[native_implemented::function(erlang:monitor/2)]
-pub fn result(process: &Process, r#type: Term, item: Term) -> exception::Result<Term> {
+pub fn result(
+    process: &Process,
+    r#type: Term,
+    item: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     let type_atom: Atom = r#type.try_into().context(TYPE_CONTEXT)?;
 
-    match type_atom.name() {
+    match type_atom.as_str() {
         "port" => unimplemented!(),
         "process" => monitor_process_identifier(process, item),
         "time_offset" => unimplemented!(),
@@ -36,16 +40,15 @@ pub fn result(process: &Process, r#type: Term, item: Term) -> exception::Result<
 fn monitor_process_identifier(
     process: &Process,
     process_identifier: Term,
-) -> exception::Result<Term> {
-    match process_identifier.decode()? {
-        TypedTerm::Atom(atom) => Ok(monitor_process_registered_name(
+) -> Result<Term, NonNull<ErlangException>> {
+    match process_identifier {
+        Term::Atom(atom) => Ok(monitor_process_registered_name(
             process,
             process_identifier,
             atom,
         )),
-        TypedTerm::Pid(pid) => Ok(monitor_process_pid(process, process_identifier, pid)),
-        TypedTerm::ExternalPid(_) => unimplemented!(),
-        TypedTerm::Tuple(tuple) => monitor_process_tuple(process, process_identifier, &tuple),
+        Term::Pid(pid) => Ok(monitor_process_pid(process, process_identifier, pid)),
+        Term::Tuple(tuple) => monitor_process_tuple(process, process_identifier, &tuple),
         _ => Err(TypeError)
             .context(PROCESS_IDENTIFIER_CONTEXT)
             .map_err(From::from),
@@ -53,7 +56,7 @@ fn monitor_process_identifier(
 }
 
 fn monitor_process_identifier_noproc(process: &Process, identifier: Term) -> Term {
-    let monitor_reference = process.next_reference();
+    let monitor_reference = process.next_local_reference_term();
     let noproc_message = noproc_message(process, monitor_reference, identifier);
     process.send_from_self(noproc_message);
 
@@ -74,7 +77,7 @@ fn monitor_process_registered_name(
 ) -> Term {
     match registry::atom_to_process(&atom) {
         Some(monitored_arc_process) => {
-            let reference = process.next_reference();
+            let reference = process.next_local_reference_term();
 
             let reference_reference: Boxed<Reference> = reference.try_into().unwrap();
             let monitor = Monitor::Name {
@@ -90,7 +93,7 @@ fn monitor_process_registered_name(
             reference
         }
         None => {
-            let identifier = process.tuple_from_slice(&[process_identifier, node_0::result()]);
+            let identifier = process.tuple_term_from_term_slice(&[process_identifier, node_0::result()]);
 
             monitor_process_identifier_noproc(process, identifier)
         }
@@ -104,7 +107,7 @@ fn monitor_process_tuple(
     process: &Process,
     _process_identifier: Term,
     tuple: &Tuple,
-) -> exception::Result<Term> {
+) -> Result<Term, NonNull<ErlangException>> {
     if tuple.len() == 2 {
         let registered_name = tuple[0];
         let registered_name_atom = term_try_into_atom("registered name", registered_name)?;
@@ -132,14 +135,14 @@ fn monitor_process_tuple(
 }
 
 fn noproc_message(process: &Process, reference: Term, identifier: Term) -> Term {
-    let noproc = atom!("noproc");
+    let noproc = atoms::Noproc.into();
 
     down_message(process, reference, identifier, noproc)
 }
 
 fn down_message(process: &Process, reference: Term, identifier: Term, info: Term) -> Term {
-    let down = atom!("DOWN");
-    let r#type = atom!("process");
+    let down = atoms::Down.into();
+    let r#type = atoms::Process.into();
 
-    process.tuple_from_slice(&[down, reference, r#type, identifier, info])
+    process.tuple_term_from_term_slice(&[down, reference, r#type, identifier, info])
 }
diff --git a/native_implemented/otp/src/erlang/monitor_2/test.rs b/native_implemented/otp/src/erlang/monitor_2/test.rs
index 0cb6e238e..d8ec62ff8 100644
--- a/native_implemented/otp/src/erlang/monitor_2/test.rs
+++ b/native_implemented/otp/src/erlang/monitor_2/test.rs
@@ -1,14 +1,13 @@
 mod with_process_type;
 
-use std::convert::TryInto;
 use std::sync::Arc;
 
 use proptest::prop_oneof;
 use proptest::strategy::{BoxedStrategy, Just, Strategy};
 use proptest::test_runner::{Config, TestRunner};
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Atom, Term};
 
 use crate::runtime::{registry, scheduler};
 
@@ -39,8 +38,8 @@ fn without_supported_type_errors_badarg() {
 fn unsupported_type(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
     strategy::term(arc_process)
         .prop_filter("Type cannot be :process", |r#type| {
-            match r#type.decode().unwrap() {
-                TypedTerm::Atom(atom) => match atom.name() {
+            match r#type {
+                Term::Atom(atom) => match atom.as_str() {
                     "process" | "port" | "time_offset" => false,
                     _ => true,
                 },
diff --git a/native_implemented/otp/src/erlang/monitor_2/test/with_process_type/with_atom_process_identifier.rs b/native_implemented/otp/src/erlang/monitor_2/test/with_process_type/with_atom_process_identifier.rs
index 3d3d1f9d3..0c003353e 100644
--- a/native_implemented/otp/src/erlang/monitor_2/test/with_process_type/with_atom_process_identifier.rs
+++ b/native_implemented/otp/src/erlang/monitor_2/test/with_process_type/with_atom_process_identifier.rs
@@ -20,11 +20,11 @@ fn without_registered_name_returns_reference_but_immediate_sends_noproc_message(
 
         assert_has_message!(
             &monitoring_arc_process,
-            monitoring_arc_process.tuple_from_slice(&[
+            monitoring_arc_process.tuple_term_from_term_slice(&[
                 tag,
                 monitor_reference,
                 r#type(),
-                monitoring_arc_process.tuple_from_slice(&[registered_name, node_0::result()]),
+                monitoring_arc_process.tuple_term_from_term_slice(&[registered_name, node_0::result()]),
                 reason
             ])
         );
diff --git a/native_implemented/otp/src/erlang/monitor_2/test/with_process_type/with_atom_process_identifier/with_registered_name.rs b/native_implemented/otp/src/erlang/monitor_2/test/with_process_type/with_atom_process_identifier/with_registered_name.rs
index babb3c52d..3e2eac361 100644
--- a/native_implemented/otp/src/erlang/monitor_2/test/with_process_type/with_atom_process_identifier/with_registered_name.rs
+++ b/native_implemented/otp/src/erlang/monitor_2/test/with_process_type/with_atom_process_identifier/with_registered_name.rs
@@ -117,22 +117,22 @@ fn when_monitored_process_exits_it_sends_message_for_each_monitor_reference() {
 
         assert_has_message!(
             &monitoring_arc_process,
-            monitoring_arc_process.tuple_from_slice(&[
+            monitoring_arc_process.tuple_term_from_term_slice(&[
                 tag,
                 first_monitor_reference,
                 r#type(),
-                monitoring_arc_process.tuple_from_slice(&[first_registered_name, node_0::result()]),
+                monitoring_arc_process.tuple_term_from_term_slice(&[first_registered_name, node_0::result()]),
                 reason
             ])
         );
         assert_has_message!(
             &monitoring_arc_process,
-            monitoring_arc_process.tuple_from_slice(&[
+            monitoring_arc_process.tuple_term_from_term_slice(&[
                 tag,
                 second_monitor_reference,
                 r#type(),
                 monitoring_arc_process
-                    .tuple_from_slice(&[second_registered_name, node_0::result()]),
+                    .tuple_term_from_term_slice(&[second_registered_name, node_0::result()]),
                 reason
             ])
         );
diff --git a/native_implemented/otp/src/erlang/monitor_2/test/with_process_type/with_local_pid_process_identifier.rs b/native_implemented/otp/src/erlang/monitor_2/test/with_process_type/with_local_pid_process_identifier.rs
index 160e3c8ae..5c80e5cd4 100644
--- a/native_implemented/otp/src/erlang/monitor_2/test/with_process_type/with_local_pid_process_identifier.rs
+++ b/native_implemented/otp/src/erlang/monitor_2/test/with_process_type/with_local_pid_process_identifier.rs
@@ -15,12 +15,12 @@ fn without_process_returns_reference_but_immediate_sends_noproc_message() {
 
         assert!(monitor_reference.is_reference());
 
-        let tag = Atom::str_to_term("DOWN");
-        let reason = Atom::str_to_term("noproc");
+        let tag = atoms::Down.into();
+        let reason = atoms::Noproc.into();
 
         assert_has_message!(
             &monitoring_arc_process,
-            monitoring_arc_process.tuple_from_slice(&[
+            monitoring_arc_process.tuple_term_from_term_slice(&[
                 tag,
                 monitor_reference,
                 r#type(),
diff --git a/native_implemented/otp/src/erlang/monitor_2/test/with_process_type/with_local_pid_process_identifier/with_process.rs b/native_implemented/otp/src/erlang/monitor_2/test/with_process_type/with_local_pid_process_identifier/with_process.rs
index d8db274f4..28cab0023 100644
--- a/native_implemented/otp/src/erlang/monitor_2/test/with_process_type/with_local_pid_process_identifier/with_process.rs
+++ b/native_implemented/otp/src/erlang/monitor_2/test/with_process_type/with_local_pid_process_identifier/with_process.rs
@@ -1,4 +1,5 @@
 use super::*;
+use firefly_rt::term::Atom;
 
 #[test]
 fn returns_reference() {
@@ -11,7 +12,7 @@ fn returns_reference() {
         let monitor_reference_result = result(
             &monitoring_arc_process,
             r#type(),
-            monitored_arc_process.pid_term(),
+            monitored_arc_process.pid_term().unwrap(),
         );
 
         assert!(monitor_reference_result.is_ok());
@@ -45,13 +46,13 @@ fn returns_different_reference_each_time() {
         let first_monitor_reference = result(
             &monitoring_arc_process,
             r#type(),
-            monitored_arc_process.pid_term(),
+            monitored_arc_process.pid_term().unwrap(),
         )
         .unwrap();
         let second_monitor_reference = result(
             &monitoring_arc_process,
             r#type(),
-            monitored_arc_process.pid_term(),
+            monitored_arc_process.pid_term().unwrap(),
         )
         .unwrap();
 
@@ -79,20 +80,20 @@ fn when_monitored_process_exits_it_sends_message_for_each_monitor_reference() {
         let first_monitor_reference = result(
             &monitoring_arc_process,
             r#type(),
-            monitored_arc_process.pid_term(),
+            monitored_arc_process.pid_term().unwrap(),
         )
         .unwrap();
 
         let second_monitor_reference = result(
             &monitoring_arc_process,
             r#type(),
-            monitored_arc_process.pid_term(),
+            monitored_arc_process.pid_term().unwrap(),
         )
         .unwrap();
 
         assert!(!monitored_arc_process.is_exiting());
 
-        let reason = Atom::str_to_term("normal");
+        let reason = atoms::Normal.into();
         exit_when_run(&monitored_arc_process, reason);
 
         assert!(scheduler::run_through(&monitored_arc_process));
@@ -104,21 +105,21 @@ fn when_monitored_process_exits_it_sends_message_for_each_monitor_reference() {
 
         assert_has_message!(
             &monitoring_arc_process,
-            monitoring_arc_process.tuple_from_slice(&[
+            monitoring_arc_process.tuple_term_from_term_slice(&[
                 tag,
                 first_monitor_reference,
                 r#type(),
-                monitored_arc_process.pid_term(),
+                monitored_arc_process.pid_term().unwrap(),
                 reason
             ])
         );
         assert_has_message!(
             &monitoring_arc_process,
-            monitoring_arc_process.tuple_from_slice(&[
+            monitoring_arc_process.tuple_term_from_term_slice(&[
                 tag,
                 second_monitor_reference,
                 r#type(),
-                monitored_arc_process.pid_term(),
+                monitored_arc_process.pid_term().unwrap(),
                 reason
             ])
         );
diff --git a/native_implemented/otp/src/erlang/monitor_2/test/with_process_type/with_tuple_process_identifier.rs b/native_implemented/otp/src/erlang/monitor_2/test/with_process_type/with_tuple_process_identifier.rs
index c3353e65d..82f33937a 100644
--- a/native_implemented/otp/src/erlang/monitor_2/test/with_process_type/with_tuple_process_identifier.rs
+++ b/native_implemented/otp/src/erlang/monitor_2/test/with_process_type/with_tuple_process_identifier.rs
@@ -10,7 +10,7 @@ fn without_atom_registered_name_errors_badarg() {
                 &strategy::term::is_not_atom(arc_process.clone()),
                 |registered_name| {
                     let identifier =
-                        arc_process.tuple_from_slice(&[registered_name, node_0::result()]);
+                        arc_process.tuple_term_from_term_slice(&[registered_name, node_0::result()]);
 
                     prop_assert_is_not_atom!(
                         result(&arc_process, r#type(), identifier),
diff --git a/native_implemented/otp/src/erlang/monitor_2/test/with_process_type/with_tuple_process_identifier/with_atom_registered_name.rs b/native_implemented/otp/src/erlang/monitor_2/test/with_process_type/with_tuple_process_identifier/with_atom_registered_name.rs
index 40cdaafe0..669cebe8d 100644
--- a/native_implemented/otp/src/erlang/monitor_2/test/with_process_type/with_tuple_process_identifier/with_atom_registered_name.rs
+++ b/native_implemented/otp/src/erlang/monitor_2/test/with_process_type/with_tuple_process_identifier/with_atom_registered_name.rs
@@ -12,7 +12,7 @@ fn without_atom_node_errors_badarg() {
                     strategy::term::is_not_atom(arc_process.clone()),
                 ),
                 |(registered_name, node)| {
-                    let identifier = arc_process.tuple_from_slice(&[registered_name, node]);
+                    let identifier = arc_process.tuple_term_from_term_slice(&[registered_name, node]);
 
                     prop_assert_is_not_atom!(result(&arc_process, r#type(), identifier), node);
 
diff --git a/native_implemented/otp/src/erlang/monitor_2/test/with_process_type/with_tuple_process_identifier/with_atom_registered_name/with_local_node.rs b/native_implemented/otp/src/erlang/monitor_2/test/with_process_type/with_tuple_process_identifier/with_atom_registered_name/with_local_node.rs
index e172d6e34..76107933c 100644
--- a/native_implemented/otp/src/erlang/monitor_2/test/with_process_type/with_tuple_process_identifier/with_atom_registered_name/with_local_node.rs
+++ b/native_implemented/otp/src/erlang/monitor_2/test/with_process_type/with_tuple_process_identifier/with_atom_registered_name/with_local_node.rs
@@ -6,7 +6,7 @@ use super::*;
 fn without_registered_name_returns_reference_but_immediate_sends_noproc_message() {
     with_process_arc(|monitoring_arc_process| {
         let registered_name = registered_name();
-        let identifier = monitoring_arc_process.tuple_from_slice(&[registered_name, node()]);
+        let identifier = monitoring_arc_process.tuple_term_from_term_slice(&[registered_name, node()]);
 
         let monitor_reference_result = result(&monitoring_arc_process, r#type(), identifier);
 
@@ -21,7 +21,7 @@ fn without_registered_name_returns_reference_but_immediate_sends_noproc_message(
 
         assert_has_message!(
             &monitoring_arc_process,
-            monitoring_arc_process.tuple_from_slice(&[
+            monitoring_arc_process.tuple_term_from_term_slice(&[
                 tag,
                 monitor_reference,
                 r#type(),
diff --git a/native_implemented/otp/src/erlang/monitor_2/test/with_process_type/with_tuple_process_identifier/with_atom_registered_name/with_local_node/with_registered_name.rs b/native_implemented/otp/src/erlang/monitor_2/test/with_process_type/with_tuple_process_identifier/with_atom_registered_name/with_local_node/with_registered_name.rs
index e76a519f2..bdf10309e 100644
--- a/native_implemented/otp/src/erlang/monitor_2/test/with_process_type/with_tuple_process_identifier/with_atom_registered_name/with_local_node/with_registered_name.rs
+++ b/native_implemented/otp/src/erlang/monitor_2/test/with_process_type/with_tuple_process_identifier/with_atom_registered_name/with_local_node/with_registered_name.rs
@@ -17,7 +17,7 @@ fn returns_reference() {
         let monitored_monitor_count_before = monitor_count(&monitored_arc_process);
         let monitoring_monitored_count_before = monitored_count(&monitoring_arc_process);
 
-        let identifier = monitoring_arc_process.tuple_from_slice(&[registered_name, node()]);
+        let identifier = monitoring_arc_process.tuple_term_from_term_slice(&[registered_name, node()]);
 
         let monitor_reference_result = result(&monitoring_arc_process, r#type(), identifier);
 
@@ -57,7 +57,7 @@ fn returns_different_reference_each_time() {
         let monitored_monitor_count_before = monitor_count(&monitored_arc_process);
         let monitoring_monitored_count_before = monitored_count(&monitoring_arc_process);
 
-        let identifier = monitoring_arc_process.tuple_from_slice(&[registered_name, node()]);
+        let identifier = monitoring_arc_process.tuple_term_from_term_slice(&[registered_name, node()]);
         let first_monitor_reference =
             result(&monitoring_arc_process, r#type(), identifier).unwrap();
         let second_monitor_reference =
@@ -93,7 +93,7 @@ fn when_monitored_process_exits_it_sends_message_for_each_monitor_reference() {
         ));
 
         let first_identifier =
-            monitoring_arc_process.tuple_from_slice(&[first_registered_name, node()]);
+            monitoring_arc_process.tuple_term_from_term_slice(&[first_registered_name, node()]);
         let first_monitor_reference =
             result(&monitoring_arc_process, r#type(), first_identifier).unwrap();
 
@@ -107,7 +107,7 @@ fn when_monitored_process_exits_it_sends_message_for_each_monitor_reference() {
         ));
 
         let second_identifier =
-            monitoring_arc_process.tuple_from_slice(&[second_registered_name, node()]);
+            monitoring_arc_process.tuple_term_from_term_slice(&[second_registered_name, node()]);
         let second_monitor_reference =
             result(&monitoring_arc_process, r#type(), second_identifier).unwrap();
 
@@ -125,7 +125,7 @@ fn when_monitored_process_exits_it_sends_message_for_each_monitor_reference() {
 
         assert_has_message!(
             &monitoring_arc_process,
-            monitoring_arc_process.tuple_from_slice(&[
+            monitoring_arc_process.tuple_term_from_term_slice(&[
                 tag,
                 first_monitor_reference,
                 r#type(),
@@ -135,7 +135,7 @@ fn when_monitored_process_exits_it_sends_message_for_each_monitor_reference() {
         );
         assert_has_message!(
             &monitoring_arc_process,
-            monitoring_arc_process.tuple_from_slice(&[
+            monitoring_arc_process.tuple_term_from_term_slice(&[
                 tag,
                 second_monitor_reference,
                 r#type(),
diff --git a/native_implemented/otp/src/erlang/monotonic_time_0.rs b/native_implemented/otp/src/erlang/monotonic_time_0.rs
index fc6be4e2c..eea3164a4 100644
--- a/native_implemented/otp/src/erlang/monotonic_time_0.rs
+++ b/native_implemented/otp/src/erlang/monotonic_time_0.rs
@@ -1,14 +1,14 @@
 #[cfg(test)]
 mod test;
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::runtime::time::{monotonic, Unit::Native};
 
 #[native_implemented::function(erlang:monotonic_time/0)]
-pub fn result(process: &Process) -> Term {
+pub async fn result(process: &Process) -> Term {
     let big_int = monotonic::time_in_unit(Native);
 
-    process.integer(big_int)
+    process.integer(big_int).unwrap()
 }
diff --git a/native_implemented/otp/src/erlang/monotonic_time_0/test.rs b/native_implemented/otp/src/erlang/monotonic_time_0/test.rs
index e32083459..1949bc989 100644
--- a/native_implemented/otp/src/erlang/monotonic_time_0/test.rs
+++ b/native_implemented/otp/src/erlang/monotonic_time_0/test.rs
@@ -1,8 +1,6 @@
 use crate::erlang::monotonic_time_0::result;
 use crate::test::with_process;
 
-use liblumen_alloc::erts::time::Milliseconds;
-
 use crate::runtime::time::monotonic;
 
 #[test]
diff --git a/native_implemented/otp/src/erlang/monotonic_time_1.rs b/native_implemented/otp/src/erlang/monotonic_time_1.rs
index ee96b73c8..49c28adb9 100644
--- a/native_implemented/otp/src/erlang/monotonic_time_1.rs
+++ b/native_implemented/otp/src/erlang/monotonic_time_1.rs
@@ -3,17 +3,17 @@ mod test;
 
 use std::convert::TryInto;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::runtime::time::{monotonic, Unit};
 
 #[native_implemented::function(erlang:monotonic_time/1)]
-pub fn result(process: &Process, unit: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, unit: Term) -> Result<Term, NonNull<ErlangException>> {
     let unit_unit: Unit = unit.try_into()?;
     let big_int = monotonic::time_in_unit(unit_unit);
-    let term = process.integer(big_int);
+    let term = process.integer(big_int).unwrap();
 
     Ok(term)
 }
diff --git a/native_implemented/otp/src/erlang/monotonic_time_1/test.rs b/native_implemented/otp/src/erlang/monotonic_time_1/test.rs
index 37a6f5a20..80ab6d869 100644
--- a/native_implemented/otp/src/erlang/monotonic_time_1/test.rs
+++ b/native_implemented/otp/src/erlang/monotonic_time_1/test.rs
@@ -3,11 +3,9 @@ mod with_small_integer;
 
 use std::time::Duration;
 
-use proptest::strategy::{Just, Strategy};
+use proptest::strategy::Just;
 
-use liblumen_alloc::atom;
-use liblumen_alloc::erts::term::prelude::*;
-use liblumen_alloc::erts::time::Milliseconds;
+use firefly_rt::term::{atoms, Term};
 
 use crate::runtime::time::monotonic;
 
diff --git a/native_implemented/otp/src/erlang/monotonic_time_1/test/with_atom.rs b/native_implemented/otp/src/erlang/monotonic_time_1/test/with_atom.rs
index 31df70b6e..61bbf1304 100644
--- a/native_implemented/otp/src/erlang/monotonic_time_1/test/with_atom.rs
+++ b/native_implemented/otp/src/erlang/monotonic_time_1/test/with_atom.rs
@@ -3,14 +3,14 @@ use super::*;
 #[test]
 fn with_invalid_unit_errors_badarg() {
     with_process(|process| {
-        assert_badarg!(result(process, atom!("invalid")), SUPPORTED_UNITS);
+        assert_badarg!(result(process, atoms::Invalid.into()), SUPPORTED_UNITS);
     });
 }
 
 #[test]
 fn with_second_increases_after_2_seconds() {
     with_process(|process| {
-        let unit = Atom::str_to_term("second");
+        let unit = atoms::Second.into();
         let start_monotonic = monotonic::freeze();
 
         let first = result(process, unit).unwrap();
@@ -26,7 +26,7 @@ fn with_second_increases_after_2_seconds() {
 #[test]
 fn with_millisecond_increases_after_2_milliseconds() {
     with_process(|process| {
-        let unit = Atom::str_to_term("millisecond");
+        let unit = atoms::Millisecond.into();
         let start_monotonic = monotonic::freeze();
 
         let first = result(process, unit).unwrap();
diff --git a/native_implemented/otp/src/erlang/monotonic_time_1/test/with_small_integer.rs b/native_implemented/otp/src/erlang/monotonic_time_1/test/with_small_integer.rs
index a07c55d3c..aa8d7de44 100644
--- a/native_implemented/otp/src/erlang/monotonic_time_1/test/with_small_integer.rs
+++ b/native_implemented/otp/src/erlang/monotonic_time_1/test/with_small_integer.rs
@@ -4,7 +4,7 @@ use super::*;
 fn with_negative_errors_badarg() {
     with_process(|process| {
         assert_badarg!(
-            result(process, process.integer(-1)),
+            result(process, process.integer(-1).unwrap()),
             "hertz must be positive"
         );
     });
@@ -13,14 +13,14 @@ fn with_negative_errors_badarg() {
 #[test]
 fn with_zero_errors_badarg() {
     with_process(|process| {
-        assert_badarg!(result(process, process.integer(0)), SUPPORTED_UNITS);
+        assert_badarg!(result(process, process.integer(0).unwrap()), SUPPORTED_UNITS);
     });
 }
 
 #[test]
 fn with_positive_increases_after_2_time_units() {
     with_process(|process| {
-        let unit = process.integer(2);
+        let unit = process.integer(2).unwrap();
 
         let first = result(process, unit).unwrap();
 
diff --git a/native_implemented/otp/src/erlang/multiply_2.rs b/native_implemented/otp/src/erlang/multiply_2.rs
index ffef1968a..388355611 100644
--- a/native_implemented/otp/src/erlang/multiply_2.rs
+++ b/native_implemented/otp/src/erlang/multiply_2.rs
@@ -1,12 +1,16 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 /// `*/2` infix operator
 #[native_implemented::function(erlang:*/2)]
-pub fn result(process: &Process, multiplier: Term, multiplicand: Term) -> exception::Result<Term> {
+pub fn result(
+    process: &Process,
+    multiplier: Term,
+    multiplicand: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     number_infix_operator!(multiplier, multiplicand, process, checked_mul, *)
 }
diff --git a/native_implemented/otp/src/erlang/multiply_2/test.rs b/native_implemented/otp/src/erlang/multiply_2/test.rs
index 5c7331d91..16ce69b31 100644
--- a/native_implemented/otp/src/erlang/multiply_2/test.rs
+++ b/native_implemented/otp/src/erlang/multiply_2/test.rs
@@ -5,8 +5,8 @@ mod with_small_integer_multiplier;
 use proptest::prop_assert;
 use proptest::strategy::Just;
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Integer, Term};
 
 use crate::erlang::multiply_2::result;
 use crate::test::strategy;
diff --git a/native_implemented/otp/src/erlang/multiply_2/test/with_big_integer_multiplier.rs b/native_implemented/otp/src/erlang/multiply_2/test/with_big_integer_multiplier.rs
index 82fefd77a..b8be33635 100644
--- a/native_implemented/otp/src/erlang/multiply_2/test/with_big_integer_multiplier.rs
+++ b/native_implemented/otp/src/erlang/multiply_2/test/with_big_integer_multiplier.rs
@@ -53,7 +53,7 @@ fn with_integer_multiplicand_returns_big_integer() {
 #[test]
 fn with_float_multiplicand_without_underflow_or_overflow_returns_float() {
     with_big_int(|process, multiplier| {
-        let multiplicand = process.float(3.0);
+        let multiplicand = 3.0.into();
 
         let result = result(process, multiplier, multiplicand);
 
@@ -61,18 +61,18 @@ fn with_float_multiplicand_without_underflow_or_overflow_returns_float() {
 
         let product = result.unwrap();
 
-        assert!(product.is_boxed_float());
+        assert!(product.is_float());
     })
 }
 
 #[test]
 fn with_float_multiplicand_with_underflow_returns_min_float() {
     with_big_int(|process, multiplier| {
-        let multiplicand = process.float(std::f64::MIN);
+        let multiplicand = f64::MIN.into();
 
         assert_eq!(
             result(process, multiplier, multiplicand),
-            Ok(process.float(std::f64::MIN))
+            Ok(f64::MIN.into())
         );
     })
 }
@@ -80,11 +80,11 @@ fn with_float_multiplicand_with_underflow_returns_min_float() {
 #[test]
 fn with_float_multiplicand_with_overflow_returns_max_float() {
     with_big_int(|process, multiplier| {
-        let multiplicand = process.float(std::f64::MAX);
+        let multiplicand = f64::MAX.into();
 
         assert_eq!(
             result(process, multiplier, multiplicand),
-            Ok(process.float(std::f64::MAX))
+            Ok(f64::MAX.into())
         );
     })
 }
diff --git a/native_implemented/otp/src/erlang/multiply_2/test/with_float_multiplier.rs b/native_implemented/otp/src/erlang/multiply_2/test/with_float_multiplier.rs
index 2d7ba58c3..d4ff6634f 100644
--- a/native_implemented/otp/src/erlang/multiply_2/test/with_float_multiplier.rs
+++ b/native_implemented/otp/src/erlang/multiply_2/test/with_float_multiplier.rs
@@ -6,7 +6,7 @@ fn without_number_multiplicand_errors_badarith() {
         |arc_process| {
             (
                 Just(arc_process.clone()),
-                strategy::term::float(arc_process.clone()),
+                strategy::term::float(),
                 strategy::term::is_not_number(arc_process.clone()),
             )
         },
@@ -30,7 +30,7 @@ fn with_number_multiplicand_returns_float() {
         |arc_process| {
             (
                 Just(arc_process.clone()),
-                strategy::term::float(arc_process.clone()),
+                strategy::term::float(),
                 strategy::term::is_number(arc_process.clone()),
             )
         },
@@ -41,7 +41,7 @@ fn with_number_multiplicand_returns_float() {
 
             let product = result.unwrap();
 
-            prop_assert!(product.is_boxed_float());
+            prop_assert!(product.is_float());
 
             Ok(())
         },
@@ -51,11 +51,11 @@ fn with_number_multiplicand_returns_float() {
 #[test]
 fn with_float_multiplicand_without_underflow_or_overflow_returns_float() {
     with(|multiplier, process| {
-        let multiplicand = process.float(3.0);
+        let multiplicand = 3.0.into();
 
         assert_eq!(
             result(process, multiplier, multiplicand),
-            Ok(process.float(6.0))
+            Ok(6.0.into())
         );
     })
 }
@@ -63,11 +63,11 @@ fn with_float_multiplicand_without_underflow_or_overflow_returns_float() {
 #[test]
 fn with_float_multiplicand_with_underflow_returns_min_float() {
     with(|multiplier, process| {
-        let multiplicand = process.float(std::f64::MIN);
+        let multiplicand = f64::MIN.into();
 
         assert_eq!(
             result(process, multiplier, multiplicand),
-            Ok(process.float(std::f64::MIN))
+            Ok(f64::MIN.into())
         );
     })
 }
@@ -75,11 +75,11 @@ fn with_float_multiplicand_with_underflow_returns_min_float() {
 #[test]
 fn with_float_multiplicand_with_overflow_returns_max_float() {
     with(|multiplier, process| {
-        let multiplicand = process.float(std::f64::MAX);
+        let multiplicand = f64::MAX.into();
 
         assert_eq!(
             result(process, multiplier, multiplicand),
-            Ok(process.float(std::f64::MAX))
+            Ok(f64::MAX.into())
         );
     })
 }
@@ -89,7 +89,7 @@ where
     F: FnOnce(Term, &Process) -> (),
 {
     with_process(|process| {
-        let multiplier = process.float(2.0);
+        let multiplier = 2.0.into();
 
         f(multiplier, &process)
     })
diff --git a/native_implemented/otp/src/erlang/multiply_2/test/with_small_integer_multiplier.rs b/native_implemented/otp/src/erlang/multiply_2/test/with_small_integer_multiplier.rs
index a428f6c21..148b8fb68 100644
--- a/native_implemented/otp/src/erlang/multiply_2/test/with_small_integer_multiplier.rs
+++ b/native_implemented/otp/src/erlang/multiply_2/test/with_small_integer_multiplier.rs
@@ -27,11 +27,11 @@ fn without_number_multiplicand_errors_badarith() {
 #[test]
 fn with_small_integer_multiplicand_without_underflow_or_overflow_returns_small_integer() {
     with(|multiplier, process| {
-        let multiplicand = process.integer(3);
+        let multiplicand = process.integer(3).unwrap();
 
         assert_eq!(
             result(process, multiplier, multiplicand),
-            Ok(process.integer(6))
+            Ok(process.integer(6).unwrap())
         );
     })
 }
@@ -39,7 +39,7 @@ fn with_small_integer_multiplicand_without_underflow_or_overflow_returns_small_i
 #[test]
 fn with_small_integer_multiplicand_with_underflow_returns_big_integer() {
     with(|multiplier, process| {
-        let multiplicand = process.integer(SmallInteger::MIN_VALUE);
+        let multiplicand = process.integer(Integer::MIN_SMALL).unwrap();
 
         assert!(multiplicand.is_smallint());
 
@@ -56,7 +56,7 @@ fn with_small_integer_multiplicand_with_underflow_returns_big_integer() {
 #[test]
 fn with_small_integer_multiplicand_with_overflow_returns_big_integer() {
     with(|multiplier, process| {
-        let multiplicand = process.integer(SmallInteger::MAX_VALUE);
+        let multiplicand = process.integer(Integer::MAX_SMALL).unwrap();
 
         assert!(multiplicand.is_smallint());
 
@@ -97,11 +97,11 @@ fn with_big_integer_multiplicand_returns_big_integer() {
 #[test]
 fn with_float_multiplicand_without_underflow_or_overflow_returns_float() {
     with(|multiplier, process| {
-        let multiplicand = process.float(3.0);
+        let multiplicand = 3.0.into();
 
         assert_eq!(
             result(process, multiplier, multiplicand),
-            Ok(process.float(6.0))
+            Ok(6.0.into())
         );
     })
 }
@@ -109,11 +109,11 @@ fn with_float_multiplicand_without_underflow_or_overflow_returns_float() {
 #[test]
 fn with_float_multiplicand_with_underflow_returns_min_float() {
     with(|multiplier, process| {
-        let multiplicand = process.float(std::f64::MIN);
+        let multiplicand = f64::MIN.into();
 
         assert_eq!(
             result(process, multiplier, multiplicand),
-            Ok(process.float(std::f64::MIN))
+            Ok(f64::MIN.into())
         );
     })
 }
@@ -121,11 +121,11 @@ fn with_float_multiplicand_with_underflow_returns_min_float() {
 #[test]
 fn with_float_multiplicand_with_overflow_returns_max_float() {
     with(|multiplier, process| {
-        let multiplicand = process.float(std::f64::MAX);
+        let multiplicand = f64::MAX.into();
 
         assert_eq!(
             result(process, multiplier, multiplicand),
-            Ok(process.float(std::f64::MAX))
+            Ok(f64::MAX.into())
         );
     })
 }
@@ -135,7 +135,7 @@ where
     F: FnOnce(Term, &Process) -> (),
 {
     with_process(|process| {
-        let multiplier = process.integer(2);
+        let multiplier = process.integer(2).unwrap();
 
         f(multiplier, &process)
     })
diff --git a/native_implemented/otp/src/erlang/negate_1.rs b/native_implemented/otp/src/erlang/negate_1.rs
index 3f1ca4bf5..6d91af0ad 100644
--- a/native_implemented/otp/src/erlang/negate_1.rs
+++ b/native_implemented/otp/src/erlang/negate_1.rs
@@ -1,36 +1,37 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
+use std::ptr::NonNull;
 use anyhow::*;
 use num_bigint::BigInt;
+use firefly_rt::backtrace::Trace;
+use firefly_rt::error::ErlangException;
 
-use liblumen_alloc::erts::exception::{self, *};
-use liblumen_alloc::erts::process::trace::Trace;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 /// `-/1` prefix operator.
 #[native_implemented::function(erlang:-/1)]
-pub fn result(process: &Process, number: Term) -> exception::Result<Term> {
-    match number.decode().unwrap() {
-        TypedTerm::SmallInteger(small_integer) => {
+pub fn result(process: &Process, number: Term) -> Result<Term, NonNull<ErlangException>> {
+    match number {
+        Term::Int(small_integer) => {
             let number_isize: isize = small_integer.into();
             let negated_isize = -number_isize;
-            let negated_number: Term = process.integer(negated_isize);
+            let negated_number: Term = process.integer(negated_isize).unwrap();
 
             Ok(negated_number)
         }
-        TypedTerm::BigInteger(big_integer) => {
+        Term::BigInt(big_integer) => {
             let big_int: &BigInt = big_integer.as_ref().into();
             let negated_big_int = -big_int;
-            let negated_number = process.integer(negated_big_int);
+            let negated_number = process.integer(negated_big_int).unwrap();
 
             Ok(negated_number)
         }
-        TypedTerm::Float(float) => {
+        Term::Float(float) => {
             let number_f64: f64 = float.into();
             let negated_f64: f64 = -number_f64;
-            let negated_number = process.float(negated_f64);
+            let negated_number = negated_f64.into();
 
             Ok(negated_number)
         }
diff --git a/native_implemented/otp/src/erlang/negate_1/test.rs b/native_implemented/otp/src/erlang/negate_1/test.rs
index 529407e01..6c16d773b 100644
--- a/native_implemented/otp/src/erlang/negate_1/test.rs
+++ b/native_implemented/otp/src/erlang/negate_1/test.rs
@@ -1,6 +1,8 @@
 use proptest::strategy::{Just, Strategy};
 use proptest::{prop_assert_eq, prop_oneof};
 
+use firefly_rt::term::Term;
+
 use crate::erlang::negate_1::result;
 use crate::test::strategy;
 
@@ -32,10 +34,10 @@ fn with_integer_returns_integer_of_opposite_sign() {
                 Just(arc_process.clone()),
                 prop_oneof![std::isize::MIN..=-1, 1..=std::isize::MAX],
             )
-                .prop_map(|(arc_process, i)| (arc_process.clone(), arc_process.integer(i), i))
+                .prop_map(|(arc_process, i)| (arc_process.clone(), arc_process.integer(i).unwrap(), i))
         },
         |(arc_process, number, i)| {
-            let negated = arc_process.integer(-i);
+            let negated = arc_process.integer(-i).unwrap();
 
             prop_assert_eq!(result(&arc_process, number), Ok(negated));
 
@@ -52,10 +54,10 @@ fn with_float_returns_float_of_opposite_sign() {
                 Just(arc_process.clone()),
                 prop_oneof![std::f64::MIN..=-1.0, 1.0..=std::f64::MAX],
             )
-                .prop_map(|(arc_process, f)| (arc_process.clone(), arc_process.float(f), f))
+                .prop_map(|(arc_process, f)| (arc_process.clone(), f.into(), f))
         },
         |(arc_process, number, f)| {
-            let negated = arc_process.float(-f);
+            let negated = (-f).into();
 
             prop_assert_eq!(result(&arc_process, number), Ok(negated));
 
diff --git a/native_implemented/otp/src/erlang/nif_error_1.rs b/native_implemented/otp/src/erlang/nif_error_1.rs
index 4ee84cb2d..f8610b707 100644
--- a/native_implemented/otp/src/erlang/nif_error_1.rs
+++ b/native_implemented/otp/src/erlang/nif_error_1.rs
@@ -1,11 +1,9 @@
 use anyhow::*;
 
-use liblumen_alloc::erts::exception::{self, error};
-use liblumen_alloc::erts::process::trace::Trace;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:nif_error/1)]
-pub fn result(reason: Term) -> exception::Result<Term> {
+pub fn result(reason: Term) -> Result<Term, NonNull<ErlangException>> {
     Err(error(
         reason,
         None,
diff --git a/native_implemented/otp/src/erlang/node_0.rs b/native_implemented/otp/src/erlang/node_0.rs
index 113037817..c11197299 100644
--- a/native_implemented/otp/src/erlang/node_0.rs
+++ b/native_implemented/otp/src/erlang/node_0.rs
@@ -1,7 +1,7 @@
 #[cfg(test)]
 mod test;
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 use crate::runtime::distribution::nodes::node;
 
diff --git a/native_implemented/otp/src/erlang/node_0/test.rs b/native_implemented/otp/src/erlang/node_0/test.rs
index b9709a118..1d6a20eae 100644
--- a/native_implemented/otp/src/erlang/node_0/test.rs
+++ b/native_implemented/otp/src/erlang/node_0/test.rs
@@ -1,5 +1,3 @@
-use liblumen_alloc::erts::term::prelude::Atom;
-
 use crate::erlang::node_0::result;
 
 #[test]
diff --git a/native_implemented/otp/src/erlang/not_1.rs b/native_implemented/otp/src/erlang/not_1.rs
index 4e1572d1e..63ae93985 100644
--- a/native_implemented/otp/src/erlang/not_1.rs
+++ b/native_implemented/otp/src/erlang/not_1.rs
@@ -1,14 +1,16 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::term::prelude::Term;
+use std::ptr::NonNull;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::Term;
 
 use crate::runtime::context::*;
 
 /// `not/1` prefix operator.
 #[native_implemented::function(erlang:not/1)]
-pub fn result(boolean: Term) -> exception::Result<Term> {
+pub fn result(boolean: Term) -> Result<Term, NonNull<ErlangException>> {
     let boolean_bool: bool = term_try_into_bool("boolean", boolean)?;
     let output = !boolean_bool;
 
diff --git a/native_implemented/otp/src/erlang/now_0.rs b/native_implemented/otp/src/erlang/now_0.rs
index 036eb612b..2cdb9e48f 100644
--- a/native_implemented/otp/src/erlang/now_0.rs
+++ b/native_implemented/otp/src/erlang/now_0.rs
@@ -1,5 +1,5 @@
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::timestamp_0;
 
diff --git a/native_implemented/otp/src/erlang/number_or_badarith_1.rs b/native_implemented/otp/src/erlang/number_or_badarith_1.rs
index e5690796a..1c91bd439 100644
--- a/native_implemented/otp/src/erlang/number_or_badarith_1.rs
+++ b/native_implemented/otp/src/erlang/number_or_badarith_1.rs
@@ -1,14 +1,15 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
+use std::ptr::NonNull;
+
 use anyhow::*;
 
-use liblumen_alloc::erts::exception::{self, *};
-use liblumen_alloc::erts::process::trace::Trace;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:+/1)]
-pub fn result(number: Term) -> exception::Result<Term> {
+pub fn result(number: Term) -> Result<Term, NonNull<ErlangException>> {
     if number.is_number() {
         Ok(number)
     } else {
diff --git a/native_implemented/otp/src/erlang/number_to_integer.rs b/native_implemented/otp/src/erlang/number_to_integer.rs
index 55f2581f9..817a9e82c 100644
--- a/native_implemented/otp/src/erlang/number_to_integer.rs
+++ b/native_implemented/otp/src/erlang/number_to_integer.rs
@@ -1,7 +1,7 @@
 use num_bigint::BigInt;
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Float, Integer, Term};
 
 pub enum NumberToInteger {
     NotANumber,
@@ -11,10 +11,10 @@ pub enum NumberToInteger {
 
 impl From<Term> for NumberToInteger {
     fn from(number: Term) -> Self {
-        match number.decode().unwrap() {
-            TypedTerm::SmallInteger(_) => Self::Integer(number),
-            TypedTerm::BigInteger(_) => Self::Integer(number),
-            TypedTerm::Float(float) => Self::F64(float.into()),
+        match number {
+            Term::Int(_) => Self::Integer(number),
+            Term::BigInt(_) => Self::Integer(number),
+            Term::Float(float) => Self::F64(float.into()),
             _ => Self::NotANumber,
         }
     }
@@ -22,15 +22,15 @@ impl From<Term> for NumberToInteger {
 
 pub fn f64_to_integer(process: &Process, f: f64) -> Term {
     // skip creating a BigInt if f64 can fit in small integer.
-    if (SmallInteger::MIN_VALUE as f64).max(Float::INTEGRAL_MIN) <= f
-        && f <= (SmallInteger::MAX_VALUE as f64).min(Float::INTEGRAL_MAX)
+    if (Integer::MIN_SMALL as f64).max(Float::I64_LOWER_BOUNDARY) <= f
+        && f <= (Integer::MAX_SMALL as f64).min(Float::I64_UPPER_BOUNDARY)
     {
-        process.integer(f as isize)
+        process.integer(f as isize).unwrap()
     } else {
         let string = f.to_string();
         let bytes = string.as_bytes();
         let big_int = BigInt::parse_bytes(bytes, 10).unwrap();
 
-        process.integer(big_int)
+        process.integer(big_int).unwrap()
     }
 }
diff --git a/native_implemented/otp/src/erlang/or_2.rs b/native_implemented/otp/src/erlang/or_2.rs
index c327c3604..4fa82ca81 100644
--- a/native_implemented/otp/src/erlang/or_2.rs
+++ b/native_implemented/otp/src/erlang/or_2.rs
@@ -1,13 +1,13 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::Term;
 
 /// `or/2` infix operator.
 ///
 /// **NOTE: NOT SHORT-CIRCUITING!**
 #[native_implemented::function(erlang:or/2)]
-pub fn result(left_boolean: Term, right_boolean: Term) -> exception::Result<Term> {
+pub fn result(left_boolean: Term, right_boolean: Term) -> Result<Term, NonNull<ErlangException>> {
     boolean_infix_operator!(left_boolean, right_boolean, |)
 }
diff --git a/native_implemented/otp/src/erlang/orelse_2.rs b/native_implemented/otp/src/erlang/orelse_2.rs
index b791286ed..63a121778 100644
--- a/native_implemented/otp/src/erlang/orelse_2.rs
+++ b/native_implemented/otp/src/erlang/orelse_2.rs
@@ -1,15 +1,15 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::Term;
 
 /// `orelse/2` infix operator.
 ///
 /// Short-circuiting, but doesn't enforce `right` is boolean.  If you need to enforce `boolean` for
 /// both operands, use `or_2`.
 #[native_implemented::function(erlang:orelse/2)]
-pub fn result(left_boolean: Term, right_term: Term) -> exception::Result<Term> {
+pub fn result(left_boolean: Term, right_term: Term) -> Result<Term, NonNull<ErlangException>> {
     let left_bool: bool = term_try_into_bool!(left_boolean)?;
 
     if left_bool {
diff --git a/native_implemented/otp/src/erlang/orelse_2/test.rs b/native_implemented/otp/src/erlang/orelse_2/test.rs
index bde0b8220..8d5407b75 100644
--- a/native_implemented/otp/src/erlang/orelse_2/test.rs
+++ b/native_implemented/otp/src/erlang/orelse_2/test.rs
@@ -4,8 +4,8 @@ mod with_true_left;
 use proptest::prop_assert_eq;
 use proptest::test_runner::{Config, TestRunner};
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Atom, Term};
 
 use crate::erlang::orelse_2::result;
 use crate::runtime::scheduler::SchedulerDependentAlloc;
diff --git a/native_implemented/otp/src/erlang/orelse_2/test/with_false_left.rs b/native_implemented/otp/src/erlang/orelse_2/test/with_false_left.rs
index a10754bb5..27c3b4f4c 100644
--- a/native_implemented/otp/src/erlang/orelse_2/test/with_false_left.rs
+++ b/native_implemented/otp/src/erlang/orelse_2/test/with_false_left.rs
@@ -17,32 +17,32 @@ fn with_true_right_returns_true() {
 
 #[test]
 fn with_local_reference_right_returns_true() {
-    with_right_returns_right(|process| process.next_reference());
+    with_right_returns_right(|process| process.next_local_reference_term());
 }
 
 #[test]
 fn with_empty_list_right_returns_true() {
-    with_right_returns_right(|_| Term::NIL);
+    with_right_returns_right(|_| Term::Nil);
 }
 
 #[test]
 fn with_list_right_returns_true() {
-    with_right_returns_right(|process| process.cons(process.integer(0), process.integer(1)));
+    with_right_returns_right(|process| process.cons(process.integer(0).unwrap(), process.integer(1).unwrap()));
 }
 
 #[test]
 fn with_small_integer_right_returns_true() {
-    with_right_returns_right(|process| process.integer(1))
+    with_right_returns_right(|process| process.integer(1).unwrap())
 }
 
 #[test]
 fn with_big_integer_right_returns_true() {
-    with_right_returns_right(|process| process.integer(SmallInteger::MAX_VALUE + 1))
+    with_right_returns_right(|process| process.integer(Integer::MAX_SMALL + 1).unwrap())
 }
 
 #[test]
 fn with_float_right_returns_true() {
-    with_right_returns_right(|process| process.float(1.0));
+    with_right_returns_right(|process| 1.0.into());
 }
 
 #[test]
@@ -57,7 +57,7 @@ fn with_external_pid_right_returns_true() {
 
 #[test]
 fn with_tuple_right_returns_true() {
-    with_right_returns_right(|process| process.tuple_from_slice(&[]));
+    with_right_returns_right(|process| process.tuple_term_from_term_slice(&[]));
 }
 
 #[test]
diff --git a/native_implemented/otp/src/erlang/orelse_2/test/with_true_left.rs b/native_implemented/otp/src/erlang/orelse_2/test/with_true_left.rs
index 8d2b36c01..284ffcd48 100644
--- a/native_implemented/otp/src/erlang/orelse_2/test/with_true_left.rs
+++ b/native_implemented/otp/src/erlang/orelse_2/test/with_true_left.rs
@@ -2,7 +2,7 @@ use super::*;
 
 #[test]
 fn with_atom_right_returns_true() {
-    with_right_returns_true(|mut _process| Atom::str_to_term("right"));
+    with_right_returns_true(|mut _process| Atom::str_to_term("right").into());
 }
 
 #[test]
@@ -17,32 +17,32 @@ fn with_true_right_returns_true() {
 
 #[test]
 fn with_local_reference_right_returns_true() {
-    with_right_returns_true(|process| process.next_reference());
+    with_right_returns_true(|process| process.next_local_reference_term());
 }
 
 #[test]
 fn with_empty_list_right_returns_true() {
-    with_right_returns_true(|_| Term::NIL);
+    with_right_returns_true(|_| Term::Nil);
 }
 
 #[test]
 fn with_list_right_returns_true() {
-    with_right_returns_true(|process| process.cons(process.integer(0), process.integer(1)));
+    with_right_returns_true(|process| process.cons(process.integer(0).unwrap(), process.integer(1).unwrap()));
 }
 
 #[test]
 fn with_small_integer_right_returns_true() {
-    with_right_returns_true(|process| process.integer(1))
+    with_right_returns_true(|process| process.integer(1).unwrap())
 }
 
 #[test]
 fn with_big_integer_right_returns_true() {
-    with_right_returns_true(|process| process.integer(SmallInteger::MAX_VALUE + 1))
+    with_right_returns_true(|process| process.integer(Integer::MAX_SMALL + 1).unwrap())
 }
 
 #[test]
 fn with_float_right_returns_true() {
-    with_right_returns_true(|process| process.float(1.0));
+    with_right_returns_true(|process| 1.0.into());
 }
 
 #[test]
@@ -57,7 +57,7 @@ fn with_external_pid_right_returns_true() {
 
 #[test]
 fn with_tuple_right_returns_true() {
-    with_right_returns_true(|process| process.tuple_from_slice(&[]));
+    with_right_returns_true(|process| process.tuple_term_from_term_slice(&[]));
 }
 
 #[test]
diff --git a/native_implemented/otp/src/erlang/process_flag_2.rs b/native_implemented/otp/src/erlang/process_flag_2.rs
index 389ce9594..a925db72d 100644
--- a/native_implemented/otp/src/erlang/process_flag_2.rs
+++ b/native_implemented/otp/src/erlang/process_flag_2.rs
@@ -1,19 +1,25 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
+use std::ptr::NonNull;
+
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::runtime::context::*;
 
 #[native_implemented::function(erlang:process_flag/2)]
-pub fn result(process: &Process, flag: Term, value: Term) -> exception::Result<Term> {
+pub fn result(
+    process: &Process,
+    flag: Term,
+    value: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     let flag_atom = term_try_into_atom!(flag)?;
 
-    match flag_atom.name() {
+    match flag_atom.as_str() {
         "error_handler" => unimplemented!(),
         "max_heap_size" => unimplemented!(),
         "message_queue_data" => unimplemented!(),
diff --git a/native_implemented/otp/src/erlang/process_flag_2/test.rs b/native_implemented/otp/src/erlang/process_flag_2/test.rs
index 449cd35a3..101196686 100644
--- a/native_implemented/otp/src/erlang/process_flag_2/test.rs
+++ b/native_implemented/otp/src/erlang/process_flag_2/test.rs
@@ -1,10 +1,8 @@
 mod with_atom_flag;
 
-use std::convert::TryInto;
+use proptest::strategy::{BoxedStrategy, Just};
 
-use proptest::strategy::{BoxedStrategy, Just, Strategy};
-
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::{atoms, Atom, Term};
 
 use crate::erlang::process_flag_2::result;
 use crate::test::*;
diff --git a/native_implemented/otp/src/erlang/process_flag_2/test/with_atom_flag.rs b/native_implemented/otp/src/erlang/process_flag_2/test/with_atom_flag.rs
index 358f00e93..ab046bb93 100644
--- a/native_implemented/otp/src/erlang/process_flag_2/test/with_atom_flag.rs
+++ b/native_implemented/otp/src/erlang/process_flag_2/test/with_atom_flag.rs
@@ -25,7 +25,7 @@ fn unsupported_flag_atom() -> BoxedStrategy<Term> {
         .prop_filter("Cannot be a supported flag name", |atom| {
             let atom_atom: Atom = (*atom).try_into().unwrap();
 
-            match atom_atom.name() {
+            match atom_atom.as_str() {
                 "trap_exit" => false,
                 _ => true,
             }
diff --git a/native_implemented/otp/src/erlang/process_flag_2/test/with_atom_flag/with_trap_exit_flag.rs b/native_implemented/otp/src/erlang/process_flag_2/test/with_atom_flag/with_trap_exit_flag.rs
index 4807eebb5..057b542b6 100644
--- a/native_implemented/otp/src/erlang/process_flag_2/test/with_atom_flag/with_trap_exit_flag.rs
+++ b/native_implemented/otp/src/erlang/process_flag_2/test/with_atom_flag/with_trap_exit_flag.rs
@@ -30,5 +30,5 @@ fn without_boolean_value_errors_badarg() {
 // integration tests
 
 fn flag() -> Term {
-    Atom::str_to_term("trap_exit")
+    atoms::TrapExit
 }
diff --git a/native_implemented/otp/src/erlang/process_info_2.rs b/native_implemented/otp/src/erlang/process_info_2.rs
index ebefd3129..f6ce1cb1d 100644
--- a/native_implemented/otp/src/erlang/process_info_2.rs
+++ b/native_implemented/otp/src/erlang/process_info_2.rs
@@ -1,19 +1,17 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
+use std::ptr::NonNull;
 use anyhow::*;
 
-use liblumen_alloc::atom;
-use liblumen_alloc::borrow::clone_to_process::CloneToProcess;
-use liblumen_alloc::erts::exception::{self, InternalResult};
-use liblumen_alloc::erts::message::{self, MessageData};
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Atom, atoms, Term};
 
 use crate::runtime::registry::pid_to_process;
 
 #[native_implemented::function(erlang:process_info/2)]
-pub fn result(process: &Process, pid: Term, item: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, pid: Term, item: Term) -> Result<Term, NonNull<ErlangException>> {
     let pid_pid = term_try_into_local_pid!(pid)?;
     let item_atom: Atom = term_try_into_atom!(item)?;
 
@@ -22,7 +20,7 @@ pub fn result(process: &Process, pid: Term, item: Term) -> exception::Result<Ter
     } else {
         match pid_to_process(&pid_pid) {
             Some(pid_arc_process) => process_info(&pid_arc_process, item_atom),
-            None => Ok(atom!("undefined")),
+            None => Ok(atoms::Undefined.into()),
         }
     }
     .map_err(From::from)
@@ -31,7 +29,7 @@ pub fn result(process: &Process, pid: Term, item: Term) -> exception::Result<Ter
 // Private
 
 fn process_info(process: &Process, item: Atom) -> InternalResult<Term> {
-    match item.name() {
+    match item.as_str() {
         "backtrace" => unimplemented!(),
         "binary" => unimplemented!(),
         "catchlevel" => unimplemented!(),
@@ -81,20 +79,20 @@ fn process_info(process: &Process, item: Atom) -> InternalResult<Term> {
 }
 
 fn links(process: &Process) -> Term {
-    let tag = atom!("links");
+    let tag = atoms::Links.into();
 
     let vec: Vec<Term> = process
         .linked_pid_set
         .iter()
         .map(|ref_multi| ref_multi.encode().unwrap())
         .collect();
-    let value = process.list_from_slice(&vec);
+    let value = process.list_from_slice(&vec).unwrap();
 
-    process.tuple_from_slice(&[tag, value])
+    process.tuple_term_from_term_slice(&[tag, value])
 }
 
 fn messages(process: &Process) -> Term {
-    let tag = atom!("messages");
+    let tag = atoms::Messages.into();
 
     let vec: Vec<Term> = process
         .mailbox
@@ -109,56 +107,56 @@ fn messages(process: &Process) -> Term {
         })
         .collect();
 
-    let value = process.list_from_slice(&vec);
+    let value = process.list_from_slice(&vec).unwrap();
 
-    process.tuple_from_slice(&[tag, value])
+    process.tuple_term_from_term_slice(&[tag, value])
 }
 
 fn monitored_by(process: &Process) -> Term {
-    let tag = atom!("monitored_by");
+    let tag = atoms::MonitoredBy.into();
 
     let vec: Vec<Term> = process
         .monitor_by_reference
         .iter()
         .map(|ref_multi| ref_multi.monitoring_pid().encode().unwrap())
         .collect();
-    let value = process.list_from_slice(&vec);
+    let value = process.list_from_slice(&vec).unwrap();
 
-    process.tuple_from_slice(&[tag, value])
+    process.tuple_term_from_term_slice(&[tag, value])
 }
 
 fn monitors(process: &Process) -> Term {
-    let monitor_type = atom!("process");
+    let monitor_type = atoms::Process.into();
     let mut vec = Vec::new();
 
     for ref_multi in process.monitored_pid_by_reference.iter() {
         let pid = ref_multi.value();
         let monitor_value = pid.encode().unwrap();
-        let monitor = process.tuple_from_slice(&[monitor_type, monitor_value]);
+        let monitor = process.tuple_term_from_term_slice(&[monitor_type, monitor_value]);
         vec.push(monitor);
     }
 
-    let tag = atom!("monitors");
-    let value = process.list_from_slice(&vec);
+    let tag = atoms::Monitors.into();
+    let value = process.list_from_slice(&vec).unwrap();
 
-    process.tuple_from_slice(&[tag, value])
+    process.tuple_term_from_term_slice(&[tag, value])
 }
 
 fn registered_name(process: &Process) -> Term {
     match *process.registered_name.read() {
         Some(registered_name) => {
-            let tag = atom!("registered_name");
+            let tag = atoms::RegisteredName.into();
             let value = registered_name.encode().unwrap();
 
-            process.tuple_from_slice(&[tag, value])
+            process.tuple_term_from_term_slice(&[tag, value])
         }
-        None => Term::NIL,
+        None => Term::Nil,
     }
 }
 
 fn trap_exit(process: &Process) -> Term {
-    let tag = atom!("trap_exit");
+    let tag = atoms::TrapExit.into();
     let value = process.traps_exit().into();
 
-    process.tuple_from_slice(&[tag, value])
+    process.tuple_term_from_term_slice(&[tag, value])
 }
diff --git a/native_implemented/otp/src/erlang/process_info_2/test.rs b/native_implemented/otp/src/erlang/process_info_2/test.rs
index 5ad86363f..cc25252c8 100644
--- a/native_implemented/otp/src/erlang/process_info_2/test.rs
+++ b/native_implemented/otp/src/erlang/process_info_2/test.rs
@@ -1,15 +1,12 @@
 mod with_local_pid;
 
-use std::convert::TryInto;
-
-use proptest::strategy::{BoxedStrategy, Just, Strategy};
+use proptest::strategy::{BoxedStrategy, Just};
 use proptest::test_runner::{Config, TestRunner};
 
-use liblumen_alloc::erts::term::prelude::*;
-
-use crate::runtime::registry;
+use firefly_rt::term::{Atom, Term};
 
 use crate::erlang::process_info_2::result;
+use crate::runtime::registry;
 use crate::test;
 use crate::test::{registered_name, strategy, with_process_arc};
 
diff --git a/native_implemented/otp/src/erlang/process_info_2/test/with_local_pid.rs b/native_implemented/otp/src/erlang/process_info_2/test/with_local_pid.rs
index db768eb10..1960cb47f 100644
--- a/native_implemented/otp/src/erlang/process_info_2/test/with_local_pid.rs
+++ b/native_implemented/otp/src/erlang/process_info_2/test/with_local_pid.rs
@@ -7,7 +7,7 @@ fn without_supported_item_errors_badarg() {
     with_process_arc(|arc_process| {
         TestRunner::new(Config::with_source_file(file!()))
             .run(&unsupported_item_atom(), |item| {
-                let pid = arc_process.pid_term();
+                let pid = arc_process.pid_term().unwrap();
                 prop_assert_badarg!(
                     result(&arc_process, pid, item),
                     "supported items are backtrace, binary, catchlevel, current_function, \
@@ -28,7 +28,7 @@ fn without_supported_item_errors_badarg() {
 
 fn unsupported_item_atom() -> BoxedStrategy<Term> {
     strategy::atom()
-        .prop_filter("Item cannot be supported", |atom| match atom.name() {
+        .prop_filter("Item cannot be supported", |atom| match atom.as_str() {
             "registered_name" => false,
             _ => true,
         })
diff --git a/native_implemented/otp/src/erlang/process_info_2/test/with_local_pid/with_registered_name/with_other.rs b/native_implemented/otp/src/erlang/process_info_2/test/with_local_pid/with_registered_name/with_other.rs
index ed65c67cf..4cba55171 100644
--- a/native_implemented/otp/src/erlang/process_info_2/test/with_local_pid/with_registered_name/with_other.rs
+++ b/native_implemented/otp/src/erlang/process_info_2/test/with_local_pid/with_registered_name/with_other.rs
@@ -11,7 +11,7 @@ fn without_registered_returns_empty_list() {
                 unregistred_arc_process.pid_term(),
                 item()
             ),
-            Ok(Term::NIL)
+            Ok(Term::Nil)
         );
     });
 }
@@ -34,7 +34,7 @@ fn with_registered_returns_empty_list() {
                 registered_process_arc.pid_term(),
                 item()
             ),
-            Ok(parent_process_arc.tuple_from_slice(&[item(), registered_name]))
+            Ok(parent_process_arc.tuple_term_from_term_slice(&[item(), registered_name]))
         );
     });
 }
diff --git a/native_implemented/otp/src/erlang/process_info_2/test/with_local_pid/with_registered_name/with_self.rs b/native_implemented/otp/src/erlang/process_info_2/test/with_local_pid/with_registered_name/with_self.rs
index 6917e9520..7d3ec011c 100644
--- a/native_implemented/otp/src/erlang/process_info_2/test/with_local_pid/with_registered_name/with_self.rs
+++ b/native_implemented/otp/src/erlang/process_info_2/test/with_local_pid/with_registered_name/with_self.rs
@@ -6,10 +6,10 @@ fn without_registered_returns_empty_list() {
         assert_eq!(
             result(
                 &unregistered_process_arc,
-                unregistered_process_arc.pid_term(),
+                unregistered_process_arc.pid_term().unwrap(),
                 item()
             ),
-            Ok(Term::NIL)
+            Ok(Term::Nil)
         );
     });
 }
@@ -31,7 +31,7 @@ fn with_registered_returns_empty_list() {
                 registered_process_arc.pid_term(),
                 item()
             ),
-            Ok(registered_process_arc.tuple_from_slice(&[item(), registered_name]))
+            Ok(registered_process_arc.tuple_term_from_term_slice(&[item(), registered_name]))
         );
     });
 }
diff --git a/native_implemented/otp/src/erlang/put_2.rs b/native_implemented/otp/src/erlang/put_2.rs
index 4f914cb60..b72d968c2 100644
--- a/native_implemented/otp/src/erlang/put_2.rs
+++ b/native_implemented/otp/src/erlang/put_2.rs
@@ -1,8 +1,8 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:put/2)]
 pub fn result(process: &Process, key: Term, value: Term) -> Term {
diff --git a/native_implemented/otp/src/erlang/put_2/test.rs b/native_implemented/otp/src/erlang/put_2/test.rs
index 65011decd..989df34fc 100644
--- a/native_implemented/otp/src/erlang/put_2/test.rs
+++ b/native_implemented/otp/src/erlang/put_2/test.rs
@@ -1,8 +1,6 @@
 use proptest::prop_assert_eq;
 use proptest::strategy::Just;
 
-use liblumen_alloc::erts::term::prelude::*;
-
 use crate::erlang::put_2::result;
 use crate::test::strategy;
 
diff --git a/native_implemented/otp/src/erlang/raise_3.rs b/native_implemented/otp/src/erlang/raise_3.rs
index bbc43e3f3..1f41430a6 100644
--- a/native_implemented/otp/src/erlang/raise_3.rs
+++ b/native_implemented/otp/src/erlang/raise_3.rs
@@ -2,18 +2,22 @@
 mod test;
 
 use std::convert::TryInto;
+use std::ptr::NonNull;
 use std::sync::Arc;
 
 use anyhow::*;
-
 use num_bigint::BigInt;
 
-use liblumen_alloc::erts::exception::{self, *};
-use liblumen_alloc::erts::term::prelude::*;
-use liblumen_alloc::erts::trace::Trace;
+use firefly_rt::backtrace::Trace;
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::{Term, Tuple};
 
 #[native_implemented::function(erlang:raise/3)]
-pub fn result(class: Term, reason: Term, stacktrace: Term) -> exception::Result<Term> {
+pub fn result(
+    class: Term,
+    reason: Term,
+    stacktrace: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     let class_class: exception::Class = class.try_into()?;
     let trace =
         trace_try_from_term(stacktrace).with_context(|| format!("stacktrace ({})", stacktrace))?;
@@ -28,9 +32,9 @@ pub fn result(class: Term, reason: Term, stacktrace: Term) -> exception::Result<
 }
 
 fn trace_try_from_term(stacktrace: Term) -> anyhow::Result<Arc<Trace>> {
-    match stacktrace.decode().unwrap() {
-        TypedTerm::Nil => Ok(Trace::from_term(stacktrace)),
-        TypedTerm::List(cons) => {
+    match stacktrace {
+        Term::Nil => Ok(Trace::from_term(stacktrace)),
+        Term::Cons(cons) => {
             for (index, result) in cons.iter().enumerate() {
                 match result {
                     Ok(element) => item_try_from_term(element).with_context(|| {
@@ -52,7 +56,7 @@ fn item_try_from_term(term: Term) -> anyhow::Result<()> {
     item_try_from_tuple(tuple)
 }
 
-fn item_try_from_tuple(tuple: Boxed<Tuple>) -> anyhow::Result<()> {
+fn item_try_from_tuple(tuple: NonNull<Tuple>) -> anyhow::Result<()> {
     match tuple.len() {
         2 => item_try_from_2_tuple(tuple).context("2-tuple"),
         3 => item_try_from_3_tuple(tuple).context("3-tuple"),
@@ -63,10 +67,10 @@ fn item_try_from_tuple(tuple: Boxed<Tuple>) -> anyhow::Result<()> {
 
 // {function, args}
 // https://github.com/erlang/otp/blob/b51f61b5f32a28737d0b03a29f19f48f38e4db19/erts/emulator/beam/bif.c#L1107-L1114
-fn item_try_from_2_tuple(tuple: Boxed<Tuple>) -> anyhow::Result<()> {
+fn item_try_from_2_tuple(tuple: NonNull<Tuple>) -> anyhow::Result<()> {
     let fun = tuple[0];
 
-    if fun.is_boxed_function() {
+    if fun.is_closure() {
         Ok(())
     } else {
         Err(anyhow!("`Fun` ({}) is not a function", fun)).context("is not format `{{Fun, Args}}`")
@@ -74,12 +78,12 @@ fn item_try_from_2_tuple(tuple: Boxed<Tuple>) -> anyhow::Result<()> {
 }
 
 // https://github.com/erlang/otp/blob/b51f61b5f32a28737d0b03a29f19f48f38e4db19/erts/emulator/beam/bif.c#L1115-L1128
-fn item_try_from_3_tuple(tuple: Boxed<Tuple>) -> anyhow::Result<()> {
+fn item_try_from_3_tuple(tuple: NonNull<Tuple>) -> anyhow::Result<()> {
     let first_element = tuple[0];
 
-    match first_element.decode().unwrap() {
+    match first_element {
         // {M, F, arity | args}
-        TypedTerm::Atom(_) => {
+        Term::Atom(_) => {
             const FORMAT: &str = "is not format `{Module, Function, Arity | Args}`";
 
             let function = tuple[1];
@@ -90,7 +94,7 @@ fn item_try_from_3_tuple(tuple: Boxed<Tuple>) -> anyhow::Result<()> {
             Ok(())
         },
         // {function, args, location}
-        TypedTerm::Closure(_) => {
+        Term::Closure(_) => {
             location_try_from_term(tuple[2]).context("is not format `{Function, Args, Location}`")
         },
         _ => Err(anyhow!("is not one of the supported formats:\n1. {Module, Function, Arity | Args}\n2. {Function, Args, Location}")),
@@ -98,11 +102,11 @@ fn item_try_from_3_tuple(tuple: Boxed<Tuple>) -> anyhow::Result<()> {
 }
 
 fn arity_or_arguments_try_from_term(term: Term) -> anyhow::Result<()> {
-    match term.decode().unwrap() {
+    match term {
         // args
-        TypedTerm::Nil | TypedTerm::List(_) => Ok(()),
+        Term::Nil | Term::Cons(_) => Ok(()),
         // arity
-        TypedTerm::SmallInteger(small_integer) => {
+        Term::Int(small_integer) => {
             let arity: isize = small_integer.into();
 
             if 0 <= arity {
@@ -112,7 +116,7 @@ fn arity_or_arguments_try_from_term(term: Term) -> anyhow::Result<()> {
             }
         }
         // arity
-        TypedTerm::BigInteger(big_integer) => {
+        Term::BigInt(big_integer) => {
             let big_int = big_integer.as_ref().into();
             let zero_big_int: &BigInt = &0.into();
 
@@ -127,7 +131,7 @@ fn arity_or_arguments_try_from_term(term: Term) -> anyhow::Result<()> {
 }
 
 // https://github.com/erlang/otp/blob/b51f61b5f32a28737d0b03a29f19f48f38e4db19/erts/emulator/beam/bif.c#L1129-L1134
-fn item_try_from_4_tuple(tuple: Boxed<Tuple>) -> anyhow::Result<()> {
+fn item_try_from_4_tuple(tuple: NonNull<Tuple>) -> anyhow::Result<()> {
     const FORMAT: &str = "is not format `{Module, Function, Arity | Args, Location}`";
 
     // {M, F, arity | args, location}
@@ -144,9 +148,9 @@ fn item_try_from_4_tuple(tuple: Boxed<Tuple>) -> anyhow::Result<()> {
 }
 
 fn location_try_from_term(term: Term) -> anyhow::Result<()> {
-    match term.decode().unwrap() {
-        TypedTerm::Nil => Ok(()),
-        TypedTerm::List(cons) => {
+    match term {
+        Term::Nil => Ok(()),
+        Term::Cons(cons) => {
             for (index, result) in cons.iter().enumerate() {
                 match result {
                     Ok(element) => location_keyword_pair_from_term(element).with_context(|| {
@@ -171,7 +175,7 @@ fn location_keyword_pair_from_term(keyword_pair: Term) -> anyhow::Result<()> {
     location_keyword_pair_from_tuple(tuple)
 }
 
-fn location_keyword_pair_from_tuple(keyword_pair: Boxed<Tuple>) -> anyhow::Result<()> {
+fn location_keyword_pair_from_tuple(keyword_pair: NonNull<Tuple>) -> anyhow::Result<()> {
     if keyword_pair.len() == 2 {
         location_keyword_pair_from_2_tuple(keyword_pair)
             .with_context(|| format!("is not a keyword pair"))
@@ -180,12 +184,12 @@ fn location_keyword_pair_from_tuple(keyword_pair: Boxed<Tuple>) -> anyhow::Resul
     }
 }
 
-fn location_keyword_pair_from_2_tuple(keyword_pair: Boxed<Tuple>) -> anyhow::Result<()> {
+fn location_keyword_pair_from_2_tuple(keyword_pair: NonNull<Tuple>) -> anyhow::Result<()> {
     let key = keyword_pair[0];
     let key_atom = term_try_into_atom!(key)?;
     let value = keyword_pair[1];
 
-    match key_atom.name() {
+    match key_atom.as_str() {
         "file" => file_try_from_term(value),
         "line" => line_try_from_term(value),
         _ => Err(anyhow!("key ({}) is neither `file` nor `line`", key)),
@@ -193,8 +197,8 @@ fn location_keyword_pair_from_2_tuple(keyword_pair: Boxed<Tuple>) -> anyhow::Res
 }
 
 fn file_try_from_term(term: Term) -> anyhow::Result<()> {
-    match term.decode().unwrap() {
-        TypedTerm::List(cons) => {
+    match term {
+        Term::Cons(cons) => {
             for (index, result) in cons.iter().enumerate() {
                 match result {
                     Ok(element) => character_try_from_term(element)
@@ -215,15 +219,15 @@ fn character_try_from_term(term: Term) -> anyhow::Result<char> {
 }
 
 fn line_try_from_term(term: Term) -> anyhow::Result<()> {
-    match term.decode().unwrap() {
-        TypedTerm::SmallInteger(small_integer) => {
+    match term {
+        Term::Int(small_integer) => {
             if 0_isize < small_integer.into() {
                 Ok(())
             } else {
                 Err(anyhow!("line ({}) is not 1 or greater", term))
             }
         }
-        TypedTerm::BigInteger(big_integer) => {
+        Term::BigInt(big_integer) => {
             let big_int = big_integer.as_ref().into();
             let zero_big_int: &BigInt = &0.into();
 
diff --git a/native_implemented/otp/src/erlang/raise_3/test.rs b/native_implemented/otp/src/erlang/raise_3/test.rs
index 918de2fbf..bb1060998 100644
--- a/native_implemented/otp/src/erlang/raise_3/test.rs
+++ b/native_implemented/otp/src/erlang/raise_3/test.rs
@@ -2,9 +2,7 @@ mod with_atom_class;
 
 use proptest::prop_assert_eq;
 
-use liblumen_alloc::atom;
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 use crate::erlang::raise_3::result;
 use crate::test::strategy;
diff --git a/native_implemented/otp/src/erlang/raise_3/test/with_atom_class.rs b/native_implemented/otp/src/erlang/raise_3/test/with_atom_class.rs
index 4c17b1fe1..711414a92 100644
--- a/native_implemented/otp/src/erlang/raise_3/test/with_atom_class.rs
+++ b/native_implemented/otp/src/erlang/raise_3/test/with_atom_class.rs
@@ -1,12 +1,10 @@
 use super::*;
 
-use std::convert::TryInto;
-
 use proptest::prop_oneof;
 use proptest::strategy::{BoxedStrategy, Just, Strategy};
-
-use liblumen_alloc::erts::exception::{Class, Exception};
 use proptest::test_runner::TestCaseError;
+use firefly_rt::term::Atom;
+
 
 #[test]
 fn without_class_errors_badarg() {
@@ -63,7 +61,7 @@ fn with_class_with_empty_list_stacktrace_raises() {
             )
         },
         |((class_variant, class), reason)| {
-            let stacktrace = Term::NIL;
+            let stacktrace = Term::Nil;
 
             prop_assert_raises(class_variant, class, reason, stacktrace)
         },
@@ -85,7 +83,7 @@ fn with_class_with_stacktrace_without_atom_module_errors_badarg() {
                             // {M, F, arity | args}
                             module.is_atom() ||
                                     // {function, args, location}
-                                    module.is_boxed_function()
+                                    module.is_closure()
                         )
                     },
                 ),
@@ -94,7 +92,7 @@ fn with_class_with_stacktrace_without_atom_module_errors_badarg() {
             )
         },
         |(arc_process, class, reason, module, function, arity_or_arguments)| {
-            let stacktrace = arc_process.list_from_slice(&[arc_process.tuple_from_slice(&[
+            let stacktrace = arc_process.list_from_slice(&[arc_process.tuple_term_from_term_slice(&[
                 module,
                 function,
                 arity_or_arguments,
@@ -124,7 +122,7 @@ fn with_class_with_stacktrace_with_atom_module_without_atom_function_errors_bada
             )
         },
         |(arc_process, class, reason, module, function, arity_or_arguments)| {
-            let stacktrace = arc_process.list_from_slice(&[arc_process.tuple_from_slice(&[
+            let stacktrace = arc_process.list_from_slice(&[arc_process.tuple_term_from_term_slice(&[
                 module,
                 function,
                 arity_or_arguments,
@@ -155,7 +153,7 @@ fn with_class_with_stacktrace_with_atom_module_with_atom_function_without_arity_
             )
         },
         |(arc_process, class, reason, module, function, arity_or_arguments)| {
-            let stacktrace = arc_process.list_from_slice(&[arc_process.tuple_from_slice(&[
+            let stacktrace = arc_process.list_from_slice(&[arc_process.tuple_term_from_term_slice(&[
                 module,
                 function,
                 arity_or_arguments,
@@ -186,10 +184,10 @@ fn with_class_with_stacktrace_with_mfa_with_file_without_charlist_errors_badarg(
             )
         },
         |(arc_process, class, reason, module, function, arity_or_arguments, file_value)| {
-            let file_key = atom!("file");
+            let file_key = atoms::File.into();
             let location = arc_process
-                .list_from_slice(&[arc_process.tuple_from_slice(&[file_key, file_value])]);
-            let stacktrace = arc_process.list_from_slice(&[arc_process.tuple_from_slice(&[
+                .list_from_slice(&[arc_process.tuple_term_from_term_slice(&[file_key, file_value])]);
+            let stacktrace = arc_process.list_from_slice(&[arc_process.tuple_term_from_term_slice(&[
                 module,
                 function,
                 arity_or_arguments,
@@ -221,10 +219,10 @@ fn with_class_with_stacktrace_with_mfa_with_non_positive_line_with_errors_badarg
             )
         },
         |(arc_process, class, reason, module, function, arity_or_arguments, line_value)| {
-            let line_key = atom!("line");
+            let line_key = atoms::Line.into();
             let location = arc_process
-                .list_from_slice(&[arc_process.tuple_from_slice(&[line_key, line_value])]);
-            let stacktrace = arc_process.list_from_slice(&[arc_process.tuple_from_slice(&[
+                .list_from_slice(&[arc_process.tuple_term_from_term_slice(&[line_key, line_value])]);
+            let stacktrace = arc_process.list_from_slice(&[arc_process.tuple_term_from_term_slice(&[
                 module,
                 function,
                 arity_or_arguments,
@@ -255,7 +253,7 @@ fn with_class_with_stacktrace_with_mfa_with_invalid_location_errors_badarg() {
                 strategy::term::atom().prop_filter("Key cannot be file or line", |key| {
                     let key_atom: Atom = (*key).try_into().unwrap();
 
-                    match key_atom.name() {
+                    match key_atom.as_str() {
                         "file" | "line" => false,
                         _ => true,
                     }
@@ -265,8 +263,8 @@ fn with_class_with_stacktrace_with_mfa_with_invalid_location_errors_badarg() {
         },
         |(arc_process, class, reason, module, function, arity_or_arguments, key, value)| {
             let location =
-                arc_process.list_from_slice(&[arc_process.tuple_from_slice(&[key, value])]);
-            let stacktrace = arc_process.list_from_slice(&[arc_process.tuple_from_slice(&[
+                arc_process.list_from_slice(&[arc_process.tuple_term_from_term_slice(&[key, value])]).unwrap();
+            let stacktrace = arc_process.list_from_slice(&[arc_process.tuple_term_from_term_slice(&[
                 module,
                 function,
                 arity_or_arguments,
@@ -298,7 +296,7 @@ fn with_atom_module_with_atom_function_with_arity_raises() {
         },
         |(arc_process, (class_variant, class), reason, module, function, arity)| {
             let stacktrace = arc_process
-                .list_from_slice(&[arc_process.tuple_from_slice(&[module, function, arity])]);
+                .list_from_slice(&[arc_process.tuple_term_from_term_slice(&[module, function, arity])]);
 
             prop_assert_raises(class_variant, class, reason, stacktrace)
         },
@@ -320,7 +318,7 @@ fn with_atom_module_with_atom_function_with_arguments_raises() {
         },
         |(arc_process, (class_variant, class), reason, module, function, arguments)| {
             let stacktrace = arc_process
-                .list_from_slice(&[arc_process.tuple_from_slice(&[module, function, arguments])]);
+                .list_from_slice(&[arc_process.tuple_term_from_term_slice(&[module, function, arguments])]);
 
             prop_assert_raises(class_variant, class, reason, stacktrace)
         },
@@ -341,8 +339,8 @@ fn with_mfa_with_empty_location_raises() {
             )
         },
         |(arc_process, (class_variant, class), reason, module, function, arity_or_arguments)| {
-            let location = Term::NIL;
-            let stacktrace = arc_process.list_from_slice(&[arc_process.tuple_from_slice(&[
+            let location = Term::Nil;
+            let stacktrace = arc_process.list_from_slice(&[arc_process.tuple_term_from_term_slice(&[
                 module,
                 function,
                 arity_or_arguments,
@@ -370,11 +368,11 @@ fn with_mfa_with_file_raises() {
             )
         },
         |(arc_process, (class_variant, class), reason, module, function, arity, file_value)| {
-            let file_key = atom!("file");
+            let file_key = atoms::File.into();
             let location = arc_process
-                .list_from_slice(&[arc_process.tuple_from_slice(&[file_key, file_value])]);
+                .list_from_slice(&[arc_process.tuple_term_from_term_slice(&[file_key, file_value])]);
             let stacktrace = arc_process.list_from_slice(&[
-                arc_process.tuple_from_slice(&[module, function, arity, location])
+                arc_process.tuple_term_from_term_slice(&[module, function, arity, location])
             ]);
 
             prop_assert_raises(class_variant, class, reason, stacktrace)
@@ -405,10 +403,10 @@ fn with_mfa_with_positive_line_raises() {
             arity_or_arguments,
             line_value,
         )| {
-            let line_key = atom!("line");
+            let line_key = atoms::Line.into();
             let location = arc_process
-                .list_from_slice(&[arc_process.tuple_from_slice(&[line_key, line_value])]);
-            let stacktrace = arc_process.list_from_slice(&[arc_process.tuple_from_slice(&[
+                .list_from_slice(&[arc_process.tuple_term_from_term_slice(&[line_key, line_value])]);
+            let stacktrace = arc_process.list_from_slice(&[arc_process.tuple_term_from_term_slice(&[
                 module,
                 function,
                 arity_or_arguments,
@@ -446,13 +444,13 @@ fn with_mfa_with_file_and_line_raises() {
             file_value,
             line_value,
         )| {
-            let file_key = atom!("file");
-            let line_key = atom!("line");
+            let file_key = atoms::File.into();
+            let line_key = atoms::Line.into();
             let location = arc_process.list_from_slice(&[
-                arc_process.tuple_from_slice(&[file_key, file_value]),
-                arc_process.tuple_from_slice(&[line_key, line_value]),
+                arc_process.tuple_term_from_term_slice(&[file_key, file_value]),
+                arc_process.tuple_term_from_term_slice(&[line_key, line_value]),
             ]);
-            let stacktrace = arc_process.list_from_slice(&[arc_process.tuple_from_slice(&[
+            let stacktrace = arc_process.list_from_slice(&[arc_process.tuple_term_from_term_slice(&[
                 module,
                 function,
                 arity_or_arguments,
@@ -466,7 +464,7 @@ fn with_mfa_with_file_and_line_raises() {
 
 fn class() -> BoxedStrategy<Term> {
     prop_oneof![Just("error"), Just("exit"), Just("throw")]
-        .prop_map(|string| atom!(&string))
+        .prop_map(|string| Atom::str_to_term(&string).into())
         .boxed()
 }
 
@@ -476,7 +474,7 @@ fn class_variant_and_term() -> BoxedStrategy<(Class, Term)> {
         Just((Class::Exit, "exit")),
         Just((Class::Throw, "throw"))
     ]
-    .prop_map(|(class_variant, string)| (class_variant, atom!(&string)))
+    .prop_map(|(class_variant, string)| (class_variant, Atom::str_to_term(&string).into()))
     .boxed()
 }
 
diff --git a/native_implemented/otp/src/erlang/read_timer_1.rs b/native_implemented/otp/src/erlang/read_timer_1.rs
index 9281a286c..5ee8a22f9 100644
--- a/native_implemented/otp/src/erlang/read_timer_1.rs
+++ b/native_implemented/otp/src/erlang/read_timer_1.rs
@@ -1,13 +1,13 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::read_timer;
 
 #[native_implemented::function(erlang:read_timer/1)]
-pub fn result(process: &Process, timer_reference: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, timer_reference: Term) -> Result<Term, NonNull<ErlangException>> {
     read_timer(timer_reference, Default::default(), process).map_err(From::from)
 }
diff --git a/native_implemented/otp/src/erlang/read_timer_1/test.rs b/native_implemented/otp/src/erlang/read_timer_1/test.rs
index 7401e8e97..8826d7335 100644
--- a/native_implemented/otp/src/erlang/read_timer_1/test.rs
+++ b/native_implemented/otp/src/erlang/read_timer_1/test.rs
@@ -1,7 +1,6 @@
 mod with_local_reference;
 
-use liblumen_alloc::erts::term::prelude::*;
-use liblumen_alloc::erts::time::Milliseconds;
+use firefly_rt::term::Term;
 
 use crate::erlang::read_timer_1::result;
 
diff --git a/native_implemented/otp/src/erlang/read_timer_1/test/with_local_reference/with_timer.rs b/native_implemented/otp/src/erlang/read_timer_1/test/with_local_reference/with_timer.rs
index 3982943fb..1d68d67a3 100644
--- a/native_implemented/otp/src/erlang/read_timer_1/test/with_local_reference/with_timer.rs
+++ b/native_implemented/otp/src/erlang/read_timer_1/test/with_local_reference/with_timer.rs
@@ -16,8 +16,8 @@ fn without_timeout_returns_milliseconds_remaining_and_does_not_send_timeout_mess
             result(process, timer_reference).expect("Timer could not be read");
 
         assert!(first_milliseconds_remaining.is_integer());
-        assert!(process.integer(0) < first_milliseconds_remaining);
-        assert!(first_milliseconds_remaining <= process.integer(milliseconds / 2));
+        assert!(process.integer(0).unwrap() < first_milliseconds_remaining);
+        assert!(first_milliseconds_remaining <= process.integer(milliseconds / 2).unwrap());
 
         // again before timeout
         let second_milliseconds_remaining =
diff --git a/native_implemented/otp/src/erlang/read_timer_2.rs b/native_implemented/otp/src/erlang/read_timer_2.rs
index e038e1f4f..8664f13f7 100644
--- a/native_implemented/otp/src/erlang/read_timer_2.rs
+++ b/native_implemented/otp/src/erlang/read_timer_2.rs
@@ -3,15 +3,19 @@ mod test;
 
 use std::convert::TryInto;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::read_timer;
 use crate::timer;
 
 #[native_implemented::function(erlang:read_timer/2)]
-pub fn result(process: &Process, timer_reference: Term, options: Term) -> exception::Result<Term> {
+pub fn result(
+    process: &Process,
+    timer_reference: Term,
+    options: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     let read_timer_options: timer::read::Options = options.try_into()?;
 
     read_timer(timer_reference, read_timer_options, process).map_err(From::from)
diff --git a/native_implemented/otp/src/erlang/read_timer_2/test.rs b/native_implemented/otp/src/erlang/read_timer_2/test.rs
index 5f5da0b98..ea324c4dd 100644
--- a/native_implemented/otp/src/erlang/read_timer_2/test.rs
+++ b/native_implemented/otp/src/erlang/read_timer_2/test.rs
@@ -1,14 +1,12 @@
 mod with_reference;
 
-use std::convert::TryInto;
 use std::sync::Arc;
 
 use proptest::prop_oneof;
 use proptest::strategy::{BoxedStrategy, Just, Strategy};
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
-use liblumen_alloc::erts::time::Milliseconds;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::read_timer_2::result;
 use crate::runtime::scheduler::SchedulerDependentAlloc;
@@ -66,16 +64,16 @@ fn with_reference_without_list_options_errors_badarg() {
 fn async_option(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
     strategy::term::is_boolean()
         .prop_map(move |async_value| {
-            arc_process.tuple_from_slice(&[Atom::str_to_term("async"), async_value])
+            arc_process.tuple_term_from_term_slice(&[Atom::str_to_term("async"), async_value])
         })
         .boxed()
 }
 
 fn options(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
     prop_oneof![
-        Just(Term::NIL),
+        Just(Term::Nil),
         async_option(arc_process.clone())
-            .prop_map(move |async_option| { arc_process.list_from_slice(&[async_option]) })
+            .prop_map(move |async_option| { arc_process.list_from_slice(&[async_option]) }).unwrap()
     ]
     .boxed()
 }
diff --git a/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_empty_list_options.rs b/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_empty_list_options.rs
index 1b7174734..a9dfc1632 100644
--- a/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_empty_list_options.rs
+++ b/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_empty_list_options.rs
@@ -5,7 +5,7 @@ mod with_timer;
 #[test]
 fn without_timer_returns_false() {
     with_process(|process| {
-        let timer_reference = process.next_reference();
+        let timer_reference = process.next_local_reference_term();
 
         assert_eq!(
             result(process, timer_reference, options(process)),
@@ -15,5 +15,5 @@ fn without_timer_returns_false() {
 }
 
 fn options(_: &Process) -> Term {
-    Term::NIL
+    Term::Nil
 }
diff --git a/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_empty_list_options/with_timer.rs b/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_empty_list_options/with_timer.rs
index 472be21d5..c04b5a305 100644
--- a/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_empty_list_options/with_timer.rs
+++ b/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_empty_list_options/with_timer.rs
@@ -15,8 +15,8 @@ fn without_timeout_returns_milliseconds_remaining_and_does_not_send_timeout_mess
             result(process, timer_reference, options(process)).expect("Timer could not be read");
 
         assert!(first_milliseconds_remaining.is_integer());
-        assert!(process.integer(0) < first_milliseconds_remaining);
-        assert!(first_milliseconds_remaining <= process.integer(half_milliseconds));
+        assert!(process.integer(0).unwrap() < first_milliseconds_remaining);
+        assert!(first_milliseconds_remaining <= process.integer(half_milliseconds).unwrap());
 
         // again before timeout
         let second_milliseconds_remaining =
diff --git a/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_list_options.rs b/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_list_options.rs
index bd91c1c4c..9a337926a 100644
--- a/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_list_options.rs
+++ b/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_list_options.rs
@@ -10,5 +10,5 @@ fn async_option(value: bool, process: &Process) -> Term {
 }
 
 fn option(key: &str, value: bool, process: &Process) -> Term {
-    process.tuple_from_slice(&[Atom::str_to_term(key), value.into()])
+    process.tuple_term_from_term_slice(&[Atom::str_to_term(key), value.into()])
 }
diff --git a/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_list_options/with_async_false.rs b/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_list_options/with_async_false.rs
index 8214129a8..a7fb0b11a 100644
--- a/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_list_options/with_async_false.rs
+++ b/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_list_options/with_async_false.rs
@@ -5,7 +5,7 @@ mod with_timer;
 #[test]
 fn without_timer_returns_false() {
     with_process(|process| {
-        let timer_reference = process.next_reference();
+        let timer_reference = process.next_local_reference_term();
 
         assert_eq!(
             result(process, timer_reference, options(process)),
@@ -15,5 +15,5 @@ fn without_timer_returns_false() {
 }
 
 fn options(process: &Process) -> Term {
-    process.cons(async_option(false, process), Term::NIL)
+    process.cons(async_option(false, process), Term::Nil)
 }
diff --git a/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_list_options/with_async_false/with_timer.rs b/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_list_options/with_async_false/with_timer.rs
index 98b0f3841..34ec86628 100644
--- a/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_list_options/with_async_false/with_timer.rs
+++ b/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_list_options/with_async_false/with_timer.rs
@@ -18,8 +18,8 @@ fn without_timeout_returns_milliseconds() {
         let first_milliseconds_remaining = first_result.unwrap();
 
         assert!(first_milliseconds_remaining.is_integer());
-        assert!(process.integer(0) < first_milliseconds_remaining);
-        assert!(first_milliseconds_remaining <= process.integer(half_milliseconds));
+        assert!(process.integer(0).unwrap() < first_milliseconds_remaining);
+        assert!(first_milliseconds_remaining <= process.integer(half_milliseconds).unwrap());
 
         // again before timeout
         let second_milliseconds_remaining =
diff --git a/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_list_options/with_async_true.rs b/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_list_options/with_async_true.rs
index f0aa53409..41cbae1f1 100644
--- a/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_list_options/with_async_true.rs
+++ b/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_list_options/with_async_true.rs
@@ -5,7 +5,7 @@ mod with_timer;
 #[test]
 fn without_timer_returns_ok_and_sends_read_timer_message() {
     with_process(|process| {
-        let timer_reference = process.next_reference();
+        let timer_reference = process.next_local_reference_term();
 
         assert_eq!(
             result(process, timer_reference, options(process)),
@@ -19,5 +19,5 @@ fn without_timer_returns_ok_and_sends_read_timer_message() {
 }
 
 fn options(process: &Process) -> Term {
-    process.cons(async_option(true, process), Term::NIL)
+    process.cons(async_option(true, process), Term::Nil)
 }
diff --git a/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_list_options/with_async_true/with_timer.rs b/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_list_options/with_async_true/with_timer.rs
index c6ebb952b..a4e73dd62 100644
--- a/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_list_options/with_async_true/with_timer.rs
+++ b/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_list_options/with_async_true/with_timer.rs
@@ -19,7 +19,7 @@ fn without_timeout_returns_milliseconds_remaining_and_does_not_send_timeout_mess
 
         let first_received_message = receive_message(process).unwrap();
 
-        let first_received_tuple_result: core::result::Result<Boxed<Tuple>, _> =
+        let first_received_tuple_result: core::result::Result<NonNull<Tuple>, _> =
             first_received_message.try_into();
 
         assert!(first_received_tuple_result.is_ok());
@@ -32,8 +32,8 @@ fn without_timeout_returns_milliseconds_remaining_and_does_not_send_timeout_mess
         let first_milliseconds_remaining = first_received_tuple[2];
 
         assert!(first_milliseconds_remaining.is_integer());
-        assert!(process.integer(0) < first_milliseconds_remaining);
-        assert!(first_milliseconds_remaining <= process.integer(milliseconds / 2));
+        assert!(process.integer(0).unwrap() < first_milliseconds_remaining);
+        assert!(first_milliseconds_remaining <= process.integer(milliseconds / 2).unwrap());
 
         // again before timeout
         assert_eq!(
@@ -43,7 +43,7 @@ fn without_timeout_returns_milliseconds_remaining_and_does_not_send_timeout_mess
 
         let second_received_message = receive_message(process).unwrap();
 
-        let second_received_tuple_result: core::result::Result<Boxed<Tuple>, _> =
+        let second_received_tuple_result: core::result::Result<NonNull<Tuple>, _> =
             second_received_message.try_into();
 
         assert!(second_received_tuple_result.is_ok());
diff --git a/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_list_options/with_invalid_option.rs b/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_list_options/with_invalid_option.rs
index 1c51c7cf0..26f27f449 100644
--- a/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_list_options/with_invalid_option.rs
+++ b/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_list_options/with_invalid_option.rs
@@ -31,22 +31,22 @@ fn with_atom_option_errors_badarg() {
 
 #[test]
 fn with_local_reference_option_errors_badarg() {
-    with_option_errors_badarg(|process| process.next_reference());
+    with_option_errors_badarg(|process| process.next_local_reference_term());
 }
 
 #[test]
 fn with_small_integer_option_errors_badarg() {
-    with_option_errors_badarg(|process| process.integer(0));
+    with_option_errors_badarg(|process| process.integer(0).unwrap());
 }
 
 #[test]
 fn with_big_integer_option_errors_badarg() {
-    with_option_errors_badarg(|process| process.integer(SmallInteger::MAX_VALUE + 1));
+    with_option_errors_badarg(|process| process.integer(Integer::MAX_SMALL + 1).unwrap());
 }
 
 #[test]
 fn with_float_option_errors_badarg() {
-    with_option_errors_badarg(|process| process.float(1.0));
+    with_option_errors_badarg(|process| 1.0.into());
 }
 
 #[test]
@@ -61,7 +61,7 @@ fn with_external_pid_option_errors_badarg() {
 
 #[test]
 fn with_tuple_option_errors_badarg() {
-    with_option_errors_badarg(|process| process.tuple_from_slice(&[]));
+    with_option_errors_badarg(|process| process.tuple_term_from_term_slice(&[]));
 }
 
 #[test]
@@ -71,12 +71,12 @@ fn with_map_option_errors_badarg() {
 
 #[test]
 fn with_empty_list_option_errors_badarg() {
-    with_option_errors_badarg(|process| process.cons(process.integer(0), process.integer(1)));
+    with_option_errors_badarg(|process| process.cons(process.integer(0).unwrap(), process.integer(1).unwrap()));
 }
 
 #[test]
 fn with_list_option_errors_badarg() {
-    with_option_errors_badarg(|process| process.cons(process.integer(0), process.integer(1)));
+    with_option_errors_badarg(|process| process.cons(process.integer(0).unwrap(), process.integer(1).unwrap()));
 }
 
 #[test]
@@ -94,8 +94,8 @@ where
     O: FnOnce(&Process) -> Term,
 {
     with_process(|process| {
-        let timer_reference = process.next_reference();
-        let options = process.cons(option(process), Term::NIL);
+        let timer_reference = process.next_local_reference_term();
+        let options = process.cons(option(process), Term::Nil);
 
         assert_badarg!(
             result(process, timer_reference, options),
diff --git a/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_list_options/without_async.rs b/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_list_options/without_async.rs
index 5b9e07053..6b1088cb5 100644
--- a/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_list_options/without_async.rs
+++ b/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_list_options/without_async.rs
@@ -5,7 +5,7 @@ mod with_timer;
 #[test]
 fn without_timer_returns_false() {
     with_process(|process| {
-        let timer_reference = process.next_reference();
+        let timer_reference = process.next_local_reference_term();
 
         assert_eq!(
             result(process, timer_reference, options(process)),
@@ -15,5 +15,5 @@ fn without_timer_returns_false() {
 }
 
 fn options(_process: &Process) -> Term {
-    Term::NIL
+    Term::Nil
 }
diff --git a/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_list_options/without_async/with_timer.rs b/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_list_options/without_async/with_timer.rs
index ce64657a8..6ae4e5b5a 100644
--- a/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_list_options/without_async/with_timer.rs
+++ b/native_implemented/otp/src/erlang/read_timer_2/test/with_reference/with_list_options/without_async/with_timer.rs
@@ -14,8 +14,8 @@ fn without_timeout_returns_milliseconds_remaining_and_does_not_send_timeout_mess
             result(process, timer_reference, options(process)).expect("Timer could not be read");
 
         assert!(first_milliseconds_remaining.is_integer());
-        assert!(process.integer(0) < first_milliseconds_remaining);
-        assert!(first_milliseconds_remaining <= process.integer(milliseconds / 2));
+        assert!(process.integer(0).unwrap() < first_milliseconds_remaining);
+        assert!(first_milliseconds_remaining <= process.integer(milliseconds / 2).unwrap());
 
         // again before timeout
         let second_milliseconds_remaining =
diff --git a/native_implemented/otp/src/erlang/register_2.rs b/native_implemented/otp/src/erlang/register_2.rs
index 2cc99dfb8..52bccd66d 100644
--- a/native_implemented/otp/src/erlang/register_2.rs
+++ b/native_implemented/otp/src/erlang/register_2.rs
@@ -1,25 +1,30 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
+use std::ptr::NonNull;
 use std::sync::Arc;
 
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::runtime::registry;
 
 #[native_implemented::function(erlang:register/2)]
-pub fn result(arc_process: Arc<Process>, name: Term, pid_or_port: Term) -> exception::Result<Term> {
+pub fn result(
+    arc_process: Arc<Process>,
+    name: Term,
+    pid_or_port: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     let atom = term_try_into_atom!(name)?;
 
-    match atom.name() {
+    match atom.as_str() {
         "undefined" => Err(anyhow!("undefined is not an allowed registered name").into()),
         _ => {
-            match pid_or_port.decode()? {
-                TypedTerm::Pid(pid) => {
+            match pid_or_port {
+                Term::Pid(pid) => {
                     match registry::pid_to_self_or_process(pid, &arc_process) {
                         Some(pid_arc_process) => {
                             if registry::put_atom_to_process(atom, pid_arc_process) {
@@ -31,17 +36,7 @@ pub fn result(arc_process: Arc<Process>, name: Term, pid_or_port: Term) -> excep
                         None => Err(anyhow!("{} is not a pid of an alive process", pid).into()),
                     }
                 }
-                TypedTerm::ExternalPid(_) => Err(anyhow!(
-                    "{} is an external pid, but only local pids can be registered",
-                    pid_or_port
-                )
-                .into()),
-                TypedTerm::Port(_) => unimplemented!(),
-                TypedTerm::ExternalPort(_) => Err(anyhow!(
-                    "{} is an external port, but only local ports can be registered",
-                    pid_or_port
-                )
-                .into()),
+                Term::Port(_) => unimplemented!(),
                 _ => Err(anyhow!("{} must be a local pid or port", pid_or_port).into()),
             }
         }
diff --git a/native_implemented/otp/src/erlang/register_2/test.rs b/native_implemented/otp/src/erlang/register_2/test.rs
index fe984d87a..488da4630 100644
--- a/native_implemented/otp/src/erlang/register_2/test.rs
+++ b/native_implemented/otp/src/erlang/register_2/test.rs
@@ -1,12 +1,9 @@
 mod with_atom_name;
 
-use std::convert::TryInto;
 use std::sync::Arc;
 
 use proptest::strategy::Just;
 
-use liblumen_alloc::erts::term::prelude::{Atom, Encoded, Pid};
-
 use crate::runtime::registry;
 
 use crate::erlang;
diff --git a/native_implemented/otp/src/erlang/register_2/test/with_atom_name.rs b/native_implemented/otp/src/erlang/register_2/test/with_atom_name.rs
index 24e67504a..fa30168c5 100644
--- a/native_implemented/otp/src/erlang/register_2/test/with_atom_name.rs
+++ b/native_implemented/otp/src/erlang/register_2/test/with_atom_name.rs
@@ -44,11 +44,11 @@ fn with_registered_name_errors_badarg() {
             result(
                 unregistered_process_arc.clone(),
                 registered_name,
-                unregistered_process_arc.pid_term(),
+                unregistered_process_arc.pid_term().unwrap(),
             ),
             format!(
                 "{} could not be registered as {}.  It may already be registered.",
-                unregistered_process_arc.pid_term(),
+                unregistered_process_arc.pid_term().unwrap(),
                 registered_name
             )
         );
diff --git a/native_implemented/otp/src/erlang/register_2/test/with_atom_name/without_registered_name.rs b/native_implemented/otp/src/erlang/register_2/test/with_atom_name/without_registered_name.rs
index 59c76f82b..1a98a36d1 100644
--- a/native_implemented/otp/src/erlang/register_2/test/with_atom_name/without_registered_name.rs
+++ b/native_implemented/otp/src/erlang/register_2/test/with_atom_name/without_registered_name.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 mod with_local_pid;
 
 #[test]
diff --git a/native_implemented/otp/src/erlang/registered_0.rs b/native_implemented/otp/src/erlang/registered_0.rs
index 606dada55..7008fc411 100644
--- a/native_implemented/otp/src/erlang/registered_0.rs
+++ b/native_implemented/otp/src/erlang/registered_0.rs
@@ -1,13 +1,15 @@
 #[cfg(test)]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use std::ptr::NonNull;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::runtime::registry;
 
 #[native_implemented::function(erlang:registered/0)]
-pub fn result(process: &Process) -> exception::Result<Term> {
+pub fn result(process: &Process) -> Result<Term, NonNull<ErlangException>> {
     registry::names(process)
 }
diff --git a/native_implemented/otp/src/erlang/registered_0/test.rs b/native_implemented/otp/src/erlang/registered_0/test.rs
index 0adf44181..2beb0b751 100644
--- a/native_implemented/otp/src/erlang/registered_0/test.rs
+++ b/native_implemented/otp/src/erlang/registered_0/test.rs
@@ -1,7 +1,7 @@
 // because registry is global and tests are concurrent, there is no way to test for completely
 // empty registry
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::{Atom, Term};
 
 use crate::erlang;
 use crate::erlang::registered_0::result;
@@ -10,13 +10,13 @@ use crate::test::with_process_arc;
 #[test]
 fn includes_registered_process_name() {
     with_process_arc(|process_arc| {
-        let name = Atom::str_to_term("registered_process_name");
+        let name: Term = Atom::str_to_term("registered_process_name").into();
 
         let before = result(&process_arc).unwrap();
 
-        match before.decode().unwrap() {
-            TypedTerm::Nil => (),
-            TypedTerm::List(before_cons) => {
+        match before {
+            Term::Nil => (),
+            Term::Cons(before_cons) => {
                 assert!(!before_cons.contains(name));
             }
             typed_term => panic!("Wrong TypedTerm ({:?})", typed_term),
@@ -29,8 +29,8 @@ fn includes_registered_process_name() {
 
         let after = result(&process_arc).unwrap();
 
-        match after.decode().unwrap() {
-            TypedTerm::List(after_cons) => assert!(after_cons.contains(name)),
+        match after {
+            Term::Cons(after_cons) => assert!(after_cons.contains(name)),
             typed_term => panic!("Wrong TypedTerm ({:?})", typed_term),
         }
     });
diff --git a/native_implemented/otp/src/erlang/rem_2.rs b/native_implemented/otp/src/erlang/rem_2.rs
index 206608693..79d661ac3 100644
--- a/native_implemented/otp/src/erlang/rem_2.rs
+++ b/native_implemented/otp/src/erlang/rem_2.rs
@@ -1,12 +1,16 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 /// `rem/2` infix operator.  Integer remainder.
 #[native_implemented::function(erlang:rem/2)]
-pub fn result(process: &Process, dividend: Term, divisor: Term) -> exception::Result<Term> {
+pub fn result(
+    process: &Process,
+    dividend: Term,
+    divisor: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     integer_infix_operator!(dividend, divisor, process, %)
 }
diff --git a/native_implemented/otp/src/erlang/rem_2/test.rs b/native_implemented/otp/src/erlang/rem_2/test.rs
index 9b56eb900..f7243f041 100644
--- a/native_implemented/otp/src/erlang/rem_2/test.rs
+++ b/native_implemented/otp/src/erlang/rem_2/test.rs
@@ -4,9 +4,9 @@ mod with_small_integer_dividend;
 use proptest::prop_assert_eq;
 use proptest::strategy::{BoxedStrategy, Just};
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Atom, Integer, Term};
 
 use crate::erlang::rem_2::result;
 use crate::runtime::scheduler::SchedulerDependentAlloc;
@@ -35,17 +35,17 @@ fn with_atom_dividend_errors_badarith() {
 
 #[test]
 fn with_local_reference_dividend_errors_badarith() {
-    with_dividend_errors_badarith(|process| process.next_reference());
+    with_dividend_errors_badarith(|process| process.next_local_reference_term());
 }
 
 #[test]
 fn with_empty_list_dividend_errors_badarith() {
-    with_dividend_errors_badarith(|_| Term::NIL);
+    with_dividend_errors_badarith(|_| Term::Nil);
 }
 
 #[test]
 fn with_list_dividend_errors_badarith() {
-    with_dividend_errors_badarith(|process| process.cons(process.integer(0), process.integer(1)));
+    with_dividend_errors_badarith(|process| process.cons(process.integer(0).unwrap(), process.integer(1).unwrap()));
 }
 
 #[test]
@@ -62,7 +62,7 @@ fn with_external_pid_dividend_errors_badarith() {
 
 #[test]
 fn with_tuple_dividend_errors_badarith() {
-    with_dividend_errors_badarith(|process| process.tuple_from_slice(&[]));
+    with_dividend_errors_badarith(|process| process.tuple_term_from_term_slice(&[]));
 }
 
 #[test]
@@ -89,7 +89,7 @@ where
 {
     errors_badarith(|process| {
         let dividend = dividend(&process);
-        let divisor = process.integer(0);
+        let divisor = process.integer(0).unwrap();
 
         result(&process, dividend, divisor)
     });
@@ -97,7 +97,7 @@ where
 
 fn errors_badarith<F>(actual: F)
 where
-    F: FnOnce(&Process) -> exception::Result<Term>,
+    F: FnOnce(&Process) -> Result<Term, NonNull<ErlangException>>,
 {
     with_process(|process| assert_badarith!(actual(&process)))
 }
diff --git a/native_implemented/otp/src/erlang/rem_2/test/with_big_integer_dividend.rs b/native_implemented/otp/src/erlang/rem_2/test/with_big_integer_dividend.rs
index 922b87b26..3db5a86f2 100644
--- a/native_implemented/otp/src/erlang/rem_2/test/with_big_integer_dividend.rs
+++ b/native_implemented/otp/src/erlang/rem_2/test/with_big_integer_dividend.rs
@@ -5,7 +5,7 @@ use crate::test::with_big_int;
 #[test]
 fn with_small_integer_divisor_with_underflow_returns_small_integer() {
     with_big_int(|process, dividend| {
-        let divisor: Term = process.integer(2);
+        let divisor: Term = process.integer(2).unwrap();
 
         assert!(divisor.is_smallint());
 
@@ -22,18 +22,18 @@ fn with_small_integer_divisor_with_underflow_returns_small_integer() {
 #[test]
 fn with_big_integer_divisor_with_underflow_returns_small_integer() {
     with_process(|process| {
-        let dividend: Term = process.integer(SmallInteger::MAX_VALUE + 2);
-        let divisor: Term = process.integer(SmallInteger::MAX_VALUE + 1);
+        let dividend: Term = process.integer(Integer::MAX_SMALL + 2).unwrap();
+        let divisor: Term = process.integer(Integer::MAX_SMALL + 1).unwrap();
 
-        assert_eq!(result(process, dividend, divisor), Ok(process.integer(1)));
+        assert_eq!(result(process, dividend, divisor), Ok(process.integer(1).unwrap()));
     })
 }
 
 #[test]
 fn with_big_integer_divisor_without_underflow_returns_big_integer() {
     with_process(|process| {
-        let dividend: Term = process.integer(SmallInteger::MAX_VALUE + 1);
-        let divisor: Term = process.integer(SmallInteger::MAX_VALUE + 2);
+        let dividend: Term = process.integer(Integer::MAX_SMALL + 1).unwrap();
+        let divisor: Term = process.integer(Integer::MAX_SMALL + 2).unwrap();
 
         assert_eq!(result(process, dividend, divisor), Ok(dividend));
     })
diff --git a/native_implemented/otp/src/erlang/rem_2/test/with_small_integer_dividend.rs b/native_implemented/otp/src/erlang/rem_2/test/with_small_integer_dividend.rs
index ae1b5aeed..781c4fd7b 100644
--- a/native_implemented/otp/src/erlang/rem_2/test/with_small_integer_dividend.rs
+++ b/native_implemented/otp/src/erlang/rem_2/test/with_small_integer_dividend.rs
@@ -17,10 +17,10 @@ fn with_small_integer_divisor_returns_small_integer() {
             prop_assert_eq!(
                 result(
                     &arc_process,
-                    arc_process.integer(dividend),
-                    arc_process.integer(divisor),
+                    arc_process.integer(dividend).unwrap(),
+                    arc_process.integer(divisor).unwrap(),
                 ),
-                Ok(arc_process.integer(dividend % divisor))
+                Ok(arc_process.integer(dividend % divisor).unwrap())
             );
 
             Ok(())
@@ -48,8 +48,8 @@ fn with_big_integer_divisor_returns_dividend() {
 
 fn divisor() -> BoxedStrategy<isize> {
     prop_oneof![
-        (SmallInteger::MIN_VALUE..=-1),
-        (1..=SmallInteger::MAX_VALUE)
+        (Integer::MIN_SMALL..=-1),
+        (1..=Integer::MAX_SMALL)
     ]
     .boxed()
 }
diff --git a/native_implemented/otp/src/erlang/round_1/test.rs b/native_implemented/otp/src/erlang/round_1/test.rs
index f1eb093c4..8c81391c1 100644
--- a/native_implemented/otp/src/erlang/round_1/test.rs
+++ b/native_implemented/otp/src/erlang/round_1/test.rs
@@ -1,5 +1,3 @@
-use std::convert::TryInto;
-
 use proptest::prop_assert;
 
 use crate::erlang::round_1::result;
diff --git a/native_implemented/otp/src/erlang/self_0.rs b/native_implemented/otp/src/erlang/self_0.rs
index 675af4bb1..af652c261 100644
--- a/native_implemented/otp/src/erlang/self_0.rs
+++ b/native_implemented/otp/src/erlang/self_0.rs
@@ -1,10 +1,10 @@
 #[cfg(test)]
 mod test;
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:self/0)]
 pub fn result(process: &Process) -> Term {
-    process.pid_term()
+    process.pid_term().unwrap()
 }
diff --git a/native_implemented/otp/src/erlang/self_0/test.rs b/native_implemented/otp/src/erlang/self_0/test.rs
index fa2c6a71b..6bbd7745e 100644
--- a/native_implemented/otp/src/erlang/self_0/test.rs
+++ b/native_implemented/otp/src/erlang/self_0/test.rs
@@ -4,6 +4,6 @@ use crate::test::with_process;
 #[test]
 fn returns_process_pid() {
     with_process(|process| {
-        assert_eq!(result(&process), process.pid_term());
+        assert_eq!(result(&process), process.pid_term().unwrap());
     });
 }
diff --git a/native_implemented/otp/src/erlang/send_2.rs b/native_implemented/otp/src/erlang/send_2.rs
index 9e3ed0274..3bbecfb2b 100644
--- a/native_implemented/otp/src/erlang/send_2.rs
+++ b/native_implemented/otp/src/erlang/send_2.rs
@@ -1,14 +1,19 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use std::ptr::NonNull;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::runtime::send::{send, Sent};
 
 #[native_implemented::function(erlang:send/2)]
-pub fn result(process: &Process, destination: Term, message: Term) -> exception::Result<Term> {
+pub fn result(
+    process: &Process,
+    destination: Term,
+    message: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     let sent = send(destination, message, Default::default(), process)?;
 
     match sent {
diff --git a/native_implemented/otp/src/erlang/send_2/test.rs b/native_implemented/otp/src/erlang/send_2/test.rs
index c20cda752..7e984989f 100644
--- a/native_implemented/otp/src/erlang/send_2/test.rs
+++ b/native_implemented/otp/src/erlang/send_2/test.rs
@@ -6,8 +6,8 @@ use proptest::strategy::Just;
 use proptest::test_runner::{Config, TestRunner};
 use proptest::{prop_assert, prop_assert_eq};
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Atom, Term};
 
 use crate::erlang;
 use crate::erlang::send_2::result;
diff --git a/native_implemented/otp/src/erlang/send_2/test/with_atom_destination/registered.rs b/native_implemented/otp/src/erlang/send_2/test/with_atom_destination/registered.rs
index bd6f9ffbf..b107d21d8 100644
--- a/native_implemented/otp/src/erlang/send_2/test/with_atom_destination/registered.rs
+++ b/native_implemented/otp/src/erlang/send_2/test/with_atom_destination/registered.rs
@@ -13,7 +13,7 @@ fn with_same_process_address_process_message_to_mailbox_and_returns_message() {
                 erlang::register_2::result(
                     arc_process.clone(),
                     destination,
-                    arc_process.pid_term()
+                    arc_process.pid_term().unwrap()
                 ),
                 Ok(true.into())
             );
diff --git a/native_implemented/otp/src/erlang/send_2/test/with_atom_destination/registered/with_different_process.rs b/native_implemented/otp/src/erlang/send_2/test/with_atom_destination/registered/with_different_process.rs
index 0c01ddb5f..4611b8cb6 100644
--- a/native_implemented/otp/src/erlang/send_2/test/with_atom_destination/registered/with_different_process.rs
+++ b/native_implemented/otp/src/erlang/send_2/test/with_atom_destination/registered/with_different_process.rs
@@ -12,7 +12,7 @@ fn without_locked_adds_process_message_to_mailbox_and_returns_message() {
                 erlang::register_2::result(
                     arc_process.clone(),
                     destination,
-                    different_arc_process.pid_term(),
+                    different_arc_process.pid_term().unwrap(),
                 ),
                 Ok(true.into())
             );
@@ -38,7 +38,7 @@ fn with_locked_adds_heap_message_to_mailbox_and_returns_message() {
                 erlang::register_2::result(
                     arc_process.clone(),
                     destination,
-                    different_arc_process.pid_term(),
+                    different_arc_process.pid_term().unwrap(),
                 ),
                 Ok(true.into())
             );
diff --git a/native_implemented/otp/src/erlang/send_2/test/with_local_pid_destination.rs b/native_implemented/otp/src/erlang/send_2/test/with_local_pid_destination.rs
index 2bfbb505d..cec9e3d81 100644
--- a/native_implemented/otp/src/erlang/send_2/test/with_local_pid_destination.rs
+++ b/native_implemented/otp/src/erlang/send_2/test/with_local_pid_destination.rs
@@ -30,7 +30,7 @@ fn with_same_process_adds_process_message_to_mailbox_and_returns_message() {
             )
         },
         |(arc_process, message)| {
-            let destination = arc_process.pid_term();
+            let destination = arc_process.pid_term().unwrap();
 
             prop_assert_eq!(result(&arc_process, destination, message), Ok(message));
 
diff --git a/native_implemented/otp/src/erlang/send_2/test/with_local_pid_destination/with_different_process.rs b/native_implemented/otp/src/erlang/send_2/test/with_local_pid_destination/with_different_process.rs
index eba8e0e83..808559c00 100644
--- a/native_implemented/otp/src/erlang/send_2/test/with_local_pid_destination/with_different_process.rs
+++ b/native_implemented/otp/src/erlang/send_2/test/with_local_pid_destination/with_different_process.rs
@@ -5,7 +5,7 @@ fn with_locked_adds_heap_message_to_mailbox_and_returns_message() {
     with_process_arc(|arc_process| {
         TestRunner::new(Config::with_source_file(file!()))
             .run(&strategy::term(arc_process.clone()), |message| {
-                let destination = arc_process.pid_term();
+                let destination = arc_process.pid_term().unwrap();
 
                 prop_assert_eq!(result(&arc_process, destination, message), Ok(message));
 
@@ -23,7 +23,7 @@ fn without_locked_adds_process_message_to_mailbox_and_returns_message() {
         TestRunner::new(Config::with_source_file(file!()))
             .run(&strategy::term(arc_process.clone()), |message| {
                 let different_arc_process = test::process::child(&arc_process);
-                let destination = different_arc_process.pid_term();
+                let destination = different_arc_process.pid_term().unwrap();
 
                 prop_assert_eq!(result(&arc_process, destination, message), Ok(message));
 
diff --git a/native_implemented/otp/src/erlang/send_2/test/with_tuple_destination.rs b/native_implemented/otp/src/erlang/send_2/test/with_tuple_destination.rs
index e11f0fe24..878e74347 100644
--- a/native_implemented/otp/src/erlang/send_2/test/with_tuple_destination.rs
+++ b/native_implemented/otp/src/erlang/send_2/test/with_tuple_destination.rs
@@ -5,7 +5,7 @@ mod with_arity_2;
 #[test]
 fn without_arity_2_errors_badarg() {
     with_process(|process| {
-        let destination = process.tuple_from_slice(&[]);
+        let destination = process.tuple_term_from_term_slice(&[]);
         let message = Atom::str_to_term("message");
 
         assert_badarg!(
diff --git a/native_implemented/otp/src/erlang/send_2/test/with_tuple_destination/with_arity_2.rs b/native_implemented/otp/src/erlang/send_2/test/with_tuple_destination/with_arity_2.rs
index 4b27190e6..2ad1adb70 100644
--- a/native_implemented/otp/src/erlang/send_2/test/with_tuple_destination/with_arity_2.rs
+++ b/native_implemented/otp/src/erlang/send_2/test/with_tuple_destination/with_arity_2.rs
@@ -15,7 +15,7 @@ fn without_atom_name_errors_badarg() {
             )
         },
         |(arc_process, name, message)| {
-            let destination = arc_process.tuple_from_slice(&[name, erlang::node_0::result()]);
+            let destination = arc_process.tuple_term_from_term_slice(&[name, erlang::node_0::result()]);
 
             prop_assert_badarg!(
                         result(&arc_process, destination, message),
@@ -29,32 +29,32 @@ fn without_atom_name_errors_badarg() {
 
 #[test]
 fn with_local_reference_name_errors_badarg() {
-    with_name_errors_badarg(|process| process.next_reference());
+    with_name_errors_badarg(|process| process.next_local_reference_term());
 }
 
 #[test]
 fn with_empty_list_name_errors_badarg() {
-    with_name_errors_badarg(|_| Term::NIL);
+    with_name_errors_badarg(|_| Term::Nil);
 }
 
 #[test]
 fn with_list_name_errors_badarg() {
-    with_name_errors_badarg(|process| process.cons(process.integer(0), process.integer(1)));
+    with_name_errors_badarg(|process| process.cons(process.integer(0).unwrap(), process.integer(1).unwrap()));
 }
 
 #[test]
 fn with_small_integer_name_errors_badarg() {
-    with_name_errors_badarg(|process| process.integer(0));
+    with_name_errors_badarg(|process| process.integer(0).unwrap());
 }
 
 #[test]
 fn with_big_integer_name_errors_badarg() {
-    with_name_errors_badarg(|process| process.integer(SmallInteger::MAX_VALUE + 1));
+    with_name_errors_badarg(|process| process.integer(Integer::MAX_SMALL + 1).unwrap());
 }
 
 #[test]
 fn with_float_name_errors_badarg() {
-    with_name_errors_badarg(|process| process.float(1.0));
+    with_name_errors_badarg(|process| 1.0.into());
 }
 
 #[test]
@@ -69,7 +69,7 @@ fn with_external_pid_name_errors_badarg() {
 
 #[test]
 fn with_tuple_name_errors_badarg() {
-    with_name_errors_badarg(|process| process.tuple_from_slice(&[]));
+    with_name_errors_badarg(|process| process.tuple_term_from_term_slice(&[]));
 }
 
 #[test]
@@ -92,7 +92,7 @@ where
     N: FnOnce(&Process) -> Term,
 {
     with_process(|process| {
-        let destination = process.tuple_from_slice(&[name(process), erlang::node_0::result()]);
+        let destination = process.tuple_term_from_term_slice(&[name(process), erlang::node_0::result()]);
         let message = Atom::str_to_term("message");
 
         assert_badarg!(
diff --git a/native_implemented/otp/src/erlang/send_2/test/with_tuple_destination/with_arity_2/with_atom_name.rs b/native_implemented/otp/src/erlang/send_2/test/with_tuple_destination/with_arity_2/with_atom_name.rs
index 327c3936f..a58558014 100644
--- a/native_implemented/otp/src/erlang/send_2/test/with_tuple_destination/with_arity_2/with_atom_name.rs
+++ b/native_implemented/otp/src/erlang/send_2/test/with_tuple_destination/with_arity_2/with_atom_name.rs
@@ -14,7 +14,7 @@ fn without_atom_node_errors_badarg() {
             )
         },
         |(arc_process, name, node, message)| {
-            let destination = arc_process.tuple_from_slice(&[name, node]);
+            let destination = arc_process.tuple_term_from_term_slice(&[name, node]);
 
             prop_assert_badarg!(
                 result(&arc_process, destination, message),
diff --git a/native_implemented/otp/src/erlang/send_2/test/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node/with_same_node.rs b/native_implemented/otp/src/erlang/send_2/test/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node/with_same_node.rs
index 404dcc06b..ec57d5a1a 100644
--- a/native_implemented/otp/src/erlang/send_2/test/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node/with_same_node.rs
+++ b/native_implemented/otp/src/erlang/send_2/test/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node/with_same_node.rs
@@ -13,7 +13,7 @@ fn unregistered_errors_badarg() {
             )
         },
         |(arc_process, name, message)| {
-            let destination = arc_process.tuple_from_slice(&[name, erlang::node_0::result()]);
+            let destination = arc_process.tuple_term_from_term_slice(&[name, erlang::node_0::result()]);
 
             prop_assert_badarg!(
                 result(&arc_process, destination, message),
diff --git a/native_implemented/otp/src/erlang/send_2/test/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node/with_same_node/registered.rs b/native_implemented/otp/src/erlang/send_2/test/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node/with_same_node/registered.rs
index b32fbfcf7..460160df7 100644
--- a/native_implemented/otp/src/erlang/send_2/test/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node/with_same_node/registered.rs
+++ b/native_implemented/otp/src/erlang/send_2/test/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node/with_same_node/registered.rs
@@ -14,11 +14,11 @@ fn with_same_process_adds_process_message_to_mailbox_and_returns_message() {
                 Ok(true.into()),
                 "Cannot register process ({:?}) pid ({:?}) with name ({:?})",
                 arc_process,
-                arc_process.pid_term(),
+                arc_process.pid_term().unwrap(),
                 name
             );
 
-            let destination = arc_process.tuple_from_slice(&[name, erlang::node_0::result()]);
+            let destination = arc_process.tuple_term_from_term_slice(&[name, erlang::node_0::result()]);
 
             prop_assert_eq!(result(&arc_process, destination, message), Ok(message));
 
diff --git a/native_implemented/otp/src/erlang/send_2/test/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node/with_same_node/registered/with_different_process.rs b/native_implemented/otp/src/erlang/send_2/test/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node/with_same_node/registered/with_different_process.rs
index 4cc2a644e..697167e8c 100644
--- a/native_implemented/otp/src/erlang/send_2/test/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node/with_same_node/registered/with_different_process.rs
+++ b/native_implemented/otp/src/erlang/send_2/test/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node/with_same_node/registered/with_different_process.rs
@@ -12,14 +12,14 @@ fn with_locked_adds_heap_message_to_mailbox_and_returns_message() {
                 erlang::register_2::result(
                     arc_process.clone(),
                     name,
-                    different_arc_process.pid_term()
+                    different_arc_process.pid_term().unwrap()
                 ),
                 Ok(true.into())
             );
 
             let _different_process_heap_lock = different_arc_process.acquire_heap();
 
-            let destination = arc_process.tuple_from_slice(&[name, erlang::node_0::result()]);
+            let destination = arc_process.tuple_term_from_term_slice(&[name, erlang::node_0::result()]);
 
             prop_assert_eq!(result(&arc_process, destination, message), Ok(message));
 
@@ -43,7 +43,7 @@ fn without_locked_adds_process_message_to_mailbox_and_returns_message() {
                 Ok(true.into())
             );
 
-            let destination = arc_process.tuple_from_slice(&[name, erlang::node_0::result()]);
+            let destination = arc_process.tuple_term_from_term_slice(&[name, erlang::node_0::result()]);
 
             prop_assert_eq!(result(&arc_process, destination, message), Ok(message));
 
diff --git a/native_implemented/otp/src/erlang/send_3.rs b/native_implemented/otp/src/erlang/send_3.rs
index ca0199694..b8c8e825d 100644
--- a/native_implemented/otp/src/erlang/send_3.rs
+++ b/native_implemented/otp/src/erlang/send_3.rs
@@ -2,10 +2,11 @@
 mod test;
 
 use std::convert::TryInto;
+use std::ptr::NonNull;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Atom, Term};
 
 use crate::runtime::send::{self, send, Sent};
 
@@ -17,7 +18,7 @@ pub fn result(
     destination: Term,
     message: Term,
     options: Term,
-) -> exception::Result<Term> {
+) -> Result<Term, NonNull<ErlangException>> {
     let send_options: send::Options = options.try_into()?;
 
     send(destination, message, send_options, process)
diff --git a/native_implemented/otp/src/erlang/send_3/test.rs b/native_implemented/otp/src/erlang/send_3/test.rs
index a2d3afe23..3765a9481 100644
--- a/native_implemented/otp/src/erlang/send_3/test.rs
+++ b/native_implemented/otp/src/erlang/send_3/test.rs
@@ -1,13 +1,12 @@
 mod with_proper_list_options;
 
-use std::convert::TryInto;
 use std::sync::Arc;
 
 use proptest::strategy::{BoxedStrategy, Just};
 use proptest::{prop_assert, prop_assert_eq};
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Atom, Term};
 
 use crate::erlang;
 use crate::erlang::send_3::result;
@@ -26,7 +25,7 @@ fn without_list_options_errors_badarg() {
         },
         |(arc_process, message, options)| {
             prop_assert_badarg!(
-                result(&arc_process, arc_process.pid_term(), message, options),
+                result(&arc_process, arc_process.pid_term().unwrap(), message, options),
                 "improper list"
             );
 
diff --git a/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options.rs b/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options.rs
index 6779af685..77ddf1421 100644
--- a/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options.rs
+++ b/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options.rs
@@ -1,7 +1,6 @@
 use super::*;
 
 use proptest::prop_oneof;
-use proptest::strategy::Strategy;
 
 mod non_empty;
 
@@ -36,10 +35,11 @@ fn valid_options(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
     let nosuspend = Atom::str_to_term("nosuspend");
 
     prop_oneof![
-        Just(Term::NIL),
-        Just(arc_process.list_from_slice(&[noconnect])),
-        Just(arc_process.list_from_slice(&[nosuspend])),
-        Just(arc_process.list_from_slice(&[noconnect, nosuspend]))
+        Just(Term::Nil),
+        Just(arc_process.list_from_slice(&[noconnect]).unwrap()),
+        Just(arc_process.list_from_slice(&[nosuspend]).unwrap()),
+        Just(arc_process.list_from_slice(&[nosuspend]).unwrap()),
+        Just(arc_process.list_from_slice(&[noconnect, nosuspend]).unwrap())
     ]
     .boxed()
 }
diff --git a/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/non_empty.rs b/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/non_empty.rs
index 5ab5e1d05..e43ca8c60 100644
--- a/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/non_empty.rs
+++ b/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/non_empty.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 mod with_noconnect;
 mod with_noconnect_and_nosuspend;
 mod with_nosuspend;
@@ -15,8 +13,8 @@ fn with_invalid_option_errors_badarg() {
                 strategy::term(arc_process.clone()),
                 strategy::term(arc_process.clone()).prop_filter(
                     "Option must be invalid",
-                    |option| match option.decode().unwrap() {
-                        TypedTerm::Atom(atom) => match atom.name() {
+                    |option| match option {
+                        Term::Atom(atom) => match atom.as_str() {
                             "noconnect" | "nosuspend" => false,
                             _ => true,
                         },
@@ -26,8 +24,8 @@ fn with_invalid_option_errors_badarg() {
             )
         },
         |(arc_process, message, option)| {
-            let destination = arc_process.pid_term();
-            let options = arc_process.list_from_slice(&[option]);
+            let destination = arc_process.pid_term().unwrap();
+            let options = arc_process.list_from_slice(&[option]).unwrap();
 
             prop_assert_badarg!(
                 result(&arc_process, destination, message, options),
diff --git a/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/non_empty/with_noconnect.rs b/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/non_empty/with_noconnect.rs
index 8dbcd18b8..cccca431b 100644
--- a/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/non_empty/with_noconnect.rs
+++ b/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/non_empty/with_noconnect.rs
@@ -3,5 +3,5 @@ use super::*;
 mod with_tuple_destination;
 
 fn options(process: &Process) -> Term {
-    process.cons(Atom::str_to_term("noconnect"), Term::NIL)
+    process.cons(Atom::str_to_term("noconnect"), Term::Nil)
 }
diff --git a/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/non_empty/with_noconnect/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node.rs b/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/non_empty/with_noconnect/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node.rs
index aaf4eb1bf..4b3f9590b 100644
--- a/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/non_empty/with_noconnect/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node.rs
+++ b/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/non_empty/with_noconnect/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node.rs
@@ -13,7 +13,7 @@ fn with_different_node_returns_noconnect() {
             );
 
             let destination =
-                arc_process.tuple_from_slice(&[name, Atom::str_to_term("node@example.com")]);
+                arc_process.tuple_term_from_term_slice(&[name, Atom::str_to_term("node@example.com")]);
             let options = options(&arc_process);
 
             prop_assert_eq!(
diff --git a/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/non_empty/with_noconnect_and_nosuspend.rs b/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/non_empty/with_noconnect_and_nosuspend.rs
index 4f44a4d4f..a0163cdfa 100644
--- a/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/non_empty/with_noconnect_and_nosuspend.rs
+++ b/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/non_empty/with_noconnect_and_nosuspend.rs
@@ -3,8 +3,8 @@ use super::*;
 mod with_tuple_destination;
 
 fn options(process: &Process) -> Term {
-    let noconnect = Atom::str_to_term("noconnect");
-    let nosuspend = Atom::str_to_term("nosuspend");
+    let noconnect = Atom::str_to_term("noconnect").into();
+    let nosuspend = Atom::str_to_term("nosuspend").into();
 
-    process.list_from_slice(&[noconnect, nosuspend])
+    process.list_from_slice(&[noconnect, nosuspend]).unwrap()
 }
diff --git a/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/non_empty/with_noconnect_and_nosuspend/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node.rs b/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/non_empty/with_noconnect_and_nosuspend/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node.rs
index 6d8003a2b..c86928c64 100644
--- a/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/non_empty/with_noconnect_and_nosuspend/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node.rs
+++ b/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/non_empty/with_noconnect_and_nosuspend/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node.rs
@@ -13,7 +13,7 @@ fn with_different_node_returns_nosuspend() {
             );
 
             let destination =
-                arc_process.tuple_from_slice(&[name, Atom::str_to_term("node@example.com")]);
+                arc_process.tuple_term_from_term_slice(&[name, Atom::str_to_term("node@example.com")]);
             let options = options(&arc_process);
 
             prop_assert_eq!(
diff --git a/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/non_empty/with_nosuspend.rs b/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/non_empty/with_nosuspend.rs
index 67e60515b..a4a85e445 100644
--- a/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/non_empty/with_nosuspend.rs
+++ b/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/non_empty/with_nosuspend.rs
@@ -3,5 +3,5 @@ use super::*;
 mod with_tuple_destination;
 
 fn options(process: &Process) -> Term {
-    process.cons(Atom::str_to_term("nosuspend"), Term::NIL)
+    process.cons(Atom::str_to_term("nosuspend"), Term::Nil)
 }
diff --git a/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/non_empty/with_nosuspend/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node.rs b/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/non_empty/with_nosuspend/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node.rs
index 22a5210cc..fa06da939 100644
--- a/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/non_empty/with_nosuspend/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node.rs
+++ b/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/non_empty/with_nosuspend/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node.rs
@@ -8,12 +8,12 @@ fn with_different_node_returns_nosuspend() {
             let name = registered_name();
 
             prop_assert_eq!(
-                erlang::register_2::result(arc_process.clone(), name, arc_process.pid_term()),
+                erlang::register_2::result(arc_process.clone(), name, arc_process.pid_term().unwrap()),
                 Ok(true.into())
             );
 
             let destination =
-                arc_process.tuple_from_slice(&[name, Atom::str_to_term("node@example.com")]);
+                arc_process.tuple_term_from_term_slice(&[name, Atom::str_to_term("node@example.com")]);
             let options = options(&arc_process);
 
             prop_assert_eq!(
diff --git a/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_atom_destination/registered.rs b/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_atom_destination/registered.rs
index bb03a0456..0becd213e 100644
--- a/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_atom_destination/registered.rs
+++ b/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_atom_destination/registered.rs
@@ -19,7 +19,7 @@ fn with_same_process_adds_process_message_to_mailbox_and_returns_ok() {
                 erlang::register_2::result(
                     arc_process.clone(),
                     destination,
-                    arc_process.pid_term(),
+                    arc_process.pid_term().unwrap(),
                 ),
                 Ok(true.into())
             );
diff --git a/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_atom_destination/registered/with_different_process.rs b/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_atom_destination/registered/with_different_process.rs
index 65518b562..7f833807d 100644
--- a/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_atom_destination/registered/with_different_process.rs
+++ b/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_atom_destination/registered/with_different_process.rs
@@ -18,7 +18,7 @@ fn without_locked_adds_heap_message_to_mailbox_and_returns_ok() {
                 erlang::register_2::result(
                     arc_process.clone(),
                     destination,
-                    different_arc_process.pid_term(),
+                    different_arc_process.pid_term().unwrap(),
                 ),
                 Ok(true.into())
             );
@@ -53,14 +53,14 @@ fn with_locked_adds_heap_message_to_mailbox_and_returns_ok() {
                 erlang::register_2::result(
                     arc_process.clone(),
                     destination,
-                    different_arc_process.pid_term(),
+                    different_arc_process.pid_term().unwrap(),
                 ),
                 Ok(true.into())
             );
 
             let _different_process_heap_lock = different_arc_process.acquire_heap();
 
-            let destination = different_arc_process.pid_term();
+            let destination = different_arc_process.pid_term().unwrap();
 
             assert_eq!(
                 result(&arc_process, destination, message, options),
diff --git a/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_local_pid_destination.rs b/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_local_pid_destination.rs
index bd96b16c5..3cb286605 100644
--- a/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_local_pid_destination.rs
+++ b/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_local_pid_destination.rs
@@ -36,7 +36,7 @@ fn with_same_process_adds_process_message_to_mailbox_and_returns_ok() {
             )
         },
         |(arc_process, message, options)| {
-            let destination = arc_process.pid_term();
+            let destination = arc_process.pid_term().unwrap();
 
             prop_assert_eq!(
                 result(&arc_process, destination, message, options),
diff --git a/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_local_pid_destination/with_different_process.rs b/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_local_pid_destination/with_different_process.rs
index 8749e5860..dd682195d 100644
--- a/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_local_pid_destination/with_different_process.rs
+++ b/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_local_pid_destination/with_different_process.rs
@@ -12,7 +12,7 @@ fn without_locked_adds_process_message_to_mailbox_and_returns_ok() {
         },
         |(arc_process, message, options)| {
             let different_arc_process = test::process::child(&arc_process);
-            let destination = different_arc_process.pid_term();
+            let destination = different_arc_process.pid_term().unwrap();
 
             prop_assert_eq!(
                 result(&arc_process, destination, message, options),
@@ -38,7 +38,7 @@ fn with_locked_adds_process_message_to_mailbox_and_returns_ok() {
         },
         |(arc_process, message, options)| {
             let different_arc_process = test::process::child(&arc_process);
-            let destination = different_arc_process.pid_term();
+            let destination = different_arc_process.pid_term().unwrap();
 
             let _different_process_heap_lock = different_arc_process.acquire_heap();
 
diff --git a/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_tuple_destination.rs b/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_tuple_destination.rs
index ee1018478..5b8860003 100644
--- a/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_tuple_destination.rs
+++ b/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_tuple_destination.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 mod with_arity_2;
 
 #[test]
@@ -13,7 +11,7 @@ fn without_arity_2_errors_badarg() {
                 strategy::term::tuple(arc_process.clone()).prop_filter(
                     "Tuple must not be arity 2",
                     |start_length| {
-                        let start_length_tuple: Boxed<Tuple> = (*start_length).try_into().unwrap();
+                        let start_length_tuple: NonNull<Tuple> = (*start_length).try_into().unwrap();
 
                         start_length_tuple.len() != 2
                     },
diff --git a/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_tuple_destination/with_arity_2.rs b/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_tuple_destination/with_arity_2.rs
index d3df034e7..c950be7c7 100644
--- a/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_tuple_destination/with_arity_2.rs
+++ b/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_tuple_destination/with_arity_2.rs
@@ -14,7 +14,7 @@ fn without_atom_name_errors_badarg() {
             )
         },
         |(arc_process, name, message, options)| {
-            let destination = arc_process.tuple_from_slice(&[name, erlang::node_0::result()]);
+            let destination = arc_process.tuple_term_from_term_slice(&[name, erlang::node_0::result()]);
 
             prop_assert_badarg!(
                         result(&arc_process, destination, message, options),
diff --git a/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node/with_same_node.rs b/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node/with_same_node.rs
index 10eaf1721..0236bd249 100644
--- a/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node/with_same_node.rs
+++ b/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node/with_same_node.rs
@@ -14,7 +14,7 @@ fn unregistered_errors_badarg() {
         },
         |(arc_process, message, options)| {
             let name = registered_name();
-            let destination = arc_process.tuple_from_slice(&[name, erlang::node_0::result()]);
+            let destination = arc_process.tuple_term_from_term_slice(&[name, erlang::node_0::result()]);
 
             prop_assert_badarg!(
                 result(&arc_process, destination, message, options),
diff --git a/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node/with_same_node/registered.rs b/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node/with_same_node/registered.rs
index c48e9e18e..c6e212728 100644
--- a/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node/with_same_node/registered.rs
+++ b/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node/with_same_node/registered.rs
@@ -20,7 +20,7 @@ fn with_same_process_adds_process_message_to_mailbox_and_returns_ok() {
                 Ok(true.into())
             );
 
-            let destination = arc_process.tuple_from_slice(&[name, erlang::node_0::result()]);
+            let destination = arc_process.tuple_term_from_term_slice(&[name, erlang::node_0::result()]);
 
             prop_assert_eq!(
                 result(&arc_process, destination, message, options),
diff --git a/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node/with_same_node/registered/with_different_process.rs b/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node/with_same_node/registered/with_different_process.rs
index 589fb09bc..ccd20987c 100644
--- a/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node/with_same_node/registered/with_different_process.rs
+++ b/native_implemented/otp/src/erlang/send_3/test/with_proper_list_options/with_tuple_destination/with_arity_2/with_atom_name/with_atom_node/with_same_node/registered/with_different_process.rs
@@ -18,12 +18,12 @@ fn without_locked_adds_process_message_to_mailbox_and_returns_ok() {
                 erlang::register_2::result(
                     arc_process.clone(),
                     name,
-                    different_arc_process.pid_term(),
+                    different_arc_process.pid_term().unwrap(),
                 ),
                 Ok(true.into())
             );
 
-            let destination = arc_process.tuple_from_slice(&[name, erlang::node_0::result()]);
+            let destination = arc_process.tuple_term_from_term_slice(&[name, erlang::node_0::result()]);
 
             prop_assert_eq!(
                 result(&arc_process, destination, message, options),
@@ -55,14 +55,14 @@ fn with_locked_adds_heap_message_to_mailbox_and_returns_ok() {
                 erlang::register_2::result(
                     arc_process.clone(),
                     name,
-                    different_arc_process.pid_term(),
+                    different_arc_process.pid_term().unwrap(),
                 ),
                 Ok(true.into())
             );
 
             let _different_process_heap_lock = different_arc_process.acquire_heap();
 
-            let destination = arc_process.tuple_from_slice(&[name, erlang::node_0::result()]);
+            let destination = arc_process.tuple_term_from_term_slice(&[name, erlang::node_0::result()]);
 
             prop_assert_eq!(
                 result(&arc_process, destination, message, options),
diff --git a/native_implemented/otp/src/erlang/send_after_3.rs b/native_implemented/otp/src/erlang/send_after_3.rs
index fefbfa049..cbde33f9c 100644
--- a/native_implemented/otp/src/erlang/send_after_3.rs
+++ b/native_implemented/otp/src/erlang/send_after_3.rs
@@ -3,9 +3,9 @@ mod test;
 
 use std::sync::Arc;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::start_timer;
 use crate::runtime::timer::Format;
@@ -16,7 +16,7 @@ pub fn result(
     time: Term,
     destination: Term,
     message: Term,
-) -> exception::Result<Term> {
+) -> Result<Term, NonNull<ErlangException>> {
     start_timer(
         time,
         destination,
diff --git a/native_implemented/otp/src/erlang/send_after_3/test.rs b/native_implemented/otp/src/erlang/send_after_3/test.rs
index d6226e2e4..c8be02502 100644
--- a/native_implemented/otp/src/erlang/send_after_3/test.rs
+++ b/native_implemented/otp/src/erlang/send_after_3/test.rs
@@ -1,11 +1,10 @@
 mod with_small_integer_time;
 
-use proptest::strategy::{Just, Strategy};
+use proptest::strategy::Just;
 use proptest::test_runner::{Config, TestRunner};
 use proptest::{prop_assert, prop_assert_eq};
 
-use liblumen_alloc::erts::term::prelude::*;
-use liblumen_alloc::erts::time::Milliseconds;
+use firefly_rt::term::Term;
 
 use crate::erlang;
 use crate::erlang::send_after_3::result;
@@ -27,7 +26,7 @@ fn without_non_negative_integer_time_errors_badarg() {
             )
         },
         |(arc_process, time, message)| {
-            let destination = arc_process.pid_term();
+            let destination = arc_process.pid_term().unwrap();
 
             prop_assert_badarg!(
                 result(arc_process.clone(), time, destination, message),
diff --git a/native_implemented/otp/src/erlang/send_after_3/test/with_small_integer_time.rs b/native_implemented/otp/src/erlang/send_after_3/test/with_small_integer_time.rs
index 128f7701e..5373e31aa 100644
--- a/native_implemented/otp/src/erlang/send_after_3/test/with_small_integer_time.rs
+++ b/native_implemented/otp/src/erlang/send_after_3/test/with_small_integer_time.rs
@@ -15,7 +15,7 @@ fn without_atom_or_pid_destination_errors_badarg() {
             )
         },
         |(arc_process, milliseconds, destination, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
 
             prop_assert_badarg!(
                 result(arc_process.clone(), time, destination, message),
diff --git a/native_implemented/otp/src/erlang/send_after_3/test/with_small_integer_time/with_atom_destination.rs b/native_implemented/otp/src/erlang/send_after_3/test/with_small_integer_time/with_atom_destination.rs
index 549b715d5..52a128cff 100644
--- a/native_implemented/otp/src/erlang/send_after_3/test/with_small_integer_time/with_atom_destination.rs
+++ b/native_implemented/otp/src/erlang/send_after_3/test/with_small_integer_time/with_atom_destination.rs
@@ -14,7 +14,7 @@ fn unregistered_sends_nothing_when_timer_expires() {
                 )
             }),
             |(milliseconds, arc_process, message)| {
-                let time = arc_process.integer(milliseconds);
+                let time = arc_process.integer(milliseconds).unwrap();
                 let destination = registered_name();
 
                 let start_monotonic = freeze_timeout();
diff --git a/native_implemented/otp/src/erlang/send_after_3/test/with_small_integer_time/with_atom_destination/registered.rs b/native_implemented/otp/src/erlang/send_after_3/test/with_small_integer_time/with_atom_destination/registered.rs
index 5c574c68b..6ab0ffd18 100644
--- a/native_implemented/otp/src/erlang/send_after_3/test/with_small_integer_time/with_atom_destination/registered.rs
+++ b/native_implemented/otp/src/erlang/send_after_3/test/with_small_integer_time/with_atom_destination/registered.rs
@@ -18,12 +18,12 @@ fn with_different_process_sends_message_when_timer_expires() {
                 erlang::register_2::result(
                     arc_process.clone(),
                     destination,
-                    destination_arc_process.pid_term(),
+                    destination_arc_process.pid_term().unwrap(),
                 ),
                 Ok(true.into())
             );
 
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
 
             let start_monotonic = freeze_timeout();
 
@@ -66,12 +66,12 @@ fn with_same_process_sends_message_when_timer_expires() {
                 erlang::register_2::result(
                     arc_process.clone(),
                     destination,
-                    arc_process.pid_term(),
+                    arc_process.pid_term().unwrap(),
                 ),
                 Ok(true.into())
             );
 
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
 
             let start_monotonic = freeze_timeout();
 
diff --git a/native_implemented/otp/src/erlang/send_after_3/test/with_small_integer_time/with_local_pid_destination.rs b/native_implemented/otp/src/erlang/send_after_3/test/with_small_integer_time/with_local_pid_destination.rs
index 4c9ca32a5..92345785a 100644
--- a/native_implemented/otp/src/erlang/send_after_3/test/with_small_integer_time/with_local_pid_destination.rs
+++ b/native_implemented/otp/src/erlang/send_after_3/test/with_small_integer_time/with_local_pid_destination.rs
@@ -11,10 +11,10 @@ fn with_different_process_sends_message_when_timer_expires() {
             )
         },
         |(arc_process, milliseconds, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
 
             let destination_arc_process = test::process::child(&arc_process);
-            let destination = destination_arc_process.pid_term();
+            let destination = destination_arc_process.pid_term().unwrap();
 
             let start_monotonic = freeze_timeout();
 
@@ -51,8 +51,8 @@ fn with_same_process_sends_message_when_timer_expires() {
             )
         },
         |(arc_process, milliseconds, message)| {
-            let time = arc_process.integer(milliseconds);
-            let destination = arc_process.pid_term();
+            let time = arc_process.integer(milliseconds).unwrap();
+            let destination = arc_process.pid_term().unwrap();
 
             let start_monotonic = freeze_timeout();
 
@@ -89,7 +89,7 @@ fn without_process_sends_nothing_when_timer_expires() {
             )
         },
         |(arc_process, milliseconds, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
             let destination = Pid::next_term();
 
             let start_monotonic = freeze_timeout();
diff --git a/native_implemented/otp/src/erlang/send_after_4.rs b/native_implemented/otp/src/erlang/send_after_4.rs
index 1da8fe268..3c536b7e1 100644
--- a/native_implemented/otp/src/erlang/send_after_4.rs
+++ b/native_implemented/otp/src/erlang/send_after_4.rs
@@ -4,9 +4,9 @@ mod test;
 use std::convert::TryInto;
 use std::sync::Arc;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::start_timer;
 use crate::runtime::timer::Format;
@@ -19,7 +19,7 @@ pub fn result(
     destination: Term,
     message: Term,
     options: Term,
-) -> exception::Result<Term> {
+) -> Result<Term, NonNull<ErlangException>> {
     let timer_start_options: timer::start::Options = options.try_into()?;
 
     start_timer(
diff --git a/native_implemented/otp/src/erlang/send_after_4/test.rs b/native_implemented/otp/src/erlang/send_after_4/test.rs
index 8334498f4..a33ff28d3 100644
--- a/native_implemented/otp/src/erlang/send_after_4/test.rs
+++ b/native_implemented/otp/src/erlang/send_after_4/test.rs
@@ -2,14 +2,12 @@ mod with_proper_list_options;
 
 use std::sync::Arc;
 
-use proptest::strategy::{BoxedStrategy, Just, Strategy};
+use proptest::strategy::{BoxedStrategy, Just};
 use proptest::test_runner::{Config, TestRunner};
 use proptest::{prop_assert, prop_assert_eq};
 
-use liblumen_alloc::atom;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
-use liblumen_alloc::erts::time::Milliseconds;
+use firefly_rt::process::Process;
+use firefly_rt::term::{atoms, Term};
 
 use crate::erlang;
 use crate::erlang::send_after_4::result;
@@ -31,14 +29,14 @@ fn without_proper_list_options_errors_badarg() {
                 )
                     .prop_map(|(arc_process, tail)| {
                         arc_process.cons(
-                            arc_process.tuple_from_slice(&[atom!("abs"), false.into()]),
+                            arc_process.tuple_term_from_term_slice(&[atoms::Abs.into(), false.into()]),
                             tail,
                         )
                     }),
             )
         },
         |(arc_process, time, message, options)| {
-            let destination = arc_process.pid_term();
+            let destination = arc_process.pid_term().unwrap();
 
             prop_assert_badarg!(
                 result(arc_process.clone(), time, destination, message, options,),
diff --git a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_empty_list_options.rs b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_empty_list_options.rs
index 2b8015c77..b9725e1f2 100644
--- a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_empty_list_options.rs
+++ b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_empty_list_options.rs
@@ -3,5 +3,5 @@ use super::*;
 mod with_small_integer_time;
 
 pub fn options(_: &Process) -> Term {
-    Term::NIL
+    Term::Nil
 }
diff --git a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_empty_list_options/with_small_integer_time.rs b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_empty_list_options/with_small_integer_time.rs
index c493b9eaf..9b1bd8f67 100644
--- a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_empty_list_options/with_small_integer_time.rs
+++ b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_empty_list_options/with_small_integer_time.rs
@@ -15,7 +15,7 @@ fn without_atom_pid_or_tuple_destination_errors_badarg() {
             )
         },
         |(arc_process, milliseconds, destination, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
 
             prop_assert_badarg!(
                 result(
diff --git a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_empty_list_options/with_small_integer_time/with_atom_destination.rs b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_empty_list_options/with_small_integer_time/with_atom_destination.rs
index 46a72231b..53aa5726e 100644
--- a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_empty_list_options/with_small_integer_time/with_atom_destination.rs
+++ b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_empty_list_options/with_small_integer_time/with_atom_destination.rs
@@ -14,7 +14,7 @@ fn unregistered_sends_nothing_when_timer_expires() {
                 )
             }),
             |(milliseconds, arc_process, message)| {
-                let time = arc_process.integer(milliseconds);
+                let time = arc_process.integer(milliseconds).unwrap();
                 let destination = registered_name();
 
                 let start_monotonic = freeze_timeout();
diff --git a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_empty_list_options/with_small_integer_time/with_atom_destination/registered.rs b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_empty_list_options/with_small_integer_time/with_atom_destination/registered.rs
index 6fcf29567..d568e296c 100644
--- a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_empty_list_options/with_small_integer_time/with_atom_destination/registered.rs
+++ b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_empty_list_options/with_small_integer_time/with_atom_destination/registered.rs
@@ -18,12 +18,12 @@ fn with_different_process_sends_message_when_timer_expires() {
                 erlang::register_2::result(
                     arc_process.clone(),
                     destination,
-                    destination_arc_process.pid_term(),
+                    destination_arc_process.pid_term().unwrap(),
                 ),
                 Ok(true.into())
             );
 
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
 
             let start_monotonic = freeze_timeout();
 
@@ -72,12 +72,12 @@ fn with_same_process_sends_message_when_timer_expires() {
                 erlang::register_2::result(
                     arc_process.clone(),
                     destination,
-                    arc_process.pid_term(),
+                    arc_process.pid_term().unwrap(),
                 ),
                 Ok(true.into())
             );
 
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
 
             let start_monotonic = freeze_timeout();
 
diff --git a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_empty_list_options/with_small_integer_time/with_local_pid_destination.rs b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_empty_list_options/with_small_integer_time/with_local_pid_destination.rs
index 688514102..c0d16e11b 100644
--- a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_empty_list_options/with_small_integer_time/with_local_pid_destination.rs
+++ b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_empty_list_options/with_small_integer_time/with_local_pid_destination.rs
@@ -11,10 +11,10 @@ fn with_different_process_sends_message_when_timer_expires() {
             )
         },
         |(arc_process, milliseconds, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
 
             let destination_arc_process = test::process::child(&arc_process);
-            let destination = destination_arc_process.pid_term();
+            let destination = destination_arc_process.pid_term().unwrap();
 
             let start_monotonic = freeze_timeout();
 
@@ -57,8 +57,8 @@ fn with_same_process_sends_message_when_timer_expires() {
             )
         },
         |(arc_process, milliseconds, message)| {
-            let time = arc_process.integer(milliseconds);
-            let destination = arc_process.pid_term();
+            let time = arc_process.integer(milliseconds).unwrap();
+            let destination = arc_process.pid_term().unwrap();
 
             let start_monotonic = freeze_timeout();
 
@@ -101,7 +101,7 @@ fn without_process_sends_nothing_when_timer_expires() {
             )
         },
         |(arc_process, milliseconds, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
             let destination = Pid::next_term();
 
             let start_monotonic = freeze_timeout();
diff --git a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs.rs b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs.rs
index d159bb00b..2d5dcbc92 100644
--- a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs.rs
+++ b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs.rs
@@ -15,7 +15,7 @@ fn without_atom_errors_badarg() {
         },
         |(arc_process, time, message, abs_value)| {
             let options = options(abs_value, &arc_process);
-            let destination = arc_process.pid_term();
+            let destination = arc_process.pid_term().unwrap();
 
             prop_assert_is_not_boolean!(
                 result(arc_process.clone(), time, destination, message, options),
@@ -30,7 +30,7 @@ fn without_atom_errors_badarg() {
 
 fn options(abs: Term, process: &Process) -> Term {
     process.cons(
-        process.tuple_from_slice(&[Atom::str_to_term("abs"), abs]),
-        Term::NIL,
+        process.tuple_term_from_term_slice(&[Atom::str_to_term("abs"), abs]),
+        Term::Nil,
     )
 }
diff --git a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false.rs b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false.rs
index 78516c333..7a9b7b07d 100644
--- a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false.rs
+++ b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false.rs
@@ -16,7 +16,7 @@ fn without_non_negative_integer_time_errors_badarg() {
             )
         },
         |(arc_process, time, message)| {
-            let destination = arc_process.pid_term();
+            let destination = arc_process.pid_term().unwrap();
             let options = options(&arc_process);
 
             prop_assert_badarg!(
diff --git a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false/with_small_integer_time.rs b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false/with_small_integer_time.rs
index c5dbb7407..b7b4896ed 100644
--- a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false/with_small_integer_time.rs
+++ b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false/with_small_integer_time.rs
@@ -15,7 +15,7 @@ fn without_atom_or_pid_destination_errors_badarg() {
             )
         },
         |(arc_process, milliseconds, destination, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
             let options = options(&arc_process);
 
             prop_assert_badarg!(
diff --git a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false/with_small_integer_time/with_atom_destination.rs b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false/with_small_integer_time/with_atom_destination.rs
index 30bd9d501..a3e227c8a 100644
--- a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false/with_small_integer_time/with_atom_destination.rs
+++ b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false/with_small_integer_time/with_atom_destination.rs
@@ -13,7 +13,7 @@ fn unregistered_sends_nothing_when_timer_expires() {
             )
         },
         |(arc_process, milliseconds, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
             let destination = registered_name();
             let options = options(&arc_process);
 
diff --git a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false/with_small_integer_time/with_atom_destination/registered.rs b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false/with_small_integer_time/with_atom_destination/registered.rs
index e3778ed87..198669a69 100644
--- a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false/with_small_integer_time/with_atom_destination/registered.rs
+++ b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false/with_small_integer_time/with_atom_destination/registered.rs
@@ -11,7 +11,7 @@ fn with_different_process_with_message_sends_message_when_timer_expires() {
             )
         },
         |(arc_process, milliseconds, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
 
             let destination_arc_process = test::process::child(&arc_process);
             let destination = registered_name();
@@ -20,7 +20,7 @@ fn with_different_process_with_message_sends_message_when_timer_expires() {
                 erlang::register_2::result(
                     arc_process.clone(),
                     destination,
-                    destination_arc_process.pid_term(),
+                    destination_arc_process.pid_term().unwrap(),
                 ),
                 Ok(true.into())
             );
@@ -62,14 +62,14 @@ fn with_same_process_with_message_sends_message_when_timer_expires() {
             )
         },
         |(arc_process, milliseconds, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
             let destination = registered_name();
 
             prop_assert_eq!(
                 erlang::register_2::result(
                     arc_process.clone(),
                     destination,
-                    arc_process.pid_term(),
+                    arc_process.pid_term().unwrap(),
                 ),
                 Ok(true.into())
             );
diff --git a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false/with_small_integer_time/with_local_pid_destination.rs b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false/with_small_integer_time/with_local_pid_destination.rs
index cb4da3237..9fdb5d517 100644
--- a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false/with_small_integer_time/with_local_pid_destination.rs
+++ b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false/with_small_integer_time/with_local_pid_destination.rs
@@ -11,10 +11,10 @@ fn with_different_process_sends_message_when_timer_expires() {
             )
         },
         |(milliseconds, arc_process, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
 
             let destination_arc_process = test::process::child(&arc_process);
-            let destination = destination_arc_process.pid_term();
+            let destination = destination_arc_process.pid_term().unwrap();
 
             let options = options(&arc_process);
 
@@ -54,9 +54,9 @@ fn with_same_process_sends_message_when_timer_expires() {
                 )
             }),
             |(milliseconds, arc_process, message)| {
-                let time = arc_process.integer(milliseconds);
+                let time = arc_process.integer(milliseconds).unwrap();
 
-                let destination = arc_process.pid_term();
+                let destination = arc_process.pid_term().unwrap();
                 let options = options(&arc_process);
 
                 let start_monotonic = freeze_timeout();
@@ -96,7 +96,7 @@ fn without_process_sends_nothing_when_timer_expires() {
                 )
             }),
             |(milliseconds, arc_process, message)| {
-                let time = arc_process.integer(milliseconds);
+                let time = arc_process.integer(milliseconds).unwrap();
                 let destination = Pid::next_term();
                 let options = options(&arc_process);
 
diff --git a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true.rs b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true.rs
index 358af03b8..d1b916d7e 100644
--- a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true.rs
+++ b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true.rs
@@ -16,7 +16,7 @@ fn without_non_negative_integer_time_errors_badarg() {
             )
         },
         |(arc_process, time, message)| {
-            let destination = arc_process.pid_term();
+            let destination = arc_process.pid_term().unwrap();
             let options = options(&arc_process);
 
             prop_assert_badarg!(
diff --git a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true/with_small_integer_time.rs b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true/with_small_integer_time.rs
index c5dbb7407..b7b4896ed 100644
--- a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true/with_small_integer_time.rs
+++ b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true/with_small_integer_time.rs
@@ -15,7 +15,7 @@ fn without_atom_or_pid_destination_errors_badarg() {
             )
         },
         |(arc_process, milliseconds, destination, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
             let options = options(&arc_process);
 
             prop_assert_badarg!(
diff --git a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true/with_small_integer_time/with_atom_destination.rs b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true/with_small_integer_time/with_atom_destination.rs
index b519418d4..2e13aa3c8 100644
--- a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true/with_small_integer_time/with_atom_destination.rs
+++ b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true/with_small_integer_time/with_atom_destination.rs
@@ -13,7 +13,7 @@ fn unregistered_sends_nothing_when_timer_expires() {
             )
         },
         |(arc_process, milliseconds, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
             let destination = registered_name();
             let options = options(&arc_process);
 
@@ -33,7 +33,7 @@ fn unregistered_sends_nothing_when_timer_expires() {
             // No sleeping is necessary because timeout is in the past and so the timer will
             // timeout at once
 
-            crate::runtime::timer::timeout();
+            runtime::timer::timeout();
 
             prop_assert!(!has_message(&arc_process, message));
 
diff --git a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true/with_small_integer_time/with_atom_destination/registered.rs b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true/with_small_integer_time/with_atom_destination/registered.rs
index ed6eb04f5..22a4ca76b 100644
--- a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true/with_small_integer_time/with_atom_destination/registered.rs
+++ b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true/with_small_integer_time/with_atom_destination/registered.rs
@@ -11,7 +11,7 @@ fn with_different_process_with_message_sends_message_when_timer_expires() {
             )
         },
         |(arc_process, milliseconds, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
 
             let destination_arc_process = test::process::child(&arc_process);
             let destination = registered_name();
@@ -20,7 +20,7 @@ fn with_different_process_with_message_sends_message_when_timer_expires() {
                 erlang::register_2::result(
                     arc_process.clone(),
                     destination,
-                    destination_arc_process.pid_term(),
+                    destination_arc_process.pid_term().unwrap(),
                 ),
                 Ok(true.into())
             );
@@ -43,7 +43,7 @@ fn with_different_process_with_message_sends_message_when_timer_expires() {
             // No sleeping is necessary because timeout is in the past and so the timer will
             // timeout at once
 
-            crate::runtime::timer::timeout();
+            runtime::timer::timeout();
 
             prop_assert!(has_message(&destination_arc_process, message));
 
@@ -63,14 +63,14 @@ fn with_same_process_with_message_sends_message_when_timer_expires() {
             )
         },
         |(arc_process, milliseconds, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
             let destination = registered_name();
 
             prop_assert_eq!(
                 erlang::register_2::result(
                     arc_process.clone(),
                     destination,
-                    arc_process.pid_term(),
+                    arc_process.pid_term().unwrap(),
                 ),
                 Ok(true.into())
             );
@@ -93,7 +93,7 @@ fn with_same_process_with_message_sends_message_when_timer_expires() {
             // No sleeping is necessary because timeout is in the past and so the timer will
             // timeout at once
 
-            crate::runtime::timer::timeout();
+            runtime::timer::timeout();
 
             prop_assert!(has_message(&arc_process, message));
 
diff --git a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true/with_small_integer_time/with_local_pid_destination.rs b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true/with_small_integer_time/with_local_pid_destination.rs
index 9ee8420a2..c5f53c637 100644
--- a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true/with_small_integer_time/with_local_pid_destination.rs
+++ b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true/with_small_integer_time/with_local_pid_destination.rs
@@ -12,10 +12,10 @@ fn with_different_process_sends_message_when_timer_expires() {
                 )
             }),
             |(milliseconds, arc_process, message)| {
-                let time = arc_process.integer(milliseconds);
+                let time = arc_process.integer(milliseconds).unwrap();
 
                 let destination_arc_process = test::process::child(&arc_process);
-                let destination = destination_arc_process.pid_term();
+                let destination = destination_arc_process.pid_term().unwrap();
 
                 let options = options(&arc_process);
 
@@ -35,7 +35,7 @@ fn with_different_process_sends_message_when_timer_expires() {
                 // No sleeping is necessary because timeout is in the past and so the timer will
                 // timeout at once
 
-                crate::runtime::timer::timeout();
+                runtime::timer::timeout();
 
                 prop_assert!(has_message(&destination_arc_process, message));
 
@@ -57,8 +57,8 @@ fn with_same_process_sends_message_when_timer_expires() {
                 )
             }),
             |(milliseconds, arc_process, message)| {
-                let time = arc_process.integer(milliseconds);
-                let destination = arc_process.pid_term();
+                let time = arc_process.integer(milliseconds).unwrap();
+                let destination = arc_process.pid_term().unwrap();
                 let options = options(&arc_process);
 
                 let result = result(arc_process.clone(), time, destination, message, options);
@@ -77,7 +77,7 @@ fn with_same_process_sends_message_when_timer_expires() {
                 // No sleeping is necessary because timeout is in the past and so the timer will
                 // timeout at once
 
-                crate::runtime::timer::timeout();
+                runtime::timer::timeout();
 
                 prop_assert!(has_message(&arc_process, message));
 
@@ -99,7 +99,7 @@ fn without_process_sends_nothing_when_timer_expires() {
                 )
             }),
             |(milliseconds, arc_process, message)| {
-                let time = arc_process.integer(milliseconds);
+                let time = arc_process.integer(milliseconds).unwrap();
                 let destination = Pid::next_term();
                 let options = options(&arc_process);
 
@@ -119,7 +119,7 @@ fn without_process_sends_nothing_when_timer_expires() {
                 // No sleeping is necessary because timeout is in the past and so the timer will
                 // timeout at once
 
-                crate::runtime::timer::timeout();
+                runtime::timer::timeout();
 
                 prop_assert!(!has_message(&arc_process, message));
 
diff --git a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean.rs b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean.rs
index 3a48d0436..d99e5a695 100644
--- a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean.rs
+++ b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean.rs
@@ -17,7 +17,7 @@ fn without_non_negative_integer_time_error_badarg() {
             )
         },
         |(arc_process, time, message, abs_value)| {
-            let destination = arc_process.pid_term();
+            let destination = arc_process.pid_term().unwrap();
             let options = options(abs_value, &arc_process);
 
             prop_assert_is_not_boolean!(
diff --git a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean/with_small_integer_time.rs b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean/with_small_integer_time.rs
index 1e5aab355..e06d8892a 100644
--- a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean/with_small_integer_time.rs
+++ b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean/with_small_integer_time.rs
@@ -16,7 +16,7 @@ fn without_atom_pid_or_tuple_destination_errors_badarg() {
             )
         },
         |(arc_process, milliseconds, destination, message, abs_value)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
             let options = options(abs_value, &arc_process);
 
             prop_assert_is_not_boolean!(
diff --git a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean/with_small_integer_time/with_atom_destination.rs b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean/with_small_integer_time/with_atom_destination.rs
index 3fedeb5ec..4e033acc5 100644
--- a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean/with_small_integer_time/with_atom_destination.rs
+++ b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean/with_small_integer_time/with_atom_destination.rs
@@ -16,7 +16,7 @@ fn unregistered_errors_badarg() {
             }),
             |(milliseconds, arc_process, message, abs_value)| {
                 let destination = registered_name();
-                let time = arc_process.integer(milliseconds);
+                let time = arc_process.integer(milliseconds).unwrap();
                 let options = options(abs_value, &arc_process);
 
                 prop_assert_is_not_boolean!(
diff --git a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean/with_small_integer_time/with_atom_destination/registered.rs b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean/with_small_integer_time/with_atom_destination/registered.rs
index 76ff12bab..6ff91667c 100644
--- a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean/with_small_integer_time/with_atom_destination/registered.rs
+++ b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean/with_small_integer_time/with_atom_destination/registered.rs
@@ -12,7 +12,7 @@ fn with_different_process_errors_badarg() {
             )
         },
         |(arc_process, milliseconds, message, abs_value)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
 
             let destination_arc_process = test::process::child(&arc_process);
             let destination = registered_name();
@@ -21,7 +21,7 @@ fn with_different_process_errors_badarg() {
                 erlang::register_2::result(
                     arc_process.clone(),
                     destination,
-                    destination_arc_process.pid_term(),
+                    destination_arc_process.pid_term().unwrap(),
                 ),
                 Ok(true.into())
             );
@@ -57,12 +57,12 @@ fn with_same_process_errors_badarg() {
                 erlang::register_2::result(
                     arc_process.clone(),
                     destination,
-                    arc_process.pid_term(),
+                    arc_process.pid_term().unwrap(),
                 ),
                 Ok(true.into())
             );
 
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
             let options = options(abs_value, &arc_process);
 
             prop_assert_is_not_boolean!(
diff --git a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean/with_small_integer_time/with_local_pid_destination.rs b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean/with_small_integer_time/with_local_pid_destination.rs
index ee754ddde..7e01a65c5 100644
--- a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean/with_small_integer_time/with_local_pid_destination.rs
+++ b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean/with_small_integer_time/with_local_pid_destination.rs
@@ -12,10 +12,10 @@ fn with_different_process_errors_badarg() {
             )
         },
         |(arc_process, milliseconds, message, abs_value)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
 
             let destination_arc_process = test::process::child(&arc_process);
-            let destination = destination_arc_process.pid_term();
+            let destination = destination_arc_process.pid_term().unwrap();
             let options = options(abs_value, &arc_process);
 
             prop_assert_is_not_boolean!(
@@ -41,8 +41,8 @@ fn with_same_process_errors_badarg() {
             )
         },
         |(arc_process, milliseconds, message, abs_value)| {
-            let time = arc_process.integer(milliseconds);
-            let destination = arc_process.pid_term();
+            let time = arc_process.integer(milliseconds).unwrap();
+            let destination = arc_process.pid_term().unwrap();
             let options = options(abs_value, &arc_process);
 
             prop_assert_is_not_boolean!(
@@ -68,7 +68,7 @@ fn without_process_errors_badarg() {
             )
         },
         |(arc_process, milliseconds, message, abs_value)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
             let destination = Pid::next_term();
             let options = options(abs_value, &arc_process);
 
diff --git a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_invalid_option.rs b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_invalid_option.rs
index d505f474c..234b96343 100644
--- a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_invalid_option.rs
+++ b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_invalid_option.rs
@@ -1,3 +1,4 @@
+use firefly_rt::term::{Atom, Cons};
 use super::*;
 
 mod with_small_integer_time;
@@ -16,7 +17,7 @@ fn without_non_negative_integer_time_errors_badarg() {
             )
         },
         |(arc_process, time, message)| {
-            let destination = arc_process.pid_term();
+            let destination = arc_process.pid_term().unwrap();
             let options = options(&arc_process);
 
             prop_assert_badarg!(
@@ -30,5 +31,5 @@ fn without_non_negative_integer_time_errors_badarg() {
 }
 
 fn options(process: &Process) -> Term {
-    process.cons(Atom::str_to_term("invalid"), Term::NIL)
+    Term::list_from_slice_in(&[Atom::str_to_term("invalid")]).unwrap()
 }
diff --git a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time.rs b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time.rs
index d9ca1a54c..0a0182a29 100644
--- a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time.rs
+++ b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time.rs
@@ -15,7 +15,7 @@ fn without_atom_pid_or_tuple_destination_errors_badarg() {
             )
         },
         |(arc_process, milliseconds, destination, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
             let options = options(&arc_process);
 
             prop_assert_badarg!(
diff --git a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_atom_destination/registered/with_different_process.rs b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_atom_destination/registered/with_different_process.rs
index 61f021012..362a0699f 100644
--- a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_atom_destination/registered/with_different_process.rs
+++ b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_atom_destination/registered/with_different_process.rs
@@ -11,7 +11,7 @@ fn errors_badarg() {
             )
         },
         |(arc_process, milliseconds, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
 
             let destination_arc_process = test::process::child(&arc_process);
             let destination = registered_name();
@@ -20,7 +20,7 @@ fn errors_badarg() {
                 erlang::register_2::result(
                     arc_process.clone(),
                     destination,
-                    destination_arc_process.pid_term(),
+                    destination_arc_process.pid_term().unwrap(),
                 ),
                 Ok(true.into())
             );
diff --git a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_atom_destination/registered/with_same_process.rs b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_atom_destination/registered/with_same_process.rs
index 1ca2c805d..cd86c8462 100644
--- a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_atom_destination/registered/with_same_process.rs
+++ b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_atom_destination/registered/with_same_process.rs
@@ -12,14 +12,14 @@ fn errors_badarg() {
                 )
             }),
             |(milliseconds, arc_process, message)| {
-                let time = arc_process.integer(milliseconds);
+                let time = arc_process.integer(milliseconds).unwrap();
                 let destination = registered_name();
 
                 prop_assert_eq!(
                     erlang::register_2::result(
                         arc_process.clone(),
                         destination,
-                        arc_process.pid_term(),
+                        arc_process.pid_term().unwrap(),
                     ),
                     Ok(true.into())
                 );
diff --git a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_atom_destination/unregistered.rs b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_atom_destination/unregistered.rs
index d254d8edd..94731e75b 100644
--- a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_atom_destination/unregistered.rs
+++ b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_atom_destination/unregistered.rs
@@ -12,7 +12,7 @@ fn errors_badarg() {
                 )
             }),
             |(milliseconds, arc_process, message)| {
-                let time = arc_process.integer(milliseconds);
+                let time = arc_process.integer(milliseconds).unwrap();
                 let destination = registered_name();
                 let options = options(&arc_process);
 
diff --git a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_local_pid_destination/with_different_process.rs b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_local_pid_destination/with_different_process.rs
index 0f62fabad..0f3571273 100644
--- a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_local_pid_destination/with_different_process.rs
+++ b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_local_pid_destination/with_different_process.rs
@@ -11,10 +11,10 @@ fn sends_message_when_timer_expires() {
             )
         },
         |(arc_process, milliseconds, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
 
             let destination_arc_process = test::process::child(&arc_process);
-            let destination = destination_arc_process.pid_term();
+            let destination = destination_arc_process.pid_term().unwrap();
 
             let options = options(&arc_process);
 
diff --git a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_local_pid_destination/with_same_process.rs b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_local_pid_destination/with_same_process.rs
index c9f93f1b2..08b792bd8 100644
--- a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_local_pid_destination/with_same_process.rs
+++ b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_local_pid_destination/with_same_process.rs
@@ -12,8 +12,8 @@ fn sends_message_when_timer_expires() {
                 )
             }),
             |(milliseconds, arc_process, message)| {
-                let destination = arc_process.pid_term();
-                let time = arc_process.integer(milliseconds);
+                let destination = arc_process.pid_term().unwrap();
+                let time = arc_process.integer(milliseconds).unwrap();
                 let options = options(&arc_process);
 
                 prop_assert_badarg!(
diff --git a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_local_pid_destination/without_process.rs b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_local_pid_destination/without_process.rs
index fa2a248e5..5ff4231d9 100644
--- a/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_local_pid_destination/without_process.rs
+++ b/native_implemented/otp/src/erlang/send_after_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_local_pid_destination/without_process.rs
@@ -11,7 +11,7 @@ fn errors_badarg() {
             )
         },
         |(arc_process, milliseconds, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
             let destination = Pid::next_term();
             let options = options(&arc_process);
 
diff --git a/native_implemented/otp/src/erlang/seq_trace.rs b/native_implemented/otp/src/erlang/seq_trace.rs
index ede4e92e5..b5f9bf153 100644
--- a/native_implemented/otp/src/erlang/seq_trace.rs
+++ b/native_implemented/otp/src/erlang/seq_trace.rs
@@ -1,8 +1,10 @@
+use std::ptr::NonNull;
+
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::Term;
 
-pub fn flag_is_not_a_supported_atom(flag: Term) -> exception::Result<Term> {
+pub fn flag_is_not_a_supported_atom(flag: Term) -> Result<Term, NonNull<ErlangException>> {
     Err(anyhow!("flag ({}) is not a supported atom (label, monotonic_timestamp, print, receive, send, serial, spawn, strict_monotonic_timestamp, or timestamp)", flag).into())
 }
diff --git a/native_implemented/otp/src/erlang/seq_trace_2.rs b/native_implemented/otp/src/erlang/seq_trace_2.rs
index d64e51ca5..907895640 100644
--- a/native_implemented/otp/src/erlang/seq_trace_2.rs
+++ b/native_implemented/otp/src/erlang/seq_trace_2.rs
@@ -1,23 +1,26 @@
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::term::prelude::*;
+use std::ptr::NonNull;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::Term;
+use firefly_rt::term::atoms;
 
 use super::seq_trace::flag_is_not_a_supported_atom;
 
 // See https://github.com/lumen/otp/blob/30e2bfb9f1fd5c65bd7d9a4159f88cdcf72023fa/erts/emulator/beam/erl_bif_trace.c#L1705-L1828
 #[native_implemented::function(erlang:seq_trace/2)]
-pub fn result(flag: Term, _value: Term) -> exception::Result<Term> {
-    let flag_name = term_try_into_atom!(flag)?.name();
+pub fn result(flag: Term, _value: Term) -> Result<Term, NonNull<ErlangException>> {
+    let flag_name = term_try_into_atom!(flag)?;
 
     match flag_name {
-        "label" => unimplemented!(),
-        "monotonic_timestamp" => unimplemented!(),
-        "print" => unimplemented!(),
-        "receive" => unimplemented!(),
-        "send" => unimplemented!(),
-        "serial" => unimplemented!(),
-        "spawn" => unimplemented!(),
-        "strict_monotonic_timestamp" => unimplemented!(),
-        "timestamp" => unimplemented!(),
+        atoms::Label => unimplemented!(),
+        atoms::MonotonicTimestamp => unimplemented!(),
+        atoms::Print => unimplemented!(),
+        atoms::Receive => unimplemented!(),
+        atoms::Send => unimplemented!(),
+        atoms::Serial => unimplemented!(),
+        atoms::Spawn => unimplemented!(),
+        atoms::StrictMonotonicTimestamp => unimplemented!(),
+        atoms::Timestamp => unimplemented!(),
         _ => flag_is_not_a_supported_atom(flag),
     }
 }
diff --git a/native_implemented/otp/src/erlang/seq_trace_info_1.rs b/native_implemented/otp/src/erlang/seq_trace_info_1.rs
index 623720031..08c5848f0 100644
--- a/native_implemented/otp/src/erlang/seq_trace_info_1.rs
+++ b/native_implemented/otp/src/erlang/seq_trace_info_1.rs
@@ -1,13 +1,15 @@
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use std::ptr::NonNull;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use super::seq_trace::flag_is_not_a_supported_atom;
 
 // See https://github.com/lumen/otp/blob/30e2bfb9f1fd5c65bd7d9a4159f88cdcf72023fa/erts/emulator/beam/erl_bif_trace.c#L1855-L1917
 #[native_implemented::function(erlang:seq_trace_info/1)]
-pub fn result(process: &Process, flag: Term) -> exception::Result<Term> {
-    let flag_name = term_try_into_atom!(flag)?.name();
+pub fn result(process: &Process, flag: Term) -> Result<Term, NonNull<ErlangException>> {
+    let flag_name = term_try_into_atom!(flag)?.as_str();
 
     // Stub as if seq tracing is ALWAYS NOT enabled
     // See https://github.com/lumen/otp/blob/30e2bfb9f1fd5c65bd7d9a4159f88cdcf72023fa/erts/emulator/beam/erl_bif_trace.c#L1865-L1879
@@ -30,13 +32,13 @@ fn boolean_item(process: &Process, item: Term) -> Term {
 }
 
 fn label(process: &Process, item: Term) -> Term {
-    tagged(process, item, Term::NIL)
+    tagged(process, item, Term::Nil)
 }
 
 fn serial(process: &Process, item: Term) -> Term {
-    tagged(process, item, Term::NIL)
+    tagged(process, item, Term::Nil)
 }
 
 fn tagged(process: &Process, tag: Term, value: Term) -> Term {
-    process.tuple_from_slice(&[tag, value])
+    process.tuple_term_from_term_slice(&[tag, value])
 }
diff --git a/native_implemented/otp/src/erlang/seq_trace_print_1.rs b/native_implemented/otp/src/erlang/seq_trace_print_1.rs
index 315336c64..9faf66f98 100644
--- a/native_implemented/otp/src/erlang/seq_trace_print_1.rs
+++ b/native_implemented/otp/src/erlang/seq_trace_print_1.rs
@@ -1,4 +1,4 @@
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 // See https://github.com/lumen/otp/blob/30e2bfb9f1fd5c65bd7d9a4159f88cdcf72023fa/erts/emulator/beam/erl_bif_trace.c#L1919-L1936
 #[native_implemented::function(erlang:seq_trace_print/1)]
diff --git a/native_implemented/otp/src/erlang/seq_trace_print_2.rs b/native_implemented/otp/src/erlang/seq_trace_print_2.rs
index d6695b4a7..0b17330e1 100644
--- a/native_implemented/otp/src/erlang/seq_trace_print_2.rs
+++ b/native_implemented/otp/src/erlang/seq_trace_print_2.rs
@@ -1,4 +1,4 @@
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 // See https://github.com/lumen/otp/blob/30e2bfb9f1fd5c65bd7d9a4159f88cdcf72023fa/erts/emulator/beam/erl_bif_trace.c#L1938-L1957
 #[native_implemented::function(erlang:seq_trace_print/2)]
diff --git a/native_implemented/otp/src/erlang/setelement_3.rs b/native_implemented/otp/src/erlang/setelement_3.rs
index 6ca2768ce..08f341078 100644
--- a/native_implemented/otp/src/erlang/setelement_3.rs
+++ b/native_implemented/otp/src/erlang/setelement_3.rs
@@ -2,18 +2,25 @@
 mod test;
 
 use std::convert::TryInto;
+use std::ptr::NonNull;
 
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::index::OneBasedIndex;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_number::TryIntoIntegerError;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::runtime::context::*;
 
 #[native_implemented::function(erlang:setelement/3)]
-pub fn result(process: &Process, index: Term, tuple: Term, value: Term) -> exception::Result<Term> {
+pub fn result(
+    process: &Process,
+    index: Term,
+    tuple: Term,
+    value: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     let initial_inner_tuple = term_try_into_tuple!(tuple)?;
     let length = initial_inner_tuple.len();
     let index_one_based: OneBasedIndex = index
@@ -24,7 +31,7 @@ pub fn result(process: &Process, index: Term, tuple: Term, value: Term) -> excep
     if index_zero_based < length {
         let mut final_element_vec = initial_inner_tuple[..].to_vec();
         final_element_vec[index_zero_based] = value;
-        let final_tuple = process.tuple_from_slice(&final_element_vec);
+        let final_tuple = process.tuple_term_from_term_slice(&final_element_vec);
 
         Ok(final_tuple)
     } else {
diff --git a/native_implemented/otp/src/erlang/setelement_3/test.rs b/native_implemented/otp/src/erlang/setelement_3/test.rs
index 955271cd7..9e5a3f010 100644
--- a/native_implemented/otp/src/erlang/setelement_3/test.rs
+++ b/native_implemented/otp/src/erlang/setelement_3/test.rs
@@ -1,9 +1,7 @@
-use std::convert::TryInto;
-
 use proptest::prop_assert_eq;
 use proptest::strategy::Just;
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Tuple;
 
 use crate::erlang::setelement_3::result;
 use crate::test::strategy;
@@ -38,14 +36,14 @@ fn with_tuple_without_valid_index_errors_badarg() {
             )
         },
         |(arc_process, (tuple, index), element)| {
-            let boxed_tuple: Boxed<Tuple> = tuple.try_into().unwrap();
+            let non_null_tuple: NonNull<Tuple> = tuple.try_into().unwrap();
 
             prop_assert_badarg!(
                 result(&arc_process, index, tuple, element),
                 format!(
                     "index ({}) is not a 1-based integer between 1-{}",
                     index,
-                    boxed_tuple.len()
+                    non_null_tuple.len()
                 )
             );
 
@@ -66,7 +64,7 @@ fn with_tuple_with_valid_index_returns_tuple_with_index_replaced() {
         },
         |(arc_process, (mut element_vec, element_vec_index, tuple, index), element)| {
             element_vec[element_vec_index] = element;
-            let new_tuple = arc_process.tuple_from_slice(&element_vec);
+            let new_tuple = arc_process.tuple_term_from_term_slice(&element_vec);
 
             prop_assert_eq!(result(&arc_process, index, tuple, element), Ok(new_tuple));
 
diff --git a/native_implemented/otp/src/erlang/size_1.rs b/native_implemented/otp/src/erlang/size_1.rs
index de260f5ec..5b65a1b67 100644
--- a/native_implemented/otp/src/erlang/size_1.rs
+++ b/native_implemented/otp/src/erlang/size_1.rs
@@ -1,24 +1,26 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
+use std::ptr::NonNull;
+
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:size/1)]
-pub fn result(process: &Process, binary_or_tuple: Term) -> exception::Result<Term> {
-    let option_size = match binary_or_tuple.decode().unwrap() {
-        TypedTerm::Tuple(tuple) => Some(tuple.len()),
-        TypedTerm::HeapBinary(heap_binary) => Some(heap_binary.full_byte_len()),
-        TypedTerm::ProcBin(process_binary) => Some(process_binary.full_byte_len()),
-        TypedTerm::SubBinary(subbinary) => Some(subbinary.full_byte_len()),
+pub fn result(process: &Process, binary_or_tuple: Term) -> Result<Term, NonNull<ErlangException>> {
+    let option_size = match binary_or_tuple {
+        Term::Tuple(tuple) => Some(tuple.len()),
+        Term::HeapBinary(heap_binary) => Some(heap_binary.full_byte_len()),
+        Term::RcBinary(process_binary) => Some(process_binary.full_byte_len()),
+        Term::RefBinary(subbinary) => Some(subbinary.full_byte_len()),
         _ => None,
     };
 
     match option_size {
-        Some(size) => Ok(process.integer(size)),
+        Some(size) => Ok(process.integer(size).unwrap()),
         None => Err(TypeError)
             .context(format!(
                 "binary_or_tuple ({}) is neither a binary nor a tuple",
diff --git a/native_implemented/otp/src/erlang/size_1/test.rs b/native_implemented/otp/src/erlang/size_1/test.rs
index bfbaa9298..2716cf4ac 100644
--- a/native_implemented/otp/src/erlang/size_1/test.rs
+++ b/native_implemented/otp/src/erlang/size_1/test.rs
@@ -1,7 +1,7 @@
 use proptest::prop_assert_eq;
-use proptest::strategy::{Just, Strategy};
+use proptest::strategy::Just;
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 use crate::erlang::size_1::result;
 use crate::test::strategy;
@@ -14,7 +14,7 @@ fn without_tuple_or_bitstring_errors_badarg() {
                 Just(arc_process.clone()),
                 strategy::term(arc_process.clone())
                     .prop_filter("Term must not be a tuple or bitstring", |term| {
-                        !(term.is_boxed_tuple() || term.is_bitstring())
+                        !(term.is_tuple() || term.is_bitstring())
                     }),
             )
         },
@@ -49,7 +49,7 @@ fn with_tuple_returns_arity() {
             })
         },
         |(arc_process, size, term)| {
-            prop_assert_eq!(result(&arc_process, term), Ok(arc_process.integer(size)));
+            prop_assert_eq!(result(&arc_process, term), Ok(arc_process.integer(size).unwrap()));
 
             Ok(())
         },
@@ -66,15 +66,15 @@ fn with_bitstring_is_byte_len() {
             )
         },
         |(arc_process, term)| {
-            let full_byte_len = match term.decode().unwrap() {
-                TypedTerm::HeapBinary(heap_binary) => heap_binary.full_byte_len(),
-                TypedTerm::SubBinary(subbinary) => subbinary.full_byte_len(),
+            let full_byte_len = match term {
+                Term::HeapBinary(heap_binary) => heap_binary.full_byte_len(),
+                Term::RefBinary(subbinary) => subbinary.full_byte_len(),
                 _ => unreachable!(),
             };
 
             prop_assert_eq!(
                 result(&arc_process, term),
-                Ok(arc_process.integer(full_byte_len))
+                Ok(arc_process.integer(full_byte_len).unwrap())
             );
 
             Ok(())
diff --git a/native_implemented/otp/src/erlang/spawn_1.rs b/native_implemented/otp/src/erlang/spawn_1.rs
index 7cad036fa..8fad972da 100644
--- a/native_implemented/otp/src/erlang/spawn_1.rs
+++ b/native_implemented/otp/src/erlang/spawn_1.rs
@@ -1,13 +1,15 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use std::ptr::NonNull;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::spawn_apply_1;
 
 #[native_implemented::function(erlang:spawn/1)]
-pub fn result(process: &Process, function: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, function: Term) -> Result<Term, NonNull<ErlangException>> {
     spawn_apply_1::result(process, function, Default::default())
 }
diff --git a/native_implemented/otp/src/erlang/spawn_3.rs b/native_implemented/otp/src/erlang/spawn_3.rs
index f0c1576b1..a7edf4970 100644
--- a/native_implemented/otp/src/erlang/spawn_3.rs
+++ b/native_implemented/otp/src/erlang/spawn_3.rs
@@ -1,9 +1,10 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use std::ptr::NonNull;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::spawn_apply_3;
 
@@ -13,6 +14,6 @@ pub fn result(
     module: Term,
     function: Term,
     arguments: Term,
-) -> exception::Result<Term> {
+) -> Result<Term, NonNull<ErlangException>> {
     spawn_apply_3::result(process, Default::default(), module, function, arguments)
 }
diff --git a/native_implemented/otp/src/erlang/spawn_apply_1.rs b/native_implemented/otp/src/erlang/spawn_apply_1.rs
index d3e52c779..63ec4e59c 100644
--- a/native_implemented/otp/src/erlang/spawn_apply_1.rs
+++ b/native_implemented/otp/src/erlang/spawn_apply_1.rs
@@ -1,10 +1,11 @@
 use std::convert::TryInto;
+use std::ptr::NonNull;
 
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Closure, Term};
 
 use crate::runtime::process::spawn::options::Options;
 use crate::runtime::scheduler::Scheduled;
@@ -13,7 +14,7 @@ pub(in crate::erlang) fn result(
     process: &Process,
     function: Term,
     options: Options,
-) -> exception::Result<Term> {
+) -> Result<Term, NonNull<ErlangException>> {
     let boxed_closure: Boxed<Closure> = function
         .try_into()
         .with_context(|| format!("function ({}) is not a function", function))?;
diff --git a/native_implemented/otp/src/erlang/spawn_apply_3.rs b/native_implemented/otp/src/erlang/spawn_apply_3.rs
index ed047d873..267cf18ce 100644
--- a/native_implemented/otp/src/erlang/spawn_apply_3.rs
+++ b/native_implemented/otp/src/erlang/spawn_apply_3.rs
@@ -1,6 +1,8 @@
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use std::ptr::NonNull;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::apply::arguments_term_to_vec;
 use crate::runtime::process::spawn::options::Options;
@@ -12,7 +14,7 @@ pub(in crate::erlang) fn result(
     module: Term,
     function: Term,
     arguments: Term,
-) -> exception::Result<Term> {
+) -> Result<Term, NonNull<ErlangException>> {
     let module_atom = term_try_into_atom!(module)?;
     let function_atom = term_try_into_atom!(function)?;
     let argument_vec = arguments_term_to_vec(arguments)?;
diff --git a/native_implemented/otp/src/erlang/spawn_link_1.rs b/native_implemented/otp/src/erlang/spawn_link_1.rs
index b039ad062..4c750a175 100644
--- a/native_implemented/otp/src/erlang/spawn_link_1.rs
+++ b/native_implemented/otp/src/erlang/spawn_link_1.rs
@@ -1,15 +1,16 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use std::ptr::NonNull;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::spawn_apply_1;
 use crate::runtime::process::spawn::options::Options;
 
 #[native_implemented::function(erlang:spawn_link/1)]
-pub fn result(process: &Process, function: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, function: Term) -> Result<Term, NonNull<ErlangException>> {
     spawn_apply_1::result(
         process,
         function,
diff --git a/native_implemented/otp/src/erlang/spawn_link_3.rs b/native_implemented/otp/src/erlang/spawn_link_3.rs
index ddc26854a..e9d0feedd 100644
--- a/native_implemented/otp/src/erlang/spawn_link_3.rs
+++ b/native_implemented/otp/src/erlang/spawn_link_3.rs
@@ -1,6 +1,8 @@
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use std::ptr::NonNull;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::spawn_apply_3;
 use crate::runtime::process::spawn::options::Options;
@@ -11,7 +13,7 @@ pub fn result(
     module: Term,
     function: Term,
     arguments: Term,
-) -> exception::Result<Term> {
+) -> Result<Term, NonNull<ErlangException>> {
     let mut options: Options = Default::default();
     options.link = true;
 
diff --git a/native_implemented/otp/src/erlang/spawn_monitor_1.rs b/native_implemented/otp/src/erlang/spawn_monitor_1.rs
index e037e6de9..490316fe7 100644
--- a/native_implemented/otp/src/erlang/spawn_monitor_1.rs
+++ b/native_implemented/otp/src/erlang/spawn_monitor_1.rs
@@ -1,15 +1,16 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use std::ptr::NonNull;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::spawn_apply_1;
 use crate::runtime::process::spawn::options::Options;
 
 #[native_implemented::function(erlang:spawn_monitor/1)]
-pub fn result(process: &Process, function: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, function: Term) -> Result<Term, NonNull<ErlangException>> {
     spawn_apply_1::result(
         process,
         function,
diff --git a/native_implemented/otp/src/erlang/spawn_monitor_3.rs b/native_implemented/otp/src/erlang/spawn_monitor_3.rs
index d32ff4753..9019fc559 100644
--- a/native_implemented/otp/src/erlang/spawn_monitor_3.rs
+++ b/native_implemented/otp/src/erlang/spawn_monitor_3.rs
@@ -1,6 +1,8 @@
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use std::ptr::NonNull;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::spawn_apply_3;
 use crate::runtime::process::spawn::options::Options;
@@ -11,7 +13,7 @@ pub fn result(
     module: Term,
     function: Term,
     arguments: Term,
-) -> exception::Result<Term> {
+) -> Result<Term, NonNull<ErlangException>> {
     let options = Options {
         monitor: true,
         ..Default::default()
diff --git a/native_implemented/otp/src/erlang/spawn_opt_2.rs b/native_implemented/otp/src/erlang/spawn_opt_2.rs
index b2d3713ac..143778311 100644
--- a/native_implemented/otp/src/erlang/spawn_opt_2.rs
+++ b/native_implemented/otp/src/erlang/spawn_opt_2.rs
@@ -2,16 +2,21 @@
 mod test;
 
 use std::convert::TryInto;
+use std::ptr::NonNull;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::spawn_apply_1;
 use crate::runtime::process::spawn::options::Options;
 
 #[native_implemented::function(erlang:spawn_opt/2)]
-pub fn result(process: &Process, function: Term, options: Term) -> exception::Result<Term> {
+pub fn result(
+    process: &Process,
+    function: Term,
+    options: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     let options: Options = options.try_into()?;
 
     spawn_apply_1::result(process, function, options)
diff --git a/native_implemented/otp/src/erlang/spawn_opt_2/test.rs b/native_implemented/otp/src/erlang/spawn_opt_2/test.rs
index 9c56f574f..c414a0cfc 100644
--- a/native_implemented/otp/src/erlang/spawn_opt_2/test.rs
+++ b/native_implemented/otp/src/erlang/spawn_opt_2/test.rs
@@ -2,8 +2,7 @@ mod with_function;
 
 use proptest::strategy::Just;
 
-use liblumen_alloc::atom;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 use crate::erlang::spawn_opt_2::result;
 use crate::test::*;
@@ -14,11 +13,11 @@ fn without_function_errors_badarg() {
         |arc_process| {
             (
                 Just(arc_process.clone()),
-                strategy::term::is_not_function(arc_process.clone()),
+                strategy::term::is_not_closure(arc_process.clone()),
             )
         },
         |(arc_process, function)| {
-            let options = Term::NIL;
+            let options = Term::Nil;
 
             prop_assert_badarg!(
                 result(&arc_process, function, options),
diff --git a/native_implemented/otp/src/erlang/spawn_opt_2/test/with_function.rs b/native_implemented/otp/src/erlang/spawn_opt_2/test/with_function.rs
index dd24ad665..8b376eb8f 100644
--- a/native_implemented/otp/src/erlang/spawn_opt_2/test/with_function.rs
+++ b/native_implemented/otp/src/erlang/spawn_opt_2/test/with_function.rs
@@ -3,6 +3,7 @@
 // `with_link_in_options_list` in integration tests
 // `with_monitor_in_options_list` in integration tests
 
+use firefly_rt::term::Atom;
 use super::*;
 
 #[test]
@@ -16,7 +17,7 @@ fn without_proper_list_options_errors_badarg() {
             )
         },
         |(arc_process, function, tail)| {
-            let options = arc_process.improper_list_from_slice(&[atom!("link")], tail);
+            let options = arc_process.improper_list_from_slice(&[Atom::str_to_term(("link").into())], tail);
 
             prop_assert_badarg!(result(&arc_process, function, options), "improper list");
 
diff --git a/native_implemented/otp/src/erlang/spawn_opt_4.rs b/native_implemented/otp/src/erlang/spawn_opt_4.rs
index d57ea8193..72b55c401 100644
--- a/native_implemented/otp/src/erlang/spawn_opt_4.rs
+++ b/native_implemented/otp/src/erlang/spawn_opt_4.rs
@@ -1,8 +1,9 @@
 use std::convert::TryInto;
+use std::ptr::NonNull;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::spawn_apply_3;
 use crate::runtime::process::spawn::options::Options;
@@ -14,7 +15,7 @@ pub fn result(
     function: Term,
     arguments: Term,
     options: Term,
-) -> exception::Result<Term> {
+) -> Result<Term, NonNull<ErlangException>> {
     let options_options: Options = options.try_into()?;
 
     spawn_apply_3::result(process, options_options, module, function, arguments)
diff --git a/native_implemented/otp/src/erlang/split_binary_2.rs b/native_implemented/otp/src/erlang/split_binary_2.rs
index edb7c3934..b353c3b0d 100644
--- a/native_implemented/otp/src/erlang/split_binary_2.rs
+++ b/native_implemented/otp/src/erlang/split_binary_2.rs
@@ -2,22 +2,26 @@
 mod test;
 
 use std::convert::TryInto;
+use std::ptr::NonNull;
 
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::alloc::TermAlloc;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Term, Tuple};
 
 #[native_implemented::function(erlang:split_binary/2)]
-pub fn result(process: &Process, binary: Term, position: Term) -> exception::Result<Term> {
+pub fn result(
+    process: &Process,
+    binary: Term,
+    position: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     let index: usize = position
         .try_into()
         .with_context(|| format!("position ({}) must be in 0..byte_size(binary)", position))?;
 
-    match binary.decode().unwrap() {
-        binary_box @ TypedTerm::HeapBinary(_) | binary_box @ TypedTerm::ProcBin(_) => {
+    match binary {
+        binary_box @ Term::HeapBinary(_) | binary_box @ Term::RcBinary(_) => {
             if index == 0 {
                 let mut heap = process.acquire_heap();
 
@@ -27,14 +31,14 @@ pub fn result(process: &Process, binary: Term, position: Term) -> exception::Res
 
                 // Don't make a subbinary of the suffix since it is the same as the
                 // `binary`.
-                let boxed_tuple = heap.tuple_from_slice(&[empty_prefix, binary])?;
-                let tuple_term = boxed_tuple.encode()?;
+                let non_null_tuple = Tuple::from_slice(&[empty_prefix.into(), binary.into()], heap)?;
+                let tuple_term = non_null_tuple.into();
 
                 Ok(tuple_term)
             } else {
                 let full_byte_length = match binary_box {
-                    TypedTerm::HeapBinary(heap_binary) => heap_binary.full_byte_len(),
-                    TypedTerm::ProcBin(process_binary) => process_binary.full_byte_len(),
+                    Term::HeapBinary(heap_binary) => heap_binary.full_byte_len(),
+                    Term::RcBinary(process_binary) => process_binary.full_byte_len(),
                     _ => unreachable!(),
                 };
 
@@ -47,7 +51,7 @@ pub fn result(process: &Process, binary: Term, position: Term) -> exception::Res
                         .subbinary_from_original(binary, index, 0, full_byte_length - index, 0)?
                         .encode()?;
 
-                    let boxed_tuple = heap.tuple_from_slice(&[prefix, suffix])?;
+                    let boxed_tuple = heap.tuple_term_from_term_slice(&[prefix, suffix])?;
                     let tuple_term = boxed_tuple.encode()?;
 
                     Ok(tuple_term)
@@ -59,7 +63,7 @@ pub fn result(process: &Process, binary: Term, position: Term) -> exception::Res
 
                     // Don't make a subbinary of the prefix since it is the same as the
                     // `binary`.
-                    let boxed_tuple = heap.tuple_from_slice(&[binary, empty_suffix])?;
+                    let boxed_tuple = heap.tuple_term_from_term_slice(&[binary, empty_suffix])?;
                     let tuple_term = boxed_tuple.encode()?;
 
                     Ok(tuple_term)
@@ -73,7 +77,7 @@ pub fn result(process: &Process, binary: Term, position: Term) -> exception::Res
                 }
             }
         }
-        TypedTerm::SubBinary(subbinary) => {
+        Term::RefBinary(subbinary) => {
             if index == 0 {
                 let mut heap = process.acquire_heap();
                 let empty_prefix = heap
@@ -88,7 +92,7 @@ pub fn result(process: &Process, binary: Term, position: Term) -> exception::Res
 
                 // Don't make a subbinary of the suffix since it is the same as the
                 // `binary`.
-                let boxed_tuple = heap.tuple_from_slice(&[empty_prefix, binary])?;
+                let boxed_tuple = heap.tuple_term_from_term_slice(&[empty_prefix, binary])?;
                 let tuple_term = boxed_tuple.encode()?;
 
                 Ok(tuple_term)
@@ -116,7 +120,7 @@ pub fn result(process: &Process, binary: Term, position: Term) -> exception::Res
                         )?
                         .encode()?;
 
-                    let boxed_tuple = heap.tuple_from_slice(&[prefix, suffix])?;
+                    let boxed_tuple = heap.tuple_term_from_term_slice(&[prefix, suffix])?;
                     let tuple_term = boxed_tuple.encode()?;
 
                     Ok(tuple_term)
@@ -135,7 +139,7 @@ pub fn result(process: &Process, binary: Term, position: Term) -> exception::Res
                             )?
                             .encode()?;
 
-                        let boxed_tuple = heap.tuple_from_slice(&[binary, empty_suffix])?;
+                        let boxed_tuple = heap.tuple_term_from_term_slice(&[binary, empty_suffix])?;
                         let tuple_term = boxed_tuple.encode()?;
 
                         Ok(tuple_term)
diff --git a/native_implemented/otp/src/erlang/split_binary_2/test.rs b/native_implemented/otp/src/erlang/split_binary_2/test.rs
index a7eaac515..954a1d4cb 100644
--- a/native_implemented/otp/src/erlang/split_binary_2/test.rs
+++ b/native_implemented/otp/src/erlang/split_binary_2/test.rs
@@ -4,6 +4,8 @@ use proptest::prop_assert_eq;
 use proptest::strategy::Just;
 use proptest::test_runner::{Config, TestRunner};
 
+use firefly_rt::term::Term;
+
 use crate::erlang::split_binary_2::result;
 use crate::test::strategy;
 use crate::test::{with_process, with_process_arc};
diff --git a/native_implemented/otp/src/erlang/split_binary_2/test/with_bitstring_binary.rs b/native_implemented/otp/src/erlang/split_binary_2/test/with_bitstring_binary.rs
index 968a8e8f2..4edebac07 100644
--- a/native_implemented/otp/src/erlang/split_binary_2/test/with_bitstring_binary.rs
+++ b/native_implemented/otp/src/erlang/split_binary_2/test/with_bitstring_binary.rs
@@ -27,7 +27,7 @@ fn without_non_negative_integer_position_errors_badarg() {
 #[test]
 fn with_zero_position_returns_empty_prefix_and_binary() {
     with_process_arc(|arc_process| {
-        let position = arc_process.integer(0);
+        let position = arc_process.integer(0).unwrap();
 
         TestRunner::new(Config::with_source_file(file!()))
             .run(
@@ -36,7 +36,7 @@ fn with_zero_position_returns_empty_prefix_and_binary() {
                     prop_assert_eq!(
                         result(&arc_process, binary, position),
                         Ok(arc_process
-                            .tuple_from_slice(&[arc_process.binary_from_bytes(&[]), binary],))
+                            .tuple_term_from_term_slice(&[arc_process.binary_from_bytes(&[]), binary],))
                     );
 
                     Ok(())
diff --git a/native_implemented/otp/src/erlang/split_binary_2/test/with_bitstring_binary/with_heap_binary/with_non_negative_integer_position.rs b/native_implemented/otp/src/erlang/split_binary_2/test/with_bitstring_binary/with_heap_binary/with_non_negative_integer_position.rs
index f2d18ff96..85c15b196 100644
--- a/native_implemented/otp/src/erlang/split_binary_2/test/with_bitstring_binary/with_heap_binary/with_non_negative_integer_position.rs
+++ b/native_implemented/otp/src/erlang/split_binary_2/test/with_bitstring_binary/with_heap_binary/with_non_negative_integer_position.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use proptest::strategy::Strategy;
-
 #[test]
 fn with_less_than_byte_len_returns_binary_prefix_and_suffix_binary() {
     run!(
@@ -18,7 +16,7 @@ fn with_less_than_byte_len_returns_binary_prefix_and_suffix_binary() {
         },
         |(arc_process, byte_vec, index)| {
             let binary = arc_process.binary_from_bytes(&byte_vec);
-            let position = arc_process.integer(index);
+            let position = arc_process.integer(index).unwrap();
 
             let prefix_bytes = &byte_vec[0..index];
             let prefix = arc_process.binary_from_bytes(prefix_bytes);
@@ -28,7 +26,7 @@ fn with_less_than_byte_len_returns_binary_prefix_and_suffix_binary() {
 
             prop_assert_eq!(
                 result(&arc_process, binary, position),
-                Ok(arc_process.tuple_from_slice(&[prefix, suffix]))
+                Ok(arc_process.tuple_term_from_term_slice(&[prefix, suffix]))
             );
 
             Ok(())
@@ -42,11 +40,11 @@ fn with_byte_len_returns_subbinary_and_empty_suffix() {
         |arc_process| (Just(arc_process.clone()), strategy::byte_vec()),
         |(arc_process, byte_vec)| {
             let binary = arc_process.binary_from_bytes(&byte_vec);
-            let position = arc_process.integer(byte_vec.len());
+            let position = arc_process.integer(byte_vec.len().unwrap());
 
             prop_assert_eq!(
                 result(&arc_process, binary, position),
-                Ok(arc_process.tuple_from_slice(&[binary, arc_process.binary_from_bytes(&[])],))
+                Ok(arc_process.tuple_term_from_term_slice(&[binary, arc_process.binary_from_bytes(&[])],))
             );
 
             Ok(())
@@ -69,7 +67,7 @@ fn with_greater_than_byte_len_errors_badarg() {
         },
         |(arc_process, byte_vec, index)| {
             let binary = arc_process.binary_from_bytes(&byte_vec);
-            let position = arc_process.integer(index);
+            let position = arc_process.integer(index).unwrap();
 
             prop_assert_badarg!(
                 result(&arc_process, binary, position),
diff --git a/native_implemented/otp/src/erlang/split_binary_2/test/with_bitstring_binary/with_subbinary/with_non_negative_integer_position.rs b/native_implemented/otp/src/erlang/split_binary_2/test/with_bitstring_binary/with_subbinary/with_non_negative_integer_position.rs
index a2e40fda5..f5966307c 100644
--- a/native_implemented/otp/src/erlang/split_binary_2/test/with_bitstring_binary/with_subbinary/with_non_negative_integer_position.rs
+++ b/native_implemented/otp/src/erlang/split_binary_2/test/with_bitstring_binary/with_subbinary/with_non_negative_integer_position.rs
@@ -4,11 +4,11 @@ use super::*;
 fn with_less_than_byte_len_returns_binary_prefix_and_suffix_bitstring() {
     with_process(|process| {
         let binary = bitstring!(1, 2 :: 2, &process);
-        let position = process.integer(1);
+        let position = process.integer(1).unwrap();
 
         assert_eq!(
             result(process, binary, position),
-            Ok(process.tuple_from_slice(&[
+            Ok(process.tuple_term_from_term_slice(&[
                 process.binary_from_bytes(&[1]),
                 bitstring!(2 :: 2, &process)
             ],))
@@ -21,11 +21,11 @@ fn with_byte_len_without_bit_count_returns_subbinary_and_empty_suffix() {
     with_process(|process| {
         let original = process.binary_from_bytes(&[1]);
         let binary = process.subbinary_from_original(original, 0, 0, 1, 0);
-        let position = process.integer(1);
+        let position = process.integer(1).unwrap();
 
         assert_eq!(
             result(process, binary, position),
-            Ok(process.tuple_from_slice(&[binary, process.binary_from_bytes(&[])],))
+            Ok(process.tuple_term_from_term_slice(&[binary, process.binary_from_bytes(&[])],))
         );
     });
 }
@@ -34,7 +34,7 @@ fn with_byte_len_without_bit_count_returns_subbinary_and_empty_suffix() {
 fn with_byte_len_with_bit_count_errors_badarg() {
     with_process(|process| {
         let binary = bitstring!(1, 2 :: 2, &process);
-        let position = process.integer(2);
+        let position = process.integer(2).unwrap();
 
         assert_badarg!(result(process, binary, position), "bitstring (<<1,2:2>>) has 2 bits in its partial bytes, so the index (2) cannot equal the total byte length (2)");
     });
@@ -44,7 +44,7 @@ fn with_byte_len_with_bit_count_errors_badarg() {
 fn with_greater_than_byte_len_errors_badarg() {
     with_process(|process| {
         let binary = bitstring!(1, 2 :: 2, &process);
-        let position = process.integer(3);
+        let position = process.integer(3).unwrap();
 
         assert_badarg!(
             result(process, binary, position),
diff --git a/native_implemented/otp/src/erlang/start_timer_3.rs b/native_implemented/otp/src/erlang/start_timer_3.rs
index ccdc36fee..43b4ca7d1 100644
--- a/native_implemented/otp/src/erlang/start_timer_3.rs
+++ b/native_implemented/otp/src/erlang/start_timer_3.rs
@@ -1,11 +1,12 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
+use std::ptr::NonNull;
 use std::sync::Arc;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::start_timer;
 use crate::runtime::timer::Format;
@@ -16,7 +17,7 @@ pub fn result(
     time: Term,
     destination: Term,
     message: Term,
-) -> exception::Result<Term> {
+) -> Result<Term, NonNull<ErlangException>> {
     start_timer(
         time,
         destination,
diff --git a/native_implemented/otp/src/erlang/start_timer_3/test.rs b/native_implemented/otp/src/erlang/start_timer_3/test.rs
index 223608f19..e38bcdc19 100644
--- a/native_implemented/otp/src/erlang/start_timer_3/test.rs
+++ b/native_implemented/otp/src/erlang/start_timer_3/test.rs
@@ -3,8 +3,7 @@ mod with_small_integer_time;
 use proptest::strategy::Just;
 use proptest::{prop_assert, prop_assert_eq};
 
-use liblumen_alloc::erts::term::prelude::*;
-use liblumen_alloc::erts::time::Milliseconds;
+use firefly_rt::term::Term;
 
 use crate::erlang;
 use crate::erlang::start_timer_3::result;
@@ -28,7 +27,7 @@ fn without_non_negative_integer_time_error_badarg() {
             )
         },
         |(arc_process, time, message)| {
-            let destination = arc_process.pid_term();
+            let destination = arc_process.pid_term().unwrap();
 
             prop_assert_badarg!(
                 result(arc_process.clone(), time, destination, message),
diff --git a/native_implemented/otp/src/erlang/start_timer_3/test/with_small_integer_time.rs b/native_implemented/otp/src/erlang/start_timer_3/test/with_small_integer_time.rs
index 295ea7747..8b4105695 100644
--- a/native_implemented/otp/src/erlang/start_timer_3/test/with_small_integer_time.rs
+++ b/native_implemented/otp/src/erlang/start_timer_3/test/with_small_integer_time.rs
@@ -15,7 +15,7 @@ fn without_atom_or_pid_destination_errors_badarg() {
             )
         },
         |(arc_process, milliseconds, destination, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
 
             prop_assert_badarg!(
                 erlang::start_timer_3::result(arc_process.clone(), time, destination, message),
diff --git a/native_implemented/otp/src/erlang/start_timer_3/test/with_small_integer_time/with_atom_destination.rs b/native_implemented/otp/src/erlang/start_timer_3/test/with_small_integer_time/with_atom_destination.rs
index f8384bf60..4f7638635 100644
--- a/native_implemented/otp/src/erlang/start_timer_3/test/with_small_integer_time/with_atom_destination.rs
+++ b/native_implemented/otp/src/erlang/start_timer_3/test/with_small_integer_time/with_atom_destination.rs
@@ -13,7 +13,7 @@ fn unregistered_sends_nothing_when_timer_expires() {
             )
         },
         |(arc_process, milliseconds, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
             let destination = registered_name();
 
             let start_monotonic = freeze_timeout();
diff --git a/native_implemented/otp/src/erlang/start_timer_3/test/with_small_integer_time/with_atom_destination/registered.rs b/native_implemented/otp/src/erlang/start_timer_3/test/with_small_integer_time/with_atom_destination/registered.rs
index d27f19098..6b747d6bc 100644
--- a/native_implemented/otp/src/erlang/start_timer_3/test/with_small_integer_time/with_atom_destination/registered.rs
+++ b/native_implemented/otp/src/erlang/start_timer_3/test/with_small_integer_time/with_atom_destination/registered.rs
@@ -11,7 +11,7 @@ fn with_different_process_sends_message_when_timer_expires() {
             )
         },
         |(arc_process, milliseconds, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
 
             let destination_arc_process = test::process::child(&arc_process);
             let destination = registered_name();
@@ -20,7 +20,7 @@ fn with_different_process_sends_message_when_timer_expires() {
                 erlang::register_2::result(
                     arc_process.clone(),
                     destination,
-                    destination_arc_process.pid_term(),
+                    destination_arc_process.pid_term().unwrap(),
                 ),
                 Ok(true.into())
             );
@@ -64,14 +64,14 @@ fn with_same_process_sends_message_when_timer_expires() {
             )
         },
         |(arc_process, milliseconds, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
             let destination = registered_name();
 
             prop_assert_eq!(
                 erlang::register_2::result(
                     arc_process.clone(),
                     destination,
-                    arc_process.pid_term(),
+                    arc_process.pid_term().unwrap(),
                 ),
                 Ok(true.into())
             );
diff --git a/native_implemented/otp/src/erlang/start_timer_3/test/with_small_integer_time/with_local_pid_destination.rs b/native_implemented/otp/src/erlang/start_timer_3/test/with_small_integer_time/with_local_pid_destination.rs
index 5656cf6e6..b3d394e09 100644
--- a/native_implemented/otp/src/erlang/start_timer_3/test/with_small_integer_time/with_local_pid_destination.rs
+++ b/native_implemented/otp/src/erlang/start_timer_3/test/with_small_integer_time/with_local_pid_destination.rs
@@ -11,10 +11,10 @@ fn with_different_process_sends_message_when_timer_expires() {
             )
         },
         |(arc_process, milliseconds, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
 
             let destination_arc_process = test::process::child(&arc_process);
-            let destination = destination_arc_process.pid_term();
+            let destination = destination_arc_process.pid_term().unwrap();
 
             let start_monotonic = freeze_timeout();
 
@@ -55,8 +55,8 @@ fn with_same_process_sends_message_when_timer_expires() {
             )
         },
         |(arc_process, milliseconds, message)| {
-            let time = arc_process.integer(milliseconds);
-            let destination = arc_process.pid_term();
+            let time = arc_process.integer(milliseconds).unwrap();
+            let destination = arc_process.pid_term().unwrap();
 
             let start_monotonic = freeze_timeout();
 
@@ -97,7 +97,7 @@ fn without_process_sends_nothing_when_timer_expires() {
             )
         },
         |(arc_process, milliseconds, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
             let destination = Pid::next_term();
 
             let start_monotonic = freeze_timeout();
@@ -115,7 +115,7 @@ fn without_process_sends_nothing_when_timer_expires() {
 
             prop_assert!(timer_reference.is_boxed_local_reference());
 
-            let timeout_message = arc_process.tuple_from_slice(&[
+            let timeout_message = arc_process.tuple_term_from_term_slice(&[
                 Atom::str_to_term("timeout"),
                 timer_reference,
                 message,
diff --git a/native_implemented/otp/src/erlang/start_timer_4.rs b/native_implemented/otp/src/erlang/start_timer_4.rs
index e0514a4a9..e403dd357 100644
--- a/native_implemented/otp/src/erlang/start_timer_4.rs
+++ b/native_implemented/otp/src/erlang/start_timer_4.rs
@@ -2,11 +2,12 @@
 mod test;
 
 use std::convert::TryInto;
+use std::ptr::NonNull;
 use std::sync::Arc;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::start_timer;
 use crate::runtime::timer::Format;
@@ -19,7 +20,7 @@ pub fn result(
     destination: Term,
     message: Term,
     options: Term,
-) -> exception::Result<Term> {
+) -> Result<Term, NonNull<ErlangException>> {
     let timer_start_options: timer::start::Options = options.try_into()?;
 
     start_timer(
diff --git a/native_implemented/otp/src/erlang/start_timer_4/test.rs b/native_implemented/otp/src/erlang/start_timer_4/test.rs
index 614fccf82..616771b9c 100644
--- a/native_implemented/otp/src/erlang/start_timer_4/test.rs
+++ b/native_implemented/otp/src/erlang/start_timer_4/test.rs
@@ -2,14 +2,12 @@ mod with_proper_list_options;
 
 use std::sync::Arc;
 
-use proptest::strategy::{BoxedStrategy, Just, Strategy};
+use proptest::strategy::{BoxedStrategy, Just};
 use proptest::test_runner::{Config, TestRunner};
 use proptest::{prop_assert, prop_assert_eq};
 
-use liblumen_alloc::atom;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
-use liblumen_alloc::erts::time::Milliseconds;
+use firefly_rt::process::Process;
+use firefly_rt::term::{atoms, Term};
 
 use crate::runtime::time::monotonic;
 
@@ -31,8 +29,8 @@ fn without_proper_list_options_errors_badarg() {
             )
         },
         |(arc_process, time, message, tail)| {
-            let destination = arc_process.pid_term();
-            let option = arc_process.tuple_from_slice(&[atom!("abs"), true.into()]);
+            let destination = arc_process.pid_term().unwrap()();
+            let option = arc_process.tuple_term_from_term_slice(&[atoms::Abs.into(), true.into()]);
             let options = arc_process.improper_list_from_slice(&[option], tail);
 
             prop_assert_badarg!(
diff --git a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_empty_list_options.rs b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_empty_list_options.rs
index 2b8015c77..b9725e1f2 100644
--- a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_empty_list_options.rs
+++ b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_empty_list_options.rs
@@ -3,5 +3,5 @@ use super::*;
 mod with_small_integer_time;
 
 pub fn options(_: &Process) -> Term {
-    Term::NIL
+    Term::Nil
 }
diff --git a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_empty_list_options/with_small_integer_time.rs b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_empty_list_options/with_small_integer_time.rs
index c493b9eaf..9b1bd8f67 100644
--- a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_empty_list_options/with_small_integer_time.rs
+++ b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_empty_list_options/with_small_integer_time.rs
@@ -15,7 +15,7 @@ fn without_atom_pid_or_tuple_destination_errors_badarg() {
             )
         },
         |(arc_process, milliseconds, destination, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
 
             prop_assert_badarg!(
                 result(
diff --git a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_empty_list_options/with_small_integer_time/with_atom_destination.rs b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_empty_list_options/with_small_integer_time/with_atom_destination.rs
index e411c2749..09a55e750 100644
--- a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_empty_list_options/with_small_integer_time/with_atom_destination.rs
+++ b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_empty_list_options/with_small_integer_time/with_atom_destination.rs
@@ -14,7 +14,7 @@ fn unregistered_sends_nothing_when_timer_expires() {
         },
         |(arc_process, milliseconds, message)| {
             let destination = registered_name();
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
 
             let start_monotonic = freeze_timeout();
 
@@ -36,7 +36,7 @@ fn unregistered_sends_nothing_when_timer_expires() {
 
             prop_assert!(timer_reference.is_boxed_local_reference());
 
-            let timeout_message = arc_process.tuple_from_slice(&[
+            let timeout_message = arc_process.tuple_term_from_term_slice(&[
                 Atom::str_to_term("timeout"),
                 timer_reference,
                 message,
diff --git a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_empty_list_options/with_small_integer_time/with_atom_destination/registered.rs b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_empty_list_options/with_small_integer_time/with_atom_destination/registered.rs
index 41dfae8d1..bcfad37bd 100644
--- a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_empty_list_options/with_small_integer_time/with_atom_destination/registered.rs
+++ b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_empty_list_options/with_small_integer_time/with_atom_destination/registered.rs
@@ -19,12 +19,12 @@ fn with_different_process_sends_message_when_timer_expires() {
                 erlang::register_2::result(
                     arc_process.clone(),
                     destination,
-                    destination_arc_process.pid_term(),
+                    destination_arc_process.pid_term().unwrap(),
                 ),
                 Ok(true.into())
             );
 
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
 
             let start_monotonic = freeze_timeout();
 
@@ -46,7 +46,7 @@ fn with_different_process_sends_message_when_timer_expires() {
 
             prop_assert!(timer_reference.is_boxed_local_reference());
 
-            let timeout_message = arc_process.tuple_from_slice(&[
+            let timeout_message = arc_process.tuple_term_from_term_slice(&[
                 Atom::str_to_term("timeout"),
                 timer_reference,
                 message,
@@ -81,12 +81,12 @@ fn with_same_process_sends_message_when_timer_expires() {
                     erlang::register_2::result(
                         arc_process.clone(),
                         destination,
-                        arc_process.pid_term(),
+                        arc_process.pid_term().unwrap(),
                     ),
                     Ok(true.into())
                 );
 
-                let time = arc_process.integer(milliseconds);
+                let time = arc_process.integer(milliseconds).unwrap();
 
                 let start_monotonic = freeze_timeout();
 
@@ -108,7 +108,7 @@ fn with_same_process_sends_message_when_timer_expires() {
 
                 prop_assert!(timer_reference.is_boxed_local_reference());
 
-                let timeout_message = arc_process.tuple_from_slice(&[
+                let timeout_message = arc_process.tuple_term_from_term_slice(&[
                     Atom::str_to_term("timeout"),
                     timer_reference,
                     message,
diff --git a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_empty_list_options/with_small_integer_time/with_local_pid_destination.rs b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_empty_list_options/with_small_integer_time/with_local_pid_destination.rs
index 0ccdcf3bd..655d5a3ae 100644
--- a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_empty_list_options/with_small_integer_time/with_local_pid_destination.rs
+++ b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_empty_list_options/with_small_integer_time/with_local_pid_destination.rs
@@ -11,10 +11,10 @@ fn with_different_process_sends_message_when_timer_expires() {
             )
         },
         |(arc_process, milliseconds, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
 
             let destination_arc_process = test::process::child(&arc_process);
-            let destination = destination_arc_process.pid_term();
+            let destination = destination_arc_process.pid_term().unwrap();
 
             let start_monotonic = freeze_timeout();
 
@@ -36,7 +36,7 @@ fn with_different_process_sends_message_when_timer_expires() {
 
             prop_assert!(timer_reference.is_boxed_local_reference());
 
-            let timeout_message = arc_process.tuple_from_slice(&[
+            let timeout_message = arc_process.tuple_term_from_term_slice(&[
                 Atom::str_to_term("timeout"),
                 timer_reference,
                 message,
@@ -64,7 +64,7 @@ fn with_same_process_sends_message_when_timer_expires() {
             )
         },
         |(arc_process, milliseconds, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
             let destination = arc_process.pid_term();
 
             let start_monotonic = freeze_timeout();
@@ -87,7 +87,7 @@ fn with_same_process_sends_message_when_timer_expires() {
 
             prop_assert!(timer_reference.is_boxed_local_reference());
 
-            let timeout_message = arc_process.tuple_from_slice(&[
+            let timeout_message = arc_process.tuple_term_from_term_slice(&[
                 Atom::str_to_term("timeout"),
                 timer_reference,
                 message,
@@ -116,7 +116,7 @@ fn without_process_sends_nothing_when_timer_expires() {
         },
         |(arc_process, milliseconds, message)| {
             let destination = Pid::next_term();
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
 
             let start_monotonic = freeze_timeout();
 
@@ -140,7 +140,7 @@ fn without_process_sends_nothing_when_timer_expires() {
 
             freeze_at_timeout(start_monotonic + milliseconds + Milliseconds(1));
 
-            let timeout_message = arc_process.tuple_from_slice(&[
+            let timeout_message = arc_process.tuple_term_from_term_slice(&[
                 Atom::str_to_term("timeout"),
                 timer_reference,
                 message,
diff --git a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs.rs b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs.rs
index d7dcc3940..8f9b5e4d6 100644
--- a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs.rs
+++ b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs.rs
@@ -15,7 +15,7 @@ fn without_atom_errors_badarg() {
         },
         |(arc_process, time, message, abs_value)| {
             let options = options(abs_value, &arc_process);
-            let destination = arc_process.pid_term();
+            let destination = arc_process.pid_term().unwrap();
 
             prop_assert_is_not_boolean!(
                 result(arc_process.clone(), time, destination, message, options),
@@ -30,7 +30,7 @@ fn without_atom_errors_badarg() {
 
 fn options(abs: Term, process: &Process) -> Term {
     process.cons(
-        process.tuple_from_slice(&[Atom::str_to_term("abs"), abs]),
-        Term::NIL,
+        process.tuple_term_from_term_slice(&[Atom::str_to_term("abs"), abs]),
+        Term::Nil,
     )
 }
diff --git a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false.rs b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false.rs
index 78516c333..7a9b7b07d 100644
--- a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false.rs
+++ b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false.rs
@@ -16,7 +16,7 @@ fn without_non_negative_integer_time_errors_badarg() {
             )
         },
         |(arc_process, time, message)| {
-            let destination = arc_process.pid_term();
+            let destination = arc_process.pid_term().unwrap();
             let options = options(&arc_process);
 
             prop_assert_badarg!(
diff --git a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false/with_small_integer_time.rs b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false/with_small_integer_time.rs
index c5dbb7407..b7b4896ed 100644
--- a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false/with_small_integer_time.rs
+++ b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false/with_small_integer_time.rs
@@ -15,7 +15,7 @@ fn without_atom_or_pid_destination_errors_badarg() {
             )
         },
         |(arc_process, milliseconds, destination, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
             let options = options(&arc_process);
 
             prop_assert_badarg!(
diff --git a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false/with_small_integer_time/with_atom_destination.rs b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false/with_small_integer_time/with_atom_destination.rs
index 37126e5c5..c09d37ddf 100644
--- a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false/with_small_integer_time/with_atom_destination.rs
+++ b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false/with_small_integer_time/with_atom_destination.rs
@@ -13,7 +13,7 @@ fn unregistered_sends_nothing_when_timer_expires() {
             )
         },
         |(arc_process, milliseconds, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
             let destination = registered_name();
             let options = options(&arc_process);
 
@@ -31,7 +31,7 @@ fn unregistered_sends_nothing_when_timer_expires() {
 
             prop_assert!(timer_reference.is_boxed_local_reference());
 
-            let timeout_message = arc_process.tuple_from_slice(&[
+            let timeout_message = arc_process.tuple_term_from_term_slice(&[
                 Atom::str_to_term("timeout"),
                 timer_reference,
                 message,
diff --git a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false/with_small_integer_time/with_atom_destination/registered.rs b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false/with_small_integer_time/with_atom_destination/registered.rs
index c8ab40e59..50aa90da4 100644
--- a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false/with_small_integer_time/with_atom_destination/registered.rs
+++ b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false/with_small_integer_time/with_atom_destination/registered.rs
@@ -11,7 +11,7 @@ fn with_different_process_with_message_sends_message_when_timer_expires() {
             )
         },
         |(arc_process, milliseconds, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
 
             let destination_arc_process = test::process::child(&arc_process);
             let destination = registered_name();
@@ -20,7 +20,7 @@ fn with_different_process_with_message_sends_message_when_timer_expires() {
                 erlang::register_2::result(
                     arc_process.clone(),
                     destination,
-                    destination_arc_process.pid_term(),
+                    destination_arc_process.pid_term().unwrap(),
                 ),
                 Ok(true.into())
             );
@@ -41,7 +41,7 @@ fn with_different_process_with_message_sends_message_when_timer_expires() {
 
             prop_assert!(timer_reference.is_boxed_local_reference());
 
-            let timeout_message = arc_process.tuple_from_slice(&[
+            let timeout_message = arc_process.tuple_term_from_term_slice(&[
                 Atom::str_to_term("timeout"),
                 timer_reference,
                 message,
@@ -69,14 +69,14 @@ fn with_same_process_with_message_sends_message_when_timer_expires() {
             )
         },
         |(arc_process, milliseconds, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
             let destination = registered_name();
 
             prop_assert_eq!(
                 erlang::register_2::result(
                     arc_process.clone(),
                     destination,
-                    arc_process.pid_term(),
+                    arc_process.pid_term().unwrap(),
                 ),
                 Ok(true.into())
             );
@@ -97,7 +97,7 @@ fn with_same_process_with_message_sends_message_when_timer_expires() {
 
             prop_assert!(timer_reference.is_boxed_local_reference());
 
-            let timeout_message = arc_process.tuple_from_slice(&[
+            let timeout_message = arc_process.tuple_term_from_term_slice(&[
                 Atom::str_to_term("timeout"),
                 timer_reference,
                 message,
diff --git a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false/with_small_integer_time/with_local_pid_destination.rs b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false/with_small_integer_time/with_local_pid_destination.rs
index 4afefcc71..831760d72 100644
--- a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false/with_small_integer_time/with_local_pid_destination.rs
+++ b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_false/with_small_integer_time/with_local_pid_destination.rs
@@ -13,10 +13,10 @@ fn with_different_process_sends_message_when_timer_expires() {
                 )
             }),
             |(milliseconds, arc_process, message)| {
-                let time = arc_process.integer(milliseconds);
+                let time = arc_process.integer(milliseconds).unwrap();
 
                 let destination_arc_process = test::process::child(&arc_process);
-                let destination = destination_arc_process.pid_term();
+                let destination = destination_arc_process.pid_term().unwrap();
 
                 let options = options(&arc_process);
 
@@ -34,7 +34,7 @@ fn with_different_process_sends_message_when_timer_expires() {
 
                 prop_assert!(timer_reference.is_boxed_local_reference());
 
-                let timeout_message = arc_process.tuple_from_slice(&[
+                let timeout_message = arc_process.tuple_term_from_term_slice(&[
                     Atom::str_to_term("timeout"),
                     timer_reference,
                     message,
@@ -64,9 +64,9 @@ fn with_same_process_sends_message_when_timer_expires() {
                 )
             }),
             |(milliseconds, arc_process, message)| {
-                let time = arc_process.integer(milliseconds);
+                let time = arc_process.integer(milliseconds).unwrap();
 
-                let destination = arc_process.pid_term();
+                let destination = arc_process.pid_term().unwrap();
                 let options = options(&arc_process);
 
                 let start_monotonic = freeze_timeout();
@@ -83,7 +83,7 @@ fn with_same_process_sends_message_when_timer_expires() {
 
                 prop_assert!(timer_reference.is_boxed_local_reference());
 
-                let timeout_message = arc_process.tuple_from_slice(&[
+                let timeout_message = arc_process.tuple_term_from_term_slice(&[
                     Atom::str_to_term("timeout"),
                     timer_reference,
                     message,
@@ -113,7 +113,7 @@ fn without_process_sends_nothing_when_timer_expires() {
                 )
             }),
             |(milliseconds, arc_process, message)| {
-                let time = arc_process.integer(milliseconds);
+                let time = arc_process.integer(milliseconds).unwrap();
                 let destination = Pid::next_term();
                 let options = options(&arc_process);
 
@@ -131,7 +131,7 @@ fn without_process_sends_nothing_when_timer_expires() {
 
                 prop_assert!(timer_reference.is_boxed_local_reference());
 
-                let timeout_message = arc_process.tuple_from_slice(&[
+                let timeout_message = arc_process.tuple_term_from_term_slice(&[
                     Atom::str_to_term("timeout"),
                     timer_reference,
                     message,
diff --git a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true.rs b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true.rs
index 358af03b8..d1b916d7e 100644
--- a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true.rs
+++ b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true.rs
@@ -16,7 +16,7 @@ fn without_non_negative_integer_time_errors_badarg() {
             )
         },
         |(arc_process, time, message)| {
-            let destination = arc_process.pid_term();
+            let destination = arc_process.pid_term().unwrap();
             let options = options(&arc_process);
 
             prop_assert_badarg!(
diff --git a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true/with_small_integer_time.rs b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true/with_small_integer_time.rs
index c5dbb7407..b7b4896ed 100644
--- a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true/with_small_integer_time.rs
+++ b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true/with_small_integer_time.rs
@@ -15,7 +15,7 @@ fn without_atom_or_pid_destination_errors_badarg() {
             )
         },
         |(arc_process, milliseconds, destination, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
             let options = options(&arc_process);
 
             prop_assert_badarg!(
diff --git a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true/with_small_integer_time/with_atom_destination.rs b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true/with_small_integer_time/with_atom_destination.rs
index 4a1bd6b78..da7357269 100644
--- a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true/with_small_integer_time/with_atom_destination.rs
+++ b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true/with_small_integer_time/with_atom_destination.rs
@@ -13,7 +13,7 @@ fn unregistered_sends_nothing_when_timer_expires() {
             )
         },
         |(arc_process, milliseconds, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
             let destination = registered_name();
             let options = options(&arc_process);
 
@@ -29,7 +29,7 @@ fn unregistered_sends_nothing_when_timer_expires() {
 
             prop_assert!(timer_reference.is_boxed_local_reference());
 
-            let timeout_message = arc_process.tuple_from_slice(&[
+            let timeout_message = arc_process.tuple_term_from_term_slice(&[
                 Atom::str_to_term("timeout"),
                 timer_reference,
                 message,
@@ -40,7 +40,7 @@ fn unregistered_sends_nothing_when_timer_expires() {
             // No sleeping is necessary because timeout is in the past and so the timer will
             // timeout at once
 
-            crate::runtime::timer::timeout();
+            runtime::timer::timeout();
 
             prop_assert!(!has_message(&arc_process, timeout_message));
 
diff --git a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true/with_small_integer_time/with_atom_destination/registered.rs b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true/with_small_integer_time/with_atom_destination/registered.rs
index 0a6b2e333..f9a16a17e 100644
--- a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true/with_small_integer_time/with_atom_destination/registered.rs
+++ b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true/with_small_integer_time/with_atom_destination/registered.rs
@@ -11,7 +11,7 @@ fn with_different_process_with_message_sends_message_when_timer_expires() {
             )
         },
         |(arc_process, milliseconds, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
 
             let destination_arc_process = test::process::child(&arc_process);
             let destination = registered_name();
@@ -20,7 +20,7 @@ fn with_different_process_with_message_sends_message_when_timer_expires() {
                 erlang::register_2::result(
                     arc_process.clone(),
                     destination,
-                    destination_arc_process.pid_term(),
+                    destination_arc_process.pid_term().unwrap(),
                 ),
                 Ok(true.into())
             );
@@ -39,7 +39,7 @@ fn with_different_process_with_message_sends_message_when_timer_expires() {
 
             prop_assert!(timer_reference.is_boxed_local_reference());
 
-            let timeout_message = arc_process.tuple_from_slice(&[
+            let timeout_message = arc_process.tuple_term_from_term_slice(&[
                 Atom::str_to_term("timeout"),
                 timer_reference,
                 message,
@@ -50,7 +50,7 @@ fn with_different_process_with_message_sends_message_when_timer_expires() {
             // No sleeping is necessary because timeout is in the past and so the timer will
             // timeout at once
 
-            crate::runtime::timer::timeout();
+            runtime::timer::timeout();
 
             prop_assert!(has_message(&destination_arc_process, timeout_message));
 
@@ -71,14 +71,14 @@ fn with_same_process_with_message_sends_message_when_timer_expires() {
                 )
             }),
             |(milliseconds, arc_process, message)| {
-                let time = arc_process.integer(milliseconds);
+                let time = arc_process.integer(milliseconds).unwrap();
                 let destination = registered_name();
 
                 prop_assert_eq!(
                     erlang::register_2::result(
                         arc_process.clone(),
                         destination,
-                        arc_process.pid_term(),
+                        arc_process.pid_term().unwrap(),
                     ),
                     Ok(true.into())
                 );
@@ -97,7 +97,7 @@ fn with_same_process_with_message_sends_message_when_timer_expires() {
 
                 prop_assert!(timer_reference.is_boxed_local_reference());
 
-                let timeout_message = arc_process.tuple_from_slice(&[
+                let timeout_message = arc_process.tuple_term_from_term_slice(&[
                     Atom::str_to_term("timeout"),
                     timer_reference,
                     message,
@@ -108,7 +108,7 @@ fn with_same_process_with_message_sends_message_when_timer_expires() {
                 // No sleeping is necessary because timeout is in the past and so the timer will
                 // timeout at once
 
-                crate::runtime::timer::timeout();
+                runtime::timer::timeout();
 
                 prop_assert!(has_message(&arc_process, timeout_message));
 
diff --git a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true/with_small_integer_time/with_local_pid_destination.rs b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true/with_small_integer_time/with_local_pid_destination.rs
index 2bbfb7ba4..cf85240f0 100644
--- a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true/with_small_integer_time/with_local_pid_destination.rs
+++ b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/with_true/with_small_integer_time/with_local_pid_destination.rs
@@ -12,10 +12,10 @@ fn with_different_process_sends_message_when_timer_expires() {
                 )
             }),
             |(milliseconds, arc_process, message)| {
-                let time = arc_process.integer(milliseconds);
+                let time = arc_process.integer(milliseconds).unwrap();
 
                 let destination_arc_process = test::process::child(&arc_process);
-                let destination = destination_arc_process.pid_term();
+                let destination = destination_arc_process.pid_term().unwrap();
 
                 let options = options(&arc_process);
 
@@ -31,7 +31,7 @@ fn with_different_process_sends_message_when_timer_expires() {
 
                 prop_assert!(timer_reference.is_boxed_local_reference());
 
-                let timeout_message = arc_process.tuple_from_slice(&[
+                let timeout_message = arc_process.tuple_term_from_term_slice(&[
                     Atom::str_to_term("timeout"),
                     timer_reference,
                     message,
@@ -42,7 +42,7 @@ fn with_different_process_sends_message_when_timer_expires() {
                 // No sleeping is necessary because timeout is in the past and so the timer will
                 // timeout at once
 
-                crate::runtime::timer::timeout();
+                runtime::timer::timeout();
 
                 prop_assert!(has_message(&destination_arc_process, timeout_message));
 
@@ -64,8 +64,8 @@ fn with_same_process_sends_message_when_timer_expires() {
                 )
             }),
             |(milliseconds, arc_process, message)| {
-                let time = arc_process.integer(milliseconds);
-                let destination = arc_process.pid_term();
+                let time = arc_process.integer(milliseconds).unwrap();
+                let destination = arc_process.pid_term().unwrap();
                 let options = options(&arc_process);
 
                 let result = result(arc_process.clone(), time, destination, message, options);
@@ -80,7 +80,7 @@ fn with_same_process_sends_message_when_timer_expires() {
 
                 prop_assert!(timer_reference.is_boxed_local_reference());
 
-                let timeout_message = arc_process.tuple_from_slice(&[
+                let timeout_message = arc_process.tuple_term_from_term_slice(&[
                     Atom::str_to_term("timeout"),
                     timer_reference,
                     message,
@@ -91,7 +91,7 @@ fn with_same_process_sends_message_when_timer_expires() {
                 // No sleeping is necessary because timeout is in the past and so the timer will
                 // timeout at once
 
-                crate::runtime::timer::timeout();
+                runtime::timer::timeout();
 
                 prop_assert!(has_message(&arc_process, timeout_message));
 
@@ -113,7 +113,7 @@ fn without_process_sends_nothing_when_timer_expires() {
                 )
             }),
             |(milliseconds, arc_process, message)| {
-                let time = arc_process.integer(milliseconds);
+                let time = arc_process.integer(milliseconds).unwrap();
                 let destination = Pid::next_term();
                 let options = options(&arc_process);
 
@@ -129,7 +129,7 @@ fn without_process_sends_nothing_when_timer_expires() {
 
                 prop_assert!(timer_reference.is_boxed_local_reference());
 
-                let timeout_message = arc_process.tuple_from_slice(&[
+                let timeout_message = arc_process.tuple_term_from_term_slice(&[
                     Atom::str_to_term("timeout"),
                     timer_reference,
                     message,
@@ -140,7 +140,7 @@ fn without_process_sends_nothing_when_timer_expires() {
                 // No sleeping is necessary because timeout is in the past and so the timer will
                 // timeout at once
 
-                crate::runtime::timer::timeout();
+                runtime::timer::timeout();
 
                 prop_assert!(!has_message(&arc_process, timeout_message));
 
diff --git a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean.rs b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean.rs
index 8cb4657d4..080bc8e4f 100644
--- a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean.rs
+++ b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean.rs
@@ -17,7 +17,7 @@ fn without_non_negative_integer_time_error_badarg() {
             )
         },
         |(arc_process, time, message, abs_value)| {
-            let destination = arc_process.pid_term();
+            let destination = arc_process.pid_term().unwrap();
             let options = options(abs_value, &arc_process);
 
             prop_assert_is_not_boolean!(
diff --git a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean/with_small_integer_time.rs b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean/with_small_integer_time.rs
index 1e5aab355..e06d8892a 100644
--- a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean/with_small_integer_time.rs
+++ b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean/with_small_integer_time.rs
@@ -16,7 +16,7 @@ fn without_atom_pid_or_tuple_destination_errors_badarg() {
             )
         },
         |(arc_process, milliseconds, destination, message, abs_value)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
             let options = options(abs_value, &arc_process);
 
             prop_assert_is_not_boolean!(
diff --git a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean/with_small_integer_time/with_atom_destination.rs b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean/with_small_integer_time/with_atom_destination.rs
index 3fa7314e1..6bfa43667 100644
--- a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean/with_small_integer_time/with_atom_destination.rs
+++ b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean/with_small_integer_time/with_atom_destination.rs
@@ -16,7 +16,7 @@ fn unregistered_sends_nothing_when_timer_expires() {
             }),
             |(milliseconds, arc_process, message, abs_value)| {
                 let destination = registered_name();
-                let time = arc_process.integer(milliseconds);
+                let time = arc_process.integer(milliseconds).unwrap();
                 let options = options(abs_value, &arc_process);
 
                 prop_assert_is_not_boolean!(
diff --git a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean/with_small_integer_time/with_atom_destination/registered.rs b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean/with_small_integer_time/with_atom_destination/registered.rs
index e3a8a3875..bef4ff7b5 100644
--- a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean/with_small_integer_time/with_atom_destination/registered.rs
+++ b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean/with_small_integer_time/with_atom_destination/registered.rs
@@ -12,7 +12,7 @@ fn with_different_process_errors_badarg() {
             )
         },
         |(arc_process, milliseconds, message, abs_value)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
 
             let destination_arc_process = test::process::child(&arc_process);
             let destination = registered_name();
@@ -21,7 +21,7 @@ fn with_different_process_errors_badarg() {
                 erlang::register_2::result(
                     arc_process.clone(),
                     destination,
-                    destination_arc_process.pid_term(),
+                    destination_arc_process.pid_term().unwrap(),
                 ),
                 Ok(true.into())
             );
@@ -58,12 +58,12 @@ fn with_same_process_errors_badarg() {
                     erlang::register_2::result(
                         arc_process.clone(),
                         destination,
-                        arc_process.pid_term()
+                        arc_process.pid_term().unwrap()
                     ),
                     Ok(true.into())
                 );
 
-                let time = arc_process.integer(milliseconds);
+                let time = arc_process.integer(milliseconds).unwrap();
                 let options = options(abs_value, &arc_process);
 
                 prop_assert_is_not_boolean!(
diff --git a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean/with_small_integer_time/with_local_pid_destination.rs b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean/with_small_integer_time/with_local_pid_destination.rs
index c41a74964..7a9ae52a7 100644
--- a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean/with_small_integer_time/with_local_pid_destination.rs
+++ b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_abs/with_atom/without_boolean/with_small_integer_time/with_local_pid_destination.rs
@@ -12,10 +12,10 @@ fn with_different_process_errors_badarg() {
             )
         },
         |(arc_process, milliseconds, message, abs_value)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
 
             let destination_arc_process = test::process::child(&arc_process);
-            let destination = destination_arc_process.pid_term();
+            let destination = destination_arc_process.pid_term().unwrap();
 
             let options = options(abs_value, &arc_process);
 
@@ -42,7 +42,7 @@ fn with_same_process_errors_badarg() {
             )
         },
         |(arc_process, milliseconds, message, abs_value)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
             let destination = arc_process.pid_term();
             let options = options(abs_value, &arc_process);
 
@@ -69,7 +69,7 @@ fn without_process_errors_badarg() {
             )
         },
         |(arc_process, milliseconds, message, abs_value)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
             let destination = Pid::next_term();
             let options = options(abs_value, &arc_process);
 
diff --git a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_invalid_option.rs b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_invalid_option.rs
index d505f474c..46fb147f0 100644
--- a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_invalid_option.rs
+++ b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_invalid_option.rs
@@ -16,7 +16,7 @@ fn without_non_negative_integer_time_errors_badarg() {
             )
         },
         |(arc_process, time, message)| {
-            let destination = arc_process.pid_term();
+            let destination = arc_process.pid_term().unwrap();
             let options = options(&arc_process);
 
             prop_assert_badarg!(
@@ -30,5 +30,5 @@ fn without_non_negative_integer_time_errors_badarg() {
 }
 
 fn options(process: &Process) -> Term {
-    process.cons(Atom::str_to_term("invalid"), Term::NIL)
+    process.cons(Atom::str_to_term("invalid"), Term::Nil)
 }
diff --git a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time.rs b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time.rs
index d9ca1a54c..0a0182a29 100644
--- a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time.rs
+++ b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time.rs
@@ -15,7 +15,7 @@ fn without_atom_pid_or_tuple_destination_errors_badarg() {
             )
         },
         |(arc_process, milliseconds, destination, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
             let options = options(&arc_process);
 
             prop_assert_badarg!(
diff --git a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_atom_destination/registered/w_d_p.rs b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_atom_destination/registered/w_d_p.rs
index 61f021012..362a0699f 100644
--- a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_atom_destination/registered/w_d_p.rs
+++ b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_atom_destination/registered/w_d_p.rs
@@ -11,7 +11,7 @@ fn errors_badarg() {
             )
         },
         |(arc_process, milliseconds, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
 
             let destination_arc_process = test::process::child(&arc_process);
             let destination = registered_name();
@@ -20,7 +20,7 @@ fn errors_badarg() {
                 erlang::register_2::result(
                     arc_process.clone(),
                     destination,
-                    destination_arc_process.pid_term(),
+                    destination_arc_process.pid_term().unwrap(),
                 ),
                 Ok(true.into())
             );
diff --git a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_atom_destination/registered/w_s_p.rs b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_atom_destination/registered/w_s_p.rs
index 81cf27ed3..85eeb7af7 100644
--- a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_atom_destination/registered/w_s_p.rs
+++ b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_atom_destination/registered/w_s_p.rs
@@ -12,14 +12,14 @@ fn errors_badarg() {
                 )
             }),
             |(milliseconds, arc_process, message)| {
-                let time = arc_process.integer(milliseconds);
+                let time = arc_process.integer(milliseconds).unwrap();
                 let destination = registered_name();
 
                 prop_assert_eq!(
                     erlang::register_2::result(
                         arc_process.clone(),
                         destination,
-                        arc_process.pid_term()
+                        arc_process.pid_term().unwrap()
                     ),
                     Ok(true.into())
                 );
diff --git a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_atom_destination/unregistered.rs b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_atom_destination/unregistered.rs
index d254d8edd..94731e75b 100644
--- a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_atom_destination/unregistered.rs
+++ b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_atom_destination/unregistered.rs
@@ -12,7 +12,7 @@ fn errors_badarg() {
                 )
             }),
             |(milliseconds, arc_process, message)| {
-                let time = arc_process.integer(milliseconds);
+                let time = arc_process.integer(milliseconds).unwrap();
                 let destination = registered_name();
                 let options = options(&arc_process);
 
diff --git a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_local_pid_destination/with_different_process.rs b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_local_pid_destination/with_different_process.rs
index 0f62fabad..0f3571273 100644
--- a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_local_pid_destination/with_different_process.rs
+++ b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_local_pid_destination/with_different_process.rs
@@ -11,10 +11,10 @@ fn sends_message_when_timer_expires() {
             )
         },
         |(arc_process, milliseconds, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
 
             let destination_arc_process = test::process::child(&arc_process);
-            let destination = destination_arc_process.pid_term();
+            let destination = destination_arc_process.pid_term().unwrap();
 
             let options = options(&arc_process);
 
diff --git a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_local_pid_destination/with_same_process.rs b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_local_pid_destination/with_same_process.rs
index c9f93f1b2..08b792bd8 100644
--- a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_local_pid_destination/with_same_process.rs
+++ b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_local_pid_destination/with_same_process.rs
@@ -12,8 +12,8 @@ fn sends_message_when_timer_expires() {
                 )
             }),
             |(milliseconds, arc_process, message)| {
-                let destination = arc_process.pid_term();
-                let time = arc_process.integer(milliseconds);
+                let destination = arc_process.pid_term().unwrap();
+                let time = arc_process.integer(milliseconds).unwrap();
                 let options = options(&arc_process);
 
                 prop_assert_badarg!(
diff --git a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_local_pid_destination/without_process.rs b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_local_pid_destination/without_process.rs
index fa2a248e5..5ff4231d9 100644
--- a/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_local_pid_destination/without_process.rs
+++ b/native_implemented/otp/src/erlang/start_timer_4/test/with_proper_list_options/with_list_options/with_invalid_option/with_small_integer_time/with_local_pid_destination/without_process.rs
@@ -11,7 +11,7 @@ fn errors_badarg() {
             )
         },
         |(arc_process, milliseconds, message)| {
-            let time = arc_process.integer(milliseconds);
+            let time = arc_process.integer(milliseconds).unwrap();
             let destination = Pid::next_term();
             let options = options(&arc_process);
 
diff --git a/native_implemented/otp/src/erlang/string_to_float.rs b/native_implemented/otp/src/erlang/string_to_float.rs
index 0b75bcd88..15704777f 100644
--- a/native_implemented/otp/src/erlang/string_to_float.rs
+++ b/native_implemented/otp/src/erlang/string_to_float.rs
@@ -2,9 +2,9 @@ use std::num::FpCategory;
 
 use anyhow::*;
 
-use liblumen_alloc::erts::exception::InternalResult;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::*;
+use firefly_rt::term::Term;
 
 use crate::runtime::context;
 
@@ -27,7 +27,7 @@ pub fn string_to_float(
                         )
                         .into())
                     } else {
-                        Ok(process.float(inner))
+                        Ok(inner.into())
                     }
                 }
                 // Erlang has no support for Nan, +inf or -inf
@@ -46,7 +46,7 @@ pub fn string_to_float(
                         // Erlang does not track the difference without +0 and -0.
                         let zero = inner.abs();
 
-                        Ok(process.float(zero))
+                        Ok(zero.into())
                     }
                 }
             }
diff --git a/native_implemented/otp/src/erlang/string_to_integer.rs b/native_implemented/otp/src/erlang/string_to_integer.rs
index 5ccba342c..27003771b 100644
--- a/native_implemented/otp/src/erlang/string_to_integer.rs
+++ b/native_implemented/otp/src/erlang/string_to_integer.rs
@@ -3,9 +3,10 @@ use std::convert::TryInto;
 use anyhow::*;
 use num_bigint::BigInt;
 
-use liblumen_alloc::erts::exception::InternalResult;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_alloc::gc::GcBox;
+
+use firefly_rt::process::Process;
+use firefly_rt::term::{OpaqueTerm, Term};
 
 use crate::runtime::base::Base;
 use crate::runtime::context;
@@ -16,12 +17,16 @@ pub fn base_string_to_integer(
     name: &'static str,
     term: Term,
     string: &str,
-) -> InternalResult<Term> {
+) -> Result<OpaqueTerm> {
     let base_base: Base = base.try_into()?;
     let bytes = string.as_bytes();
 
     match BigInt::parse_bytes(bytes, base_base.radix()) {
-        Some(big_int) => Ok(process.integer(big_int)),
+        Some(big_int) => {
+            let big_integer: BigInteger = big_int.into();
+            let gc_box_big_integer = GcBox::new_in(big_integer, process)?;
+            Ok(gc_box_big_integer.into())
+        }
         None => Err(anyhow!("{} is not in base ({})", context::string(name, term), base).into()),
     }
 }
@@ -33,7 +38,7 @@ pub fn decimal_string_to_integer(
     string: &str,
 ) -> InternalResult<Term> {
     match BigInt::parse_bytes(string.as_bytes(), 10) {
-        Some(big_int) => Ok(process.integer(big_int)),
+        Some(big_int) => Ok(process.integer(big_int).unwrap()),
         None => Err(anyhow!("{} is not base 10", context::string(name, term)).into()),
     }
 }
diff --git a/native_implemented/otp/src/erlang/subtract_2.rs b/native_implemented/otp/src/erlang/subtract_2.rs
index 8812d152a..fad2f7d49 100644
--- a/native_implemented/otp/src/erlang/subtract_2.rs
+++ b/native_implemented/otp/src/erlang/subtract_2.rs
@@ -1,12 +1,18 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use std::ptr::NonNull;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 /// `-/2` infix operator
 #[native_implemented::function(erlang:-/2)]
-pub fn result(process: &Process, minuend: Term, subtrahend: Term) -> exception::Result<Term> {
+pub fn result(
+    process: &Process,
+    minuend: Term,
+    subtrahend: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     number_infix_operator!(minuend, subtrahend, process, checked_sub, -)
 }
diff --git a/native_implemented/otp/src/erlang/subtract_2/test.rs b/native_implemented/otp/src/erlang/subtract_2/test.rs
index 9b9cd3791..b1fbbc6a0 100644
--- a/native_implemented/otp/src/erlang/subtract_2/test.rs
+++ b/native_implemented/otp/src/erlang/subtract_2/test.rs
@@ -4,8 +4,8 @@ mod with_integer_minuend;
 use proptest::prop_assert;
 use proptest::strategy::Just;
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Integer, Term};
 
 use crate::erlang::subtract_2::result;
 use crate::test::strategy;
@@ -90,7 +90,7 @@ fn with_integer_minuend_with_float_subtrahend_returns_float() {
             (
                 Just(arc_process.clone()),
                 strategy::term::is_integer(arc_process.clone()),
-                strategy::term::float(arc_process.clone()),
+                strategy::term::float(),
             )
         },
         |(arc_process, minuend, subtrahend)| {
diff --git a/native_implemented/otp/src/erlang/subtract_2/test/with_float_minuend.rs b/native_implemented/otp/src/erlang/subtract_2/test/with_float_minuend.rs
index 4bbe22341..7106187de 100644
--- a/native_implemented/otp/src/erlang/subtract_2/test/with_float_minuend.rs
+++ b/native_implemented/otp/src/erlang/subtract_2/test/with_float_minuend.rs
@@ -6,7 +6,7 @@ fn with_float_minuend_with_integer_subtrahend_returns_float() {
         |arc_process| {
             (
                 Just(arc_process.clone()),
-                strategy::term::float(arc_process.clone()),
+                strategy::term::float(),
                 strategy::term::is_integer(arc_process.clone()),
             )
         },
@@ -17,7 +17,7 @@ fn with_float_minuend_with_integer_subtrahend_returns_float() {
 
             let difference = result.unwrap();
 
-            prop_assert!(difference.is_boxed_float());
+            prop_assert!(difference.is_float());
 
             Ok(())
         },
@@ -41,7 +41,7 @@ fn with_float_minuend_with_float_subtrahend_returns_float() {
 
             let difference = result.unwrap();
 
-            prop_assert!(difference.is_boxed_float());
+            prop_assert!(difference.is_float());
 
             Ok(())
         },
@@ -51,11 +51,11 @@ fn with_float_minuend_with_float_subtrahend_returns_float() {
 #[test]
 fn with_float_subtrahend_with_underflow_returns_min_float() {
     with(|minuend, process| {
-        let subtrahend = process.float(std::f64::MAX);
+        let subtrahend = f64::MAX.into();
 
         assert_eq!(
             result(&process, minuend, subtrahend),
-            Ok(process.float(std::f64::MIN))
+            Ok(f64::MIN.into())
         );
     })
 }
@@ -63,11 +63,11 @@ fn with_float_subtrahend_with_underflow_returns_min_float() {
 #[test]
 fn with_float_subtrahend_with_overflow_returns_max_float() {
     with(|minuend, process| {
-        let subtrahend = process.float(std::f64::MIN);
+        let subtrahend = f64::MIN.into();
 
         assert_eq!(
             result(&process, minuend, subtrahend),
-            Ok(process.float(std::f64::MAX))
+            Ok(f64::MAX.into())
         );
     })
 }
@@ -77,7 +77,7 @@ where
     F: FnOnce(Term, &Process) -> (),
 {
     with_process(|process| {
-        let minuend = process.float(2.0);
+        let minuend = 2.0.into();
 
         f(minuend, &process)
     })
diff --git a/native_implemented/otp/src/erlang/subtract_2/test/with_integer_minuend/big.rs b/native_implemented/otp/src/erlang/subtract_2/test/with_integer_minuend/big.rs
index 590a2b1c8..10f053804 100644
--- a/native_implemented/otp/src/erlang/subtract_2/test/with_integer_minuend/big.rs
+++ b/native_implemented/otp/src/erlang/subtract_2/test/with_integer_minuend/big.rs
@@ -5,7 +5,7 @@ use crate::test::with_big_int;
 #[test]
 fn with_big_integer_subtrahend_with_underflow_returns_small_integer() {
     with_big_int(|process, minuend| {
-        let subtrahend = process.integer(SmallInteger::MAX_VALUE + 1);
+        let subtrahend = process.integer(Integer::MAX_SMALL + 1).unwrap();
 
         assert!(subtrahend.is_boxed_bigint());
 
@@ -22,11 +22,11 @@ fn with_big_integer_subtrahend_with_underflow_returns_small_integer() {
 #[test]
 fn with_float_subtrahend_with_underflow_returns_min_float() {
     with_big_int(|process, minuend| {
-        let subtrahend = process.float(std::f64::MAX);
+        let subtrahend = f64::MAX.into();
 
         assert_eq!(
             result(&process, minuend, subtrahend),
-            Ok(process.float(std::f64::MIN))
+            Ok(f64::MIN.into())
         );
     })
 }
@@ -34,11 +34,11 @@ fn with_float_subtrahend_with_underflow_returns_min_float() {
 #[test]
 fn with_float_subtrahend_with_overflow_returns_max_float() {
     with_big_int(|process, minuend| {
-        let subtrahend = process.float(std::f64::MIN);
+        let subtrahend = f64::MIN.into();
 
         assert_eq!(
             result(&process, minuend, subtrahend),
-            Ok(process.float(std::f64::MAX))
+            Ok(f64::MAX.into())
         );
     })
 }
diff --git a/native_implemented/otp/src/erlang/subtract_2/test/with_integer_minuend/small.rs b/native_implemented/otp/src/erlang/subtract_2/test/with_integer_minuend/small.rs
index 52879a9c8..f386c739d 100644
--- a/native_implemented/otp/src/erlang/subtract_2/test/with_integer_minuend/small.rs
+++ b/native_implemented/otp/src/erlang/subtract_2/test/with_integer_minuend/small.rs
@@ -3,8 +3,8 @@ use super::*;
 #[test]
 fn with_small_integer_subtrahend_with_underflow_returns_big_integer() {
     with_process(|process| {
-        let minuend = process.integer(SmallInteger::MIN_VALUE);
-        let subtrahend = process.integer(SmallInteger::MAX_VALUE);
+        let minuend = process.integer(Integer::MIN_SMALL).unwrap();
+        let subtrahend = process.integer(Integer::MAX_SMALL).unwrap();
 
         assert!(subtrahend.is_smallint());
 
@@ -21,7 +21,7 @@ fn with_small_integer_subtrahend_with_underflow_returns_big_integer() {
 #[test]
 fn with_small_integer_subtrahend_with_overflow_returns_big_integer() {
     with(|minuend, process| {
-        let subtrahend = process.integer(SmallInteger::MIN_VALUE);
+        let subtrahend = process.integer(Integer::MIN_SMALL).unwrap();
 
         assert!(subtrahend.is_smallint());
 
@@ -38,11 +38,11 @@ fn with_small_integer_subtrahend_with_overflow_returns_big_integer() {
 #[test]
 fn with_float_subtrahend_with_underflow_returns_min_float() {
     with(|minuend, process| {
-        let subtrahend = process.float(std::f64::MAX);
+        let subtrahend = f64::MAX.into();
 
         assert_eq!(
             result(&process, minuend, subtrahend),
-            Ok(process.float(std::f64::MIN))
+            Ok(f64::MIN.into())
         );
     })
 }
@@ -50,11 +50,11 @@ fn with_float_subtrahend_with_underflow_returns_min_float() {
 #[test]
 fn with_float_subtrahend_with_overflow_returns_max_float() {
     with(|minuend, process| {
-        let subtrahend = process.float(std::f64::MIN);
+        let subtrahend = f64::MIN.into();
 
         assert_eq!(
             result(&process, minuend, subtrahend),
-            Ok(process.float(std::f64::MAX))
+            Ok(f64::MAX.into())
         );
     })
 }
@@ -64,7 +64,7 @@ where
     F: FnOnce(Term, &Process) -> (),
 {
     with_process(|process| {
-        let minuend = process.integer(2);
+        let minuend = process.integer(2).unwrap();
 
         f(minuend, &process)
     })
diff --git a/native_implemented/otp/src/erlang/subtract_list_2.rs b/native_implemented/otp/src/erlang/subtract_list_2.rs
index 662a3f627..d67fb984d 100644
--- a/native_implemented/otp/src/erlang/subtract_list_2.rs
+++ b/native_implemented/otp/src/erlang/subtract_list_2.rs
@@ -1,19 +1,25 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
+use std::ptr::NonNull;
+
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 /// `--/2`
 #[native_implemented::function(erlang:--/2)]
-pub fn result(process: &Process, minuend: Term, subtrahend: Term) -> exception::Result<Term> {
-    match minuend.decode().unwrap() {
-        TypedTerm::Nil => match subtrahend.decode()? {
-            TypedTerm::Nil => Ok(minuend),
-            TypedTerm::List(subtrahend_cons) => {
+pub fn result(
+    process: &Process,
+    minuend: Term,
+    subtrahend: Term,
+) -> Result<Term, NonNull<ErlangException>> {
+    match minuend {
+        Term::Nil => match subtrahend {
+            Term::Nil => Ok(minuend),
+            Term::Cons(subtrahend_cons) => {
                 if subtrahend_cons.is_proper() {
                     Ok(minuend)
                 } else {
@@ -22,8 +28,8 @@ pub fn result(process: &Process, minuend: Term, subtrahend: Term) -> exception::
             }
             _ => Err(TypeError).context(is_not_a_proper_list("subtrahend", subtrahend)),
         },
-        TypedTerm::List(minuend_cons) => match subtrahend.decode()? {
-            TypedTerm::Nil => {
+        Term::Cons(minuend_cons) => match subtrahend {
+            Term::Nil => {
                 if minuend_cons.is_proper() {
                     Ok(minuend)
                 } else {
@@ -32,7 +38,7 @@ pub fn result(process: &Process, minuend: Term, subtrahend: Term) -> exception::
                         .map_err(From::from)
                 }
             }
-            TypedTerm::List(subtrahend_cons) => {
+            Term::Cons(subtrahend_cons) => {
                 match minuend_cons
                     .into_iter()
                     .collect::<std::result::Result<Vec<Term>, _>>()
@@ -57,7 +63,7 @@ pub fn result(process: &Process, minuend: Term, subtrahend: Term) -> exception::
                             };
                         }
 
-                        Ok(process.list_from_slice(&minuend_vec))
+                        Ok(process.list_from_slice(&minuend_vec)).unwrap()
                     }
                     Err(ImproperList { .. }) => {
                         Err(ImproperListError).context(is_not_a_proper_list("minuend", minuend))
@@ -66,8 +72,8 @@ pub fn result(process: &Process, minuend: Term, subtrahend: Term) -> exception::
             }
             _ => Err(TypeError).context(is_not_a_proper_list("subtrahend", subtrahend)),
         },
-        _ => match subtrahend.decode().unwrap() {
-            TypedTerm::Nil | TypedTerm::List(_) => {
+        _ => match subtrahend {
+            Term::Nil | Term::Cons(_) => {
                 Err(TypeError).context(is_not_a_proper_list("minuend", minuend))
             }
             _ => Err(TypeError).context(format!(
diff --git a/native_implemented/otp/src/erlang/subtract_list_2/test.rs b/native_implemented/otp/src/erlang/subtract_list_2/test.rs
index 18deded7b..48905cae8 100644
--- a/native_implemented/otp/src/erlang/subtract_list_2/test.rs
+++ b/native_implemented/otp/src/erlang/subtract_list_2/test.rs
@@ -3,6 +3,8 @@ mod with_proper_list_minuend;
 use proptest::prop_assert_eq;
 use proptest::strategy::Just;
 
+use firefly_rt::term::Term;
+
 use crate::erlang::subtract_list_2::result;
 use crate::test::strategy;
 
diff --git a/native_implemented/otp/src/erlang/subtract_list_2/test/with_proper_list_minuend.rs b/native_implemented/otp/src/erlang/subtract_list_2/test/with_proper_list_minuend.rs
index eb6901ba7..38850f7a0 100644
--- a/native_implemented/otp/src/erlang/subtract_list_2/test/with_proper_list_minuend.rs
+++ b/native_implemented/otp/src/erlang/subtract_list_2/test/with_proper_list_minuend.rs
@@ -32,12 +32,12 @@ fn with_subtrahend_list_returns_minuend_with_first_copy_of_each_element_in_subtr
             )
         },
         |(arc_process, element1, element2)| {
-            let minuend = arc_process.list_from_slice(&[element1, element2, element1]);
-            let subtrahend = arc_process.list_from_slice(&[element1]);
+            let minuend = arc_process.list_from_slice(&[element1, element2, element1]).unwrap();
+            let subtrahend = arc_process.list_from_slice(&[element1]).unwrap();
 
             prop_assert_eq!(
                 result(&arc_process, minuend, subtrahend),
-                Ok(arc_process.list_from_slice(&[element2, element1]))
+                Ok(arc_process.list_from_slice(&[element2, element1]).unwrap())
             );
 
             Ok(())
diff --git a/native_implemented/otp/src/erlang/system_flag_2.rs b/native_implemented/otp/src/erlang/system_flag_2.rs
index 003431cc3..511aed4aa 100644
--- a/native_implemented/otp/src/erlang/system_flag_2.rs
+++ b/native_implemented/otp/src/erlang/system_flag_2.rs
@@ -1,13 +1,15 @@
+use std::ptr::NonNull;
+
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:system_flag/2)]
-pub fn result(flag: Term, _value: Term) -> exception::Result<Term> {
+pub fn result(flag: Term, _value: Term) -> Result<Term, NonNull<ErlangException>> {
     let flag_atom = term_try_into_atom!(flag)?;
 
-    match flag_atom.name() {
+    match flag_atom.as_str() {
         "backtrace_depth" => unimplemented!(),
         "cpu_topology" => unimplemented!(),
         "dirty_cpu_schedulers_online" => unimplemented!(),
diff --git a/native_implemented/otp/src/erlang/system_info_1.rs b/native_implemented/otp/src/erlang/system_info_1.rs
index f345abea9..4b6554934 100644
--- a/native_implemented/otp/src/erlang/system_info_1.rs
+++ b/native_implemented/otp/src/erlang/system_info_1.rs
@@ -1,12 +1,14 @@
+use std::ptr::NonNull;
+
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:system_info/1)]
-pub fn result(item: Term) -> exception::Result<Term> {
-    match item.decode().unwrap() {
-        TypedTerm::Atom(atom) => match atom.name() {
+pub fn result(item: Term) -> Result<Term, NonNull<ErlangException>> {
+    match item {
+        Term::Atom(atom) => match atom.as_str() {
             "alloc_util_allocators" => unimplemented!(),
             "allocated_areas" => unimplemented!(),
             "allocator" => unimplemented!(),
@@ -91,12 +93,12 @@ pub fn result(item: Term) -> exception::Result<Term> {
             )
             .into()),
         },
-        TypedTerm::Tuple(boxed_tuple) => {
-            if boxed_tuple.len() == 2 {
-                let tag = boxed_tuple[0];
+        Term::Tuple(ref tuple) => {
+            if tuple.len() == 2 {
+                let tag = tuple[0];
 
-                match tag.decode().unwrap() {
-                    TypedTerm::Atom(tag_atom) => match tag_atom.name() {
+                match tag {
+                    Term::Atom(tag_atom) => match tag_atom.as_str() {
                         "allocator" => unimplemented!(),
                         "allocator_sizes" => unimplemented!(),
                         "cpu_topology" => unimplemented!(),
@@ -144,7 +146,7 @@ const SUPPORTED_ATOMS: &'static str = "`allocated_areas`, `allocator`, \
 const SUPPORTED_TUPLES: &'static str = "`{allocator, Alloc}`, `{allocator_sizes, Alloc}`, \
           `{cpu_topology, defined | detected | used}`, or `{wordsize, internal | external}`";
 
-fn item_is_not_supported_tuple(item: Term) -> exception::Result<Term> {
+fn item_is_not_supported_tuple(item: Term) -> Result<Term, NonNull<ErlangException>> {
     Err(anyhow!(
         "item ({}) is not a supported tuple ({})",
         item,
diff --git a/native_implemented/otp/src/erlang/system_time_0.rs b/native_implemented/otp/src/erlang/system_time_0.rs
index 967244c37..67a7d8888 100644
--- a/native_implemented/otp/src/erlang/system_time_0.rs
+++ b/native_implemented/otp/src/erlang/system_time_0.rs
@@ -1,8 +1,8 @@
 #[cfg(test)]
 mod test;
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::runtime::time::{system, Unit::Native};
 
@@ -10,5 +10,5 @@ use crate::runtime::time::{system, Unit::Native};
 pub fn result(process: &Process) -> Term {
     let big_int = system::time_in_unit(Native);
 
-    process.integer(big_int)
+    process.integer(big_int).unwrap()
 }
diff --git a/native_implemented/otp/src/erlang/system_time_1.rs b/native_implemented/otp/src/erlang/system_time_1.rs
index 86651e765..01afd17d7 100644
--- a/native_implemented/otp/src/erlang/system_time_1.rs
+++ b/native_implemented/otp/src/erlang/system_time_1.rs
@@ -2,18 +2,19 @@
 mod test;
 
 use std::convert::TryInto;
+use std::ptr::NonNull;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::runtime::time::{system, Unit};
 
 #[native_implemented::function(erlang:system_time/1)]
-pub fn result(process: &Process, unit: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, unit: Term) -> Result<Term, NonNull<ErlangException>> {
     let unit_unit: Unit = unit.try_into()?;
     let big_int = system::time_in_unit(unit_unit);
-    let term = process.integer(big_int);
+    let term = process.integer(big_int).unwrap();
 
     Ok(term)
 }
diff --git a/native_implemented/otp/src/erlang/system_time_1/test.rs b/native_implemented/otp/src/erlang/system_time_1/test.rs
index dabcd7fff..ba7147182 100644
--- a/native_implemented/otp/src/erlang/system_time_1/test.rs
+++ b/native_implemented/otp/src/erlang/system_time_1/test.rs
@@ -1,10 +1,9 @@
 mod with_atom;
 mod with_small_integer;
 
-use proptest::strategy::{Just, Strategy};
+use proptest::strategy::Just;
 
-use liblumen_alloc::atom;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 use crate::erlang::system_time_1::result;
 use crate::test::{strategy, with_process};
diff --git a/native_implemented/otp/src/erlang/system_time_1/test/with_atom.rs b/native_implemented/otp/src/erlang/system_time_1/test/with_atom.rs
index 35c294f64..c15a486d8 100644
--- a/native_implemented/otp/src/erlang/system_time_1/test/with_atom.rs
+++ b/native_implemented/otp/src/erlang/system_time_1/test/with_atom.rs
@@ -7,7 +7,7 @@ use std::time::Duration;
 fn with_invalid_unit_errors_badarg() {
     with_process(|process| {
         assert_badarg!(
-            result(process, atom!("invalid")),
+            result(process, atoms::Invalid.into()),
             "atom (invalid) is not supported"
         );
     });
diff --git a/native_implemented/otp/src/erlang/system_time_1/test/with_small_integer.rs b/native_implemented/otp/src/erlang/system_time_1/test/with_small_integer.rs
index 396fb8395..d363c1457 100644
--- a/native_implemented/otp/src/erlang/system_time_1/test/with_small_integer.rs
+++ b/native_implemented/otp/src/erlang/system_time_1/test/with_small_integer.rs
@@ -7,7 +7,7 @@ use std::time::Duration;
 fn with_negative_errors_badarg() {
     with_process(|process| {
         assert_badarg!(
-            result(process, process.integer(-1)),
+            result(process, process.integer(-1).unwrap()),
             "hertz must be positive"
         );
     });
@@ -17,7 +17,7 @@ fn with_negative_errors_badarg() {
 fn with_zero_errors_badarg() {
     with_process(|process| {
         assert_badarg!(
-            result(process, process.integer(0)),
+            result(process, process.integer(0).unwrap()),
             "hertz must be positive"
         );
     });
@@ -26,7 +26,7 @@ fn with_zero_errors_badarg() {
 #[test]
 fn with_positive_increases_after_2_time_units() {
     with_process(|process| {
-        let unit = process.integer(2);
+        let unit = process.integer(2).unwrap();
 
         let first = result(process, unit).unwrap();
 
diff --git a/native_implemented/otp/src/erlang/term_to_binary.rs b/native_implemented/otp/src/erlang/term_to_binary.rs
index d288c1724..d3efb00d7 100644
--- a/native_implemented/otp/src/erlang/term_to_binary.rs
+++ b/native_implemented/otp/src/erlang/term_to_binary.rs
@@ -7,14 +7,11 @@ use std::sync::Arc;
 
 use num_bigint::{BigInt, Sign};
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::closure::{Creator, Definition};
-use liblumen_alloc::erts::term::prelude::*;
-use liblumen_alloc::erts::Node;
-
-use crate::runtime::distribution::nodes::node::{self, arc_node};
+use firefly_rt::process::Process;
+use firefly_rt::term::{Atom, Cons, ImproperList, Pid, Term};
 
 use crate::runtime::distribution::external_term_format::{version, Tag};
+use crate::runtime::distribution::nodes::node::{self, arc_node};
 
 use options::*;
 
@@ -100,7 +97,7 @@ fn append_pid(byte_vec: &mut Vec<u8>, arc_node: Arc<Node>, id: u32, serial: u32)
 
     push_tag(byte_vec, tag);
 
-    byte_vec.extend_from_slice(&atom_to_byte_vec(arc_node.name()));
+    byte_vec.extend_from_slice(&atom_to_byte_vec(arc_node.as_str()));
     byte_vec.extend_from_slice(&id.to_be_bytes());
     byte_vec.extend_from_slice(&serial.to_be_bytes());
 
@@ -124,7 +121,7 @@ fn append_usize_as_u32(byte_vec: &mut Vec<u8>, len_usize: usize) {
 }
 
 fn atom_to_byte_vec(atom: Atom) -> Vec<u8> {
-    let bytes = atom.name().as_bytes();
+    let bytes = atom.as_str().as_bytes();
     let len_usize = bytes.len();
     let mut byte_vec: Vec<u8> = Vec::new();
 
@@ -151,7 +148,7 @@ fn atom_to_byte_vec(atom: Atom) -> Vec<u8> {
 // -- http://erlang.org/doc/apps/erts/erl_ext_dist.html#list_ext
 fn cons_to_element_vec_tail(cons: &Cons) -> (Vec<Term>, Term) {
     let mut element_vec: Vec<Term> = Vec::new();
-    let mut tail = Term::NIL;
+    let mut tail = Term::Nil;
 
     for result in cons.into_iter() {
         match result {
@@ -176,11 +173,11 @@ fn term_to_byte_vec(process: &Process, options: &Options, term: Term) -> Vec<u8>
     let mut byte_vec: Vec<u8> = vec![version::NUMBER];
 
     while let Some(front_term) = stack.pop_front() {
-        match front_term.decode().unwrap() {
-            TypedTerm::Atom(atom) => {
+        match front_term {
+            Term::Atom(atom) => {
                 byte_vec.extend_from_slice(&atom_to_byte_vec(atom));
             }
-            TypedTerm::List(cons) => {
+            Term::Cons(cons) => {
                 match try_cons_to_string_ext_byte_vec(&cons) {
                     Ok(mut string_ext_byte_vec) => byte_vec.append(&mut string_ext_byte_vec),
                     Err(_) => {
@@ -199,10 +196,10 @@ fn term_to_byte_vec(process: &Process, options: &Options, term: Term) -> Vec<u8>
                     }
                 };
             }
-            TypedTerm::Nil => {
+            Term::Nil => {
                 push_tag(&mut byte_vec, Tag::Nil);
             }
-            TypedTerm::Pid(pid) => {
+            Term::Pid(pid) => {
                 append_pid(
                     &mut byte_vec,
                     arc_node(),
@@ -210,7 +207,7 @@ fn term_to_byte_vec(process: &Process, options: &Options, term: Term) -> Vec<u8>
                     pid.serial() as u32,
                 );
             }
-            TypedTerm::SmallInteger(small_integer) => {
+            Term::Int(small_integer) => {
                 let small_integer_isize: isize = small_integer.into();
 
                 match try_append_isize_as_small_integer_or_integer(
@@ -228,89 +225,88 @@ fn term_to_byte_vec(process: &Process, options: &Options, term: Term) -> Vec<u8>
                     }
                 }
             }
-            TypedTerm::BigInteger(big_integer) => {
+            Term::BigInt(big_integer) => {
                 let big_int: &BigInt = big_integer.as_ref().into();
 
                 append_big_int(&mut byte_vec, big_int);
             }
-            TypedTerm::Float(float) => {
+            Term::Float(float) => {
                 let float_f64: f64 = float.into();
 
                 push_tag(&mut byte_vec, Tag::NewFloat);
                 byte_vec.extend_from_slice(&float_f64.to_be_bytes());
             }
-            TypedTerm::Closure(closure) => {
-                match closure.definition() {
-                    Definition::Export { function } => {
-                        push_tag(&mut byte_vec, Tag::Export);
-                        byte_vec.append(&mut atom_to_byte_vec(closure.module()));
-                        byte_vec.append(&mut atom_to_byte_vec(*function));
-                        try_append_isize_as_small_integer_or_integer(
-                            &mut byte_vec,
-                            closure.arity() as isize,
-                        )
+            Term::Closure(gc_box_closure) => {
+                let closure = gc_box_closure.as_ref();
+                let env = closure.env();
+
+                // export
+                if env.is_empty() {
+                    push_tag(&mut byte_vec, Tag::Export);
+                    byte_vec.append(&mut atom_to_byte_vec(closure.module()));
+                    byte_vec.append(&mut atom_to_byte_vec(*closure.name));
+                    try_append_isize_as_small_integer_or_integer(
+                        &mut byte_vec,
+                        closure.arity() as isize,
+                    )
                         .unwrap();
-                    }
-                    Definition::Anonymous {
-                        index,
-                        old_unique,
-                        unique,
-                        //creator,
-                    } => {
-                        let default_creator = Creator::Local(Pid::default());
-                        let mut sized_byte_vec: Vec<u8> = Vec::new();
-
-                        let module_function_arity = closure.module_function_arity();
-                        sized_byte_vec.push(module_function_arity.arity);
-
-                        sized_byte_vec.extend_from_slice(unique);
-                        sized_byte_vec.extend_from_slice(&index.to_be_bytes());
-
-                        let env_len_u32: u32 = closure.env_len().try_into().unwrap();
-                        sized_byte_vec.extend_from_slice(&env_len_u32.to_be_bytes());
-
-                        sized_byte_vec.append(&mut atom_to_byte_vec(module_function_arity.module));
-
-                        // > [index] encoded using SMALL_INTEGER_EXT or INTEGER_EXT.
-                        try_append_isize_as_small_integer_or_integer(
-                            &mut sized_byte_vec,
-                            (*index).try_into().unwrap(),
-                        )
+                }
+                // anonymous
+                else {
+                    let mut sized_byte_vec: Vec<u8> = Vec::new();
+
+                    let module_function_arity = closure.module_function_arity();
+                    sized_byte_vec.push(module_function_arity.arity);
+
+                    let unique: [u8; 16] = Default::default();
+                    sized_byte_vec.extend_from_slice(&unique);
+
+                    let index: usize = 0;
+                    sized_byte_vec.extend_from_slice(&index.to_be_bytes());
+
+                    let env_len_u32: u32 = env.len().try_into().unwrap();
+                    sized_byte_vec.extend_from_slice(&env_len_u32.to_be_bytes());
+
+                    sized_byte_vec.append(&mut atom_to_byte_vec(module_function_arity.module));
+
+                    // > [index] encoded using SMALL_INTEGER_EXT or INTEGER_EXT.
+                    try_append_isize_as_small_integer_or_integer(
+                        &mut sized_byte_vec,
+                        (*index).try_into().unwrap(),
+                    )
                         .unwrap();
 
-                        // > An integer encoded using SMALL_INTEGER_EXT or INTEGER_EXT
-                        // But this means OldUniq can't be the same a Uniq with a different
-                        // encoding,
-                        try_append_isize_as_small_integer_or_integer(
-                            &mut sized_byte_vec,
-                            (*old_unique).try_into().unwrap(),
-                        )
+                    let old_unique: u32 = 0;
+                    // > An integer encoded using SMALL_INTEGER_EXT or INTEGER_EXT
+                    // But this means OldUniq can't be the same a Uniq with a different
+                    // encoding,
+                    try_append_isize_as_small_integer_or_integer(
+                        &mut sized_byte_vec,
+                        (*old_unique).try_into().unwrap(),
+                    )
                         .unwrap();
 
-                        append_creator(&mut sized_byte_vec, &default_creator);
+                    let pid: Pid = Default::default();
+                    append_pid(
+                        &mut byte_vec,
+                        node::arc_node(),
+                        pid.number() as u32,
+                        pid.serial() as u32,
+                    );
 
-                        for term in closure.env_slice() {
-                            sized_byte_vec.append(&mut term_to_byte_vec(process, options, *term));
-                        }
+                    for term in closure.env_slice() {
+                        sized_byte_vec.append(&mut term_to_byte_vec(process, options, *term));
+                    }
 
-                        const SIZE_BYTE_LEN: usize = mem::size_of::<u32>();
-                        let size = (SIZE_BYTE_LEN + sized_byte_vec.len()) as u32;
+                    const SIZE_BYTE_LEN: usize = mem::size_of::<u32>();
+                    let size = (SIZE_BYTE_LEN + sized_byte_vec.len()) as u32;
 
-                        push_tag(&mut byte_vec, Tag::NewFunction);
-                        byte_vec.extend_from_slice(&size.to_be_bytes());
-                        byte_vec.append(&mut sized_byte_vec);
-                    }
+                    push_tag(&mut byte_vec, Tag::NewFunction);
+                    byte_vec.extend_from_slice(&size.to_be_bytes());
+                    byte_vec.append(&mut sized_byte_vec);
                 }
             }
-            TypedTerm::ExternalPid(external_pid) => {
-                append_pid(
-                    &mut byte_vec,
-                    external_pid.arc_node(),
-                    external_pid.number() as u32,
-                    external_pid.serial() as u32,
-                );
-            }
-            TypedTerm::Map(map) => {
+            Term::Map(map) => {
                 push_tag(&mut byte_vec, Tag::Map);
 
                 let len_usize = map.len();
@@ -321,7 +317,7 @@ fn term_to_byte_vec(process: &Process, options: &Options, term: Term) -> Vec<u8>
                     stack.push_front(*key);
                 }
             }
-            TypedTerm::HeapBinary(heap_bin) => {
+            Term::HeapBinary(heap_bin) => {
                 push_tag(&mut byte_vec, Tag::Binary);
 
                 let len_usize = heap_bin.full_byte_len();
@@ -329,20 +325,7 @@ fn term_to_byte_vec(process: &Process, options: &Options, term: Term) -> Vec<u8>
 
                 byte_vec.extend_from_slice(heap_bin.as_bytes());
             }
-            TypedTerm::MatchContext(match_context) => {
-                if match_context.is_binary() {
-                    if match_context.is_aligned() {
-                        append_binary_bytes(&mut byte_vec, unsafe {
-                            match_context.as_bytes_unchecked()
-                        });
-                    } else {
-                        unimplemented!()
-                    }
-                } else {
-                    unimplemented!()
-                }
-            }
-            TypedTerm::ProcBin(proc_bin) => {
+            Term::RcBinary(proc_bin) => {
                 push_tag(&mut byte_vec, Tag::Binary);
 
                 let len_usize = proc_bin.full_byte_len();
@@ -350,7 +333,7 @@ fn term_to_byte_vec(process: &Process, options: &Options, term: Term) -> Vec<u8>
 
                 byte_vec.extend_from_slice(proc_bin.as_bytes());
             }
-            TypedTerm::Reference(reference) => {
+            Term::Reference(reference) => {
                 let scheduler_id_u32: u32 = reference.scheduler_id().into();
                 let number: u64 = reference.number().into();
 
@@ -370,7 +353,7 @@ fn term_to_byte_vec(process: &Process, options: &Options, term: Term) -> Vec<u8>
                 byte_vec.extend_from_slice(&scheduler_id_u32.to_be_bytes());
                 byte_vec.extend_from_slice(&number.to_be_bytes());
             }
-            TypedTerm::SubBinary(subbinary) => {
+            Term::RefBinary(subbinary) => {
                 if subbinary.is_binary() {
                     push_tag(&mut byte_vec, Tag::Binary);
 
@@ -406,7 +389,7 @@ fn term_to_byte_vec(process: &Process, options: &Options, term: Term) -> Vec<u8>
                     byte_vec.push(last_byte);
                 }
             }
-            TypedTerm::Tuple(tuple) => {
+            Term::Tuple(tuple) => {
                 let len_usize = tuple.len();
 
                 if len_usize <= SMALL_TUPLE_EXT_MAX_LEN {
diff --git a/native_implemented/otp/src/erlang/term_to_binary/options.rs b/native_implemented/otp/src/erlang/term_to_binary/options.rs
index af7e4abb4..3bf2582ad 100644
--- a/native_implemented/otp/src/erlang/term_to_binary/options.rs
+++ b/native_implemented/otp/src/erlang/term_to_binary/options.rs
@@ -3,7 +3,7 @@ mod minor_version;
 
 use std::convert::{TryFrom, TryInto};
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::{Atom, Term};
 
 use compression::*;
 use minor_version::*;
@@ -25,8 +25,8 @@ impl Default for Options {
 
 impl Options {
     fn put_option_term(&mut self, option: Term) -> Result<&Self, TryFromTermError> {
-        match option.decode().unwrap() {
-            TypedTerm::Atom(atom) => match atom.name() {
+        match option {
+            Term::Atom(atom) => match atom.as_str() {
                 "compressed" => {
                     self.compression = Default::default();
 
@@ -34,13 +34,13 @@ impl Options {
                 }
                 name => Err(TryFromTermError::AtomName(name)),
             },
-            TypedTerm::Tuple(tuple) => {
+            Term::Tuple(tuple) => {
                 if tuple.len() == 2 {
                     let atom: Atom = tuple[0]
                         .try_into()
                         .map_err(|_| TryFromTermError::KeywordKeyType)?;
 
-                    match atom.name() {
+                    match atom.as_str() {
                         "compressed" => {
                             self.compression = tuple[1]
                                 .try_into()
@@ -74,11 +74,12 @@ impl TryFrom<Term> for Options {
         let mut options_term = term;
 
         loop {
-            match options_term.decode().unwrap() {
-                TypedTerm::Nil => return Ok(options),
-                TypedTerm::List(cons) => {
-                    options.put_option_term(cons.head)?;
-                    options_term = cons.tail;
+            match options_term {
+                Term::Nil => return Ok(options),
+                Term::Cons(non_null_cons) => {
+                    let cons = unsafe { non_null_cons.as_ref() };
+                    options.put_option_term(cons.head())?;
+                    options_term = cons.tail();
 
                     continue;
                 }
diff --git a/native_implemented/otp/src/erlang/term_to_binary/options/compression.rs b/native_implemented/otp/src/erlang/term_to_binary/options/compression.rs
index 46d8b26a1..3631da622 100644
--- a/native_implemented/otp/src/erlang/term_to_binary/options/compression.rs
+++ b/native_implemented/otp/src/erlang/term_to_binary/options/compression.rs
@@ -1,6 +1,7 @@
 use std::convert::{TryFrom, TryInto};
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_number::TryIntoIntegerError;
+use firefly_rt::term::Term;
 
 pub struct Compression(pub u8);
 
diff --git a/native_implemented/otp/src/erlang/term_to_binary/options/minor_version.rs b/native_implemented/otp/src/erlang/term_to_binary/options/minor_version.rs
index 1e547ee42..45e9b5c8c 100644
--- a/native_implemented/otp/src/erlang/term_to_binary/options/minor_version.rs
+++ b/native_implemented/otp/src/erlang/term_to_binary/options/minor_version.rs
@@ -1,6 +1,8 @@
 use std::convert::{TryFrom, TryInto};
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_number::TryIntoIntegerError;
+
+use firefly_rt::term::Term;
 
 pub struct MinorVersion(u8);
 
diff --git a/native_implemented/otp/src/erlang/term_to_binary_1.rs b/native_implemented/otp/src/erlang/term_to_binary_1.rs
index e4e4131f9..f0501bf55 100644
--- a/native_implemented/otp/src/erlang/term_to_binary_1.rs
+++ b/native_implemented/otp/src/erlang/term_to_binary_1.rs
@@ -1,8 +1,8 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::term_to_binary::term_to_binary;
 
diff --git a/native_implemented/otp/src/erlang/term_to_binary_1/test.rs b/native_implemented/otp/src/erlang/term_to_binary_1/test.rs
index ed1dffc4e..4ea39ce96 100644
--- a/native_implemented/otp/src/erlang/term_to_binary_1/test.rs
+++ b/native_implemented/otp/src/erlang/term_to_binary_1/test.rs
@@ -1,9 +1,8 @@
 use proptest::strategy::Just;
 use proptest::{prop_assert, prop_assert_eq};
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::scheduler;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Atom, Term};
 
 use crate::erlang::binary_to_term_1;
 use crate::erlang::term_to_binary_1::result;
@@ -31,7 +30,7 @@ fn roundtrips_through_binary_to_term() {
 fn with_negative_float_returns_new_float_ext() {
     with_process(|process| {
         assert_eq!(
-            result(process, process.float(std::f64::MIN)),
+            result(process, f64::MIN.into()),
             process.binary_from_bytes(&[
                 VERSION_NUMBER,
                 NEW_FLOAT_EXT,
@@ -53,7 +52,7 @@ fn with_negative_float_returns_new_float_ext() {
 fn with_zero_float_returns_new_float_ext() {
     with_process(|process| {
         assert_eq!(
-            result(process, process.float(0.0)),
+            result(process, 0.0.into()),
             process.binary_from_bytes(&[
                 VERSION_NUMBER,
                 NEW_FLOAT_EXT,
@@ -75,7 +74,7 @@ fn with_zero_float_returns_new_float_ext() {
 fn with_positive_float_returns_new_float_ext() {
     with_process(|process| {
         assert_eq!(
-            result(process, process.float(std::f64::MAX)),
+            result(process, f64::MAX.into()),
             process.binary_from_bytes(&[
                 VERSION_NUMBER,
                 NEW_FLOAT_EXT,
@@ -144,7 +143,7 @@ fn with_unsigned_byte_small_integer_returns_small_integer_ext() {
         let small_integer_u8 = 0b1010_1010_u8;
 
         assert_eq!(
-            result(process, process.integer(small_integer_u8)),
+            result(process, process.integer(small_integer_u8).unwrap()),
             process.binary_from_bytes(&[VERSION_NUMBER, SMALL_INTEGER_EXT, small_integer_u8])
         );
     });
@@ -157,7 +156,7 @@ fn with_negative_i32_small_integer_returns_integer_ext() {
         let small_integer_i32 = std::i32::MIN;
 
         assert_eq!(
-            result(process, process.integer(small_integer_i32)),
+            result(process, process.integer(small_integer_i32).unwrap()),
             process.binary_from_bytes(&[
                 VERSION_NUMBER,
                 INTEGER_EXT,
@@ -177,7 +176,7 @@ fn with_positive_i32_small_integer_returns_integer_ext() {
         let small_integer_i32 = std::i32::MAX;
 
         assert_eq!(
-            result(process, process.integer(small_integer_i32)),
+            result(process, process.integer(small_integer_i32).unwrap()),
             process.binary_from_bytes(&[
                 VERSION_NUMBER,
                 INTEGER_EXT,
@@ -262,7 +261,7 @@ fn with_pid_returns_pid_ext() {
 fn with_empty_tuple_returns_small_tuple_ext() {
     with_process(|process| {
         assert_eq!(
-            result(process, process.tuple_from_slice(&[])),
+            result(process, process.tuple_term_from_term_slice(&[])),
             process.binary_from_bytes(&[VERSION_NUMBER, SMALL_TUPLE_EXT, 0])
         );
     });
@@ -288,7 +287,7 @@ fn with_non_empty_tuple_returns_small_tuple_ext() {
 fn with_empty_list_returns_nil_ext() {
     with_process(|process| {
         assert_eq!(
-            result(process, Term::NIL),
+            result(process, Term::Nil),
             process.binary_from_bytes(&[VERSION_NUMBER, NIL_EXT])
         );
     });
@@ -338,7 +337,7 @@ fn with_improper_list_returns_list_ext() {
 fn with_proper_list_returns_list_ext() {
     with_process(|process| {
         assert_eq!(
-            result(process, process.list_from_slice(&[process.integer(256)])),
+            result(process, process.list_from_slice(&[process.integer(256).unwrap()])).unwrap(),
             process.binary_from_bytes(&[131, 108, 0, 0, 0, 1, 98, 0, 0, 1, 0, 106])
         )
     });
@@ -352,9 +351,9 @@ fn with_nested_list_returns_list_ext() {
             result(
                 process,
                 process.list_from_slice(&[
-                    process.list_from_slice(&[process.integer(1100), process.integer(1200)]),
-                    process.list_from_slice(&[process.integer(2100), process.integer(2200)])
-                ])
+                    process.list_from_slice(&[process.integer(1100).unwrap(), process.integer(1200).unwrap_or()]).unwrap(),
+                    process.list_from_slice(&[process.integer(2100).unwrap(), process.integer(2200).unwrap()]).unwrap()
+                ]).unwrap()
             ),
             process.binary_from_bytes(&[
                 131, 108, 0, 0, 0, 2, 108, 0, 0, 0, 2, 98, 0, 0, 4, 76, 98, 0, 0, 4, 176, 106, 108,
@@ -510,7 +509,7 @@ fn with_subbinary_with_binary_without_aligned_returns_binary_ext() {
 fn with_small_integer_returns_small_big_ext() {
     with_process(|process| {
         assert_eq!(
-            result(process, process.integer(9_999_999_999_i64)),
+            result(process, process.integer(9_999_999_999_i64).unwrap()),
             process.binary_from_bytes(&[131, 110, 5, 0, 255, 227, 11, 84, 2])
         )
     })
@@ -520,7 +519,7 @@ fn with_small_integer_returns_small_big_ext() {
 #[test]
 fn with_big_integer_returns_small_big_ext() {
     with_process(|process| {
-        let big_integer = process.integer(9_223_372_036_854_775_807_i64);
+        let big_integer = process.integer(9_223_372_036_854_775_807_i64).unwrap();
 
         assert!(big_integer.is_boxed_bigint());
 
@@ -594,7 +593,7 @@ fn non_empty_atom_byte_vec() -> Vec<u8> {
 }
 
 fn non_empty_tuple_term(process: &Process) -> Term {
-    process.tuple_from_slice(&[non_empty_atom_term()])
+    process.tuple_term_from_term_slice(&[non_empty_atom_term()])
 }
 
 fn non_empty_tuple_byte_vec() -> Vec<u8> {
diff --git a/native_implemented/otp/src/erlang/throw_1.rs b/native_implemented/otp/src/erlang/throw_1.rs
index a81b6f841..f7c83aceb 100644
--- a/native_implemented/otp/src/erlang/throw_1.rs
+++ b/native_implemented/otp/src/erlang/throw_1.rs
@@ -1,14 +1,16 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
+use std::ptr::NonNull;
 use anyhow::*;
 
-use liblumen_alloc::erts::exception::{self, *};
-use liblumen_alloc::erts::process::trace::Trace;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::backtrace::Trace;
+use firefly_rt::error::ErlangException;
+
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:throw/1)]
-pub fn result(reason: Term) -> exception::Result<Term> {
+pub fn result(reason: Term) -> Result<Term, NonNull<ErlangException>> {
     Err(throw(
         reason,
         Trace::capture(),
diff --git a/native_implemented/otp/src/erlang/time_0.rs b/native_implemented/otp/src/erlang/time_0.rs
index 41d1edbac..e51ea3d78 100644
--- a/native_implemented/otp/src/erlang/time_0.rs
+++ b/native_implemented/otp/src/erlang/time_0.rs
@@ -1,15 +1,16 @@
 #[cfg(test)]
 mod test;
 
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
+
 use crate::runtime::time::datetime;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
 
 #[native_implemented::function(erlang:time/0)]
 pub fn result(process: &Process) -> Term {
     let time: [usize; 3] = datetime::local_time();
 
-    process.tuple_from_slice(&[
+    process.tuple_term_from_term_slice(&[
         process.integer(time[0]),
         process.integer(time[1]),
         process.integer(time[2]),
diff --git a/native_implemented/otp/src/erlang/time_offset_0.rs b/native_implemented/otp/src/erlang/time_offset_0.rs
index d07ee014f..a63ffbb1e 100644
--- a/native_implemented/otp/src/erlang/time_offset_0.rs
+++ b/native_implemented/otp/src/erlang/time_offset_0.rs
@@ -1,8 +1,8 @@
 #[cfg(test)]
 mod test;
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::runtime::time::{monotonic, system, Unit::Native};
 
@@ -11,5 +11,5 @@ pub fn result(process: &Process) -> Term {
     let system_time = system::time_in_unit(Native);
     let monotonic_time = monotonic::time_in_unit(Native);
 
-    process.integer(system_time - monotonic_time)
+    process.integer(system_time - monotonic_time).unwrap()
 }
diff --git a/native_implemented/otp/src/erlang/time_offset_0/test.rs b/native_implemented/otp/src/erlang/time_offset_0/test.rs
index 88984d9cb..2922655cb 100644
--- a/native_implemented/otp/src/erlang/time_offset_0/test.rs
+++ b/native_implemented/otp/src/erlang/time_offset_0/test.rs
@@ -1,3 +1,5 @@
+use firefly_rt::term::Term;
+
 use crate::erlang::monotonic_time_0;
 use crate::erlang::subtract_2;
 use crate::erlang::system_time_0;
@@ -19,7 +21,7 @@ fn approximately_system_time_minus_monotonic_time() {
             subtract_2::result(process, expected_time_offset, time_offset).unwrap();
 
         assert!(
-            time_offset_delta <= process.integer(TIME_OFFSET_DELTA_LIMIT),
+            time_offset_delta <= process.integer(TIME_OFFSET_DELTA_LIMIT).unwrap(),
             "time_offset_delta ({:?}) <= TIME_OFFSET_DELTA_LIMIT ({:?})",
             time_offset_delta,
             TIME_OFFSET_DELTA_LIMIT
diff --git a/native_implemented/otp/src/erlang/time_offset_1.rs b/native_implemented/otp/src/erlang/time_offset_1.rs
index d6a99f1dd..f27d80ddf 100644
--- a/native_implemented/otp/src/erlang/time_offset_1.rs
+++ b/native_implemented/otp/src/erlang/time_offset_1.rs
@@ -2,19 +2,20 @@
 mod test;
 
 use std::convert::TryInto;
+use std::ptr::NonNull;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::runtime::time::{monotonic, system, Unit};
 
 #[native_implemented::function(erlang:time_offset/1)]
-pub fn result(process: &Process, unit: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, unit: Term) -> Result<Term, NonNull<ErlangException>> {
     let unit_unit: Unit = unit.try_into()?;
     let system_time = system::time_in_unit(unit_unit);
     let monotonic_time = monotonic::time_in_unit(unit_unit);
-    let term = process.integer(system_time - monotonic_time);
+    let term = process.integer(system_time - monotonic_time).unwrap();
 
     Ok(term)
 }
diff --git a/native_implemented/otp/src/erlang/time_offset_1/test.rs b/native_implemented/otp/src/erlang/time_offset_1/test.rs
index 7b80c407e..39e4c28be 100644
--- a/native_implemented/otp/src/erlang/time_offset_1/test.rs
+++ b/native_implemented/otp/src/erlang/time_offset_1/test.rs
@@ -1,4 +1,4 @@
-use liblumen_alloc::atom;
+use firefly_rt::term::{atoms, Term};
 
 use crate::erlang::{
     convert_time_unit_3, monotonic_time_1, subtract_2, system_time_1, time_offset_1,
@@ -39,7 +39,7 @@ fn approximately_system_time_minus_monotonic_time_in_perf_counter_ticks() {
 
 fn approximately_system_time_minus_monotonic_time_in_unit(unit_str: &str) {
     with_process(|process| {
-        let unit = atom!(unit_str);
+        let unit = Term::str_to_term(unit_str).into();
         let monotonic_time = monotonic_time_1::result(process, unit).unwrap();
         let system_time = system_time_1::result(process, unit).unwrap();
         let time_offset = time_offset_1::result(process, unit).unwrap();
@@ -47,11 +47,11 @@ fn approximately_system_time_minus_monotonic_time_in_unit(unit_str: &str) {
             subtract_2::result(process, system_time, monotonic_time).unwrap();
         let time_offset_delta =
             subtract_2::result(process, expected_time_offset, time_offset).unwrap();
-        let time_offset_delta_limit_seconds = process.integer(TIME_OFFSET_DELTA_LIMIT_SECONDS);
+        let time_offset_delta_limit_seconds = process.integer(TIME_OFFSET_DELTA_LIMIT_SECONDS).unwrap();
         let time_offset_delta_limit = convert_time_unit_3::result(
             process,
             time_offset_delta_limit_seconds,
-            atom!("seconds"),
+            atoms::Seconds.into(),
             unit,
         )
         .unwrap();
diff --git a/native_implemented/otp/src/erlang/timestamp_0.rs b/native_implemented/otp/src/erlang/timestamp_0.rs
index e5a986f35..7c8d02b2c 100644
--- a/native_implemented/otp/src/erlang/timestamp_0.rs
+++ b/native_implemented/otp/src/erlang/timestamp_0.rs
@@ -4,8 +4,9 @@ mod test;
 use num_bigint::{BigInt, ToBigInt};
 use num_traits::cast::ToPrimitive;
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::*;
+use firefly_rt::term::Term;
 
 use crate::runtime::time::{system, Unit::Microsecond};
 
@@ -14,10 +15,10 @@ pub fn result(process: &Process) -> Term {
     let big_int = system::time_in_unit(Microsecond);
     let erlang_timestamp = ErlangTimestamp::from_microseconds(&big_int);
 
-    process.tuple_from_slice(&[
-        process.integer(erlang_timestamp.megaseconds as usize),
-        process.integer(erlang_timestamp.seconds as usize),
-        process.integer(erlang_timestamp.microseconds as usize),
+    process.tuple_term_from_term_slice(&[
+        process.integer(erlang_timestamp.megaseconds as usize).unwrap(),
+        process.integer(erlang_timestamp.seconds as usize).unwrap(),
+        process.integer(erlang_timestamp.microseconds as usize).unwrap(),
     ])
 }
 
diff --git a/native_implemented/otp/src/erlang/timestamp_0/test.rs b/native_implemented/otp/src/erlang/timestamp_0/test.rs
index a67f4acd8..bb54083cd 100644
--- a/native_implemented/otp/src/erlang/timestamp_0/test.rs
+++ b/native_implemented/otp/src/erlang/timestamp_0/test.rs
@@ -1,7 +1,7 @@
+use firefly_rt::term::Term;
+
 use crate::erlang::{add_2, multiply_2, subtract_2, system_time_1, timestamp_0, tuple_size_1};
 use crate::test::with_process;
-use liblumen_alloc::erts::term::prelude::*;
-use std::convert::TryInto;
 
 const DELTA_LIMIT_MICROSECONDS: u64 = 5_000;
 
@@ -12,7 +12,7 @@ fn returns_a_three_element_tuple() {
 
         let tuple_size_result = tuple_size_1::result(process, timestamp).unwrap();
 
-        assert_eq!(tuple_size_result, process.integer(3));
+        assert_eq!(tuple_size_result, process.integer(3).unwrap());
     });
 }
 
@@ -27,18 +27,18 @@ fn approximately_system_time() {
 
         let timestamp = timestamp_0::result(process);
 
-        let timestamp_tuple: Boxed<Tuple> = timestamp.try_into().unwrap();
+        let timestamp_tuple: NonNull<Tuple> = timestamp.try_into().unwrap();
 
         let megasecs = multiply_2::result(
             process,
             timestamp_tuple.get_element(0).unwrap(),
-            process.integer(1000000000000 as usize),
+            process.integer(1000000000000 as usize).unwrap(),
         )
         .unwrap();
         let secs = multiply_2::result(
             process,
             timestamp_tuple.get_element(1).unwrap(),
-            process.integer(1000000),
+            process.integer(1000000).unwrap(),
         )
         .unwrap();
 
@@ -51,7 +51,7 @@ fn approximately_system_time() {
         )
         .unwrap();
 
-        let delta_limit_microseconds = process.integer(DELTA_LIMIT_MICROSECONDS);
+        let delta_limit_microseconds = process.integer(DELTA_LIMIT_MICROSECONDS).unwrap();
 
         let delta = subtract_2::result(process, system_time_from_timestamp, system_time).unwrap();
 
diff --git a/native_implemented/otp/src/erlang/tl_1.rs b/native_implemented/otp/src/erlang/tl_1.rs
index a74cdeb12..e8daf103d 100644
--- a/native_implemented/otp/src/erlang/tl_1.rs
+++ b/native_implemented/otp/src/erlang/tl_1.rs
@@ -1,8 +1,10 @@
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::term::prelude::*;
+use std::ptr::NonNull;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::{Cons, Term};
 
 #[native_implemented::function(erlang:tl/1)]
-pub fn result(list: Term) -> exception::Result<Term> {
+pub fn result(list: Term) -> Result<Term, NonNull<ErlangException>> {
     let cons: Boxed<Cons> = term_try_into_non_empty_list!(list)?;
 
     Ok(cons.tail)
diff --git a/native_implemented/otp/src/erlang/trunc_1/test.rs b/native_implemented/otp/src/erlang/trunc_1/test.rs
index 4449feea8..431b40684 100644
--- a/native_implemented/otp/src/erlang/trunc_1/test.rs
+++ b/native_implemented/otp/src/erlang/trunc_1/test.rs
@@ -1,5 +1,3 @@
-use std::convert::TryInto;
-
 use proptest::prop_assert_eq;
 
 use crate::erlang::trunc_1::result;
diff --git a/native_implemented/otp/src/erlang/tuple_size_1.rs b/native_implemented/otp/src/erlang/tuple_size_1.rs
index 6e65a009a..41c98a63b 100644
--- a/native_implemented/otp/src/erlang/tuple_size_1.rs
+++ b/native_implemented/otp/src/erlang/tuple_size_1.rs
@@ -1,14 +1,16 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use std::ptr::NonNull;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:tuple_size/1)]
-pub fn result(process: &Process, tuple: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, tuple: Term) -> Result<Term, NonNull<ErlangException>> {
     let tuple = term_try_into_tuple!(tuple)?;
-    let size = process.integer(tuple.len());
+    let size = process.integer(tuple.len()).unwrap();
 
     Ok(size)
 }
diff --git a/native_implemented/otp/src/erlang/tuple_size_1/test.rs b/native_implemented/otp/src/erlang/tuple_size_1/test.rs
index ab759dcae..0da8be4a1 100644
--- a/native_implemented/otp/src/erlang/tuple_size_1/test.rs
+++ b/native_implemented/otp/src/erlang/tuple_size_1/test.rs
@@ -1,5 +1,7 @@
 use proptest::prop_assert_eq;
-use proptest::strategy::{Just, Strategy};
+use proptest::strategy::Just;
+
+use firefly_rt::term::Term;
 
 use crate::erlang::tuple_size_1::result;
 use crate::test::strategy;
@@ -38,7 +40,7 @@ fn with_tuple_returns_arity() {
             })
         },
         |(arc_process, size, term)| {
-            prop_assert_eq!(result(&arc_process, term), Ok(arc_process.integer(size)));
+            prop_assert_eq!(result(&arc_process, term), Ok(arc_process.integer(size).unwrap()));
 
             Ok(())
         },
diff --git a/native_implemented/otp/src/erlang/tuple_to_list_1.rs b/native_implemented/otp/src/erlang/tuple_to_list_1.rs
index 7d8e33f1f..b941e7e3e 100644
--- a/native_implemented/otp/src/erlang/tuple_to_list_1.rs
+++ b/native_implemented/otp/src/erlang/tuple_to_list_1.rs
@@ -1,16 +1,17 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::alloc::TermAlloc;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use std::ptr::NonNull;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(erlang:tuple_to_list/1)]
-pub fn result(process: &Process, tuple: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, tuple: Term) -> Result<Term, NonNull<ErlangException>> {
     let tuple = term_try_into_tuple!(tuple)?;
     let mut heap = process.acquire_heap();
-    let mut acc = Term::NIL;
+    let mut acc = Term::Nil;
 
     for element in tuple.iter().rev() {
         acc = heap.cons(*element, acc)?.into();
diff --git a/native_implemented/otp/src/erlang/tuple_to_list_1/test.rs b/native_implemented/otp/src/erlang/tuple_to_list_1/test.rs
index 1d35eecd4..c7f79a4d3 100644
--- a/native_implemented/otp/src/erlang/tuple_to_list_1/test.rs
+++ b/native_implemented/otp/src/erlang/tuple_to_list_1/test.rs
@@ -1,6 +1,8 @@
 use proptest::prop_assert_eq;
 use proptest::strategy::Just;
 
+use firefly_rt::term::Term;
+
 use crate::erlang::tuple_to_list_1::result;
 use crate::test::strategy;
 
@@ -31,8 +33,8 @@ fn with_tuple_returns_list() {
             )
         },
         |(arc_process, element_vec)| {
-            let tuple = arc_process.tuple_from_slice(&element_vec);
-            let list = arc_process.list_from_slice(&element_vec);
+            let tuple = arc_process.tuple_term_from_term_slice(&element_vec);
+            let list = arc_process.list_from_slice(&element_vec).unwrap();
 
             prop_assert_eq!(result(&arc_process, tuple), Ok(list));
 
diff --git a/native_implemented/otp/src/erlang/unique_integer.rs b/native_implemented/otp/src/erlang/unique_integer.rs
index 2686db0b0..dd473be2b 100644
--- a/native_implemented/otp/src/erlang/unique_integer.rs
+++ b/native_implemented/otp/src/erlang/unique_integer.rs
@@ -4,8 +4,8 @@ use std::sync::atomic::{AtomicU64, Ordering};
 
 use lazy_static::lazy_static;
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::runtime::scheduler;
 
@@ -30,7 +30,7 @@ pub fn unique_integer(process: &Process, options: Options) -> Term {
 
         // See https://github.com/erlang/otp/blob/769ff22c750d939fdc9cb45fae1e44817ec04307/erts/emulator/beam/erl_bif_unique.c#L669-L697
         if options.positive {
-            process.integer(u)
+            process.integer(u).unwrap()
         } else {
             // When not positive allow for negative and positive even though the counter is unsigned
             // by subtracting counter value down into signed range.
@@ -40,7 +40,7 @@ pub fn unique_integer(process: &Process, options: Options) -> Term {
                 (u - NEGATED_I64_MIN_U64) as i64
             };
 
-            process.integer(i)
+            process.integer(i).unwrap()
         }
     } else {
         // Non-monotonic unique integers are per-scheduler (https://github.com/erlang/otp/blob/769ff22c750d939fdc9cb45fae1e44817ec04307/erts/emulator/beam/erl_bif_unique.c#L572-L584)
@@ -54,7 +54,7 @@ pub fn unique_integer(process: &Process, options: Options) -> Term {
         let u: u128 = (scheduler_id_u128 << 64) | scheduler_unique_integer;
 
         if options.positive {
-            process.integer(u)
+            process.integer(u).unwrap()
         } else {
             let i = if u < NEGATED_I128_MIN_U128 {
                 (u as i128) + std::i128::MIN
@@ -62,7 +62,7 @@ pub fn unique_integer(process: &Process, options: Options) -> Term {
                 (u - NEGATED_I128_MIN_U128) as i128
             };
 
-            process.integer(i)
+            process.integer(i).unwrap()
         }
     }
 }
diff --git a/native_implemented/otp/src/erlang/unique_integer/options.rs b/native_implemented/otp/src/erlang/unique_integer/options.rs
index 2d43a1a56..be9be3ee0 100644
--- a/native_implemented/otp/src/erlang/unique_integer/options.rs
+++ b/native_implemented/otp/src/erlang/unique_integer/options.rs
@@ -2,7 +2,8 @@ use std::convert::{TryFrom, TryInto};
 
 use anyhow::*;
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::*;
+use firefly_rt::term::Term;
 
 use crate::runtime::proplist::*;
 
@@ -26,7 +27,7 @@ impl Options {
     fn put_option_term(&mut self, option: Term) -> Result<&Self, anyhow::Error> {
         let atom: Atom = option.try_into().context(SUPPORTED_OPTION_CONTEXT)?;
 
-        match atom.name() {
+        match atom.as_str() {
             "monotonic" => {
                 self.monotonic = true;
 
@@ -50,11 +51,12 @@ impl TryFrom<Term> for Options {
         let mut options_term = term;
 
         loop {
-            match options_term.decode().unwrap() {
-                TypedTerm::Nil => return Ok(options),
-                TypedTerm::List(cons) => {
-                    options.put_option_term(cons.head)?;
-                    options_term = cons.tail;
+            match options_term {
+                Term::Nil => return Ok(options),
+                Term::Cons(non_null_cons) => {
+                    let cons = unsafe { non_null_cons.as_ref() };
+                    options.put_option_term(cons.head())?;
+                    options_term = cons.tail();
 
                     continue;
                 }
diff --git a/native_implemented/otp/src/erlang/unique_integer_0.rs b/native_implemented/otp/src/erlang/unique_integer_0.rs
index 88d0013b1..b392d7629 100644
--- a/native_implemented/otp/src/erlang/unique_integer_0.rs
+++ b/native_implemented/otp/src/erlang/unique_integer_0.rs
@@ -1,8 +1,8 @@
 #[cfg(test)]
 mod test;
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::unique_integer::unique_integer;
 
diff --git a/native_implemented/otp/src/erlang/unique_integer_0/test.rs b/native_implemented/otp/src/erlang/unique_integer_0/test.rs
index db56a3cfa..d62ab1856 100644
--- a/native_implemented/otp/src/erlang/unique_integer_0/test.rs
+++ b/native_implemented/otp/src/erlang/unique_integer_0/test.rs
@@ -1,14 +1,14 @@
 use crate::erlang::unique_integer_0::result;
 use crate::test::with_process;
 
-use liblumen_alloc::erts::term::prelude::Encoded;
+use firefly_rt::term::Term;
 
 #[test]
 fn returns_non_monotonic_negative_and_positive_integer() {
     with_process(|process| {
         let first_unique_integer = result(process);
 
-        let zero = process.integer(0);
+        let zero = process.integer(0).unwrap();
 
         assert!(first_unique_integer.is_integer());
         assert!(first_unique_integer <= zero);
diff --git a/native_implemented/otp/src/erlang/unique_integer_1.rs b/native_implemented/otp/src/erlang/unique_integer_1.rs
index 930e40610..3cfc5df74 100644
--- a/native_implemented/otp/src/erlang/unique_integer_1.rs
+++ b/native_implemented/otp/src/erlang/unique_integer_1.rs
@@ -3,14 +3,14 @@ mod test;
 
 use std::convert::TryInto;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::erlang::unique_integer::{unique_integer, Options};
 
 #[native_implemented::function(erlang:unique_integer/1)]
-pub fn result(process: &Process, options: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, options: Term) -> Result<Term, NonNull<ErlangException>> {
     let options_options: Options = options.try_into()?;
 
     Ok(unique_integer(process, options_options))
diff --git a/native_implemented/otp/src/erlang/unique_integer_1/test.rs b/native_implemented/otp/src/erlang/unique_integer_1/test.rs
index e9ffd056d..b8ba6f151 100644
--- a/native_implemented/otp/src/erlang/unique_integer_1/test.rs
+++ b/native_implemented/otp/src/erlang/unique_integer_1/test.rs
@@ -1,7 +1,6 @@
-use proptest::strategy::{Just, Strategy};
+use proptest::strategy::Just;
 
-use liblumen_alloc::atom;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::{atoms, Atom, Term};
 
 use crate::erlang::unique_integer_1::result;
 use crate::test::strategy;
@@ -15,15 +14,15 @@ fn without_proper_list_of_options_errors_badargs() {
                 Just(arc_process.clone()),
                 strategy::term(arc_process.clone()).prop_filter(
                     "Cannot be a proper list of valid options",
-                    |term| match term.decode().unwrap() {
-                        TypedTerm::Nil => false,
-                        TypedTerm::List(cons) => {
+                    |term| match term {
+                        Term::Nil => false,
+                        Term::Cons(cons) => {
                             let mut filter = true;
 
                             for result in cons.into_iter() {
                                 match result {
-                                    Ok(element) => match element.decode().unwrap() {
-                                        TypedTerm::Atom(atom) => match atom.name() {
+                                    Ok(element) => match element {
+                                        Term::Atom(atom) => match atom.as_str() {
                                             "monotonic" | "positive" => {
                                                 filter = false;
 
@@ -54,7 +53,7 @@ fn without_proper_list_of_options_errors_badargs() {
 
 #[test]
 fn without_options_returns_non_monotonic_negative_and_positive_integer() {
-    const OPTIONS: Term = Term::NIL;
+    const OPTIONS: Term = Term::Nil;
 
     with_process(|process| {
         let result_first_unique_integer = result(process, OPTIONS);
@@ -62,7 +61,7 @@ fn without_options_returns_non_monotonic_negative_and_positive_integer() {
         assert!(result_first_unique_integer.is_ok());
 
         let first_unique_integer = result_first_unique_integer.unwrap();
-        let zero = process.integer(0);
+        let zero = process.integer(0).unwrap();
 
         assert!(first_unique_integer.is_integer());
         assert!(first_unique_integer <= zero);
@@ -83,14 +82,14 @@ fn without_options_returns_non_monotonic_negative_and_positive_integer() {
 #[test]
 fn with_monotonic_returns_monotonic_negative_and_positiver_integer() {
     with_process(|process| {
-        let options = process.list_from_slice(&[atom!("monotonic")]);
+        let options = process.list_from_slice(&[atoms::Monotonic.into()]).unwrap();
 
         let result_first_unique_integer = result(process, options);
 
         assert!(result_first_unique_integer.is_ok());
 
         let first_unique_integer = result_first_unique_integer.unwrap();
-        let zero = process.integer(0);
+        let zero = process.integer(0).unwrap();
 
         assert!(first_unique_integer.is_integer());
         assert!(first_unique_integer <= zero);
@@ -111,14 +110,14 @@ fn with_monotonic_returns_monotonic_negative_and_positiver_integer() {
 #[test]
 fn with_monotonic_and_positive_returns_monotonic_positiver_integer() {
     with_process(|process| {
-        let options = process.list_from_slice(&[atom!("monotonic"), atom!("positive")]);
+        let options = process.list_from_slice(&[atoms::Monotonic.into(), atoms::Positive.into()]).unwrap();
 
         let result_first_unique_integer = result(process, options);
 
         assert!(result_first_unique_integer.is_ok());
 
         let first_unique_integer = result_first_unique_integer.unwrap();
-        let zero = process.integer(0);
+        let zero = process.integer(0).unwrap();
 
         assert!(first_unique_integer.is_integer());
         assert!(zero <= first_unique_integer);
@@ -139,14 +138,14 @@ fn with_monotonic_and_positive_returns_monotonic_positiver_integer() {
 #[test]
 fn with_positive_returns_non_monotonic_and_positive_integer() {
     with_process(|process| {
-        let options = process.list_from_slice(&[atom!("positive")]);
+        let options = process.list_from_slice(&[Atom::str_to_term("positive").into()]).unwrap();
 
         let result_first_unique_integer = result(process, options);
 
         assert!(result_first_unique_integer.is_ok());
 
         let first_unique_integer = result_first_unique_integer.unwrap();
-        let zero = process.integer(0);
+        let zero = process.integer(0).unwrap();
 
         assert!(first_unique_integer.is_integer());
         assert!(zero <= first_unique_integer);
diff --git a/native_implemented/otp/src/erlang/universaltime_0.rs b/native_implemented/otp/src/erlang/universaltime_0.rs
index 46cdf5ba5..6c1985e24 100644
--- a/native_implemented/otp/src/erlang/universaltime_0.rs
+++ b/native_implemented/otp/src/erlang/universaltime_0.rs
@@ -1,24 +1,25 @@
 #[cfg(test)]
 mod test;
 
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
+
 use crate::runtime::time::datetime;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
 
 #[native_implemented::function(erlang:universaltime/0)]
 pub fn result(process: &Process) -> Term {
     let now: [usize; 6] = datetime::utc_now();
 
-    let date_tuple = process.tuple_from_slice(&[
-        process.integer(now[0]),
-        process.integer(now[1]),
-        process.integer(now[2]),
+    let date_tuple = process.tuple_term_from_term_slice(&[
+        process.integer(now[0]).unwrap(),
+        process.integer(now[1]).unwrap(),
+        process.integer(now[2]).unwrap(),
     ]);
-    let time_tuple = process.tuple_from_slice(&[
-        process.integer(now[3]),
-        process.integer(now[4]),
-        process.integer(now[5]),
+    let time_tuple = process.tuple_term_from_term_slice(&[
+        process.integer(now[3]).unwrap(),
+        process.integer(now[4]).unwrap(),
+        process.integer(now[5]).unwrap(),
     ]);
 
-    process.tuple_from_slice(&[date_tuple, time_tuple])
+    process.tuple_term_from_term_slice(&[date_tuple, time_tuple])
 }
diff --git a/native_implemented/otp/src/erlang/unlink_1.rs b/native_implemented/otp/src/erlang/unlink_1.rs
index e9ca9da6d..6129bdc93 100644
--- a/native_implemented/otp/src/erlang/unlink_1.rs
+++ b/native_implemented/otp/src/erlang/unlink_1.rs
@@ -1,18 +1,20 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
+use std::ptr::NonNull;
+
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::runtime::registry::pid_to_process;
 
 #[native_implemented::function(erlang:unlink/1)]
-fn result(process: &Process, pid_or_port: Term) -> exception::Result<Term> {
-    match pid_or_port.decode().unwrap() {
-        TypedTerm::Pid(pid) => {
+fn result(process: &Process, pid_or_port: Term) -> Result<Term, NonNull<ErlangException>> {
+    match pid_or_port {
+        Term::Pid(pid) => {
             if pid == process.pid() {
                 Ok(true.into())
             } else {
@@ -26,9 +28,7 @@ fn result(process: &Process, pid_or_port: Term) -> exception::Result<Term> {
                 Ok(true.into())
             }
         }
-        TypedTerm::Port(_) => unimplemented!(),
-        TypedTerm::ExternalPid(_) => unimplemented!(),
-        TypedTerm::ExternalPort(_) => unimplemented!(),
+        Term::Port(_) => unimplemented!(),
         _ => Err(TypeError)
             .context(format!(
                 "pid_or_port ({}) is neither a pid nor a port",
diff --git a/native_implemented/otp/src/erlang/unlink_1/test.rs b/native_implemented/otp/src/erlang/unlink_1/test.rs
index 61dbadc64..b3ddabfc0 100644
--- a/native_implemented/otp/src/erlang/unlink_1/test.rs
+++ b/native_implemented/otp/src/erlang/unlink_1/test.rs
@@ -2,8 +2,8 @@ mod with_local_pid;
 
 use proptest::strategy::{Just, Strategy};
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Encoded;
+use firefly_rt::process::Process;
+use firefly_rt::term::Atom;
 
 use crate::erlang::unlink_1::result;
 use crate::test::strategy;
diff --git a/native_implemented/otp/src/erlang/unlink_1/test/with_local_pid.rs b/native_implemented/otp/src/erlang/unlink_1/test/with_local_pid.rs
index c0790eb9e..b61caed53 100644
--- a/native_implemented/otp/src/erlang/unlink_1/test/with_local_pid.rs
+++ b/native_implemented/otp/src/erlang/unlink_1/test/with_local_pid.rs
@@ -1,7 +1,5 @@
 use super::*;
 
-use liblumen_alloc::erts::term::prelude::{Atom, Pid};
-
 use crate::runtime::scheduler;
 
 use crate::test;
diff --git a/native_implemented/otp/src/erlang/unregister_1.rs b/native_implemented/otp/src/erlang/unregister_1.rs
index 69051931f..c61f0f1de 100644
--- a/native_implemented/otp/src/erlang/unregister_1.rs
+++ b/native_implemented/otp/src/erlang/unregister_1.rs
@@ -1,15 +1,17 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
+use std::ptr::NonNull;
+
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::Term;
 
 use crate::runtime::registry;
 
 #[native_implemented::function(erlang:unregister/1)]
-pub fn result(name: Term) -> exception::Result<Term> {
+pub fn result(name: Term) -> Result<Term, NonNull<ErlangException>> {
     let atom = term_try_into_atom!(name)?;
 
     if registry::unregister(&atom) {
diff --git a/native_implemented/otp/src/erlang/unregister_1/test.rs b/native_implemented/otp/src/erlang/unregister_1/test.rs
index 93e7543a4..45a87b3c3 100644
--- a/native_implemented/otp/src/erlang/unregister_1/test.rs
+++ b/native_implemented/otp/src/erlang/unregister_1/test.rs
@@ -1,11 +1,7 @@
 mod with_atom_name;
 
-use std::convert::TryInto;
-
 use proptest::test_runner::{Config, TestRunner};
 
-use liblumen_alloc::erts::term::prelude::*;
-
 use crate::runtime::registry;
 
 use crate::erlang;
diff --git a/native_implemented/otp/src/erlang/whereis_1.rs b/native_implemented/otp/src/erlang/whereis_1.rs
index d5e264c3f..06320e8cd 100644
--- a/native_implemented/otp/src/erlang/whereis_1.rs
+++ b/native_implemented/otp/src/erlang/whereis_1.rs
@@ -1,20 +1,20 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::atom;
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::term::prelude::*;
+use std::ptr::NonNull;
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::{atoms, Term};
 
 use crate::runtime::registry;
 
 #[native_implemented::function(erlang:whereis/1)]
-pub fn result(name: Term) -> exception::Result<Term> {
+pub fn result(name: Term) -> Result<Term, NonNull<ErlangException>> {
     let atom = term_try_into_atom!(name)?;
     let option = registry::atom_to_process(&atom).map(|arc_process| arc_process.pid());
 
     let term = match option {
         Some(pid) => pid.encode()?,
-        None => atom!("undefined"),
+        None => atoms::Undefined.into(),
     };
 
     Ok(term)
diff --git a/native_implemented/otp/src/erlang/whereis_1/test.rs b/native_implemented/otp/src/erlang/whereis_1/test.rs
index 5a100d55d..3be3d8835 100644
--- a/native_implemented/otp/src/erlang/whereis_1/test.rs
+++ b/native_implemented/otp/src/erlang/whereis_1/test.rs
@@ -2,8 +2,6 @@ mod with_atom_name;
 
 use proptest::test_runner::{Config, TestRunner};
 
-use liblumen_alloc::erts::term::prelude::*;
-
 use crate::erlang;
 use crate::erlang::whereis_1::result;
 use crate::test::with_process_arc;
diff --git a/native_implemented/otp/src/erlang/xor_2.rs b/native_implemented/otp/src/erlang/xor_2.rs
index 225bcffcf..455ecd62b 100644
--- a/native_implemented/otp/src/erlang/xor_2.rs
+++ b/native_implemented/otp/src/erlang/xor_2.rs
@@ -1,13 +1,15 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::term::prelude::*;
+use std::ptr::NonNull;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::Term;
 
 /// `xor/2` infix operator.
 ///
 /// **NOTE: NOT SHORT-CIRCUITING!**
 #[native_implemented::function(erlang:xor/2)]
-pub fn result(left_boolean: Term, right_boolean: Term) -> exception::Result<Term> {
+pub fn result(left_boolean: Term, right_boolean: Term) -> Result<Term, NonNull<ErlangException>> {
     boolean_infix_operator!(left_boolean, right_boolean, ^)
 }
diff --git a/native_implemented/otp/src/lib.rs b/native_implemented/otp/src/lib.rs
index 1e9d9eb8d..240b20ac6 100644
--- a/native_implemented/otp/src/lib.rs
+++ b/native_implemented/otp/src/lib.rs
@@ -12,10 +12,8 @@ pub mod lists;
 pub mod lumen;
 pub mod maps;
 pub mod number;
-#[cfg(not(test))]
-use lumen_rt_core as runtime;
-#[cfg(test)]
-use lumen_rt_full as runtime;
+mod proplist;
+use firefly_rt_tiny as runtime;
 pub mod timer;
 
 #[cfg(test)]
diff --git a/native_implemented/otp/src/lists.rs b/native_implemented/otp/src/lists.rs
index 993f28197..518f06f3d 100644
--- a/native_implemented/otp/src/lists.rs
+++ b/native_implemented/otp/src/lists.rs
@@ -6,8 +6,6 @@ pub mod member_2;
 pub mod reverse_1;
 pub mod reverse_2;
 
-use liblumen_alloc::erts::term::prelude::Atom;
-
 fn module() -> Atom {
     Atom::from_str("lists")
 }
diff --git a/native_implemented/otp/src/lists/keyfind_3.rs b/native_implemented/otp/src/lists/keyfind_3.rs
index 08a24ecda..525c2306c 100644
--- a/native_implemented/otp/src/lists/keyfind_3.rs
+++ b/native_implemented/otp/src/lists/keyfind_3.rs
@@ -1,20 +1,22 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
+use std::ptr::NonNull;
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::*;
+use firefly_rt::term::Term;
 
 use crate::runtime::context::term_try_into_one_based_index;
 
 #[native_implemented::function(lists:keyfind/3)]
-pub fn result(key: Term, index: Term, tuple_list: Term) -> exception::Result<Term> {
+pub fn result(key: Term, index: Term, tuple_list: Term) -> Result<Term, NonNull<ErlangException>> {
     let index = term_try_into_one_based_index(index)?;
 
-    match tuple_list.decode()? {
-        TypedTerm::Nil => Ok(false.into()),
-        TypedTerm::List(cons) => match cons.keyfind(index, key)? {
+    match tuple_list {
+        Term::Nil => Ok(false.into()),
+        Term::Cons(cons) => match cons.keyfind(index, key)? {
             Some(found) => Ok(found),
             None => Ok(false.into()),
         },
diff --git a/native_implemented/otp/src/lists/keyfind_3/test.rs b/native_implemented/otp/src/lists/keyfind_3/test.rs
index d4b1e0fd3..9ac61923e 100644
--- a/native_implemented/otp/src/lists/keyfind_3/test.rs
+++ b/native_implemented/otp/src/lists/keyfind_3/test.rs
@@ -1,10 +1,10 @@
 mod with_one_based_index;
 
 use proptest::prop_assert_eq;
-use proptest::strategy::{Just, Strategy};
+use proptest::strategy::Just;
 use proptest::test_runner::{Config, TestRunner};
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::{Atom, Term};
 
 use crate::lists::keyfind_3::result;
 use crate::test::strategy;
diff --git a/native_implemented/otp/src/lists/keyfind_3/test/with_one_based_index.rs b/native_implemented/otp/src/lists/keyfind_3/test/with_one_based_index.rs
index f4e99b817..6e976f40b 100644
--- a/native_implemented/otp/src/lists/keyfind_3/test/with_one_based_index.rs
+++ b/native_implemented/otp/src/lists/keyfind_3/test/with_one_based_index.rs
@@ -13,7 +13,7 @@ fn with_empty_tuple_list_returns_false() {
                     strategy::term::index::is_one_based(arc_process.clone()),
                 ),
                 |(key, one_based_index)| {
-                    let tuple_list = Term::NIL;
+                    let tuple_list = Term::Nil;
 
                     prop_assert_eq!(result(key, one_based_index, tuple_list), Ok(false.into()));
 
diff --git a/native_implemented/otp/src/lists/keyfind_3/test/with_one_based_index/with_improper_list.rs b/native_implemented/otp/src/lists/keyfind_3/test/with_one_based_index/with_improper_list.rs
index 211b2f344..e22068a4b 100644
--- a/native_implemented/otp/src/lists/keyfind_3/test/with_one_based_index/with_improper_list.rs
+++ b/native_implemented/otp/src/lists/keyfind_3/test/with_one_based_index/with_improper_list.rs
@@ -4,8 +4,8 @@ use super::*;
 fn without_found_errors_badarg() {
     with_process_arc(|arc_process| {
         let key = Atom::str_to_term("not_found");
-        let one_based_index = arc_process.integer(1);
-        let slice = &[arc_process.tuple_from_slice(&[])];
+        let one_based_index = arc_process.integer(1).unwrap();
+        let slice = &[arc_process.tuple_term_from_term_slice(&[])];
         let tail = Atom::str_to_term("tail");
         let tuple_list = arc_process.improper_list_from_slice(slice, tail);
 
@@ -27,14 +27,14 @@ fn with_non_tuple_in_list_with_found_returns_tuple() {
                 .prop_map(
                     |(arc_process, before_key_vec, key, after_key_vec, non_tuple)| {
                         let index_zero_based_usize = before_key_vec.len() + 1;
-                        let index_one_based_term = arc_process.integer(index_zero_based_usize);
+                        let index_one_based_term = arc_process.integer(index_zero_based_usize).unwrap();
 
                         let mut tuple_with_key_element_vec = Vec::new();
                         tuple_with_key_element_vec.extend_from_slice(&before_key_vec);
                         tuple_with_key_element_vec.push(key);
                         tuple_with_key_element_vec.extend_from_slice(&after_key_vec);
                         let tuple_with_key =
-                            arc_process.tuple_from_slice(&tuple_with_key_element_vec);
+                            arc_process.tuple_term_from_term_slice(&tuple_with_key_element_vec);
 
                         let tail = Atom::str_to_term("tail");
                         let tuple_list = arc_process
@@ -81,14 +81,14 @@ fn with_shorter_tuple_in_list_with_found_returns_tuple() {
                 .prop_map(
                     |(arc_process, before_key_vec, key, after_key_vec, short_tuple)| {
                         let index_zero_based_usize = before_key_vec.len() + 1;
-                        let index_one_based_term = arc_process.integer(index_zero_based_usize);
+                        let index_one_based_term = arc_process.integer(index_zero_based_usize).unwrap();
 
                         let mut tuple_with_key_element_vec = Vec::new();
                         tuple_with_key_element_vec.extend_from_slice(&before_key_vec);
                         tuple_with_key_element_vec.push(key);
                         tuple_with_key_element_vec.extend_from_slice(&after_key_vec);
                         let tuple_with_key =
-                            arc_process.tuple_from_slice(&tuple_with_key_element_vec);
+                            arc_process.tuple_term_from_term_slice(&tuple_with_key_element_vec);
 
                         let tail = Atom::str_to_term("tail");
                         let tuple_list = arc_process
@@ -110,8 +110,8 @@ fn with_shorter_tuple_in_list_with_found_returns_tuple() {
 fn with_found_returns_tuple() {
     with_process_arc(|arc_process| {
         let key = Atom::str_to_term("found");
-        let one_based_index = arc_process.integer(1);
-        let element = arc_process.tuple_from_slice(&[key]);
+        let one_based_index = arc_process.integer(1).unwrap();
+        let element = arc_process.tuple_term_from_term_slice(&[key]);
         let slice = &[element];
         let tail = Atom::str_to_term("tail");
         let tuple_list = arc_process.improper_list_from_slice(slice, tail);
diff --git a/native_implemented/otp/src/lists/keyfind_3/test/with_one_based_index/with_proper_non_empty_list.rs b/native_implemented/otp/src/lists/keyfind_3/test/with_one_based_index/with_proper_non_empty_list.rs
index 6d2d9de39..dbf8f2a6f 100644
--- a/native_implemented/otp/src/lists/keyfind_3/test/with_one_based_index/with_proper_non_empty_list.rs
+++ b/native_implemented/otp/src/lists/keyfind_3/test/with_one_based_index/with_proper_non_empty_list.rs
@@ -4,9 +4,9 @@ use super::*;
 fn without_found_returns_false() {
     with_process_arc(|arc_process| {
         let key = Atom::str_to_term("not_found");
-        let one_based_index = arc_process.integer(1);
-        let slice = &[arc_process.tuple_from_slice(&[])];
-        let tuple_list = arc_process.list_from_slice(slice);
+        let one_based_index = arc_process.integer(1).unwrap();
+        let slice = &[arc_process.tuple_term_from_term_slice(&[])];
+        let tuple_list = arc_process.list_from_slice(slice).unwrap();
 
         assert_eq!(result(key, one_based_index, tuple_list), Ok(false.into()));
     });
@@ -26,16 +26,16 @@ fn with_non_tuple_in_list_with_found_returns_tuple() {
                 .prop_map(
                     |(arc_process, before_key_vec, key, after_key_vec, non_tuple)| {
                         let index_zero_based_usize = before_key_vec.len() + 1;
-                        let index_one_based_term = arc_process.integer(index_zero_based_usize);
+                        let index_one_based_term = arc_process.integer(index_zero_based_usize).unwrap();
 
                         let mut tuple_with_key_element_vec = Vec::new();
                         tuple_with_key_element_vec.extend_from_slice(&before_key_vec);
                         tuple_with_key_element_vec.push(key);
                         tuple_with_key_element_vec.extend_from_slice(&after_key_vec);
                         let tuple_with_key =
-                            arc_process.tuple_from_slice(&tuple_with_key_element_vec);
+                            arc_process.tuple_term_from_term_slice(&tuple_with_key_element_vec);
 
-                        let tuple_list = arc_process.list_from_slice(&[non_tuple, tuple_with_key]);
+                        let tuple_list = arc_process.list_from_slice(&[non_tuple, tuple_with_key]).unwrap();
 
                         (key, index_one_based_term, tuple_list, tuple_with_key)
                     },
@@ -78,17 +78,17 @@ fn with_shorter_tuple_in_list_with_found_returns_tuple() {
                 .prop_map(
                     |(arc_process, before_key_vec, key, after_key_vec, short_tuple)| {
                         let index_zero_based_usize = before_key_vec.len() + 1;
-                        let index_one_based_term = arc_process.integer(index_zero_based_usize);
+                        let index_one_based_term = arc_process.integer(index_zero_based_usize).unwrap();
 
                         let mut tuple_with_key_element_vec = Vec::new();
                         tuple_with_key_element_vec.extend_from_slice(&before_key_vec);
                         tuple_with_key_element_vec.push(key);
                         tuple_with_key_element_vec.extend_from_slice(&after_key_vec);
                         let tuple_with_key =
-                            arc_process.tuple_from_slice(&tuple_with_key_element_vec);
+                            arc_process.tuple_term_from_term_slice(&tuple_with_key_element_vec);
 
                         let tuple_list =
-                            arc_process.list_from_slice(&[short_tuple, tuple_with_key]);
+                            arc_process.list_from_slice(&[short_tuple, tuple_with_key]).unwrap();
 
                         (key, index_one_based_term, tuple_list, tuple_with_key)
                     },
@@ -106,10 +106,10 @@ fn with_shorter_tuple_in_list_with_found_returns_tuple() {
 fn with_found_returns_tuple() {
     with_process_arc(|arc_process| {
         let key = Atom::str_to_term("found");
-        let one_based_index = arc_process.integer(1);
-        let element = arc_process.tuple_from_slice(&[key]);
+        let one_based_index = arc_process.integer(1).unwrap();
+        let element = arc_process.tuple_term_from_term_slice(&[key]);
         let slice = &[element];
-        let tuple_list = arc_process.list_from_slice(slice);
+        let tuple_list = arc_process.list_from_slice(slice).unwrap();
 
         assert_eq!(result(key, one_based_index, tuple_list), Ok(element));
     });
diff --git a/native_implemented/otp/src/lists/keymember_3.rs b/native_implemented/otp/src/lists/keymember_3.rs
index 799ac0b81..a4a325f8c 100644
--- a/native_implemented/otp/src/lists/keymember_3.rs
+++ b/native_implemented/otp/src/lists/keymember_3.rs
@@ -1,20 +1,22 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
+use std::ptr::NonNull;
+
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::Term;
 
 use crate::runtime::context::*;
 
 #[native_implemented::function(lists:keymember/3)]
-pub fn result(key: Term, index: Term, tuple_list: Term) -> exception::Result<Term> {
+pub fn result(key: Term, index: Term, tuple_list: Term) -> Result<Term, NonNull<ErlangException>> {
     let index = term_try_into_one_based_index(index)?;
 
-    match tuple_list.decode()? {
-        TypedTerm::Nil => Ok(false.into()),
-        TypedTerm::List(cons) => match cons.keyfind(index, key)? {
+    match tuple_list {
+        Term::Nil => Ok(false.into()),
+        Term::Cons(cons) => match cons.keyfind(index, key)? {
             Some(_) => Ok(true.into()),
             None => Ok(false.into()),
         },
diff --git a/native_implemented/otp/src/lists/keymember_3/test.rs b/native_implemented/otp/src/lists/keymember_3/test.rs
index 92223ecfd..75a2eddf8 100644
--- a/native_implemented/otp/src/lists/keymember_3/test.rs
+++ b/native_implemented/otp/src/lists/keymember_3/test.rs
@@ -1,10 +1,10 @@
 mod with_one_based_index;
 
 use proptest::prop_assert_eq;
-use proptest::strategy::{Just, Strategy};
+use proptest::strategy::Just;
 use proptest::test_runner::{Config, TestRunner};
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 use crate::lists::keymember_3::result;
 use crate::test::strategy;
diff --git a/native_implemented/otp/src/lists/keymember_3/test/with_one_based_index.rs b/native_implemented/otp/src/lists/keymember_3/test/with_one_based_index.rs
index f4e99b817..6e976f40b 100644
--- a/native_implemented/otp/src/lists/keymember_3/test/with_one_based_index.rs
+++ b/native_implemented/otp/src/lists/keymember_3/test/with_one_based_index.rs
@@ -13,7 +13,7 @@ fn with_empty_tuple_list_returns_false() {
                     strategy::term::index::is_one_based(arc_process.clone()),
                 ),
                 |(key, one_based_index)| {
-                    let tuple_list = Term::NIL;
+                    let tuple_list = Term::Nil;
 
                     prop_assert_eq!(result(key, one_based_index, tuple_list), Ok(false.into()));
 
diff --git a/native_implemented/otp/src/lists/keymember_3/test/with_one_based_index/with_improper_list.rs b/native_implemented/otp/src/lists/keymember_3/test/with_one_based_index/with_improper_list.rs
index 0dd1e3c47..9b42e6f38 100644
--- a/native_implemented/otp/src/lists/keymember_3/test/with_one_based_index/with_improper_list.rs
+++ b/native_implemented/otp/src/lists/keymember_3/test/with_one_based_index/with_improper_list.rs
@@ -4,8 +4,8 @@ use super::*;
 fn without_found_errors_badarg() {
     with_process_arc(|arc_process| {
         let key = Atom::str_to_term("not_found");
-        let one_based_index = arc_process.integer(1);
-        let slice = &[arc_process.tuple_from_slice(&[])];
+        let one_based_index = arc_process.integer(1).unwrap();
+        let slice = &[arc_process.tuple_term_from_term_slice(&[])];
         let tail = Atom::str_to_term("tail");
         let tuple_list = arc_process.improper_list_from_slice(slice, tail);
 
@@ -27,14 +27,14 @@ fn with_non_tuple_in_list_with_found_returns_true() {
                 .prop_map(
                     |(arc_process, before_key_vec, key, after_key_vec, non_tuple)| {
                         let index_zero_based_usize = before_key_vec.len() + 1;
-                        let index_one_based_term = arc_process.integer(index_zero_based_usize);
+                        let index_one_based_term = arc_process.integer(index_zero_based_usize).unwrap();
 
                         let mut tuple_with_key_element_vec = Vec::new();
                         tuple_with_key_element_vec.extend_from_slice(&before_key_vec);
                         tuple_with_key_element_vec.push(key);
                         tuple_with_key_element_vec.extend_from_slice(&after_key_vec);
                         let tuple_with_key =
-                            arc_process.tuple_from_slice(&tuple_with_key_element_vec);
+                            arc_process.tuple_term_from_term_slice(&tuple_with_key_element_vec);
 
                         let tail = Atom::str_to_term("tail");
                         let tuple_list = arc_process
@@ -81,14 +81,14 @@ fn with_shorter_tuple_in_list_with_found_returns_true() {
                 .prop_map(
                     |(arc_process, before_key_vec, key, after_key_vec, short_tuple)| {
                         let index_zero_based_usize = before_key_vec.len() + 1;
-                        let index_one_based_term = arc_process.integer(index_zero_based_usize);
+                        let index_one_based_term = arc_process.integer(index_zero_based_usize).unwrap();
 
                         let mut tuple_with_key_element_vec = Vec::new();
                         tuple_with_key_element_vec.extend_from_slice(&before_key_vec);
                         tuple_with_key_element_vec.push(key);
                         tuple_with_key_element_vec.extend_from_slice(&after_key_vec);
                         let tuple_with_key =
-                            arc_process.tuple_from_slice(&tuple_with_key_element_vec);
+                            arc_process.tuple_term_from_term_slice(&tuple_with_key_element_vec);
 
                         let tail = Atom::str_to_term("tail");
                         let tuple_list = arc_process
@@ -110,8 +110,8 @@ fn with_shorter_tuple_in_list_with_found_returns_true() {
 fn with_found_returns_true() {
     with_process_arc(|arc_process| {
         let key = Atom::str_to_term("found");
-        let one_based_index = arc_process.integer(1);
-        let element = arc_process.tuple_from_slice(&[key]);
+        let one_based_index = arc_process.integer(1).unwrap();
+        let element = arc_process.tuple_term_from_term_slice(&[key]);
         let slice = &[element];
         let tail = Atom::str_to_term("tail");
         let tuple_list = arc_process.improper_list_from_slice(slice, tail);
diff --git a/native_implemented/otp/src/lists/keymember_3/test/with_one_based_index/with_proper_non_empty_list.rs b/native_implemented/otp/src/lists/keymember_3/test/with_one_based_index/with_proper_non_empty_list.rs
index a8998af26..e4dbc5cb3 100644
--- a/native_implemented/otp/src/lists/keymember_3/test/with_one_based_index/with_proper_non_empty_list.rs
+++ b/native_implemented/otp/src/lists/keymember_3/test/with_one_based_index/with_proper_non_empty_list.rs
@@ -4,9 +4,9 @@ use super::*;
 fn without_found_returns_false() {
     with_process_arc(|arc_process| {
         let key = Atom::str_to_term("not_found");
-        let one_based_index = arc_process.integer(1);
-        let slice = &[arc_process.tuple_from_slice(&[])];
-        let tuple_list = arc_process.list_from_slice(slice);
+        let one_based_index = arc_process.integer(1).unwrap();
+        let slice = &[arc_process.tuple_term_from_term_slice(&[])];
+        let tuple_list = arc_process.list_from_slice(slice).unwrap();
 
         assert_eq!(result(key, one_based_index, tuple_list), Ok(false.into()));
     });
@@ -26,16 +26,16 @@ fn with_non_tuple_in_list_with_found_returns_true() {
                 .prop_map(
                     |(arc_process, before_key_vec, key, after_key_vec, non_tuple)| {
                         let index_zero_based_usize = before_key_vec.len() + 1;
-                        let index_one_based_term = arc_process.integer(index_zero_based_usize);
+                        let index_one_based_term = arc_process.integer(index_zero_based_usize).unwrap();
 
                         let mut tuple_with_key_element_vec = Vec::new();
                         tuple_with_key_element_vec.extend_from_slice(&before_key_vec);
                         tuple_with_key_element_vec.push(key);
                         tuple_with_key_element_vec.extend_from_slice(&after_key_vec);
                         let tuple_with_key =
-                            arc_process.tuple_from_slice(&tuple_with_key_element_vec);
+                            arc_process.tuple_term_from_term_slice(&tuple_with_key_element_vec);
 
-                        let tuple_list = arc_process.list_from_slice(&[non_tuple, tuple_with_key]);
+                        let tuple_list = arc_process.list_from_slice(&[non_tuple, tuple_with_key]).unwrap();
 
                         (key, index_one_based_term, tuple_list)
                     },
@@ -78,17 +78,17 @@ fn with_shorter_tuple_in_list_with_found_returns_true() {
                 .prop_map(
                     |(arc_process, before_key_vec, key, after_key_vec, short_tuple)| {
                         let index_zero_based_usize = before_key_vec.len() + 1;
-                        let index_one_based_term = arc_process.integer(index_zero_based_usize);
+                        let index_one_based_term = arc_process.integer(index_zero_based_usize).unwrap();
 
                         let mut tuple_with_key_element_vec = Vec::new();
                         tuple_with_key_element_vec.extend_from_slice(&before_key_vec);
                         tuple_with_key_element_vec.push(key);
                         tuple_with_key_element_vec.extend_from_slice(&after_key_vec);
                         let tuple_with_key =
-                            arc_process.tuple_from_slice(&tuple_with_key_element_vec);
+                            arc_process.tuple_term_from_term_slice(&tuple_with_key_element_vec);
 
                         let tuple_list =
-                            arc_process.list_from_slice(&[short_tuple, tuple_with_key]);
+                            arc_process.list_from_slice(&[short_tuple, tuple_with_key]).unwrap();
 
                         (key, index_one_based_term, tuple_list)
                     },
@@ -106,10 +106,10 @@ fn with_shorter_tuple_in_list_with_found_returns_true() {
 fn with_found_returns_true() {
     with_process_arc(|arc_process| {
         let key = Atom::str_to_term("found");
-        let one_based_index = arc_process.integer(1);
-        let element = arc_process.tuple_from_slice(&[key]);
+        let one_based_index = arc_process.integer(1).unwrap();
+        let element = arc_process.tuple_term_from_term_slice(&[key]);
         let slice = &[element];
-        let tuple_list = arc_process.list_from_slice(slice);
+        let tuple_list = arc_process.list_from_slice(slice).unwrap();
 
         assert_eq!(result(key, one_based_index, tuple_list), Ok(true.into()));
     });
diff --git a/native_implemented/otp/src/lists/member_2.rs b/native_implemented/otp/src/lists/member_2.rs
index 1fb91bb4a..194a8ef4f 100644
--- a/native_implemented/otp/src/lists/member_2.rs
+++ b/native_implemented/otp/src/lists/member_2.rs
@@ -1,16 +1,17 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
+use std::ptr::NonNull;
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(lists:member/2)]
-pub fn result(element: Term, list: Term) -> exception::Result<Term> {
-    match list.decode()? {
-        TypedTerm::Nil => Ok(false.into()),
-        TypedTerm::List(cons) => {
+pub fn result(element: Term, list: Term) -> Result<Term, NonNull<ErlangException>> {
+    match list {
+        Term::Nil => Ok(false.into()),
+        Term::Cons(cons) => {
             for result in cons.into_iter() {
                 match result {
                     Ok(term) => {
diff --git a/native_implemented/otp/src/lists/member_2/test.rs b/native_implemented/otp/src/lists/member_2/test.rs
index 45736c808..730900983 100644
--- a/native_implemented/otp/src/lists/member_2/test.rs
+++ b/native_implemented/otp/src/lists/member_2/test.rs
@@ -4,7 +4,7 @@ mod with_proper_non_empty_list;
 use proptest::prop_assert_eq;
 use proptest::test_runner::{Config, TestRunner};
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 use crate::lists::member_2::result;
 use crate::test::strategy;
@@ -15,7 +15,7 @@ fn with_empty_list_returns_false() {
     with_process_arc(|arc_process| {
         TestRunner::new(Config::with_source_file(file!()))
             .run(&strategy::term(arc_process.clone()), |element| {
-                let list = Term::NIL;
+                let list = Term::Nil;
 
                 prop_assert_eq!(result(element, list), Ok(false.into()));
 
diff --git a/native_implemented/otp/src/lists/member_2/test/with_proper_non_empty_list.rs b/native_implemented/otp/src/lists/member_2/test/with_proper_non_empty_list.rs
index 617bbe914..fd0962775 100644
--- a/native_implemented/otp/src/lists/member_2/test/with_proper_non_empty_list.rs
+++ b/native_implemented/otp/src/lists/member_2/test/with_proper_non_empty_list.rs
@@ -5,7 +5,7 @@ fn without_found_returns_false() {
     with_process_arc(|arc_process| {
         let element = Atom::str_to_term("not_found");
         let slice = &[];
-        let list = arc_process.list_from_slice(slice);
+        let list = arc_process.list_from_slice(slice).unwrap();
 
         assert_eq!(result(element, list), Ok(false.into()));
     });
@@ -16,7 +16,7 @@ fn with_found_returns_true() {
     with_process_arc(|arc_process| {
         let element = Atom::str_to_term("found");
         let slice = &[element];
-        let list = arc_process.list_from_slice(slice);
+        let list = arc_process.list_from_slice(slice).unwrap();
 
         assert_eq!(result(element, list), Ok(true.into()));
     });
diff --git a/native_implemented/otp/src/lists/reverse_1.rs b/native_implemented/otp/src/lists/reverse_1.rs
index b0d2302f6..df986f92d 100644
--- a/native_implemented/otp/src/lists/reverse_1.rs
+++ b/native_implemented/otp/src/lists/reverse_1.rs
@@ -1,13 +1,13 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::lists::reverse_2;
 
 #[native_implemented::function(lists:reverse/1)]
-fn result(process: &Process, list: Term) -> exception::Result<Term> {
-    reverse_2::result(process, list, Term::NIL)
+fn result(process: &Process, list: Term) -> Result<Term, NonNull<ErlangException>> {
+    reverse_2::result(process, list, Term::Nil)
 }
diff --git a/native_implemented/otp/src/lists/reverse_1/test.rs b/native_implemented/otp/src/lists/reverse_1/test.rs
index 9af33ca94..ffef371d9 100644
--- a/native_implemented/otp/src/lists/reverse_1/test.rs
+++ b/native_implemented/otp/src/lists/reverse_1/test.rs
@@ -3,7 +3,7 @@ mod with_proper_list;
 use proptest::prop_assert_eq;
 use proptest::test_runner::{Config, TestRunner};
 
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::term::Term;
 
 use crate::lists::reverse_1::result;
 use crate::test::strategy;
diff --git a/native_implemented/otp/src/lists/reverse_1/test/with_proper_list.rs b/native_implemented/otp/src/lists/reverse_1/test/with_proper_list.rs
index 9ca253549..3f85ccb04 100644
--- a/native_implemented/otp/src/lists/reverse_1/test/with_proper_list.rs
+++ b/native_implemented/otp/src/lists/reverse_1/test/with_proper_list.rs
@@ -7,7 +7,7 @@ use crate::test::strategy::NON_EMPTY_RANGE_INCLUSIVE;
 #[test]
 fn with_empty_list_returns_empty_list() {
     with_process_arc(|arc_process| {
-        assert_eq!(result(&arc_process, Term::NIL), Ok(Term::NIL));
+        assert_eq!(result(&arc_process, Term::Nil), Ok(Term::Nil));
     });
 }
 
@@ -20,10 +20,10 @@ fn reverses_order_of_elements_of_list() {
             .run(
                 &proptest::collection::vec(strategy::term(arc_process.clone()), size_range),
                 |vec| {
-                    let list = arc_process.list_from_slice(&vec);
+                    let list = arc_process.list_from_slice(&vec).unwrap();
 
                     let reversed_vec: Vec<Term> = vec.iter().rev().copied().collect();
-                    let reversed = arc_process.list_from_slice(&reversed_vec);
+                    let reversed = arc_process.list_from_slice(&reversed_vec).unwrap();
 
                     prop_assert_eq!(result(&arc_process, list), Ok(reversed));
 
diff --git a/native_implemented/otp/src/lists/reverse_2.rs b/native_implemented/otp/src/lists/reverse_2.rs
index 881699211..2a5b742d3 100644
--- a/native_implemented/otp/src/lists/reverse_2.rs
+++ b/native_implemented/otp/src/lists/reverse_2.rs
@@ -1,17 +1,19 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
+use std::ptr::NonNull;
+
 use anyhow::*;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(lists:reverse/2)]
-pub fn result(process: &Process, list: Term, tail: Term) -> exception::Result<Term> {
-    match list.decode()? {
-        TypedTerm::Nil => Ok(tail),
-        TypedTerm::List(cons) => {
+pub fn result(process: &Process, list: Term, tail: Term) -> Result<Term, NonNull<ErlangException>> {
+    match list {
+        Term::Nil => Ok(tail),
+        Term::Cons(cons) => {
             let mut reversed = tail;
 
             for result in cons.into_iter() {
diff --git a/native_implemented/otp/src/lists/reverse_2/test.rs b/native_implemented/otp/src/lists/reverse_2/test.rs
index fc287edc0..1edb0d6a5 100644
--- a/native_implemented/otp/src/lists/reverse_2/test.rs
+++ b/native_implemented/otp/src/lists/reverse_2/test.rs
@@ -3,7 +3,7 @@ mod with_proper_list;
 use proptest::prop_assert_eq;
 use proptest::test_runner::{Config, TestRunner};
 
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::term::Term;
 
 use crate::lists::reverse_2::result;
 use crate::test::strategy;
diff --git a/native_implemented/otp/src/lists/reverse_2/test/with_proper_list.rs b/native_implemented/otp/src/lists/reverse_2/test/with_proper_list.rs
index 2e5905a99..260dc7af9 100644
--- a/native_implemented/otp/src/lists/reverse_2/test/with_proper_list.rs
+++ b/native_implemented/otp/src/lists/reverse_2/test/with_proper_list.rs
@@ -9,7 +9,7 @@ fn with_empty_list_returns_tail() {
     with_process_arc(|arc_process| {
         TestRunner::new(Config::with_source_file(file!()))
             .run(&strategy::term(arc_process.clone()), |tail| {
-                prop_assert_eq!(result(&arc_process, Term::NIL, tail), Ok(tail));
+                prop_assert_eq!(result(&arc_process, Term::Nil, tail), Ok(tail));
 
                 Ok(())
             })
@@ -29,7 +29,7 @@ fn reverses_order_of_elements_of_list_and_concatenate_tail() {
                     strategy::term(arc_process.clone()),
                 ),
                 |(vec, tail)| {
-                    let list = arc_process.list_from_slice(&vec);
+                    let list = arc_process.list_from_slice(&vec).unwrap();
 
                     let reversed_vec: Vec<Term> = vec.iter().rev().copied().collect();
                     let reversed_with_tail =
@@ -49,7 +49,7 @@ fn reverse_reverse_with_empty_list_tail_returns_original_list() {
     with_process_arc(|arc_process| {
         TestRunner::new(Config::with_source_file(file!()))
             .run(&strategy::term::list::proper(arc_process.clone()), |list| {
-                let tail = Term::NIL;
+                let tail = Term::Nil;
                 let reversed_with_tail = result(&arc_process, list, tail).unwrap();
 
                 prop_assert_eq!(result(&arc_process, reversed_with_tail, tail), Ok(list));
diff --git a/native_implemented/otp/src/lumen.rs b/native_implemented/otp/src/lumen.rs
index ba42ee11a..e7b0f0dd5 100644
--- a/native_implemented/otp/src/lumen.rs
+++ b/native_implemented/otp/src/lumen.rs
@@ -6,8 +6,9 @@ pub mod is_big_integer_1;
 pub mod is_small_integer_1;
 pub mod log_exit_1;
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::*;
+use firefly_rt::term::Atom;
 
 pub fn module() -> Atom {
-    Atom::from_str("lumen")
+    Atom::from_str("lumen").unwrap()
 }
diff --git a/native_implemented/otp/src/lumen/apply_apply_2_1.rs b/native_implemented/otp/src/lumen/apply_apply_2_1.rs
index 781308c83..e96ab09ad 100644
--- a/native_implemented/otp/src/lumen/apply_apply_2_1.rs
+++ b/native_implemented/otp/src/lumen/apply_apply_2_1.rs
@@ -1,18 +1,17 @@
 //! This is used as the `init_fn` for `Scheduler::spawn_closure`, as the spawning code can only
 //! pass at most 1 argument and `erlang:apply/2` takes two arguments
 use anyhow::anyhow;
+use firefly_rt::backtrace::Trace;
 
-use liblumen_alloc::erts::exception::{badarity, Exception};
-use liblumen_alloc::erts::process::ffi::ErlangResult;
-use liblumen_alloc::erts::process::trace::Trace;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::function::ErlangResult;
+use firefly_rt::term::{atoms, Term};
 
 use crate::erlang;
 use crate::erlang::apply::arguments_term_to_vec;
 
 #[export_name = "lumen:apply_apply_2/1"]
 pub extern "C-unwind" fn apply_apply_2(arguments: Term) -> ErlangResult {
-    let arc_process = crate::runtime::process::current_process();
+    let arc_process = runtime::process::current_process();
     let argument_vec = match arguments_term_to_vec(arguments) {
         Ok(args) => args,
         Err(err) => match err {
@@ -36,7 +35,7 @@ pub extern "C-unwind" fn apply_apply_2(arguments: Term) -> ErlangResult {
     } else {
         let function = arc_process.export_closure(
             erlang::module(),
-            Atom::from_str("apply"),
+            atoms::Apply,
             2,
             erlang::apply_2::CLOSURE_NATIVE,
         );
diff --git a/native_implemented/otp/src/lumen/apply_apply_3_1.rs b/native_implemented/otp/src/lumen/apply_apply_3_1.rs
index 51896a4d4..9de490186 100644
--- a/native_implemented/otp/src/lumen/apply_apply_3_1.rs
+++ b/native_implemented/otp/src/lumen/apply_apply_3_1.rs
@@ -2,17 +2,17 @@
 //! code can only pass at most 1 argument and `erlang:apply/3` takes three arguments
 use anyhow::anyhow;
 
-use liblumen_alloc::erts::exception::{badarity, Exception};
-use liblumen_alloc::erts::process::ffi::ErlangResult;
-use liblumen_alloc::erts::process::trace::Trace;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::*;
+use firefly_rt::backtrace::Trace;
+use firefly_rt::function::ErlangResult;
+use firefly_rt::term::{atoms, Term};
 
 use crate::erlang;
 use crate::erlang::apply::arguments_term_to_vec;
 
 #[export_name = "lumen:apply_apply_3/1"]
 pub extern "C-unwind" fn apply_apply_3(arguments: Term) -> ErlangResult {
-    let arc_process = crate::runtime::process::current_process();
+    let arc_process = runtime::process::current_process();
     let argument_vec = match arguments_term_to_vec(arguments) {
         Ok(args) => args,
         Err(err) => match err {
@@ -37,7 +37,7 @@ pub extern "C-unwind" fn apply_apply_3(arguments: Term) -> ErlangResult {
     } else {
         let function = arc_process.export_closure(
             erlang::module(),
-            Atom::from_str("apply"),
+            atoms::Apply,
             3,
             erlang::apply_3::CLOSURE_NATIVE,
         );
diff --git a/native_implemented/otp/src/lumen/is_big_integer_1.rs b/native_implemented/otp/src/lumen/is_big_integer_1.rs
index 422798877..bb93a27ca 100644
--- a/native_implemented/otp/src/lumen/is_big_integer_1.rs
+++ b/native_implemented/otp/src/lumen/is_big_integer_1.rs
@@ -1,9 +1,9 @@
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(lumen:is_big_integer/1)]
 pub fn result(term: Term) -> Term {
-    match term.decode() {
-        Ok(TypedTerm::BigInteger(_)) => true,
+    match term {
+        Term::BigInt(_) => true,
         _ => false,
     }
     .into()
diff --git a/native_implemented/otp/src/lumen/is_small_integer_1.rs b/native_implemented/otp/src/lumen/is_small_integer_1.rs
index 437c3d5e3..25c726f79 100644
--- a/native_implemented/otp/src/lumen/is_small_integer_1.rs
+++ b/native_implemented/otp/src/lumen/is_small_integer_1.rs
@@ -1,4 +1,5 @@
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::*;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(lumen:is_small_integer/1)]
 pub fn result(term: Term) -> Term {
diff --git a/native_implemented/otp/src/lumen/log_exit_1.rs b/native_implemented/otp/src/lumen/log_exit_1.rs
index 2defbb80b..f146a7a8d 100644
--- a/native_implemented/otp/src/lumen/log_exit_1.rs
+++ b/native_implemented/otp/src/lumen/log_exit_1.rs
@@ -1,10 +1,12 @@
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::term::prelude::*;
+use std::ptr::NonNull;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::Term;
 
 use crate::runtime::process::replace_log_exit;
 
 #[native_implemented::function(lumen:log_exit/1)]
-fn result(log_exit: Term) -> exception::Result<Term> {
+fn result(log_exit: Term) -> Result<Term, NonNull<ErlangException>> {
     let boolean_bool: bool = term_try_into_bool!(log_exit)?;
 
     Ok(replace_log_exit(boolean_bool).into())
diff --git a/native_implemented/otp/src/macros/exception.rs b/native_implemented/otp/src/macros/exception.rs
index a28b1b6b9..4602a4f5b 100644
--- a/native_implemented/otp/src/macros/exception.rs
+++ b/native_implemented/otp/src/macros/exception.rs
@@ -3,11 +3,10 @@ macro_rules! assert_badarg {
     ($actual:expr, $expected_substring:expr) => {{
         let actual = $actual;
 
-        if let Err(liblumen_alloc::erts::exception::Exception::Runtime(
-            liblumen_alloc::erts::exception::RuntimeException::Error(ref error),
-        )) = actual
+        if let Err(ref non_null_erlang_exception) = actual
         {
-            assert_eq!(error.reason(), liblumen_alloc::atom!("badarg"));
+            let erlang_exceptiion = unsafe { non_null_erlang_exception.as_ref() };
+            assert_eq!(erlang_exceptiion.reason(), firefly_rt::term::atoms::BadArg.into());
 
             let source_message = format!("{:?}", error.source());
             let expected_substring = $expected_substring;
@@ -41,9 +40,6 @@ macro_rules! assert_badarith {
 #[cfg(test)]
 macro_rules! assert_error {
     ($left:expr, $reason:expr) => {{
-        use liblumen_alloc::erts::exception::error;
-        use liblumen_alloc::erts::process::trace::Trace;
-
         assert_eq!(
             $left,
             Err(error(
@@ -56,18 +52,12 @@ macro_rules! assert_error {
         )
     }};
     ($left:expr, $reason:expr,) => {{
-        use liblumen_alloc::error;
-
         assert_eq!($left, Err(error!($reason).into()))
     }};
     ($left:expr, $reason:expr, $arguments:expr) => {{
-        use liblumen_alloc::error;
-
         assert_eq!($left, Err(error!($reason, $arguments).into()))
     }};
     ($left:expr, $reason:expr, $arguments:expr,) => {{
-        use liblumen_alloc::error;
-
         assert_eq!($left, Err(error!($reason, $arguments).into()))
     }};
 }
@@ -123,7 +113,7 @@ macro_rules! prop_assert_badarg {
         prop_assert_error!(
             $actual,
             "badarg",
-            liblumen_alloc::atom!("badarg"),
+            firefly_rt::term::atoms::Badarg,
             $expected_substring
         )
     }};
@@ -222,7 +212,7 @@ macro_rules! prop_assert_badarith {
         prop_assert_error!(
             $actual,
             "badarith",
-            liblumen_alloc::atom!("badarith"),
+            firefly_rt::term::atoms::Badarith.into(),
             $expected_substring
         )
     }};
@@ -234,7 +224,7 @@ macro_rules! prop_assert_badkey {
         prop_assert_error!(
             $actual,
             "badkey",
-            $process.tuple_from_slice(&[liblumen_alloc::atom!("badkey"), $expected_key]),
+            $process.tuple_term_from_term_slice(&[firefly_rt::term::atoms::Badkey.into(), $expected_key]),
             $expected_substring,
         )
     }};
@@ -258,7 +248,7 @@ macro_rules! prop_assert_badmap {
         prop_assert_error!(
             $actual,
             "badmap",
-            $process.tuple_from_slice(&[liblumen_alloc::atom!("badmap"), $expected_map]),
+            $process.tuple_term_from_term_slice(&[firefly_rt::term::atoms::Badmap.into(), $expected_map]),
             $expected_substring,
         )
     }};
diff --git a/native_implemented/otp/src/macros/integer.rs b/native_implemented/otp/src/macros/integer.rs
index 1dc9bdae5..bc4a64e63 100644
--- a/native_implemented/otp/src/macros/integer.rs
+++ b/native_implemented/otp/src/macros/integer.rs
@@ -5,52 +5,50 @@ macro_rules! bitwise_infix_operator {
         use anyhow::*;
         use num_bigint::BigInt;
 
-        use liblumen_alloc::erts::exception::*;
-        use liblumen_alloc::erts::process::trace::Trace;
-        use liblumen_alloc::erts::term::prelude::*;
+        use firefly_rt::*;
 
-        match ($left.decode().unwrap(), $right.decode().unwrap()) {
+        match ($left, $right) {
             (
-                TypedTerm::SmallInteger(left_small_integer),
-                TypedTerm::SmallInteger(right_small_integer),
+                Term::Int(left_small_integer),
+                Term::Int(right_small_integer),
             ) => {
                 let left_isize: isize = left_small_integer.into();
                 let right_isize: isize = right_small_integer.into();
                 let output = left_isize.$infix(right_isize);
-                let output_term = $process.integer(output);
+                let output_term = $process.integer(output).unwrap();
 
                 Ok(output_term)
             }
             (
-                TypedTerm::SmallInteger(left_small_integer),
-                TypedTerm::BigInteger(right_big_integer),
+                Term::Int(left_small_integer),
+                Term::BigInt(right_big_integer),
             ) => {
                 let left_big_int: BigInteger = left_small_integer.into();
                 let right_big_int = right_big_integer.as_ref();
 
                 let output_big_int: BigInt = left_big_int.$infix(right_big_int).into();
-                let output_term = $process.integer(output_big_int);
+                let output_term = $process.integer(output_big_int).unwrap();
 
                 Ok(output_term)
             }
             (
-                TypedTerm::BigInteger(left_big_integer),
-                TypedTerm::SmallInteger(right_small_integer),
+                Term::BigInt(left_big_integer),
+                Term::Int(right_small_integer),
             ) => {
                 let left_big_int = left_big_integer.as_ref();
                 let right_big_int: BigInteger = right_small_integer.into();
 
                 let output_big_int: BigInt = left_big_int.$infix(right_big_int).into();
-                let output_term = $process.integer(output_big_int);
+                let output_term = $process.integer(output_big_int).unwrap();
 
                 Ok(output_term)
             }
-            (TypedTerm::BigInteger(left_big_integer), TypedTerm::BigInteger(right_big_integer)) => {
+            (Term::BigInt(left_big_integer), Term::BigInt(right_big_integer)) => {
                 let left_big_int = left_big_integer.as_ref();
                 let right_big_int = right_big_integer.as_ref();
 
                 let output_big_int: BigInt = left_big_int.$infix(right_big_int).into();
-                let output_term = $process.integer(output_big_int);
+                let output_term = $process.integer(output_big_int).unwrap();
 
                 Ok(output_term)
             }
@@ -77,14 +75,12 @@ macro_rules! bitshift_infix_operator {
         use anyhow::*;
         use num_bigint::BigInt;
 
-        use liblumen_alloc::erts::exception::*;
-        use liblumen_alloc::erts::term::prelude::*;
-        use liblumen_alloc::erts::process::trace::Trace;
+                use firefly_rt::*;
 
         pub const MAX_SHIFT: usize = std::mem::size_of::<isize>() * 8 - 1;
 
-        let option_shifted = match $integer.decode().unwrap() {
-            TypedTerm::SmallInteger(integer_small_integer) => {
+        let option_shifted = match $integer {
+            Term::Int(integer_small_integer) => {
                 let integer_isize: isize = integer_small_integer.into();
                 let shift_isize: isize = term_try_into_isize!($shift).map_err(ArcError::new).map_err(|source| badarith(Trace::capture(), Some(source)))?;
 
@@ -94,13 +90,13 @@ macro_rules! bitshift_infix_operator {
 
                     if shift_usize <= MAX_SHIFT {
                         let shifted = integer_isize $positive shift_usize;
-                        let shifted_term = $process.integer(shifted);
+                        let shifted_term = $process.integer(shifted).unwrap();
 
                         Some(shifted_term)
                     } else {
                         let big_int: BigInt = integer_isize.into();
                         let shifted = big_int $positive shift_usize;
-                        let shifted_term = $process.integer(shifted);
+                        let shifted_term = $process.integer(shifted).unwrap();
 
                         Some(shifted_term)
                     }
@@ -109,19 +105,19 @@ macro_rules! bitshift_infix_operator {
 
                     if shift_usize <= MAX_SHIFT {
                         let shifted = integer_isize $negative shift_usize;
-                        let shifted_term = $process.integer(shifted);
+                        let shifted_term = $process.integer(shifted).unwrap();
 
                         Some(shifted_term)
                     } else {
                         let big_int: BigInt = integer_isize.into();
                         let shifted = big_int $negative shift_usize;
-                        let shifted_term = $process.integer(shifted);
+                        let shifted_term = $process.integer(shifted).unwrap();
 
                         Some(shifted_term)
                     }
                 }
             }
-            TypedTerm::BigInteger(integer_big_integer) => {
+            Term::BigInt(integer_big_integer) => {
                 let big_int = integer_big_integer.as_ref();
                 let shift_isize: isize = term_try_into_isize!($shift).map_err(ArcError::new).map_err(|source| badarith(Trace::capture(), Some(source)))?;
 
@@ -139,7 +135,7 @@ macro_rules! bitshift_infix_operator {
 
                 // Provide a chance to convert to SmallInteger if possible
                 let shifted: BigInt = shifted.into();
-                let shifted_term = $process.integer(shifted);
+                let shifted_term = $process.integer(shifted).unwrap();
 
                 Some(shifted_term)
             }
@@ -158,12 +154,10 @@ macro_rules! integer_infix_operator {
         use anyhow::*;
         use num_bigint::BigInt;
 
-        use liblumen_alloc::erts::exception::*;
-        use liblumen_alloc::erts::term::prelude::*;
-        use liblumen_alloc::erts::process::trace::Trace;
+                use firefly_rt::*;
 
-        match ($left.decode().unwrap(), $right.decode().unwrap()) {
-            (TypedTerm::SmallInteger(left_small_integer), TypedTerm::SmallInteger(right_small_integer)) => {
+        match ($left, $right) {
+            (Term::Int(left_small_integer), Term::Int(right_small_integer)) => {
                 let left_isize: isize = left_small_integer.into();
                 let right_isize: isize = right_small_integer.into();
 
@@ -171,22 +165,22 @@ macro_rules! integer_infix_operator {
                     Err(badarith(Trace::capture(), Some(anyhow!("{} ({}) cannot be zero", stringify!($right), $right).into())))
                 } else {
                     let quotient = left_isize $infix right_isize;
-                    let quotient_term = $process.integer(quotient);
+                    let quotient_term = $process.integer(quotient).unwrap();
 
                     Ok(quotient_term)
                 }
             }
-            (TypedTerm::SmallInteger(left_small_integer), TypedTerm::BigInteger(right_big_integer)) => {
+            (Term::Int(left_small_integer), Term::BigInt(right_big_integer)) => {
                 let left_big_int: BigInteger = left_small_integer.into();
                 let right_big_int = right_big_integer.as_ref();
 
                 let quotient = left_big_int $infix right_big_int;
                 let quotient: BigInt = quotient.into();
-                let quotient_term = $process.integer(quotient);
+                let quotient_term = $process.integer(quotient).unwrap();
 
                 Ok(quotient_term)
             }
-            (TypedTerm::BigInteger(left_big_integer), TypedTerm::SmallInteger(right_small_integer)) => {
+            (Term::BigInt(left_big_integer), Term::Int(right_small_integer)) => {
                 let right_isize: isize = right_small_integer.into();
 
                 if right_isize == 0 {
@@ -197,18 +191,18 @@ macro_rules! integer_infix_operator {
 
                     let quotient = left_big_int $infix right_big_int;
                     let quotient: BigInt = quotient.into();
-                    let quotient_term = $process.integer(quotient);
+                    let quotient_term = $process.integer(quotient).unwrap();
 
                     Ok(quotient_term)
                 }
             }
-            (TypedTerm::BigInteger(left_big_integer), TypedTerm::BigInteger(right_big_integer)) => {
+            (Term::BigInt(left_big_integer), Term::BigInt(right_big_integer)) => {
                 let left_big_int = left_big_integer.as_ref();
                 let right_big_int = right_big_integer.as_ref();
 
                 let quotient = left_big_int $infix right_big_int;
                 let quotient: BigInt = quotient.into();
-                let quotient_term = $process.integer(quotient);
+                let quotient_term = $process.integer(quotient).unwrap();
 
                 Ok(quotient_term)
             }
diff --git a/native_implemented/otp/src/macros/number.rs b/native_implemented/otp/src/macros/number.rs
index 812f76946..e745e6533 100644
--- a/native_implemented/otp/src/macros/number.rs
+++ b/native_implemented/otp/src/macros/number.rs
@@ -3,62 +3,60 @@ macro_rules! number_infix_operator {
         use anyhow::*;
         use num_bigint::BigInt;
 
-        use liblumen_alloc::erts::exception::*;
-        use liblumen_alloc::erts::process::trace::Trace;
-        use liblumen_alloc::erts::term::prelude::*;
+        use firefly_rt::term::Term;
 
         use crate::number::Operands::*;
 
-        let operands = match ($left.decode().unwrap(), $right.decode().unwrap()) {
-            (TypedTerm::SmallInteger(left_small_integer), TypedTerm::SmallInteger(right_small_integer)) => {
+        let operands = match ($left, $right) {
+            (Term::Int(left_small_integer), Term::Int(right_small_integer)) => {
                 let left_isize = left_small_integer.into();
                 let right_isize = right_small_integer.into();
 
                 ISizes(left_isize, right_isize)
             }
-            (TypedTerm::SmallInteger(left_small_integer), TypedTerm::BigInteger(right_big_integer)) => {
+            (Term::Int(left_small_integer), Term::BigInt(right_big_integer)) => {
                 let left_big_int: BigInt = left_small_integer.into();
                 let right_big_int: &BigInt = right_big_integer.as_ref().into();
 
                 BigInts(left_big_int, right_big_int.clone())
             }
-            (TypedTerm::SmallInteger(left_small_integer), TypedTerm::Float(right_float)) => {
+            (Term::Int(left_small_integer), Term::Float(right_float)) => {
                 let left_f64: f64 = left_small_integer.into();
                 let right_f64 = right_float.into();
 
                 Floats(left_f64, right_f64)
             }
-            (TypedTerm::BigInteger(left_big_integer), TypedTerm::SmallInteger(right_small_integer)) => {
+            (Term::BigInt(left_big_integer), Term::Int(right_small_integer)) => {
                 let left_big_int: &BigInt = left_big_integer.as_ref().into();
                 let right_big_int: BigInt = right_small_integer.into();
 
                 BigInts(left_big_int.clone(), right_big_int)
             }
-            (TypedTerm::Float(left_float), TypedTerm::SmallInteger(right_small_integer)) => {
+            (Term::Float(left_float), Term::Int(right_small_integer)) => {
                 let left_f64 = left_float.into();
                 let right_f64: f64 = right_small_integer.into();
 
                 Floats(left_f64, right_f64)
             }
-            (TypedTerm::BigInteger(left_big_integer), TypedTerm::BigInteger(right_big_integer)) => {
+            (Term::BigInt(left_big_integer), Term::BigInt(right_big_integer)) => {
                 let left_big_int: &BigInt = left_big_integer.as_ref().into();
                 let right_big_int: &BigInt = right_big_integer.as_ref().into();
 
                 BigInts(left_big_int.clone(), right_big_int.clone())
             }
-            (TypedTerm::BigInteger(left_big_integer), TypedTerm::Float(right_float)) => {
+            (Term::BigInt(left_big_integer), Term::Float(right_float)) => {
                 let left_f64: f64 = left_big_integer.into();
                 let right_f64 = right_float.into();
 
                 Floats(left_f64, right_f64)
             }
-            (TypedTerm::Float(left_float), TypedTerm::BigInteger(right_big_integer)) => {
+            (Term::Float(left_float), Term::BigInt(right_big_integer)) => {
                 let left_f64 = left_float.into();
                 let right_f64: f64 = right_big_integer.into();
 
                 Floats(left_f64, right_f64)
             }
-            (TypedTerm::Float(left_float), TypedTerm::Float(right_float)) => {
+            (Term::Float(left_float), Term::Float(right_float)) => {
                 let left_f64 = left_float.into();
                 let right_f64 = right_float.into();
 
@@ -84,13 +82,13 @@ macro_rules! number_infix_operator {
             ),
             ISizes(left_isize, right_isize) => {
                 match left_isize.$checked(right_isize) {
-                    Some(sum_isize) => Ok($process.integer(sum_isize)),
+                    Some(sum_isize) => Ok($process.integer(sum_isize).unwrap()),
                     None => {
                         let left_big_int: BigInt = left_isize.into();
                         let right_big_int: BigInt = right_isize.into();
 
                         let sum_big_int = left_big_int $infix right_big_int;
-                        let sum_term = $process.integer(sum_big_int);
+                        let sum_term = $process.integer(sum_big_int).unwrap();
 
                         Ok(sum_term)
                     }
@@ -98,13 +96,13 @@ macro_rules! number_infix_operator {
             }
             Floats(left, right) => {
                 let output = left $infix right;
-                let output_term = $process.float(output);
+                let output_term = output.into();
 
                 Ok(output_term)
             }
             BigInts(left, right) => {
                 let output = left $infix right;
-                let output_term = $process.integer(output);
+                let output_term = $process.integer(output).unwrap();
 
                 Ok(output_term)
             }
@@ -115,14 +113,14 @@ macro_rules! number_infix_operator {
 macro_rules! number_to_integer {
     ($f:ident) => {
         use anyhow::*;
-        use liblumen_alloc::erts::exception;
-        use liblumen_alloc::erts::process::Process;
-        use liblumen_alloc::erts::term::prelude::*;
+        use firefly_rt::error::ErlangException;
+        use firefly_rt::process::Process;
+        use firefly_rt::term::{Term, TypeError};
 
         use crate::erlang::number_to_integer::{f64_to_integer, NumberToInteger};
 
         #[native_implemented::function(erlang:$f/1)]
-        pub fn result(process: &Process, number: Term) -> exception::Result<Term> {
+        pub fn result(process: &Process, number: Term) -> Result<Term, NonNull<ErlangException>> {
             match number.into() {
                 NumberToInteger::Integer(integer) => Ok(integer),
                 NumberToInteger::F64(f) => {
diff --git a/native_implemented/otp/src/maps.rs b/native_implemented/otp/src/maps.rs
index 70123e8f6..dc8eb855b 100644
--- a/native_implemented/otp/src/maps.rs
+++ b/native_implemented/otp/src/maps.rs
@@ -11,8 +11,6 @@ pub mod take_2;
 pub mod update_3;
 pub mod values_1;
 
-use liblumen_alloc::erts::term::prelude::Atom;
-
 fn module() -> Atom {
     Atom::from_str("maps")
 }
diff --git a/native_implemented/otp/src/maps/find_2.rs b/native_implemented/otp/src/maps/find_2.rs
index 529f591dc..2257eef55 100644
--- a/native_implemented/otp/src/maps/find_2.rs
+++ b/native_implemented/otp/src/maps/find_2.rs
@@ -1,22 +1,22 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::atom;
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use std::ptr::NonNull;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::{atoms, Term};
 
 #[native_implemented::function(maps:find/2)]
-pub fn result(process: &Process, key: Term, map: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, key: Term, map: Term) -> Result<Term, NonNull<ErlangException>> {
     let map = term_try_into_map_or_badmap!(process, map)?;
 
     let result = match map.get(key) {
         Some(term) => {
-            let ok = atom!("ok");
+            let ok = atoms::Ok;
 
-            process.tuple_from_slice(&[ok, term])
+            process.tuple_term_from_term_slice(&[ok, term])
         }
-        None => atom!("error"),
+        None => atoms::Error.into(),
     };
 
     Ok(result)
diff --git a/native_implemented/otp/src/maps/find_2/test.rs b/native_implemented/otp/src/maps/find_2/test.rs
index cefcdf3f5..f8d0df6ce 100644
--- a/native_implemented/otp/src/maps/find_2/test.rs
+++ b/native_implemented/otp/src/maps/find_2/test.rs
@@ -1,11 +1,8 @@
 mod with_map;
 
 use proptest::prop_assert_eq;
-use proptest::strategy::Strategy;
 use proptest::test_runner::{Config, TestRunner};
 
-use liblumen_alloc::atom;
-
 use crate::maps::find_2::result;
 use crate::test::strategy;
 use crate::test::with_process_arc;
diff --git a/native_implemented/otp/src/maps/find_2/test/with_map.rs b/native_implemented/otp/src/maps/find_2/test/with_map.rs
index 7cdbb36e3..6c4a77aed 100644
--- a/native_implemented/otp/src/maps/find_2/test/with_map.rs
+++ b/native_implemented/otp/src/maps/find_2/test/with_map.rs
@@ -1,5 +1,7 @@
 use super::*;
 
+use firefly_rt::term::Atom;
+
 #[test]
 fn without_key_returns_error_atom() {
     with_process_arc(|arc_process| {
@@ -13,12 +15,12 @@ fn without_key_returns_error_atom() {
                         key != non_key
                     })
                     .prop_map(|(key, non_key)| {
-                        let value = atom!("value");
+                        let value = Atom::str_to_term("value");
 
                         (non_key, arc_process.map_from_slice(&[(key, value)]))
                     }),
                 |(key, map)| {
-                    let error = atom!("error");
+                    let error = atoms::Error.into();
 
                     prop_assert_eq!(result(&arc_process, key, map), Ok(error.into()));
 
@@ -35,14 +37,14 @@ fn with_key_returns_success_tuple() {
         TestRunner::new(Config::with_source_file(file!()))
             .run(
                 &strategy::term(arc_process.clone()).prop_map(|key| {
-                    let value = atom!("value");
+                    let value = Atom::str_to_term("value").into();
 
                     (key, arc_process.map_from_slice(&[(key, value)]))
                 }),
                 |(key, map)| {
-                    let ok = atom!("ok");
-                    let value = atom!("value");
-                    let success_tuple = arc_process.tuple_from_slice(&[ok, value]);
+                    let ok = atoms::Ok;
+                    let value = Atom::str_to_term("value").into();
+                    let success_tuple = arc_process.tuple_term_from_term_slice(&[ok, value]);
 
                     prop_assert_eq!(result(&arc_process, key, map), Ok(success_tuple.into()));
 
diff --git a/native_implemented/otp/src/maps/from_list_1.rs b/native_implemented/otp/src/maps/from_list_1.rs
index 0c7de8599..1b2910d71 100644
--- a/native_implemented/otp/src/maps/from_list_1.rs
+++ b/native_implemented/otp/src/maps/from_list_1.rs
@@ -1,9 +1,11 @@
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use std::ptr::NonNull;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Map, Term};
 
 #[native_implemented::function(maps:from_list/1)]
-pub fn result(process: &Process, list: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, list: Term) -> Result<Term, NonNull<ErlangException>> {
     let hash_map = Map::from_list(list)?;
     let map = process.map_from_hash_map(hash_map);
 
diff --git a/native_implemented/otp/src/maps/get_2.rs b/native_implemented/otp/src/maps/get_2.rs
index bae1d5a51..aa4e6f39a 100644
--- a/native_implemented/otp/src/maps/get_2.rs
+++ b/native_implemented/otp/src/maps/get_2.rs
@@ -1,15 +1,17 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
+use std::ptr::NonNull;
+
 use anyhow::*;
 
-use liblumen_alloc::erts::exception::{self, *};
-use liblumen_alloc::erts::process::trace::Trace;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::backtrace::Trace;
+use firefly_rt::process::Process;
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(maps:get/2)]
-pub fn result(process: &Process, key: Term, map: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, key: Term, map: Term) -> Result<Term, NonNull<ErlangException>> {
     let boxed_map = term_try_into_map_or_badmap!(process, map)?;
 
     match boxed_map.get(key) {
diff --git a/native_implemented/otp/src/maps/get_2/test.rs b/native_implemented/otp/src/maps/get_2/test.rs
index 99e1d9973..4e3169b21 100644
--- a/native_implemented/otp/src/maps/get_2/test.rs
+++ b/native_implemented/otp/src/maps/get_2/test.rs
@@ -1,11 +1,9 @@
 mod with_map;
 
 use proptest::prop_assert_eq;
-use proptest::strategy::{Just, Strategy};
+use proptest::strategy::Just;
 use proptest::test_runner::{Config, TestRunner};
 
-use liblumen_alloc::atom;
-
 use crate::maps::get_2::result;
 use crate::test::strategy;
 use crate::test::with_process_arc;
diff --git a/native_implemented/otp/src/maps/get_2/test/with_map.rs b/native_implemented/otp/src/maps/get_2/test/with_map.rs
index 1ecd79a59..090f8aa79 100644
--- a/native_implemented/otp/src/maps/get_2/test/with_map.rs
+++ b/native_implemented/otp/src/maps/get_2/test/with_map.rs
@@ -16,7 +16,7 @@ fn without_key_errors_badkey() {
                     key != non_key
                 })
                 .prop_map(|(arc_process, key, non_key)| {
-                    let value = atom!("value");
+                    let value = Atom::str_to_term("value").into();
                     (
                         arc_process.clone(),
                         non_key,
@@ -43,12 +43,12 @@ fn with_key_returns_value() {
         TestRunner::new(Config::with_source_file(file!()))
             .run(
                 &strategy::term(arc_process.clone()).prop_map(|key| {
-                    let value = atom!("value");
+                    let value = Atom::str_to_term("value").into();
 
                     (key, arc_process.map_from_slice(&[(key, value)]))
                 }),
                 |(key, map)| {
-                    let value = atom!("value");
+                    let value = Atom::str_to_term("value").into();
                     prop_assert_eq!(result(&arc_process, key, map), Ok(value.into()));
 
                     Ok(())
diff --git a/native_implemented/otp/src/maps/get_3.rs b/native_implemented/otp/src/maps/get_3.rs
index 1ce4659d9..bf408f869 100644
--- a/native_implemented/otp/src/maps/get_3.rs
+++ b/native_implemented/otp/src/maps/get_3.rs
@@ -1,12 +1,19 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use std::ptr::NonNull;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(maps:get/3)]
-pub fn result(process: &Process, key: Term, map: Term, default: Term) -> exception::Result<Term> {
+pub fn result(
+    process: &Process,
+    key: Term,
+    map: Term,
+    default: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     let boxed_map = term_try_into_map_or_badmap!(process, map)?;
 
     Ok(boxed_map.get(key).unwrap_or(default).into())
diff --git a/native_implemented/otp/src/maps/get_3/test.rs b/native_implemented/otp/src/maps/get_3/test.rs
index a24549ad0..2bd47f72d 100644
--- a/native_implemented/otp/src/maps/get_3/test.rs
+++ b/native_implemented/otp/src/maps/get_3/test.rs
@@ -1,11 +1,8 @@
 mod with_map;
 
 use proptest::prop_assert_eq;
-use proptest::strategy::Strategy;
 use proptest::test_runner::{Config, TestRunner};
 
-use liblumen_alloc::atom;
-
 use crate::maps::get_3::result;
 use crate::test::strategy;
 use crate::test::with_process_arc;
diff --git a/native_implemented/otp/src/maps/get_3/test/with_map.rs b/native_implemented/otp/src/maps/get_3/test/with_map.rs
index 67e0c6e1d..79be57186 100644
--- a/native_implemented/otp/src/maps/get_3/test/with_map.rs
+++ b/native_implemented/otp/src/maps/get_3/test/with_map.rs
@@ -13,12 +13,12 @@ fn without_key_returns_default() {
                         key != non_key
                     })
                     .prop_map(|(key, non_key)| {
-                        let value = atom!("value");
+                        let value = Atom::str_to_term("value").into();
 
                         (non_key, arc_process.map_from_slice(&[(key, value)]))
                     }),
                 |(key, map)| {
-                    let default = atom!("default");
+                    let default = Atom::str_to_term("default").into();
                     prop_assert_eq!(result(&arc_process, key, map, default), Ok(default.into()));
 
                     Ok(())
@@ -34,13 +34,13 @@ fn with_key_returns_value() {
         TestRunner::new(Config::with_source_file(file!()))
             .run(
                 &strategy::term(arc_process.clone()).prop_map(|key| {
-                    let value = atom!("value");
+                    let value = Atom::str_to_term("value").into();
 
                     (key, arc_process.map_from_slice(&[(key, value)]))
                 }),
                 |(key, map)| {
-                    let default = atom!("default");
-                    let value = atom!("value");
+                    let default = Atom::str_to_term("default").into();
+                    let value = Atom::str_to_term("value").into();
                     prop_assert_eq!(result(&arc_process, key, map, default), Ok(value.into()));
 
                     Ok(())
diff --git a/native_implemented/otp/src/maps/is_key_2.rs b/native_implemented/otp/src/maps/is_key_2.rs
index 930e3a30e..052bf3287 100644
--- a/native_implemented/otp/src/maps/is_key_2.rs
+++ b/native_implemented/otp/src/maps/is_key_2.rs
@@ -1,12 +1,14 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use std::ptr::NonNull;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(maps:is_key/2)]
-pub fn result(process: &Process, key: Term, map: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, key: Term, map: Term) -> Result<Term, NonNull<ErlangException>> {
     let boxed_map = term_try_into_map_or_badmap!(process, map)?;
 
     Ok(boxed_map.is_key(key).into())
diff --git a/native_implemented/otp/src/maps/is_key_2/test.rs b/native_implemented/otp/src/maps/is_key_2/test.rs
index 5d32358fa..2f422ebcf 100644
--- a/native_implemented/otp/src/maps/is_key_2/test.rs
+++ b/native_implemented/otp/src/maps/is_key_2/test.rs
@@ -1,11 +1,8 @@
 mod with_map;
 
 use proptest::prop_assert_eq;
-use proptest::strategy::Strategy;
 use proptest::test_runner::{Config, TestRunner};
 
-use liblumen_alloc::atom;
-
 use crate::maps::is_key_2::result;
 use crate::test::strategy;
 use crate::test::with_process_arc;
diff --git a/native_implemented/otp/src/maps/is_key_2/test/with_map.rs b/native_implemented/otp/src/maps/is_key_2/test/with_map.rs
index 01037b098..443a514ec 100644
--- a/native_implemented/otp/src/maps/is_key_2/test/with_map.rs
+++ b/native_implemented/otp/src/maps/is_key_2/test/with_map.rs
@@ -1,3 +1,4 @@
+use firefly_rt::term::Atom;
 use super::*;
 
 #[test]
@@ -13,7 +14,7 @@ fn without_key_returns_false() {
                         key != non_key
                     })
                     .prop_map(|(key, non_key)| {
-                        let value = atom!("value");
+                        let value = Atom::str_to_term("value");
 
                         (non_key, arc_process.map_from_slice(&[(key, value)]))
                     }),
@@ -33,7 +34,7 @@ fn with_key_returns_true() {
         TestRunner::new(Config::with_source_file(file!()))
             .run(
                 &strategy::term(arc_process.clone()).prop_map(|key| {
-                    let value = atom!("value");
+                    let value = Atom::str_to_term("value").into();
 
                     (key, arc_process.map_from_slice(&[(key, value)]))
                 }),
diff --git a/native_implemented/otp/src/maps/keys_1.rs b/native_implemented/otp/src/maps/keys_1.rs
index fd6c27f89..620893632 100644
--- a/native_implemented/otp/src/maps/keys_1.rs
+++ b/native_implemented/otp/src/maps/keys_1.rs
@@ -1,15 +1,16 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use std::ptr::NonNull;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(maps:keys/1)]
-pub fn result(process: &Process, map: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, map: Term) -> Result<Term, NonNull<ErlangException>> {
     let boxed_map = term_try_into_map_or_badmap!(process, map)?;
     let keys = boxed_map.keys();
-    let list = process.list_from_slice(&keys);
+    let list = process.list_from_slice(&keys).unwrap();
 
     Ok(list)
 }
diff --git a/native_implemented/otp/src/maps/keys_1/test.rs b/native_implemented/otp/src/maps/keys_1/test.rs
index 012709eb8..f3580d335 100644
--- a/native_implemented/otp/src/maps/keys_1/test.rs
+++ b/native_implemented/otp/src/maps/keys_1/test.rs
@@ -1,11 +1,9 @@
 mod with_map;
 
 use proptest::prop_assert_eq;
-use proptest::strategy::Strategy;
 use proptest::test_runner::{Config, TestRunner};
 
-use liblumen_alloc::atom;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 use crate::maps::keys_1::result;
 use crate::test::strategy;
diff --git a/native_implemented/otp/src/maps/keys_1/test/with_map.rs b/native_implemented/otp/src/maps/keys_1/test/with_map.rs
index 71f3e8b51..6d2c2dc21 100644
--- a/native_implemented/otp/src/maps/keys_1/test/with_map.rs
+++ b/native_implemented/otp/src/maps/keys_1/test/with_map.rs
@@ -5,7 +5,7 @@ fn returns_empty_list_of_keys() {
     with_process_arc(|arc_process| {
         let empty_map = arc_process.map_from_slice(&[]);
 
-        assert_eq!(result(&arc_process, empty_map), Ok(Term::NIL));
+        assert_eq!(result(&arc_process, empty_map), Ok(Term::Nil));
     });
 }
 
@@ -15,10 +15,10 @@ fn returns_list_of_keys() {
         TestRunner::new(Config::with_source_file(file!()))
             .run(
                 &(strategy::term(arc_process.clone())).prop_map(|key| {
-                    let value = atom!("value");
+                    let value = Atom::str_to_term("value").into();
 
                     (
-                        arc_process.list_from_slice(&[key]),
+                        arc_process.list_from_slice(&[key]).unwrap(),
                         arc_process.map_from_slice(&[(key, value)]),
                     )
                 }),
diff --git a/native_implemented/otp/src/maps/merge_2.rs b/native_implemented/otp/src/maps/merge_2.rs
index 198aa1b6f..5b69c0ff6 100644
--- a/native_implemented/otp/src/maps/merge_2.rs
+++ b/native_implemented/otp/src/maps/merge_2.rs
@@ -1,14 +1,16 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
+use std::ptr::NonNull;
+
 use hashbrown::HashMap;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(maps:merge/2)]
-pub fn result(process: &Process, map1: Term, map2: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, map1: Term, map2: Term) -> Result<Term, NonNull<ErlangException>> {
     let boxed_map1 = term_try_into_map_or_badmap!(process, map1)?;
     let boxed_map2 = term_try_into_map_or_badmap!(process, map2)?;
 
diff --git a/native_implemented/otp/src/maps/merge_2/test.rs b/native_implemented/otp/src/maps/merge_2/test.rs
index 1c6ddfbb9..ce0c10c6e 100644
--- a/native_implemented/otp/src/maps/merge_2/test.rs
+++ b/native_implemented/otp/src/maps/merge_2/test.rs
@@ -1,7 +1,7 @@
 mod with_map_map1;
 
 use proptest::prop_assert_eq;
-use proptest::strategy::{Just, Strategy};
+use proptest::strategy::Just;
 use proptest::test_runner::{Config, TestRunner};
 
 use crate::maps::merge_2::result;
diff --git a/native_implemented/otp/src/maps/merge_2/test/with_map_map1/with_map_map2.rs b/native_implemented/otp/src/maps/merge_2/test/with_map_map1/with_map_map2.rs
index 17890b88b..82bddfe98 100644
--- a/native_implemented/otp/src/maps/merge_2/test/with_map_map1/with_map_map2.rs
+++ b/native_implemented/otp/src/maps/merge_2/test/with_map_map1/with_map_map2.rs
@@ -1,12 +1,8 @@
 use super::*;
 
-use std::convert::TryInto;
-
 use proptest::prop_assert;
 use proptest::strategy::Just;
 
-use liblumen_alloc::erts::term::prelude::{Boxed, Map};
-
 #[test]
 fn with_same_key_in_map1_and_map2_uses_value_from_map2() {
     run!(
diff --git a/native_implemented/otp/src/maps/put_3.rs b/native_implemented/otp/src/maps/put_3.rs
index 7785b9355..744f276c8 100644
--- a/native_implemented/otp/src/maps/put_3.rs
+++ b/native_implemented/otp/src/maps/put_3.rs
@@ -1,12 +1,19 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use std::ptr::NonNull;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(maps:put/3)]
-pub fn result(process: &Process, key: Term, value: Term, map: Term) -> exception::Result<Term> {
+pub fn result(
+    process: &Process,
+    key: Term,
+    value: Term,
+    map: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     let boxed_map = term_try_into_map_or_badmap!(process, map)?;
 
     match boxed_map.put(key, value) {
diff --git a/native_implemented/otp/src/maps/put_3/test.rs b/native_implemented/otp/src/maps/put_3/test.rs
index 2c6d1af47..078c82186 100644
--- a/native_implemented/otp/src/maps/put_3/test.rs
+++ b/native_implemented/otp/src/maps/put_3/test.rs
@@ -1,11 +1,8 @@
 mod with_map;
 
 use proptest::prop_assert_eq;
-use proptest::strategy::Strategy;
 use proptest::test_runner::{Config, TestRunner};
 
-use liblumen_alloc::atom;
-
 use crate::maps::put_3::result;
 use crate::test::strategy;
 use crate::test::with_process_arc;
diff --git a/native_implemented/otp/src/maps/put_3/test/with_map.rs b/native_implemented/otp/src/maps/put_3/test/with_map.rs
index 6264b3812..9c6cbc768 100644
--- a/native_implemented/otp/src/maps/put_3/test/with_map.rs
+++ b/native_implemented/otp/src/maps/put_3/test/with_map.rs
@@ -31,12 +31,12 @@ fn with_key_puts_replacement_value() {
         TestRunner::new(Config::with_source_file(file!()))
             .run(
                 &strategy::term(arc_process.clone()).prop_map(|key| {
-                    let value = atom!("value");
+                    let value = Atom::str_to_term("value").into();
 
                     (key, arc_process.map_from_slice(&[(key, value)]))
                 }),
                 |(key, map)| {
-                    let value2 = atom!("value2");
+                    let value2 = Atom::str_to_term("value2").into();
                     let updated_map = arc_process.map_from_slice(&[(key, value2)]);
                     prop_assert_eq!(
                         result(&arc_process, key, value2, map),
diff --git a/native_implemented/otp/src/maps/remove_2.rs b/native_implemented/otp/src/maps/remove_2.rs
index 626c389c1..2999c825f 100644
--- a/native_implemented/otp/src/maps/remove_2.rs
+++ b/native_implemented/otp/src/maps/remove_2.rs
@@ -1,12 +1,14 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use std::ptr::NonNull;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(maps:remove/2)]
-pub fn result(process: &Process, key: Term, map: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, key: Term, map: Term) -> Result<Term, NonNull<ErlangException>> {
     let boxed_map = term_try_into_map_or_badmap!(process, map)?;
 
     match boxed_map.remove(key) {
diff --git a/native_implemented/otp/src/maps/remove_2/test.rs b/native_implemented/otp/src/maps/remove_2/test.rs
index 734dc69c3..d4b1a5343 100644
--- a/native_implemented/otp/src/maps/remove_2/test.rs
+++ b/native_implemented/otp/src/maps/remove_2/test.rs
@@ -1,11 +1,8 @@
 mod with_map;
 
 use proptest::prop_assert_eq;
-use proptest::strategy::Strategy;
 use proptest::test_runner::{Config, TestRunner};
 
-use liblumen_alloc::atom;
-
 use crate::maps::remove_2::result;
 use crate::test::strategy;
 use crate::test::with_process_arc;
diff --git a/native_implemented/otp/src/maps/remove_2/test/with_map.rs b/native_implemented/otp/src/maps/remove_2/test/with_map.rs
index 77967e80d..715c6c272 100644
--- a/native_implemented/otp/src/maps/remove_2/test/with_map.rs
+++ b/native_implemented/otp/src/maps/remove_2/test/with_map.rs
@@ -1,3 +1,4 @@
+use firefly_rt::term::Atom;
 use super::*;
 
 #[test]
@@ -13,7 +14,7 @@ fn without_key_returns_equivalent_map() {
                         key != non_key
                     })
                     .prop_map(|(key, non_key)| {
-                        let value = atom!("value");
+                        let value = Atom::str_to_term("value");
 
                         (non_key, arc_process.map_from_slice(&[(key, value)]))
                     }),
@@ -33,7 +34,7 @@ fn with_key_returns_new_map() {
         TestRunner::new(Config::with_source_file(file!()))
             .run(
                 &strategy::term(arc_process.clone()).prop_map(|key| {
-                    let value = atom!("value");
+                    let value = Atom::str_to_term("value").into();
 
                     (key, arc_process.map_from_slice(&[(key, value)]))
                 }),
diff --git a/native_implemented/otp/src/maps/take_2.rs b/native_implemented/otp/src/maps/take_2.rs
index 0e5b5fcf6..c8b6ccfe6 100644
--- a/native_implemented/otp/src/maps/take_2.rs
+++ b/native_implemented/otp/src/maps/take_2.rs
@@ -1,21 +1,22 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::atom;
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use std::ptr::NonNull;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::{atoms, Term};
 
 #[native_implemented::function(maps:take/2)]
-pub fn result(process: &Process, key: Term, map: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, key: Term, map: Term) -> Result<Term, NonNull<ErlangException>> {
     let boxed_map = term_try_into_map_or_badmap!(process, map)?;
 
     let result = match boxed_map.take(key) {
         Some((value, hash_map)) => {
             let map = process.map_from_hash_map(hash_map);
-            process.tuple_from_slice(&[value, map])
+            process.tuple_term_from_term_slice(&[value, map])
         }
-        None => atom!("error"),
+        None => atoms::Error.into(),
     };
 
     Ok(result)
diff --git a/native_implemented/otp/src/maps/take_2/test.rs b/native_implemented/otp/src/maps/take_2/test.rs
index b69007ae0..c69367d7c 100644
--- a/native_implemented/otp/src/maps/take_2/test.rs
+++ b/native_implemented/otp/src/maps/take_2/test.rs
@@ -1,11 +1,8 @@
 mod with_map;
 
 use proptest::prop_assert_eq;
-use proptest::strategy::Strategy;
 use proptest::test_runner::{Config, TestRunner};
 
-use liblumen_alloc::atom;
-
 use crate::maps::take_2::result;
 use crate::test::strategy;
 use crate::test::with_process_arc;
diff --git a/native_implemented/otp/src/maps/take_2/test/with_map.rs b/native_implemented/otp/src/maps/take_2/test/with_map.rs
index 0db968c83..08afa378a 100644
--- a/native_implemented/otp/src/maps/take_2/test/with_map.rs
+++ b/native_implemented/otp/src/maps/take_2/test/with_map.rs
@@ -13,12 +13,12 @@ fn without_key_returns_error_atom() {
                         key != non_key
                     })
                     .prop_map(|(key, non_key)| {
-                        let value = atom!("value");
+                        let value = Atom::str_to_term("value").into();
 
                         (non_key, arc_process.map_from_slice(&[(key, value)]))
                     }),
                 |(key, map)| {
-                    let error = atom!("error");
+                    let error = atoms::Error.into();
 
                     prop_assert_eq!(result(&arc_process, key, map), Ok(error.into()));
 
@@ -35,14 +35,14 @@ fn with_key_returns_value_and_map_tuple() {
         TestRunner::new(Config::with_source_file(file!()))
             .run(
                 &strategy::term(arc_process.clone()).prop_map(|key| {
-                    let value = atom!("value");
+                    let value = Atom::str_to_term("value").into();
 
                     (key, arc_process.map_from_slice(&[(key, value)]))
                 }),
                 |(key, map)| {
-                    let value = atom!("value");
+                    let value = Atom::str_to_term("value").into();
                     let empty_map = arc_process.map_from_slice(&[]);
-                    let value_and_map_tuple = arc_process.tuple_from_slice(&[value, empty_map]);
+                    let value_and_map_tuple = arc_process.tuple_term_from_term_slice(&[value, empty_map]);
 
                     prop_assert_eq!(
                         result(&arc_process, key, map),
diff --git a/native_implemented/otp/src/maps/update_3.rs b/native_implemented/otp/src/maps/update_3.rs
index 0eeeaa8a2..b05865be4 100644
--- a/native_implemented/otp/src/maps/update_3.rs
+++ b/native_implemented/otp/src/maps/update_3.rs
@@ -1,15 +1,21 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
+use std::ptr::NonNull;
+
 use anyhow::*;
 
-use liblumen_alloc::erts::exception::{self, *};
-use liblumen_alloc::erts::process::trace::Trace;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::error::ErlangException;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(maps:update/3)]
-pub fn result(process: &Process, key: Term, value: Term, map: Term) -> exception::Result<Term> {
+pub fn result(
+    process: &Process,
+    key: Term,
+    value: Term,
+    map: Term,
+) -> Result<Term, NonNull<ErlangException>> {
     let boxed_map = term_try_into_map_or_badmap!(process, map)?;
 
     match boxed_map.update(key, value) {
diff --git a/native_implemented/otp/src/maps/update_3/test.rs b/native_implemented/otp/src/maps/update_3/test.rs
index 32b1cbfba..09dc76c2d 100644
--- a/native_implemented/otp/src/maps/update_3/test.rs
+++ b/native_implemented/otp/src/maps/update_3/test.rs
@@ -1,10 +1,9 @@
 mod with_map;
 
 use proptest::prop_assert_eq;
-use proptest::strategy::Strategy;
 use proptest::test_runner::{Config, TestRunner};
 
-use liblumen_alloc::atom;
+use firefly_rt::term::Atom;
 
 use crate::maps::update_3::result;
 use crate::test::strategy;
diff --git a/native_implemented/otp/src/maps/update_3/test/with_map.rs b/native_implemented/otp/src/maps/update_3/test/with_map.rs
index 704486ab0..cc6986643 100644
--- a/native_implemented/otp/src/maps/update_3/test/with_map.rs
+++ b/native_implemented/otp/src/maps/update_3/test/with_map.rs
@@ -32,12 +32,12 @@ fn with_key_updates_replacement_value() {
         TestRunner::new(Config::with_source_file(file!()))
             .run(
                 &strategy::term(arc_process.clone()).prop_map(|key| {
-                    let value = atom!("value");
+                    let value = Atom::str_to_term("value").into();
 
                     (key, arc_process.map_from_slice(&[(key, value)]))
                 }),
                 |(key, map)| {
-                    let value2 = atom!("value2");
+                    let value2 = Atom::str_to_term("value2").into();
                     let updated_map = arc_process.map_from_slice(&[(key, value2)]);
                     prop_assert_eq!(
                         result(&arc_process, key, value2, map),
diff --git a/native_implemented/otp/src/maps/values_1.rs b/native_implemented/otp/src/maps/values_1.rs
index fde4272be..0ffd6e78f 100644
--- a/native_implemented/otp/src/maps/values_1.rs
+++ b/native_implemented/otp/src/maps/values_1.rs
@@ -1,15 +1,17 @@
 #[cfg(all(not(target_arch = "wasm32"), test))]
 mod test;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use std::ptr::NonNull;
+
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(maps:values/1)]
-pub fn result(process: &Process, map: Term) -> exception::Result<Term> {
+pub fn result(process: &Process, map: Term) -> Result<Term, NonNull<ErlangException>> {
     let boxed_map = term_try_into_map_or_badmap!(process, map)?;
     let values = boxed_map.values();
-    let list = process.list_from_slice(&values);
+    let list = process.list_from_slice(&values).unwrap();
 
     Ok(list)
 }
diff --git a/native_implemented/otp/src/maps/values_1/test.rs b/native_implemented/otp/src/maps/values_1/test.rs
index 4447f0283..e60e2d6be 100644
--- a/native_implemented/otp/src/maps/values_1/test.rs
+++ b/native_implemented/otp/src/maps/values_1/test.rs
@@ -1,11 +1,9 @@
 mod with_map;
 
 use proptest::prop_assert_eq;
-use proptest::strategy::Strategy;
 use proptest::test_runner::{Config, TestRunner};
 
-use liblumen_alloc::atom;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::{Atom, Term};
 
 use crate::maps::values_1::result;
 use crate::test::strategy;
diff --git a/native_implemented/otp/src/maps/values_1/test/with_map.rs b/native_implemented/otp/src/maps/values_1/test/with_map.rs
index ae03b4e6d..6caf08b39 100644
--- a/native_implemented/otp/src/maps/values_1/test/with_map.rs
+++ b/native_implemented/otp/src/maps/values_1/test/with_map.rs
@@ -5,7 +5,7 @@ fn returns_empty_list_of_values() {
     with_process_arc(|arc_process| {
         let empty_map = arc_process.map_from_slice(&[]);
 
-        assert_eq!(result(&arc_process, empty_map), Ok(Term::NIL));
+        assert_eq!(result(&arc_process, empty_map), Ok(Term::Nil));
     });
 }
 
@@ -15,10 +15,10 @@ fn returns_list_of_values() {
         TestRunner::new(Config::with_source_file(file!()))
             .run(
                 &(strategy::term(arc_process.clone())).prop_map(|value| {
-                    let key = atom!("key");
+                    let key = Atom::str_to_term("key").into();
 
                     (
-                        arc_process.list_from_slice(&[value]),
+                        arc_process.list_from_slice(&[value]).unwrap(),
                         arc_process.map_from_slice(&[(key, value)]),
                     )
                 }),
diff --git a/native_implemented/otp/src/proplist.rs b/native_implemented/otp/src/proplist.rs
new file mode 100644
index 000000000..155d6d7d5
--- /dev/null
+++ b/native_implemented/otp/src/proplist.rs
@@ -0,0 +1,15 @@
+use thiserror::Error;
+
+#[derive(Debug, Error)]
+pub enum TryPropListFromTermError {
+    #[error("atom name is not a supported property")]
+    AtomName(&'static str),
+    #[error("tuple in proplist can only be a 2-tuple")]
+    TupleNotPair,
+    #[error("a keyword key can only be an atom")]
+    KeywordKeyType,
+    #[error("keyword key is not a property name")]
+    KeywordKeyName(&'static str),
+    #[error("property must be a keyword key or an atom")]
+    PropertyType,
+}
diff --git a/native_implemented/otp/src/test.rs b/native_implemented/otp/src/test.rs
index ddf37aeba..7f11db6cf 100644
--- a/native_implemented/otp/src/test.rs
+++ b/native_implemented/otp/src/test.rs
@@ -18,22 +18,22 @@ pub mod strategy;
 #[cfg(all(not(target_arch = "wasm32"), test))]
 pub use self::proptest::*;
 
+use std::ptr::NonNull;
+use std::str::FromStr;
 use std::sync::Arc;
 
-use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
-use liblumen_alloc::erts::time::{Milliseconds, Monotonic};
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Atom, Pid, Term};
+use firefly_rt::time::{Milliseconds, Monotonic};
 
 use crate::erlang::{self, exit_1};
-use crate::runtime::scheduler::{Scheduled, SchedulerDependentAlloc};
+use crate::runtime::scheduler::{next_local_reference_term, Scheduled, SchedulerDependentAlloc};
 use crate::runtime::time::monotonic;
 use crate::runtime::timer;
 
 pub fn exit_when_run(process: &Process, reason: Term) {
-    process.queue_frame_with_arguments(exit_1::frame().with_arguments(false, &[reason]));
-    process.stack_queued_frames_with_arguments();
-    process.scheduler().unwrap().stop_waiting(process);
+    todo!();
 }
 
 pub fn freeze_timeout() -> Monotonic {
@@ -48,15 +48,15 @@ pub fn freeze_at_timeout(frozen: Monotonic) {
     timer::timeout();
 }
 
-pub fn module() -> Atom {
+pub fn module() -> Result<Atom, AtomError> {
     Atom::from_str("test")
 }
 
 pub fn with_big_int(f: fn(&Process, Term) -> ()) {
     with_process(|process| {
-        let big_int: Term = process.integer(SmallInteger::MAX_VALUE + 1);
+        let big_int: Term = process.integer(Integer::MAX_SMALL + 1).unwrap();
 
-        assert!(big_int.is_boxed_bigint());
+        assert!(big_int.is_big_int());
 
         f(&process, big_int)
     })
@@ -83,7 +83,7 @@ pub fn with_options_with_timer_in_same_thread_with_timeout_returns_false_after_t
     result: N,
     options: O,
 ) where
-    N: Fn(&Process, Term, Term) -> exception::Result<Term>,
+    N: Fn(&Process, Term, Term) -> Result<Term, NonNull<ErlangException>>,
     O: Fn(&Process) -> Term,
 {
     with_timer_in_same_thread(|milliseconds, message, timer_reference, process| {
@@ -107,11 +107,11 @@ pub fn with_options_with_timer_in_same_thread_with_timeout_returns_false_after_t
 }
 
 pub fn with_timer_in_same_thread_with_timeout_returns_false_after_timeout_message_was_sent(
-    result: fn(&Process, Term) -> exception::Result<Term>,
+    result: fn(&Process, Term) -> Result<Term, NonNull<ErlangException>>,
 ) {
     with_options_with_timer_in_same_thread_with_timeout_returns_false_after_timeout_message_was_sent(
         |process, timer_reference, _| result(process, timer_reference),
-        |_| Term::NIL,
+        |_| Term::Nil,
     )
 }
 
@@ -122,14 +122,13 @@ where
     let same_thread_process_arc = process::default();
     let milliseconds = Milliseconds(100);
 
-    let message = Atom::str_to_term("message");
-    let timer_reference = erlang::start_timer_3::result(
-        same_thread_process_arc.clone(),
-        same_thread_process_arc.integer(milliseconds),
-        same_thread_process_arc.pid().into(),
-        message,
-    )
-    .unwrap();
+    let message: Term = Atom::str_to_term("message").into();
+    let time: Term = next_local_reference_term.integer(milliseconds);
+    let destination: Term = same_thread_process_arc.pid_term().unwrap();
+
+    let timer_reference =
+        erlang::start_timer_3::result(same_thread_process_arc.clone(), time, destination, message)
+            .unwrap();
 
     f(
         milliseconds,
@@ -139,9 +138,11 @@ where
     );
 }
 
-pub fn without_timer_returns_false(result: fn(&Process, Term) -> exception::Result<Term>) {
+pub fn without_timer_returns_false(
+    result: fn(&Process, Term) -> Result<Term, NonNull<ErlangException>>,
+) {
     with_process(|process| {
-        let timer_reference = process.next_reference();
+        let timer_reference = next_local_reference_term(process).unwrap();
 
         assert_eq!(result(process, timer_reference), Ok(false.into()));
     });
diff --git a/native_implemented/otp/src/test/anonymous_0.rs b/native_implemented/otp/src/test/anonymous_0.rs
index a685e4f4c..351db545d 100644
--- a/native_implemented/otp/src/test/anonymous_0.rs
+++ b/native_implemented/otp/src/test/anonymous_0.rs
@@ -1,6 +1,5 @@
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::closure::*;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 pub fn anonymous_closure(process: &Process) -> Term {
     process.anonymous_closure_with_env_from_slice(
diff --git a/native_implemented/otp/src/test/anonymous_1.rs b/native_implemented/otp/src/test/anonymous_1.rs
index 4a170701f..58e989e3a 100644
--- a/native_implemented/otp/src/test/anonymous_1.rs
+++ b/native_implemented/otp/src/test/anonymous_1.rs
@@ -1,6 +1,5 @@
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::closure::*;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 pub fn anonymous_closure(process: &Process) -> Term {
     process.anonymous_closure_with_env_from_slice(
diff --git a/native_implemented/otp/src/test/init.rs b/native_implemented/otp/src/test/init.rs
index cf4404a53..030854721 100644
--- a/native_implemented/otp/src/test/init.rs
+++ b/native_implemented/otp/src/test/init.rs
@@ -1,6 +1,6 @@
 pub mod start_0;
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Atom;
 
 fn module() -> Atom {
     Atom::from_str("init")
diff --git a/native_implemented/otp/src/test/init/start_0.rs b/native_implemented/otp/src/test/init/start_0.rs
index 7cf89309b..93a7306d7 100644
--- a/native_implemented/otp/src/test/init/start_0.rs
+++ b/native_implemented/otp/src/test/init/start_0.rs
@@ -1,5 +1,5 @@
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(test:start/0)]
 fn result(process: &Process) -> Term {
diff --git a/native_implemented/otp/src/test/loop_0.rs b/native_implemented/otp/src/test/loop_0.rs
index 9fabbc1ad..68cde02aa 100644
--- a/native_implemented/otp/src/test/loop_0.rs
+++ b/native_implemented/otp/src/test/loop_0.rs
@@ -1,5 +1,5 @@
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 pub use super::module;
 
diff --git a/native_implemented/otp/src/test/process.rs b/native_implemented/otp/src/test/process.rs
index 07ceb08e7..99be8b9e2 100644
--- a/native_implemented/otp/src/test/process.rs
+++ b/native_implemented/otp/src/test/process.rs
@@ -2,8 +2,8 @@ use std::sync::{Arc, Once};
 
 use panic_control::chain_hook_ignoring;
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::runtime::process::set_log_exit;
 use crate::runtime::process::spawn::Options;
diff --git a/native_implemented/otp/src/test/proptest.rs b/native_implemented/otp/src/test/proptest.rs
index a6b7344fe..56e1b1402 100644
--- a/native_implemented/otp/src/test/proptest.rs
+++ b/native_implemented/otp/src/test/proptest.rs
@@ -1,7 +1,6 @@
 pub mod float_to_string;
 
-use std::convert::TryInto;
-
+use std::ptr::NonNull;
 use std::sync::atomic::AtomicUsize;
 use std::sync::Arc;
 
@@ -13,10 +12,9 @@ use proptest::strategy::{Just, Strategy};
 use proptest::test_runner::{Config, TestCaseResult, TestRunner};
 use proptest::{prop_assert, prop_assert_eq};
 
-use liblumen_alloc::erts::message::{self, Message};
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
-use liblumen_alloc::erts::{exception, Node};
+use firefly_rt::error::ErlangException;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Atom, Term};
 
 use crate::test::strategy::term::binary;
 use crate::test::strategy::term::binary::sub::{bit_offset, byte_count, byte_offset};
@@ -61,8 +59,8 @@ pub fn arc_process_to_arc_process_subbinary_zero_start_byte_count_length(
             (
                 arc_process.clone(),
                 binary,
-                arc_process.integer(0),
-                arc_process.integer(subbinary.full_byte_len()),
+                arc_process.integer(0.into()).unwrap(),
+                arc_process.integer(subbinary.full_byte_len()).unwrap(),
             )
         })
 }
@@ -123,7 +121,7 @@ pub fn monitored_count(process: &Process) -> usize {
 
 pub fn number_to_integer_with_float(
     source_file: &'static str,
-    result: fn(&Process, Term) -> exception::Result<Term>,
+    result: fn(&Process, Term) -> Result<Term, NonNull<ErlangException>>,
     non_zero_assertion: fn(Term, f64, Term) -> TestCaseResult,
 ) {
     run(
@@ -131,7 +129,7 @@ pub fn number_to_integer_with_float(
         |arc_process| {
             (
                 Just(arc_process.clone()),
-                strategy::term::float(arc_process.clone()),
+                strategy::term::float(),
             )
         },
         |(arc_process, number)| {
@@ -198,12 +196,12 @@ pub fn timeout_message(timer_reference: Term, message: Term, process: &Process)
 }
 
 pub fn timer_message(tag: &str, timer_reference: Term, message: Term, process: &Process) -> Term {
-    process.tuple_from_slice(&[Atom::str_to_term(tag), timer_reference, message])
+    process.tuple_term_from_term_slice(&[Atom::str_to_term(tag), timer_reference, message])
 }
 
 pub fn with_binary_without_atom_encoding_errors_badarg(
     source_file: &'static str,
-    result: fn(Term, Term) -> exception::Result<Term>,
+    result: fn(Term, Term) -> Result<Term, NonNull<ErlangException>>,
 ) {
     run(
         source_file,
@@ -226,7 +224,7 @@ pub fn with_binary_without_atom_encoding_errors_badarg(
 
 pub fn with_binary_with_atom_without_name_encoding_errors_badarg(
     source_file: &'static str,
-    result: fn(Term, Term) -> exception::Result<Term>,
+    result: fn(Term, Term) -> Result<Term, NonNull<ErlangException>>,
 ) {
     run(
         source_file,
@@ -241,7 +239,7 @@ pub fn with_binary_with_atom_without_name_encoding_errors_badarg(
 
             prop_assert_badarg!(
                         result(binary, encoding),
-                        format!("invalid atom encoding name: '{0}' is not one of the supported values (latin1, unicode, or utf8)", encoding_atom.name())
+                        format!("invalid atom encoding name: '{0}' is not one of the supported values (latin1, unicode, or utf8)", encoding_atom.as_str())
                     );
 
             Ok(())
@@ -251,7 +249,7 @@ pub fn with_binary_with_atom_without_name_encoding_errors_badarg(
 
 pub fn with_integer_returns_integer(
     source_file: &'static str,
-    result: fn(&Process, Term) -> exception::Result<Term>,
+    result: fn(&Process, Term) -> Result<Term, NonNull<ErlangException>>,
 ) {
     run(
         source_file,
@@ -271,7 +269,7 @@ pub fn with_integer_returns_integer(
 
 pub fn without_boolean_left_errors_badarg(
     source_file: &'static str,
-    result: fn(Term, Term) -> exception::Result<Term>,
+    result: fn(Term, Term) -> Result<Term, NonNull<ErlangException>>,
 ) {
     run(
         source_file,
@@ -291,7 +289,7 @@ pub fn without_boolean_left_errors_badarg(
 
 pub fn without_binary_errors_badarg(
     source_file: &'static str,
-    result: fn(&Process, Term) -> exception::Result<Term>,
+    result: fn(&Process, Term) -> Result<Term, NonNull<ErlangException>>,
 ) {
     run(
         source_file,
@@ -314,7 +312,7 @@ pub fn without_binary_errors_badarg(
 
 pub fn without_binary_with_encoding_is_not_binary(
     source_file: &'static str,
-    result: fn(Term, Term) -> exception::Result<Term>,
+    result: fn(Term, Term) -> Result<Term, NonNull<ErlangException>>,
 ) {
     run(
         source_file,
@@ -334,7 +332,7 @@ pub fn without_binary_with_encoding_is_not_binary(
 
 pub fn without_bitstring_errors_badarg(
     source_file: &'static str,
-    result: fn(&Process, Term) -> exception::Result<Term>,
+    result: fn(&Process, Term) -> Result<Term, NonNull<ErlangException>>,
 ) {
     run(
         source_file,
@@ -357,7 +355,7 @@ pub fn without_bitstring_errors_badarg(
 
 pub fn without_float_errors_badarg(
     source_file: &'static str,
-    result: fn(&Process, Term) -> exception::Result<Term>,
+    result: fn(&Process, Term) -> Result<Term, NonNull<ErlangException>>,
 ) {
     run(
         source_file,
@@ -380,7 +378,7 @@ pub fn without_float_errors_badarg(
 
 pub fn without_float_with_empty_options_errors_badarg(
     source_file: &'static str,
-    result: fn(&Process, Term, Term) -> exception::Result<Term>,
+    result: fn(&Process, Term, Term) -> Result<Term, NonNull<ErlangException>>,
 ) {
     run(
         source_file,
@@ -391,7 +389,7 @@ pub fn without_float_with_empty_options_errors_badarg(
             )
         },
         |(arc_process, float)| {
-            let options = Term::NIL;
+            let options = Term::Nil;
 
             prop_assert_badarg!(
                 result(&arc_process, float, options),
@@ -405,14 +403,14 @@ pub fn without_float_with_empty_options_errors_badarg(
 
 pub fn without_function_errors_badarg(
     source_file: &'static str,
-    result: fn(&Process, Term) -> exception::Result<Term>,
+    result: fn(&Process, Term) -> Result<Term, NonNull<ErlangException>>,
 ) {
     run(
         source_file,
         |arc_process| {
             (
                 Just(arc_process.clone()),
-                strategy::term::is_not_function(arc_process.clone()),
+                strategy::term::is_not_closure(arc_process.clone()),
             )
         },
         |(arc_process, function)| {
@@ -428,7 +426,7 @@ pub fn without_function_errors_badarg(
 
 pub fn without_integer_errors_badarg(
     source_file: &'static str,
-    result: fn(&Process, Term) -> exception::Result<Term>,
+    result: fn(&Process, Term) -> Result<Term, NonNull<ErlangException>>,
 ) {
     run(
         source_file,
@@ -451,7 +449,7 @@ pub fn without_integer_errors_badarg(
 
 pub fn without_integer_integer_with_base_errors_badarg(
     source_file: &'static str,
-    result: fn(&Process, Term, Term) -> exception::Result<Term>,
+    result: fn(&Process, Term, Term) -> Result<Term, NonNull<ErlangException>>,
 ) {
     run(
         source_file,
@@ -475,7 +473,7 @@ pub fn without_integer_integer_with_base_errors_badarg(
 
 pub fn with_integer_integer_without_base_base_errors_badarg(
     source_file: &'static str,
-    result: fn(&Process, Term, Term) -> exception::Result<Term>,
+    result: fn(&Process, Term, Term) -> Result<Term, NonNull<ErlangException>>,
 ) {
     run(
         source_file,
@@ -499,7 +497,7 @@ pub fn with_integer_integer_without_base_base_errors_badarg(
 
 pub fn without_integer_dividend_errors_badarith(
     source_file: &'static str,
-    result: fn(&Process, Term, Term) -> exception::Result<Term>,
+    result: fn(&Process, Term, Term) -> Result<Term, NonNull<ErlangException>>,
 ) {
     run(
         source_file,
@@ -526,7 +524,7 @@ pub fn without_integer_dividend_errors_badarith(
 
 pub fn with_integer_dividend_without_integer_divisor_errors_badarith(
     source_file: &'static str,
-    result: fn(&Process, Term, Term) -> exception::Result<Term>,
+    result: fn(&Process, Term, Term) -> Result<Term, NonNull<ErlangException>>,
 ) {
     run(
         source_file,
@@ -553,7 +551,7 @@ pub fn with_integer_dividend_without_integer_divisor_errors_badarith(
 
 pub fn with_integer_dividend_with_zero_divisor_errors_badarith(
     source_file: &'static str,
-    result: fn(&Process, Term, Term) -> exception::Result<Term>,
+    result: fn(&Process, Term, Term) -> Result<Term, NonNull<ErlangException>>,
 ) {
     run(
         source_file,
@@ -561,7 +559,7 @@ pub fn with_integer_dividend_with_zero_divisor_errors_badarith(
             (
                 Just(arc_process.clone()),
                 strategy::term::is_integer(arc_process.clone()),
-                Just(arc_process.integer(0)),
+                Just(arc_process.integer(0).unwrap()),
             )
         },
         |(arc_process, dividend, divisor)| {
@@ -577,7 +575,7 @@ pub fn with_integer_dividend_with_zero_divisor_errors_badarith(
 
 pub fn without_number_errors_badarg(
     source_file: &'static str,
-    result: fn(&Process, Term) -> exception::Result<Term>,
+    result: fn(&Process, Term) -> Result<Term, NonNull<ErlangException>>,
 ) {
     run(
         source_file,
@@ -597,7 +595,7 @@ pub fn without_number_errors_badarg(
 
 pub fn without_timer_reference_errors_badarg(
     source_file: &'static str,
-    result: fn(&Process, Term) -> exception::Result<Term>,
+    result: fn(&Process, Term) -> Result<Term, NonNull<ErlangException>>,
 ) {
     run(
         source_file,
diff --git a/native_implemented/otp/src/test/proptest/float_to_string.rs b/native_implemented/otp/src/test/proptest/float_to_string.rs
index 8ba37f3b4..f2a3d4310 100644
--- a/native_implemented/otp/src/test/proptest/float_to_string.rs
+++ b/native_implemented/otp/src/test/proptest/float_to_string.rs
@@ -4,19 +4,19 @@ use proptest::strategy::BoxedStrategy;
 
 pub fn without_valid_option_errors_badarg(
     source_file: &'static str,
-    result: fn(&Process, Term, Term) -> exception::Result<Term>,
+    result: fn(&Process, Term, Term) -> Result<Term, NonNull<ErlangException>>,
 ) {
     run(
         source_file,
         |arc_process| {
             (
                 Just(arc_process.clone()),
-                super::strategy::term::float(arc_process.clone()),
+                super::strategy::term::float(),
                 (
                     Just(arc_process.clone()),
                     is_not_option(arc_process.clone()),
                 )
-                    .prop_map(|(arc_process, option)| arc_process.list_from_slice(&[option])),
+                    .prop_map(|(arc_process, option)| arc_process.list_from_slice(&[option])).unwrap(),
             )
         },
         |(arc_process, float, options)| {
@@ -37,22 +37,22 @@ fn is_not_option(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
 }
 
 fn is_option(term: &Term) -> bool {
-    match term.decode().unwrap() {
-        TypedTerm::Atom(atom) => atom.name() == "compact",
-        TypedTerm::Tuple(tuple) => {
+    match term {
+        Term::Atom(atom) => atom.as_str() == "compact",
+        Term::Tuple(tuple) => {
             (tuple.len() == 2) && {
-                match tuple[0].decode().unwrap() {
-                    TypedTerm::Atom(tag_atom) => match tag_atom.name() {
-                        "decimals" => match tuple[1].decode().unwrap() {
-                            TypedTerm::SmallInteger(small_integer) => {
+                match tuple[0] {
+                    Term::Atom(tag_atom) => match tag_atom.as_str() {
+                        "decimals" => match tuple[1] {
+                            Term::Int(small_integer) => {
                                 let i: isize = small_integer.into();
 
                                 0 <= i && i <= 253
                             }
                             _ => false,
                         },
-                        "scientific" => match tuple[1].decode().unwrap() {
-                            TypedTerm::SmallInteger(small_integer) => {
+                        "scientific" => match tuple[1] {
+                            Term::Int(small_integer) => {
                                 let i: isize = small_integer.into();
 
                                 0 <= i && i <= 249
diff --git a/native_implemented/otp/src/test/return_from_fn_0.rs b/native_implemented/otp/src/test/return_from_fn_0.rs
index ea2a06b9b..f7dd99492 100644
--- a/native_implemented/otp/src/test/return_from_fn_0.rs
+++ b/native_implemented/otp/src/test/return_from_fn_0.rs
@@ -1,4 +1,4 @@
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 pub fn returned() -> Term {
     Atom::str_to_term("returned_from_fn")
diff --git a/native_implemented/otp/src/test/return_from_fn_1.rs b/native_implemented/otp/src/test/return_from_fn_1.rs
index 35f35ede4..0ba4b57a6 100644
--- a/native_implemented/otp/src/test/return_from_fn_1.rs
+++ b/native_implemented/otp/src/test/return_from_fn_1.rs
@@ -1,4 +1,4 @@
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::Term;
 
 #[native_implemented::function(test:return_from_fn/1)]
 fn result(argument: Term) -> Term {
diff --git a/native_implemented/otp/src/test/strategy.rs b/native_implemented/otp/src/test/strategy.rs
index 259fd59bd..fd0d36370 100644
--- a/native_implemented/otp/src/test/strategy.rs
+++ b/native_implemented/otp/src/test/strategy.rs
@@ -1,4 +1,5 @@
 use std::ops::RangeInclusive;
+use std::str::FromStr;
 use std::sync::Arc;
 
 use proptest::arbitrary::any;
@@ -6,9 +7,9 @@ use proptest::collection::SizeRange;
 use proptest::prop_oneof;
 use proptest::strategy::{BoxedStrategy, Just, Strategy};
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
-use liblumen_alloc::erts::time::Milliseconds;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Atom, Term};
+use firefly_rt::time::Milliseconds;
 
 pub mod base;
 pub mod byte_vec;
@@ -25,7 +26,7 @@ pub fn atom() -> BoxedStrategy<Atom> {
         .prop_filter("Reserved for existing/safe atom tests", |s| {
             !s.starts_with(NON_EXISTENT_ATOM_PREFIX)
         })
-        .prop_map(|s| Atom::try_from_str(&s).unwrap())
+        .prop_map(|s| Atom::from_str(&s).unwrap())
         .boxed()
 }
 
@@ -39,11 +40,11 @@ pub fn byte_vec() -> BoxedStrategy<Vec<u8>> {
 
 pub fn milliseconds() -> BoxedStrategy<Milliseconds> {
     prop_oneof![
-        Just(crate::runtime::timer::at_once_milliseconds()),
-        Just(crate::runtime::timer::soon_milliseconds()) /* TODO make timer::timeout() faster when there are lots of empty slots to skip,
-                                                         Just(crate::runtime::timer::later_milliseconds()),
-                                                         Just(crate::runtime::timer::long_term_milliseconds())
-                                                         */
+        Just(runtime::timer::at_once_milliseconds()),
+        Just(runtime::timer::soon_milliseconds()) /* TODO make timer::timeout() faster when there are lots of empty slots to skip,
+                                                  Just(runtime::timer::later_milliseconds()),
+                                                  Just(runtime::timer::long_term_milliseconds())
+                                                  */
     ]
     .boxed()
 }
diff --git a/native_implemented/otp/src/test/strategy/module_function_arity.rs b/native_implemented/otp/src/test/strategy/module_function_arity.rs
index fc2141282..917dfb197 100644
--- a/native_implemented/otp/src/test/strategy/module_function_arity.rs
+++ b/native_implemented/otp/src/test/strategy/module_function_arity.rs
@@ -1,7 +1,7 @@
 use proptest::arbitrary::any;
 use proptest::strategy::{BoxedStrategy, Strategy};
 
-use liblumen_alloc::erts::term::prelude::Atom;
+use firefly_rt::term::Atom;
 
 use crate::test::strategy::term::NON_EXISTENT_ATOM_PREFIX;
 
diff --git a/native_implemented/otp/src/test/strategy/node.rs b/native_implemented/otp/src/test/strategy/node.rs
index b07313597..5abfe8f28 100644
--- a/native_implemented/otp/src/test/strategy/node.rs
+++ b/native_implemented/otp/src/test/strategy/node.rs
@@ -6,7 +6,7 @@ use std::sync::Arc;
 use proptest::arbitrary::any;
 use proptest::strategy::{BoxedStrategy, Strategy};
 
-use liblumen_alloc::erts::Node;
+use firefly_rt::term::Node;
 
 use crate::runtime::distribution::nodes;
 
diff --git a/native_implemented/otp/src/test/strategy/node/atom.rs b/native_implemented/otp/src/test/strategy/node/atom.rs
index beb811fb1..0933be306 100644
--- a/native_implemented/otp/src/test/strategy/node/atom.rs
+++ b/native_implemented/otp/src/test/strategy/node/atom.rs
@@ -1,7 +1,7 @@
 use proptest::arbitrary::any;
 use proptest::strategy::{BoxedStrategy, Strategy};
 
-use liblumen_alloc::erts::term::prelude::Atom;
+use firefly_rt::term::Atom;
 
 pub fn external() -> BoxedStrategy<Atom> {
     any::<String>()
diff --git a/native_implemented/otp/src/test/strategy/node/id.rs b/native_implemented/otp/src/test/strategy/node/id.rs
index b44254cb6..4be09bb0c 100644
--- a/native_implemented/otp/src/test/strategy/node/id.rs
+++ b/native_implemented/otp/src/test/strategy/node/id.rs
@@ -3,7 +3,7 @@ use proptest::strategy::{BoxedStrategy, Strategy};
 pub fn external() -> BoxedStrategy<usize> {
     super::id()
         .prop_filter("Can't be local node ID", |id| {
-            id != &crate::runtime::distribution::nodes::node::id()
+            id != &runtime::distribution::nodes::node::id()
         })
         .boxed()
 }
diff --git a/native_implemented/otp/src/test/strategy/term.rs b/native_implemented/otp/src/test/strategy/term.rs
index b0ec89efe..733949df5 100644
--- a/native_implemented/otp/src/test/strategy/term.rs
+++ b/native_implemented/otp/src/test/strategy/term.rs
@@ -1,5 +1,4 @@
 use std::cmp::{max, min};
-use std::convert::TryInto;
 use std::num::FpCategory;
 use std::ops::RangeInclusive;
 use std::sync::Arc;
@@ -9,9 +8,11 @@ use proptest::collection::SizeRange;
 use proptest::prop_oneof;
 use proptest::strategy::{BoxedStrategy, Just, Strategy};
 
-use liblumen_alloc::erts::term::prelude::*;
-use liblumen_alloc::erts::Process;
-use liblumen_alloc::{atom, fixnum_from};
+use firefly_alloc::gc::GcBox;
+
+use firefly_rt::process::Process;
+use firefly_rt::term::{atoms, Float, Integer, Term};
+use firefly_rt_tiny::scheduler::local_reference_term;
 
 use super::size_range;
 
@@ -29,7 +30,7 @@ pub const NON_EXISTENT_ATOM_PREFIX: &str = "non_existent";
 
 pub fn atom() -> BoxedStrategy<Term> {
     super::atom()
-        .prop_map(|atom| atom.encode().unwrap())
+        .prop_map(|atom| atom.into())
         .boxed()
 }
 
@@ -52,7 +53,7 @@ pub fn charlist(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
                 .map(|f| f.into())
                 .collect();
 
-            arc_process.list_from_slice(&codepoint_terms)
+            arc_process.list_from_slice(&codepoint_terms).unwrap()
         })
         .boxed()
 }
@@ -70,12 +71,12 @@ pub fn container(
     .boxed()
 }
 
-pub fn float(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
+pub fn float() -> BoxedStrategy<Term> {
     any::<f64>()
         .prop_filter("Negative and positive 0.0 are the same for Erlang", |f| {
             !(f.classify() == FpCategory::Zero && f.is_sign_negative())
         })
-        .prop_map(move |f| arc_process.float(f))
+        .prop_map(move |f| f.into())
         .boxed()
 }
 
@@ -95,7 +96,7 @@ pub fn function_port_pid_tuple_map_list_or_bitstring(
 
 pub fn is_base(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
     super::base::base()
-        .prop_map(move |base| arc_process.integer(base))
+        .prop_map(move |base| arc_process.integer(base).unwrap())
         .boxed()
 }
 
@@ -117,15 +118,15 @@ pub fn is_boolean() -> BoxedStrategy<Term> {
 
 pub fn is_byte(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
     (Just(arc_process), any::<u8>())
-        .prop_map(|(arc_process, byte_u8)| arc_process.integer(byte_u8))
+        .prop_map(|(arc_process, byte_u8)| arc_process.integer(byte_u8).unwrap())
         .boxed()
 }
 
 pub fn is_encoding() -> BoxedStrategy<Term> {
     prop_oneof![
-        Just(atom!("latin1")),
-        Just(atom!("unicode")),
-        Just(atom!("utf8"))
+        Just(atoms::Latin1.into()),
+        Just(atoms::Unicode.into()),
+        Just(atoms::Utf8.into())
     ]
     .boxed()
 }
@@ -189,9 +190,9 @@ pub fn is_not_atom(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
 pub(crate) fn is_not_base(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
     super::term(arc_process)
         .prop_filter("Cannot be a base (2-36)", |term| {
-            match term.decode().unwrap() {
-                TypedTerm::SmallInteger(small_integer) => {
-                    let integer: isize = small_integer.into();
+            match term {
+                Term::Int(small_integer) => {
+                    let integer = *small_integer;
 
                     (2 <= integer) && (integer <= 36)
                 }
@@ -209,13 +210,13 @@ pub fn is_not_binary(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
         integer::big(arc_process.clone()),
         local_reference(arc_process.clone()),
         is_function(arc_process.clone()),
-        float(arc_process.clone()),
+        float(),
         // TODO `Export`
         // TODO `ReferenceCountedBinary`
         pid::external(arc_process.clone()),
         // TODO `ExternalPort`
         // TODO `ExternalReference`
-        Just(Term::NIL),
+        Just(Term::Nil),
         pid::local(),
         // TODO `LocalPort`,
         atom(),
@@ -233,13 +234,13 @@ pub fn is_not_bitstring(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
         integer::big(arc_process.clone()),
         local_reference(arc_process.clone()),
         is_function(arc_process.clone()),
-        float(arc_process.clone()),
+        float(),
         // TODO `Export`
         // TODO `ReferenceCountedBinary`
         pid::external(arc_process.clone()),
         // TODO `ExternalPort`
         // TODO `ExternalReference`
-        Just(Term::NIL),
+        Just(Term::Nil),
         pid::local(),
         // TODO `LocalPort`,
         atom(),
@@ -255,6 +256,12 @@ pub fn is_not_boolean(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
         .boxed()
 }
 
+pub fn is_not_closure(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
+    super::term(arc_process)
+        .prop_filter("Term cannot be a function", |v| !v.is_closure())
+        .boxed()
+}
+
 pub fn is_not_send_after_destination(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
     super::term(arc_process.clone())
         .prop_filter(
@@ -269,7 +276,7 @@ pub fn is_not_destination(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
         .prop_filter(
             "Destination must not be an atom, pid, or tuple",
             |destination| {
-                !(destination.is_atom() || destination.is_pid() || destination.is_boxed_tuple())
+                !(destination.is_atom() || destination.is_pid() || destination.is_tuple())
             },
         )
         .boxed()
@@ -277,13 +284,7 @@ pub fn is_not_destination(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
 
 pub fn is_not_float(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
     super::term(arc_process)
-        .prop_filter("Term cannot be a float", |v| !v.is_boxed_float())
-        .boxed()
-}
-
-pub fn is_not_function(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
-    super::term(arc_process)
-        .prop_filter("Term cannot be a function", |v| !v.is_boxed_function())
+        .prop_filter("Term cannot be a float", |v| !v.is_float())
         .boxed()
 }
 
@@ -301,7 +302,7 @@ pub fn is_not_list(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
         integer::big(arc_process.clone()),
         local_reference(arc_process.clone()),
         is_function(arc_process.clone()),
-        float(arc_process.clone()),
+        float(),
         // TODO `Export`
         // TODO `ReferenceCountedBinary`
         binary::heap::with_size_range(size_range.clone(), arc_process.clone()),
@@ -329,12 +330,12 @@ pub fn is_not_local_pid(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
 
 pub fn is_not_map(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
     super::term(arc_process)
-        .prop_filter("Term cannot be a map", |v| !v.is_boxed_map())
+        .prop_filter("Term cannot be a map", |v| !v.is_map())
         .boxed()
 }
 
 pub fn is_not_non_negative_integer(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
-    let zero = arc_process.integer(0);
+    let zero = arc_process.integer(0).unwrap();
 
     super::term(arc_process)
         .prop_filter("Term must no be a non-negative integer", move |term| {
@@ -363,7 +364,7 @@ pub fn is_not_proper_list(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
         integer::big(arc_process.clone()),
         local_reference(arc_process.clone()),
         is_function(arc_process.clone()),
-        float(arc_process.clone()),
+        float(),
         // TODO `Export`
         // TODO `ReferenceCountedBinary`
         binary::heap::with_size_range(size_range.clone(), arc_process.clone()),
@@ -392,7 +393,7 @@ pub fn is_not_reference(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
 
 pub fn is_not_tuple(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
     super::term(arc_process)
-        .prop_filter("Value must not be a tuple", |v| !v.is_boxed_tuple())
+        .prop_filter("Value must not be a tuple", |v| !v.is_tuple())
         .boxed()
 }
 
@@ -406,7 +407,7 @@ pub fn is_number(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
 
     prop_oneof![
         integer::big(big_integer_arc_process),
-        float(float_arc_process),
+        float(),
         integer::small(small_integer_arc_process)
     ]
     .boxed()
@@ -433,7 +434,7 @@ pub fn leaf(
         integer::big(arc_process.clone()),
         local_reference(arc_process.clone()),
         is_function(arc_process.clone()),
-        float(arc_process.clone()),
+        float(),
         // TODO `Export`
         // TODO `ReferenceCountedBinary`
         binary::heap::with_size_range(range_inclusive.into(), arc_process.clone()),
@@ -441,7 +442,7 @@ pub fn leaf(
         pid::external(arc_process.clone()),
         // TODO `ExternalPort`
         // TODO `ExternalReference`
-        Just(Term::NIL),
+        Just(Term::Nil),
         pid::local(),
         // TODO `LocalPort`,
         atom(),
@@ -456,7 +457,7 @@ pub fn list_or_bitstring(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
 
 pub fn local_reference(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
     proptest::prelude::any::<u64>()
-        .prop_map(move |number| arc_process.reference(number))
+        .prop_map(move |number| local_reference_term(arc_process, number).unwrap())
         .boxed()
 }
 
@@ -474,8 +475,8 @@ pub fn map_list_or_bitstring(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
 }
 
 fn negative_big_integer_float_integral_i64() -> Option<BoxedStrategy<i64>> {
-    let float_integral_min = Float::INTEGRAL_MIN as i64;
-    let big_integer_max_negative = SmallInteger::MIN_VALUE as i64 - 1;
+    let float_integral_min = Float::I64_LOWER_BOUNDARY as i64;
+    let big_integer_max_negative = Integer::MIN_SMALL as i64 - 1;
 
     if float_integral_min < big_integer_max_negative {
         let boxed_strategy: BoxedStrategy<i64> =
@@ -560,8 +561,8 @@ pub fn pid_or_port(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
 }
 
 fn positive_big_integer_float_integral_i64() -> Option<BoxedStrategy<i64>> {
-    let float_integral_max = Float::INTEGRAL_MAX as i64;
-    let big_integer_min_positive = SmallInteger::MAX_VALUE as i64 + 1;
+    let float_integral_max = Float::I64_UPPER_BOUNDARY as i64;
+    let big_integer_min_positive = Integer::MAX_SMALL as i64 + 1;
 
     if big_integer_min_positive < float_integral_max {
         let boxed_strategy: BoxedStrategy<i64> =
@@ -575,8 +576,8 @@ fn positive_big_integer_float_integral_i64() -> Option<BoxedStrategy<i64>> {
 
 /// Produces `i64` that fall in the range that produce both integral floats and small integers
 pub fn small_integer_float_integral_i64() -> BoxedStrategy<i64> {
-    let integral_min = max(Float::INTEGRAL_MIN as i64, SmallInteger::MIN_VALUE as i64);
-    let integral_max = min(Float::INTEGRAL_MAX as i64, SmallInteger::MAX_VALUE as i64);
+    let integral_min = max(Float::I64_LOWER_BOUNDARY as i64, Integer::MIN_SMALL as i64);
+    let integral_max = min(Float::I64_UPPER_BOUNDARY as i64, Integer::MAX_SMALL as i64);
 
     (integral_min..=integral_max).boxed()
 }
diff --git a/native_implemented/otp/src/test/strategy/term/atom.rs b/native_implemented/otp/src/test/strategy/term/atom.rs
index 1502c52ba..931b18931 100644
--- a/native_implemented/otp/src/test/strategy/term/atom.rs
+++ b/native_implemented/otp/src/test/strategy/term/atom.rs
@@ -1,15 +1,13 @@
-use std::convert::TryInto;
+use proptest::strategy::BoxedStrategy;
 
-use proptest::strategy::{BoxedStrategy, Strategy};
-
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::{Atom, Term};
 
 pub fn is_not_encoding() -> BoxedStrategy<Term> {
     super::atom()
         .prop_filter("Encoding must not be latin1, unicode, utf8", |term| {
             let atom: Atom = (*term).try_into().unwrap();
 
-            match atom.name() {
+            match atom.as_str() {
                 "latin1" | "unicode" | "utf8" => false,
                 _ => true,
             }
diff --git a/native_implemented/otp/src/test/strategy/term/binary.rs b/native_implemented/otp/src/test/strategy/term/binary.rs
index 69bcb0352..648d120e9 100644
--- a/native_implemented/otp/src/test/strategy/term/binary.rs
+++ b/native_implemented/otp/src/test/strategy/term/binary.rs
@@ -4,8 +4,8 @@ use proptest::arbitrary::any;
 use proptest::prop_oneof;
 use proptest::strategy::{BoxedStrategy, Just, Strategy};
 
-use liblumen_alloc::erts::term::prelude::Term;
-use liblumen_alloc::erts::Process;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::test::strategy::size_range;
 use crate::test::strategy::term::binary::sub::{bit_count, bit_offset, byte_count, byte_offset};
diff --git a/native_implemented/otp/src/test/strategy/term/binary/heap.rs b/native_implemented/otp/src/test/strategy/term/binary/heap.rs
index a0c90cca3..13ff8718e 100644
--- a/native_implemented/otp/src/test/strategy/term/binary/heap.rs
+++ b/native_implemented/otp/src/test/strategy/term/binary/heap.rs
@@ -3,8 +3,8 @@ use std::sync::Arc;
 use proptest::collection::SizeRange;
 use proptest::strategy::{BoxedStrategy, Strategy};
 
-use liblumen_alloc::erts::term::prelude::Term;
-use liblumen_alloc::erts::Process;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::test::strategy::byte_vec;
 
diff --git a/native_implemented/otp/src/test/strategy/term/binary/sub.rs b/native_implemented/otp/src/test/strategy/term/binary/sub.rs
index c48311147..49a0ee758 100644
--- a/native_implemented/otp/src/test/strategy/term/binary/sub.rs
+++ b/native_implemented/otp/src/test/strategy/term/binary/sub.rs
@@ -2,8 +2,8 @@ use std::sync::Arc;
 
 use proptest::strategy::{BoxedStrategy, Just, Strategy};
 
-use liblumen_alloc::erts::term::prelude::Term;
-use liblumen_alloc::erts::Process;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::test::strategy::{self, bits_to_bytes, size_range};
 
diff --git a/native_implemented/otp/src/test/strategy/term/binary/sub/is_binary.rs b/native_implemented/otp/src/test/strategy/term/binary/sub/is_binary.rs
index aa0031015..155e10b32 100644
--- a/native_implemented/otp/src/test/strategy/term/binary/sub/is_binary.rs
+++ b/native_implemented/otp/src/test/strategy/term/binary/sub/is_binary.rs
@@ -2,8 +2,8 @@ use std::sync::Arc;
 
 use proptest::strategy::{BoxedStrategy, Strategy};
 
-use liblumen_alloc::erts::term::prelude::Term;
-use liblumen_alloc::erts::Process;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::test::strategy::term::binary::sub::{bit_offset, byte_count, byte_offset};
 
diff --git a/native_implemented/otp/src/test/strategy/term/function.rs b/native_implemented/otp/src/test/strategy/term/function.rs
index e013afbcd..fda32b68a 100644
--- a/native_implemented/otp/src/test/strategy/term/function.rs
+++ b/native_implemented/otp/src/test/strategy/term/function.rs
@@ -8,8 +8,8 @@ use num_bigint::BigInt;
 use proptest::prop_oneof;
 use proptest::strategy::{BoxedStrategy, Strategy};
 
-use liblumen_alloc::erts::term::prelude::*;
-use liblumen_alloc::erts::Process;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Atom, Term};
 
 use crate::test::strategy;
 
@@ -34,7 +34,7 @@ pub fn anonymous(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
 }
 
 pub fn arity(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
-    arity_u8().prop_map(move |u| arc_process.integer(u)).boxed()
+    arity_u8().prop_map(move |u| arc_process.integer(u).unwrap()).boxed()
 }
 
 pub fn arity_or_arguments(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
@@ -59,16 +59,16 @@ pub fn export(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
 
 pub fn is_not_arity_or_arguments(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
     super::super::term(arc_process)
-        .prop_filter("Arity and argument must be neither an arity (>= 0) or arguments (an empty or non-empty proper list)", |term| match term.decode().unwrap() {
-            TypedTerm::Nil => false,
-            TypedTerm::List(cons) => !cons.is_proper(),
-            TypedTerm::BigInteger(big_integer) => {
+        .prop_filter("Arity and argument must be neither an arity (>= 0) or arguments (an empty or non-empty proper list)", |term| match term {
+            Term::Nil => false,
+            Term::Cons(cons) => !cons.is_proper(),
+            Term::BigInt(big_integer) => {
                 let big_int: &BigInt = big_integer.as_ref().into();
                 let zero_big_int: &BigInt = &0.into();
 
                 big_int < zero_big_int
             }
-            TypedTerm::SmallInteger(small_integer) => {
+            Term::Int(small_integer) => {
                 let i: isize = small_integer.into();
 
                 i < 0
diff --git a/native_implemented/otp/src/test/strategy/term/function/anonymous.rs b/native_implemented/otp/src/test/strategy/term/function/anonymous.rs
index a8cb657a0..72b0a87c4 100644
--- a/native_implemented/otp/src/test/strategy/term/function/anonymous.rs
+++ b/native_implemented/otp/src/test/strategy/term/function/anonymous.rs
@@ -1,4 +1,3 @@
-mod creator;
 mod without_native;
 
 use std::convert::TryInto;
@@ -8,16 +7,11 @@ use proptest::arbitrary::any;
 use proptest::prop_oneof;
 use proptest::strategy::{BoxedStrategy, Just, Strategy};
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::closure::Creator;
-use liblumen_alloc::erts::term::prelude::Term;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::test;
 
-pub fn creator() -> BoxedStrategy<Creator> {
-    prop_oneof![creator::local(), creator::external()].boxed()
-}
-
 pub fn index() -> BoxedStrategy<u32> {
     // A `u32`, but must be encodable as an `i32` for INTEGER_EXT
     (0..=(std::i32::MAX as u32)).boxed()
@@ -62,9 +56,8 @@ pub fn without_native(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
         old_unique(),
         unique(),
         super::arity_u8(),
-        creator(),
     )
-        .prop_map(move |(module, index, old_unique, unique, arity, creator)| {
+        .prop_map(move |(module, index, old_unique, unique, arity)| {
             arc_process.anonymous_closure_with_env_from_slice(
                 module,
                 index,
@@ -72,7 +65,6 @@ pub fn without_native(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
                 unique,
                 arity,
                 None,
-                creator,
                 &[],
             )
         })
diff --git a/native_implemented/otp/src/test/strategy/term/function/anonymous/creator.rs b/native_implemented/otp/src/test/strategy/term/function/anonymous/creator.rs
deleted file mode 100644
index 463c21218..000000000
--- a/native_implemented/otp/src/test/strategy/term/function/anonymous/creator.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-use proptest::strategy::{BoxedStrategy, Strategy};
-
-use liblumen_alloc::erts::term::closure::Creator;
-use liblumen_alloc::erts::term::prelude::{ExternalPid, Pid};
-
-use crate::test::strategy::node;
-use crate::test::strategy::term::pid;
-
-pub fn external() -> BoxedStrategy<Creator> {
-    (node::external(), pid::number(), pid::serial())
-        .prop_map(|(arc_node, number, serial)| ExternalPid::new(arc_node, number, serial).unwrap())
-        .prop_map(|external_pid| Creator::External(external_pid))
-        .boxed()
-}
-
-pub fn local() -> BoxedStrategy<Creator> {
-    (pid::number(), pid::serial())
-        .prop_map(|(number, serial)| Pid::new(number, serial).unwrap())
-        .prop_map(|local_pid| Creator::Local(local_pid))
-        .boxed()
-}
diff --git a/native_implemented/otp/src/test/strategy/term/function/anonymous/without_native.rs b/native_implemented/otp/src/test/strategy/term/function/anonymous/without_native.rs
index 6c6da5113..4702d9f4f 100644
--- a/native_implemented/otp/src/test/strategy/term/function/anonymous/without_native.rs
+++ b/native_implemented/otp/src/test/strategy/term/function/anonymous/without_native.rs
@@ -1,9 +1,9 @@
 use std::sync::Arc;
 
-use proptest::strategy::{BoxedStrategy, Strategy};
+use proptest::strategy::BoxedStrategy;
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 pub fn with_arity(arc_process: Arc<Process>, arity: u8) -> BoxedStrategy<Term> {
     (
@@ -11,9 +11,8 @@ pub fn with_arity(arc_process: Arc<Process>, arity: u8) -> BoxedStrategy<Term> {
         super::index(),
         super::old_unique(),
         super::unique(),
-        super::creator(),
     )
-        .prop_map(move |(module, index, old_unique, unique, creator)| {
+        .prop_map(move |(module, index, old_unique, unique)| {
             arc_process.anonymous_closure_with_env_from_slice(
                 module,
                 index,
@@ -21,7 +20,6 @@ pub fn with_arity(arc_process: Arc<Process>, arity: u8) -> BoxedStrategy<Term> {
                 unique,
                 arity,
                 None,
-                creator,
                 &[],
             )
         })
diff --git a/native_implemented/otp/src/test/strategy/term/function/export.rs b/native_implemented/otp/src/test/strategy/term/function/export.rs
index f6047f7a8..602d5491a 100644
--- a/native_implemented/otp/src/test/strategy/term/function/export.rs
+++ b/native_implemented/otp/src/test/strategy/term/function/export.rs
@@ -5,8 +5,8 @@ use std::sync::Arc;
 use proptest::prop_oneof;
 use proptest::strategy::{BoxedStrategy, Just, Strategy};
 
-use liblumen_alloc::erts::term::prelude::{Atom, Term};
-use liblumen_alloc::erts::Process;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Atom, Term};
 
 use crate::erlang;
 use crate::test::strategy;
diff --git a/native_implemented/otp/src/test/strategy/term/function/export/without_native.rs b/native_implemented/otp/src/test/strategy/term/function/export/without_native.rs
index 5fc5baded..94dd853d9 100644
--- a/native_implemented/otp/src/test/strategy/term/function/export/without_native.rs
+++ b/native_implemented/otp/src/test/strategy/term/function/export/without_native.rs
@@ -1,9 +1,9 @@
 use std::sync::Arc;
 
-use proptest::strategy::{BoxedStrategy, Strategy};
+use proptest::strategy::BoxedStrategy;
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 pub fn with_arity(arc_process: Arc<Process>, arity: u8) -> BoxedStrategy<Term> {
     (super::module_atom(), super::function())
diff --git a/native_implemented/otp/src/test/strategy/term/index.rs b/native_implemented/otp/src/test/strategy/term/index.rs
index 4ead146f8..7dd6ad879 100644
--- a/native_implemented/otp/src/test/strategy/term/index.rs
+++ b/native_implemented/otp/src/test/strategy/term/index.rs
@@ -4,7 +4,7 @@ use num_bigint::BigInt;
 
 use proptest::strategy::{BoxedStrategy, Strategy};
 
-use liblumen_alloc::erts::Process;
+use firefly_rt::process::Process;
 
 use crate::test::strategy;
 
@@ -20,13 +20,13 @@ pub fn is_not_one_based(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
     strategy::term(arc_process)
         .prop_filter(
             "Index either must not be an integer or must be an integer <= 1",
-            |index| match index.decode().unwrap() {
-                TypedTerm::SmallInteger(small_integer) => {
+            |index| match index {
+                Term::Int(small_integer) => {
                     let i: isize = small_integer.into();
 
                     i < 1
                 }
-                TypedTerm::BigInteger(big_integer) => {
+                Term::BigInt(big_integer) => {
                     let index_big_int: &BigInt = big_integer.as_ref().into();
                     let one_big_int: BigInt = 1.into();
 
diff --git a/native_implemented/otp/src/test/strategy/term/integer.rs b/native_implemented/otp/src/test/strategy/term/integer.rs
index c9332a8ab..0ad18fa64 100644
--- a/native_implemented/otp/src/test/strategy/term/integer.rs
+++ b/native_implemented/otp/src/test/strategy/term/integer.rs
@@ -3,8 +3,6 @@ use std::sync::Arc;
 use proptest::prop_oneof;
 use proptest::strategy::{BoxedStrategy, Strategy};
 
-use liblumen_alloc::erts::Process;
-
 use super::*;
 
 pub mod big;
@@ -51,7 +49,7 @@ pub fn positive(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
 }
 
 pub fn small(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
-    (SmallInteger::MIN_VALUE..=SmallInteger::MAX_VALUE)
-        .prop_map(move |i| arc_process.integer(i))
+    (Integer::MIN_SMALL..=Integer::MAX_SMALL)
+        .prop_map(move |i| arc_process.integer(i).unwrap())
         .boxed()
 }
diff --git a/native_implemented/otp/src/test/strategy/term/integer/big.rs b/native_implemented/otp/src/test/strategy/term/integer/big.rs
index 90131d381..e0dc93676 100644
--- a/native_implemented/otp/src/test/strategy/term/integer/big.rs
+++ b/native_implemented/otp/src/test/strategy/term/integer/big.rs
@@ -2,25 +2,26 @@ use std::sync::Arc;
 
 use proptest::prop_oneof;
 use proptest::strategy::{BoxedStrategy, Strategy};
+use firefly_rt::term::Integer;
 
 use super::*;
 
 pub fn isize() -> BoxedStrategy<isize> {
     prop_oneof![
-        (std::isize::MIN..(SmallInteger::MIN_VALUE - 1)),
-        ((SmallInteger::MAX_VALUE + 1)..std::isize::MAX)
+        (std::isize::MIN..(Integer::MIN_SMALL - 1)),
+        ((Integer::MAX_SMALL + 1)..std::isize::MAX)
     ]
     .boxed()
 }
 
 pub fn negative(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
-    (std::isize::MIN..(SmallInteger::MIN_VALUE - 1))
-        .prop_map(move |i| arc_process.integer(i))
+    (isize::MIN..(Integer::MIN_SMALL - 1))
+        .prop_map(move |i| arc_process.integer(i).unwrap())
         .boxed()
 }
 
 pub fn positive(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
-    ((SmallInteger::MAX_VALUE + 1)..std::isize::MAX)
-        .prop_map(move |i| arc_process.integer(i))
+    ((Integer::MAX_SMALL + 1)..isize::MAX)
+        .prop_map(move |i| arc_process.integer(i).unwrap())
         .boxed()
 }
diff --git a/native_implemented/otp/src/test/strategy/term/integer/small.rs b/native_implemented/otp/src/test/strategy/term/integer/small.rs
index 250b2cc4e..81b92c486 100644
--- a/native_implemented/otp/src/test/strategy/term/integer/small.rs
+++ b/native_implemented/otp/src/test/strategy/term/integer/small.rs
@@ -2,32 +2,33 @@ use std::sync::Arc;
 
 use proptest::strategy::{BoxedStrategy, Strategy};
 
-use super::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Integer, Term};
 
 pub fn isize() -> BoxedStrategy<isize> {
-    (SmallInteger::MIN_VALUE..=SmallInteger::MAX_VALUE).boxed()
+    (Integer::MIN_SMALL..=Integer::MAX_SMALL).boxed()
 }
 
 pub fn negative(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
-    (SmallInteger::MIN_VALUE..=-1)
-        .prop_map(move |i| arc_process.integer(i))
+    (Integer::MIN_SMALL..=-1)
+        .prop_map(move |i| arc_process.integer(i).unwrap())
         .boxed()
 }
 
 pub fn non_negative(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
-    (0..=SmallInteger::MAX_VALUE)
-        .prop_map(move |i| arc_process.integer(i))
+    (0..=Integer::MAX_SMALL)
+        .prop_map(move |i| arc_process.integer(i).unwrap())
         .boxed()
 }
 
 pub fn non_positive(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
-    (SmallInteger::MIN_VALUE..=0)
-        .prop_map(move |i| arc_process.integer(i))
+    (Integer::MIN_SMALL..=0)
+        .prop_map(move |i| arc_process.integer(i).unwrap())
         .boxed()
 }
 
 pub fn positive(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
-    (1..=SmallInteger::MAX_VALUE)
-        .prop_map(move |i| arc_process.integer(i))
+    (1..=Integer::MAX_SMALL)
+        .prop_map(move |i| arc_process.integer(i).unwrap())
         .boxed()
 }
diff --git a/native_implemented/otp/src/test/strategy/term/list.rs b/native_implemented/otp/src/test/strategy/term/list.rs
index d2d8f029f..df5a304fa 100644
--- a/native_implemented/otp/src/test/strategy/term/list.rs
+++ b/native_implemented/otp/src/test/strategy/term/list.rs
@@ -6,8 +6,8 @@ use proptest::collection::SizeRange;
 use proptest::prop_oneof;
 use proptest::strategy::{BoxedStrategy, Just, Strategy};
 
-use liblumen_alloc::erts::term::prelude::Term;
-use liblumen_alloc::erts::Process;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::test::strategy::{self, NON_EMPTY_RANGE_INCLUSIVE};
 
@@ -30,8 +30,8 @@ pub fn intermediate(
 ) -> BoxedStrategy<Term> {
     proptest::collection::vec(element, size_range)
         .prop_map(move |vec| match vec.len() {
-            0 => Term::NIL,
-            1 => arc_process.list_from_slice(&vec),
+            0 => Term::Nil,
+            1 => arc_process.list_from_slice(&vec).unwrap(),
             len => {
                 let last_index = len - 1;
 
@@ -46,7 +46,7 @@ pub fn non_empty_maybe_improper(arc_process: Arc<Process>) -> BoxedStrategy<Term
 
     proptest::collection::vec(strategy::term(arc_process.clone()), size_range)
         .prop_map(move |vec| match vec.len() {
-            1 => arc_process.list_from_slice(&vec),
+            1 => arc_process.list_from_slice(&vec).unwrap(),
             len => {
                 let last_index = len - 1;
 
@@ -63,10 +63,10 @@ pub fn non_empty_proper(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
         Just(arc_process.clone()),
         proptest::collection::vec(strategy::term(arc_process), size_range),
     )
-        .prop_map(|(arc_process, vec)| arc_process.list_from_slice(&vec))
+        .prop_map(|(arc_process, vec)| arc_process.list_from_slice(&vec)).unwrap()
         .boxed()
 }
 
 pub fn proper(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
-    prop_oneof![Just(Term::NIL), non_empty_proper(arc_process)].boxed()
+    prop_oneof![Just(Term::Nil), non_empty_proper(arc_process)].boxed()
 }
diff --git a/native_implemented/otp/src/test/strategy/term/list/io.rs b/native_implemented/otp/src/test/strategy/term/list/io.rs
index ff89e10fa..a9bc80a64 100644
--- a/native_implemented/otp/src/test/strategy/term/list/io.rs
+++ b/native_implemented/otp/src/test/strategy/term/list/io.rs
@@ -3,8 +3,8 @@ use std::sync::Arc;
 use proptest::prop_oneof;
 use proptest::strategy::{BoxedStrategy, Just, Strategy};
 
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 use crate::test::strategy::term::{is_binary, is_byte};
 use crate::test::strategy::{DEPTH, MAX_LEN};
@@ -53,5 +53,5 @@ pub fn root(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
 }
 
 pub fn tail(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
-    prop_oneof![is_binary(arc_process.clone()), Just(Term::NIL)].boxed()
+    prop_oneof![is_binary(arc_process.clone()), Just(Term::Nil)].boxed()
 }
diff --git a/native_implemented/otp/src/test/strategy/term/map.rs b/native_implemented/otp/src/test/strategy/term/map.rs
index 2086b1768..8dbc73c4a 100644
--- a/native_implemented/otp/src/test/strategy/term/map.rs
+++ b/native_implemented/otp/src/test/strategy/term/map.rs
@@ -3,8 +3,8 @@ use std::sync::Arc;
 use proptest::collection::SizeRange;
 use proptest::strategy::{BoxedStrategy, Strategy};
 
-use liblumen_alloc::erts::term::prelude::Term;
-use liblumen_alloc::erts::Process;
+use firefly_rt::process::Process;
+use firefly_rt::term::Term;
 
 pub fn intermediate(
     key_or_value: BoxedStrategy<Term>,
diff --git a/native_implemented/otp/src/test/strategy/term/pid.rs b/native_implemented/otp/src/test/strategy/term/pid.rs
index db6c958ea..79671200d 100644
--- a/native_implemented/otp/src/test/strategy/term/pid.rs
+++ b/native_implemented/otp/src/test/strategy/term/pid.rs
@@ -2,8 +2,8 @@ use std::sync::Arc;
 
 use proptest::strategy::{BoxedStrategy, Strategy};
 
-use liblumen_alloc::erts::term::prelude::*;
-use liblumen_alloc::erts::Process;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Pid, Term};
 
 use crate::test::strategy::node;
 
diff --git a/native_implemented/otp/src/test/strategy/term/tuple.rs b/native_implemented/otp/src/test/strategy/term/tuple.rs
index 3c761cf2f..38392673d 100644
--- a/native_implemented/otp/src/test/strategy/term/tuple.rs
+++ b/native_implemented/otp/src/test/strategy/term/tuple.rs
@@ -1,14 +1,14 @@
-use std::convert::TryInto;
+use std::ptr::NonNull;
 use std::sync::Arc;
 
 use num_bigint::BigInt;
 
 use proptest::collection::SizeRange;
 use proptest::strategy::{BoxedStrategy, Just, Strategy};
+use firefly_alloc::gc::GcBox;
 
-use liblumen_alloc::erts::Process;
-
-use super::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Term, Tuple};
 
 pub fn intermediate(
     element: BoxedStrategy<Term>,
@@ -16,7 +16,7 @@ pub fn intermediate(
     arc_process: Arc<Process>,
 ) -> BoxedStrategy<Term> {
     proptest::collection::vec(element, size_range)
-        .prop_map(move |vec| arc_process.tuple_from_slice(&vec))
+        .prop_map(move |vec| arc_process.tuple_term_from_term_slice(&vec).unwrap())
         .boxed()
 }
 
@@ -33,8 +33,8 @@ pub fn with_index(arc_process: Arc<Process>) -> BoxedStrategy<(Vec<Term>, usize,
             (
                 element_vec.clone(),
                 zero_based_index,
-                arc_process.tuple_from_slice(&element_vec),
-                arc_process.integer(zero_based_index + 1),
+                arc_process.tuple_term_from_term_slice(&element_vec).unwrap(),
+                arc_process.integer(zero_based_index + 1).unwrap(),
             )
         })
         .boxed()
@@ -52,15 +52,16 @@ pub fn non_empty(arc_process: Arc<Process>) -> BoxedStrategy<Term> {
 pub fn without_index(arc_process: Arc<Process>) -> BoxedStrategy<(Term, Term)> {
     (non_empty(arc_process.clone()), super::super::term(arc_process.clone()))
         .prop_filter("Index either needs to not be an integer or not be an integer in the index range 1..=len", |(tuple, index)| {
-            let index_big_int_result: std::result::Result<BigInt, _> = (*index).try_into();
+            let index_gc_box_big_int_result: Result<GcBox<BigInt>, _> = (*index).try_into();
 
-            match index_big_int_result {
-                Ok(index_big_int) => {
-                    let tuple_tuple: Boxed<Tuple> = (*tuple).try_into().unwrap();
+            match index_gc_box_big_int_result {
+                Ok(index_gc_box_big_int) => {
+                    let non_null_tuple: NonNull<Tuple> = (*tuple).try_into().unwrap();
                     let min_index: BigInt = 1.into();
-                    let max_index: BigInt = tuple_tuple.len().into();
+                    let index_big_int = index_gc_box_big_int.as_ref();
+                    let max_index: BigInt = non_null_tuple.as_ref().len().into();
 
-                    !((min_index <= index_big_int) && (index_big_int <= max_index))
+                    !((min_index <= *./graindex_big_int) && (index_big_int <= *max_index))
                 }
                 _ => true,
             }
diff --git a/native_implemented/otp/src/timer.rs b/native_implemented/otp/src/timer.rs
index d55407cc1..00358305e 100644
--- a/native_implemented/otp/src/timer.rs
+++ b/native_implemented/otp/src/timer.rs
@@ -1,5 +1,3 @@
-use liblumen_alloc::erts::term::prelude::Atom;
-
 pub mod tc_3;
 
 pub mod cancel;
diff --git a/native_implemented/otp/src/timer/cancel.rs b/native_implemented/otp/src/timer/cancel.rs
index c5eae30e6..b64f94fa4 100644
--- a/native_implemented/otp/src/timer/cancel.rs
+++ b/native_implemented/otp/src/timer/cancel.rs
@@ -2,7 +2,7 @@ use core::convert::{TryFrom, TryInto};
 
 use anyhow::*;
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::{Atom, Term, Tuple};
 
 use crate::runtime::proplist::TryPropListFromTermError;
 
@@ -15,14 +15,14 @@ const SUPPORTED_OPTIONS_CONTEXT: &str = "supported options are {:async, bool} or
 
 impl Options {
     fn put_option_term(&mut self, option: Term) -> Result<&Options, anyhow::Error> {
-        let tuple: Boxed<Tuple> = option.try_into().context(SUPPORTED_OPTIONS_CONTEXT)?;
+        let tuple: NonNull<Tuple> = option.try_into().context(SUPPORTED_OPTIONS_CONTEXT)?;
 
         if tuple.len() == 2 {
             let atom: Atom = tuple[0]
                 .try_into()
                 .map_err(|_| TryPropListFromTermError::KeywordKeyType)?;
 
-            match atom.name() {
+            match atom.as_str() {
                 "async" => {
                     self.r#async = tuple[1].try_into().context("async value must be a bool")?;
 
@@ -59,13 +59,14 @@ impl TryFrom<Term> for Options {
         let mut options_term = term;
 
         loop {
-            match options_term.decode().unwrap() {
-                TypedTerm::Nil => return Ok(options),
-                TypedTerm::List(cons) => {
+            match options_term {
+                Term::Nil => return Ok(options),
+                Term::Cons(non_null_cons) => {
+                    let cons = unsafe { non_null_cons.as_ref() };
                     options
-                        .put_option_term(cons.head)
+                        .put_option_term(cons.head())
                         .with_context(|| SUPPORTED_OPTIONS_CONTEXT)?;
-                    options_term = cons.tail;
+                    options_term = cons.tail();
 
                     continue;
                 }
diff --git a/native_implemented/otp/src/timer/read.rs b/native_implemented/otp/src/timer/read.rs
index 6dd13301f..38df051bc 100644
--- a/native_implemented/otp/src/timer/read.rs
+++ b/native_implemented/otp/src/timer/read.rs
@@ -2,7 +2,7 @@ use std::convert::{TryFrom, TryInto};
 
 use anyhow::*;
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::{Atom, Term, Tuple};
 
 use crate::runtime::proplist::TryPropListFromTermError;
 
@@ -14,14 +14,14 @@ const SUPPORTED_OPTIONS_CONTEXT: &str = "supported option is {:async, bool}";
 
 impl Options {
     fn put_option_term(&mut self, option: Term) -> Result<&Options, anyhow::Error> {
-        let tuple: Boxed<Tuple> = option.try_into().context(SUPPORTED_OPTIONS_CONTEXT)?;
+        let tuple: NonNull<Tuple> = option.try_into().context(SUPPORTED_OPTIONS_CONTEXT)?;
 
         if tuple.len() == 2 {
             let atom: Atom = tuple[0]
                 .try_into()
                 .map_err(|_| TryPropListFromTermError::KeywordKeyType)?;
 
-            match atom.name() {
+            match atom.as_str() {
                 "async" => {
                     self.r#async = tuple[1].try_into().context("async value must be a bool")?;
 
@@ -50,11 +50,12 @@ impl TryFrom<Term> for Options {
         let mut options_term = term;
 
         loop {
-            match options_term.decode().unwrap() {
-                TypedTerm::Nil => return Ok(options),
-                TypedTerm::List(cons) => {
-                    options.put_option_term(cons.head)?;
-                    options_term = cons.tail;
+            match options_term {
+                Term::Nil => return Ok(options),
+                Term::Cons(non_null_cons) => {
+                    let cons = unsafe { non_null_cons.as_ref() };
+                    options.put_option_term(cons.head())?;
+                    options_term = cons.tail();
 
                     continue;
                 }
diff --git a/native_implemented/otp/src/timer/start.rs b/native_implemented/otp/src/timer/start.rs
index 10c7e761e..1939c1a24 100644
--- a/native_implemented/otp/src/timer/start.rs
+++ b/native_implemented/otp/src/timer/start.rs
@@ -1,8 +1,9 @@
-use core::convert::{TryFrom, TryInto};
+use core::convert::TryFrom;
 
 use anyhow::*;
 
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::term::{Atom, Term, Tuple};
+use crate::proplist::TryPropListFromTermError;
 
 use crate::runtime::context::*;
 use crate::runtime::proplist::*;
@@ -15,7 +16,7 @@ const SUPPORTED_OPTIONS_CONTEXT: &str = "supported option is {:abs, bool}";
 
 impl Options {
     fn put_option_term(&mut self, option: Term) -> Result<&Options, anyhow::Error> {
-        let tuple: Boxed<Tuple> = option.try_into().context(SUPPORTED_OPTIONS_CONTEXT)?;
+        let tuple: NonNull<Tuple> = option.try_into().context(SUPPORTED_OPTIONS_CONTEXT)?;
 
         if tuple.len() == 2 {
             let atom: Atom = tuple[0]
@@ -23,7 +24,7 @@ impl Options {
                 .map_err(|_| TryPropListFromTermError::KeywordKeyType)
                 .context(SUPPORTED_OPTIONS_CONTEXT)?;
 
-            match atom.name() {
+            match atom.as_str() {
                 "abs" => {
                     let value = tuple[1];
                     let absolute: bool = term_try_into_bool("abs value", value)?;
@@ -61,11 +62,12 @@ impl TryFrom<Term> for Options {
         let mut options_term = term;
 
         loop {
-            match options_term.decode().unwrap() {
-                TypedTerm::Nil => return Ok(options),
-                TypedTerm::List(cons) => {
-                    options.put_option_term(cons.head)?;
-                    options_term = cons.tail;
+            match options_term {
+                Term::Nil => return Ok(options),
+                Term::Cons(non_null_cons) => {
+                    let cons = unsafe { non_null_cons.as_ref() };
+                    options.put_option_term(cons.head())?;
+                    options_term = cons.tail();
 
                     continue;
                 }
diff --git a/native_implemented/otp/src/timer/tc_3.rs b/native_implemented/otp/src/timer/tc_3.rs
index b8686c553..7df7f9cfc 100644
--- a/native_implemented/otp/src/timer/tc_3.rs
+++ b/native_implemented/otp/src/timer/tc_3.rs
@@ -9,25 +9,23 @@
 //! end
 //! ```
 
-mod label_1;
-mod label_2;
-mod label_3;
-mod label_4;
-mod label_5;
-
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
+use firefly_rt::process::Process;
+use firefly_rt::term::{Atom, Term};
 
+use crate::erlang::apply_3::apply_3;
+use crate::erlang::convert_time_unit_3;
 use crate::erlang::monotonic_time_0;
 
 // Private
 
 #[native_implemented::function(timer:tc/3)]
-fn result(process: &Process, module: Term, function: Term, arguments: Term) -> Term {
-    process.queue_frame_with_arguments(monotonic_time_0::frame().with_arguments(false, &[]));
-    process.queue_frame_with_arguments(
-        label_1::frame().with_arguments(true, &[module, function, arguments]),
-    );
+async fn result(process: &Process, module: Term, function: Term, arguments: Term) -> Term {
+    let before = monotonic_time_0::result(process).await;
+    let value = apply_3(module, function, arguments).await;
+    let after = monotonic_time_0::result(process).await;
+    let duration = after - before;
+    let time = convert_time_unit_3::result(process, duration.into(),  Atom::str_to_term("native").into(),
+                                           Atom::str_to_term("microsecond").into()).await?;
 
-    Term::NONE
+    process.tuple_term_from_term_slice(&[time, value])
 }
diff --git a/native_implemented/otp/src/timer/tc_3/label_1.rs b/native_implemented/otp/src/timer/tc_3/label_1.rs
deleted file mode 100644
index b45dde53e..000000000
--- a/native_implemented/otp/src/timer/tc_3/label_1.rs
+++ /dev/null
@@ -1,36 +0,0 @@
-//! ```elixir
-//! # label 1
-//! # pushed to stack: (module, function arguments, before)
-//! # returned from call: before
-//! # full stack: (before, module, function arguments)
-//! # returns: value
-//! value = apply(module, function, arguments)
-//! after = :erlang.monotonic_time()
-//! duration = after - before
-//! time = :erlang.convert_time_unit(duration, :native, :microsecond)
-//! {time, value}
-//! ```
-
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
-
-use crate::erlang::apply_3;
-
-use super::label_2;
-
-// Private
-
-#[native_implemented::label]
-fn result(process: &Process, before: Term, module: Term, function: Term, arguments: Term) -> Term {
-    assert!(before.is_integer());
-    assert!(module.is_atom(), "module ({:?}) is not an atom", module);
-    assert!(function.is_atom());
-    assert!(arguments.is_list());
-
-    process.queue_frame_with_arguments(
-        apply_3::frame().with_arguments(false, &[module, function, arguments]),
-    );
-    process.queue_frame_with_arguments(label_2::frame().with_arguments(true, &[before]));
-
-    Term::NONE
-}
diff --git a/native_implemented/otp/src/timer/tc_3/label_2.rs b/native_implemented/otp/src/timer/tc_3/label_2.rs
deleted file mode 100644
index b778c4c33..000000000
--- a/native_implemented/otp/src/timer/tc_3/label_2.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-//! ```elixir
-//! # label 2
-//! # pushed to stack: (before)
-//! # returned from call: value
-//! # full stack: (value, before)
-//! # returns: after
-//! after = :erlang.monotonic_time()
-//! duration = after - before
-//! time = :erlang.convert_time_unit(duration, :native, :microsecond)
-//! {time, value}
-//! ```
-
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
-
-use crate::erlang::monotonic_time_0;
-
-use super::label_3;
-
-// Private
-
-#[native_implemented::label]
-fn result(process: &Process, value: Term, before: Term) -> Term {
-    assert!(before.is_integer());
-
-    process.queue_frame_with_arguments(monotonic_time_0::frame().with_arguments(false, &[]));
-    process.queue_frame_with_arguments(label_3::frame().with_arguments(true, &[before, value]));
-
-    Term::NONE
-}
diff --git a/native_implemented/otp/src/timer/tc_3/label_3.rs b/native_implemented/otp/src/timer/tc_3/label_3.rs
deleted file mode 100644
index 312365794..000000000
--- a/native_implemented/otp/src/timer/tc_3/label_3.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-//! ```elixir
-//! # label 3
-//! # pushed to stack: (before, value)
-//! # returned from call: after
-//! # full stack: (after, before, value)
-//! # returns: duration
-//! duration = after - before
-//! time = :erlang.convert_time_unit(duration, :native, :microsecond)
-//! {time, value}
-//! ```
-
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
-
-use crate::erlang::subtract_2;
-
-use super::label_4;
-
-// Private
-
-#[native_implemented::label]
-fn result(process: &Process, after: Term, before: Term, value: Term) -> Term {
-    assert!(after.is_integer());
-    assert!(before.is_integer());
-
-    process.queue_frame_with_arguments(subtract_2::frame().with_arguments(false, &[after, before]));
-    process.queue_frame_with_arguments(label_4::frame().with_arguments(true, &[value]));
-
-    Term::NONE
-}
diff --git a/native_implemented/otp/src/timer/tc_3/label_4.rs b/native_implemented/otp/src/timer/tc_3/label_4.rs
deleted file mode 100644
index 4d46f5c23..000000000
--- a/native_implemented/otp/src/timer/tc_3/label_4.rs
+++ /dev/null
@@ -1,35 +0,0 @@
-//! ```elixir
-//! # label 4
-//! # pushed to stack: (value)
-//! # returned from call: duration
-//! # full stack: (duration, value)
-//! # returns: time
-//! time = :erlang.convert_time_unit(duration, :native, :microsecond)
-//! {time, value}
-//! ```
-
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
-
-use crate::erlang::convert_time_unit_3;
-
-use super::label_5;
-
-// Private
-
-#[native_implemented::label]
-fn result(process: &Process, duration: Term, value: Term) -> Term {
-    assert!(duration.is_integer());
-
-    process.queue_frame_with_arguments(convert_time_unit_3::frame().with_arguments(
-        false,
-        &[
-            duration,
-            Atom::str_to_term("native"),
-            Atom::str_to_term("microsecond"),
-        ],
-    ));
-    process.queue_frame_with_arguments(label_5::frame().with_arguments(true, &[value]));
-
-    Term::NONE
-}
diff --git a/native_implemented/otp/src/timer/tc_3/label_5.rs b/native_implemented/otp/src/timer/tc_3/label_5.rs
deleted file mode 100644
index 750193135..000000000
--- a/native_implemented/otp/src/timer/tc_3/label_5.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-//! ```elixir
-//! # label 5
-//! # pushed to stack: (value)
-//! # returned from call: time
-//! # full stack: (time, value)
-//! # returns: {time, value}
-//! {time, value}
-//! ```
-
-use liblumen_alloc::erts::process::Process;
-use liblumen_alloc::erts::term::prelude::*;
-
-// Private
-
-#[native_implemented::label]
-fn result(process: &Process, time: Term, value: Term) -> Term {
-    assert!(time.is_integer());
-
-    process.tuple_from_slice(&[time, value])
-}
diff --git a/native_implemented/web/Cargo.toml b/native_implemented/web/Cargo.toml
index 77f2e6a87..fa66810b9 100644
--- a/native_implemented/web/Cargo.toml
+++ b/native_implemented/web/Cargo.toml
@@ -12,8 +12,7 @@ crate-type = ["staticlib", "rlib"]
 [dependencies]
 anyhow = "1.0.11"
 js-sys = "0.3.25"
-liblumen_alloc = { path = "../../liblumen_alloc" }
-liblumen_core = { path = "../../library/core" }
+liblumen_alloc = { path = "../../library/alloc" }
 liblumen_otp = { path = "../otp" }
 lumen_rt_full = { path = "../../runtimes/full" }
 panic-control = "0.1.4"
diff --git a/native_implemented/web/src/async/apply_3.rs b/native_implemented/web/src/async/apply_3.rs
index c5bc41f8f..598465bff 100644
--- a/native_implemented/web/src/async/apply_3.rs
+++ b/native_implemented/web/src/async/apply_3.rs
@@ -6,7 +6,7 @@ use liblumen_core::locks::Mutex;
 
 use liblumen_alloc::erts::exception;
 use liblumen_alloc::erts::fragment::HeapFragment;
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use crate::executor::{self, Executor};
diff --git a/native_implemented/web/src/document/body_1.rs b/native_implemented/web/src/document/body_1.rs
index bbcb891e2..ca00c8b20 100644
--- a/native_implemented/web/src/document/body_1.rs
+++ b/native_implemented/web/src/document/body_1.rs
@@ -6,7 +6,7 @@
 //! ```
 
 use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use crate::{document, option_to_ok_tuple_or_error};
diff --git a/native_implemented/web/src/document/create_element_2.rs b/native_implemented/web/src/document/create_element_2.rs
index a1eed9384..a0ccc3848 100644
--- a/native_implemented/web/src/document/create_element_2.rs
+++ b/native_implemented/web/src/document/create_element_2.rs
@@ -7,7 +7,7 @@
 
 use liblumen_alloc::atom;
 use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use crate::runtime::binary_to_string::binary_to_string;
diff --git a/native_implemented/web/src/document/create_text_node_2.rs b/native_implemented/web/src/document/create_text_node_2.rs
index f11756454..54fdf9a62 100644
--- a/native_implemented/web/src/document/create_text_node_2.rs
+++ b/native_implemented/web/src/document/create_text_node_2.rs
@@ -3,7 +3,7 @@
 //! ```
 
 use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use crate::runtime::binary_to_string::binary_to_string;
diff --git a/native_implemented/web/src/document/get_element_by_id_2.rs b/native_implemented/web/src/document/get_element_by_id_2.rs
index df8bc2b5f..c69e2f1f3 100644
--- a/native_implemented/web/src/document/get_element_by_id_2.rs
+++ b/native_implemented/web/src/document/get_element_by_id_2.rs
@@ -6,7 +6,7 @@
 //! ```
 
 use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use crate::runtime::binary_to_string::binary_to_string;
diff --git a/native_implemented/web/src/document/new_0.rs b/native_implemented/web/src/document/new_0.rs
index 16776d9ac..30daa5b46 100644
--- a/native_implemented/web/src/document/new_0.rs
+++ b/native_implemented/web/src/document/new_0.rs
@@ -9,7 +9,7 @@
 //! ```
 
 use liblumen_alloc::atom;
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::Term;
 
 use crate::ok_tuple;
diff --git a/native_implemented/web/src/element/class_name_1.rs b/native_implemented/web/src/element/class_name_1.rs
index 258ae7aa9..87be3d0ef 100644
--- a/native_implemented/web/src/element/class_name_1.rs
+++ b/native_implemented/web/src/element/class_name_1.rs
@@ -3,7 +3,7 @@
 //! ``
 
 use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use crate::element;
diff --git a/native_implemented/web/src/element/set_attribute_3.rs b/native_implemented/web/src/element/set_attribute_3.rs
index 7830dc4f0..c4b9dd08d 100644
--- a/native_implemented/web/src/element/set_attribute_3.rs
+++ b/native_implemented/web/src/element/set_attribute_3.rs
@@ -7,7 +7,7 @@
 
 use liblumen_alloc::atom;
 use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use crate::element;
diff --git a/native_implemented/web/src/event/target_1.rs b/native_implemented/web/src/event/target_1.rs
index 4671fd156..72aa6867b 100644
--- a/native_implemented/web/src/event/target_1.rs
+++ b/native_implemented/web/src/event/target_1.rs
@@ -6,7 +6,7 @@
 
 use liblumen_alloc::atom;
 use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use crate::event;
diff --git a/native_implemented/web/src/event_listener/apply_4.rs b/native_implemented/web/src/event_listener/apply_4.rs
index 1f757e0d0..eda173499 100644
--- a/native_implemented/web/src/event_listener/apply_4.rs
+++ b/native_implemented/web/src/event_listener/apply_4.rs
@@ -9,7 +9,7 @@
 
 mod label_1;
 
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use liblumen_otp::erlang;
diff --git a/native_implemented/web/src/executor/apply_4.rs b/native_implemented/web/src/executor/apply_4.rs
index 267a1114c..ba381504f 100644
--- a/native_implemented/web/src/executor/apply_4.rs
+++ b/native_implemented/web/src/executor/apply_4.rs
@@ -8,7 +8,7 @@
 
 mod label_1;
 
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use liblumen_otp::erlang;
diff --git a/native_implemented/web/src/html_form_element/element_2.rs b/native_implemented/web/src/html_form_element/element_2.rs
index b73f229ba..49a96af23 100644
--- a/native_implemented/web/src/html_form_element/element_2.rs
+++ b/native_implemented/web/src/html_form_element/element_2.rs
@@ -11,7 +11,7 @@ use web_sys::HtmlInputElement;
 
 use liblumen_alloc::atom;
 use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use crate::html_form_element;
diff --git a/native_implemented/web/src/html_input_element/value_1.rs b/native_implemented/web/src/html_input_element/value_1.rs
index 34d87955e..67b8ade08 100644
--- a/native_implemented/web/src/html_input_element/value_1.rs
+++ b/native_implemented/web/src/html_input_element/value_1.rs
@@ -3,7 +3,7 @@
 //! ```
 
 use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use crate::html_input_element;
diff --git a/native_implemented/web/src/lib.rs b/native_implemented/web/src/lib.rs
index 94b4f22d5..1b97bbb42 100644
--- a/native_implemented/web/src/lib.rs
+++ b/native_implemented/web/src/lib.rs
@@ -32,7 +32,7 @@ use web_sys::{DomException, Window};
 use liblumen_core::entry;
 
 use liblumen_alloc::atom;
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::Term;
 use liblumen_alloc::erts::time::Milliseconds;
 
diff --git a/native_implemented/web/src/math/random_integer_1.rs b/native_implemented/web/src/math/random_integer_1.rs
index 08a5d0476..e2ff3c6c3 100644
--- a/native_implemented/web/src/math/random_integer_1.rs
+++ b/native_implemented/web/src/math/random_integer_1.rs
@@ -9,7 +9,7 @@ use std::convert::TryInto;
 use anyhow::*;
 
 use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 #[native_implemented::function(Elixir.Lumen.Web.Math:random_integer/1)]
diff --git a/native_implemented/web/src/node/append_child_2.rs b/native_implemented/web/src/node/append_child_2.rs
index 22aa9c180..058be19ab 100644
--- a/native_implemented/web/src/node/append_child_2.rs
+++ b/native_implemented/web/src/node/append_child_2.rs
@@ -23,7 +23,7 @@
 
 use liblumen_alloc::atom;
 use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use crate::{error_tuple, node};
diff --git a/native_implemented/web/src/node/insert_before_3.rs b/native_implemented/web/src/node/insert_before_3.rs
index 153512259..1598c020f 100644
--- a/native_implemented/web/src/node/insert_before_3.rs
+++ b/native_implemented/web/src/node/insert_before_3.rs
@@ -18,7 +18,7 @@ use web_sys::DomException;
 
 use liblumen_alloc::atom;
 use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use crate::{node, ok_tuple};
diff --git a/native_implemented/web/src/node/replace_child_3.rs b/native_implemented/web/src/node/replace_child_3.rs
index 811b630b7..ee3b2409c 100644
--- a/native_implemented/web/src/node/replace_child_3.rs
+++ b/native_implemented/web/src/node/replace_child_3.rs
@@ -18,7 +18,7 @@ use web_sys::DomException;
 
 use liblumen_alloc::atom;
 use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use crate::{node, ok_tuple};
diff --git a/native_implemented/web/src/promise.rs b/native_implemented/web/src/promise.rs
index 4d3aaeedd..f4493766c 100644
--- a/native_implemented/web/src/promise.rs
+++ b/native_implemented/web/src/promise.rs
@@ -4,7 +4,7 @@ use js_sys::Promise;
 
 use liblumen_core::locks::Mutex;
 
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 pub fn to_term(promise: Promise, process: &Process) -> Term {
diff --git a/native_implemented/web/src/web_socket/new_1.rs b/native_implemented/web/src/web_socket/new_1.rs
index 4badda297..dd6c80870 100644
--- a/native_implemented/web/src/web_socket/new_1.rs
+++ b/native_implemented/web/src/web_socket/new_1.rs
@@ -8,7 +8,7 @@
 use web_sys::WebSocket;
 
 use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::Term;
 
 use crate::runtime::binary_to_string::binary_to_string;
diff --git a/native_implemented/web/src/window/document_1.rs b/native_implemented/web/src/window/document_1.rs
index b7b2d9dfa..12f5f357b 100644
--- a/native_implemented/web/src/window/document_1.rs
+++ b/native_implemented/web/src/window/document_1.rs
@@ -11,7 +11,7 @@ use anyhow::*;
 use web_sys::Window;
 
 use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use crate::option_to_ok_tuple_or_error;
diff --git a/native_implemented/web/src/window/on_submit_1.rs b/native_implemented/web/src/window/on_submit_1.rs
index 5a781f1df..41bf4a7b0 100644
--- a/native_implemented/web/src/window/on_submit_1.rs
+++ b/native_implemented/web/src/window/on_submit_1.rs
@@ -13,7 +13,7 @@ use wasm_bindgen::JsCast;
 use web_sys::{Event, HtmlFormElement};
 
 use liblumen_alloc::atom;
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use liblumen_otp::erlang;
diff --git a/native_implemented/web/src/window/window_0.rs b/native_implemented/web/src/window/window_0.rs
index dbbbe86ea..5db657eec 100644
--- a/native_implemented/web/src/window/window_0.rs
+++ b/native_implemented/web/src/window/window_0.rs
@@ -5,7 +5,7 @@
 //! end
 //! ```
 
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::Term;
 
 use crate::option_to_ok_tuple_or_error;
diff --git a/native_implemented/web/tests/web/document/body_1/with_body.rs b/native_implemented/web/tests/web/document/body_1/with_body.rs
index d1318d476..f3001acc8 100644
--- a/native_implemented/web/tests/web/document/body_1/with_body.rs
+++ b/native_implemented/web/tests/web/document/body_1/with_body.rs
@@ -9,7 +9,7 @@ pub mod label_1;
 #[path = "with_body/label_2.rs"]
 pub mod label_2;
 
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use liblumen_web::window;
diff --git a/native_implemented/web/tests/web/document/body_1/with_body/label_1.rs b/native_implemented/web/tests/web/document/body_1/with_body/label_1.rs
index 1c977efd4..21aef593a 100644
--- a/native_implemented/web/tests/web/document/body_1/with_body/label_1.rs
+++ b/native_implemented/web/tests/web/document/body_1/with_body/label_1.rs
@@ -11,7 +11,7 @@
 
 use std::convert::TryInto;
 
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use super::label_2;
diff --git a/native_implemented/web/tests/web/document/body_1/with_body/label_2.rs b/native_implemented/web/tests/web/document/body_1/with_body/label_2.rs
index 86e690c02..a16a95b93 100644
--- a/native_implemented/web/tests/web/document/body_1/with_body/label_2.rs
+++ b/native_implemented/web/tests/web/document/body_1/with_body/label_2.rs
@@ -10,7 +10,7 @@
 
 use std::convert::TryInto;
 
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 #[native_implemented::label]
diff --git a/native_implemented/web/tests/web/document/body_1/without_body.rs b/native_implemented/web/tests/web/document/body_1/without_body.rs
index 92ddbdd81..2466dd3a5 100644
--- a/native_implemented/web/tests/web/document/body_1/without_body.rs
+++ b/native_implemented/web/tests/web/document/body_1/without_body.rs
@@ -7,7 +7,7 @@
 #[path = "without_body/label_1.rs"]
 pub mod label_1;
 
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use liblumen_web::document;
diff --git a/native_implemented/web/tests/web/document/body_1/without_body/label_1.rs b/native_implemented/web/tests/web/document/body_1/without_body/label_1.rs
index 5857b1dfc..b5c1688ba 100644
--- a/native_implemented/web/tests/web/document/body_1/without_body/label_1.rs
+++ b/native_implemented/web/tests/web/document/body_1/without_body/label_1.rs
@@ -10,7 +10,7 @@
 
 use std::convert::TryInto;
 
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 #[native_implemented::label]
diff --git a/native_implemented/web/tests/web/element/class_name_1/test_0.rs b/native_implemented/web/tests/web/element/class_name_1/test_0.rs
index f4e846a38..439888c8f 100644
--- a/native_implemented/web/tests/web/element/class_name_1/test_0.rs
+++ b/native_implemented/web/tests/web/element/class_name_1/test_0.rs
@@ -13,7 +13,7 @@ pub mod label_2;
 #[path = "test_0/label_3.rs"]
 pub mod label_3;
 
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use liblumen_web::window;
diff --git a/native_implemented/web/tests/web/element/class_name_1/test_0/label_1.rs b/native_implemented/web/tests/web/element/class_name_1/test_0/label_1.rs
index f3ad13b1f..6e0cd863a 100644
--- a/native_implemented/web/tests/web/element/class_name_1/test_0/label_1.rs
+++ b/native_implemented/web/tests/web/element/class_name_1/test_0/label_1.rs
@@ -14,7 +14,7 @@ use std::convert::TryInto;
 
 use web_sys::Window;
 
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use super::label_2;
diff --git a/native_implemented/web/tests/web/element/class_name_1/test_0/label_2.rs b/native_implemented/web/tests/web/element/class_name_1/test_0/label_2.rs
index 49493d64b..fea873dbd 100644
--- a/native_implemented/web/tests/web/element/class_name_1/test_0/label_2.rs
+++ b/native_implemented/web/tests/web/element/class_name_1/test_0/label_2.rs
@@ -13,7 +13,7 @@ use std::convert::TryInto;
 
 use web_sys::Document;
 
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use super::label_3;
diff --git a/native_implemented/web/tests/web/element/class_name_1/test_0/label_3.rs b/native_implemented/web/tests/web/element/class_name_1/test_0/label_3.rs
index c4fb90413..0668a8b93 100644
--- a/native_implemented/web/tests/web/element/class_name_1/test_0/label_3.rs
+++ b/native_implemented/web/tests/web/element/class_name_1/test_0/label_3.rs
@@ -10,7 +10,7 @@
 
 use std::convert::TryInto;
 
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 #[native_implemented::label]
diff --git a/native_implemented/web/tests/web/element/remove_1/removes_element.rs b/native_implemented/web/tests/web/element/remove_1/removes_element.rs
index 2f7be9f49..f97a3a0af 100644
--- a/native_implemented/web/tests/web/element/remove_1/removes_element.rs
+++ b/native_implemented/web/tests/web/element/remove_1/removes_element.rs
@@ -19,7 +19,7 @@ pub mod label_4;
 #[path = "removes_element/label_5.rs"]
 pub mod label_5;
 
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use liblumen_web::window;
diff --git a/native_implemented/web/tests/web/element/remove_1/removes_element/label_1.rs b/native_implemented/web/tests/web/element/remove_1/removes_element/label_1.rs
index 48fa64aa0..716db1bdd 100644
--- a/native_implemented/web/tests/web/element/remove_1/removes_element/label_1.rs
+++ b/native_implemented/web/tests/web/element/remove_1/removes_element/label_1.rs
@@ -16,7 +16,7 @@ use std::convert::TryInto;
 
 use web_sys::Window;
 
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use super::label_2;
diff --git a/native_implemented/web/tests/web/element/remove_1/removes_element/label_2.rs b/native_implemented/web/tests/web/element/remove_1/removes_element/label_2.rs
index c7b78f8a0..c79914902 100644
--- a/native_implemented/web/tests/web/element/remove_1/removes_element/label_2.rs
+++ b/native_implemented/web/tests/web/element/remove_1/removes_element/label_2.rs
@@ -15,7 +15,7 @@ use std::convert::TryInto;
 
 use web_sys::Document;
 
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use super::label_3;
diff --git a/native_implemented/web/tests/web/element/remove_1/removes_element/label_3.rs b/native_implemented/web/tests/web/element/remove_1/removes_element/label_3.rs
index 63ec4437f..0d88b1132 100644
--- a/native_implemented/web/tests/web/element/remove_1/removes_element/label_3.rs
+++ b/native_implemented/web/tests/web/element/remove_1/removes_element/label_3.rs
@@ -13,7 +13,7 @@
 use std::convert::TryInto;
 
 use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use super::label_4;
diff --git a/native_implemented/web/tests/web/element/remove_1/removes_element/label_4.rs b/native_implemented/web/tests/web/element/remove_1/removes_element/label_4.rs
index 0b1e31155..9c732ed08 100644
--- a/native_implemented/web/tests/web/element/remove_1/removes_element/label_4.rs
+++ b/native_implemented/web/tests/web/element/remove_1/removes_element/label_4.rs
@@ -13,7 +13,7 @@ use std::convert::TryInto;
 
 use web_sys::Element;
 
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use super::label_5;
diff --git a/native_implemented/web/tests/web/element/remove_1/removes_element/label_5.rs b/native_implemented/web/tests/web/element/remove_1/removes_element/label_5.rs
index d1cfb0874..8b29759b3 100644
--- a/native_implemented/web/tests/web/element/remove_1/removes_element/label_5.rs
+++ b/native_implemented/web/tests/web/element/remove_1/removes_element/label_5.rs
@@ -8,7 +8,7 @@
 //! Lumen.Web.Wait.with_return(remove_ok)
 //! ```
 
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 #[native_implemented::label]
diff --git a/native_implemented/web/tests/web/math/random_integer_1/returns_integer_between_0_inclusive_and_max_exclusive.rs b/native_implemented/web/tests/web/math/random_integer_1/returns_integer_between_0_inclusive_and_max_exclusive.rs
index c1c5fc970..fd97c5f17 100644
--- a/native_implemented/web/tests/web/math/random_integer_1/returns_integer_between_0_inclusive_and_max_exclusive.rs
+++ b/native_implemented/web/tests/web/math/random_integer_1/returns_integer_between_0_inclusive_and_max_exclusive.rs
@@ -3,7 +3,7 @@
 //! random_integer = Lumen.Web.Math.random_integer(exclusive_max)
 //! ```
 
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use liblumen_web::math::random_integer_1;
diff --git a/native_implemented/web/tests/web/node/insert_before_3/with_nil_reference_child_appends_new_child.rs b/native_implemented/web/tests/web/node/insert_before_3/with_nil_reference_child_appends_new_child.rs
index 9e2c2cf98..80f126a5f 100644
--- a/native_implemented/web/tests/web/node/insert_before_3/with_nil_reference_child_appends_new_child.rs
+++ b/native_implemented/web/tests/web/node/insert_before_3/with_nil_reference_child_appends_new_child.rs
@@ -21,7 +21,7 @@ pub mod label_5;
 #[path = "with_nil_reference_child_appends_new_child/label_6.rs"]
 pub mod label_6;
 
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use liblumen_web::document;
diff --git a/native_implemented/web/tests/web/node/insert_before_3/with_nil_reference_child_appends_new_child/label_1.rs b/native_implemented/web/tests/web/node/insert_before_3/with_nil_reference_child_appends_new_child/label_1.rs
index ff3dfcd69..7a172a1bb 100644
--- a/native_implemented/web/tests/web/node/insert_before_3/with_nil_reference_child_appends_new_child/label_1.rs
+++ b/native_implemented/web/tests/web/node/insert_before_3/with_nil_reference_child_appends_new_child/label_1.rs
@@ -15,7 +15,7 @@
 use std::convert::TryInto;
 
 use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use super::label_2;
diff --git a/native_implemented/web/tests/web/node/insert_before_3/with_nil_reference_child_appends_new_child/label_2.rs b/native_implemented/web/tests/web/node/insert_before_3/with_nil_reference_child_appends_new_child/label_2.rs
index 19b0db7ed..ba0f33823 100644
--- a/native_implemented/web/tests/web/node/insert_before_3/with_nil_reference_child_appends_new_child/label_2.rs
+++ b/native_implemented/web/tests/web/node/insert_before_3/with_nil_reference_child_appends_new_child/label_2.rs
@@ -14,7 +14,7 @@
 use std::convert::TryInto;
 
 use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use super::label_3;
diff --git a/native_implemented/web/tests/web/node/insert_before_3/with_nil_reference_child_appends_new_child/label_3.rs b/native_implemented/web/tests/web/node/insert_before_3/with_nil_reference_child_appends_new_child/label_3.rs
index 46b418639..b51cc8e18 100644
--- a/native_implemented/web/tests/web/node/insert_before_3/with_nil_reference_child_appends_new_child/label_3.rs
+++ b/native_implemented/web/tests/web/node/insert_before_3/with_nil_reference_child_appends_new_child/label_3.rs
@@ -12,7 +12,7 @@
 
 use std::convert::TryInto;
 
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use super::label_4;
diff --git a/native_implemented/web/tests/web/node/insert_before_3/with_nil_reference_child_appends_new_child/label_4.rs b/native_implemented/web/tests/web/node/insert_before_3/with_nil_reference_child_appends_new_child/label_4.rs
index 059294a92..7c7648dba 100644
--- a/native_implemented/web/tests/web/node/insert_before_3/with_nil_reference_child_appends_new_child/label_4.rs
+++ b/native_implemented/web/tests/web/node/insert_before_3/with_nil_reference_child_appends_new_child/label_4.rs
@@ -13,7 +13,7 @@ use std::convert::TryInto;
 
 use web_sys::Element;
 
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use super::label_5;
diff --git a/native_implemented/web/tests/web/node/insert_before_3/with_nil_reference_child_appends_new_child/label_5.rs b/native_implemented/web/tests/web/node/insert_before_3/with_nil_reference_child_appends_new_child/label_5.rs
index 1896ae586..9333d73b5 100644
--- a/native_implemented/web/tests/web/node/insert_before_3/with_nil_reference_child_appends_new_child/label_5.rs
+++ b/native_implemented/web/tests/web/node/insert_before_3/with_nil_reference_child_appends_new_child/label_5.rs
@@ -9,7 +9,7 @@
 //! ```
 
 use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use super::label_6;
diff --git a/native_implemented/web/tests/web/node/insert_before_3/with_nil_reference_child_appends_new_child/label_6.rs b/native_implemented/web/tests/web/node/insert_before_3/with_nil_reference_child_appends_new_child/label_6.rs
index 2ccab9876..259372573 100644
--- a/native_implemented/web/tests/web/node/insert_before_3/with_nil_reference_child_appends_new_child/label_6.rs
+++ b/native_implemented/web/tests/web/node/insert_before_3/with_nil_reference_child_appends_new_child/label_6.rs
@@ -9,7 +9,7 @@
 
 use std::convert::TryInto;
 
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 #[native_implemented::label]
diff --git a/native_implemented/web/tests/web/node/insert_before_3/with_reference_child_inserts_before_reference_child.rs b/native_implemented/web/tests/web/node/insert_before_3/with_reference_child_inserts_before_reference_child.rs
index f8f3ac663..e6439ff5f 100644
--- a/native_implemented/web/tests/web/node/insert_before_3/with_reference_child_inserts_before_reference_child.rs
+++ b/native_implemented/web/tests/web/node/insert_before_3/with_reference_child_inserts_before_reference_child.rs
@@ -21,7 +21,7 @@ pub mod label_5;
 #[path = "with_reference_child_inserts_before_reference_child/label_6.rs"]
 pub mod label_6;
 
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use liblumen_web::document;
diff --git a/native_implemented/web/tests/web/node/insert_before_3/with_reference_child_inserts_before_reference_child/label_1.rs b/native_implemented/web/tests/web/node/insert_before_3/with_reference_child_inserts_before_reference_child/label_1.rs
index d67f86a7b..b9f35538e 100644
--- a/native_implemented/web/tests/web/node/insert_before_3/with_reference_child_inserts_before_reference_child/label_1.rs
+++ b/native_implemented/web/tests/web/node/insert_before_3/with_reference_child_inserts_before_reference_child/label_1.rs
@@ -15,7 +15,7 @@
 use std::convert::TryInto;
 
 use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use super::label_2;
diff --git a/native_implemented/web/tests/web/node/insert_before_3/with_reference_child_inserts_before_reference_child/label_2.rs b/native_implemented/web/tests/web/node/insert_before_3/with_reference_child_inserts_before_reference_child/label_2.rs
index 58b3d78b7..88f1e8204 100644
--- a/native_implemented/web/tests/web/node/insert_before_3/with_reference_child_inserts_before_reference_child/label_2.rs
+++ b/native_implemented/web/tests/web/node/insert_before_3/with_reference_child_inserts_before_reference_child/label_2.rs
@@ -14,7 +14,7 @@
 use std::convert::TryInto;
 
 use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use super::label_3;
diff --git a/native_implemented/web/tests/web/node/insert_before_3/with_reference_child_inserts_before_reference_child/label_3.rs b/native_implemented/web/tests/web/node/insert_before_3/with_reference_child_inserts_before_reference_child/label_3.rs
index 355b773a7..b36d5e2b9 100644
--- a/native_implemented/web/tests/web/node/insert_before_3/with_reference_child_inserts_before_reference_child/label_3.rs
+++ b/native_implemented/web/tests/web/node/insert_before_3/with_reference_child_inserts_before_reference_child/label_3.rs
@@ -12,7 +12,7 @@
 
 use std::convert::TryInto;
 
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use super::label_4;
diff --git a/native_implemented/web/tests/web/node/insert_before_3/with_reference_child_inserts_before_reference_child/label_4.rs b/native_implemented/web/tests/web/node/insert_before_3/with_reference_child_inserts_before_reference_child/label_4.rs
index 09689e24a..206caa9dc 100644
--- a/native_implemented/web/tests/web/node/insert_before_3/with_reference_child_inserts_before_reference_child/label_4.rs
+++ b/native_implemented/web/tests/web/node/insert_before_3/with_reference_child_inserts_before_reference_child/label_4.rs
@@ -9,7 +9,7 @@
 //! {:ok, inserted_child} = Lumen.Web.insert_before(parent, new_child, reference_child)
 //! ```
 
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use super::label_5;
diff --git a/native_implemented/web/tests/web/node/insert_before_3/with_reference_child_inserts_before_reference_child/label_5.rs b/native_implemented/web/tests/web/node/insert_before_3/with_reference_child_inserts_before_reference_child/label_5.rs
index 179313f17..0b1507f11 100644
--- a/native_implemented/web/tests/web/node/insert_before_3/with_reference_child_inserts_before_reference_child/label_5.rs
+++ b/native_implemented/web/tests/web/node/insert_before_3/with_reference_child_inserts_before_reference_child/label_5.rs
@@ -9,7 +9,7 @@
 //! ```
 
 use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use super::label_6;
diff --git a/native_implemented/web/tests/web/node/insert_before_3/with_reference_child_inserts_before_reference_child/label_6.rs b/native_implemented/web/tests/web/node/insert_before_3/with_reference_child_inserts_before_reference_child/label_6.rs
index 7805cecc4..51cd9db17 100644
--- a/native_implemented/web/tests/web/node/insert_before_3/with_reference_child_inserts_before_reference_child/label_6.rs
+++ b/native_implemented/web/tests/web/node/insert_before_3/with_reference_child_inserts_before_reference_child/label_6.rs
@@ -9,7 +9,7 @@
 
 use std::convert::TryInto;
 
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 #[native_implemented::label]
diff --git a/native_implemented/web/tests/web/node/replace_child_3/with_new_child_is_parent_returns_error_hierarchy_request.rs b/native_implemented/web/tests/web/node/replace_child_3/with_new_child_is_parent_returns_error_hierarchy_request.rs
index ed0560fd9..bc7c718b2 100644
--- a/native_implemented/web/tests/web/node/replace_child_3/with_new_child_is_parent_returns_error_hierarchy_request.rs
+++ b/native_implemented/web/tests/web/node/replace_child_3/with_new_child_is_parent_returns_error_hierarchy_request.rs
@@ -15,7 +15,7 @@ pub mod label_3;
 #[path = "with_new_child_is_parent_returns_error_hierarchy_request/label_4.rs"]
 pub mod label_4;
 
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use liblumen_web::document;
diff --git a/native_implemented/web/tests/web/node/replace_child_3/with_new_child_is_parent_returns_error_hierarchy_request/label_1.rs b/native_implemented/web/tests/web/node/replace_child_3/with_new_child_is_parent_returns_error_hierarchy_request/label_1.rs
index fc1cbeda7..327d7159c 100644
--- a/native_implemented/web/tests/web/node/replace_child_3/with_new_child_is_parent_returns_error_hierarchy_request/label_1.rs
+++ b/native_implemented/web/tests/web/node/replace_child_3/with_new_child_is_parent_returns_error_hierarchy_request/label_1.rs
@@ -13,7 +13,7 @@
 use std::convert::TryInto;
 
 use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use super::label_2;
diff --git a/native_implemented/web/tests/web/node/replace_child_3/with_new_child_is_parent_returns_error_hierarchy_request/label_2.rs b/native_implemented/web/tests/web/node/replace_child_3/with_new_child_is_parent_returns_error_hierarchy_request/label_2.rs
index 741b29c04..48d0e35d4 100644
--- a/native_implemented/web/tests/web/node/replace_child_3/with_new_child_is_parent_returns_error_hierarchy_request/label_2.rs
+++ b/native_implemented/web/tests/web/node/replace_child_3/with_new_child_is_parent_returns_error_hierarchy_request/label_2.rs
@@ -12,7 +12,7 @@
 use std::convert::TryInto;
 
 use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use super::label_3;
diff --git a/native_implemented/web/tests/web/node/replace_child_3/with_new_child_is_parent_returns_error_hierarchy_request/label_3.rs b/native_implemented/web/tests/web/node/replace_child_3/with_new_child_is_parent_returns_error_hierarchy_request/label_3.rs
index a815a1aaa..6782653b9 100644
--- a/native_implemented/web/tests/web/node/replace_child_3/with_new_child_is_parent_returns_error_hierarchy_request/label_3.rs
+++ b/native_implemented/web/tests/web/node/replace_child_3/with_new_child_is_parent_returns_error_hierarchy_request/label_3.rs
@@ -10,7 +10,7 @@
 
 use std::convert::TryInto;
 
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use super::label_4;
diff --git a/native_implemented/web/tests/web/node/replace_child_3/with_new_child_is_parent_returns_error_hierarchy_request/label_4.rs b/native_implemented/web/tests/web/node/replace_child_3/with_new_child_is_parent_returns_error_hierarchy_request/label_4.rs
index 37a4176e2..2782fcbd4 100644
--- a/native_implemented/web/tests/web/node/replace_child_3/with_new_child_is_parent_returns_error_hierarchy_request/label_4.rs
+++ b/native_implemented/web/tests/web/node/replace_child_3/with_new_child_is_parent_returns_error_hierarchy_request/label_4.rs
@@ -7,7 +7,7 @@
 //! {:error, :hierarchy_request} = Lumen.Web.replace_child(parent, old_child, parent)
 //! ```
 
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 #[native_implemented::label]
diff --git a/native_implemented/web/tests/web/node/replace_child_3/with_new_child_returns_ok_replaced_child.rs b/native_implemented/web/tests/web/node/replace_child_3/with_new_child_returns_ok_replaced_child.rs
index f39f21254..5a77dcbe0 100644
--- a/native_implemented/web/tests/web/node/replace_child_3/with_new_child_returns_ok_replaced_child.rs
+++ b/native_implemented/web/tests/web/node/replace_child_3/with_new_child_returns_ok_replaced_child.rs
@@ -18,7 +18,7 @@ pub mod label_4;
 #[path = "with_new_child_returns_ok_replaced_child/label_5.rs"]
 pub mod label_5;
 
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use liblumen_web::document;
diff --git a/native_implemented/web/tests/web/node/replace_child_3/with_new_child_returns_ok_replaced_child/label_1.rs b/native_implemented/web/tests/web/node/replace_child_3/with_new_child_returns_ok_replaced_child/label_1.rs
index 1ecbfc2b8..1679a46e7 100644
--- a/native_implemented/web/tests/web/node/replace_child_3/with_new_child_returns_ok_replaced_child/label_1.rs
+++ b/native_implemented/web/tests/web/node/replace_child_3/with_new_child_returns_ok_replaced_child/label_1.rs
@@ -14,7 +14,7 @@
 use std::convert::TryInto;
 
 use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use super::label_2;
diff --git a/native_implemented/web/tests/web/node/replace_child_3/with_new_child_returns_ok_replaced_child/label_2.rs b/native_implemented/web/tests/web/node/replace_child_3/with_new_child_returns_ok_replaced_child/label_2.rs
index 3c9e4995d..7a95d201f 100644
--- a/native_implemented/web/tests/web/node/replace_child_3/with_new_child_returns_ok_replaced_child/label_2.rs
+++ b/native_implemented/web/tests/web/node/replace_child_3/with_new_child_returns_ok_replaced_child/label_2.rs
@@ -13,7 +13,7 @@
 use std::convert::TryInto;
 
 use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use super::label_3;
diff --git a/native_implemented/web/tests/web/node/replace_child_3/with_new_child_returns_ok_replaced_child/label_3.rs b/native_implemented/web/tests/web/node/replace_child_3/with_new_child_returns_ok_replaced_child/label_3.rs
index 704aecce9..84195d5c0 100644
--- a/native_implemented/web/tests/web/node/replace_child_3/with_new_child_returns_ok_replaced_child/label_3.rs
+++ b/native_implemented/web/tests/web/node/replace_child_3/with_new_child_returns_ok_replaced_child/label_3.rs
@@ -11,7 +11,7 @@
 
 use std::convert::TryInto;
 
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use super::label_4;
diff --git a/native_implemented/web/tests/web/node/replace_child_3/with_new_child_returns_ok_replaced_child/label_4.rs b/native_implemented/web/tests/web/node/replace_child_3/with_new_child_returns_ok_replaced_child/label_4.rs
index cdb91be10..24a8d0786 100644
--- a/native_implemented/web/tests/web/node/replace_child_3/with_new_child_returns_ok_replaced_child/label_4.rs
+++ b/native_implemented/web/tests/web/node/replace_child_3/with_new_child_returns_ok_replaced_child/label_4.rs
@@ -9,7 +9,7 @@
 //! ```
 
 use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use super::label_5;
diff --git a/native_implemented/web/tests/web/node/replace_child_3/with_new_child_returns_ok_replaced_child/label_5.rs b/native_implemented/web/tests/web/node/replace_child_3/with_new_child_returns_ok_replaced_child/label_5.rs
index 579fc1d8f..946d76205 100644
--- a/native_implemented/web/tests/web/node/replace_child_3/with_new_child_returns_ok_replaced_child/label_5.rs
+++ b/native_implemented/web/tests/web/node/replace_child_3/with_new_child_returns_ok_replaced_child/label_5.rs
@@ -10,7 +10,7 @@
 use std::convert::TryInto;
 
 use liblumen_alloc::erts::exception;
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 #[native_implemented::label]
diff --git a/runtimes/core/src/context.rs b/runtimes/core/src/context.rs
index 8e5578893..acd9a915d 100644
--- a/runtimes/core/src/context.rs
+++ b/runtimes/core/src/context.rs
@@ -6,7 +6,7 @@ use anyhow::*;
 
 use liblumen_alloc::erts::exception::{self, badmap, Exception};
 use liblumen_alloc::erts::process::trace::Trace;
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 
 use crate::time;
diff --git a/runtimes/core/src/process/spawn/options.rs b/runtimes/core/src/process/spawn/options.rs
index 2cf0abd48..05d7d2017 100644
--- a/runtimes/core/src/process/spawn/options.rs
+++ b/runtimes/core/src/process/spawn/options.rs
@@ -7,7 +7,7 @@ use anyhow::*;
 use liblumen_alloc::erts::exception::Alloc;
 use liblumen_alloc::erts::process::alloc::{default_heap_size, heap, next_heap_size};
 use liblumen_alloc::erts::process::priority::Priority;
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 use liblumen_alloc::ModuleFunctionArity;
 
diff --git a/runtimes/core/src/scheduler.rs b/runtimes/core/src/scheduler.rs
index 5c59155c9..6f0a555a0 100644
--- a/runtimes/core/src/scheduler.rs
+++ b/runtimes/core/src/scheduler.rs
@@ -11,7 +11,7 @@ use lazy_static::lazy_static;
 
 use liblumen_core::locks::{Mutex, RwLock};
 
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 pub use liblumen_alloc::erts::scheduler::id::ID;
 use liblumen_alloc::erts::term::prelude::*;
 use liblumen_alloc::Priority;
diff --git a/runtimes/crt/build.rs b/runtimes/crt/build.rs
index 5eb17f6cc..75f8f7f29 100644
--- a/runtimes/crt/build.rs
+++ b/runtimes/crt/build.rs
@@ -63,7 +63,8 @@ fn main() {
         .arg(&libstd_rlib)
         .stdout(Stdio::piped());
     let symbols = output(nm_cmd);
-    // Find the first line containing the mangled symbol for std::rt::lang_start_internal, and postprocess it
+    // Find the first line containing the mangled symbol for std::rt::lang_start_internal, and
+    // postprocess it
     let lang_start_symbol = symbols
         .lines()
         .map(|line| line.trim())
diff --git a/runtimes/full/Cargo.toml b/runtimes/full/Cargo.toml
index 0aa7fe9fa..84d8129d7 100644
--- a/runtimes/full/Cargo.toml
+++ b/runtimes/full/Cargo.toml
@@ -15,8 +15,7 @@ colored = "2.0"
 thiserror = "1.0"
 lazy_static = "1.4"
 libc = "0.2"
-liblumen_core = { path = "../../library/core" }
-liblumen_alloc = { path = "../../liblumen_alloc" }
+liblumen_alloc = { path = "../../library/alloc" }
 log = "0.4"
 lumen_rt_core = { path = "../core" }
 num-bigint = "0.4"
diff --git a/runtimes/full/src/run.rs b/runtimes/full/src/run.rs
index 529656b70..3a750e141 100644
--- a/runtimes/full/src/run.rs
+++ b/runtimes/full/src/run.rs
@@ -1,6 +1,6 @@
 use std::sync::Arc;
 
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 
 pub mod queues;
 
diff --git a/runtimes/minimal/src/builtins/receive.rs b/runtimes/minimal/src/builtins/receive.rs
index c97709200..da823a4ab 100644
--- a/runtimes/minimal/src/builtins/receive.rs
+++ b/runtimes/minimal/src/builtins/receive.rs
@@ -2,7 +2,7 @@ use std::convert::TryInto;
 use std::sync::Arc;
 
 use liblumen_alloc::erts::message::Message;
-use liblumen_alloc::erts::process::Process;
+use liblumen_rt::process::Process;
 use liblumen_alloc::erts::term::prelude::*;
 use liblumen_alloc::erts::timeout::{ReceiveTimeout, Timeout};
 
diff --git a/runtimes/tiny/src/erlang/mod.rs b/runtimes/tiny/src/erlang/mod.rs
index d07d0e3f1..7b5f021af 100644
--- a/runtimes/tiny/src/erlang/mod.rs
+++ b/runtimes/tiny/src/erlang/mod.rs
@@ -450,7 +450,7 @@ fn make_reason<R: Into<OpaqueTerm>>(tag: Atom, reason: R) -> OpaqueTerm {
     scheduler::with_current(|scheduler| {
         let arc_proc = scheduler.current_process();
         let proc = arc_proc.deref();
-        Tuple::from_slice(&[tag.into(), reason.into()], proc)
+        Tuple::from_opaque_term_slice(&[tag.into(), reason.into()], proc)
             .unwrap()
             .into()
     })
diff --git a/runtimes/tiny/src/intrinsic/mod.rs b/runtimes/tiny/src/intrinsic/mod.rs
index a3a90b7ec..971a25651 100644
--- a/runtimes/tiny/src/intrinsic/mod.rs
+++ b/runtimes/tiny/src/intrinsic/mod.rs
@@ -348,8 +348,8 @@ pub extern "C-unwind" fn bs_push(
             ok!(bin)
         }
         BinaryEntrySpecifier::Binary { unit } => {
-            // Size must be a non-negative integer, or None to represent pushing all of the source value
-            // into the destination buffer
+            // Size must be a non-negative integer, or None to represent pushing all of the source
+            // value into the destination buffer
             let size: Option<usize> = match size.into() {
                 Term::None => None,
                 Term::Int(sz) if sz >= 0 => {
diff --git a/runtimes/tiny/src/lib.rs b/runtimes/tiny/src/lib.rs
index ba4904557..81bfa0672 100644
--- a/runtimes/tiny/src/lib.rs
+++ b/runtimes/tiny/src/lib.rs
@@ -1,10 +1,12 @@
+#![feature(allocator_api)]
 #![feature(c_unwind)]
+#![feature(iterator_try_collect)]
+#![feature(let_else)]
 #![feature(once_cell)]
-#![feature(ptr_metadata)]
 #![feature(process_exitcode_internals)]
+#![feature(ptr_metadata)]
 #![feature(thread_local)]
-#![feature(let_else)]
-#![feature(iterator_try_collect)]
+#![feature(thread_id_value)]
 
 extern crate firefly_crt;
 
@@ -12,7 +14,7 @@ mod env;
 mod erlang;
 mod init;
 mod intrinsic;
-mod scheduler;
+pub mod scheduler;
 mod sys;
 
 use bus::Bus;
diff --git a/runtimes/tiny/src/scheduler/mod.rs b/runtimes/tiny/src/scheduler/mod.rs
index eda3b6c34..1e36e45bf 100644
--- a/runtimes/tiny/src/scheduler/mod.rs
+++ b/runtimes/tiny/src/scheduler/mod.rs
@@ -1,6 +1,7 @@
 mod exit;
 mod queue;
 
+use std::alloc::{AllocError, Allocator};
 use std::arch::global_asm;
 use std::cell::{OnceCell, UnsafeCell};
 use std::mem;
@@ -11,9 +12,11 @@ use std::sync::{
 };
 use std::thread::{self, ThreadId};
 
+use firefly_alloc::gc::GcBox;
+
 use firefly_rt::function::{DynamicCallee, ModuleFunctionArity};
 use firefly_rt::process::{Process, ProcessStatus};
-use firefly_rt::term::{OpaqueTerm, Pid, ProcessId};
+use firefly_rt::term::{OpaqueTerm, Pid, ProcessId, Reference, ReferenceId, Term};
 
 use self::queue::RunQueue;
 
@@ -31,6 +34,20 @@ where
     fun(CURRENT_SCHEDULER.get().unwrap())
 }
 
+pub fn next_local_reference_term<A: Allocator>(alloc: A) -> Result<Term, AllocError> {
+    CURRENT_SCHEDULER
+        .get()
+        .unwrap()
+        .next_local_reference_term(alloc)
+}
+
+pub fn local_reference_term<A: Allocator>(alloc: A, id: u64) -> Result<Term, AllocError> {
+    CURRENT_SCHEDULER
+        .get()
+        .unwrap()
+        .local_reference_term(alloc, id)
+}
+
 /// Initializes the scheduler for the current thread, if not already initialized,
 /// returning a reference to it
 pub fn init<'a>() -> bool {
@@ -130,6 +147,52 @@ impl Scheduler {
         })
     }
 
+    fn scheduler_id(&self) -> u16 {
+        self
+            .id
+            .as_u64()
+            .get()
+            .try_into()
+            .expect("Scheduler ID does not fit in u16")
+    }
+
+    fn next_reference_id(&self) -> ReferenceId {
+        let id = self.next_reference_id.fetch_add(1, Ordering::SeqCst);
+        self.reference_id(id)
+    }
+
+    fn next_local_reference(&self) -> Reference {
+        Reference::Local {
+            id: self.next_reference_id(),
+        }
+    }
+
+    pub fn next_local_reference_term<A: Allocator>(&self, alloc: A) -> Result<Term, AllocError> {
+        Ok(Term::Reference(GcBox::new_in(
+            self.next_local_reference(),
+            alloc,
+        )?))
+    }
+
+    fn reference_id(&self, id: u64) -> ReferenceId {
+        let scheduler_id = self.scheduler_id();
+
+        ReferenceId::new(scheduler_id, id)
+    }
+
+    fn local_reference(&self, id: u64) -> Reference {
+        Reference::Local {
+            id: self.reference_id(id)
+        }
+    }
+
+    pub fn local_reference_term<A: Allocator>(&self, alloc: A, id: u64) -> Result<Term, AllocError> {
+        Ok(Term::Reference(GcBox::new_in(
+            self.local_reference(id),
+            alloc,
+        )?))
+    }
+
     fn parent(&self) -> ProcessId {
         self.current().process.pid()
     }
@@ -205,7 +268,8 @@ impl Scheduler {
         //
         // If this process exits, the scheduler terminates
         let mfa: ModuleFunctionArity = "init:start/0".parse().unwrap();
-        //let init_fn = function::find_symbol(&mfa).expect("unable to locate init:start/0 function!");
+        //let init_fn = function::find_symbol(&mfa).expect("unable to locate init:start/0
+        // function!");
         let init_fn = crate::init::start as DynamicCallee;
         let process = Arc::new(Process::new(Some(self.parent()), ProcessId::next(), mfa));