Correct way to throw exceptions/errors from C to ST

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

Correct way to throw exceptions/errors from C to ST

Roland Plüss-2
Another something that I could not really figure out using the
documentations. Let's say you have a CCallOut from ST to C. Inside this
C function something goes wrong, for example an invalid argument passed.
How do you properly raise an exception back to Smalltalk? I tried doing
something like this:

gst_eval_code( "SystemExceptions.InvalidArgument new signal" );

But this causes the VM to call abort since an exception happened outside
the bytecode. I assume you need to be more clever in this case. So what
is the correct way to throw these kinds of exceptions from inside a C
function?

--
Yours sincerely
Plüss Roland

Leader and Head Programmer
- Game: Epsylon ( http://www.indiedb.com/games/epsylon )
- Game Engine: Drag[en]gine ( http://www.indiedb.com/engines/dragengine
, http://dragengine.rptd.ch/wiki )
- Normal Map Generator: DENormGen ( http://epsylon.rptd.ch/denormgen.php )
- As well as various Blender export scripts und game tools


_______________________________________________
help-smalltalk mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-smalltalk

signature.asc (188 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Correct way to throw exceptions/errors from C to ST

Holger Freyther
On Sat, Apr 04, 2015 at 02:50:01AM +0200, Roland Plüss wrote:

Oh,

> gst_eval_code( "SystemExceptions.InvalidArgument new signal" );
>
> But this causes the VM to call abort since an exception happened outside
> the bytecode. I assume you need to be more clever in this case. So what
> is the correct way to throw these kinds of exceptions from inside a C
> function?

Oh I don't know. The signal should occur once is out of C. E.g.
you should be able to return an instance of InvalidArgument and
in the Smalltalk code that triggered the C call-out check for the
response and then signal it?


_______________________________________________
help-smalltalk mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: Correct way to throw exceptions/errors from C to ST

Roland Plüss-2


On 04/04/2015 06:24 PM, Holger Hans Peter Freyther wrote:

> On Sat, Apr 04, 2015 at 02:50:01AM +0200, Roland Plüss wrote:
>
> Oh,
>
>> gst_eval_code( "SystemExceptions.InvalidArgument new signal" );
>>
>> But this causes the VM to call abort since an exception happened outside
>> the bytecode. I assume you need to be more clever in this case. So what
>> is the correct way to throw these kinds of exceptions from inside a C
>> function?
> Oh I don't know. The signal should occur once is out of C. E.g.
> you should be able to return an instance of InvalidArgument and
> in the Smalltalk code that triggered the C call-out check for the
> response and then signal it?
>
I don't know. I tried an example like this:

C++: => gst_perform( something )
Smalltalk: something[] => do a cCall (let's say cc)
C++: => cc: thrown exception using gst_eval_code(
"SystemExceptions.InvalidArgument new signal" );

Now let's say I try to catch the exception in Smalltalk. If I'm not
wrong it would look something like this:

something [
   [ anObject aCCallThatThrows ] on: Exception do: [ 'a test' printNl ]
]

But the exception is not handled but abort called by the byte code.
Could it be it fails because I'm using gst_perform?

--
Mit freundlichen Grüssen
Plüss Roland

Leader und Head Programmer
- Game: Epsylon ( http://www.indiedb.com/games/epsylon )
- Game Engine: Drag[en]gine ( http://www.indiedb.com/engines/dragengine
, http://dragengine.rptd.ch/wiki )
- Normal Map Generator: DENormGen ( http://epsylon.rptd.ch/denormgen.php )
- Sowie verschiedene Blender Export-Skripts und Game-Tools


_______________________________________________
help-smalltalk mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-smalltalk

signature.asc (188 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Correct way to throw exceptions/errors from C to ST

Paolo Bonzini-2
In reply to this post by Roland Plüss-2


On 04/04/2015 02:50, Roland Plüss wrote:

> Another something that I could not really figure out using the
> documentations. Let's say you have a CCallOut from ST to C. Inside
> this C function something goes wrong, for example an invalid
> argument passed. How do you properly raise an exception back to
> Smalltalk? I tried doing something like this:
>
> gst_eval_code( "SystemExceptions.InvalidArgument new signal" );
>
> But this causes the VM to call abort since an exception happened
> outside the bytecode. I assume you need to be more clever in this
> case. So what is the correct way to throw these kinds of exceptions
> from inside a C function?

You return a C-style error and have a Smalltalk wrapper convert it to
a Smalltalk exception.  Or you do argument checking in Smalltalk and
the rest in C.

Paolo

_______________________________________________
help-smalltalk mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: Correct way to throw exceptions/errors from C to ST

Paolo Bonzini-2
In reply to this post by Roland Plüss-2


On 05/04/2015 00:21, Roland Plüss wrote:
> something [ [ anObject aCCallThatThrows ] on: Exception do: [ 'a
> test' printNl ] ]
>
> But the exception is not handled but abort called by the byte
> code. Could it be it fails because I'm using gst_perform?

It's because each call to gst_perform is done in a separate Smalltalk
Process.  Holger's proposed solution (return the exception) sounds great.

Paolo

_______________________________________________
help-smalltalk mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: Correct way to throw exceptions/errors from C to ST

Roland Plüss-2


On 04/05/2015 08:07 AM, Paolo Bonzini wrote:

>
> On 05/04/2015 00:21, Roland Plüss wrote:
>> something [ [ anObject aCCallThatThrows ] on: Exception do: [ 'a
>> test' printNl ] ]
>>
>> But the exception is not handled but abort called by the byte
>> code. Could it be it fails because I'm using gst_perform?
> It's because each call to gst_perform is done in a separate Smalltalk
> Process.  Holger's proposed solution (return the exception) sounds great.
>
> Paolo
That sounds bad. I don't want to spawn a new process whenever I send a
message to the smalltalk scripts for performance reasons (unless running
a smalltalk process is so lightweight you don't notice it). Do I have to
use a different call? I didn't find anything better than this.

--
Yours sincerely
Plüss Roland

Leader and Head Programmer
- Game: Epsylon ( http://www.indiedb.com/games/epsylon )
- Game Engine: Drag[en]gine ( http://www.indiedb.com/engines/dragengine
, http://dragengine.rptd.ch/wiki )
- Normal Map Generator: DENormGen ( http://epsylon.rptd.ch/denormgen.php )
- As well as various Blender export scripts und game tools


_______________________________________________
help-smalltalk mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-smalltalk

signature.asc (188 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Correct way to throw exceptions/errors from C to ST

Roland Plüss-2
In reply to this post by Paolo Bonzini-2


On 04/05/2015 08:06 AM, Paolo Bonzini wrote:

>
> On 04/04/2015 02:50, Roland Plüss wrote:
>> Another something that I could not really figure out using the
>> documentations. Let's say you have a CCallOut from ST to C. Inside
>> this C function something goes wrong, for example an invalid
>> argument passed. How do you properly raise an exception back to
>> Smalltalk? I tried doing something like this:
>>
>> gst_eval_code( "SystemExceptions.InvalidArgument new signal" );
>>
>> But this causes the VM to call abort since an exception happened
>> outside the bytecode. I assume you need to be more clever in this
>> case. So what is the correct way to throw these kinds of exceptions
>> from inside a C function?
> You return a C-style error and have a Smalltalk wrapper convert it to
> a Smalltalk exception.  Or you do argument checking in Smalltalk and
> the rest in C.
>
> Paolo
What you mean with "C-style error"? A C++ exception (that doesn't work
it looks like)? The cCall is of void return type so I can't return
anything. And smalltalk side can't check the arguments as the
information required to perform the checks is sometimes located deep
inside the engine code base.

--
Yours sincerely
Plüss Roland

Leader and Head Programmer
- Game: Epsylon ( http://www.indiedb.com/games/epsylon )
- Game Engine: Drag[en]gine ( http://www.indiedb.com/engines/dragengine
, http://dragengine.rptd.ch/wiki )
- Normal Map Generator: DENormGen ( http://epsylon.rptd.ch/denormgen.php )
- As well as various Blender export scripts und game tools


_______________________________________________
help-smalltalk mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-smalltalk

signature.asc (188 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Correct way to throw exceptions/errors from C to ST

Holger Freyther
In reply to this post by Roland Plüss-2
On Sun, Apr 05, 2015 at 05:44:52PM +0200, Roland Plüss wrote:

> That sounds bad. I don't want to spawn a new process whenever I send a
> message to the smalltalk scripts for performance reasons (unless running
> a smalltalk process is so lightweight you don't notice it). Do I have to
> use a different call? I didn't find anything better than this.

Smalltalk processes are cheap. You need an execution environment
for thisContext and others and the easiest is to create a temporary
call-in process.



_______________________________________________
help-smalltalk mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: Correct way to throw exceptions/errors from C to ST

Holger Freyther
In reply to this post by Roland Plüss-2
On Sun, Apr 05, 2015 at 05:47:29PM +0200, Roland Plüss wrote:

> What you mean with "C-style error"? A C++ exception (that doesn't work
> it looks like)? The cCall is of void return type so I can't return
> anything. And smalltalk side can't check the arguments as the
> information required to perform the checks is sometimes located deep
> inside the engine code base.

"C-style" error.. a non zero return code and maybe setting a
variable with the semantic of errno. The return type of "void"
is your decision? Can't you return something to indicate success
or failure?

_______________________________________________
help-smalltalk mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: Correct way to throw exceptions/errors from C to ST

Roland Plüss-2


On 04/06/2015 06:45 PM, Holger Hans Peter Freyther wrote:

> On Sun, Apr 05, 2015 at 05:47:29PM +0200, Roland Plüss wrote:
>
>> What you mean with "C-style error"? A C++ exception (that doesn't work
>> it looks like)? The cCall is of void return type so I can't return
>> anything. And smalltalk side can't check the arguments as the
>> information required to perform the checks is sometimes located deep
>> inside the engine code base.
> "C-style" error.. a non zero return code and maybe setting a
> variable with the semantic of errno. The return type of "void"
> is your decision? Can't you return something to indicate success
> or failure?
I sure can decide the return type. I just considered it quite quick and
easy if I could return an #int if I link to a function actually
returning an integer. I certainly could return nil but then I have no
idea what error really happened nor can I properly catch it (well...
besides ifNotNil: ). Since Smalltalk has already an exception/error
system why not using it? I don't like wrangling a language unless
there's no other choice.

And as far as I know I can't include any code into a <primitive>
declared method.

I once did the trick with errno type error handling in a module I made
for Smalltalk but it's cumbersome to use and error prone.

--
Mit freundlichen Grüssen
Plüss Roland

Leader und Head Programmer
- Game: Epsylon ( http://www.indiedb.com/games/epsylon )
- Game Engine: Drag[en]gine ( http://www.indiedb.com/engines/dragengine
, http://dragengine.rptd.ch/wiki )
- Normal Map Generator: DENormGen ( http://epsylon.rptd.ch/denormgen.php )
- Sowie verschiedene Blender Export-Skripts und Game-Tools


_______________________________________________
help-smalltalk mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-smalltalk

signature.asc (188 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Correct way to throw exceptions/errors from C to ST

Holger Freyther
On Tue, Apr 07, 2015 at 06:24:15PM +0200, Roland Plüss wrote:

> I sure can decide the return type. I just considered it quite quick and
> easy if I could return an #int if I link to a function actually
> returning an integer. I certainly could return nil but then I have no
> idea what error really happened nor can I properly catch it (well...
> besides ifNotNil: ). Since Smalltalk has already an exception/error
> system why not using it? I don't like wrangling a language unless
> there's no other choice.

It is a matter of how much time you have. In most cases I don't
think we want code like:

Smalltalk code...
C-code
C-code
Exception
Smalltalk code...

This will be problematic with native code.. we will do a longjmp
through it or such. So what we can do is that the "next" execution
context can be set once the process returns to Smalltalk. We are
not many but if you want to implement it I am happy to help you.

>
> And as far as I know I can't include any code into a <primitive>
> declared method.
>
> I once did the trick with errno type error handling in a module I made
> for Smalltalk but it's cumbersome to use and error prone.

<primitive> will execute the Smalltalk code in case the primtive
failed.  E.g. for the Array

kernel/Array.st-    at: anIndex ifAbsent: aBlock [
kernel/Array.st-        "Answer the index-th indexed instance variable of the receiver"
kernel/Array.st-
kernel/Array.st-        <category: 'built ins'>
kernel/Array.st:        <primitive: VMpr_Object_basicAt>
kernel/Array.st-        ^self checkIndexableBounds: anIndex ifAbsent: aBlock
kernel/Array.st-    ]


_______________________________________________
help-smalltalk mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: Correct way to throw exceptions/errors from C to ST

Paolo Bonzini-2
In reply to this post by Roland Plüss-2
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256



On 07/04/2015 18:24, Roland Plüss wrote:

>
>
> On 04/06/2015 06:45 PM, Holger Hans Peter Freyther wrote:
>> On Sun, Apr 05, 2015 at 05:47:29PM +0200, Roland Plüss wrote:
>>
>>> What you mean with "C-style error"? A C++ exception (that
>>> doesn't work it looks like)? The cCall is of void return type
>>> so I can't return anything. And smalltalk side can't check the
>>> arguments as the information required to perform the checks is
>>> sometimes located deep inside the engine code base.
>> "C-style" error.. a non zero return code and maybe setting a
>> variable with the semantic of errno. The return type of "void" is
>> your decision? Can't you return something to indicate success or
>> failure?
> I sure can decide the return type. I just considered it quite quick
> and easy if I could return an #int if I link to a function
> actually returning an integer. I certainly could return nil but
> then I have no idea what error really happened nor can I properly
> catch it (well... besides ifNotNil: ). Since Smalltalk has already
> an exception/error system why not using it? I don't like wrangling
> a language unless there's no other choice.

You can return an exception object and throw it from Smalltalk.  It
certainly can work with methods that would return #void (return nil if
there is no exception), it is a bit more complicated for methods that
could either return a value or throw an exception.

Paolo

>
> And as far as I know I can't include any code into a <primitive>
> declared method.
>
> I once did the trick with errno type error handling in a module I
> made for Smalltalk but it's cumbersome to use and error prone.
>
>
>
> _______________________________________________ help-smalltalk
> mailing list [hidden email]
> https://lists.gnu.org/mailman/listinfo/help-smalltalk
>
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2

iQEcBAEBCAAGBQJVJOf/AAoJEL/70l94x66Dw98H+QGQDaAUZSJmG3oAp/wLnDeF
KEdwJEdB48rTaoqLV0VH7xn4uvY5fqrCOl4AXsDzHT7wx4GT0qnvlJGcnftWWrV1
+rO6vuSnrYSJuk89oNESS+EjvSUarjYry+C9T06LqCf00bjTJ6TJ35gvGMVRrzd0
zN77jHIPJX04sCP4ST0xsZoz/aQHkNRV9C5EpqdQd4l0oWFaid3nTmso0owmKWjO
C6SuIskIjiXuTOVxTfPMuXCGD0VLNgq/aaMXAWonVkGGXVeBHHTKury6wlAngLbh
iN2q7V8OUna8LCe828OnQktuSAwFmsXW9rvlK97LB1EuE2H8C3g1d5jLEiLTs1U=
=1up1
-----END PGP SIGNATURE-----

_______________________________________________
help-smalltalk mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: Correct way to throw exceptions/errors from C to ST

Roland Plüss-2
In reply to this post by Holger Freyther


On 04/07/2015 07:51 PM, Holger Hans Peter Freyther wrote:

> On Tue, Apr 07, 2015 at 06:24:15PM +0200, Roland Plüss wrote:
>
>> I sure can decide the return type. I just considered it quite quick and
>> easy if I could return an #int if I link to a function actually
>> returning an integer. I certainly could return nil but then I have no
>> idea what error really happened nor can I properly catch it (well...
>> besides ifNotNil: ). Since Smalltalk has already an exception/error
>> system why not using it? I don't like wrangling a language unless
>> there's no other choice.
> It is a matter of how much time you have. In most cases I don't
> think we want code like:
>
> Smalltalk code...
> C-code
> C-code
> Exception
> Smalltalk code...
>
> This will be problematic with native code.. we will do a longjmp
> through it or such. So what we can do is that the "next" execution
> context can be set once the process returns to Smalltalk. We are
> not many but if you want to implement it I am happy to help you.
Unfortunately I don't have time at the time being... at last not for a
Smalltalk VM endeavour. But once I'm done with the current work load
it's certainly an option. I could imagine something like having an
exception holder somewhere so if an exception happens the exception
object (which exists already in Smalltalk) is placed in a specific place
in the VM context. Once the cCall returns it can look if there is an OOP
stashed away and if so call in the current execution context
"ExceptionOOP signal". We would be in a valid Smalltalk execution
context and it would act like an exception signaled just in that place
from inside Smalltalk. This would be in my opinion a very small change
like 2 VM functions added: void gst_set_ccall_error(OOP exception) and
OOP gst_get_ccall_error(). Then inside the ccall function in the VM just
add a check to see if that OOP is set and get rolling. Theoretically
this could even be done in the Smalltalk side after finishing processing
the ccall by checking if the OOP is set in the VM and processing it.
Would be close to your ErrNo solution but instead of an integer it would
be an OOP instead.

>> And as far as I know I can't include any code into a <primitive>
>> declared method.
>>
>> I once did the trick with errno type error handling in a module I made
>> for Smalltalk but it's cumbersome to use and error prone.
> <primitive> will execute the Smalltalk code in case the primtive
> failed.  E.g. for the Array
>
> kernel/Array.st-    at: anIndex ifAbsent: aBlock [
> kernel/Array.st-        "Answer the index-th indexed instance variable of the receiver"
> kernel/Array.st-
> kernel/Array.st-        <category: 'built ins'>
> kernel/Array.st:        <primitive: VMpr_Object_basicAt>
> kernel/Array.st-        ^self checkIndexableBounds: anIndex ifAbsent: aBlock
> kernel/Array.st-    ]
>
When exactly does a primitive fail and how can I trigger this from
inside a cCall? This might actually be abused for a little trick if
working right.

--
Mit freundlichen Grüssen
Plüss Roland

Leader und Head Programmer
- Game: Epsylon ( http://www.indiedb.com/games/epsylon )
- Game Engine: Drag[en]gine ( http://www.indiedb.com/engines/dragengine
, http://dragengine.rptd.ch/wiki )
- Normal Map Generator: DENormGen ( http://epsylon.rptd.ch/denormgen.php )
- Sowie verschiedene Blender Export-Skripts und Game-Tools


_______________________________________________
help-smalltalk mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-smalltalk

signature.asc (188 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Correct way to throw exceptions/errors from C to ST

Roland Plüss-2


On 04/08/2015 01:45 PM, Roland Plüss wrote:

> And as far as I know I can't include any code into a <primitive>
> declared method.
>
> I once did the trick with errno type error handling in a module I made
> for Smalltalk but it's cumbersome to use and error prone.
>> <primitive> will execute the Smalltalk code in case the primtive
>> failed.  E.g. for the Array
>>
>> kernel/Array.st-    at: anIndex ifAbsent: aBlock [
>> kernel/Array.st-        "Answer the index-th indexed instance variable of the receiver"
>> kernel/Array.st-
>> kernel/Array.st-        <category: 'built ins'>
>> kernel/Array.st:        <primitive: VMpr_Object_basicAt>
>> kernel/Array.st-        ^self checkIndexableBounds: anIndex ifAbsent: aBlock
>> kernel/Array.st-    ]
>>
> When exactly does a primitive fail and how can I trigger this from
> inside a cCall? This might actually be abused for a little trick if
> working right.
>
Maybe the question got lost in the mailing list? What does make a
primitive fail as seen from the Smalltalk VM?

--
Yours sincerely
Plüss Roland

Leader and Head Programmer
- Game: Epsylon ( http://www.indiedb.com/games/epsylon )
- Game Engine: Drag[en]gine ( http://www.indiedb.com/engines/dragengine
, http://dragengine.rptd.ch/wiki )
- Normal Map Generator: DENormGen ( http://epsylon.rptd.ch/denormgen.php )
- As well as various Blender export scripts und game tools


_______________________________________________
help-smalltalk mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-smalltalk

signature.asc (188 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Correct way to throw exceptions/errors from C to ST

Holger Freyther

> On 12 Apr 2015, at 16:19, Roland Plüss <[hidden email]> wrote:
>
>>
> Maybe the question got lost in the mailing list? What does make a
> primitive fail as seen from the Smalltalk VM?

If you have a look at libgst/prims.def there is PRIMS_FAILED to indicate
that a primitive failed. Is VMpr_CFuncDescriptor_call the call you end up
making? In that case if NULL is returned from the c binding layer the
primitive will fail
_______________________________________________
help-smalltalk mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: Correct way to throw exceptions/errors from C to ST

Roland Plüss-2

On 04/12/2015 07:42 PM, Holger Freyther wrote:
>> On 12 Apr 2015, at 16:19, Roland Plüss <[hidden email]> wrote:
>>
>> Maybe the question got lost in the mailing list? What does make a
>> primitive fail as seen from the Smalltalk VM?
> If you have a look at libgst/prims.def there is PRIMS_FAILED to indicate
> that a primitive failed. Is VMpr_CFuncDescriptor_call the call you end up
> making? In that case if NULL is returned from the c binding layer the
> primitive will fail
That sounds good but I don't know if I use that. My setup looks
something like this:

    gst_define_cfunc( "DECanvas.getCanvasCount", ( void*
)ccGetCanvasCount );

and in this example ccGetCanvasCount is:

int stClassCanvas::ccGetCanvasCount( OOP self ){
   return some integer;
}

So I don't think I'm using that function. Or does it automatically do
this if the return value is OOP?

--
Mit freundlichen Grüssen
Plüss Roland

Leader und Head Programmer
- Game: Epsylon ( http://www.indiedb.com/games/epsylon )
- Game Engine: Drag[en]gine ( http://www.indiedb.com/engines/dragengine
, http://dragengine.rptd.ch/wiki )
- Normal Map Generator: DENormGen ( http://epsylon.rptd.ch/denormgen.php )
- Sowie verschiedene Blender Export-Skripts und Game-Tools


_______________________________________________
help-smalltalk mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-smalltalk

signature.asc (188 bytes) Download Attachment