Return strings in numeric primitives

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

Return strings in numeric primitives

David Leonhardt
Hey.

I'm doing my own numeric primitive.
I could return numeric values, doing something like:

                   self pop: 1 thenPush: ( objectMemory integerObjectOf: 21 ).

What I couldn't do is find a way to return a string, for example 'Hello World'.


Thanks,
David.

_______________________________________________
VM-beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/vm-beginners
Reply | Threaded
Open this post in threaded view
|

Return strings in numeric primitives

David Leonhardt
For more details.

With this code, I get a string and return it.

self var: #stringObj declareC: 'int stringObj'.
self var: #stringPtr declareC: 'char *stringPtr'.
self var: #stringSize declareC: 'int stringSize'.
stringObj := objectMemory stackValue: 0.
stringSize := objectMemory stSizeOf: stringObj.
stringPtr := self cCoerce: (objectMemory arrayValueOf: stringObj) to: 'char *'.

But I can't replace stringObj := 'Hello World'. Why?



2012/6/30 David Leonhardt <[hidden email]>
Hey.

I'm doing my own numeric primitive.
I could return numeric values, doing something like:

                   self pop: 1 thenPush: ( objectMemory integerObjectOf: 21 ).

What I couldn't do is find a way to return a string, for example 'Hello World'.


Thanks,
David.


_______________________________________________
VM-beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/vm-beginners
Reply | Threaded
Open this post in threaded view
|

Re: Return strings in numeric primitives

Igor Stasenko
On 30 June 2012 18:58, David Leonhardt <[hidden email]> wrote:

> For more details.
>
> With this code, I get a string and return it.
>
> self var: #stringObj declareC: 'int stringObj'.
> self var: #stringPtr declareC: 'char *stringPtr'.
> self var: #stringSize declareC: 'int stringSize'.
> stringObj := objectMemory stackValue: 0.
> stringSize := objectMemory stSizeOf: stringObj.
> stringPtr := self cCoerce: (objectMemory arrayValueOf: stringObj) to: 'char
> *'.
>
> But I can't replace stringObj := 'Hello World'. Why?
>
>
Wait, you want to read from string object, or create a string object
from C string?

For "returning" a string, first, you should instantiate an instance of
ByteString, and then copy characters there.

// instantiating

stringOop := interpreterProxy instantiateClass: interpreterProxy
classByteString indexableSize: size.

// getting a pointer to first character in bytestring instance
<var: firstBytePtr type: 'char*'>
firstBytePtr := interpreterProxy firstIndexableField: stringOop

// copying to/from
0 to: size-1 do:[ :i | firstBytePtr at: i put: (....) ]

>
> 2012/6/30 David Leonhardt <[hidden email]>
>>
>> Hey.
>>
>> I'm doing my own numeric primitive.
>> I could return numeric values, doing something like:
>>
>>                    self pop: 1 thenPush: ( objectMemory integerObjectOf:
>> 21 ).
>>
>> What I couldn't do is find a way to return a string, for example 'Hello
>> World'.
>>
>>
>> Thanks,
>> David.
>
>
>
> _______________________________________________
> VM-beginners mailing list
> [hidden email]
> http://lists.squeakfoundation.org/mailman/listinfo/vm-beginners
>



--
Best regards,
Igor Stasenko.
_______________________________________________
VM-beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/vm-beginners
Reply | Threaded
Open this post in threaded view
|

Re: Return strings in numeric primitives

David T. Lewis
In reply to this post by David Leonhardt
On Sat, Jun 30, 2012 at 12:15:01PM -0300, David Leonhardt wrote:

> Hey.
>
> I'm doing my own numeric primitive.
> I could return numeric values, doing something like:
>
>                    self pop: 1 thenPush: ( objectMemory integerObjectOf: 21
> ).
>
> What I couldn't do is find a way to return a string, for example 'Hello
> World'.


