Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatically throw error on negative return from C function #154

Open
matwachich opened this issue Mar 27, 2015 · 10 comments
Open

Automatically throw error on negative return from C function #154

matwachich opened this issue Mar 27, 2015 · 10 comments

Comments

@matwachich
Copy link

Hi!

I'm writting a golang wrapper for duktape (github.com/matwachich/goduk) and I'm facing the fact that duktape's way of handling error throwing from C/Go functions (using setjmp/longjmp) is incompatible with go! I mean it is impossible to call duk_error from a Go function.

So I must use the negative value return shortcut to throw errors from Go functions.
But doing this it is impossible to set an error message (like with duk_error).

So I think it will be nice to automatically throw an error found on stack's top just after returning (a negative value) from a C/Go function call. So we could do something like:

int my_c_function(ctx* duk_context) {
// ...
// error
duk_push_error_object(ctx, "My error message");
return -1;
// just after this return, an error object is on stack's top, so it is thrown automatically
}

Thanks!

@svaarala
Copy link
Owner

Any value can be thrown so there is no reliable way of detecting that the stack top after a return is an error that should be thrown.

But we could dedicate a return value to indicate "throw the error value on top of stack", e.g. DUK_RET_THROW.

@matwachich
Copy link
Author

Yes, I like this. I think it's not very difficult to implement, so can we expect to see this enhancement?

Thanks!

@svaarala
Copy link
Owner

It's not difficult to implement but I'd like to understand what problem we're trying to solve. Could you describe your problem in a bit more detail?

@matwachich
Copy link
Author

Here is the issue that I posted on golang google group
https://groups.google.com/forum/#!topic/golang-nuts/1szTEg7CnYk

@svaarala
Copy link
Owner

Even if this change was made, what would happen if the script were to cause an error to be thrown as a side effect rather than calling duk_error() explicitly? For example, the script might try to hex decode an invalid value, access a property off an invalid base value, etc.

Wouldn't the same setjmp/longjmp problem happen in these cases?

@matwachich
Copy link
Author

I didn't studied all thoses cases, but what I see is that when the error is thrown from C or duktape code there is no problem.
For example, calling throw in duktape code causes no problem at all.

@svaarala
Copy link
Owner

Suppose for example that in duk_myError() you'd replace ctx.Error with ctx.EvalString (or similar) and that eval code would cause an error to be thrown (say, "null.foo = 123") - would that work?

@matwachich
Copy link
Author

Nope. But anyway, EvalString is not supposed to succeed on erroneous code (if I understand how Duktape works). Only a protected code will throw an error on erroneous code.

I tried with EvalString, and of course the program crashes. But with PevalString, it works ("TypeError: invalid base value" is left on stack's top)

@svaarala
Copy link
Owner

(To clarify, any code can throw an error for various reasons. If nothing else, there may be an out-of-memory or other internal error. Protected calls catch errors that happen inside the protected call they make.)

As the problem seems to be a longjmp crossing a Go activation, it might be worth trying to find a solution where errors are always caught on such boundaries.

@matwachich
Copy link
Author

So my suggestion to catch the error 'after' returning from the Go function.
But anyway, I don't know very well duktape's internals, so if you have better suggestions (than returning a special value indicating that an error is waiting to be thrown on stack's top) it would be great!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants