Hi,
So, I’m building the PharoVM along with all his dependencies. For me, this is a major step because I can drop the old build process finally. Now, I’m having serious problems with FFI (that they were not present before), :
1. CRASH IN WINDOWS (32bits):
In Win32, it crashes automatically when trying to access this funtion:
getEnvSize: nameString ^ self ffiCall: #( int GetEnvironmentVariableA ( String nameString, nil, 0 ) ) module: #Kernel32
(this works perfectly fine in older versions)
2. CALLBACKS FAILING:
Callbacks have problems. The examples passes but they are very simple… as soon as I try to do something complicates (like unqlite bindings or libgit2 bindings, who use callbacks intensively), callbacks stops working. I traced the problem up to this method:
StackInterpreter>>#returnAs:ThroughCallback:Context:
returnAs: returnTypeOop ThroughCallback: vmCallbackContext Context: callbackMethodContext "callbackMethodContext is an activation of invokeCallback:[stack:registers:jmpbuf:]. Its sender is the VM's state prior to the callback. Reestablish that state (via longjmp), and mark callbackMethodContext as dead." <export: true> <var: #vmCallbackContext type: #'VMCallbackContext *'> | calloutMethodContext theFP thePage | <var: #theFP type: #'char *'> <var: #thePage type: #'StackPage *'> ((self isIntegerObject: returnTypeOop) and: [self isLiveContext: callbackMethodContext]) ifFalse: [^false]. calloutMethodContext := self externalInstVar: SenderIndex ofContext: callbackMethodContext. (self isLiveContext: calloutMethodContext) ifFalse: [^false]. "We're about to leave this stack page; must save the current frame's instructionPointer." self push: instructionPointer. self externalWriteBackHeadFramePointers. "Mark callbackMethodContext as dead; the common case is that it is the current frame. We go the extra mile for the debugger." (self isSingleContext: callbackMethodContext) ifTrue: [self markContextAsDead: callbackMethodContext] ifFalse: [theFP := self frameOfMarriedContext: callbackMethodContext. framePointer = theFP "common case" ifTrue: [(self isBaseFrame: theFP) ifTrue: [stackPages freeStackPage: stackPage] ifFalse: "calloutMethodContext is immediately below on the same page. Make it current." [instructionPointer := (self frameCallerSavedIP: framePointer) asUnsignedInteger. stackPointer := framePointer + (self frameStackedReceiverOffset: framePointer) + objectMemory wordSize. framePointer := self frameCallerFP: framePointer. self setMethod: (self frameMethodObject: framePointer). self restoreCStackStateForCallbackContext: vmCallbackContext. "N.B. siglongjmp is defines as _longjmp on non-win32 platforms. This matches the use of _setjmp in ia32abicc.c." self siglong: vmCallbackContext trampoline jmp: (self integerValueOf: returnTypeOop). ^true]] ifFalse: [self externalDivorceFrame: theFP andContext: callbackMethodContext. self markContextAsDead: callbackMethodContext]]. "Make the calloutMethodContext the active frame. The case where calloutMethodContext is immediately below callbackMethodContext on the same page is handled above." (self isStillMarriedContext: calloutMethodContext) ifTrue: [theFP := self frameOfMarriedContext: calloutMethodContext. thePage := stackPages stackPageFor: theFP. "findSPOf:on: points to the word beneath the instructionPointer, but there is no instructionPointer on the top frame of the current page." self assert: thePage ~= stackPage. stackPointer := (self findSPOf: theFP on: thePage) - objectMemory wordSize. framePointer := theFP] ifFalse: [thePage := self makeBaseFrameFor: calloutMethodContext. framePointer := thePage headFP. stackPointer := thePage headSP]. instructionPointer := self popStack. self setMethod: (objectMemory fetchPointer: MethodIndex ofObject: calloutMethodContext). self setStackPageAndLimit: thePage. self restoreCStackStateForCallbackContext: vmCallbackContext. "N.B. siglongjmp is defines as _longjmp on non-win32 platforms. This matches the use of _setjmp in ia32abicc.c." self siglong: vmCallbackContext trampoline jmp: (self integerValueOf: returnTypeOop). "NOTREACHED" ^true
with the first siglongjmp callbacks are passing fine. with the last (it would be if framePointer = theFP AND !(isBaseFrame: theFP) ) it doesn’t.
So… from here I’m a bit lost… I need some help :)
thanks, Esteban