From 76552b688d855581d0ba7ed9ed9d246ebaf1d4d9 Mon Sep 17 00:00:00 2001 From: jaeger Date: Wed, 4 May 2011 18:02:59 +0000 Subject: [PATCH] Added a draft of assembler module template. git-svn-id: svn://kolibrios.org@1926 a494cfbc-eb01-0410-851d-a64ba20cac60 --- .../tinypy/tinypy/fasm_modules/macros.inc | 552 ++++++++++++++++++ .../tinypy/tinypy/fasm_modules/proc32.inc | 270 +++++++++ .../tinypy/tinypy/fasm_modules/struct.inc | 180 ++++++ .../tinypy/tinypy/fasm_modules/testmod.s | 135 +++++ .../tinypy/tinypy/fasm_modules/tinypy.inc | 175 ++++++ 5 files changed, 1312 insertions(+) create mode 100644 programs/develop/tinypy/tinypy/fasm_modules/macros.inc create mode 100644 programs/develop/tinypy/tinypy/fasm_modules/proc32.inc create mode 100644 programs/develop/tinypy/tinypy/fasm_modules/struct.inc create mode 100644 programs/develop/tinypy/tinypy/fasm_modules/testmod.s create mode 100644 programs/develop/tinypy/tinypy/fasm_modules/tinypy.inc diff --git a/programs/develop/tinypy/tinypy/fasm_modules/macros.inc b/programs/develop/tinypy/tinypy/fasm_modules/macros.inc new file mode 100644 index 0000000000..7568c3afaa --- /dev/null +++ b/programs/develop/tinypy/tinypy/fasm_modules/macros.inc @@ -0,0 +1,552 @@ +@^ fix macro comment { +^@ fix } + +; ------------------------- +macro library [lname,fname] +{ + forward + dd __#lname#_library_table__,__#lname#_library_name__ + common + dd 0 + forward + align 4 + __#lname#_library_name__ db fname,0 +} + +macro import lname,[name,sname] +{ + common + align 4 + __#lname#_library_table__: + forward + if used name + name dd __#name#_import_name__ + end if + common + dd 0 + forward + if used name + align 4 + __#name#_import_name__ db sname,0 + end if +} + +macro export [name,sname] +{ + forward + dd __#name#_export_name__,name + common + dd 0 + forward + align 4 + __#name#_export_name__ db sname,0 +} +; ------------------------- + +macro m2m dest,src { + push src + pop dest +} + + +macro iglobal { + IGlobals equ IGlobals, + macro __IGlobalBlock { } + +macro uglobal { + UGlobals equ UGlobals, + macro __UGlobalBlock { } + +endg fix } ; Use endg for ending iglobal and uglobal blocks. + + +macro IncludeIGlobals{ + macro IGlobals dummy,[n] \{ __IGlobalBlock + purge __IGlobalBlock \} + match I, IGlobals \{ I \} } + +macro IncludeUGlobals{ + macro UGlobals dummy,[n] \{ + \common + \local begin, size + begin = $ + virtual at $ + \forward + __UGlobalBlock + purge __UGlobalBlock + \common + size = $ - begin + end virtual + rb size + \} + match U, UGlobals \{ U \} } + +uglobal +endg + +iglobal +endg + + +; new application structure +macro meos_app_start + { + use32 + org 0x0 + + db 'MENUET01' + dd 0x01 + dd __start + dd __end + dd __memory + dd __stack + + if used __params & ~defined __params + dd __params + else + dd 0x0 + end if + + dd 0x0 + } +MEOS_APP_START fix meos_app_start + +macro code + { + __start: + } +CODE fix code + +macro data + { + __data: + IncludeIGlobals + } +DATA fix data + +macro udata + { + if used __params & ~defined __params + __params: + db 0 + __end: + rb 255 + else + __end: + end if + __udata: + IncludeUGlobals + } +UDATA fix udata + +macro meos_app_end + { + align 32 + rb 2048 + __stack: + __memory: + } +MEOS_APP_END fix meos_app_end + + +; macro for defining multiline text data +struc mstr [sstring] + { + forward + local ssize + virtual at 0 + db sstring + ssize = $ + end virtual + dd ssize + db sstring + common + dd -1 + } + +; macro for defining multiline text data +struc mls [sstring] + { + forward + local ssize + virtual at 0 + db sstring ; mod + ssize = $ + end virtual + db ssize + db sstring + common + db -1 ; mod + } + + + +; strings +macro sz name,[data] { ; from MFAR [mike.dld] + common + if used name + name db data + .size = $-name + end if +} + +macro szZ name,[data] { ; same as sz, but with 0 at the end of line (ASCIIZ string) [dunkaist] + common + if used name + name db data,0 + .size = $-name-1 + end if +} +sz0 fix szZ + +macro lsz name,[lng,data] { ; from MFAR [mike.dld] + common + if used name + label name + forward + if lang eq lng + db data + end if + common + .size = $-name + end if +} + +macro szc name,elsz,[data] { ; from MFAR [mike.dld] + common + local s,m + m = 0 + if used name + label name + forward + virtual at 0 + db data + s = $ + end virtual + d#elsz s + if m < s + m = s + end if + db data + common + .size = $-name + .maxl = m + end if +} + +macro lszc name,elsz,[lng,data] { ; from MFAR [mike.dld] + common + local s,m,c + m = 0 + c = 0 + if used name + label name + forward + if lang eq lng + virtual at 0 + db data + s = $ + end virtual + d#elsz s + if m < s + m = s + end if + db data + c = c+1 + end if + common + .size = $-name + .maxl = m + .count = c + end if +} + + +; easy system call macro +macro mpack dest, hsrc, lsrc +{ + if (hsrc eqtype 0) & (lsrc eqtype 0) + mov dest, (hsrc) shl 16 + lsrc + else + if (hsrc eqtype 0) & (~lsrc eqtype 0) + mov dest, (hsrc) shl 16 + add dest, lsrc + else + mov dest, hsrc + shl dest, 16 + add dest, lsrc + end if + end if +} + +macro __mov reg,a,b { ; mike.dld + if (~a eq)&(~b eq) + mpack reg,a,b + else if (~a eq)&(b eq) + mov reg,a + end if +} + + +include 'config.inc' +;__CPU_type equ p5 +SYSENTER_VAR equ 0 + +macro mcall a,b,c,d,e,f { ; mike.dld, updated by Ghost for Fast System Calls + local ..ret_point + __mov eax,a + __mov ebx,b + __mov ecx,c + __mov edx,d + __mov esi,e + __mov edi,f + + if __CPU_type eq p5 + int 0x40 + else + if __CPU_type eq p6 + push ebp + mov ebp, esp + push ..ret_point ; it may be 2 or 5 byte + sysenter + ..ret_point: + pop edx + pop ecx + + else + if __CPU_type eq k6 + push ecx + syscall + pop ecx + else + display 'ERROR : unknown CPU type (set to p5)', 10, 13 + __CPU_type equ p5 + int 0x40 + end if + end if + end if +} + + +; ------------------------- +macro header a,[b] { + common + use32 + org 0 + db 'MENUET',a + forward + if b eq + dd 0 + else + dd b + end if } +macro section name { align 16 + label name } +macro func name { + if ~used name + display 'FUNC NOT USED: ',`name,13,10 + else + align 4 + name: + ;diff16 `name,0,name +;pushad +;pushfd +;dps `name +;newline +;mcall 5,1 +;popfd +;popad +} +macro endf { end if } + +macro diff16 title,l1,l2 + { + local s,d + s = l2-l1 + display title,': 0x' + repeat 8 + d = '0' + s shr ((8-%) shl 2) and $0F + if d > '9' + d = d + 'A'-'9'-1 + end if + display d + end repeat + display 13,10 + } + +macro diff10 title,l1,l2 + { + local s,d,z,m + s = l2-l1 + z = 0 + m = 1000000000 + display title,': ' + repeat 10 + d = '0' + s / m + s = s - (s/m)*m + m = m / 10 + if d <> '0' + z = 1 + end if + if z <> 0 + display d + end if + end repeat + display 13,10 + } + +; optimize the code for size +__regs fix + +macro add arg1,arg2 + { + if (arg2 eqtype 0) + if (arg2) = 1 + inc arg1 + else + add arg1,arg2 + end if + else + add arg1,arg2 + end if + } + +macro sub arg1,arg2 + { + if (arg2 eqtype 0) + if (arg2) = 1 + dec arg1 + else + sub arg1,arg2 + end if + else + sub arg1,arg2 + end if + } + +macro mov arg1,arg2 + { + if (arg1 in __regs) & ((arg2 eqtype 0) | (arg2 eqtype '0')) + if (arg2) = 0 + xor arg1,arg1 + else if (arg2) = 1 + xor arg1,arg1 + inc arg1 + else if (arg2) = -1 + or arg1,-1 + else if (arg2) > -128 & (arg2) < 128 + push arg2 + pop arg1 + else + mov arg1,arg2 + end if + else + mov arg1,arg2 + end if + } + + +macro RGB [a] { + common + match (r=,g=,b),a \{ + \dd ((r) shl 16) or ((g) shl 8) or (b) + \} +} + + +struc POINT _t,_dx,_dy { + .x _t _dx + .y _t _dy +} + +; structure definition helper +include 'struct.inc' + +struct RECT + left dd ? + top dd ? + right dd ? + bottom dd ? +ends + +struct BOX + left dd ? + top dd ? + width dd ? + height dd ? +ends + +; structures used in MeOS +struct process_information + cpu_usage dd ? ; +0 + window_stack_position dw ? ; +4 + window_stack_value dw ? ; +6 + dw ? ; +8 + process_name rb 12 ; +10 + memory_start dd ? ; +22 + used_memory dd ? ; +26 + PID dd ? ; +30 + box BOX ; +34 + slot_state dw ? ; +50 + dw ? ; +52 + client_box BOX ; +54 + wnd_state db ? ; +70 + rb (1024-71) +ends + +struct system_colors + frame dd ? + grab dd ? + grab_button dd ? + grab_button_text dd ? + grab_text dd ? + work dd ? + work_button dd ? + work_button_text dd ? + work_text dd ? + work_graph dd ? +ends + +struct FILEDATE + Second db ? + Minute db ? + Hour db ? + db ? + Day db ? + Month db ? + Year dw ? +ends + +struct FILEINFO + Attributes dd ? + IsUnicode db ? + db 3 dup(?) + DateCreate FILEDATE + DateAccess FILEDATE + DateModify FILEDATE + Size dq ? +ends + +; constants + +; events +EV_IDLE = 0 +EV_TIMER = 0 +EV_REDRAW = 1 +EV_KEY = 2 +EV_BUTTON = 3 +EV_EXIT = 4 +EV_BACKGROUND = 5 +EV_MOUSE = 6 +EV_IPC = 7 +EV_STACK = 8 + +; event mask bits for function 40 +EVM_REDRAW = 1b +EVM_KEY = 10b +EVM_BUTTON = 100b +EVM_EXIT = 1000b +EVM_BACKGROUND = 10000b +EVM_MOUSE = 100000b +EVM_IPC = 1000000b +EVM_STACK = 10000000b diff --git a/programs/develop/tinypy/tinypy/fasm_modules/proc32.inc b/programs/develop/tinypy/tinypy/fasm_modules/proc32.inc new file mode 100644 index 0000000000..aa3ffc9702 --- /dev/null +++ b/programs/develop/tinypy/tinypy/fasm_modules/proc32.inc @@ -0,0 +1,270 @@ + +; Macroinstructions for defining and calling procedures + +macro stdcall proc,[arg] ; directly call STDCALL procedure + { common + if ~ arg eq + reverse + pushd arg + common + end if + call proc } + +macro invoke proc,[arg] ; indirectly call STDCALL procedure + { common + if ~ arg eq + reverse + pushd arg + common + end if + call [proc] } + +macro ccall proc,[arg] ; directly call CDECL procedure + { common + size@ccall = 0 + if ~ arg eq + reverse + pushd arg + size@ccall = size@ccall+4 + common + end if + call proc + if size@ccall + add esp,size@ccall + end if } + +macro cinvoke proc,[arg] ; indirectly call CDECL procedure + { common + size@ccall = 0 + if ~ arg eq + reverse + pushd arg + size@ccall = size@ccall+4 + common + end if + call [proc] + if size@ccall + add esp,size@ccall + end if } + +macro proc [args] ; define procedure + { common + match name params, args> + \{ define@proc name, \{ prologue name,flag,parmbytes,localbytes,reglist \} + macro locals + \{ virtual at ebp-localbytes+current + macro label def \\{ match . type,def> \\\{ deflocal@proc .,label, + \\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \} + macro finish@proc \{ localbytes = (((current-1) shr 2)+1) shl 2 + end if \} } + +macro defargs@proc [arg] + { common + if ~ arg eq + forward + local ..arg,current@arg + match argname:type, arg + \{ current@arg equ argname + label ..arg type + argname equ ..arg + if dqword eq type + dd ?,?,?,? + else if tbyte eq type + dd ?,?,? + else if qword eq type | pword eq type + dd ?,? + else + dd ? + end if \} + match =current@arg,current@arg + \{ current@arg equ arg + arg equ ..arg + ..arg dd ? \} + common + args@proc equ current@arg + forward + restore current@arg + common + end if } + +macro deflocal@proc name,def,[val] + { common + match vars, all@vars \{ all@vars equ all@vars, \} + all@vars equ all@vars name + forward + local ..var,..tmp + match =label,def \{ ..tmp equ \} + match tmp,..tmp \{ ..var def val \} + match ,..tmp \{ label ..var val \} + match =?, val \{ ..tmp equ \} + match any =dup (=?), val \{ ..tmp equ \} + match tmp : value, ..tmp : val + \{ tmp: end virtual + initlocal@proc ..var,def value + virtual at tmp\} + common + match first rest, ..var, \{ name equ first \} } + +macro initlocal@proc name,def + { virtual at name + def + size@initlocal = $ - name + end virtual + position@initlocal = 0 + while size@initlocal > position@initlocal + virtual at name + def + if size@initlocal - position@initlocal < 2 + current@initlocal = 1 + load byte@initlocal byte from name+position@initlocal + else if size@initlocal - position@initlocal < 4 + current@initlocal = 2 + load word@initlocal word from name+position@initlocal + else + current@initlocal = 4 + load dword@initlocal dword from name+position@initlocal + end if + end virtual + if current@initlocal = 1 + mov byte [name+position@initlocal],byte@initlocal + else if current@initlocal = 2 + mov word [name+position@initlocal],word@initlocal + else + mov dword [name+position@initlocal],dword@initlocal + end if + position@initlocal = position@initlocal + current@initlocal + end while } + +macro endp + { purge ret,locals,endl + finish@proc + purge finish@proc + restore regs@proc + match all,args@proc \{ restore all \} + restore args@proc + match all,all@vars \{ restore all \} } + +macro local [var] + { common + locals + forward done@local equ + match varname[count]:vartype, var + \{ match =BYTE, vartype \\{ varname rb count + restore done@local \\} + match =WORD, vartype \\{ varname rw count + restore done@local \\} + match =DWORD, vartype \\{ varname rd count + restore done@local \\} + match =PWORD, vartype \\{ varname rp count + restore done@local \\} + match =QWORD, vartype \\{ varname rq count + restore done@local \\} + match =TBYTE, vartype \\{ varname rt count + restore done@local \\} + match =DQWORD, vartype \\{ label varname dqword + rq count+count + restore done@local \\} + match , done@local \\{ virtual + varname vartype + end virtual + rb count*sizeof.\#vartype + restore done@local \\} \} + match :varname:vartype, done@local:var + \{ match =BYTE, vartype \\{ varname db ? + restore done@local \\} + match =WORD, vartype \\{ varname dw ? + restore done@local \\} + match =DWORD, vartype \\{ varname dd ? + restore done@local \\} + match =PWORD, vartype \\{ varname dp ? + restore done@local \\} + match =QWORD, vartype \\{ varname dq ? + restore done@local \\} + match =TBYTE, vartype \\{ varname dt ? + restore done@local \\} + match =DQWORD, vartype \\{ label varname dqword + dq ?,? + restore done@local \\} + match , done@local \\{ varname vartype + restore done@local \\} \} + match ,done@local + \{ var + restore done@local \} + common + endl } diff --git a/programs/develop/tinypy/tinypy/fasm_modules/struct.inc b/programs/develop/tinypy/tinypy/fasm_modules/struct.inc new file mode 100644 index 0000000000..947a84e89a --- /dev/null +++ b/programs/develop/tinypy/tinypy/fasm_modules/struct.inc @@ -0,0 +1,180 @@ + +; Macroinstructions for defining data structures + +macro struct name + { fields@struct equ name + match child parent, name \{ fields@struct equ child,fields@\#parent \} + sub@struct equ + struc db [val] \{ \common fields@struct equ fields@struct,.,db, \} + struc dw [val] \{ \common fields@struct equ fields@struct,.,dw, \} + struc du [val] \{ \common fields@struct equ fields@struct,.,du, \} + struc dd [val] \{ \common fields@struct equ fields@struct,.,dd, \} + struc dp [val] \{ \common fields@struct equ fields@struct,.,dp, \} + struc dq [val] \{ \common fields@struct equ fields@struct,.,dq, \} + struc dt [val] \{ \common fields@struct equ fields@struct,.,dt, \} + struc rb count \{ fields@struct equ fields@struct,.,db,count dup (?) \} + struc rw count \{ fields@struct equ fields@struct,.,dw,count dup (?) \} + struc rd count \{ fields@struct equ fields@struct,.,dd,count dup (?) \} + struc rp count \{ fields@struct equ fields@struct,.,dp,count dup (?) \} + struc rq count \{ fields@struct equ fields@struct,.,dq,count dup (?) \} + struc rt count \{ fields@struct equ fields@struct,.,dt,count dup (?) \} + macro db [val] \{ \common \local anonymous + fields@struct equ fields@struct,anonymous,db, \} + macro dw [val] \{ \common \local anonymous + fields@struct equ fields@struct,anonymous,dw, \} + macro du [val] \{ \common \local anonymous + fields@struct equ fields@struct,anonymous,du, \} + macro dd [val] \{ \common \local anonymous + fields@struct equ fields@struct,anonymous,dd, \} + macro dp [val] \{ \common \local anonymous + fields@struct equ fields@struct,anonymous,dp, \} + macro dq [val] \{ \common \local anonymous + fields@struct equ fields@struct,anonymous,dq, \} + macro dt [val] \{ \common \local anonymous + fields@struct equ fields@struct,anonymous,dt, \} + macro rb count \{ \local anonymous + fields@struct equ fields@struct,anonymous,db,count dup (?) \} + macro rw count \{ \local anonymous + fields@struct equ fields@struct,anonymous,dw,count dup (?) \} + macro rd count \{ \local anonymous + fields@struct equ fields@struct,anonymous,dd,count dup (?) \} + macro rp count \{ \local anonymous + fields@struct equ fields@struct,anonymous,dp,count dup (?) \} + macro rq count \{ \local anonymous + fields@struct equ fields@struct,anonymous,dq,count dup (?) \} + macro rt count \{ \local anonymous + fields@struct equ fields@struct,anonymous,dt,count dup (?) \} + macro union \{ fields@struct equ fields@struct,,union,< + sub@struct equ union \} + macro struct \{ fields@struct equ fields@struct,,substruct,< + sub@struct equ substruct \} + virtual at 0 } + +macro ends + { match , sub@struct \{ restruc db,dw,du,dd,dp,dq,dt + restruc rb,rw,rd,rp,rq,rt + purge db,dw,du,dd,dp,dq,dt + purge rb,rw,rd,rp,rq,rt + purge union,struct + match name=,fields,fields@struct \\{ fields@struct equ + make@struct name,fields + fields@\\#name equ fields \\} + end virtual \} + match any, sub@struct \{ fields@struct equ fields@struct> \} + restore sub@struct } + +macro make@struct name,[field,type,def] + { common + if $ + display 'Error: definition of ',`name,' contains illegal instructions.',0Dh,0Ah + err + end if + local define + define equ name + forward + local sub + match , field \{ make@substruct type,name,sub def + define equ define,.,sub, \} + match any, field \{ define equ define,.#field,type, \} + common + match fields, define \{ define@struct fields \} } + +macro define@struct name,[field,type,def] + { common + local list + list equ + forward + if ~ field eq . + name#field type def + sizeof.#name#field = $ - name#field + else + rb sizeof.#type + end if + local value + match any, list \{ list equ list, \} + list equ list + common + sizeof.#name = $ + restruc name + match values, list \{ + struc name value \\{ + match any, fields@struct \\\{ fields@struct equ fields@struct,.,name, \\\} + match , fields@struct \\\{ label . + forward + match , value \\\\{ field type def \\\\} + match any, value \\\\{ field type value + if ~ field eq . + rb sizeof.#name#field - ($-field) + end if \\\\} + common \\\} \\} \} } + +macro enable@substruct + { macro make@substruct substruct,parent,name,[field,type,def] + \{ \common + \local define + define equ parent,name + \forward + \local sub + match , field \\{ match any, type \\\{ enable@substruct + make@substruct type,name,sub def + purge make@substruct + define equ define,.,sub, \\\} \\} + match any, field \\{ define equ define,.\#field,type, \\} + \common + match fields, define \\{ define@\#substruct fields \\} \} } + +enable@substruct + +macro define@union parent,name,[field,type,def] + { common + virtual at 0 + forward + if ~ field eq . + virtual at 0 + parent#field type def + sizeof.#parent#field = $ - parent#field + end virtual + if sizeof.#parent#field > $ + rb sizeof.#parent#field - $ + end if + else if sizeof.#type > $ + rb sizeof.#type - $ + end if + common + sizeof.#name = $ + end virtual + struc name [value] \{ \common + label .\#name + last@union equ + forward + match any, last@union \\{ virtual at .\#name + field type def + end virtual \\} + match , last@union \\{ match , value \\\{ field type def \\\} + match any, value \\\{ field type value \\\} \\} + last@union equ field + common rb sizeof.#name - ($ - .\#name) \} } + +macro define@substruct parent,name,[field,type,def] + { common + virtual at 0 + forward + if ~ field eq . + parent#field type def + sizeof.#parent#field = $ - parent#field + else + rb sizeof.#type + end if + local value + common + sizeof.#name = $ + end virtual + struc name value \{ + label .\#name + forward + match , value \\{ field type def \\} + match any, value \\{ field type value + if ~ field eq . + rb sizeof.#parent#field - ($-field) + end if \\} + common \} } diff --git a/programs/develop/tinypy/tinypy/fasm_modules/testmod.s b/programs/develop/tinypy/tinypy/fasm_modules/testmod.s new file mode 100644 index 0000000000..c77b3ea08d --- /dev/null +++ b/programs/develop/tinypy/tinypy/fasm_modules/testmod.s @@ -0,0 +1,135 @@ +format ELF +use32 +include 'proc32.inc' +include 'struct.inc' +include 'tinypy.inc' + +extrn tp_dict +extrn tp_set +extrn tp_get +extrn tp_None +extrn tp_fnc + +public testmod_init +public getsize + +;Module name +modname db "testmod" +modnamelen = $-modname +debug_print_name db "debug_print" +debug_print_namelen = $-debug_print_name + +testmod_dict rb sizeof.tp_obj +debug_print_obj rb sizeof.tp_obj +tmp_tp_obj rb sizeof.tp_obj + +getsize: + mov eax, tp_vm.params + ret + +;void debug_print(tp_vm *tp) +debug_print: + push ebp + mov ebp, esp + ; Store registers + push eax + push ebx + push ecx + push edx + ;Reserve space for tp_obj variable in stack + sub esp, sizeof.tp_obj + ; Obtain tp_string parameter + push_tp_obj tp_None + mov eax, dword[ebp+8] + add eax, tp_vm.params + push_tp_obj_at_reg eax + push dword[ebp+8] + push tmp_tp_obj;esp+(sizeof.tp_obj*2+4) + call tp_get + ;Restore stack + add esp, 56;sizeof.tp_obj*3+4;8? + ;Leave if parameter is not a string. tp_raise() should be called here. + ;cmp dword[esp], TP_STRING + ;jne .exit + ;mov ecx, dword[esp+12] + ;mov edx, dword[esp+8] +;.cont: + ; Print message. +; mov eax, 63 +; mov ebx, 1 +; push ecx +; mov cl, byte[edx] +; inc edx +; int 40h +; pop ecx +; loop .cont +;.exit: + pop edx + pop ecx + pop ebx + pop eax + mov esp, ebp + pop ebp + ret + +;void testmod_init(tp_vm *tp); +testmod_init: + push ebp + mov ebp, esp + ;Save registers + push eax + push ebx + push ecx + ; Create module dictionary and store its address in testmod_str + mov eax, dword [ebp + 8] + push eax + push testmod_dict + call tp_dict + add esp, 4 ;Clear stack + ; Push tp_obj structure pointed by testmod_dict + push_tp_obj testmod_dict + ; Push modname as a tp_obj object + push modnamelen; len + push modname ; val + push 0 ;_tp_string info + push TP_STRING ; type + ; Push tp_obj structure pointed by tp->modules + mov eax, dword [ebp + 8] + add eax, tp_vm.modules + 16 + mov ecx, 4 +.push_tpobj1: + sub eax, 4 + push dword[eax] +loop .push_tpobj1 + push eax + call tp_set + add esp, sizeof.tp_obj*3+4 + ; Register "debug_print" function + ;Reserve memory for function tp_obj object + sub esp, sizeof.tp_obj + mov eax, esp + push debug_print + push dword[ebp+8] + push eax + call tp_fnc + add esp, 8; tp_obj is already in stack, adding other arguments + ;Pushing function name tp_obj + ;mov eax, esp + ;push_tp_obj_at_reg eax + push debug_print_namelen + push debug_print_name + push 0 + push TP_STRING + ;Pushing module dictionary tp_obj + push_tp_obj testmod_dict + ;Pushing tp_vm + push dword[ebp+8] + call tp_set + add esp, sizeof.tp_obj*3+4 + ; Leaving function + pop ecx + pop ebx + pop eax + mov esp, ebp + pop ebp + ret diff --git a/programs/develop/tinypy/tinypy/fasm_modules/tinypy.inc b/programs/develop/tinypy/tinypy/fasm_modules/tinypy.inc new file mode 100644 index 0000000000..e5f220c5ba --- /dev/null +++ b/programs/develop/tinypy/tinypy/fasm_modules/tinypy.inc @@ -0,0 +1,175 @@ +; Python object types +TP_NONE equ 0 +TP_NUMBER equ 1 +TP_STRING equ 2 +TP_DICT equ 3 +TP_LIST equ 4 +TP_FNC equ 5 +TP_DATA equ 6 + +; Python "number" object. Can be treated as integer or float. +struct tp_number_ + type rd 1 + val rd 1 +ends + +; GC information for "string" object +struct _tp_string + gci rd 1 + s rb 1 +ends + +; Python "string" object +struct tp_string_ + type rd 1 + info rd 1 ;pointer to _tp_string + val rd 1 + len rd 1 +ends + +; GC information for "list" object +struct _tp_list + gci rd 1 + items rd 1 + len rd 1 + alloc rd 1 +ends + +; Python "list" object +struct tp_list_ + type rd 1 + val rd 1 ;pointer to _tp_list +ends + + +; GC information for "dict" object +struct _tp_dict + gci rd 1 + items rd 1 + len rd 1 + alloc rd 1 + cur rd 1 + mask rd 1 + used rd 1 +ends + +; Python "dict" object +struct tp_dict_ + type rd 1 + val rd 1 ;pointer to _tp_dict +ends + +; GC information for "function" object +; todo + +; Python "function" object +struct tp_fnc_ + type rd 1 + info rd 1 + ftype rd 1 + val rd 1 +ends + +; Python "data" object +struct tp_data_ + type rd 1 + info rd 1 + val rd 1 + magic rd 1 +ends + +struct tp_gc_info + type rd 1 + data rd 1 +ends + +; Generic Python object +struct tp_obj +union + type rd 1 + string tp_string_ + number tp_number_ + gc_info tp_gc_info + dict tp_dict_ + list tp_list_ + fnc tp_fnc_ + dat tp_data_ +ends +ends + +; Bytecode element +struct sregs + .i rb 1 + .a rb 1 + .b rb 1 + .c rb 1 +ends + +struct tp_code +union + i rb 1 + regs sregs + string rb 4 + number rp 1 +ends +ends + +; TinyPy VM frame +struct tp_frame_ + .codes rd 1 + .cur rd 1 + .jump rd 1 + .regs rd 1 + .ret_dest rd 1 + .fname rb sizeof.tp_obj + .name rb sizeof.tp_obj + .line rb sizeof.tp_obj + .globals rb sizeof.tp_obj + .lineno rd 1 + .cregs rd 1 +ends + +; TinyPy VM +TP_FRAMES equ 256 +struct tp_vm + builtins rb sizeof.tp_obj + modules rb sizeof.tp_obj + frames rb TP_FRAMES*sizeof.tp_frame_ + _params rb sizeof.tp_obj + params rb sizeof.tp_obj + _regs rb sizeof.tp_obj + regs rq 1 + root rb sizeof.tp_obj + jmp_buf rd 1 + jump rd 1 + ex rb sizeof.tp_obj + chars rb 512 + cur rd 1 + white rb sizeof._tp_list + grey rb sizeof._tp_list + black rb sizeof._tp_list + strings rb sizeof._tp_dict + steps rd 1 +ends + +macro push_tp_obj obj +{ + local .push_more + mov ebx, obj + 12 + mov ecx, 4 +.push_more: + push dword[ebx] + sub ebx, 4 + loop .push_more +} + +macro push_tp_obj_at_reg reg +{ + local .push_more + add reg, 12 + mov ecx, 4 +.push_more: + push dword[reg] + sub reg, 4 + loop .push_more +}