Closed
Bug 22048
Opened 26 years ago
Closed 25 years ago
XUL brutal sharing needs super-prototype love
Categories
(Core :: JavaScript Engine, defect, P1)
Tracking
()
RESOLVED
FIXED
M15
People
(Reporter: mcafee, Assigned: brendan)
Details
(Keywords: js1.5)
Attachments
(5 files)
|
752 bytes,
patch
|
Details | Diff | Splinter Review | |
|
7.33 KB,
text/html
|
Details | |
|
23.88 KB,
patch
|
Details | Diff | Splinter Review | |
|
20.67 KB,
patch
|
Details | Diff | Splinter Review | |
|
409 bytes,
text/plain
|
Details |
Got a JS emoticon error this morning,
input text field stopped accepting input and
I had to quit the app. Not sure how I did this,
if you need more info I can research the problem more.
Updated•26 years ago
|
Status: NEW → ASSIGNED
Component: XPApps → chatzilla
Summary: IRC: JS emoticon error → IRC: JS emoticon error
Comment 1•26 years ago
|
||
(changing component to chatzilla)
Was the message something like "emoticon.search has no properties" around line
193 in test-static.js?
afaik, that's the only place in the code it's actually referred to as an
"emoticon". This patch *should* prevent the hard error, but I've got no idea
how it actually occurs. I'll check this in when the tree opens.
Index: munger.js
===================================================================
RCS file: /cvsroot/mozilla/extensions/irc/xul/lib/munger.js,v
retrieving revision 1.1
diff -u -r1.1 munger.js
--- munger.js 1999/11/29 03:57:33 1.1
+++ munger.js 1999/12/17 21:38:10
@@ -64,7 +64,7 @@
else
ary = text.match(this.entries[entry].regex);
- if (ary != null)
+ if ((ary != null) && (ary[1]))
{
var startPos = text.indexOf(ary[1]);
| Reporter | ||
Comment 2•26 years ago
|
||
yes, the error looked like that.
Didn't know about chatzilla component, nice!
Updated•26 years ago
|
Status: ASSIGNED → RESOLVED
Closed: 26 years ago
Resolution: --- → DUPLICATE
Comment 3•26 years ago
|
||
| Assignee | ||
Updated•26 years ago
|
Status: RESOLVED → REOPENED
| Assignee | ||
Comment 4•26 years ago
|
||
THis
| Assignee | ||
Updated•26 years ago
|
Assignee: rginda → brendan
Status: REOPENED → NEW
| Assignee | ||
Updated•26 years ago
|
Status: NEW → ASSIGNED
| Assignee | ||
Updated•26 years ago
|
Resolution: DUPLICATE → ---
| Assignee | ||
Updated•26 years ago
|
Priority: P3 → P1
| Assignee | ||
Comment 5•26 years ago
|
||
Er, that is to say: this is a distinct bug from 22098 -- see my comment with two
alternative fixes in bug 22098 for more.
/be
| Assignee | ||
Updated•26 years ago
|
Target Milestone: M13
| Assignee | ||
Updated•26 years ago
|
Summary: IRC: JS emoticon error → JS compiler-looks-up-RegExp bug exposed by brutal sharing in XUL
| Assignee | ||
Updated•26 years ago
|
Summary: JS compiler-looks-up-RegExp bug exposed by brutal sharing in XUL → JS compiler-looks-up-RegExp bug exposed by XUL brutal sharing
| Assignee | ||
Updated•26 years ago
|
Summary: JS compiler-looks-up-RegExp bug exposed by XUL brutal sharing → JS compiler-looks-up-RegExp (exposed by XUL brutal sharing)
Comment 6•26 years ago
|
||
The real patch to make chatzilla work is:
Index: test3-static.js
===================================================================
RCS file: /cvsroot/mozilla/extensions/irc/xul/tests/test3-static.js,v
retrieving revision 1.11
@@ -131,7 +132,8 @@
"event-tracer", true /* negate */,
false /* disable */);
- obj.munger = new CMunger();
+ obj.munger = new CMunger();
+ /*
obj.munger.addRule ("you-talking-to-me?", matchMyNick, "");
obj.munger.addRule
("link", /((http|mailto|ftp)\:\/\/[^\)\s]*|www\.\S+\.\S[^\)\s]*)/,
@@ -140,13 +142,14 @@
("face",
/((^|\s)[\<\>]?[\;\=\:\8]\~?[\-\^\v]?[\)\|\(pP\<\>oO0\[\]\/\\](\s|$))/,
insertSmiley);
- obj.munger.addRule ("rheet", /(rhe+t\!*)/i, "rheet");
+ obj.munger.addRule ("rheet", /(rhee+t\!*)/i, "rheet");
obj.munger.addRule ("bold", /(\*.*\*)/, "bold");
obj.munger.addRule ("italic", /[^sS](\/.*\/)/, "italic");
obj.munger.addRule ("teletype", /(\|.*\|)/, "teletype");
obj.munger.addRule ("underline", /(\_.*\_)/, "underline");
//obj.munger.addRule ("strikethrough", /(\-.*\-)/, "strikethrough");
obj.munger.addRule ("smallcap", /(\#.*\#)/, "smallcap");
+ */
}
| Assignee | ||
Updated•26 years ago
|
OS: other → All
Hardware: Other → All
| Assignee | ||
Comment 7•26 years ago
|
||
I'm going with my solution #1: Call JS_InitStandardClasses(cx) in the XUL code
that makes this "prototype global" object against which XUL scripts are
compiled." Auto-cloning RegExp objects created by the JS compiler for literal
regular expressions imposes too much overhead on compile/exec evaluation (where
there is no brutal compile early, exec later in multiple contexts, sharing).
Patch coming up.
/be
| Assignee | ||
Comment 8•26 years ago
|
||
Comment 9•26 years ago
|
||
Patch fixes both bugs.
| Assignee | ||
Updated•26 years ago
|
Status: ASSIGNED → RESOLVED
Closed: 26 years ago → 26 years ago
Resolution: --- → FIXED
| Assignee | ||
Comment 10•26 years ago
|
||
Fixed in rdf/content/src/nsXULPrototypeDocument.cpp.
/be
Comment 11•26 years ago
|
||
This is still showing up in the WinNT builds.
/foo/ instanceof RegExp fails in windows, works as expected in linux debug and
opt.
Status: RESOLVED → REOPENED
Component: chatzilla → Javascript Engine
OS: All → Windows NT
Comment 13•26 years ago
|
||
Clearing FIXED resolution due to reopen. Setting QA Contact to rginda
QA Contact: desale → rginda
Resolution: FIXED → ---
| Assignee | ||
Comment 14•26 years ago
|
||
Not an M13 stopper. The problem is no longer that /hi/.test is not defined -- we
fixed that. Now the problem is that /hi/ instanceof RegExp is false in XUL
windows because brutal sharing uses a secret global object to scope the
compilation of /hi/, and then at runtime uses a DOM XUL window to scope the right
operand, RegExp. We've broken prototype identity, yay!
This can be fixed in M14, either by sharing one set of standard classes among all
XUL windows, or by two-layer prototype hierarchy.
/be
Status: REOPENED → ASSIGNED
Target Milestone: M13 → M14
| Assignee | ||
Updated•26 years ago
|
Summary: JS compiler-looks-up-RegExp (exposed by XUL brutal sharing) → XUL brutal sharing needs super-prototype love
Comment 15•26 years ago
|
||
Comment 16•26 years ago
|
||
uuh, ignore that attachment. Wrong bug.
| Assignee | ||
Comment 17•26 years ago
|
||
Argh, two-layer prototype hierarchy is impossible: say you have a XUL window, x,
and the prototype document d. Then if you make
d.Object.prototype === x.Object.prototype.__proto__
you can't arrange for
(new x.RegExp("hi")) instanceof x.Object
because JS supports only a single prototype per object
(x.RegExp.prototype.__proto__ === x.RegExp.prototype, and
x.RegExp.prototype.__proto__ === x.Object.prototype, and
x.Object.prototype.__proto__ === null, but there cannot be any
x.Object.prototype along that chain).
So we're left with one set of standard classes for all XUL windows. This is
certainly faster, too. It requires changing the DOM code in nsGlobalWindow.cpp
so that ::JS_InitStandardClasses is not always called. For XUL windows, I think
we want to clone each standard class constructor function; non-constructors such
as Math we can share by reference. We need constructor clones so that instances
get parented by their particular XUL windows, not by the hidden XUL prototype
document script object used for compilation. Hope this is clear enough!
I'll hack up a patch to extend the JS API with JS_CloneStandardClasses.
/be
Assignee: brendan → waterson
Status: ASSIGNED → NEW
Comment 18•26 years ago
|
||
Remember, all XUL cometh not from the same security domain. We can load XUL
files just like regular content. So this may require some cleverness in the code
that is init-ing standard classes to determine whether it can share or not.
Status: NEW → ASSIGNED
| Assignee | ||
Comment 20•26 years ago
|
||
I'd go further: XUL loaded from untrusted domains (not from the unified,
singular domain of chrome:) should not brutally share the prototype document's
script object for compile-time constructors (Function, RegExp). Can we have a
per-origin compile-time scope object? That would seem to preserve the identity
relations we crave, without compromising security.
/be
| Assignee | ||
Comment 21•26 years ago
|
||
I'm a dumbass, typos messed up my example (note d for x everywhere after the
first ==='s left operand):
(x.RegExp.prototype.__proto__ === d.RegExp.prototype, and
d.RegExp.prototype.__proto__ === d.Object.prototype, and
d.Object.prototype.__proto__ === null, but there cannot be any
x.Object.prototype along that chain).
Anyway, same punchline: no "MI" or multiple prototype delegation a la Self in
JS, wahhh.
/be
| Assignee | ||
Comment 22•26 years ago
|
||
I promised a JS_CloneStandardObjects patch, but thinking about it more, I bet we
can do even better, in terms of per-XUL-window set-new-document cost.
Instead of cloning a bunch of constructors, some of which may never be called,
we should specialize the XUL window resolve hook (JSClass.resolve, or perhaps
better: nsIJSScriptObject::Resolve) to look for undefined properties named by
XUL scripts in the prototype document's script object. If a property of the
same name is found there, check its type (JS_TypeOfValue). If JSTYPE_FUNCTION,
then JS_CloneFunctionObject and JS_DefineProperty; else just JS_DefineProperty
to share the value.
Waterson, I may cough up a patch for this if it'll help you. I probably won't
do the work in dom/src/base to avoid calling ::JS_InitStandardClasses, or the
work to make a per-trust-domain locus of compilation scope and standard classes.
/be
| Assignee | ||
Comment 23•26 years ago
|
||
OK, I don't think this is a js1.5 bug any more (although I still question the
special case whereby e instanceof Exception is true no matter which
Exception.prototype e delegates to, in a world of multiple top-level objects and
their standard classes (including Exception)).
/be
Keywords: js1.5
Comment 24•25 years ago
|
||
brendan: backatcha.
Assignee: waterson → brendan
Status: ASSIGNED → NEW
Target Milestone: M15 → M16
| Assignee | ||
Comment 25•25 years ago
|
||
I'm actually interested in revamping the context-universal e instanceof
SyntaxError (e.g.) behavior, generalizing it so that instanceof works for brutal
sharing embeddings of JS too. Also, the way jsfun.c and jsexn.c conspire to
implement this (js_exnHasInstance) seems flimsy, or hokey, or something -- but I
haven't spent the time to think of a general way. I'll do that now.
/be
Status: NEW → ASSIGNED
| Assignee | ||
Updated•25 years ago
|
Target Milestone: M16 → M15
| Assignee | ||
Comment 26•25 years ago
|
||
| Assignee | ||
Comment 27•25 years ago
|
||
| Assignee | ||
Comment 28•25 years ago
|
||
Read the -wu diffs for best code-buddying results. Note also that I'm checking
in the fix for http://bugzilla.mozilla.org/show_bug.cgi?id=33391 (included in
jsfun.c).
/be
| Assignee | ||
Comment 29•25 years ago
|
||
Looking for some r= love tonight (M15 deadline).
/be
Comment 30•25 years ago
|
||
Comment 31•25 years ago
|
||
js engine passes all tests, mozilla passes testcase.
| Assignee | ||
Comment 32•25 years ago
|
||
Adding jband.
/be
Comment 33•25 years ago
|
||
r=jband
| Assignee | ||
Comment 34•25 years ago
|
||
Thanks to jband's review, I fixed the #undef WRAP_EXCEPTION to be #undef
MAKE_EXCEPTION_CTOR, and I squished a warning by making the sentinel initializer
at the end of the exceptions table be {0,0,NULL} rather than {0,0}.
/be
| Assignee | ||
Comment 35•25 years ago
|
||
Fixed, thanks to jband, mccabe, and rginda.
/be
Status: ASSIGNED → RESOLVED
Closed: 26 years ago → 25 years ago
Resolution: --- → FIXED
Comment 36•25 years ago
|
||
This patch is an improvement for native objects, but I'm not sure it's as
general as it could be for user-defined functions.
With a little dredging, I remembered the original problem with using the
'constructor' property to implement. (Apologies to Brendan, if this is what you
showed me on John's whiteboard.) This objection applies to user-generated
functions, might apply to brutal-shared functions, and doesn't apply to
builtins.
The constructor property is a property of the initial, default .prototype
property of newly generated user functions. In general, user-generated function
hierarchies are built by assinging to function .prototype properties. This
overwrites the .constructor information, so it can't be used to test whether an
object was built by a given function.
Function A() {}
// A gets .prototype property, and .prototype.constructor === A
Function B() {}
// ditto
// Make A instances get behavior from B.prototype
A.prototype = new B // overwrites A.prototype.constructor
a = new A(); // a.__proto__ === B.prototype
a.__proto__.constructor === B // !
a instanceof A
a instanceof B
In the single-window case, these expressions are both true, by the
prototype-chasing hasInstance. Is the first expression true in the
brutal-sharing case? Does the question even come up, for brutally-shared
user-defined functions?
| Assignee | ||
Comment 37•25 years ago
|
||
Good point, the first expression (a instanceof A) is false in the brutal sharing
case, unless you add A.prototype.constructor = A; after A.prototype = new B.
The (a.__proto__.constructor === B) invariant that you commented with // ! has
always been an anomaly in this kind of JS, brutal sharing or no brutal sharing.
I mean, we just constructed a via (new A), so you'd think a's constructor was A,
eh? [sorry] OTOH, A.prototype was set to a (new B), and all instances of B
I remember this coming up in the ancient days, 3.0 or so, and I advised folks
then to set A.prototype.constructor = A after setting A.prototype = new B. This
is exactly what the JS engine does (js_SetClassPrototype) for natives: when you
set constructor.prototype, you set .prototype.constructor to point back. So, is
this policy good enough (if documented -- help me, rginda!) to close the bug?
/be
| Assignee | ||
Comment 38•25 years ago
|
||
Oops, didn't finish editing that last sentence of paragraph 2: "OTOH,
A.prototype was set to a (new B), and all instances of B " should have read
"OTOH, A.prototype was set to an instance of B (new B), whose constructor is
naturally enough B."
Notice that any brutal sharer may set A.prototype.constructor = A, even though
each sharer gets its own function-object clone for A. Brutal sharing means that
either all the function objects (clone-parent when brutally-shared source was
loaded; clones for each sharing "context") have the same native function
pointer, or they all have the same shared JSScript. Brutal sharing thus reduces
JS-compiled scripts to equivalence in number and shared-ness with C or C++
compiled native functions.
/be
You need to log in
before you can comment on or make changes to this bug.
Description
•