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: {
10 _@(Chunk traits) wordSize [overrideThis].
12 define: #SlotEntry &slots: {#name. #offset}.
14 se@(SlotEntry traits) newNamed: name offset: offset
15 [se clone `>> [name := name. offset := offset. ]].
17 define: #RoleEntry &slots: {
23 re@(RoleEntry traits) newNamed: name rolePositions: positions methodDefinition: method
25 [name := name. rolePositions := positions. methodDefinition := method. ]].
27 define: #MethodDefinition &slots: {
28 #dispatchPositions -> 0.
33 define: #Map &slots: {
35 #representative -> Nil.
42 map@(Map traits) addSlotNamed: name at: offset
45 (map slotTable collect: #clone `er)
46 ; {map surroundings SlotEntry newNamed: name offset: offset}.
49 map@(Map traits) addRoleNamed: name at: position dispatching: def
51 map roleTable doWithIndex:
53 role methodDefinition == def
55 [(map roleTable := map roleTable copy) at: index :=
56 (map surroundings RoleEntry
58 rolePositions: (role rolePositions bitOr: (1 bitShift: position))
59 methodDefinition: def).
62 map roleTable copyWith:
63 (map surroundings RoleEntry
65 rolePositions: (1 bitShift: position)
66 methodDefinition: def).
70 define: #Object &parents: {Chunk} &slots: {
76 _@(Object traits) headerWords
79 obj@(Object traits) wordSizeSansPayload
80 [obj headerWords + obj slotValues size].
82 obj@(Object traits) wordSize
83 [obj wordSizeSansPayload].
85 obj@(Object traits) makeSlotNamed: name valued: value
87 index := obj bmap slotCount.
88 obj bmap := obj bmap clone `>>
89 [slotCount := index + 1.
90 addSlotNamed: name at: obj headerWords + index * obj surroundings BytesPerWord. ].
91 obj slotValues := obj slotValues copyWith: value.
95 obj@(Object traits) slotNamed: name
98 detect: [| :slot | slot name = name]
99 ifNone: [obj error: 'Slot missing: ' ; name]
102 obj@(Object traits) setSlot: name to: val
104 (obj slotNamed: name) ifNotNilDo:
105 [| :slot | obj slotValues at: slot offset / obj surroundings BytesPerWord - obj headerWords put: val]
108 obj@(Object traits) getSlot: name
110 (obj slotNamed: name) ifNotNilDo:
111 [| :slot | obj slotValues at: slot offset / obj surroundings BytesPerWord - obj headerWords]
114 obj@(Object traits) addDelegateValued: value
116 obj bmap := obj bmap clone `>>
117 [delegates := obj bmap delegates copyWith: value. ].
121 obj@(Object traits) addRoleNamed: name at: position dispatching: def
123 obj bmap addRoleNamed: name at: position dispatching: def
126 method@(Object traits) addMethodNamed: name on: roles
128 def := method surroundings MethodDefinition new
129 `>> [dispatchPositions := 0. method := method. ].
133 [def dispatchPositions := def dispatchPositions bitOr: (1 bitShift: index).
134 role addRoleNamed: name at: index dispatching: def]].
135 "inform: 'Adding method %r roles: %r pos: %r', name, roles, def dispatchPositions."
139 define: #Array &parents: {Object}.
141 define: #OopArray &parents: {Array} &slots: {
145 arr@(OopArray traits) wordSize
146 [arr wordSizeSansPayload + arr elements size].
148 define: #ByteArray &parents: {Array} &slots: {
149 #elements -> imports ByteArray new
152 arr@(ByteArray traits) byteSize
154 arr wordSizeSansPayload * arr surroundings BytesPerWord + arr elements size
157 arr@(ByteArray traits) wordSize
159 arr wordSizeSansPayload + (arr elements size + arr surroundings BytesPerWord - 1 // arr surroundings BytesPerWord)
162 define: #CompiledMethod &parents: {Object}.
164 define: #Generator &slots: {
165 #translations -> IdentityDictionary new.
166 #chunks -> ExtensibleArray new.
167 #characters -> ({} newSizeOf: imports ASCIIString Character CharacterSet).
168 #symbols -> Dictionary new.
169 #littleEndian -> True.
170 #bytesPerWord -> BytesPerWord.
173 #objects -> Dictionary new.
176 gen@(Generator traits) new &littleEndian: littleEndian &wordSize: wordSize
178 littleEndian `defaultsTo: gen littleEndian.
179 wordSize `defaultsTo: Platform Current bytesPerWord * 8.
180 define: #BytesPerWord -> (wordSize // 8).
182 [objects := gen objects new.
183 translations := gen translations new.
184 chunks := gen chunks new.
185 characters := gen characters copy.
186 symbols := gen symbols new.
187 bytesPerWord := wordSize // 8.
188 littleEndian := littleEndian. ]
191 gen@(Generator traits) generateImageBooting: method withPrims: prims
192 "Generates the primary image objects such that the supplied CompiledMethod
193 will be interpreted immediately upon loading the image."
195 inform: 'Generating kernel'.
197 inform: 'Generating utilities'.
198 gen generateUtilities.
199 inform: 'Generating kernel accessors'.
200 gen generateKernelAccessors.
201 inform: 'Generating interpreter'.
202 gen generateInterpreterBooting: method.
203 inform: 'Generating bootstrap namespace'.
204 gen generateBootstrapNamespace.
205 inform: 'Generating prims'.
206 prims do: [| :assoc | gen generatePrimitive: assoc value at: assoc key].
207 inform: 'Generating maps'.
209 inform: 'Generating linkage'.
213 gen@(Generator traits) objectsAt: name
214 [gen objects at: name].
216 gen@(Generator traits) objectsAt: name put: obj
218 inform: ' Adding object %s', name.
219 gen objects at: name put: obj
222 gen@(Generator traits) bytesAt: i in: arr put: val numBytes: bytes
226 arr elements at: i + index put:
227 (val byteShift: (gen littleEndian ifTrue: [0 - index]
228 ifFalse: [0 - bytes + index])) intoByte]
231 gen@(Generator traits) shortAt: i in: arr put: val
233 gen bytesAt: i in: arr put: val numBytes: 2
236 gen@(Generator traits) wordAt: i in: arr put: val
238 gen bytesAt: i in: arr put: val numBytes: gen bytesPerWord
241 gen@(Generator traits) capacityForTable: table
243 (table size * 5 // 4) leastGreaterPowerOfTwo
246 gen@(Generator traits) generateSlotTableFor: map
247 [| obj capacity selector hash |
248 capacity := gen capacityForTable: map slotTable.
249 obj := gen cloneOf: (gen objectsAt: #ArrayProto) sized: 2 * capacity.
252 selector := gen generateLiteral: se name.
253 hash := (selector idHash bitAnd: capacity - 1) * 2.
254 [(obj elements at: hash) isNil]
256 [hash := (hash + 2) \\ (capacity * 2)].
257 obj elements at: hash put: selector.
258 obj elements at: hash + 1 put: se offset].
262 gen@(Generator traits) generateRoleTableFor: map
263 [| obj capacity selector hash insert |
264 capacity := gen capacityForTable: map roleTable.
265 obj := gen cloneOf: (gen objectsAt: #ArrayProto) sized: 4 * capacity.
268 selector := gen generateLiteral: re name.
269 hash := (selector idHash bitAnd: capacity - 1) * 4.
270 [(obj elements at: hash) isNil
271 \/ [(obj elements at: hash) == selector]]
273 [hash := (hash + 4) \\ (capacity * 4)].
275 [(obj elements at: insert) isNil]
277 [insert := (insert + 4) \\ (capacity * 4)].
278 obj elements at: insert put: selector.
279 obj elements at: insert + 1 put: re rolePositions.
280 obj elements at: insert + 2 put: (gen generateMethodDef: re methodDefinition).
283 [[(obj elements at: hash + 3) isNil]
284 whileFalse: [hash := (obj elements at: hash + 3) * 4].
285 obj elements at: hash + 3 put: insert // 4]].
289 gen@(Generator traits) generateMethodDef: def
291 gen translations at: def ifAbsentPut:
293 (sym := def method getSlot: #selector)
294 setSlot: #cacheMask to: ((sym getSlot: #cacheMask) bitOr: def dispatchPositions).
295 (obj := gen cloneOf: (gen objectsAt: #MethodDefinitionProto)) `>>
296 [setSlot: #method to: def method.
297 setSlot: #slotAccessor to: (gen generateLiteral: def slotAccessor). ].
298 gen wordAt: 1 * gen bytesPerWord in: obj put: def dispatchPositions.
302 gen@(Generator traits) generateMap: map
304 gen translations at: map ifAbsentPut:
305 [(gen cloneOf: (gen objectsAt: #MapProto)) `>>
306 [setSlot: #flags to: map flags.
307 setSlot: #representative to: (map representative ifNil: [gen objectsAt: #NilObject]).
308 setSlot: #delegates to: (gen cloneOf: (gen objectsAt: #ArrayProto) elements: map delegates).
309 setSlot: #slotCount to: map slotCount.
310 setSlot: #slotTable to: (gen generateSlotTableFor: map).
311 setSlot: #roleTable to: (gen generateRoleTableFor: map). ]]
314 gen@(Generator traits) generateMaps
316 gen objects keysAndValuesDo:
318 inform: ' Adding map for %s', name.
319 gen generateMap: obj bmap]
322 obj@(Object traits) nextOop
323 "Answer the pointer to just beyond this object."
324 [obj oop + (obj wordSize * obj surroundings BytesPerWord)].
326 gen@(Generator traits) assignOops
327 "Assign oops to all of the chunks, accumulating the final oop which is used
328 to set the image size."
330 gen imageSize := gen chunks inject: 0 into:
331 [| :oop :chunk | chunk oop := oop. chunk nextOop]
334 gen@(Generator traits) emitInteger: val on: stream byteSize: byteSize
335 "Takes an integer and outputs the binary data value in the correct byte-order
338 stream next: byteSize putInteger: val &littleEndian: gen littleEndian
341 gen@(Generator traits) emitWord: val on: stream
342 "Takes an integer and outputs the binary data value in the correct byte-order
345 gen emitInteger: val on: stream byteSize: gen bytesPerWord
348 gen@(Generator traits) emitOopOf: chunk on: stream
349 [gen emitWord: chunk oop on: stream].
351 gen@(Generator traits) emitOopOf: _@Nil on: stream
352 [gen emitOopOf: (gen objectsAt: #NilObject) on: stream].
354 gen@(Generator traits) emitOopOf: i@(imports SmallInteger traits) on: stream
355 [gen emitWord: (i << 1 bitOr: 1) on: stream].
357 gen@(Generator traits) emitHeaderOf: obj sized: size payload: payload format: format on: stream
363 [stream nextPut: (2r00000001 bitOr: (hash bitAnd: 16r7F) << 1).
364 stream nextPut: (hash >> 7) intoByte.
365 stream nextPut: (hash >> 15) intoByte.
366 stream nextPut: format << 6.
367 gen emitInteger: 0 on: stream byteSize: gen bytesPerWord - 4]
369 [gen emitInteger: 0 on: stream byteSize: gen bytesPerWord - 4.
370 stream nextPut: (2r10000000 bitOr: (hash >> 16 bitAnd: 16r7F)).
371 stream nextPut: (hash >> 8) intoByte.
372 stream nextPut: hash intoByte.
373 stream nextPut: format].
375 "size in words of slot data"
376 gen emitWord: size on: stream.
377 "size in bytes of payload (oop array or byte array)"
378 gen emitWord: payload on: stream.
381 gen@(Generator traits) emit: obj@(Object traits) on: stream
383 gen emitHeaderOf: obj
388 gen emitWord: (gen translations at: obj bmap) oop on: stream.
390 [| :slotVal | gen emitOopOf: slotVal on: stream].
394 gen@(Generator traits) emit: obj@(OopArray traits) on: stream
396 gen emitHeaderOf: obj
397 sized: obj wordSizeSansPayload
398 payload: obj elements size * gen bytesPerWord
401 gen emitWord: (gen translations at: obj bmap) oop on: stream.
402 obj slotValues ;; obj elements do:
403 [| :slotVal | gen emitOopOf: slotVal on: stream].
407 gen@(Generator traits) emit: obj@(ByteArray traits) on: stream
409 gen emitHeaderOf: obj
410 sized: obj wordSizeSansPayload
411 payload: obj elements size
414 gen emitWord: (gen translations at: obj bmap) oop on: stream.
416 [| :slotVal | gen emitOopOf: slotVal on: stream].
417 stream nextPutAll: obj elements.
418 stream next: (gen bytesPerWord - obj elements size) \\ gen bytesPerWord put: 0.
422 gen@(Generator traits) emitHeaderOn: stream
424 gen emitWord: 16rABCDEF43 on: stream.
425 gen emitWord: gen imageSize on: stream.
426 gen emitWord: gen nextHash on: stream.
427 gen emitWord: ((gen objectsAt: #GlobalsObject) getSlot: #specialOops) oop on: stream.
428 "i shortened dispatch id to one word"
429 gen emitWord: 0 on: stream.
432 gen@(Generator traits) emitOn: stream
433 "Emits a bootstrap image on the stream after it has been generated."
435 inform: 'Assigning oops'.
437 inform: 'Emitting image: %s', stream resource locator.
438 gen emitHeaderOn: stream.
439 gen chunks do: [| :chunk | gen emit: chunk on: stream]
442 gen@(Generator traits) newIdentityHash
444 hash := gen nextHash.
449 gen@(Generator traits) newMap
451 gen surroundings Map clone
454 gen@(Generator traits) newObject &layout: layout &map: map
456 layout `defaultsTo: gen surroundings Object.
457 map `defaultsTo: gen newMap.
458 obj := layout clone `>> [idHash := gen newIdentityHash. bmap := map. ].
459 obj slotValues := obj slotValues newSize: map slotCount.
460 map representative := obj.
461 gen chunks addLast: obj.
465 gen@(Generator traits) cloneOf: proto@(Object traits)
467 gen chunks addLast: proto clone `>>
468 [idHash := gen newIdentityHash. slotValues := proto slotValues copy. ]
471 gen@(Generator traits) cloneOf: arr@(Array traits)
472 [resend `>> [elements := arr elements copy. ]].
474 gen@(Generator traits) cloneOf: proto sized: size
475 [(gen cloneOf: proto) `>> [elements := proto elements newSize: size. ]].
477 gen@(Generator traits) cloneOf: proto elements: elements
478 [(gen cloneOf: proto) `>> [elements := elements as: proto elements. ]].
480 gen@(Generator traits) addAccessorFor: slotName on: obj
481 [| accessor selector |
482 selector := obj accessorNameFor: slotName.
483 (accessor := gen cloneOf: (gen objectsAt: #CompiledMethodProto)) `>>
484 [setSlot: #method to: accessor.
485 setSlot: #selector to: (gen generateLiteral: selector).
486 setSlot: #inputVariables to: 1.
487 setSlot: #localVariables to: 1.
488 setSlot: #registerCount to: 3.
489 setSlot: #literals to: (gen cloneOf: (gen objectsAt: #ArrayProto) elements: {gen generateLiteral: slotName}).
490 setSlot: #selectors to: (gen cloneOf: (gen objectsAt: #ArrayProto) elements: {gen generateLiteral: #atSlotNamed:}).
492 (gen cloneOf: (gen objectsAt: #ArrayProto) elements: {
493 VM SSACode loadVariable. 0.
494 VM SSACode loadLiteral. 1. gen generateLiteral: slotName.
495 VM SSACode directSendMessage. 0. gen generateLiteral: #atSlotNamed:. 2. 0. 1.
496 VM SSACode returnRegister. 0
498 (accessor addMethodNamed: selector on: {obj}) slotAccessor: slotName.
502 gen@(Generator traits) addMutatorFor: slotName on: obj
503 [| mutator selector |
504 selector := obj mutatorNameFor: slotName.
505 (mutator := gen cloneOf: (gen objectsAt: #CompiledMethodProto)) `>>
506 [setSlot: #method to: mutator.
507 setSlot: #selector to: (gen generateLiteral: selector).
508 setSlot: #inputVariables to: 2.
509 setSlot: #localVariables to: 1.
510 setSlot: #registerCount to: 4.
511 setSlot: #literals to: (gen cloneOf: (gen objectsAt: #ArrayProto) elements: {gen generateLiteral: slotName}).
512 setSlot: #selectors to: (gen cloneOf: (gen objectsAt: #ArrayProto) elements: {gen generateLiteral: #atSlotNamed:put:}).
514 (gen cloneOf: (gen objectsAt: #ArrayProto) elements: {
515 VM SSACode loadVariable. 0.
516 VM SSACode loadVariable. 1.
517 VM SSACode loadLiteral. 2. gen generateLiteral: slotName.
518 VM SSACode directSendMessage. 0. gen generateLiteral: #atSlotNamed:put:. 3. 0. 2. 1.
519 VM SSACode returnRegister. 0
521 (mutator addMethodNamed: selector on: {obj. Nil}) slotAccessor: slotName.
525 gen@(Generator traits) addAccessorsFor: slotName on: obj
527 gen addAccessorFor: slotName on: obj.
528 gen addMutatorFor: slotName on: obj
531 gen@(Generator traits) generateKernelAccessors
535 obj bmap slotTable do: [| :slot | gen addAccessorsFor: slot name on: obj]]
538 gen@(Generator traits) generatePrototype: name &suffix: suffix &layout: layout &parents: parents &slots: slotSpecs &elements: elements
539 [| traits window result |
540 suffix `defaultsTo: 'Proto'.
541 traits := (gen objectsAt: (name ; 'Traits') intern := gen newObject)
542 `>> [addDelegateValued: Nil. ].
543 window := (gen objectsAt: (name ; 'Window') intern := gen newObject)
544 `>> [bmap flags := 1. addDelegateValued: Nil. ].
547 [parents reverseDoWithIndex:
549 window addDelegateValued: parent]].
550 window addDelegateValued: traits.
551 result := (gen objectsAt: (name ; suffix) intern := gen newObject &layout: layout)
552 `>> [addDelegateValued: window. ].
554 [(result hasSlotNamed: #elements) ifTrue: [result elements := elements]].
555 (slotSpecs `defaultsTo: {}) do:
556 [| :spec | result makeSlotNamed: spec key valued: spec value].
560 gen@(Generator traits) generateInstance: name of: window
561 [(gen objectsAt: name := gen newObject) `>>
562 [addDelegateValued: window.]
565 gen@(Generator traits) generateKernel
567 gen generatePrototype: 'Root'.
568 gen generatePrototype: 'Oddball' &parents: {gen objectsAt: #RootTraits}.
569 gen generatePrototype: 'Derivable' &parents: {gen objectsAt: #RootTraits}.
570 gen generatePrototype: 'Cloneable' &parents: {gen objectsAt: #DerivableTraits. gen objectsAt: #RootTraits}.
572 gen generateInstance: #NilObject of: (gen objectsAt: #OddballWindow).
573 gen generateInstance: #NoRoleObject of: (gen objectsAt: #OddballWindow).
575 gen generatePrototype: 'Boolean' &parents: {gen objectsAt: #OddballTraits. gen objectsAt: #RootTraits}.
576 gen generateInstance: #TrueObject of: (gen objectsAt: #BooleanWindow).
577 gen generateInstance: #FalseObject of: (gen objectsAt: #BooleanWindow).
579 gen generatePrototype: 'Array' &layout: gen surroundings OopArray
580 &parents: {gen objectsAt: #NilObject. gen objectsAt: #NilObject. gen objectsAt: #NilObject. gen objectsAt: #CloneableTraits. gen objectsAt: #DerivableTraits. gen objectsAt: #RootTraits}
581 &elements: Array new.
582 gen generatePrototype: 'ByteArray' &layout: gen surroundings ByteArray
583 &parents: {gen objectsAt: #NilObject. gen objectsAt: #NilObject. gen objectsAt: #NilObject. gen objectsAt: #CloneableTraits. gen objectsAt: #DerivableTraits. gen objectsAt: #RootTraits}
584 &elements: ByteArray new.
586 gen generatePrototype: 'SmallInteger' &parents: {gen objectsAt: #NilObject. gen objectsAt: #NilObject. gen objectsAt: #NilObject. gen objectsAt: #NilObject. gen objectsAt: #OddballTraits. gen objectsAt: #RootTraits}.
587 (gen generatePrototype: 'Float' &layout: gen surroundings ByteArray
588 &parents: {gen objectsAt: #NilObject. gen objectsAt: #NilObject. gen objectsAt: #NilObject. gen objectsAt: #NilObject. gen objectsAt: #ByteArrayTraits. gen objectsAt: #NilObject. gen objectsAt: #NilObject. gen objectsAt: #NilObject. gen objectsAt: #CloneableTraits. gen objectsAt: #DerivableTraits. gen objectsAt: #RootTraits})
589 `>> [elements := ByteArray newSize: gen bytesPerWord].
591 gen generatePrototype: 'ASCIIString' &layout: gen surroundings ByteArray
592 &parents: {gen objectsAt: #NilObject. gen objectsAt: #ByteArrayTraits. gen objectsAt: #NilObject. gen objectsAt: #NilObject. gen objectsAt: #NilObject. gen objectsAt: #CloneableTraits. gen objectsAt: #DerivableTraits. gen objectsAt: #RootTraits}.
594 gen generatePrototype: 'Symbol' &layout: gen surroundings ByteArray
595 &parents: {gen objectsAt: #ASCIIStringTraits. gen objectsAt: #NilObject. gen objectsAt: #ByteArrayTraits. gen objectsAt: #NilObject. gen objectsAt: #NilObject. gen objectsAt: #NilObject. gen objectsAt: #CloneableTraits. gen objectsAt: #DerivableTraits. gen objectsAt: #RootTraits}
596 &slots: {#cacheMask -> 0}.
598 gen symbols at: #'' put: (gen objectsAt: #SymbolProto).
600 gen generatePrototype: 'ASCIICharacter'
601 &parents: {gen objectsAt: #NilObject. gen objectsAt: #OddballTraits. gen objectsAt: #RootTraits} &slots: {#code -> 0}.
602 gen characters at: 0 put: (gen objectsAt: #ASCIICharacterProto).
603 1 below: gen characters size do:
605 c := gen cloneOf: (gen objectsAt: #ASCIICharacterProto).
606 c setSlot: #code to: index.
607 gen characters at: index put: c].
608 (gen objectsAt: #ASCIIStringTraits) makeSlotNamed: #Character valued: (gen objectsAt: #ASCIICharacterProto).
610 gen generatePrototype: 'Namespace'
611 &parents: {gen objectsAt: #CloneableTraits. gen objectsAt: #DerivableTraits. gen objectsAt: #RootTraits}.
612 gen generateInstance: #BootstrapObject of: (gen objectsAt: #NamespaceWindow).
614 gen generatePrototype: 'Method' &parents: {gen objectsAt: #CloneableTraits. gen objectsAt: #DerivableTraits. gen objectsAt: #RootTraits}.
616 gen generatePrototype: 'PrimitiveMethod'
617 &parents: {gen objectsAt: #MethodTraits. gen objectsAt: #CloneableTraits. gen objectsAt: #DerivableTraits. gen objectsAt: #RootTraits}
618 &slots: {#index -> 0. #selector -> (gen objectsAt: #NilObject). #inputVariables -> 0}.
620 gen generatePrototype: 'CompiledMethod'
621 &parents: {gen objectsAt: #MethodTraits. gen objectsAt: #CloneableTraits. gen objectsAt: #DerivableTraits. gen objectsAt: #RootTraits}
623 #method -> (gen objectsAt: #NilObject).
624 #selector -> (gen objectsAt: #NilObject).
625 #inputVariables -> 0. #localVariables -> 0.
626 #restVariable -> (gen objectsAt: #FalseObject).
627 #optionalKeywords -> (gen objectsAt: #ArrayProto).
628 #heapAllocate -> (gen objectsAt: #FalseObject).
629 #environment -> (gen objectsAt: #BootstrapObject).
630 #literals -> (gen objectsAt: #ArrayProto).
631 #selectors -> (gen objectsAt: #ArrayProto).
632 #code -> (gen objectsAt: #ArrayProto).
633 #sourceTree -> (gen objectsAt: #NilObject).
634 #debugMap -> (gen objectsAt: #ArrayProto).
635 #isInlined -> (gen objectsAt: #FalseObject).
636 #oldCode -> (gen objectsAt: #NilObject).
638 #calleeCount -> (gen objectsAt: #NilObject).
640 #cachedInCallers -> (gen objectsAt: #NilObject).
641 #cachedInCallersCount -> 0.
642 #nextInlineAtCallCount -> (gen objectsAt: #NilObject).
643 #reserved5 -> (gen objectsAt: #NilObject).
646 gen generatePrototype: 'Closure' &layout: gen surroundings OopArray
647 &parents: {gen objectsAt: #MethodTraits. gen objectsAt: #ArrayTraits. gen objectsAt: #NilObject. gen objectsAt: #NilObject. gen objectsAt: #NilObject. gen objectsAt: #CloneableTraits. gen objectsAt: #DerivableTraits. gen objectsAt: #RootTraits}
648 &slots: {#method -> (gen objectsAt: #NilObject)}.
650 gen generatePrototype: 'MethodDefinition' &layout: gen surroundings ByteArray
651 &parents: {gen objectsAt: #CloneableTraits. gen objectsAt: #DerivableTraits. gen objectsAt: #RootTraits}
653 #method -> (gen objectsAt: #CompiledMethodProto).
654 #slotAccessor -> (gen objectsAt: #NilObject)}
655 &elements: (ByteArray newSize: 4 * gen bytesPerWord).
657 gen generatePrototype: 'Map' &layout: gen surroundings ByteArray
658 &parents: {gen objectsAt: #CloneableTraits. gen objectsAt: #DerivableTraits. gen objectsAt: #RootTraits}
661 #representative -> (gen objectsAt: #NilObject).
662 #delegates -> (gen objectsAt: #ArrayProto).
664 #slotTable -> (gen objectsAt: #ArrayProto).
665 #roleTable -> (gen objectsAt: #ArrayProto)}
666 &elements: (ByteArray newSize: 3 * gen bytesPerWord).
668 gen generatePrototype: 'LexicalContext' &layout: gen surroundings OopArray
669 &parents: {gen objectsAt: #ArrayTraits. gen objectsAt: #NilObject. gen objectsAt: #NilObject. gen objectsAt: #NilObject. gen objectsAt: #CloneableTraits. gen objectsAt: #DerivableTraits. gen objectsAt: #RootTraits}
670 &slots: {#framePointer -> 0}.
672 gen generatePrototype: 'Interpreter' &layout: gen surroundings ByteArray
673 &parents: {gen objectsAt: #CloneableTraits. gen objectsAt: #DerivableTraits. gen objectsAt: #RootTraits}
675 #stack -> (gen objectsAt: #ArrayProto).
676 #method -> (gen objectsAt: #NilObject).
677 #closure -> (gen objectsAt: #NilObject).
678 #lexicalContext -> (gen objectsAt: #NilObject).
679 #ensureHandlers -> 0}
680 &elements: (ByteArray newSize: 5 * gen bytesPerWord).
682 (gen objectsAt: #EnsureMarkerObject := gen cloneOf: (gen objectsAt: #CompiledMethodProto)) `>>
684 setSlot: #method to: marker.
686 (gen cloneOf: (gen objectsAt: #ArrayProto)
687 elements: {VM SSACode resume})].
690 Generator traits define: #Compiler &parents: {VM SSACompiler} &slots: {
694 c@(Generator Compiler traits) newFor: gen
697 result generator := gen.
701 c@(Generator Compiler traits) branchTableHash: key
703 ((literal ::= c generator generateLiteral: key) isSameAs: SmallInteger)
705 ifFalse: [literal idHash]
708 gen@(Generator traits) generateInterpreterBooting: method
710 compiler ::= gen Compiler newFor: gen.
711 inform: 'Compiling bootstrap source into VM instructions.'.
713 methodCompiled ::= (compiler generate: method result: Nil &topLevel: True)
714 `>> [heapAllocate := False. ].
716 "compiler decompile: method code."
718 methodLiteral ::= gen generateLiteral: methodCompiled.
720 stackSize := 16. "if you change this, change vm.c which has it hard-coded in the beginning of interpret()"
722 stackObj ::= (gen cloneOf: (gen objectsAt: #ArrayProto) sized: stackSize) `>>
723 [elements at: 0 put: 0. "-6: prev sp"
724 elements at: 1 put: -1. "-5: resultStackPointer"
725 elements at: 2 put: 0. "-4: code pointer"
726 elements at: 3 put: methodLiteral. "-3: closure"
727 elements at: 4 put: 0. "-2: lexical context"
728 elements at: 5 put: 0. "-1: prev fp"
729 elements at: 6 put: 0. ].
731 codeSize ::= methodCompiled code size.
733 (interpreter ::= gen objectsAt: #InterpreterObject := gen cloneOf: (gen objectsAt: #InterpreterProto)) `>>
734 [setSlot: #stack to: stackObj.
735 setSlot: #method to: methodLiteral.
736 setSlot: #closure to: methodLiteral. ].
737 gen wordAt: 0 * gen bytesPerWord in: interpreter put: 6. " frame pointer (framesize=6)"
738 "long at 1 is code pointer -- I guess this gets filled later or is zero"
739 gen wordAt: 2 * gen bytesPerWord in: interpreter put: codeSize.
740 gen wordAt: 3 * gen bytesPerWord in: interpreter put: 6. "stack pointer (framesize=6)"
741 gen wordAt: 4 * gen bytesPerWord in: interpreter put: stackSize
744 gen@(Generator traits) generateUtilities
746 gen generateInstance: #ConsoleObject of: (gen objectsAt: #OddballWindow).
748 gen generatePrototype: 'File' &parents: {
749 gen objectsAt: #NilObject.
750 gen objectsAt: #CloneableTraits.
751 gen objectsAt: #DerivableTraits.
752 gen objectsAt: #RootTraits
754 gen generatePrototype: 'Directory' &parents: {
755 gen objectsAt: #NilObject.
756 gen objectsAt: #CloneableTraits.
757 gen objectsAt: #DerivableTraits.
758 gen objectsAt: #RootTraits
760 gen generatePrototype: 'ExternalLibrary' &parents: {
761 gen objectsAt: #NilObject.
762 gen objectsAt: #CloneableTraits.
763 gen objectsAt: #DerivableTraits.
764 gen objectsAt: #RootTraits
768 gen@(Generator traits) generateBootstrapNamespace
770 gen objectsAt: #PrototypesObject := gen cloneOf: (gen objectsAt: #NamespaceProto).
771 (gen objectsAt: #BootstrapObject) addDelegateValued: (gen objectsAt: #PrototypesObject).
772 "timmy: no named delegate slots but name needed for accessor"
773 (gen objectsAt: #BootstrapObject) makeSlotNamed: #prototypes valued: (gen objectsAt: #PrototypesObject).
774 gen addAccessorFor: #prototypes on: (gen objectsAt: #BootstrapObject).
775 "Install slots/accessors in the 'prototypes' namespace,
776 set up traits traits, and set up printName. Make sure all bootstrapped protos
777 are listed here, otherwise these important steps are left out for them."
778 [| :slotName :objectName obj printNameLiteral window traits |
779 obj := gen objectsAt: objectName.
780 (gen objectsAt: #PrototypesObject) makeSlotNamed: slotName valued: obj.
781 gen addAccessorFor: slotName on: (gen objectsAt: #PrototypesObject).
782 window := obj bmap delegates first.
783 window bmap delegates at: 0 put: (gen objectsAt: #CloneableWindow).
784 traits := window bmap delegates last"(window getSlot: #traits)".
785 traits bmap delegates at: 0 put: (gen objectsAt: #CloneableWindow).
786 printNameLiteral := gen generateLiteral: slotName name.
787 traits makeSlotNamed: #printNameTraits valued: printNameLiteral.
788 gen addAccessorFor: #printNameTraits on: traits.
789 window makeSlotNamed: #printNameWindow valued: printNameLiteral.
790 gen addAccessorFor: #printNameWindow on: window
793 {#Oddball. #OddballProto}.
794 {#Cloneable. #CloneableProto}.
795 {#Derivable. #DerivableProto}.
796 {#Namespace. #NamespaceProto}.
797 {#Boolean. #BooleanProto}.
798 {#Array. #ArrayProto}.
799 {#ByteArray. #ByteArrayProto}.
800 {#ASCIIString. #ASCIIStringProto}.
801 {#ASCIICharacter. #ASCIICharacterProto}.
802 {#Symbol. #SymbolProto}.
803 {#SmallInteger. #SmallIntegerProto}.
804 {#SingleFloat. #FloatProto}.
806 {#LexicalContext. #LexicalContextProto}.
807 {#MethodDefinition. #MethodDefinitionProto}.
808 {#Method. #MethodProto}.
809 {#PrimitiveMethod. #PrimitiveMethodProto}.
810 {#CompiledMethod. #CompiledMethodProto}.
811 {#Closure. #ClosureProto}.
812 {#Interpreter. #InterpreterProto}.
814 {#Directory. #DirectoryProto}.
815 {#ExternalLibrary. #ExternalLibraryProto}
818 gen objectsAt: #GlobalsObject := gen cloneOf: (gen objectsAt: #NamespaceProto).
819 (gen objectsAt: #BootstrapObject) addDelegateValued: (gen objectsAt: #GlobalsObject).
820 (gen objectsAt: #BootstrapObject) makeSlotNamed: #globals valued: (gen objectsAt: #GlobalsObject).
821 gen addAccessorFor: #globals on: (gen objectsAt: #BootstrapObject).
823 (gen objectsAt: #GlobalsObject) makeSlotNamed: key valued: value.
824 gen addAccessorFor: key on: (gen objectsAt: #GlobalsObject)] applier for: {
825 {#Console. gen objectsAt: #ConsoleObject}.
826 {#NoRole. gen objectsAt: #NoRoleObject}.
827 {#Nil. gen objectsAt: #NilObject}.
828 {#True. gen objectsAt: #TrueObject}.
829 {#False. gen objectsAt: #FalseObject}.
830 {#lobby. gen objectsAt: #BootstrapObject}.
831 {#bootstrapCharacters. gen cloneOf: (gen objectsAt: #ArrayProto) elements: gen characters}.
832 {#Symbols. gen objectsAt: #ArrayProto}.
833 {#bootstrapInterpreter. gen objectsAt: #InterpreterObject}.
834 {#ensureMarker. gen objectsAt: #EnsureMarkerObject}.
835 {#specialOops. gen objectsAt: #ArrayProto}.
836 {#features. gen objectsAt: #ArrayProto}.
838 gen addMutatorFor: #features on: (gen objectsAt: #GlobalsObject)
841 gen@(Generator traits) generateLinkage
842 "TODO: The order in this method must be the same as in memory.slate, enforce it"
844 (gen objectsAt: #GlobalsObject) setSlot: #specialOops to:
845 (gen cloneOf: (gen objectsAt: #ArrayProto) elements:
855 #MethodDefinitionProto.
859 #CompiledMethodWindow.
860 #PrimitiveMethodWindow.
862 #LexicalContextProto.
865 } collect: #(gen objectsAt: _) `er)
881 #badTypeError} collect: #(gen generateLiteral: _) `er)).
882 (gen objectsAt: #GlobalsObject) setSlot: #Symbols to:
883 (gen cloneOf: (gen objectsAt: #ArrayProto) elements: gen symbols valueSet).
886 gen@(Generator traits) generatePrimitive: prim at: index
887 "Given a MethodDefinition representing a Pidgin primitive definition,
888 this defines a PrimitiveMethod stub that will invoke the given primitive
889 index. Must be called after generateImageBooting:."
891 (gen cloneOf: (gen objectsAt: #PrimitiveMethodProto)) `>>
892 [setSlot: #selector to: (gen generateLiteral: prim selector).
893 setSlot: #inputVariables to: prim roles size.
894 setSlot: #index to: index.
895 addMethodNamed: prim selector on:
898 (role isSameAs: nodes UnaryMessage) ifTrue:
899 [inform: ' Adding primitive %s to %s', index, role selector.
900 gen objectsAt: role selector]]) ]
903 gen@(Generator traits) generateLiteral: literal
906 ifTrue: [gen objectsAt: #NoRoleObject]
907 ifFalse: [error: 'Unsupported literal.']
910 gen@(Generator traits) generateLiteral: i@(imports SmallInteger traits)
913 gen@(Generator traits) generateLiteral: _@(imports BigInteger traits)
915 error: 'The bootstrap generator does not support big integers.'
918 gen@(Generator traits) generateLiteral: _@True
919 [gen objectsAt: #TrueObject].
921 gen@(Generator traits) generateLiteral: _@False
922 [gen objectsAt: #FalseObject].
924 gen@(Generator traits) generateLiteral: _@Nil
925 [gen objectsAt: #NilObject].
927 gen@(Generator traits) generateLiteral: _@lobby
928 [gen objectsAt: #BootstrapObject].
930 gen@(Generator traits) generateLiteral: s@(imports ASCIIString traits)
933 ifTrue: [gen objectsAt: #ASCIIStringProto]
934 ifFalse: [gen cloneOf: (gen objectsAt: #ASCIIStringProto) elements:
935 (s collect: #code`er into: (ByteArray newSizeOf: s))]
938 gen@(Generator traits) generateLiteral: s@(imports Symbol traits)
940 gen symbols at: s ifAbsentPut:
941 [gen cloneOf: (gen objectsAt: #SymbolProto) elements:
942 (s name collect: #code`er into: (ByteArray newSizeOf: s name))]
945 gen@(Generator traits) generateLiteral: f@(imports SingleFloat traits)
947 obj := gen cloneOf: (gen objectsAt: #FloatProto) elements: (ByteArray newWithAll: f).
948 gen littleEndian = -1.0 isLittleEndian
949 ifFalse: [obj elements := obj elements reversed].
953 gen@(Generator traits) generateLiteral: a@(imports ByteArray traits)
956 ifTrue: [gen objectsAt: #ByteArrayProto]
957 ifFalse: [gen cloneOf: (gen objectsAt: #ByteArrayProto) elements: a]
960 gen@(Generator traits) generateLiteral: a@(imports Array traits)
963 ifTrue: [gen objectsAt: #ArrayProto]
964 ifFalse: [gen cloneOf: (gen objectsAt: #ArrayProto) elements:
965 (a collect: #(gen generateLiteral: _) `er)]
968 gen@(Generator traits) generateLiteral: c@(imports ASCIIString Character traits)
970 gen characters at: c code
973 gen@(Generator traits) generateLiteral: block@(imports CompiledMethod traits)
975 obj := (gen cloneOf: (gen objectsAt: #CompiledMethodProto)) `>>
977 setSlot: #inputVariables to: block inputVariables.
978 setSlot: #localVariables to: block localVariables.
979 setSlot: #restVariable to: (gen generateLiteral: block restVariable).
980 setSlot: #heapAllocate to: (gen generateLiteral: block heapAllocate).
981 setSlot: #literals to: (gen generateLiteral: block literals).
982 setSlot: #registerCount to: (gen generateLiteral: block registerCount).
983 setSlot: #selectors to: (gen generateLiteral: block selectors).
984 setSlot: #code to: (gen generateLiteral: block code).
985 setSlot: #method to: obj. ].
986 block optionalKeywords isEmpty ifFalse:
987 [obj setSlot: #optionalKeywords to: (gen generateLiteral: block optionalKeywords)].