[Vm-beginners] Return strings in numeric primitives

Bert Freudenberg bert at freudenbergs.de
Mon Jul 2 12:17:17 UTC 2012


On 02.07.2012, at 06:15, David T. Lewis wrote:

> On Sun, Jul 01, 2012 at 06:01:23PM -0300, David Leonhardt wrote:
>> mmm.... it seems like I don't understand how to try with strings...
>> ok, I need something more basic or more information.
>> Someone know where can I read about how to try strings en SLang?
>> 
> 
> When you create a new String object to return from your primitive,
> that object is part of the object memory managed by the VM. If you
> have the string "hello world" in some C code for your primitive,
> that string is not part of the object memory managed by the VM.
> It is just a null-terminated array of characters somewhere in the
> C program, allocated in memory somewhere outside of the Squeak
> object memory. This means that if you want your primitive to return
> a string, you should have your primitive create a new object of
> type String, copy the data from the C string into the data portion
> of the String object, and return that object as the result of the
> primitive.
> 
> Thus in order for a primitive to answer the string "hello world",
> the primitive should create a new instance of a String object with
> length 11. This object will (inside the object memory) have a header
> that indicates the type of object, and enough data space to hold
> 11 bytes of char data from a C string. If you copy "hello world"
> from the C string into the data area of the new String object, then
> you will have a 'hello world' String object in the Smalltalk object
> memory. You can put that object on the stack to return it as the
> result of a primitive call, and the result will be a primitive
> that answers the string 'hello world'.

When copying from a C string to a Squeak string be sure to *not* copy the terminating zero byte.

"hello world" in C occupies 12 bytes - the 11 characters and an additional 0 to indicate the end of the string.

In Squeak, the character data would only consist of the 11 characters. The length is in the String object's header. If you were to accidentally copy the 0, this would be written in the memory after the String object, possibly corrupting the header of the next object in memory.

You must allocate the string object with the right size, because it cannot be changed later. E.g.

	stringOOP := interpreterProxy
		instantiateClass: interpreterProxy classString
		indexableSize: 11.

stringOOP is an object reference - it does *not* point to the actual character data. 

To get a pointer to the string's character data, use:

	<var: 'stringPointer' type: 'char *'>
	stringPointer := interpreterProxy arrayValueOf: stringOOP.

That gives you a pointer where you can write your 11 characters to, by whatever means. Just be sure to not write more than 11 bytes.

When you're done, you can return the string from the primitive by pushing its OOP onto the stack. The Slang translator converts a Squeak return into a stack push (just look at the generated C code):

	^ stringOOP

>> Are differences between how to try strings on numeric primitives and named
>> primitives? Because I'm doing proves with numeric primitives.
>> 
> 
> No, there is no difference between numeric primitives and named
> primitives. These are just two different ways of calling a primitive
> from the image. If you write a primitive to answer the string
> 'hello world', you will write it the same way regardless of whether
> it is a numbered primitive or a named primitive. But in general you
> should use named primitives whenever possible.
> 
> Dave


- Bert -


More information about the VM-beginners mailing list