Closed
Bug 108474
Opened 24 years ago
Closed 14 years ago
PRESERVE_JSOBJECT_IDENTITY must be defined for compatibility
Categories
(Core Graveyard :: Java: Live Connect, defect)
Core Graveyard
Java: Live Connect
Tracking
(Not tracked)
RESOLVED
INCOMPLETE
People
(Reporter: tjw, Unassigned)
Details
Attachments
(1 file)
|
6.62 KB,
patch
|
Details | Diff | Splinter Review |
Well, I just spent my Sunday tracking down a 'bug' in the LiveConnect
library. I feel silly since I've already tracked this bug down once in the
LiveConnect implementation I was working on before switching to the
Mozilla implementation. I say 'bug' because it is really a misuse of
LiveConnect by Adobe.
The problem is that the SVG plugin from Adobe doesn't obey the 'internal'
part of JSObject.internal. They try to work around a Netscape bug (I don't
know what versions or if it is fixed already or what) where objects created
via LiveConnect don't have their __parent__ and __proto__ slots set up
correctly.
So, they reach in and grab the internal field and set these slots. Really.
I figured out a bunch of this and contacted the SVG folks at Adobe who
confirmed that (a) this is what happens and (b) the plugin is already
shipping so it's going to have to stay that while for a way.
They didn't have a good way of determining at runtime whether the bug
was fixed (or at least didn't have time to figure it out).
So in the Mozilla implementation of LiveConnect, this bug manifests
itself as overwriting the pointer to the first JSArena in the JSArenaPool
gcArenaPool in the JSRuntime. This is because we have:
struct JSObjectHandle {
JSObject *js_obj;
JSRuntime *rt;
};
but they are assuming that the internal field is a JSObject, so they read
the second word of the internal pointer (the rt pointer here, the 'slots' in
JSObject) and write to the first two words pointed to by that (the __proto__
and __parent__ fields in JSObject's slots).
Sadly, when I try to build LiveConnect with
PRESERVE_JSOBJECT_IDENTITY defined, I get a #error saying that it
isn't fully implemented. It really needs to and probably needs to be made
the default (at least it does if you ever want to load the Carbon SVG plugin
on Mac OS X).
I'll be looking at what needs to be implemented still with this option, but I
thought I would bring this to your attention.
I'm not really sure why the option is still there if no one knew about this
SVG grossness, but I didn't find any bugs mentioning
PRESERVE_JSOBJECT_IDENTITY.
Here is the mail from the SVG plugin developer talking about this issue:
Date: Thu, 18 Oct 2001 14:53:24 -0700
Subject: Mac OS X SVG plugin in OmniWeb
From: "Timothy J. Wood" <tjw@omnigroup.com>
To: palewis@adobe.com
X-Mailer: Apple Mail (2.472)
Hi Paton!
I was given your email address by Greg Christopher as a contact for the
SVG plugin.
I'm currently trying to get the SVG plugin fully functional in OmniWeb,
including LiveConnect support. With a small tweak I got OmniWeb to load
the plugin and display SVG (basically to the same extent that IE does).
I've got a chunk of LiveConnect working now, but there is still quite a bit
left to do.
I've run into one pretty ugly stumbling block in that the SVG plugin reads
the 'internal' field of my netscape.javascript.JSObject implementation
(which is bad enough) but even worse, it reads and writes values through
that pointer. As the SVG plugin has no idea how my data is laid out, it
clobbers memory by doing this.
It ends up that the SVG plugin reads 'internal', then reads the second
word of the returned value (as a pointer). Finally the first words pointed to
by this pointer is written. It may be that the is even more access to this
internal field later on in the program -- I've only looked at the immediate
crasher problems so far in order to continued work on supporting the
plugin.
I have worked around this by setting up a big block of memory as my
internal field and putting all my stuff way at the end (and setting up the
second word to point the third to have a valid pointer above).
We would really like to get the SVG plugin fully functional in some
browser on the Mac (apparently IE doesn't support LiveConnect yet) and
we certainly would hate to ship our LiveConnect support with this terrible
hack.
I presume that the SVG plugin is assuming some structure
(undocumented as far as I can tell) on the part of the 'internal' field. Our
best outcome would be to have the plugin not access this field at all (hey,
it is named 'internal' :), but failing that, if you could point us at some
documentation about the structure of the internal field, we may be able to
emulate it for the short term.
From: Peter Sorotokin <psorotok@adobe.com>
Date: Thu Oct 18, 2001 08:50:43 PM US/Pacific
To: tjw@omnigroup.com
Cc: "Paton J. Lewis" <palewis@adobe.com>
Subject: Re: Fwd: Mac OS X SVG plugin in OmniWeb
Tim,
It's amazing how you've been able to figure all this out! Your description is
actually almost
complete.
SVG plug-in assumes that internal field references JSObject (C structure,
not Java class,
referer to JavaScript interpreter source code that can be found in Mozilla
distribution, see file jsapi.h).
Here is relevant comment from our source code (from the place where
these assignemnts happen):
// This is a NN JavaScript hack. We cannot create proper JSObject
// through LiveConnect, unless call originated from JavaScript itself
// JSObject.exec is not enough. But we cannot cause external
JavaScript
// to call us (the only way is to use javascript: URL, but that
// causes random crashes). So we get handicapped object that
LiveConnect
// created and "fix" it by changing its __proto__ and __parent__
// internal properties. NN JavaScript is garbage-collection based, so
// no need to care about refcounts.
If we don't do this, we get not fully initialized javascript object from
LiveConnect that
we cannot use as global object for our scripts. Therefore we must do this
hack
for Netscape. This is the only place on Mac where we do think kind of
hacks in
LiveConnect, so if you worked around those, you should be OK.
I can see this creating problems to you if your internal field does not
exactly match
Netscape's... We will have to discuss what we can do about it, but since
we are
long past RC, I cannot promise anything, even if it is trivial to do. Would
sniffing your
"user agent" and not applying this "fix" if we see OmniWeb there be
enough?
Note that we create our own "global" object and evaluate all our scripts in
context
of this object. Unless parent link of this object is properly set to HTML
window
object some scripts will not work properly in SVG plug-in. Netscape does
not
do it properly (I think it is a bug in their code) and we "fix" it, so your object
must be correct or SVG scripting will not work right.
Peter
Updated•24 years ago
|
Status: UNCONFIRMED → NEW
Ever confirmed: true
| Reporter | ||
Comment 1•24 years ago
|
||
I've got most of a patch working but there is one ugly problem (which is
presumably why the object handle goo was added in the first place).
In Java_netscape_javascript_JSObject_finalize we need to remove the
root to the JavaScript JSObject (by calling
jsj_remove_js_obj_reflection_from_hashtable). This function currently
requires a JSContext argument which it just uses to call
JS_RemoveRoot(). We could just as easily use a JSRuntime (as the
object handle code does) and call JS_RemoveRootRT().
I would propose that rather than creating an object handle and using that
as the internal field, that another private field, "jsRuntime", be added to
netscape.javascript.JSObject. Hopefully there aren't ever enough
JSObject instances around that the space for the extra pointer will matter.
This will allow removing the root from the hash table w/o trying to figure
out what JSContext to use (which is hard since there isn't necessarily any
other JavaScript on the stack and thus the embedding application doesn't
necessarily have an opportunity to maintain a current context stack).
Comments?
| Reporter | ||
Comment 2•24 years ago
|
||
Another alternative, obviously, would be to take JSRuntime used when
adding the JavaScript JSObject to the hashtable and stick it in the bucket.
It looks like the hash table can have a pair of functions to allocate/
deallocate buckets so we could just define a custom bucket type that has
a JSRuntime pointer in it too.
This sounds better than the extra field on netscape.javascript.JSObject.
| Reporter | ||
Comment 3•24 years ago
|
||
The following patch turns on PRESERVE_JSOBJECT_IDENTITY by default and implements all the parts that were missing before.
In particular, the identity hash table buckets now store a pointer to the runtime for the object so that the finalize Java method can be implemented. Added a trivial jsj_UnwrapJSObjectWrapper().
Implemented Java_netscape_javascript_JSObject_equals() to consider to object reference equal if they are the same Java object (according to JNI IsSameObject()). This is correct because of the invariant that there is a one to one mapping between JavaScript JSObjects and Java JSObjects when PRESERVE_JSOBJECT_IDENTITY is defined.
| Reporter | ||
Comment 4•24 years ago
|
||
Comment 5•24 years ago
|
||
Reassigning to Patrick for consideration of this patch -
Assignee: rogerl → beard
Comment 6•19 years ago
|
||
-> default assignee for old netscape assigned bugs.
Assignee: beard → live-connect
Comment 7•19 years ago
|
||
Since the PRESERVE_JSOBJECT_IDENTITY part isn't fully implemented, there need to be a patch to complete it. How can we verify the patch with SVG plugins?
"njJSObject_long_internal" seems to be also an internal part of Java Object. Do we need another way to read it instead touching the "internal"? I think it's fine for us to read it. But It's not correct to write it.
In the bug description, it said that there isn't a good way to "create proper JSObject through LiveConnect, unless call originated from JavaScript itself". I guess the idea is that "LiveConnect don't have their __parent__ and __proto__ slots set up correctly." Then the question is can we fix the problem in Liveconnect itself? I notice that there are two member functions in "struct JSObjectOps" named "setProto" and "setParent". They are NULL in the "JavaObject_ops" for Java Object. Can we implement these functions to set the __parent__ and __proto__ instead writing to the slots directly?
Any comments?
Comment 8•14 years ago
|
||
Firefox code moved from custom Liveconnect code to the NPAPI/NPRuntime bridge a while back. Mass-closing the bugs in the liveconnect component which are likely invalid. If you believe that this bug is still relevant to modern versions of Firefox, please reopen it and move it the "Core" product, component "Plug-Ins".
Status: NEW → RESOLVED
Closed: 14 years ago
Resolution: --- → INCOMPLETE
You need to log in
before you can comment on or make changes to this bug.
Description
•