(Toy) Compiler Infrastructure influenced by LLVM written in Rust

Overview

Sericum

CircleCI

Compiler Infrastructure influenced by LLVM written in Rust

Do not expect too much stuff!

To Do

  • Implement basic block parameters
  • Make it possible to generate code for multiple targets without rebuilding sericum itself
  • Verify IR
  • More optimizations for IR
  • Support returning struct as value
  • Write documents

Build

Requirement: Rust nightly

cargo test           --features x86_64                          # build for x86_64
cargo test brainfuxk --features x86_64 --release -- --nocapture # this is fun. just try it.
cargo test           --features aarch64                         # build for aarch64. a few features are implemented.
cargo test           --features riscv64                         # currently doesn't work. need help.

Example

cargo test demo --features $ARCH -- --nocapture # $ARCH is x86_64 or aarch64
  • Useful macro is available to describe IR
let fibo = sericum_ir!(m; define [i32] f [(i32)] {
    entry:
        cond = icmp le (%arg.0), (i32 2);
        br (%cond) l1, l2;
    l1:
        ret (i32 1);
    l2:
        a1 = sub (%arg.0), (i32 1);
        r1 = call f [(%a1)];
        a2 = sub (%arg.0), (i32 2);
        r2 = call f [(%a2)];
        r3 = add (%r1), (%r2);
        ret (%r3);
});

Make your own language using sericum as backend

./minilang and ./sericumcc may help you.

