1 "fixme: this is overwritten everytime you make a new generator"
2 define: #BytesPerWord -> 4.
3 "The size of a word in bytes on the target platform."
4 "TODO: Make this an attribute of an accessible target description."
6 define: #Chunk &slots: {#oop}.
8 _@(Chunk traits) wordSize [overrideThis].
10 define: #SlotEntry &slots: {#name. #offset}.
12 se@(SlotEntry traits) newNamed: name offset: offset
13 [se clone `>> [name := name. offset := offset. ]].
15 define: #RoleEntry &slots:
16 {#name. #rolePositions -> 0. #methodDefinition}.
18 re@(RoleEntry traits) newNamed: name rolePositions: positions methodDefinition: method
20 [name := name. rolePositions := positions. methodDefinition := method. ]].
22 define: #MethodDefinition &slots:
23 {#dispatchPositions -> 0. #method. #slotAccessor}.
25 md@(MethodDefinition traits) newDispatchPositions: positions method: method
26 [md clone `>> [dispatchPositions := positions. method := method. ]].
29 {#flags -> 0. #representative -> Nil.
35 map@(Map traits) addSlotNamed: name at: offset
37 map slotTable infect: #clone `er.
38 map slotTable := map slotTable copyWith:
39 (map surroundings SlotEntry newNamed: name offset: offset).
42 map@(Map traits) addRoleNamed: name at: position dispatching: def
47 role methodDefinition == def
49 [(map roleTable := map roleTable copy) at: index :=
50 (map surroundings RoleEntry
52 rolePositions: (role rolePositions bitOr: (1 bitShift: position))
53 methodDefinition: def).
56 map roleTable copyWith:
57 (map surroundings RoleEntry
59 rolePositions: (1 bitShift: position)
60 methodDefinition: def).
64 define: #Object &parents: {Chunk} &slots:
65 {#idHash. #bmap -> Map. #slotValues -> {}}.
67 _@(Object traits) headerWords
70 obj@(Object traits) wordSizeSansPayload
71 [obj headerWords + obj slotValues size].
73 obj@(Object traits) wordSize
74 [obj wordSizeSansPayload].
76 obj@(Object traits) makeSlotNamed: name valued: value
78 index := obj bmap slotCount.
79 obj bmap := obj bmap clone `>>
80 [slotCount := index + 1.
81 addSlotNamed: name at: obj headerWords + index * obj surroundings BytesPerWord. ].
82 obj slotValues := obj slotValues copyWith: value.
86 obj@(Object traits) setSlot: name to: val
89 do: [| :slot | slot name = name ifTrue:
90 [^ (obj slotValues at: slot offset / obj surroundings BytesPerWord - obj headerWords put: val)]].
91 error: 'Slot missing: ' ; name
94 obj@(Object traits) setSlots: namesAndValues
96 namesAndValues do: [| :assoc | obj setSlot: assoc key to: assoc value]
99 obj@(Object traits) getSlot: name
102 do: [| :slot | slot name = name ifTrue:
103 [^ (obj slotValues at: slot offset / obj surroundings BytesPerWord - obj headerWords)]].
104 error: 'Slot missing: ' ; name
107 obj@(Object traits) addDelegateValued: value
109 obj bmap := obj bmap clone `>>
110 [delegates := obj bmap delegates copyWith: value. ].
114 obj@(Object traits) addRoleNamed: name at: position dispatching: def
116 obj bmap addRoleNamed: name at: position dispatching: def
119 method@(Object traits) addMethodNamed: name on: roles
121 def := method surroundings MethodDefinition newDispatchPositions: 0 method: method.
125 [def dispatchPositions := def dispatchPositions bitOr: (1 bitShift: index).
126 role addRoleNamed: name at: index dispatching: def]].
127 "inform: 'Adding method %r roles: %r pos: %r', name, roles, def dispatchPositions."
131 define: #Array &parents: {Object}.
133 define: #OopArray &parents: {Array}
134 &slots: {#elements -> {}}.
136 arr@(OopArray traits) wordSize
137 [arr wordSizeSansPayload + arr elements size].
139 define: #ByteArray &parents: {Array}
140 &slots: {#elements -> imports ByteArray new}.
142 arr@(ByteArray traits) byteSize
144 arr wordSizeSansPayload * arr surroundings BytesPerWord + arr elements size
147 arr@(ByteArray traits) wordSize
149 arr wordSizeSansPayload + (arr elements size + arr surroundings BytesPerWord - 1 // arr surroundings BytesPerWord)
152 define: #CompiledMethod &parents: {Object}.
154 define: #Generator &slots: {
155 #translations -> IdentityDictionary new.
156 #chunks -> ExtensibleArray new.
157 #characters -> ({} newSizeOf: imports ASCIIString Character CharacterSet).
158 #symbols -> Dictionary new.
159 #littleEndian -> True.
160 #bytesPerWord -> BytesPerWord.
163 #objects -> Dictionary new.
166 gen@(Generator traits) new &littleEndian: littleEndian &wordSize: wordSize
168 littleEndian `defaultsTo: gen littleEndian.
169 wordSize `defaultsTo: Platform Current bytesPerWord * 8.
170 define: #BytesPerWord -> (wordSize // 8).
172 #{#objects. #translations. #chunks. #characters. #symbols. #bytesPerWord. #littleEndian}
173 to: {gen objects new.
174 gen translations new.
182 gen@(Generator traits) generateImageBooting: method withPrims: prims
183 "Generates the primary image objects such that the supplied CompiledMethod
184 will be interpreted immediately upon loading the image."
186 inform: 'Generating kernel'.
188 inform: 'Generating utilities'.
189 gen generateUtilities.
190 inform: 'Generating kernel accessors'.
191 gen generateKernelAccessors.
192 inform: 'Generating interpreter'.
193 gen generateInterpreterBooting: method.
194 inform: 'Generating lobby'.
196 inform: 'Generating prims'.
197 prims do: [| :assoc | gen generatePrimitive: assoc value at: assoc key].
198 inform: 'Generating maps'.
200 inform: 'Generating linkage'.
204 gen@(Generator traits) objectNamed: name
205 [gen objects at: name].
207 gen@(Generator traits) bytesAt: i in: arr put: val numBytes: bytes
211 arr elements at: i + index put:
212 (val byteShift: (gen littleEndian ifTrue: [0 - index]
213 ifFalse: [0 - bytes + index])) intoByte]
216 gen@(Generator traits) shortAt: i in: arr put: val
218 gen bytesAt: i in: arr put: val numBytes: gen bytesPerWord // 2
221 gen@(Generator traits) longAt: i in: arr put: val
223 gen bytesAt: i in: arr put: val numBytes: gen bytesPerWord
226 gen@(Generator traits) capacityForTable: table
228 (table size * 5 // 4) leastGreaterPowerOfTwo
231 gen@(Generator traits) generateSlotTableFor: map
232 [| obj capacity selector hash |
233 capacity := gen capacityForTable: map slotTable.
234 obj := gen cloneOf: (gen objectNamed: #ArrayProto) sized: 2 * capacity.
237 selector := gen generateLiteral: se name.
238 hash := (selector idHash bitAnd: capacity - 1) * 2.
239 [(obj elements at: hash) isNil]
241 [hash := (hash + 2) \\ (capacity * 2)].
242 obj elements at: hash put: selector.
243 obj elements at: hash + 1 put: se offset].
247 gen@(Generator traits) generateRoleTableFor: map
248 [| obj capacity selector hash insert |
249 capacity := gen capacityForTable: map roleTable.
250 obj := gen cloneOf: (gen objectNamed: #ArrayProto) sized: 4 * capacity.
253 selector := gen generateLiteral: re name.
254 hash := (selector idHash bitAnd: capacity - 1) * 4.
255 [(obj elements at: hash) isNil
256 \/ [(obj elements at: hash) == selector]]
258 [hash := (hash + 4) \\ (capacity * 4)].
260 [(obj elements at: insert) isNil]
262 [insert := (insert + 4) \\ (capacity * 4)].
263 obj elements at: insert put: selector.
264 obj elements at: insert + 1 put: re rolePositions.
265 obj elements at: insert + 2 put: (gen generateMethodDef: re methodDefinition).
268 [[(obj elements at: hash + 3) isNil]
269 whileFalse: [hash := (obj elements at: hash + 3) * 4].
270 obj elements at: hash + 3 put: insert // 4]].
274 gen@(Generator traits) generateMethodDef: def
276 gen translations at: def
279 (sym := def method getSlot: #selector)
280 setSlot: #cacheMask to: ((sym getSlot: #cacheMask) bitOr: def dispatchPositions).
281 (obj := gen cloneOf: (gen objectNamed: #MethodDefinitionProto)) setSlots: {
282 #method -> def method.
283 #slotAccessor -> (gen generateLiteral: def slotAccessor)
285 gen longAt: 1 * gen bytesPerWord in: obj put: def dispatchPositions.
289 gen@(Generator traits) generateMap: map
291 gen translations at: map
293 [(gen cloneOf: (gen objectNamed: #MapProto)) `>>
294 [setSlots: {#flags -> map flags.
295 #representative -> (map representative ifNil: [gen objectNamed: #NilObject]).
296 #delegates -> (gen cloneOf: (gen objectNamed: #ArrayProto) elements: map delegates).
297 #slotCount -> map slotCount.
298 #slotTable -> (gen generateSlotTableFor: map).
299 #roleTable -> (gen generateRoleTableFor: map)}. ]]
302 gen@(Generator traits) generateMaps
304 gen objects keysAndValuesDo:
306 inform: ' Adding map for %s', name.
307 gen generateMap: obj bmap]
310 obj@(Object traits) nextOop
311 "Answer the pointer to just beyond this object."
312 [obj oop + (obj wordSize * obj surroundings BytesPerWord)].
314 gen@(Generator traits) assignOops
315 "Assign oops to all of the chunks, accumulating the final oop which is used
316 to set the image size."
318 gen imageSize := gen chunks inject: 0 into:
319 [| :oop :chunk | chunk oop := oop. chunk nextOop]
322 gen@(Generator traits) emitInteger: val on: stream byteSize: byteSize
323 "Takes an integer and outputs the binary data value in the correct byte-order
326 stream next: byteSize putInteger: val &littleEndian: gen littleEndian
329 gen@(Generator traits) emitLong: val on: stream
330 "Takes an integer and outputs the binary data value in the correct byte-order
333 gen emitInteger: val on: stream byteSize: gen bytesPerWord
336 gen@(Generator traits) emitOopOf: chunk on: stream
337 [gen emitLong: chunk oop on: stream].
339 gen@(Generator traits) emitOopOf: _@Nil on: stream
340 [gen emitOopOf: (gen objectNamed: #NilObject) on: stream].
342 gen@(Generator traits) emitOopOf: i@(imports SmallInteger traits) on: stream
343 [gen emitLong: (i << 1 bitOr: 1) on: stream].
345 gen@(Generator traits) emitObjectHashed: hash sized: size payload: payload format: format on: stream
347 "fix: check big endian"
349 gen littleEndian ifFalse:
350 [gen emitInteger: 0 on: stream byteSize: gen bytesPerWord - 4].
354 [{2r1 bitOr: (hash bitAnd: 16r7F) << 1.
355 (hash >> 7) intoByte.
356 (hash >> 15) intoByte.
359 [{2r10000000 bitOr: (hash >> 16 bitAnd: 16r7F).
360 (hash >> 8) intoByte.
362 format}]) as: ByteArray).
363 gen littleEndian ifTrue:
364 [gen emitInteger: 0 on: stream byteSize: gen bytesPerWord - 4].
366 "size in words of slot data"
367 gen emitLong: size on: stream.
368 "size in bytes of payload (oop array or byte array)"
369 gen emitLong: payload on: stream.
374 gen@(Generator traits) emit: obj@(Object traits) on: stream
376 gen emitObjectHashed: obj idHash sized: obj wordSize payload: 0 format: 2r00 on: stream.
377 gen emitLong: (gen translations at: obj bmap) oop on: stream.
379 do: [| :slotVal | gen emitOopOf: slotVal on: stream].
383 gen@(Generator traits) emit: obj@(OopArray traits) on: stream
385 gen emitObjectHashed: obj idHash
386 sized: obj wordSizeSansPayload
387 payload: obj elements size * gen bytesPerWord
390 gen emitLong: (gen translations at: obj bmap) oop on: stream.
391 (obj slotValues ;; obj elements)
392 do: [| :slotVal | gen emitOopOf: slotVal on: stream].
396 gen@(Generator traits) emit: obj@(ByteArray traits) on: stream
398 gen emitObjectHashed: obj idHash
399 sized: obj wordSizeSansPayload
400 payload: obj elements size
403 gen emitLong: (gen translations at: obj bmap) oop on: stream.
404 obj slotValues do: [| :slotVal | gen emitOopOf: slotVal on: stream].
405 stream nextPutAll: obj elements.
406 stream next: (gen bytesPerWord - obj elements size) \\ gen bytesPerWord put: 0.
410 gen@(Generator traits) emitHeaderOn: stream
412 gen emitLong: 16rABCDEF43 on: stream.
413 gen emitLong: gen imageSize on: stream.
414 gen emitLong: gen nextHash on: stream.
415 gen emitLong: ((gen objectNamed: #GlobalsObject) getSlot: #specialOops) oop on: stream.
416 "i shortened dispatch id to one word"
417 gen emitLong: 0 on: stream.
420 gen@(Generator traits) emitOn: stream
421 "Emits a bootstrap image on the stream after it has been generated."
423 inform: 'Assigning oops'.
425 inform: 'Emitting image: %s', stream resource locator.
426 gen emitHeaderOn: stream.
427 gen chunks do: [| :chunk | gen emit: chunk on: stream]
430 gen@(Generator traits) addObjectNamed: name valued: obj
432 inform: ' Adding object %s', name.
433 gen objects at: name put: obj.
437 gen@(Generator traits) newIdentityHash
439 hash := gen nextHash.
444 gen@(Generator traits) new: layout fromMap: map
446 obj := layout clone `>> [idHash := gen newIdentityHash. bmap := map. ].
447 obj slotValues := obj slotValues newSize: map slotCount.
448 map representative := obj.
449 gen chunks addLast: obj.
453 gen@(Generator traits) newMap
455 gen surroundings Map clone
458 gen@(Generator traits) newObject
460 gen new: gen surroundings Object
463 gen@(Generator traits) new: layout
465 gen new: layout fromMap: gen newMap
468 gen@(Generator traits) cloneOf: proto@(Object traits)
470 gen chunks addLast: proto clone `>>
471 [idHash := gen newIdentityHash. slotValues := proto slotValues copy. ]
474 gen@(Generator traits) cloneOf: arr@(Array traits)
475 [resend `>> [elements := arr elements copy. ]].
477 gen@(Generator traits) cloneOf: proto sized: size
478 [(gen cloneOf: proto) `>> [elements := proto elements newSize: size. ]].
480 gen@(Generator traits) cloneOf: proto elements: elements
481 [(gen cloneOf: proto) `>> [elements := elements as: proto elements. ]].
483 gen@(Generator traits) addAccessorFor: slotName on: obj
484 [| accessor selector |
485 selector := obj accessorNameFor: slotName.
486 accessor := gen cloneOf: (gen objectNamed: #CompiledMethodProto).
489 #selector -> (gen generateLiteral: selector).
490 #inputVariables -> 1.
491 #localVariables -> 1.
493 #literals -> (gen cloneOf: (gen objectNamed: #ArrayProto) elements: {gen generateLiteral: slotName}).
494 #selectors -> (gen cloneOf: (gen objectNamed: #ArrayProto) elements: {gen generateLiteral: #atSlotNamed:}).
496 (gen cloneOf: (gen objectNamed: #ArrayProto)
498 VM SSACode loadVariable. 0.
499 VM SSACode loadLiteral. 1. gen generateLiteral: slotName.
500 VM SSACode directSendMessage. 0. gen generateLiteral: #atSlotNamed:. 2. 0. 1.
501 VM SSACode returnRegister. 0
504 (accessor addMethodNamed: selector on: {obj}) slotAccessor: slotName.
508 gen@(Generator traits) addMutatorFor: slotName on: obj
509 [| mutator selector |
510 mutator := gen cloneOf: (gen objectNamed: #CompiledMethodProto).
511 selector := obj mutatorNameFor: slotName.
514 #selector -> (gen generateLiteral: selector).
515 #inputVariables -> 2.
516 #localVariables -> 1.
518 #literals -> (gen cloneOf: (gen objectNamed: #ArrayProto) elements: {gen generateLiteral: slotName}).
519 #selectors -> (gen cloneOf: (gen objectNamed: #ArrayProto) elements: {gen generateLiteral: #atSlotNamed:put:}).
521 (gen cloneOf: (gen objectNamed: #ArrayProto)
524 VM SSACode loadVariable. 0.
525 VM SSACode loadVariable. 1.
526 VM SSACode loadLiteral. 2. gen generateLiteral: slotName.
527 VM SSACode directSendMessage. 0. gen generateLiteral: #atSlotNamed:put:. 3. 0. 2. 1.
528 VM SSACode returnRegister. 0
531 (mutator addMethodNamed: selector on: {obj. Nil}) slotAccessor: slotName.
535 gen@(Generator traits) addAccessorsFor: slotName on: obj
537 gen addAccessorFor: slotName on: obj.
538 gen addMutatorFor: slotName on: obj
541 gen@(Generator traits) generateKernelAccessors
545 obj bmap slotTable do: [| :slot | gen addAccessorsFor: slot name on: obj]]
548 gen@(Generator traits) generatePrototype: name &suffix: suffix &layout: layout &parents: parents &slots: slotSpecs &elements: elements
549 [| traits window result |
550 suffix `defaultsTo: 'Proto'.
551 traits := (gen addObjectNamed: (name ; 'Traits') intern valued: gen newObject)
552 `>> [addDelegateValued: Nil. ].
553 window := (gen addObjectNamed: (name ; 'Window') intern valued: gen newObject)
554 `>> [bmap flags := 1. addDelegateValued: Nil. ].
557 [parents reverseDoWithIndex:
559 window addDelegateValued: parent]].
560 window addDelegateValued: traits.
561 result := (gen addObjectNamed: (name ; suffix) intern
562 valued: (layout ifNil: [gen newObject] ifNotNil: [gen new: layout]))
563 `>> [addDelegateValued: window. ].
565 [(result hasSlotNamed: #elements) ifTrue: [result elements := elements]].
566 (slotSpecs `defaultsTo: {}) do:
567 [| :spec | result makeSlotNamed: spec key valued: spec value].
571 gen@(Generator traits) generateInstance: name of: window
572 [(gen addObjectNamed: name valued: gen newObject) `>>
573 [addDelegateValued: window.]
576 gen@(Generator traits) generateKernel
578 gen generatePrototype: 'Root'.
579 gen generatePrototype: 'Oddball' &parents: {gen objectNamed: #RootTraits}.
580 gen generatePrototype: 'Derivable' &parents: {gen objectNamed: #RootTraits}.
581 gen generatePrototype: 'Cloneable' &parents: {gen objectNamed: #DerivableTraits. gen objectNamed: #RootTraits}.
583 gen generateInstance: #NilObject of: (gen objectNamed: #OddballWindow).
584 gen generateInstance: #NoRoleObject of: (gen objectNamed: #OddballWindow).
586 gen generatePrototype: 'Boolean' &parents: {gen objectNamed: #OddballTraits. gen objectNamed: #RootTraits}.
587 gen generateInstance: #TrueObject of: (gen objectNamed: #BooleanWindow).
588 gen generateInstance: #FalseObject of: (gen objectNamed: #BooleanWindow).
590 gen generatePrototype: 'Array' &layout: gen surroundings OopArray
591 &parents: {gen objectNamed: #NilObject. gen objectNamed: #NilObject. gen objectNamed: #NilObject. gen objectNamed: #CloneableTraits. gen objectNamed: #DerivableTraits. gen objectNamed: #RootTraits}
592 &elements: Array new.
593 gen generatePrototype: 'ByteArray' &layout: gen surroundings ByteArray
594 &parents: {gen objectNamed: #NilObject. gen objectNamed: #NilObject. gen objectNamed: #NilObject. gen objectNamed: #CloneableTraits. gen objectNamed: #DerivableTraits. gen objectNamed: #RootTraits}
595 &elements: ByteArray new.
597 gen generatePrototype: 'SmallInteger' &parents: {gen objectNamed: #NilObject. gen objectNamed: #NilObject. gen objectNamed: #NilObject. gen objectNamed: #NilObject. gen objectNamed: #OddballTraits. gen objectNamed: #RootTraits}.
598 (gen generatePrototype: 'Float' &layout: gen surroundings ByteArray
599 &parents: {gen objectNamed: #NilObject. gen objectNamed: #NilObject. gen objectNamed: #NilObject. gen objectNamed: #NilObject. gen objectNamed: #ByteArrayTraits. gen objectNamed: #NilObject. gen objectNamed: #NilObject. gen objectNamed: #NilObject. gen objectNamed: #CloneableTraits. gen objectNamed: #DerivableTraits. gen objectNamed: #RootTraits}) `>>
600 [elements: (ByteArray newSize: gen bytesPerWord)].
602 gen generatePrototype: 'ASCIIString' &layout: gen surroundings ByteArray
603 &parents: {gen objectNamed: #NilObject. gen objectNamed: #ByteArrayTraits. gen objectNamed: #NilObject. gen objectNamed: #NilObject. gen objectNamed: #NilObject. gen objectNamed: #CloneableTraits. gen objectNamed: #DerivableTraits. gen objectNamed: #RootTraits}.
605 gen generatePrototype: 'Symbol' &layout: gen surroundings ByteArray
606 &parents: {gen objectNamed: #ASCIIStringTraits. gen objectNamed: #NilObject. gen objectNamed: #ByteArrayTraits. gen objectNamed: #NilObject. gen objectNamed: #NilObject. gen objectNamed: #NilObject. gen objectNamed: #CloneableTraits. gen objectNamed: #DerivableTraits. gen objectNamed: #RootTraits}
607 &slots: {#cacheMask -> 0}.
609 gen symbols at: #'' put: (gen objectNamed: #SymbolProto).
611 gen generatePrototype: 'ASCIICharacter'
612 &parents: {gen objectNamed: #NilObject. gen objectNamed: #OddballTraits. gen objectNamed: #RootTraits} &slots: {#code -> 0}.
613 gen characters at: 0 put: (gen objectNamed: #ASCIICharacterProto).
614 1 below: gen characters size
616 c: (gen cloneOf: (gen objectNamed: #ASCIICharacterProto)).
617 c setSlot: #code to: index.
618 gen characters at: index put: c].
619 (gen objectNamed: #ASCIIStringTraits) makeSlotNamed: #Character valued: (gen objectNamed: #ASCIICharacterProto).
621 gen generatePrototype: 'Namespace'
622 &parents: {gen objectNamed: #CloneableTraits. gen objectNamed: #DerivableTraits. gen objectNamed: #RootTraits}.
623 gen generateInstance: #BootstrapObject of: (gen objectNamed: #NamespaceWindow).
625 gen generatePrototype: 'Method' &parents: {gen objectNamed: #CloneableTraits. gen objectNamed: #DerivableTraits. gen objectNamed: #RootTraits}.
627 gen generatePrototype: 'PrimitiveMethod'
628 &parents: {gen objectNamed: #MethodTraits. gen objectNamed: #CloneableTraits. gen objectNamed: #DerivableTraits. gen objectNamed: #RootTraits}
629 &slots: {#index -> 0. #selector -> (gen objectNamed: #NilObject). #inputVariables -> 0}.
631 gen generatePrototype: 'CompiledMethod'
632 &parents: {gen objectNamed: #MethodTraits. gen objectNamed: #CloneableTraits. gen objectNamed: #DerivableTraits. gen objectNamed: #RootTraits}
633 &slots: {#method -> (gen objectNamed: #NilObject). #selector -> (gen objectNamed: #NilObject).
634 #inputVariables -> 0. #localVariables -> 0.
635 #restVariable -> (gen objectNamed: #FalseObject).
636 #optionalKeywords -> (gen objectNamed: #ArrayProto).
637 #heapAllocate -> (gen objectNamed: #FalseObject).
638 #environment -> (gen objectNamed: #BootstrapObject).
639 #literals -> (gen objectNamed: #ArrayProto).
640 #selectors -> (gen objectNamed: #ArrayProto).
641 #code -> (gen objectNamed: #ArrayProto).
642 #sourceTree -> (gen objectNamed: #NilObject).
643 #debugMap -> (gen objectNamed: #ArrayProto).
644 #isInlined -> (gen objectNamed: #FalseObject).
645 #oldCode -> (gen objectNamed: #NilObject).
647 #calleeCount -> (gen objectNamed: #NilObject).
649 #cachedInCallers -> (gen objectNamed: #NilObject).
650 #cachedInCallersCount -> 0.
651 #nextInlineAtCallCount -> (gen objectNamed: #NilObject).
652 #reserved5 -> (gen objectNamed: #NilObject).
655 gen generatePrototype: 'Closure' &layout: gen surroundings OopArray
656 &parents: {gen objectNamed: #MethodTraits. gen objectNamed: #ArrayTraits. gen objectNamed: #NilObject. gen objectNamed: #NilObject. gen objectNamed: #NilObject. gen objectNamed: #CloneableTraits. gen objectNamed: #DerivableTraits. gen objectNamed: #RootTraits}
657 &slots: {#method -> (gen objectNamed: #NilObject)}.
659 gen generatePrototype: 'MethodDefinition' &layout: gen surroundings ByteArray
660 &parents: {gen objectNamed: #CloneableTraits. gen objectNamed: #DerivableTraits. gen objectNamed: #RootTraits}
661 &slots: {#method -> (gen objectNamed: #CompiledMethodProto). #slotAccessor -> (gen objectNamed: #NilObject)}
662 &elements: (ByteArray newSize: 4 * gen bytesPerWord).
664 gen generatePrototype: 'Map' &layout: gen surroundings ByteArray
665 &parents: {gen objectNamed: #CloneableTraits. gen objectNamed: #DerivableTraits. gen objectNamed: #RootTraits}
666 &slots: {#flags -> 0. #representative -> (gen objectNamed: #NilObject).
667 #delegates -> (gen objectNamed: #ArrayProto). #slotCount -> 0.
668 #slotTable -> (gen objectNamed: #ArrayProto). #roleTable -> (gen objectNamed: #ArrayProto)}
669 &elements: (ByteArray newSize: 3 * gen bytesPerWord).
671 gen generatePrototype: 'LexicalContext' &layout: gen surroundings OopArray
672 &parents: {gen objectNamed: #ArrayTraits. gen objectNamed: #NilObject. gen objectNamed: #NilObject. gen objectNamed: #NilObject. gen objectNamed: #CloneableTraits. gen objectNamed: #DerivableTraits. gen objectNamed: #RootTraits}
673 &slots: {#framePointer -> 0}.
675 gen generatePrototype: 'Interpreter' &layout: gen surroundings ByteArray
676 &parents: {gen objectNamed: #CloneableTraits. gen objectNamed: #DerivableTraits. gen objectNamed: #RootTraits}
677 &slots: {#stack -> (gen objectNamed: #ArrayProto).
678 #method -> (gen objectNamed: #NilObject).
679 #closure -> (gen objectNamed: #NilObject).
680 #lexicalContext -> (gen objectNamed: #NilObject).
681 #ensureHandlers -> 0}
682 &elements: (ByteArray newSize: 5 * gen bytesPerWord).
684 (gen addObjectNamed: #EnsureMarkerObject valued: (gen cloneOf: (gen objectNamed: #CompiledMethodProto))) `>>
686 setSlot: #method to: marker.
688 (gen cloneOf: (gen objectNamed: #ArrayProto)
689 elements: {VM SSACode resume})].
692 gen@(Generator traits) generateInterpreterBooting: method
693 [| compiler stackObj stackSize methodObj codeSize |
694 compiler := VM SSACompiler new.
695 _@compiler branchTableHash: key
697 literal := gen generateLiteral: key.
698 (literal isSameAs: SmallInteger)
700 ifFalse: [literal idHash]
702 inform: 'Compiling the syntax tree of bootstrap code and libraries into SSA code.'.
704 method := (compiler generate: method result: Nil &topLevel: True) `>> [heapAllocate := False. ].
706 "compiler decompile: method code."
708 methodObj := gen generateLiteral: method.
710 stackSize := 16. "if you change this, change vm.c which has it hard-coded in the beginning of interpret()"
712 stackObj := (gen cloneOf: (gen objectNamed: #ArrayProto) sized: stackSize) `>>
713 [elements at: 0 put: 0. "-6: prev sp"
714 elements at: 1 put: -1. "-5: resultStackPointer"
715 elements at: 2 put: 0. "-4: code pointer"
716 elements at: 3 put: methodObj. "-3: closure"
717 elements at: 4 put: 0. "-2: lexical context"
718 elements at: 5 put: 0. "-1: prev fp"
719 elements at: 6 put: 0. ].
721 codeSize := method code size.
723 gen addObjectNamed: #InterpreterObject valued: (gen cloneOf: (gen objectNamed: #InterpreterProto)).
724 (gen objectNamed: #InterpreterObject) setSlots: {
726 #method -> methodObj.
727 #closure -> methodObj
729 gen longAt: 0 * gen bytesPerWord in: (gen objectNamed: #InterpreterObject) put: 6. " frame pointer (framesize=6)"
730 "long at 1 is code pointer -- I guess this gets filled later or is zero"
731 gen longAt: 2 * gen bytesPerWord in: (gen objectNamed: #InterpreterObject) put: codeSize.
732 gen longAt: 3 * gen bytesPerWord in: (gen objectNamed: #InterpreterObject) put: 6. "stack pointer (framesize=6)"
733 gen longAt: 4 * gen bytesPerWord in: (gen objectNamed: #InterpreterObject) put: stackSize
736 gen@(Generator traits) generateUtilities
738 gen generateInstance: #ConsoleObject of: (gen objectNamed: #OddballWindow).
740 gen generatePrototype: 'File' &parents: {
741 gen objectNamed: #NilObject.
742 gen objectNamed: #CloneableTraits.
743 gen objectNamed: #DerivableTraits.
744 gen objectNamed: #RootTraits
746 gen generatePrototype: 'Directory' &parents: {
747 gen objectNamed: #NilObject.
748 gen objectNamed: #CloneableTraits.
749 gen objectNamed: #DerivableTraits.
750 gen objectNamed: #RootTraits
752 gen generatePrototype: 'ExternalLibrary' &parents: {
753 gen objectNamed: #NilObject.
754 gen objectNamed: #CloneableTraits.
755 gen objectNamed: #DerivableTraits.
756 gen objectNamed: #RootTraits
760 gen@(Generator traits) generateLobby
762 gen addObjectNamed: #PrototypesObject valued: (gen cloneOf: (gen objectNamed: #NamespaceProto)).
763 (gen objectNamed: #BootstrapObject) addDelegateValued: (gen objectNamed: #PrototypesObject).
764 "timmy: no named delegate slots but name needed for accessor"
765 (gen objectNamed: #BootstrapObject) makeSlotNamed: #prototypes valued: (gen objectNamed: #PrototypesObject).
766 gen addAccessorFor: #prototypes on: (gen objectNamed: #BootstrapObject).
767 "Install slots/accessors in the 'prototypes' namespace,
768 set up traits traits, and set up printName. Make sure all bootstrapped protos
769 are listed here, otherwise these important steps are left out for them."
770 [| :slotName :objectName obj printNameLiteral window traits |
771 obj := gen objectNamed: objectName.
772 (gen objectNamed: #PrototypesObject) makeSlotNamed: slotName valued: obj.
773 gen addAccessorFor: slotName on: (gen objectNamed: #PrototypesObject).
774 window := obj bmap delegates first.
775 window bmap delegates at: 0 put: (gen objectNamed: #CloneableWindow).
776 traits := window bmap delegates last"(window getSlot: #traits)".
777 traits bmap delegates at: 0 put: (gen objectNamed: #CloneableWindow).
778 printNameLiteral := gen generateLiteral: slotName name.
779 traits makeSlotNamed: #printNameTraits valued: printNameLiteral.
780 gen addAccessorFor: #printNameTraits on: traits.
781 window makeSlotNamed: #printNameWindow valued: printNameLiteral.
782 gen addAccessorFor: #printNameWindow on: window
785 {#Oddball. #OddballProto}.
786 {#Cloneable. #CloneableProto}.
787 {#Derivable. #DerivableProto}.
788 {#Namespace. #NamespaceProto}.
789 {#Boolean. #BooleanProto}.
790 {#Array. #ArrayProto}.
791 {#ByteArray. #ByteArrayProto}.
792 {#ASCIIString. #ASCIIStringProto}.
793 {#ASCIICharacter. #ASCIICharacterProto}.
794 {#Symbol. #SymbolProto}.
795 {#SmallInteger. #SmallIntegerProto}.
796 {#SingleFloat. #FloatProto}.
798 {#LexicalContext. #LexicalContextProto}.
799 {#MethodDefinition. #MethodDefinitionProto}.
800 {#Method. #MethodProto}.
801 {#PrimitiveMethod. #PrimitiveMethodProto}.
802 {#CompiledMethod. #CompiledMethodProto}.
803 {#Closure. #ClosureProto}.
804 {#Interpreter. #InterpreterProto}.
806 {#Directory. #DirectoryProto}.
807 {#ExternalLibrary. #ExternalLibraryProto}
810 gen addObjectNamed: #GlobalsObject valued: (gen cloneOf: (gen objectNamed: #NamespaceProto)).
811 (gen objectNamed: #BootstrapObject) addDelegateValued: (gen objectNamed: #GlobalsObject).
812 (gen objectNamed: #BootstrapObject) makeSlotNamed: #globals valued: (gen objectNamed: #GlobalsObject).
813 gen addAccessorFor: #globals on: (gen objectNamed: #BootstrapObject).
815 (gen objectNamed: #GlobalsObject) makeSlotNamed: key valued: value.
816 gen addAccessorFor: key on: (gen objectNamed: #GlobalsObject)] applier for: {
817 #Console. gen objectNamed: #ConsoleObject.
818 #NoRole. gen objectNamed: #NoRoleObject.
819 #Nil. gen objectNamed: #NilObject.
820 #True. gen objectNamed: #TrueObject.
821 #False. gen objectNamed: #FalseObject.
822 #lobby. gen objectNamed: #BootstrapObject.
823 #bootstrapCharacters. gen cloneOf: (gen objectNamed: #ArrayProto) elements: gen characters.
824 #bootstrapSymbols. gen objectNamed: #ArrayProto.
825 #Symbols. gen objectNamed: #NilObject.
826 #bootstrapInterpreter. gen objectNamed: #InterpreterObject.
827 #ensureMarker. gen objectNamed: #EnsureMarkerObject.
828 #specialOops. gen objectNamed: #ArrayProto.
829 #features. gen objectNamed: #ArrayProto.
831 gen addMutatorFor: #bootstrapSymbols on: (gen objectNamed: #GlobalsObject).
832 gen addMutatorFor: #features on: (gen objectNamed: #GlobalsObject)
835 gen@(Generator traits) generateLinkage
836 "TODO: The order in this method must be the same as in memory.slate, enforce it"
838 (gen objectNamed: #GlobalsObject) setSlot: #specialOops to:
839 (gen cloneOf: (gen objectNamed: #ArrayProto) elements:
849 #MethodDefinitionProto.
853 #CompiledMethodWindow.
854 #PrimitiveMethodWindow.
856 #LexicalContextProto.
859 } collect: #(gen objectNamed: _) `er)
875 #badTypeError} collect: #(gen generateLiteral: _) `er)).
876 (gen objectNamed: #GlobalsObject) setSlot: #bootstrapSymbols to:
877 (gen cloneOf: (gen objectNamed: #ArrayProto) elements: gen symbols valueSet).
880 gen@(Generator traits) generatePrimitive: prim at: index
881 "Given a MethodDefinition representing a Pidgin primitive definition,
882 this defines a PrimitiveMethod stub that will invoke the given primitive
883 index. Must be called after generateImageBooting:."
885 (gen cloneOf: (gen objectNamed: #PrimitiveMethodProto)) `>>
887 #selector -> (gen generateLiteral: prim selector).
888 #inputVariables -> prim roles size.
891 addMethodNamed: prim selector on:
894 (role isSameAs: nodes UnaryMessage)
896 [inform: ' Adding primitive %s to %s', index, role selector.
897 gen objectNamed: role selector]]) ]
900 gen@(Generator traits) generateLiteral: literal
903 ifTrue: [gen objectNamed: #NoRoleObject]
904 ifFalse: [error: 'Unsupported literal.']
907 gen@(Generator traits) generateLiteral: i@(imports SmallInteger traits)
910 gen@(Generator traits) generateLiteral: _@(imports BigInteger traits)
912 error: 'The bootstrap generator does not support big integers.'
915 gen@(Generator traits) generateLiteral: _@True
916 [gen objectNamed: #TrueObject].
918 gen@(Generator traits) generateLiteral: _@False
919 [gen objectNamed: #FalseObject].
921 gen@(Generator traits) generateLiteral: _@Nil
922 [gen objectNamed: #NilObject].
924 gen@(Generator traits) generateLiteral: _@lobby
925 [gen objectNamed: #BootstrapObject].
927 gen@(Generator traits) generateLiteral: s@(imports ASCIIString traits)
930 ifTrue: [gen objectNamed: #ASCIIStringProto]
931 ifFalse: [gen cloneOf: (gen objectNamed: #ASCIIStringProto) elements:
932 (s collect: #code`er into: (ByteArray newSizeOf: s))]
935 gen@(Generator traits) generateLiteral: s@(imports Symbol traits)
940 [gen cloneOf: (gen objectNamed: #SymbolProto) elements:
941 (s name collect: #code`er into: (ByteArray newSizeOf: s name))]
944 gen@(Generator traits) generateLiteral: f@(imports SingleFloat traits)
946 obj := gen cloneOf: (gen objectNamed: #FloatProto) elements: (ByteArray newWithAll: f).
947 gen littleEndian = -1.0 isLittleEndian
948 ifFalse: [obj elements := obj elements reversed].
952 gen@(Generator traits) generateLiteral: a@(imports ByteArray traits)
955 ifTrue: [gen objectNamed: #ByteArrayProto]
956 ifFalse: [gen cloneOf: (gen objectNamed: #ByteArrayProto) elements: a]
959 gen@(Generator traits) generateLiteral: a@(imports Array traits)
962 ifTrue: [gen objectNamed: #ArrayProto]
963 ifFalse: [gen cloneOf: (gen objectNamed: #ArrayProto) elements:
964 (a collect: #(gen generateLiteral: _) `er)]
967 gen@(Generator traits) generateLiteral: c@(imports ASCIIString Character traits)
969 gen characters at: c code
972 gen@(Generator traits) generateLiteral: block@(imports CompiledMethod traits)
974 obj := (gen cloneOf: (gen objectNamed: #CompiledMethodProto)) `>>
976 #inputVariables -> block inputVariables.
977 #localVariables -> block localVariables.
978 #restVariable -> (gen generateLiteral: block restVariable).
979 #heapAllocate -> (gen generateLiteral: block heapAllocate).
980 #literals -> (gen generateLiteral: block literals).
981 #registerCount -> (gen generateLiteral: block registerCount).
982 #selectors -> (gen generateLiteral: block selectors).
983 #code -> (gen generateLiteral: block code)}. ].
984 obj setSlot: #method to: obj.
985 block optionalKeywords isEmpty ifFalse:
986 [obj setSlot: #optionalKeywords to: (gen generateLiteral: block optionalKeywords)].