DIRECTORY JaMBasic, JaMVM, Basics, PrincOps, PrincOpsUtils, UnsafeStorage; JaMVMImpl: MONITOR IMPORTS PrincOpsUtils, JaMVM, Basics, UnsafeStorage EXPORTS JaMVM = { OPEN JaMBasic; Offs: TYPE = [0..1]; Ptr: TYPE = LONG POINTER; segment: Ptr _ NIL; -- to base of current chunk of storage size: LONG CARDINAL _ 0; -- size of current segment words: LONG CARDINAL _ 0; -- number of words allocated from this chunk offset: CARDINAL _ 0; totalWords: LONG CARDINAL _ 0; -- total # of words allocated by UnsafeStorage totalSegments: LONG CARDINAL _ 0; -- total # of objects allocated by UnsafeStorage WordsForPages: PROC[p: CARDINAL] RETURNS[LONG CARDINAL] = INLINE { RETURN[Basics.LongMult[p,PrincOps.wordsPerPage]] }; PagesForWords: PROC[w: LONG CARDINAL] RETURNS[CARDINAL] = INLINE { RETURN[Basics.LongDiv[w + PrincOps.wordsPerPage - 1, PrincOps.wordsPerPage]] }; Expand: PROC [atleast: LONG CARDINAL] = { want: CARDINAL _ PagesForWords[atleast]; pages: CARDINAL _ 4*((MAX[want,64]+1)/4); -- round up to multiple of 4 size _ WordsForPages[pages]; segment _ UnsafeStorage.NewUObject[size, UnsafeStorage.GetSystemUZone[]]; totalWords _ totalWords + size; totalSegments _ totalSegments + 1; words _ 0; offset _ 0; }; AllocWords: ENTRY PROC[n: LONG CARDINAL] RETURNS[Ptr] = { DO ptr: Ptr; IF offset > 0 THEN { words _ words + 1; offset _ 0 }; ptr _ segment + words; words _ words + n; IF words >= size THEN { Expand[n]; LOOP }; RETURN[ptr]; ENDLOOP; }; AllocChars: ENTRY PROC[n: CARDINAL] RETURNS[Ptr,Offs] = { DO ptr: Ptr _ segment + words; offs: Offs _ offset; frac: CARDINAL _ offs + n MOD 2; words _ words + n/2 + frac/2; -- mind overflow! offset _ frac MOD 2; IF words >= size THEN { Expand[n/2 + frac/2]; LOOP }; RETURN[ptr,offs]; ENDLOOP; }; AllocString: PUBLIC PROC[length: StringLength] RETURNS[string Object] = { string: string Object _ [L,string[length: length, text: , offset: ]]; [string.text,string.offset] _ AllocChars[length]; RETURN[string]; }; AllocArray: PUBLIC PROC[length: CARDINAL] RETURNS[array Object] = { array: array Object _ [L,array[length: length, base: ]]; array.base _ AllocWords[Basics.LongMult[length,SIZE[Object]]]; RETURN[array]; }; AllocTuples: PROC[size: CARDINAL] RETURNS[beg,end: TuplePtr] = { words: LONG CARDINAL _ Basics.LongMult[size,SIZE[Tuple]]; beg _ AllocWords[words]; end _ beg + words; RETURN[beg,end]; }; AllocDict: PUBLIC PROC[size: CARDINAL] RETURNS[dict Object] = { dict: dict Object _ [L,dict[AllocWords[SIZE[DictBody]]]]; dd: DictBody _ [curlen: 0, maxlen: 0, size: size, beg: , end: , curatt: 0, attach: [L,array[0,NIL]]]; [dd.beg,dd.end] _ AllocTuples[size]; JaMVM.PutDict[dict,dd]; RETURN[dict]; }; CopyArray: PUBLIC PROC[src,dst: array Object] = { count: CARDINAL _ MIN[src.length,dst.length]; -- number of objects to copy sptr: LONG POINTER _ src.base; dptr: LONG POINTER _ dst.base; words: LONG CARDINAL _ Basics.LongMult[count,SIZE[Object]]; chunk: CARDINAL = (LAST[CARDINAL]/SIZE[Object])*SIZE[Object]; WHILE words>0 DO w: CARDINAL _ Basics.LowHalf[MIN[words,chunk]]; PrincOpsUtils.LongCOPY[from: sptr, nwords: w, to: dptr]; sptr _ sptr + w; dptr _ dptr + w; words _ words - w; ENDLOOP; }; GetText: PUBLIC PROC[string: string Object, text: LONG STRING] = { count: CARDINAL _ MIN[string.length,text.maxlength]; stext: LONG POINTER TO TextBody _ string.text; soffs: CARDINAL _ string.offset; FOR i: CARDINAL IN[0..count) DO text[i] _ stext[soffs+i] ENDLOOP; text.length _ count; }; PutText: PUBLIC PROC[string: string Object, text: LONG STRING] = { count: CARDINAL _ MIN[string.length,text.length]; stext: LONG POINTER TO TextBody _ string.text; soffs: CARDINAL _ string.offset; FOR i: CARDINAL IN[0..count) DO stext[soffs+i] _ text[i] ENDLOOP; }; CopyString: PUBLIC PROC[src,dst: string Object] = { count: CARDINAL _ MIN[src.length,dst.length]; -- number of chars to copy stext: LONG POINTER TO TextBody _ src.text; dtext: LONG POINTER TO TextBody _ dst.text; soffs: CARDINAL _ src.offset; doffs: CARDINAL _ dst.offset; FOR i: CARDINAL IN[0..count) DO dtext[doffs+i] _ stext[soffs+i] ENDLOOP; }; rootInfo: LONG POINTER TO Root _ NIL; GetRoot: PUBLIC PROC[root: LONG POINTER TO Root] = { root^ _ rootInfo^ }; PutRoot: PUBLIC PROC[root: LONG POINTER TO Root] = { rootInfo^ _ root^ }; Start: PUBLIC PROC = { rootInfo _ AllocWords[SIZE[Root]]; }; }. ìJaMVMImpl.mesa Original version by Martin Newell, February 1979 Updated June 12, 1979 4:42 PM by MN Bill Paxton, November 5, 1982 9:45 am Russ Atkinson, July 22, 1983 7:43 pm Globals Procedures create a space to the hold monster Ê ˜šœ™Jšœ0™0Jšœ$™$Jšœ%™%J™$—J˜šÏk ˜ J˜ J˜J˜J˜ J˜Jšœ˜J˜—šœ ˜Jšœ,˜3Jšœ ˜Jšœ ˜—J˜šœ™J˜Jšœœ ˜Jšœœœœ˜J˜JšœœÏc&˜:Jšœœœž˜3Jšœœœž,˜FJšœœ˜Jšœ œœž.˜NJšœœœž0˜SJ˜—Jšœ ™ J˜šÏn œœœœœœœ˜BJšœ-˜3—šŸ œœœœœœœ˜BJšœI˜OJ˜—šŸœœ œœ˜)Jšœœ˜(Jšœœœž˜FJ˜Jšœ"™"JšœI˜IJšœ˜Jšœ"˜"J˜ J˜ J˜J˜—š Ÿ œœœœœœ ˜9š˜J˜ Jšœ œ#˜5J˜Jšœ˜Jšœœœ˜*Jšœ˜ Jšœ˜—J˜J˜—š Ÿ œœœœœ˜9š˜J˜J˜Jšœœ œ˜ Jšœž˜/Jšœœ˜Jšœœœ˜5Jšœ ˜Jšœ˜—J˜J˜—šŸ œœœœ˜IJšœœ+˜EJ˜1Jšœ ˜J˜J˜—š Ÿ œœœ œœ˜CJšœœ ˜8Jšœ/œ ˜>Jšœ˜J˜J˜—šŸ œœœœ˜@Jšœœœœ ˜9J˜+Jšœ ˜J˜J˜—š Ÿ œœœœœ˜?Jšœœœ˜9˜1Jšœ"œ œ˜3—J˜$J˜Jšœ˜ J˜J˜—šŸ œœœ˜1Jšœœœž˜JJšœœœ ˜Jšœœœ ˜Jšœœœœ ˜;Jš œœœœœ œ ˜=šœ ˜Jšœœœ˜/J˜8J˜4Jšœ˜—J˜J˜—š Ÿœœœœœ˜BJšœœœ˜4Jšœœœœ˜.Jšœœ˜ Jš œœœ œœ˜AJ˜J˜J˜—š Ÿœœœœœ˜BJšœœœ˜1Jšœœœœ˜.Jšœœ˜ Jš œœœ œœ˜AJ˜J˜—šŸ œœœ˜3Jšœœœž˜HJšœœœœ˜+Jšœœœœ˜+Jšœœ˜Jšœœ˜Jš œœœ œ!œ˜HJ˜J˜—Jš œ œœœœ˜%J˜Jš Ÿœœœœœœ˜IJš Ÿœœœœœœ˜IJ˜šŸœœœ˜Jšœœ˜"J˜J˜—J˜J˜J˜J˜—…—æò