Comments
  • Problem in internal function call.

    Problem in internal function call.

    I met a SIGSEGV when running the code below. When remove call (->cilk_println_i32), the code terminates normally. Do you figure any reason out about this? Any problems about save/restore physical registers around the func call?

    use cilk::{
        exec::{jit::x64::compiler},
        *,
    };
    
    pub fn sample() {
        let mut m = module::Module::new("cilk");
    
        // Internal function must be defined when you use it
        let cilk_println_i32 = m.add_function(ir::function::Function::new(
            "cilk.println.i32",
            ir::types::Type::Void,
            vec![ir::types::Type::Int32],
        ));
    
        let main = cilk_ir!(m; define [void] main () {
            entry:
                i = alloca i32;
                store (i32 10), (%i);
                li = load (%i);
                __ = call (->cilk_println_i32) [(%li)];    // If remove this line, this code works.
                ret (void);
        });
    
        let mut jit = compiler::JITCompiler::new(&m);
        jit.compile_module();
        jit.run(main, vec![]);
    }
    
    error: process didn't exit successfully: `~/Documents/GitHub/cilk/target/debug/deps/sample-9b41210e16725396 --nocapture sample` (signal: 11, SIGSEGV: invalid memory reference)
    
    opened by sisshiki1969 7
  • Better DAG handling

    Better DAG handling

    Currently, DAG nodes are managed using id_arena. However, it's troblesome to write code like arena[id].sth, which should be written like node.sth. So I'm planning to use raw pointer to take around dag nodes. (it's unsafe though) Are there better ideas?

    opened by maekawatoshiki 6
  • Panic in Opcode::Call

    Panic in Opcode::Call

    I'm working on compiling JavaScript to cilk-ir with rapidus, and executing by jit/x64/compiler. And found a curious behavior described below. Both of the codes work with an interpreter correctly.

    Do you have any idea?

    This IR works well.

    liveness: define i32 main(i32) {
    label.0:        // pred(), succ(), def(4,1,3), in(), out()
        %1 = alloca i32
        store i32 100, i32* %1
        %3 = load i32* %1
        %4 = call i32 f(i32 %3, )
        ret i32 %4
        ret i32 0
    
    }
    liveness: define i32 f(i32) {
    label.0:        // pred(), succ(), def(1), in(), out()
        %1 = add i32 %arg.0, i32 1
        ret i32 %1
        ret i32 0
    
    }
    vreg:1  reg:None        spill:false
    vreg:2  reg:None        spill:false
    vreg:3  reg:Some(Register(0))   spill:false
    vreg:4  reg:Some(Register(0))   spill:false
    vreg:5  reg:None        spill:false
    vreg:6  reg:None        spill:false
    vreg:1  reg:Some(Register(0))   spill:false
    vreg:2  reg:None        spill:false
    vreg:3  reg:None        spill:false
    exec: Int32(101)
    saved register: []
    jit: Int32(101)
    

    But this goes panic when compiling call instruction.

    liveness: define i32 main(i32) {
    label.0:        // pred(), succ(), def(4,1,3), in(), out()
        %1 = alloca i32
        store i32 100, i32* %1
        %3 = load i32* %1
        %4 = call i32 f(i32 %3, )
        ret i32 0
    
    }
    liveness: define i32 f(i32) {
    label.0:        // pred(), succ(), def(1), in(), out()
        %1 = add i32 %arg.0, i32 1
        ret i32 %1
        ret i32 0
    
    }
    vreg:1  reg:None        spill:false
    vreg:2  reg:None        spill:false
    vreg:3  reg:Some(Register(0))   spill:false
    vreg:4  reg:None        spill:false
    vreg:5  reg:None        spill:false
    vreg:1  reg:Some(Register(0))   spill:false
    vreg:2  reg:None        spill:false
    vreg:3  reg:None        spill:false
    exec: Int32(0)
    saved register: []
    thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', src/libcore/option.rs:347:21
    stack backtrace:
       0: backtrace::backtrace::libunwind::trace
                 at /Users/vsts/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.29/src/backtrace/libunwind.rs:88
       ...
      11: core::option::Option<T>::unwrap
                 at /rustc/dfd52ba6ac2262c6b61c59ec86bfd23e4e53d3de/src/libcore/macros.rs:12
      12: cilk::exec::jit::x64::compiler::JITCompiler::compile
                 at cilk/src/exec/jit/x64/compiler.rs:223
      13: rapidus::main
                 at rapidus/src/main.rs:83
      ...
    
    

    The JavaScript source codes are here.

    /// This works.
    let x = 100
    return f(x)
    function f(x) {
      return x + 1
    }
    /// This fails.
    let x = 100
    f(x)
    function f(x) {
      return x + 1
    }
    
    opened by sisshiki1969 6
  • Naming issue: The Cilk language

    Naming issue: The Cilk language

    Disclaimer: I have nothing to do with the Cilk language.


    I noticed that this compiler infrastructure has the same name as the Cilk programming language, which is released in the 1990s: https://en.wikipedia.org/wiki/Cilk.

    This can be a bit confusing because there are currently two "Cilk"s in the field of compiler implementation. But the confusion should be a little because one is a language and the other is a tool for compilers.

    My question is: Have you already discussed this naming issue? If you've already done so, please just close this issue. If not, I think it is a good idea to consider this issue before your Cilk becomes more famous :)

    opened by nekketsuuu 4
  • About `cargo test --doc`

    About `cargo test --doc`

    I pushed some commits (that add some doc-comment to src/ir/module.rs experimentally) under docs branch,
    but cargo test --docnot worked yet because some files occurs fail to resolve error while compilation.
    cilk must fix this Inconsistency first, for expecting efficiently tests

    What do you think?

    docs ブランチを切ってdoc-commentをいくつか書いてみました.
    しかし現状cilkで cargo test [--doc] が失敗するため,docs.rs ページのビルドも失敗する という問題があります.

    そこで,私に「cargo test によって発生するバグたちを潰す作業」 をやらせてもらえませんか?
    コンパイルエラーを削除することができればdocs.rsも生えて,使ってくれる人も増えるはず.
    (TODOにテスト書きたいというのもあったので,そのままユニットテストを書くのもやっていこうかな?と思っています)

    opened by Drumato 4
  • JavaScript-like front-end for cilk.

    JavaScript-like front-end for cilk.

    I am working on a compiler which converts JavaScript source code to cilk-IR and execute. https://github.com/sisshiki1969/rapidus-cilk Be aware that cilk folder is empty, so git clone here before execution.

    limitation

    • Currently, only integer is supported.
    • All variables must be declared using let.
    • Can not refer external variables (variables declared outside of the function).
    • A block scope is not yet implemented. (Function scope only)
    • Can use console.log() to print.

    sample code

    function fibo(x) {
      if (x == 1) {
        return 1
      } else if (x == 2) {
        return 1
      } else {
        return fibo_sub(x - 1, x - 2)
      }
      // function in function
      function fibo_sub(x, y) {
        return fibo(x) + fibo(y)
      }
    }
    
    let x = fibo(10)
    console.log(x)
    return x
    
    function prime(n) {
      if (n % 2 == 0) return 0
      for (let k = 3; k * k <= n; k += 2) { if (n % k == 0) return 0 }
      return 1
    }
    
    let max = 2
    
    for (let i = 2; i <= 20; i += 1) {
      if (prime(i) == 1) {
        console.log(i)
        max = i
      }
    }
    
    return max
    
    let x = 0
    while (x <= 8) {
      x += 1
    }
    console.log(x)
    return x
    
    opened by sisshiki1969 1
Owner
uint256_t
C++/Rust; Undergraduate student
uint256_t
An esoteric language/compiler written with Rust and Rust LLVM bindings

MeidoLang (メイドラング) A not so useful and esoteric language. The goal of this project was to contain some quirky or novel syntax in a stack-style program

null 0 Dec 24, 2021
Symbolic execution of LLVM IR with an engine written in Rust

haybale: Symbolic execution of LLVM IR, written in Rust haybale is a general-purpose symbolic execution engine written in Rust. It operates on LLVM IR

UCSD PLSysSec 404 Jan 1, 2023
A simple password manager written in Rust

ripasso A simple password manager written in Rust. The root crate ripasso is a library for accessing and decrypting passwords stored in pass format (G

Joakim Lundborg 548 Dec 26, 2022
A fast, simple, recursive content discovery tool written in Rust.

A simple, fast, recursive content discovery tool written in Rust ?? Releases ✨ Example Usage ✨ Contributing ✨ Documentation ?? ?? What the heck is a f

epi 3.6k Dec 30, 2022
link is a command and control framework written in rust

link link is a command and control framework written in rust. Currently in alpha. Table of Contents Introduction Features Feedback Build Process Ackno

null 427 Dec 24, 2022
simple multi-threaded port scanner written in rust

knockson simple multi-threaded port scanner written in rust Install Using AUR https://aur.archlinux.org/packages/knockson-bin/ yay -Syu knockson-bin M

Josh Münte 4 Oct 5, 2022
Multi-threaded Padding Oracle attacks against any service. Written in Rust.

rustpad is a multi-threaded successor to the classic padbuster, written in Rust. It abuses a Padding Oracle vulnerability to decrypt any cypher text or encrypt arbitrary plain text without knowing the encryption key!

Kibouo 76 Dec 16, 2022
OpenSK is an open-source implementation for security keys written in Rust that supports both FIDO U2F and FIDO2 standards.

OpenSK This repository contains a Rust implementation of a FIDO2 authenticator. We developed OpenSK as a Tock OS application. We intend to bring a ful

Google 2.4k Jan 7, 2023
Unofficial Bitwarden compatible server written in Rust, formerly known as bitwarden_rs

Alternative implementation of the Bitwarden server API written in Rust and compatible with upstream Bitwarden clients*, perfect for self-hosted deploy

Daniel García 21.5k Jan 8, 2023
An impish, cross-platform binary parsing crate, written in Rust

libgoblin Documentation https://docs.rs/goblin/ changelog Usage Goblin requires rustc 1.40.0. Add to your Cargo.toml [dependencies] goblin = "0.4" Fea

null 891 Dec 29, 2022
rd is a record/replay debugger written in rust

rd The Record & Debug Tool The Record & Debug Tool (rd) is a Rust language port of the rr-debugger/rr debugger. With rd you can record Linux program e

Sidharth Kshatriya 947 Dec 8, 2022
Simple prepender virus written in Rust

Linux.Fe2O3 This is a POC ELF prepender written in Rust. I like writting prependers on languages that I'm learning and find interesting. As for the na

Guilherme Thomazi Bonicontro 91 Dec 9, 2022
Linux LPE using polkit-1 written in Rust.

CVE-2021-4024-Rust Linux LPE using polkit-1 written in Rust. Build instructions Install rust if you haven't already git clone https://github.com/deoxy

Kevin Pham 1 Feb 3, 2022
A simple allocator written in Rust that manages memory in fixed-size chunks.

Simple Chunk Allocator A simple no_std allocator written in Rust that manages memory in fixed-size chunks/blocks. Useful for basic no_std binaries whe

Philipp Schuster 7 Aug 8, 2022
subscout is a simple, nimble subdomain enumeration tool written in Rust language

subscout is a simple, nimble subdomain enumeration tool written in Rust language. It is designed to help bug bounty hunters, security professionals and penetration testers discover subdomains of a given target domain.

Dom Sec 5 Apr 5, 2023
Attempts to suspend all known AV/EDRs processes on Windows using syscalls and the undocumented NtSuspendProcess API. Made with <3 for pentesters. Written in Rust.

Ronflex Attempts to suspend all known AV/EDRs processes on Windows using syscalls and the undocumented NtSuspendProcess API. Made with <3 for penteste

null 5 Apr 17, 2023
💔 Heartbleed vulnerability exploit written in Rust

Heartbleed ?? Heartbleed vulnerability exploit written in Rust What is it Heartbleed is a buffer over-read vulnerability in outdated versions of OpenS

Gianmatteo Palmieri 4 May 23, 2023
Detects usage of unsafe Rust in a Rust crate and its dependencies.

cargo-geiger ☢️ Looking for maintainer: https://github.com/rust-secure-code/cargo-geiger/issues/210 A program that lists statistics related to the usa

Rust Secure Code Working Group 1.1k Jan 4, 2023
Rust-verification-tools - RVT is a collection of tools/libraries to support both static and dynamic verification of Rust programs.

Rust verification tools This is a collection of tools/libraries to support both static and dynamic verification of Rust programs. We see static verifi

null 253 Dec 31, 2022