Here is one way to do it. This example is from OSProcessPlugin. If you load
OSProcessPlugin from SqueakSource, you can find a few examples of how this
is used in the primitives.

  stringFromCString: aCString
        "Answer a new String copied from a null-terminated C string.
        Caution: This may invoke the garbage collector."
        | len newString p |
        <var: 'aCString' type: 'const char *'>
        <var: 'p' type: 'void *'>
        len := self
                cCode: 'strlen(aCString)'
                inSmalltalk: [aCString size].
        newString := interpreterProxy
                instantiateClass: interpreterProxy classString
                indexableSize: len.
        p := interpreterProxy arrayValueOf: newString.
        self cCode: 'strncpy(p, aCString, len)'
                inSmalltalk: [ | s |
                        s := interpreterProxy firstIndexableField: newString.
                        (1 to: len) do: [:i | s at: i - 1 put: (aCString at: i) asciiValue]].
        ^ newString


HTH,
Dave

_______________________________________________
VM-beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/vm-beginners
Reply | Threaded
Open this post in threaded view
|

Re: Return strings in numeric primitives

David Leonhardt
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?

Are differences between how to try strings on numeric primitives and named primitives? Because I'm doing proves with numeric primitives.

Thank you very much.



_______________________________________________
VM-beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/vm-beginners
Reply | Threaded
Open this post in threaded view
|

Re: Return strings in numeric primitives

David T. Lewis
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'.

>
> 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

_______________________________________________
VM-beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/vm-beginners
Reply | Threaded
Open this post in threaded view
|

Re: Return strings in numeric primitives

David Leonhardt
Ok, thank you!

David.


2012/7/2 David T. Lewis <[hidden email]>
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'.

>
> 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



_______________________________________________
VM-beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/vm-beginners
Reply | Threaded
Open this post in threaded view
|

Re: Return strings in numeric primitives

Bert Freudenberg
In reply to this post by David T. Lewis

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 -_______________________________________________
VM-beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/vm-beginners
Reply | Threaded
Open this post in threaded view
|

Re: Return strings in numeric primitives

David Leonhardt
Thank you all !!


This is de code I made. It seems to work:

primitiveHelloWorld
| stringOop stringPtr size |
<var: 'stringPtr' type: 'char*'>
size := 11.
stringOop := self instantiateClass: self classString indexableSize: size.
stringPtr := self firstIndexableField: stringOop.
0 to: size-1 do:[ :i | stringPtr at: i put: ('Hello World' at: i) ].
self pop:1 thenPush: stringOop.

I had to use push, ^ not work at the same way.

Best regards,
David.

_______________________________________________
VM-beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/vm-beginners
Reply | Threaded
Open this post in threaded view
|

Re: Return strings in numeric primitives

David T. Lewis
On Tue, Jul 03, 2012 at 12:04:40AM -0300, David Leonhardt wrote:

> Thank you all !!
>
>
> This is de code I made. It seems to work:
>
> primitiveHelloWorld
> | stringOop stringPtr size |
>  <var: 'stringPtr' type: 'char*'>
>  size := 11.
> stringOop := self instantiateClass: self classString indexableSize: size.
> stringPtr := self firstIndexableField: stringOop.
>  0 to: size-1 do:[ :i | stringPtr at: i put: ('Hello World' at: i) ].
>  self pop:1 thenPush: stringOop.
>
> I had to use push, ^ not work at the same way.
>
> Best regards,
> David.

Well done, I think you have solved the puzzle :)

Dave

_______________________________________________
VM-beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/vm-beginners
Reply | Threaded
Open this post in threaded view
|

Re: Return strings in numeric primitives

Mariano Martinez Peck
In reply to this post by David T. Lewis


On Mon, Jul 2, 2012 at 6:15 AM, David T. Lewis <[hidden email]> 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'.


Excellent explanations.

 
>
> 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

_______________________________________________
VM-beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/vm-beginners



--
Mariano
http://marianopeck.wordpress.com


_______________________________________________
VM-beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/vm-beginners
Reply | Threaded
Open this post in threaded view
|

Re: Return strings in numeric primitives

David Leonhardt


2012/7/3 Mariano Martinez Peck <[hidden email]>

Excellent explanations.

Yes, I had know what I was doing.



Thanks!


--
Mariano
http://marianopeck.wordpress.com



_______________________________________________
VM-beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/vm-beginners