Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

change in structure (to be continued)

  • Loading branch information...
commit 475e43a4524da122e341a36f5593e518e444dc49 1 parent 89e98e2
@showstopper showstopper authored
View
1  .gitignore
@@ -1,2 +1 @@
ooc_tmp
-yajit
View
2  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
View
64 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()
+}
+
View
3  yajit.use
@@ -0,0 +1,3 @@
+Name: yajit
+Description: small ooc-lib for closure support
+SourcePath: .
View
71 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)
+}
View
111 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
+ }
+}
+
View
47 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
+
+}
Please sign in to comment.
Something went wrong with that request. Please try again.