WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
10114
Exceptions thrown by WebKitPlugins are ignored
https://bugs.webkit.org/show_bug.cgi?id=10114
Summary
Exceptions thrown by WebKitPlugins are ignored
Dan Waylonis
Reported
2006-07-25 19:14:07 PDT
I have a WebKitPlugin. I found that if my plugin calls [WebScriptObject throwException:@"foo"], the exception is not propagated. The problem is that there are multiple ExecStates that are created by the interpreter when evaluating a try / catch block. The throwException routine (and setException:) do not take this into account. I have created a patch to fix this. The patch includes code changes and test changes.
Attachments
Patch to fix WebKitPlugin exceptions
(9.27 KB, patch)
2006-07-25 19:16 PDT
,
Dan Waylonis
ggaren
: review-
Details
Formatted Diff
Diff
Updated patch with ggaren's suggestions
(8.78 KB, patch)
2006-08-01 16:01 PDT
,
Dan Waylonis
ggaren
: review-
Details
Formatted Diff
Diff
Patch to fix WebKitPlugin exceptions
(10.84 KB, patch)
2006-08-03 18:00 PDT
,
Dan Waylonis
ggaren
: review+
Details
Formatted Diff
Diff
Patch to fix WebKitPlugin exceptions
(10.98 KB, patch)
2006-08-29 15:30 PDT
,
Dan Waylonis
no flags
Details
Formatted Diff
Diff
Show Obsolete
(3)
View All
Add attachment
proposed patch, testcase, etc.
Dan Waylonis
Comment 1
2006-07-25 19:16:29 PDT
Created
attachment 9688
[details]
Patch to fix WebKitPlugin exceptions This patch provides code to fix the bug and test cases.
Darin Adler
Comment 2
2006-07-26 13:57:38 PDT
Comment on
attachment 9688
[details]
Patch to fix WebKitPlugin exceptions I want Geoff Garen or Maciej Stachowiak to review this.
Dan Waylonis
Comment 3
2006-07-26 14:04:48 PDT
Hi, sounds like a good idea. I thought about this some more and there might be a problem in a multi-view or threaded environment. It might be better to use the pthread_getspecific() / pthread_setspecific() for the storage to the ExecStates pointer in the ObjcInstance class rather than a static variable.
Darin Adler
Comment 4
2006-07-28 20:34:31 PDT
(In reply to
comment #3
)
> Hi, sounds like a good idea. I thought about this some more and there might be > a problem in a multi-view or threaded environment. It might be better to use > the pthread_getspecific() / pthread_setspecific() for the storage to the > ExecStates pointer in the ObjcInstance class rather than a static variable.
I agree that per-thread would be better in principle. May not matter in practice.
Geoffrey Garen
Comment 5
2006-07-31 16:02:16 PDT
Comment on
attachment 9688
[details]
Patch to fix WebKitPlugin exceptions I don't think it's right for the WebScriptObject API to be responsible for tracking the current ExecState. That's really a job for the JS engine. We attempted a similar hack to this one in JavaScriptGlue, and bad things happened (crashes, incompatibilities when the engine changed, mismatches between the stored ExecState and the real one). There's also the threading issue you mention, if we add support for ObjC plug-ins to the JS API. The interpreter knows about the global ExecState and the most nested Context. I think a better solution would be to use that model. Giving Context a back-pointer to its sibling ExecState (ExecState already keeps a pointer to its sibling Context) is probably easiest. Then you can write code like this: throwError(interp->context()->execState(), GeneralError, exceptionMessage); Since Context and ExecState should probably merge in the end, the code can eventually become this: throwError(interp->context(), GeneralError, exceptionMessage); For now, a Context is transient and stack-allocated, so there aren't any ownership issues to worry about.
Dan Waylonis
Comment 6
2006-08-01 16:01:51 PDT
Created
attachment 9805
[details]
Updated patch with ggaren's suggestions
Dan Waylonis
Comment 7
2006-08-01 16:02:46 PDT
I made a new patch using Geoff's suggestion to put the ExecState backpointer in the Context.
Geoffrey Garen
Comment 8
2006-08-01 19:26:14 PDT
This looks pretty good. + ExecState(Interpreter* interp, Context* con); In this prototype, and others, there's no need to provide names that give no additional data. This would be better: + ExecState(Interpreter*, Context*); +ExecState::ExecState(Interpreter* interp, Context* con) In this implementation, and others, it would be clearer to use the full words "interpreter" and "context." + void setExecState(ExecState *es) { m_execState = es; } Our formatting guidelines say to use "Type* " rather than "Type *", even though not all of our code follows that guideline yet. Also, it's an idiom throughout JavaScriptCore to name ExecState variables "exec", rather than "es". - (void)setException:(NSString *)description { - if (const RootObject *root = [self _executionContext]) - throwError(root->interpreter()->globalExec(), GeneralError, description); + [[self class] throwException:description]; } This isn't quite right, as it won't necessarily set an exception in the target object's execution context, which is what the API promises. You really want logic that says, "Use root->interpreter()->context()->execState() if it exists, otherwise root->interpreter()->globalExec()." + void setExecState(ExecState *es) { m_execState = es; } + ExecState* execState() { return (m_execState); } I think it's impossible to create a Context without having an ExecState available. So a clearer approach would be to require an ExecState as an argument to the Context's constructor. Then you could change this code + if (state) { + throwError(state, GeneralError, exceptionMessage); return YES; + } else + fprintf(stderr, "No exec state for 0x%x\n", (unsigned int)interp->context()); } into an assertion. Also, "state" should be "exec".
Geoffrey Garen
Comment 9
2006-08-01 19:27:03 PDT
PS. "throwIfArgumentIsNotHello" is a pretty cool method name.
Dan Waylonis
Comment 10
2006-08-03 18:00:08 PDT
Created
attachment 9864
[details]
Patch to fix WebKitPlugin exceptions Using Geoff's suggestions to update the patch. I wasn't able to use the ExecState as an argument to the Context's constructor as there are times that the Context is created before the new ExecState (JSC/kjs/function.cpp: callAsFunction()) is created.
Igor Morozov
Comment 11
2006-08-16 13:41:16 PDT
I got the same problem developing plugin for safari. The only difference is that I'm using NPAPI. So if I call setexception I cannot try/catch it in Javascript. I don't get any exception at all. Are you guys saying there is no way to throw an exception in current execution context?
Dan Waylonis
Comment 12
2006-08-22 13:52:55 PDT
Comment on
attachment 9864
[details]
Patch to fix WebKitPlugin exceptions Please review.
Darin Adler
Comment 13
2006-08-29 13:41:06 PDT
Comment on
attachment 9864
[details]
Patch to fix WebKitPlugin exceptions Is there a reason the ExecState function has been changed to no longer be inlined? I ask because I'm concerned about how the change might affect performance, and avoiding one extra level of function call in code that is used in only a few places seems still worthwhile. Formatting is incorrect in ExecState.cpp: indenting is inconsistent and we normally indent the initializers rather than putting them flush left. + ExecState* execState() { return (m_execState); } We don't put parentheses around return statements like these. We'll need to do a performance test to check that this is OK. Actually I have one big question. What guarantees that the context won't outlast the execution state? I'm worried that the code in WebScriptObject.mm might try to set the exception in a deallocated ExecState on the stack. review- only because of that one last question. The other issues seem to be minor ones.
Dan Waylonis
Comment 14
2006-08-29 15:30:11 PDT
Created
attachment 10307
[details]
Patch to fix WebKitPlugin exceptions Fix indention, formatting, parenthesis.
Dan Waylonis
Comment 15
2006-08-29 15:38:20 PDT
I changed the ExecState constructor to be in the .cpp file because I couldn't get it to compile when it was inlined in the ExecState.h file. As far as the concern about a deallocated ExecState goes, I don't know. If I had to take a guess, it seems like ExecState and Context travel in pairs. If you haven't already seen bugs with exceptions being thrown with stale Contexts, then you probably won't see the problem with ExecState.
Geoffrey Garen
Comment 16
2006-08-29 15:38:40 PDT
Comment on
attachment 9864
[details]
Patch to fix WebKitPlugin exceptions I spoke with Darin about this. The Context won't outlast the ExecState because both are allocated in tandem on the stack. Our current code relies on the same idiom to ensure that the ExecState won't outlast the Context. Eventually, ExecState and Context should just merge to become the same object.
Geoffrey Garen
Comment 17
2006-08-29 15:40:50 PDT
(In reply to
comment #11
)
> I got the same problem developing plugin for safari. The only difference is > that I'm using NPAPI.
Igor, the NPAPI is a completely different API. With respect to the WebKit Objective-C API, no, without this patch there is no way to throw an exception in the current execution context.
Geoffrey Garen
Comment 18
2006-08-29 16:10:26 PDT
I'll land this after performance testing.
Geoffrey Garen
Comment 19
2006-08-30 11:39:00 PDT
Committed revision 16117.
Timothy Hatcher
Comment 20
2006-09-02 11:29:45 PDT
This has landed, why is there another patch waiting to be reviewed?
Darin Adler
Comment 21
2006-09-03 12:19:07 PDT
Comment on
attachment 10307
[details]
Patch to fix WebKitPlugin exceptions I'm clearing the review flag on this.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug