strip unused functions, rc4, base64
This commit is contained in:
@@ -7,7 +7,7 @@ func main[] : I64
|
|||||||
let s: I64 = 1
|
let s: I64 = 1
|
||||||
let j: I64 = 0
|
let j: I64 = 0
|
||||||
while j < 13
|
while j < 13
|
||||||
s = s * Char.parse_i64(String.nth(n, i + j))
|
s = s * U8.parse_i64(String.nth(n, i + j))
|
||||||
j = j + 1
|
j = j + 1
|
||||||
if s > out
|
if s > out
|
||||||
out = s
|
out = s
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ macro_rules! emit {
|
|||||||
|
|
||||||
static REGISTERS: [&str; 6] = ["rdi", "rsi", "rdx", "rcx", "r8", "r9"];
|
static REGISTERS: [&str; 6] = ["rdi", "rsi", "rdx", "rcx", "r8", "r9"];
|
||||||
// TODO: currently they are all just 8 byte values
|
// TODO: currently they are all just 8 byte values
|
||||||
static TYPES: [&str; 6] = ["I64", "String", "Bool", "Ptr", "Char", "Array"];
|
static TYPES: [&str; 6] = ["U8", "I64", "String", "Bool", "Ptr", "Array"];
|
||||||
|
|
||||||
pub struct CodegenX86_64 {
|
pub struct CodegenX86_64 {
|
||||||
output: String,
|
output: String,
|
||||||
@@ -127,14 +127,43 @@ extern closedir
|
|||||||
extern exit
|
extern exit
|
||||||
extern gettimeofday
|
extern gettimeofday
|
||||||
|
|
||||||
|
section .text.Bit.lshift
|
||||||
|
Bit.lshift:
|
||||||
|
mov rcx, rsi
|
||||||
|
mov rax, rdi
|
||||||
|
shl rax, cl
|
||||||
|
ret
|
||||||
|
|
||||||
|
section .text.Bit.rshift
|
||||||
|
Bit.rshift:
|
||||||
|
mov rcx, rsi
|
||||||
|
mov rax, rdi
|
||||||
|
sar rax, cl
|
||||||
|
ret
|
||||||
|
|
||||||
|
section .text.Bit.and
|
||||||
|
Bit.and:
|
||||||
|
mov rax, rdi
|
||||||
|
and rax, rsi
|
||||||
|
ret
|
||||||
|
|
||||||
|
section .text.Bit.or
|
||||||
|
Bit.or:
|
||||||
|
mov rax, rdi
|
||||||
|
or rax, rsi
|
||||||
|
ret
|
||||||
|
|
||||||
|
section .text.String.nth
|
||||||
String.nth:
|
String.nth:
|
||||||
movzx rax, byte [rdi + rsi]
|
movzx rax, byte [rdi + rsi]
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
section .text.String.set
|
||||||
String.set:
|
String.set:
|
||||||
mov [rdi + rsi], dl
|
mov [rdi + rsi], dl
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
section .text.OS.time
|
||||||
OS.time:
|
OS.time:
|
||||||
push rbx
|
push rbx
|
||||||
sub rsp, 16
|
sub rsp, 16
|
||||||
@@ -152,6 +181,7 @@ OS.time:
|
|||||||
pop rbx
|
pop rbx
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
section .text.OS.listdir
|
||||||
OS.listdir:
|
OS.listdir:
|
||||||
push r14
|
push r14
|
||||||
push rbx
|
push rbx
|
||||||
@@ -193,16 +223,19 @@ OS.listdir:
|
|||||||
pop r14
|
pop r14
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
section .text.Array.nth
|
||||||
Array.nth:
|
Array.nth:
|
||||||
mov rax, [rdi]
|
mov rax, [rdi]
|
||||||
mov rax, [rax + rsi*8]
|
mov rax, [rax + rsi*8]
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
section .text.Array.set
|
||||||
Array.set:
|
Array.set:
|
||||||
mov rax, [rdi]
|
mov rax, [rdi]
|
||||||
mov [rax + rsi*8], rdx
|
mov [rax + rsi*8], rdx
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
section .text.Array.push
|
||||||
Array.push:
|
Array.push:
|
||||||
push r14
|
push r14
|
||||||
push rbx
|
push rbx
|
||||||
@@ -231,10 +264,12 @@ Array.push:
|
|||||||
pop r14
|
pop r14
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
section .text.Array.size
|
||||||
Array.size:
|
Array.size:
|
||||||
mov rax, [rdi + 16]
|
mov rax, [rdi + 16]
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
section .text.Array.free
|
||||||
Array.free:
|
Array.free:
|
||||||
push rbx
|
push rbx
|
||||||
mov rbx, rdi
|
mov rbx, rdi
|
||||||
@@ -315,6 +350,7 @@ Array.free:
|
|||||||
if name.lexeme == "main" {
|
if name.lexeme == "main" {
|
||||||
emit!(&mut self.output, "global {}", name.lexeme);
|
emit!(&mut self.output, "global {}", name.lexeme);
|
||||||
}
|
}
|
||||||
|
emit!(&mut self.output, "section .text.{}", name.lexeme);
|
||||||
emit!(&mut self.output, "{}:", name.lexeme);
|
emit!(&mut self.output, "{}:", name.lexeme);
|
||||||
emit!(&mut self.output, " push rbp");
|
emit!(&mut self.output, " push rbp");
|
||||||
emit!(&mut self.output, " mov rbp, rsp");
|
emit!(&mut self.output, " mov rbp, rsp");
|
||||||
|
|||||||
12
src/main.rs
12
src/main.rs
@@ -50,7 +50,7 @@ fn compile_file(path: String) -> Result<(), ZernError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !Command::new("nasm")
|
if !Command::new("nasm")
|
||||||
.args(["-f", "elf64", "-w+all", "-o", "out.o", "out.s"])
|
.args(["-f", "elf64", "-o", "out.o", "out.s"])
|
||||||
.status()
|
.status()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.success()
|
.success()
|
||||||
@@ -60,7 +60,15 @@ fn compile_file(path: String) -> Result<(), ZernError> {
|
|||||||
|
|
||||||
// TODO: drop libc entirely
|
// TODO: drop libc entirely
|
||||||
if !Command::new("./musl-1.2.4/root/bin/musl-gcc")
|
if !Command::new("./musl-1.2.4/root/bin/musl-gcc")
|
||||||
.args(["-static", "-o", "out", "out.o"])
|
.args([
|
||||||
|
"-static",
|
||||||
|
"-o",
|
||||||
|
"out",
|
||||||
|
"out.o",
|
||||||
|
"-flto",
|
||||||
|
"-Os",
|
||||||
|
"-Wl,--gc-sections",
|
||||||
|
])
|
||||||
.status()
|
.status()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.success()
|
.success()
|
||||||
|
|||||||
82
src/std.zr
82
src/std.zr
@@ -11,7 +11,7 @@ func print_i64[x: I64] : I64
|
|||||||
printf("%ld\n", x)
|
printf("%ld\n", x)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
func String.is_whitespace[c: Char] : Bool
|
func String.is_whitespace[c: U8] : Bool
|
||||||
return c == 10 || c == 32 || c == 13 || c == 9
|
return c == 10 || c == 32 || c == 13 || c == 9
|
||||||
|
|
||||||
func String.concat[a: String, b: String] : String
|
func String.concat[a: String, b: String] : String
|
||||||
@@ -20,6 +20,12 @@ func String.concat[a: String, b: String] : String
|
|||||||
strcat(c, b)
|
strcat(c, b)
|
||||||
return c
|
return c
|
||||||
|
|
||||||
|
func String.find[s: String, needle: U8] : I64
|
||||||
|
for i in 0:strlen(s)
|
||||||
|
if String.nth(s, i) == needle
|
||||||
|
return i
|
||||||
|
return -1
|
||||||
|
|
||||||
func String.substr[s: String, start: I64, length: I64] : String
|
func String.substr[s: String, start: I64, length: I64] : String
|
||||||
let out: String = malloc(length + 1)
|
let out: String = malloc(length + 1)
|
||||||
strlcpy(out, s + start, length + 1)
|
strlcpy(out, s + start, length + 1)
|
||||||
@@ -42,8 +48,7 @@ func String.rev[s: String] : String
|
|||||||
let out: String = malloc(len + 1)
|
let out: String = malloc(len + 1)
|
||||||
|
|
||||||
for i in 0:len
|
for i in 0:len
|
||||||
let c: Char = String.nth(s, len - i - 1)
|
String.set(out, i, String.nth(s, len - i - 1))
|
||||||
String.set(out, i, c)
|
|
||||||
String.set(out, len, 0)
|
String.set(out, len, 0)
|
||||||
return out
|
return out
|
||||||
|
|
||||||
@@ -72,7 +77,7 @@ func IO.write_file[path: String, content: String] : I64
|
|||||||
fclose(file)
|
fclose(file)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
func Char.parse_i64[c: Char]: I64
|
func U8.parse_i64[c: U8]: I64
|
||||||
return c - 48
|
return c - 48
|
||||||
|
|
||||||
func I64.to_string[n: I64] : String
|
func I64.to_string[n: I64] : String
|
||||||
@@ -145,4 +150,71 @@ func Math.is_prime[n: I64]: I64
|
|||||||
return true
|
return true
|
||||||
|
|
||||||
func Array.new[] : Array
|
func Array.new[] : Array
|
||||||
return calloc(1, 24)
|
return calloc(1, 24)
|
||||||
|
|
||||||
|
func Math.Crypto.rc4[key: String, plaintext: String]: String
|
||||||
|
let S: String = malloc(256)
|
||||||
|
for i in 0:256
|
||||||
|
String.set(S, i, i)
|
||||||
|
|
||||||
|
let j: I64 = 0
|
||||||
|
let key_len: I64 = strlen(key)
|
||||||
|
for i in 0:256
|
||||||
|
j = (j + String.nth(S, i) + String.nth(key, i % key_len)) % 256
|
||||||
|
let tmp: U8 = String.nth(S, i)
|
||||||
|
String.set(S, i, String.nth(S, j))
|
||||||
|
String.set(S, j, tmp)
|
||||||
|
|
||||||
|
let i: I64 = 0
|
||||||
|
j = 0
|
||||||
|
let plaintext_len: I64 = strlen(plaintext)
|
||||||
|
let ciphertext: String = malloc(plaintext_len+1)
|
||||||
|
for n in 0:plaintext_len
|
||||||
|
i = (i + 1) % 256
|
||||||
|
j = (j + String.nth(S, i)) % 256
|
||||||
|
|
||||||
|
let tmp: U8 = String.nth(S, i)
|
||||||
|
String.set(S, i, String.nth(S, j))
|
||||||
|
String.set(S, j, tmp)
|
||||||
|
|
||||||
|
let r: I64 = String.nth(S, (String.nth(S, i) + String.nth(S, j)) % 256)
|
||||||
|
String.set(ciphertext, n, r ^ String.nth(plaintext, n))
|
||||||
|
|
||||||
|
String.set(ciphertext, plaintext_len, 0)
|
||||||
|
free(S)
|
||||||
|
return ciphertext
|
||||||
|
|
||||||
|
func Math.Crypto.base64_encode[s: String] : String
|
||||||
|
let chars: String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
|
||||||
|
let s_len: I64 = strlen(s)
|
||||||
|
let output: String = malloc(s_len*2)
|
||||||
|
let i: I64 = 0
|
||||||
|
let j: I64 = 0
|
||||||
|
|
||||||
|
while i < s_len
|
||||||
|
let b1: U8 = String.nth(s, i)
|
||||||
|
let b2: U8 = 0
|
||||||
|
if i + 1 < s_len
|
||||||
|
b2 = String.nth(s, i+1)
|
||||||
|
let b3: U8 = 0
|
||||||
|
if i + 2 < s_len
|
||||||
|
b3 = String.nth(s, i+2)
|
||||||
|
i = i + 3
|
||||||
|
|
||||||
|
let triple: I64 = Bit.or(Bit.or(Bit.lshift(b1, 16), Bit.lshift(b2, 8)), b3)
|
||||||
|
String.set(output, j, String.nth(chars, Bit.and(Bit.rshift(triple, 18), 63)))
|
||||||
|
String.set(output, j+1, String.nth(chars, Bit.and(Bit.rshift(triple, 12), 63)))
|
||||||
|
String.set(output, j+2, String.nth(chars, Bit.and(Bit.rshift(triple, 6), 63)))
|
||||||
|
String.set(output, j+3, String.nth(chars, Bit.and(triple, 63)))
|
||||||
|
j = j + 4
|
||||||
|
|
||||||
|
let padding: I64 = s_len % 3
|
||||||
|
let equals: U8 = String.nth("=", 0)
|
||||||
|
if padding == 1
|
||||||
|
String.set(output, j-2, equals)
|
||||||
|
String.set(output, j-1, equals)
|
||||||
|
else if padding == 2
|
||||||
|
String.set(output, j-1, equals)
|
||||||
|
|
||||||
|
String.set(output, j, 0)
|
||||||
|
return output
|
||||||
Reference in New Issue
Block a user