Skip to content

Commit

Permalink
change in structure (to be continued)
Browse files Browse the repository at this point in the history
  • Loading branch information
showstopper committed Dec 26, 2009
1 parent 89e98e2 commit 475e43a
Show file tree
Hide file tree
Showing 7 changed files with 297 additions and 2 deletions.
1 change: 0 additions & 1 deletion .gitignore
@@ -1,2 +1 @@
ooc_tmp
yajit
2 changes: 1 addition & 1 deletion Makefile
@@ -1,7 +1,7 @@
.PHONY: all clean

all:
ooc yajit -gcc -D_BSD_SOURCE -driver=sequence -noclean -g -shout -v
ooc tests/test_partial -o=tests/test_partial -gcc -D_BSD_SOURCE -driver=sequence -g -shout -v

clean:
rm -rf ooc_tmp
Expand Down
64 changes: 64 additions & 0 deletions tests/test_partial.ooc
@@ -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()
}

3 changes: 3 additions & 0 deletions yajit.use
@@ -0,0 +1,3 @@
Name: yajit
Description: small ooc-lib for closure support
SourcePath: .
71 changes: 71 additions & 0 deletions yajit/BinarySeq.ooc
@@ -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)
}
111 changes: 111 additions & 0 deletions yajit/Partial.ooc
@@ -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
}
}

47 changes: 47 additions & 0 deletions yajit/x86-32/OpCodes.ooc
@@ -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

}

0 comments on commit 475e43a

Please sign in to comment.