<div id="__MailbirdStyleContent" style="font-size: 10pt;font-family: Arial;color: #000000;text-align: left" dir="ltr">
                                        Hi Eliot --<div><br></div><div>This means that we would have to change the Squeak 6.0 image again for the next VM release? Okay ... we should make sure that #primitiveScreenScaleFactor MUST ALWAYS answer 1.0 when <span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">upscaleDisplayIfHighDPI is true</span>...</div><div><br></div><div>> [...] <span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">then VMs are expected to upscale the display on high DPI displays as they have in the past.</span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px"><br></span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">Still not correct. Only (!) the --metal backend on macOS did that in the past. All other cases and platforms relied on the platform to do the scaling. The VM had nothing to do with it. Potato potato... =D</span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px"><br></span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">Best,</span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">Marcel</span></div><div class="mb_sig"></div>
                                        <blockquote class="history_container" type="cite" style="border-left-style: solid;border-width: 1px;margin-top: 20px;margin-left: 0px;padding-left: 10px;min-width: 500px">
                        <p style="color: #AAAAAA; margin-top: 10px;">Am 21.06.2022 02:38:37 schrieb commits@source.squeak.org <commits@source.squeak.org>:</p><div style="font-family:Arial,Helvetica,sans-serif"> <br>Eliot Miranda uploaded a new version of VMMaker to project VM Maker:<br>http://source.squeak.org/VMMaker/VMMaker.oscog-eem.3194.mcz<br><br>==================== Summary ====================<br><br>Name: VMMaker.oscog-eem.3194<br>Author: eem<br>Time: 20 June 2022, 5:37:47.097263 pm<br>UUID: b977319b-9026-4c13-afff-8f5515732e4f<br>Ancestors: VMMaker.oscog-eem.3193<br><br>Add the upscaleDisplayIfHighDPI flag to the VM.  This is true by default.  It is controlled by bit 8 of the Persistent image header flags, accessed via vmParameterAt: 48 [put:...].<br><br>When this flag is true (i.e. when the image header flag bit is unset) then VMs are expected to upscale the display on high DPI displays as they have in the past.  When this flag is false (i.e. when the image header flag bit is set) the VM is expected not to upscale, leaving it to the image to do so.<br><br>This flag is present to enable new VMs to allow the image to do its own scaling while keeping on scaling older images unaware of the option.<br><br>=============== Diff against VMMaker.oscog-eem.3193 ===============<br><br>Item was changed:<br>  ----- Method: CoInterpreter>>getImageHeaderFlags (in category 'image save/restore') -----<br>  getImageHeaderFlags<br>      "Answer the flags that are contained in the 7th long of the image header."<br>          ^fullScreenFlag "0 or 1"<br>    + (VMBIGENDIAN ifTrue: [0] ifFalse: [2]) "this is the imageFloatsLittleEndian flag"<br>         + (flagInterpretedMethods ifTrue: [8] ifFalse: [0])<br>   + (preemptionYields ifTrue: [0] ifFalse: [16r10])<br>     + (newFinalization ifTrue: [16r40] ifFalse: [0])<br>      + (sendWheelEvents ifTrue: [16r80] ifFalse: [0])<br>      + (primitiveDoMixedArithmetic ifTrue: [0] ifFalse: [16r100])<br>+         "N.B. flag mask 16r200 is fileTimesInUTC, responded to by the FIlePlugin & FileAttributesPlugin"<br>+       + (upscaleDisplayIfHighDPI ifTrue: [0] ifFalse: [16r400])<br>+    + (imageHeaderFlags bitClear: 1+2+8+16r10+16r40+16r80+16r100+16r200+16r400) "these are any flags we do not recognize"!<br>-     + (imageHeaderFlags bitClear: 1+2+8+16r10+16r40+16r80+16r100) "these are any flags we do not recognize"!<br><br>Item was changed:<br>  ----- Method: CoInterpreter>>setImageHeaderFlags: (in category 'internal interpreter access') -----<br>  setImageHeaderFlags: flags<br>    "Set an array of flags indicating various properties of the saved image, responded to on image load.<br>      These are the same as the image header flags shifted right two bits, omitting the fullScreenFlag and float byte order flag.<br>           Bit 0: if set, implies the image's Process class has threadId as its 3rd inst var (zero relative) (meaningful to the MT VM only)<br>      Bit 1: if set, methods that are interpreted will have the flag bit set in their header<br>        Bit 2: if set, implies preempting a process does not put it to the back of its run queue<br>      Bit 3: if set, implies a threaded VM will not disown the VM if owned by the GUI thread (meaningful to the MT VM only)<br>         Bit 4: if set, implies the new finalization scheme where WeakArrays are queued<br>        Bit 5: if set, implies wheel events will be delivered as such and not mapped to arrow key events<br>      Bit 6: if set, implies arithmetic primitives will fail if given arguments of different types (float vs int)<br>+          Bit 7: if set, implies file primitives (FilePlugin, FileAttributesPlugin) will answer file times in UTC not local times<br>+      Bit 8: if set, implies the VM will not upscale the display on high DPI monitors; older VMs did this by default.<br>+      Bit 8: if set, implies the VM will not upscale the display on high DPI devices"<br>+        flags asUnsignedInteger > 511 ifTrue:<br>-      Bit 7: if set, implies file primitives (FilePlugin, FileAttributesPlugin) will answer file times in UTC not local times"<br>-       flags asUnsignedInteger > 255 ifTrue:<br>              [^self primitiveFailFor: PrimErrUnsupported].<br>         "processHasThreadId := flags anyMask: 1. specific to CoInterpreterMT"<br>       imageHeaderFlags := (flags anyMask: 1)<br>                                                        ifTrue: [imageHeaderFlags bitOr: 4]<br>                                                   ifFalse: [imageHeaderFlags bitClear: 4].<br>      flagInterpretedMethods := flags anyMask: 2.<br>   preemptionYields := flags noMask: 4.<br>          "noThreadingOfGUIThread := flags anyMask: 8.. specific to CoInterpreterMT"<br>          imageHeaderFlags := (flags anyMask: 8)<br>                                                        ifTrue: [imageHeaderFlags bitOr: 32]<br>                                                          ifFalse: [imageHeaderFlags bitClear: 32].<br>     newFinalization := flags anyMask: 16.<br>         sendWheelEvents := flags anyMask: 32.<br>         primitiveDoMixedArithmetic := flags noMask: 64.<br>       imageHeaderFlags := (flags anyMask: 128)<br>                                                      ifTrue: [imageHeaderFlags bitOr: 512]<br>+                                                        ifFalse: [imageHeaderFlags bitClear: 512].<br>+   upscaleDisplayIfHighDPI := flags noMask: 256!<br>-                                                        ifFalse: [imageHeaderFlags bitClear: 512]!<br><br>Item was changed:<br>  ----- Method: CoInterpreter>>setImageHeaderFlagsFrom: (in category 'image save/restore') -----<br>  setImageHeaderFlagsFrom: headerFlags<br>       "Set the flags that are contained in the 7th long of the image header."<br>     imageHeaderFlags := headerFlags. "so as to preserve unrecognised flags."<br>    fullScreenFlag := headerFlags bitAnd: 1.<br>      imageFloatsBigEndian := (headerFlags noMask: 2) ifTrue: [1] ifFalse: [0].<br>     "processHasThreadId := headerFlags anyMask: 4. specific to CoInterpreterMT"<br>         flagInterpretedMethods := headerFlags anyMask: 8.<br>     preemptionYields := headerFlags noMask: 16.<br>   "noThreadingOfGUIThread := headerFlags anyMask: 32. specific to CoInterpreterMT"<br>    newFinalization := headerFlags anyMask: 64.<br>   sendWheelEvents := headerFlags anyMask: 128.<br>+         primitiveDoMixedArithmetic := headerFlags noMask: 256.<br>+       "N.B. flag mask 512 is responded to by the FIlePlugin & FileAttributesPlugin"<br>+  upscaleDisplayIfHighDPI := headerFlags noMask: 1024!<br>-         primitiveDoMixedArithmetic := headerFlags noMask: 256!<br><br>Item was changed:<br>  ----- Method: CoInterpreterMT>>getImageHeaderFlags (in category 'image save/restore') -----<br>  getImageHeaderFlags<br>       "Answer the flags that are contained in the 7th long of the image header."<br>          ^fullScreenFlag "0 or 1"<br>    + (VMBIGENDIAN ifTrue: [0] ifFalse: [2]) "this is the imageFloatsLittleEndian flag"<br>         + (processHasThreadId ifTrue: [4] ifFalse: [0])<br>       + (flagInterpretedMethods ifTrue: [8] ifFalse: [0])<br>   + (preemptionYields ifTrue: [0] ifFalse: [16r10])<br>     "was: noThreadingOfGUIThread ifTrue: [16r20] ifFalse: [0]); a broken idea"<br>          + (newFinalization ifTrue: [16r40] ifFalse: [0])<br>      + (sendWheelEvents ifTrue: [16r80] ifFalse: [0])<br>      + (primitiveDoMixedArithmetic ifTrue: [0] ifFalse: [16r100])<br>+         "N.B. flag mask 16r200 is fileTimesInUTC, responded to by the FIlePlugin & FileAttributesPlugin"<br>+       + (upscaleDisplayIfHighDPI ifTrue: [0] ifFalse: [16r400])<br>+    + (imageHeaderFlags bitClear: 16r7FF) "these are any flags we do not recognize"!<br>-   + (imageHeaderFlags bitClear: 16r1FF) "these are any flags we do not recognize"!<br><br>Item was changed:<br>  ----- Method: CoInterpreterMT>>setImageHeaderFlags: (in category 'internal interpreter access') -----<br>  setImageHeaderFlags: flags<br>          "Set an array of flags indicating various properties of the saved image, responded to on image load.<br>      These are the same as the image header flags shifted right two bits, omitting the fullScreenFlag and float byte order flag.<br>           Bit 0: if set, implies the image's Process class has threadId as its 3rd inst var (zero relative)<br>     Bit 1: if set, methods that are interpreted will have the flag bit set in their header<br>        Bit 2: if set, implies preempting a process does not put it to the back of its run queue<br>      Bit 3: unassigned; used to mean if set, implies a threaded VM will not disown the VM if owned by the GUI thread; a broken idea<br>        Bit 4: if set, implies the new finalization scheme where WeakArrays are queued<br>        Bit 5: if set, implies wheel events will be delivered as such and not mapped to arrow key events<br>      Bit 6: if set, implies arithmetic primitives will fail if given arguments of different types (float vs int)<br>+          Bit 7: if set, implies file primitives (FilePlugin, FileAttributesPlugin) will answer file times in UTC not local times<br>+      Bit 8: if set, implies the VM will not upscale the display on high DPI devices"<br>+        flags asUnsignedInteger > 511 ifTrue:<br>-      Bit 7: if set, implies file primitives (FilePlugin, FileAttributesPlugin) will answer file times in UTC not local times"<br>-       flags asUnsignedInteger > 255 ifTrue:<br>              [^self primitiveFailFor: PrimErrUnsupported].<br>         (flags anyMask: 8) ifTrue:<br>            [^self primitiveFailFor: PrimErrInappropriate].<br>       processHasThreadId := flags anyMask: 1.<br>       flagInterpretedMethods := flags anyMask: 2.<br>   preemptionYields := flags noMask: 4.<br>          "was: noThreadingOfGUIThread := flags anyMask: 8. a broken idea"<br>    newFinalization := flags anyMask: 16.<br>         sendWheelEvents := flags anyMask: 32.<br>         primitiveDoMixedArithmetic := flags noMask: 64.<br>       imageHeaderFlags := (flags anyMask: 128)<br>                                                      ifTrue: [imageHeaderFlags bitOr: 512]<br>+                                                        ifFalse: [imageHeaderFlags bitClear: 512].<br>+   upscaleDisplayIfHighDPI := flags noMask: 256!<br>-                                                        ifFalse: [imageHeaderFlags bitClear: 512]!<br><br>Item was changed:<br>  ----- Method: CoInterpreterMT>>setImageHeaderFlagsFrom: (in category 'image save/restore') -----<br>  setImageHeaderFlagsFrom: headerFlags<br>     "Set the flags that are contained in the 7th long of the image header."<br>     imageHeaderFlags := headerFlags. "so as to preserve unrecognised flags."<br>    fullScreenFlag := headerFlags bitAnd: 1.<br>      imageFloatsBigEndian := (headerFlags noMask: 2) ifTrue: [1] ifFalse: [0].<br>     processHasThreadId := headerFlags anyMask: 4.<br>         flagInterpretedMethods := headerFlags anyMask: 8.<br>     preemptionYields := headerFlags noMask: 16.<br>   "was: noThreadingOfGUIThread := headerFlags anyMask: 32. a broken idea"<br>     newFinalization := headerFlags anyMask: 64.<br>   sendWheelEvents := headerFlags anyMask: 128.<br>          primitiveDoMixedArithmetic := headerFlags noMask: 256.<br>+       "N.B. flag mask 512 is responded to by the FIlePlugin & FileAttributesPlugin"<br>+  upscaleDisplayIfHighDPI := headerFlags noMask: 1024.<br>  <br>      processHasThreadId ifFalse:<br>           [self print: 'warning, processHasThreadId flag is unset; cannot function as a threaded VM if so.'; cr]!<br><br>Item was changed:<br>  InterpreterPrimitives subclass: #StackInterpreter<br>(excessive size, no diff calculated)<br><br>Item was changed:<br>  ----- Method: StackInterpreter class>>declareCVarsIn: (in category 'translation') -----<br>  declareCVarsIn: aCCodeGenerator<br>      | vmClass |<br>   self class == thisContext methodClass ifFalse: [^self]. "Don't duplicate decls in subclasses"<br>       vmClass := aCCodeGenerator vmClass. "Generate primitiveTable etc based on vmClass, not just StackInterpreter"<br>       aCCodeGenerator<br>               addHeaderFile: '<stdio.h> /* for printf */';<br>            addHeaderFile: '<stdlib.h> /* for e.g. alloca */';<br>              addHeaderFile: '<setjmp.h>';<br>            addHeaderFile: '<wchar.h> /* for wint_t */';<br>            addHeaderFile: '"vmCallback.h"';<br>            addHeaderFile: '"sqMemoryFence.h"';<br>                 addHeaderFile: '"sqImageFileAccess.h"';<br>             addHeaderFile: '"sqSetjmpShim.h"';<br>                  addHeaderFile: '"dispdbg.h"'.<br>       LowcodeVM ifTrue:<br>             [aCCodeGenerator addHeaderFile: '"sqLowcodeFFI.h"'].<br>  <br>    vmClass declareInterpreterVersionIn: aCCodeGenerator defaultName: 'Stack'.<br>+   #('primitiveDoMixedArithmetic' 'upscaleDisplayIfHighDPI' ) do:<br>+                [:var|<br>+              aCCodeGenerator<br>+                      var: var<br>+                     declareC: 'sqInt ', var, ' = true'].<br>          aCCodeGenerator<br>               var: #interpreterProxy  type: #'struct VirtualMachine*'.<br>      aCCodeGenerator<br>               declareVar: #sendTrace type: 'volatile int';<br>                  declareVar: #byteCount type: #usqLong. "see dispdbg.h"<br>      "These need to be pointers or unsigned."<br>    self declareC: #(instructionPointer method newMethod)<br>                 as: #usqInt<br>           in: aCCodeGenerator.<br>          "These are all pointers; char * because Slang has no support for C pointer arithmetic."<br>     self declareC: #(localIP localSP localFP stackPointer framePointer stackLimit breakSelector)<br>                  as: #'char *'<br>                 in: aCCodeGenerator.<br>          aCCodeGenerator<br>               var: #breakSelectorLength<br>             declareC: 'sqInt breakSelectorLength = MinSmallInteger'.<br>      self declareC: #(stackPage overflowedPage)<br>            as: #'StackPage *'<br>            in: aCCodeGenerator.<br>          aCCodeGenerator<br>               var: #transcript type: #'FILE *'.<br>     aCCodeGenerator removeVariable: 'stackPages'.  "this is an implicit receiver in the translated code."<br>       "This defines bytecodeSetSelector as 0 if MULTIPLEBYTECODESETS<br>    is not defined, for the benefit of the interpreter on slow machines."<br>   aCCodeGenerator addConstantForBinding: (self bindingOf: #MULTIPLEBYTECODESETS).<br>       MULTIPLEBYTECODESETS == false ifTrue:<br>                 [aCCodeGenerator<br>                      removeVariable: 'bytecodeSetSelector'].<br>       BytecodeSetHasExtensions == false ifTrue:<br>             [aCCodeGenerator<br>                      removeVariable: 'extA';<br>                       removeVariable: 'extB'].<br>      aCCodeGenerator<br>               var: #methodCache<br>             declareC: 'sqIntptr_t methodCache[MethodCacheSize + 1 /* ', (MethodCacheSize + 1) printString, ' */]'.<br>        NewspeakVM<br>            ifTrue:<br>                       [aCCodeGenerator<br>                              var: #nsMethodCache<br>                           declareC: 'sqIntptr_t nsMethodCache[NSMethodCacheSize + 1 /* ', (NSMethodCacheSize + 1) printString, ' */]']<br>                  ifFalse:<br>                      [aCCodeGenerator<br>                              removeVariable: #nsMethodCache;<br>                               removeVariable: 'localAbsentReceiver';<br>                                removeVariable: 'localAbsentReceiverOrZero'].<br>         AtCacheTotalSize isInteger ifTrue:<br>            [aCCodeGenerator<br>                      var: #atCache<br>                         declareC: 'sqInt atCache[AtCacheTotalSize + 1 /* ', (AtCacheTotalSize + 1) printString, ' */]'].<br>      aCCodeGenerator<br>               var: #primitiveTable<br>                  declareC: 'void (*primitiveTable[MaxPrimitiveIndex + 2 /* ', (MaxPrimitiveIndex + 2) printString, ' */])(void) = ', vmClass primitiveTableString.<br>     vmClass primitiveTable do:<br>            [:symbolOrNot|<br>                (symbolOrNot isSymbol<br>                  and: [symbolOrNot ~~ #primitiveFail]) ifTrue:<br>                        [(aCCodeGenerator methodNamed: symbolOrNot) ifNotNil:<br>                                 [:tMethod| tMethod returnType: #void]]].<br>  <br>          vmClass objectMemoryClass hasSpurMemoryManagerAPI<br>             ifTrue:<br>                       [aCCodeGenerator<br>                              var: #primitiveAccessorDepthTable<br>                             type: 'signed char'<br>                           sizeString: 'MaxPrimitiveIndex + 2 /* ', (MaxPrimitiveIndex + 2) printString, ' */'<br>                           array: (vmClass primitiveAccessorDepthTableUsing: aCCodeGenerator).<br>                    aCCodeGenerator<br>                              removeConstant: #PrimNumberInstVarAt;<br>                                 removeConstant: #PrimNumberPerform;<br>                           removeConstant: # PrimNumberPerformWithArgs;<br>                                  removeConstant: #PrimNumberShallowCopy;<br>                               removeConstant: #PrimNumberSlotAt;<br>                            removeConstant: #PrimNumberFlushExternalPrimitives;<br>                           removeConstant: #PrimNumberUnloadModule]<br>              ifFalse:<br>                      [aCCodeGenerator<br>                              removeVariable: #primitiveAccessorDepthTable;<br>                                 removeConstant: #PrimNumberVMParameter].<br>  <br>          aCCodeGenerator<br>               var: #displayBits type: #'void *';<br>            var: #primitiveCalloutPointer declareC: 'void *primitiveCalloutPointer = (void *)-1'.<br>         self declareC: #(displayWidth displayHeight displayDepth) as: #int in: aCCodeGenerator.<br>       aCCodeGenerator<br>               var: #primitiveFunctionPointer<br>                        declareC: 'void (*primitiveFunctionPointer)()';<br>                       var: 'pcPreviousToFunction'<br>                           declareC: 'sqInt (* const pcPreviousToFunction)(sqInt,sqInt) = ', (aCCodeGenerator cFunctionNameFor: PCPreviousToFunction);<br>           var: #externalPrimitiveTable<br>                          declareC: 'void (*externalPrimitiveTable[MaxExternalPrimitiveTableSize + 1 /* ', (MaxExternalPrimitiveTableSize + 1) printString, ' */])(void)';<br>              var: #interruptCheckChain<br>                     declareC: 'void (*interruptCheckChain)(void) = 0';<br>            var: #showSurfaceFn<br>                   declareC: 'int (*showSurfaceFn)(sqIntptr_t, int, int, int, int)'.<br>  <br>         self declareCAsUSqLong: #(nextPollUsecs nextWakeupUsecs<br>                                                               "these are high-frequency enough that they're overflowing quite quickly on modern hardware"<br>                                                                 statProcessSwitch statIOProcessEvents statForceInterruptCheck<br>                                                                 statCheckForEvents statStackOverflow statStackPageDivorce<br>                                                             statIdleUsecs)<br>                in: aCCodeGenerator.<br>          aCCodeGenerator var: #nextProfileTick type: #sqLong.<br>          aCCodeGenerator var: #reenterInterpreter type: 'jmp_buf'.<br>     LowcodeVM<br>             ifTrue:<br>                       [aCCodeGenerator<br>                              var: #lowcodeCalloutState type: #'sqLowcodeCalloutState*'.<br>                     self declareC: #(nativeSP nativeStackPointer shadowCallStackPointer)<br>                                 as: #'char *'<br>                                 in: aCCodeGenerator]<br>                  ifFalse:<br>                      [#(lowcodeCalloutState nativeSP nativeStackPointer shadowCallStackPointer) do:<br>                                [:var| aCCodeGenerator removeVariable: var]].<br>         (self instVarNames select: [:ivn| ivn beginsWith: 'longRunningPrimitive']) do:<br>                [:lrpmVar|<br>            aCCodeGenerator<br>                       var: lrpmVar<br>                          declareC: '#if LRPCheck\', ((lrpmVar endsWith: 'Usecs') ifTrue: [#usqLong] ifFalse: [#sqInt]), ' ', lrpmVar, '\#endif']!<br><br>Item was changed:<br>  ----- Method: StackInterpreter class>>mustBeGlobal: (in category 'translation') -----<br>  mustBeGlobal: var<br>     "Answer if a variable must be global and exported.  Used for inst vars that are accessed from VM support code,<br>    and for variables that are initialized to some value (e.g. primitiveDoMixedArithmetic)."<br>  <br>    ^(super mustBeGlobal: var)<br>       or: [(self objectMemoryClass mustBeGlobal: var)<br>       or: [(#('interpreterProxy' 'interpreterVersion' 'inIOProcessEvents' 'sendWheelEvents'<br>                      'deferDisplayUpdates' 'cannotDeferDisplayUpdates' 'eventTraceMask' 'extraVMMemory'<br>                    'showSurfaceFn' 'displayBits' 'displayWidth' 'displayHeight' 'displayDepth'<br>                   'desiredNumStackPages' 'desiredEdenBytes'<br>+                    'primitiveDoMixedArithmetic' 'upscaleDisplayIfHighDPI'<br>-                       'primitiveDoMixedArithmetic'<br>                          'breakLookupClassTag' 'breakSelector' 'breakSelectorLength' 'sendTrace' 'checkAllocFiller' 'checkedPluginName'<br>                        "'reenterInterpreter'" 'suppressHeartbeatFlag' 'ffiExceptionResponse'<br>                       'debugCallbackInvokes' 'debugCallbackPath' 'debugCallbackReturns') includes: var)<br>        or: [ "This allows slow machines to define bytecodeSetSelector as 0<br>                   to avoid the interpretation overhead."<br>                   MULTIPLEBYTECODESETS not and: [var = 'bytecodeSetSelector']]]]!<br><br>Item was changed:<br>  ----- Method: StackInterpreter>>getImageHeaderFlags (in category 'image save/restore') -----<br>  getImageHeaderFlags<br>     "Answer the flags that are contained in the 7th long of the image header."<br>          ^fullScreenFlag "0 or 1"<br>    + (VMBIGENDIAN ifTrue: [0] ifFalse: [2]) "this is the imageFloatsLittleEndian flag"<br>         + (preemptionYields ifTrue: [0] ifFalse: [16r10])<br>     + (newFinalization ifTrue: [16r40] ifFalse: [0])<br>      + (sendWheelEvents ifTrue: [16r80] ifFalse: [0])<br>      + (primitiveDoMixedArithmetic ifTrue: [0] ifFalse: [16r100])<br>+         "N.B. flag mask 16r200 is fileTimesInUTC, responded to by the FIlePlugin & FileAttributesPlugin"<br>+       + (upscaleDisplayIfHighDPI ifTrue: [0] ifFalse: [16r400])<br>+    + (imageHeaderFlags bitClear: 1+2+16r10+16r40+16r80+16r100+16r200+16r400) "these are any flags we do not recognize"!<br>-       + (imageHeaderFlags bitClear: 1+2+16r10+16r40+16r80+16r100) "these are any flags we do not recognize"!<br><br>Item was changed:<br>  ----- Method: StackInterpreter>>initialize (in category 'initialization') -----<br>  initialize<br>          "Here we can initialize the variables C initializes to zero.  #initialize methods do /not/ get translated."<br>         super initialize.<br>-    primitiveDoMixedArithmetic := true. "whether we authorize primitives to perform mixed arithmetic or not".<br>   newFinalization := false.<br>     stackLimit := 0. "This is also the initialization flag for the stack system."<br>       stackPage := overflowedPage := nil.<br>   extraFramesToMoveOnOverflow := 0.<br>     bytecodeSetSelector := 0.<br>     highestRunnableProcessPriority := 0.<br>          nextPollUsecs := 0.<br>   nextWakeupUsecs := 0.<br>         tempOop := tempOop2 := theUnknownShort := 0.<br>          interruptPending := false.<br>    inIOProcessEvents := 0.<br>       fullScreenFlag := 0.<br>          sendWheelEvents := deferDisplayUpdates := cannotDeferDisplayUpdates := false.<br>         displayBits := displayWidth := displayHeight := displayDepth := 0.<br>    pendingFinalizationSignals := statPendingFinalizationSignals := 0.<br>    globalSessionID := 0.<br>         longRunningPrimitiveStartUsecs := longRunningPrimitiveStopUsecs := 0.<br>         maxExtSemTabSizeSet := false.<br>         debugCallbackInvokes := debugCallbackPath := debugCallbackReturns := 0.<br>       primitiveCalloutPointer := -1. "initialized in declaration in declareCVarsIn:"<br>      transcript := Transcript. "initialized to stdout in readImageFromFile:HeapSize:StartingAt:"<br>         pcPreviousToFunction := PCPreviousToFunction. "initialized via StackInterpreter class>>declareCVarsIn:"<br>       statForceInterruptCheck := statStackOverflow := statCheckForEvents :=<br>         statProcessSwitch := statIOProcessEvents := statStackPageDivorce :=<br>   statIdleUsecs := 0!<br><br>Item was changed:<br>  ----- Method: StackInterpreter>>initializeInterpreter: (in category 'initialization') -----<br>  initializeInterpreter: bytesToShift<br>+         "Initialize Interpreter state before starting execution of a new image.<br>+          N.B. do *NOT* initialize variables that can be initialized via command line<br>+          arguments since command line arguments are proicessed before the image<br>+       is loaded and this initialization takes place after the image is loaded.<br>+     Anything that us not initialized to either 0 or false (the C default value)<br>+          should be initialized in StackInterpeeter class>>declareCVarsIn:"<br>-        "Initialize Interpreter state before starting execution of a new image."<br>    interpreterProxy := self sqGetInterpreterProxy.<br>       self dummyReferToProxy.<br>       objectMemory initializeObjectMemory: bytesToShift.<br>    self checkAssumedCompactClasses.<br>      self initializeExtraClassInstVarIndices.<br>      method := newMethod := objectMemory nilObject.<br>        self cCode: '' inSmalltalk:<br>           [breakSelectorLength ifNil:<br>                   [breakSelectorLength := objectMemory minSmallInteger].<br>                 breakLookupClassTag ifNil: [breakLookupClassTag := -1].<br>               reenterInterpreter := ReenterInterpreter new].<br>       methodDictLinearSearchLimit := 8.<br>     self initialCleanup.<br>-         primitiveDoMixedArithmetic := true.<br>   LowcodeVM ifTrue: [ self setupNativeStack ].<br>          profileSemaphore := profileProcess := profileMethod := objectMemory nilObject.<br>        self cCode: '' inSmalltalk:<br>           [InitializationOptions at: #profiling ifPresent:<br>                      [:profiling| "hack turn on profiling, for testing in the simulator."<br>                         profiling ifTrue:<br>                            [profileSemaphore := objectMemory cloneObject: (objectMemory splObj: TheInterruptSemaphore).<br>                                   objectMemory<br>                                         storePointerUnchecked: FirstLinkIndex ofObject: profileSemaphore withValue: objectMemory nilObject;<br>                                   storePointerUnchecked: NextLinkIndex ofObject: profileSemaphore withValue: objectMemory nilObject;<br>                                    storePointerUnchecked: ExcessSignalsIndex ofObject: profileSemaphore withValue: (objectMemory integerObjectOf: 0)]]].<br>         interruptKeycode := 2094. "cmd-. as used for Mac but no other OS"<br>   [globalSessionID = 0] whileTrue:<br>              [globalSessionID := self<br>                                                              cCode: [((self time: #NULL) + self ioMSecs) bitAnd: 16r7FFFFFFF]<br>                                                              inSmalltalk: [(Random new next * (SmallInteger maxVal min: 16r7FFFFFFF)) asInteger]].<br>         metaAccessorDepth := -2.<br>      super initializeInterpreter: bytesToShift!<br><br>Item was changed:<br>  ----- Method: StackInterpreter>>setImageHeaderFlags: (in category 'internal interpreter access') -----<br>  setImageHeaderFlags: flags<br>         "Set an array of flags indicating various properties of the saved image, responded to on image load.<br>      These are the same as the image header flags shifted right two bits, omitting the fullScreenFlag and float byte order flag.<br>           Bit 0: if set, implies the image's Process class has threadId as its 3rd inst var (zero relative) (meaningful to the MT VM only)<br>      Bit 1: if set, methods that are interpreted will have the flag bit set in their header (meaningful to the Cog VM only)<br>        Bit 2: if set, implies preempting a process does not put it to the back of its run queue<br>      Bit 3: if set, implies a threaded VM will not disown the VM if owned by the GUI thread (meaningful to the MT VM only)<br>         Bit 4: if set, implies the new finalization scheme where WeakArrays are queued<br>        Bit 5: if set, implies wheel events will be delivered as such and not mapped to arrow key events<br>      Bit 6: if set, implies arithmetic primitives will fail if given arguments of different types (float vs int)<br>+          Bit 7: if set, implies file primitives (FilePlugin, FileAttributesPlugin) will answer file times in UTC not local times<br>+      Bit 8: if set, implies the VM will not upscale the display on high DPI devices"<br>+        flags asUnsignedInteger > 511 ifTrue:<br>-      Bit 7: if set, implies file primitives (FilePlugin, FileAttributesPlugin) will answer file times in UTC not local times"<br>-       flags asUnsignedInteger > 255 ifTrue:<br>              [^self primitiveFailFor: PrimErrUnsupported].<br>         "processHasThreadId := flags anyMask: 1. specific to CoInterpreterMT"<br>       imageHeaderFlags := (flags anyMask: 1)<br>                                                        ifTrue: [imageHeaderFlags bitOr: 4]<br>                                                   ifFalse: [imageHeaderFlags bitClear: 4].<br>      "flagInterpretedMethods := flags anyMask: 2. specific to CoInterpreter"<br>     imageHeaderFlags := (flags anyMask: 2)<br>                                                        ifTrue: [imageHeaderFlags bitOr: 8]<br>                                                   ifFalse: [imageHeaderFlags bitClear: 8].<br>      preemptionYields := flags noMask: 4.<br>          "noThreadingOfGUIThread := flags anyMask: 8.. specific to CoInterpreterMT"<br>          imageHeaderFlags := (flags anyMask: 8)<br>                                                        ifTrue: [imageHeaderFlags bitOr: 32]<br>                                                          ifFalse: [imageHeaderFlags bitClear: 32].<br>     newFinalization := flags anyMask: 16.<br>         sendWheelEvents := flags anyMask: 32.<br>         primitiveDoMixedArithmetic := flags noMask: 64.<br>       imageHeaderFlags := (flags anyMask: 128)<br>                                                      ifTrue: [imageHeaderFlags bitOr: 512]<br>+                                                        ifFalse: [imageHeaderFlags bitClear: 512].<br>+   upscaleDisplayIfHighDPI := flags noMask: 256!<br>-                                                        ifFalse: [imageHeaderFlags bitClear: 512]!<br><br>Item was changed:<br>  ----- Method: StackInterpreter>>setImageHeaderFlagsFrom: (in category 'image save/restore') -----<br>  setImageHeaderFlagsFrom: headerFlags<br>    "Set the flags that are contained in the 7th long of the image header."<br>     imageHeaderFlags := headerFlags. "so as to preserve unrecognised flags."<br>    fullScreenFlag := headerFlags bitAnd: 1.<br>      imageFloatsBigEndian := (headerFlags noMask: 2) ifTrue: [1] ifFalse: [0].<br>     "processHasThreadId := headerFlags anyMask: 4. specific to CoInterpreterMT"<br>         "flagInterpretedMethods := headerFlags anyMask: 8. specific to CoInterpreter"<br>       preemptionYields := headerFlags noMask: 16.<br>   "noThreadingOfGUIThread := headerFlags anyMask: 32. specific to CoInterpreterMT"<br>    newFinalization := headerFlags anyMask: 64.<br>   sendWheelEvents := headerFlags anyMask: 128.<br>+         primitiveDoMixedArithmetic := headerFlags noMask: 256.<br>+       "N.B. flag mask 512 is responded to by the FIlePlugin & FileAttributesPlugin"<br>+  upscaleDisplayIfHighDPI := headerFlags noMask: 1024!<br>-         primitiveDoMixedArithmetic := headerFlags noMask: 256!<br><br></wchar.h></setjmp.h></stdlib.h></stdio.h></div></blockquote></div>