For various reasons, I'm wanting to build a plugin to a library that
requires me to hold onto pointers to things. This means I need to store the pointer in an ivar in a squeak object and use it on subsequent calls. Can I get away with using a SmallInteger for this? Basically doing something like: primNewContext | ctx | self export: true. self primitive: 'primCreateContext' parameters: #(). self var: #ctx type: 'int'. ctx := self cCode: 'LIB_NewContext()'. ^ctx. primDestroyContext: ctx self export: true. self primitive: 'primDestroyContext' parameters: #(SmallInteger). self cCode: 'LIB_DestroyContext((void*)ctx)'. Or is this evil and I should consider a different technique? If this is evil, what is the good way to store external addresses in ivars? Thanks |
Although this seems correct at first, you run into trouble because
SmallInteger has a finite range smaller than a 32bit integer. Ignoring the 64bit needs you would pass the value in as a Oops then do this pv := interpreterProxy positive32BitValueOf: anAddressOops. or perhaps use positive64BitIntegerFor: ? on return you do this to pass the bits back. ^ interpreterProxy positive32BitIntegerFor: address It's likely you need to look at finalization and registering an external object (Smalltalk registerExternalObject: ) to ensure you free things when the smalltalk object is GCed, and to check to see if the object is still valid save after an image restart to prevent passing in a bogus address which your C plugin would cheerfully attempt to use. MPEGFile has some example code in it. On 23-Jan-06, at 3:01 PM, Todd Blanchard wrote: > For various reasons, I'm wanting to build a plugin to a library > that requires me to hold onto pointers to things. This means I > need to store the pointer in an ivar in a squeak object and use it > on subsequent calls. > > Can I get away with using a SmallInteger for this? Basically doing > something like: > > primNewContext > | ctx | > > self export: true. > self primitive: 'primCreateContext' parameters: #(). > self var: #ctx type: 'int'. > ctx := self cCode: 'LIB_NewContext()'. > ^ctx. > > primDestroyContext: ctx > self export: true. > self primitive: 'primDestroyContext' parameters: #(SmallInteger). > self cCode: 'LIB_DestroyContext((void*)ctx)'. > > Or is this evil and I should consider a different technique? > If this is evil, what is the good way to store external addresses > in ivars? > > Thanks -- ======================================================================== === John M. McIntosh <[hidden email]> 1-800-477-2659 Corporate Smalltalk Consulting Ltd. http://www.smalltalkconsulting.com ======================================================================== === |
In reply to this post by tblanchard
Generally, it's safer to use indexes (handles) that the VM maps to
appropriate pointers. That's because otherwise a restarted image might invoke the primitive with a pointer from a previous session. Cheers, - Andreas Todd Blanchard wrote: > For various reasons, I'm wanting to build a plugin to a library that > requires me to hold onto pointers to things. This means I need to > store the pointer in an ivar in a squeak object and use it on > subsequent calls. > > Can I get away with using a SmallInteger for this? Basically doing > something like: > > primNewContext > | ctx | > > self export: true. > self primitive: 'primCreateContext' parameters: #(). > self var: #ctx type: 'int'. > ctx := self cCode: 'LIB_NewContext()'. > ^ctx. > > primDestroyContext: ctx > self export: true. > self primitive: 'primDestroyContext' parameters: #(SmallInteger). > self cCode: 'LIB_DestroyContext((void*)ctx)'. > > Or is this evil and I should consider a different technique? > If this is evil, what is the good way to store external addresses in > ivars? > > Thanks > > |
In reply to this post by johnmci
My plan is to add the class containing the pointer to the startup/
shutdown lists and make them zombies (I can't reasonably re-animate them with full state I don't think). So I've got this: primNewRuntime: bytesToAllocate | rtid size | self export: true. self var: #rtid type: 'void *'. self var: #size type: 'unsigned int'. size := interpreterProxy positive32BitValueOf: bytesToAllocate. rtid := self cCode: 'LIB_NewRuntime(size)'. ^interpreterProxy positive32BitIntegerFor: rtid. Look OK? Is there a good way to make it future proof for 64 bit addresses? Off the top of my head I can think of: primNewRuntime: bytesToAllocate | rtid size | self export: true. self var: #rtid type: 'void *'. self var: #size type: 'unsigned int'. (self cCode: 'sizeof(void*)') = 4 ifTrue: [ size := interpreterProxy positive32BitValueOf: bytesToAllocate. rtid := self cCode: 'LIB_NewRuntime(size)'. ^interpreterProxy positive32BitIntegerFor: rtid. ] ifFalse: [ size := interpreterProxy positive64BitValueOf: bytesToAllocate. rtid := self cCode: 'LIB_NewRuntime(size)'. ^interpreterProxy positive64BitIntegerFor: rtid. ] Maybe you know a better way? On Jan 23, 2006, at 3:29 PM, John M McIntosh wrote: > Although this seems correct at first, you run into trouble because > SmallInteger has a finite range smaller than a 32bit integer. > Ignoring the 64bit needs you would pass the value in as a Oops > then do this > > pv := interpreterProxy positive32BitValueOf: anAddressOops. > or perhaps > use positive64BitIntegerFor: ? > > on return you do this to pass the bits back. > ^ interpreterProxy positive32BitIntegerFor: address > > It's likely you need to look at finalization and registering an > external object (Smalltalk registerExternalObject: ) > to ensure you free things when the smalltalk object is GCed, and to > check to see if the object is still valid save after an image > restart to > prevent passing in a bogus address which your C plugin would > cheerfully attempt to use. MPEGFile has some example code in it. > > > On 23-Jan-06, at 3:01 PM, Todd Blanchard wrote: > >> For various reasons, I'm wanting to build a plugin to a library >> that requires me to hold onto pointers to things. This means I >> need to store the pointer in an ivar in a squeak object and use it >> on subsequent calls. >> >> Can I get away with using a SmallInteger for this? Basically >> doing something like: >> >> primNewContext >> | ctx | >> >> self export: true. >> self primitive: 'primCreateContext' parameters: #(). >> self var: #ctx type: 'int'. >> ctx := self cCode: 'LIB_NewContext()'. >> ^ctx. >> >> primDestroyContext: ctx >> self export: true. >> self primitive: 'primDestroyContext' parameters: #(SmallInteger). >> self cCode: 'LIB_DestroyContext((void*)ctx)'. >> >> Or is this evil and I should consider a different technique? >> If this is evil, what is the good way to store external addresses >> in ivars? >> >> Thanks > > -- > ====================================================================== > ===== > John M. McIntosh <[hidden email]> 1-800-477-2659 > Corporate Smalltalk Consulting Ltd. http:// > www.smalltalkconsulting.com > ====================================================================== > ===== > |
> Is there a good way to make it future proof for 64 bit addresses?
Generally, it's safer to use indexes (handles) that the VM maps to appropriate pointers... wait ... I wrote that before, didn't I? ;-) Todd Blanchard wrote: > My plan is to add the class containing the pointer to the startup/ > shutdown lists and make them zombies (I can't reasonably re-animate > them with full state I don't think). > > So I've got this: > > primNewRuntime: bytesToAllocate > > | rtid size | > > self export: true. > self var: #rtid type: 'void *'. > self var: #size type: 'unsigned int'. > size := interpreterProxy positive32BitValueOf: bytesToAllocate. > rtid := self cCode: 'LIB_NewRuntime(size)'. > ^interpreterProxy positive32BitIntegerFor: rtid. > > Look OK? > Is there a good way to make it future proof for 64 bit addresses? Off > the top of my head I can think of: > > primNewRuntime: bytesToAllocate > > | rtid size | > > self export: true. > self var: #rtid type: 'void *'. > self var: #size type: 'unsigned int'. > (self cCode: 'sizeof(void*)') = 4 ifTrue: > [ > size := interpreterProxy positive32BitValueOf: bytesToAllocate. > rtid := self cCode: 'LIB_NewRuntime(size)'. > ^interpreterProxy positive32BitIntegerFor: rtid. > ] > ifFalse: > [ > size := interpreterProxy positive64BitValueOf: bytesToAllocate. > rtid := self cCode: 'LIB_NewRuntime(size)'. > ^interpreterProxy positive64BitIntegerFor: rtid. > ] > > Maybe you know a better way? > > On Jan 23, 2006, at 3:29 PM, John M McIntosh wrote: > >> Although this seems correct at first, you run into trouble because >> SmallInteger has a finite range smaller than a 32bit integer. >> Ignoring the 64bit needs you would pass the value in as a Oops then >> do this >> >> pv := interpreterProxy positive32BitValueOf: anAddressOops. >> or perhaps >> use positive64BitIntegerFor: ? >> >> on return you do this to pass the bits back. >> ^ interpreterProxy positive32BitIntegerFor: address >> >> It's likely you need to look at finalization and registering an >> external object (Smalltalk registerExternalObject: ) >> to ensure you free things when the smalltalk object is GCed, and to >> check to see if the object is still valid save after an image restart to >> prevent passing in a bogus address which your C plugin would >> cheerfully attempt to use. MPEGFile has some example code in it. >> >> >> On 23-Jan-06, at 3:01 PM, Todd Blanchard wrote: >> >>> For various reasons, I'm wanting to build a plugin to a library that >>> requires me to hold onto pointers to things. This means I need to >>> store the pointer in an ivar in a squeak object and use it on >>> subsequent calls. >>> >>> Can I get away with using a SmallInteger for this? Basically doing >>> something like: >>> >>> primNewContext >>> | ctx | >>> >>> self export: true. >>> self primitive: 'primCreateContext' parameters: #(). >>> self var: #ctx type: 'int'. >>> ctx := self cCode: 'LIB_NewContext()'. >>> ^ctx. >>> >>> primDestroyContext: ctx >>> self export: true. >>> self primitive: 'primDestroyContext' parameters: #(SmallInteger). >>> self cCode: 'LIB_DestroyContext((void*)ctx)'. >>> >>> Or is this evil and I should consider a different technique? >>> If this is evil, what is the good way to store external addresses in >>> ivars? >>> >>> Thanks >> >> >> -- >> ====================================================================== >> ===== >> John M. McIntosh <[hidden email]> 1-800-477-2659 >> Corporate Smalltalk Consulting Ltd. http:// www.smalltalkconsulting.com >> ====================================================================== >> ===== >> > > |
OK OK I get it now, I'm convinced. :-)
On Jan 23, 2006, at 11:00 PM, Andreas Raab wrote: > > Is there a good way to make it future proof for 64 bit addresses? > > Generally, it's safer to use indexes (handles) that the VM maps to > appropriate pointers... wait ... I wrote that before, didn't I? > > ;-) > > > Todd Blanchard wrote: >> My plan is to add the class containing the pointer to the startup/ >> shutdown lists and make them zombies (I can't reasonably re- >> animate them with full state I don't think). >> So I've got this: >> primNewRuntime: bytesToAllocate >> | rtid size | >> self export: true. >> self var: #rtid type: 'void *'. >> self var: #size type: 'unsigned int'. >> size := interpreterProxy positive32BitValueOf: bytesToAllocate. >> rtid := self cCode: 'LIB_NewRuntime(size)'. >> ^interpreterProxy positive32BitIntegerFor: rtid. >> Look OK? >> Is there a good way to make it future proof for 64 bit >> addresses? Off the top of my head I can think of: >> primNewRuntime: bytesToAllocate >> | rtid size | >> self export: true. >> self var: #rtid type: 'void *'. >> self var: #size type: 'unsigned int'. >> (self cCode: 'sizeof(void*)') = 4 ifTrue: >> [ >> size := interpreterProxy positive32BitValueOf: >> bytesToAllocate. >> rtid := self cCode: 'LIB_NewRuntime(size)'. >> ^interpreterProxy positive32BitIntegerFor: rtid. >> ] >> ifFalse: >> [ >> size := interpreterProxy positive64BitValueOf: >> bytesToAllocate. >> rtid := self cCode: 'LIB_NewRuntime(size)'. >> ^interpreterProxy positive64BitIntegerFor: rtid. >> ] >> Maybe you know a better way? >> On Jan 23, 2006, at 3:29 PM, John M McIntosh wrote: >>> Although this seems correct at first, you run into trouble >>> because SmallInteger has a finite range smaller than a 32bit >>> integer. >>> Ignoring the 64bit needs you would pass the value in as a Oops >>> then do this >>> >>> pv := interpreterProxy positive32BitValueOf: anAddressOops. >>> or perhaps >>> use positive64BitIntegerFor: ? >>> >>> on return you do this to pass the bits back. >>> ^ interpreterProxy positive32BitIntegerFor: address >>> >>> It's likely you need to look at finalization and registering an >>> external object (Smalltalk registerExternalObject: ) >>> to ensure you free things when the smalltalk object is GCed, and >>> to check to see if the object is still valid save after an >>> image restart to >>> prevent passing in a bogus address which your C plugin would >>> cheerfully attempt to use. MPEGFile has some example code in it. >>> >>> >>> On 23-Jan-06, at 3:01 PM, Todd Blanchard wrote: >>> >>>> For various reasons, I'm wanting to build a plugin to a library >>>> that requires me to hold onto pointers to things. This means I >>>> need to store the pointer in an ivar in a squeak object and use >>>> it on subsequent calls. >>>> >>>> Can I get away with using a SmallInteger for this? Basically >>>> doing something like: >>>> >>>> primNewContext >>>> | ctx | >>>> >>>> self export: true. >>>> self primitive: 'primCreateContext' parameters: #(). >>>> self var: #ctx type: 'int'. >>>> ctx := self cCode: 'LIB_NewContext()'. >>>> ^ctx. >>>> >>>> primDestroyContext: ctx >>>> self export: true. >>>> self primitive: 'primDestroyContext' parameters: # >>>> (SmallInteger). self cCode: 'LIB_DestroyContext((void*)ctx)'. >>>> >>>> Or is this evil and I should consider a different technique? >>>> If this is evil, what is the good way to store external >>>> addresses in ivars? >>>> >>>> Thanks >>> >>> >>> -- >>> ==================================================================== >>> == ===== >>> John M. McIntosh <[hidden email]> 1-800-477-2659 >>> Corporate Smalltalk Consulting Ltd. http:// >>> www.smalltalkconsulting.com >>> ==================================================================== >>> == ===== >>> |
In reply to this post by Andreas.Raab
Handles?
Sure you did, in that case you could use small integers and ignore the 32/64 bit issue. With a range check of course on the array you are indexing (32 or 64 bit addresses) and a register as external object and cross check, or do a shutdown/ startup check to prevent passing in a bogus handle. I'll also add you can say rtid := self LIB_NewRuntime: size of course, the compiler will complain, but it will change that into rtid = LIB_NewRuntime(size) On 23-Jan-06, at 11:00 PM, Andreas Raab wrote: > > Is there a good way to make it future proof for 64 bit addresses? > > Generally, it's safer to use indexes (handles) that the VM maps to > appropriate pointers... wait ... I wrote that before, didn't I? > > ;-) > > > Todd Blanchard wrote: >> My plan is to add the class containing the pointer to the startup/ >> shutdown lists and make them zombies (I can't reasonably re- >> animate them with full state I don't think). >> So I've got this: >> primNewRuntime: bytesToAllocate >> | rtid size | >> self export: true. >> self var: #rtid type: 'void *'. >> self var: #size type: 'unsigned int'. >> size := interpreterProxy positive32BitValueOf: bytesToAllocate. >> rtid := self cCode: 'LIB_NewRuntime(size)'. >> ^interpreterProxy positive32BitIntegerFor: rtid. >> Look OK? >> Is there a good way to make it future proof for 64 bit >> addresses? Off the top of my head I can think of: >> primNewRuntime: bytesToAllocate >> | rtid size | >> self export: true. >> self var: #rtid type: 'void *'. >> self var: #size type: 'unsigned int'. >> (self cCode: 'sizeof(void*)') = 4 ifTrue: >> [ >> size := interpreterProxy positive32BitValueOf: >> bytesToAllocate. >> rtid := self cCode: 'LIB_NewRuntime(size)'. >> ^interpreterProxy positive32BitIntegerFor: rtid. >> ] >> ifFalse: >> [ >> size := interpreterProxy positive64BitValueOf: >> bytesToAllocate. >> rtid := self cCode: 'LIB_NewRuntime(size)'. >> ^interpreterProxy positive64BitIntegerFor: rtid. >> ] >> Maybe you know a better way? >> On Jan 23, 2006, at 3:29 PM, John M McIntosh wrote: >>> Although this seems correct at first, you run into trouble >>> because SmallInteger has a finite range smaller than a 32bit >>> integer. >>> Ignoring the 64bit needs you would pass the value in as a Oops >>> then do this >>> >>> pv := interpreterProxy positive32BitValueOf: anAddressOops. >>> or perhaps >>> use positive64BitIntegerFor: ? >>> >>> on return you do this to pass the bits back. >>> ^ interpreterProxy positive32BitIntegerFor: address >>> >>> It's likely you need to look at finalization and registering an >>> external object (Smalltalk registerExternalObject: ) >>> to ensure you free things when the smalltalk object is GCed, and >>> to check to see if the object is still valid save after an >>> image restart to >>> prevent passing in a bogus address which your C plugin would >>> cheerfully attempt to use. MPEGFile has some example code in it. >>> >>> >>> On 23-Jan-06, at 3:01 PM, Todd Blanchard wrote: >>> >>>> For various reasons, I'm wanting to build a plugin to a library >>>> that requires me to hold onto pointers to things. This means I >>>> need to store the pointer in an ivar in a squeak object and use >>>> it on subsequent calls. >>>> >>>> Can I get away with using a SmallInteger for this? Basically >>>> doing something like: >>>> >>>> primNewContext >>>> | ctx | >>>> >>>> self export: true. >>>> self primitive: 'primCreateContext' parameters: #(). >>>> self var: #ctx type: 'int'. >>>> ctx := self cCode: 'LIB_NewContext()'. >>>> ^ctx. >>>> >>>> primDestroyContext: ctx >>>> self export: true. >>>> self primitive: 'primDestroyContext' parameters: # >>>> (SmallInteger). self cCode: 'LIB_DestroyContext((void*)ctx)'. >>>> >>>> Or is this evil and I should consider a different technique? >>>> If this is evil, what is the good way to store external >>>> addresses in ivars? >>>> >>>> Thanks >>> >>> >>> -- >>> ==================================================================== >>> == ===== >>> John M. McIntosh <[hidden email]> 1-800-477-2659 >>> Corporate Smalltalk Consulting Ltd. http:// >>> www.smalltalkconsulting.com >>> ==================================================================== >>> == ===== >>> -- ======================================================================== === John M. McIntosh <[hidden email]> 1-800-477-2659 Corporate Smalltalk Consulting Ltd. http://www.smalltalkconsulting.com ======================================================================== === |
Am 24.01.2006 um 08:06 schrieb John M McIntosh: > > I'll also add you can say rtid := self LIB_NewRuntime: size of > course, the compiler will complain, but it will change that into > rtid = LIB_NewRuntime(size) After you hacked the compiler to allow underscores in identifiers, of course. I'm all for it for precisely this usage case, but there are backwards-compatibility issues. - Bert - |
Free forum by Nabble | Edit this page |