Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
change in structure (to be continued)
- Loading branch information
1 parent
89e98e2
commit 475e43a
Showing
7 changed files
with
297 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1 @@ | ||
ooc_tmp | ||
yajit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
use yajit | ||
import structs/ArrayList | ||
import yajit/Partial | ||
|
||
|
||
test: func { | ||
"-- Yay =) This is the test function --" println() | ||
} | ||
|
||
test2: func (ptr: Pointer, arg: Int, secArg: Int, thirdArg: Short) -> String { | ||
printf("Address of param %p, number = %d, name = '%s'\n", ptr, ptr as TestStruct number, ptr as TestStruct name) | ||
printf("First non-closure arg: %d\n", arg) | ||
printf("Second arg: %d\n", secArg) | ||
printf("%d\n", thirdArg) | ||
return "Oh my god, even return values work!" | ||
} | ||
|
||
test3: func(i, j, k: Int) -> Int { | ||
printf("i:%d\n", i) | ||
printf("j:%d\n", j) | ||
printf("k:%d\n", k) | ||
i+j | ||
} | ||
|
||
test4: func(i, j: Int) -> Int { | ||
printf("i:%d\n", i) | ||
printf("j:%d\n", j) | ||
i+j | ||
} | ||
|
||
test5: func(i, j: Int, tStruct: TestStruct, k: Float) -> Int { | ||
printf("i:%d\n", i) | ||
printf("j:%d\n", j) | ||
printf("k:%f\n", k) | ||
printf("Address of param %p, number = %d, name = '%s'\n", tStruct, tStruct as TestStruct number, tStruct as TestStruct name) | ||
i+j+k | ||
} | ||
|
||
main: func { | ||
a := TestStruct new(42, "mwahhaha") | ||
"Generating code.." println() | ||
clArg1 := Cell<Int> new(21) | ||
clArg2 := Cell<Int> new(44) | ||
clArg3 := Cell<Pointer> new(a) | ||
closureArgs := ArrayList<Cell<Pointer>> new() | ||
closureArgs add(clArg1).add(clArg2).add(clArg3) | ||
partial := Partial new(test2) | ||
partial setNonPartialArgs("iii") | ||
function1 := partial genCode(a) as Func -> String | ||
function1(2, 3, 4) println() | ||
partial = Partial new(test3) | ||
partial setNonPartialArgs("ii") | ||
function2 := partial genCode(4) as Func -> Int | ||
printf("%d\n", function2(2, 2)) | ||
partial = Partial new(test4) | ||
function3 := partial genCode(closureArgs) as Func -> Int | ||
function3() | ||
partial = Partial new(test5) | ||
partial setNonPartialArgs("i") | ||
function4 := partial genCode(closureArgs) as Func -> Int | ||
function4 (partial converseFloat(23.3)) | ||
"Finished!" println() | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
Name: yajit | ||
Description: small ooc-lib for closure support | ||
SourcePath: . |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import os/mmap | ||
import structs/HashMap | ||
include errno | ||
|
||
errno: extern Int | ||
strerror: extern func (Int) -> String | ||
|
||
BinarySeq: class { | ||
|
||
data : UChar* | ||
size : SizeT | ||
index := 0 | ||
transTable := HashMap<Int> new() | ||
|
||
init: func ~withData (=size, .data) { | ||
this(size) | ||
index = size | ||
memcpy(this data, data, size * sizeof(UChar)) | ||
} | ||
|
||
init: func ~withSize (=size) { | ||
memsize := size * sizeof(UChar) | ||
// at least 4096, and a multiple of 4096 that is bigger than memsize | ||
realsize := memsize + 4096 - (memsize % 4096) | ||
data = gc_malloc(realsize) | ||
result := mprotect(data, realsize, PROT_READ | PROT_WRITE | PROT_EXEC) | ||
if(result != 0) { | ||
printf("mprotect(%p, %d) failed with code %d. Message = %s\n", data, realsize, result, strerror(errno)) | ||
} | ||
initTransTable() | ||
// mmap is leaking (cause we don't know when to free), and apparently not needed, but just in case, here's the correct call | ||
//data = mmap(null, memsize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_LOCKED | MAP_ANONYMOUS, -1, 0) | ||
} | ||
|
||
initTransTable: func { | ||
transTable["c"] = Char size | ||
transTable["d"] = Double size | ||
transTable["f"] = Float size | ||
transTable["h"] = Short size | ||
transTable["i"] = Int size | ||
transTable["l"] = Long size | ||
transTable["P"] = Pointer size | ||
} | ||
|
||
append: func ~other (other: This) -> This { | ||
append(other data, other size) | ||
} | ||
|
||
append: func ~withLength (ptr: Pointer, ptrLength: SizeT) -> This { | ||
memcpy(data + index, ptr, ptrLength) | ||
index += ptrLength | ||
return this | ||
} | ||
|
||
reset: func { index = 0 } | ||
|
||
print: func { | ||
for(i : Int in 0..index) | ||
printf("%.2x ", data[i]) | ||
println() | ||
} | ||
|
||
} | ||
|
||
operator += (b1, b2 : BinarySeq) -> BinarySeq { | ||
b1 append(b2) | ||
} | ||
|
||
operator += <T> (b1 : BinarySeq, addon: T) -> BinarySeq { | ||
b1 append(addon&, T size) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
import BinarySeq | ||
import x86-32/OpCodes | ||
import os/mmap | ||
import structs/[ArrayList,HashMap] | ||
include errno | ||
|
||
|
||
Cell: class <T>{ | ||
val :T | ||
init: func(=val) {} | ||
} | ||
|
||
TestStruct : class { | ||
number: Int | ||
name: String | ||
init: func (=number, =name) {} | ||
} | ||
|
||
reverse: func <T> (list: ArrayList<T>) { | ||
"i'm reversed" println() | ||
i := 0 | ||
j := list size() -1 | ||
tmp: T | ||
while (i <= j / 2) { | ||
tmp = list[i] | ||
list[i] = list[j] | ||
list[j] = tmp | ||
i += 1 | ||
j -= 1 | ||
} | ||
} | ||
|
||
Partial: class { | ||
|
||
funcPtr: Func | ||
argSizes := "" | ||
op: BinarySeq | ||
init: func(=funcPtr) {initSequence(1024)} | ||
|
||
getBase: func(argSizes: String, op: BinarySeq) -> Int{ | ||
base := 0x04 | ||
for (c: Char in argSizes) { | ||
base = base + op transTable get(String new(c)) | ||
} | ||
return base | ||
} | ||
|
||
pushNonClosureArgs: func(base: Int) { | ||
for (c: Char in argSizes) { | ||
s := String new(c) | ||
OpCodes pushCallerArg(op, op transTable[s]) | ||
op append(base& as UChar*, UChar size) | ||
base = base - op transTable get(s) //op transTable get(s) | ||
} | ||
printf("EndBase: %d\n", base) | ||
"pushNonClosureArgs: " println() | ||
op print() | ||
"" println() | ||
} | ||
converseFloat: static func(f: Float) -> Int {(f& as Int32*)@} | ||
|
||
initSequence: func(s: Int) -> BinarySeq { | ||
op = BinarySeq new(s) | ||
op append(OpCodes PUSH_EBP) | ||
op append(OpCodes MOV_EBP_ESP) | ||
"Init sequence: " print() | ||
op print() | ||
"" println() | ||
return op | ||
} | ||
|
||
finishSequence: func { | ||
op append(OpCodes MOV_EBX_ADDRESS) | ||
op append(funcPtr& as Pointer*, Pointer size) | ||
op append(OpCodes CALL_EBX) | ||
op append(OpCodes LEAVE) | ||
op append(OpCodes RET) | ||
} | ||
|
||
genCode: func <T>(closure: T) -> Pointer { | ||
pushNonClosureArgs(getBase(argSizes, op)) | ||
OpCodes pushClosure(op, closure) | ||
finishSequence() | ||
op print() | ||
return op data as Func | ||
} | ||
|
||
setNonPartialArgs: func(=argSizes) {} | ||
|
||
genCode: func ~argList(closure: ArrayList<Cell<Pointer>>) -> Pointer { | ||
// IMPORTANT!! bug concerning choice of right polymorphic func | ||
// even if a non-closure arg is smaller than 4 byte | ||
// treating it as it'd have 4 bytes works | ||
// should be fixed later on, but it's currently | ||
// more important to have somehing working :) | ||
printf("\n%daaa\n\n", closure size()) | ||
op := initSequence(1024) | ||
closureArgs := closure clone() // cloning fixes problem with reverse (don't ask why^^) | ||
reverse(closureArgs) | ||
pushNonClosureArgs(getBase(argSizes, op)) | ||
for (item: Cell<Pointer> in closureArgs) { | ||
T := item T | ||
OpCodes pushClosure (op, item val as T) | ||
} | ||
finishSequence() | ||
printf("Code = ") | ||
op print() | ||
return op data as Func | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import ../BinarySeq | ||
|
||
OpCodes: class { | ||
|
||
init : func {} | ||
|
||
PUSH_EBP := static const BinarySeq new(1, [0x55 as UChar]) | ||
PUSH_BYTE := static const BinarySeq new(1, [0x6a as UChar]) | ||
PUSH_WORD := static const BinarySeq new(2, [0x66 as UChar, 0x68]) | ||
PUSH_DWORD := static const BinarySeq new(1, [0x68 as UChar]) | ||
PUSHW_EBP_VAL := static const BinarySeq new(3, [0x66 as UChar, 0xff, 0x75]) | ||
PUSHDW_EBP_VAL := static const BinarySeq new(2, [0xff as UChar, 0x75]) | ||
MOV_EBP_ESP := static const BinarySeq new(2, [0x89 as UChar, 0xe5]) | ||
MOV_EBX_ADDRESS := static const BinarySeq new(1, [0xbb as UChar]) | ||
MOV_EBX_EBP_PLUS_8 := static const BinarySeq new(3, [0x8b as UChar, 0x5d, 0x08]) | ||
PUSH_EBX := static const BinarySeq new(1, [0x53 as UChar]) | ||
PUSH_ADDRESS := static const BinarySeq new(1, [0x68 as UChar]) | ||
CALL_ADDRESS := static const BinarySeq new(1, [0xe8 as UChar]) | ||
CALL_EBX := static const BinarySeq new(2, [0xff as UChar, 0xd3]) | ||
LEAVE := static const BinarySeq new(1, [0xc9 as UChar]) | ||
RET := static const BinarySeq new(1, [0xc3 as UChar]) | ||
|
||
pushClosure: static func <T> (bseq: BinarySeq, arg: T) -> BinarySeq { | ||
match T size { | ||
case 1 => bseq append(PUSH_BYTE) | ||
case 2 => bseq append(PUSH_WORD) | ||
case 4 => bseq append(PUSH_DWORD) | ||
case => {fprintf(stderr, "Trying to push unknown size: %d\n", T size) | ||
x := 0 | ||
x = 10 / x // dirty way of throwing an exception | ||
} | ||
} | ||
bseq append(arg&, T size) | ||
} | ||
|
||
pushCallerArg: static func <T> (bseq: BinarySeq, arg: T) -> BinarySeq { | ||
match T size { | ||
case 1 || 2 => bseq += OpCodes PUSHW_EBP_VAL | ||
case 4 => bseq += OpCodes PUSHDW_EBP_VAL | ||
case =>{fprintf(stderr, "Trying to push unknown size: %d\n", T size) | ||
x := 0 | ||
x = 10 / x // dirty way of throwing an exception | ||
} | ||
} | ||
return bseq | ||
|
||
} |