Closed
Bug 312116
(js-catchall)
Opened 19 years ago
Closed 14 years ago
should support catchall getters/setters
Categories
(Core :: JavaScript Engine, enhancement, P2)
Core
JavaScript Engine
Tracking
()
RESOLVED
WONTFIX
People
(Reporter: shaver, Unassigned)
References
Details
Attachments
(1 file, 1 obsolete file)
(deleted),
patch
|
Details | Diff | Splinter Review |
We want to be able to do things like:
js> o = { get *(name) { return name + "!"; } };
[object Object]
js> o.foo
foo!
Don't you agree?
Reporter | ||
Comment 1•19 years ago
|
||
This makes getters and toSource work, but still needs:
- setters
- Object.prototype.__define[GS]etter__ support
- a distinguished XDR representation of the anyname atom for proper
serialization behaviour
Ahoy!
Comment 2•19 years ago
|
||
It would be great if it could also [gs]et constructs like
Object.foo::@bar
for E4X stuff.
Reporter | ||
Comment 3•19 years ago
|
||
Sean: gimme a test case? Synthesizing the XML data-model parts sounds like
pain, but I'll keep an open mind.
Assignee: general → shaver
Comment 4•19 years ago
|
||
(In reply to comment #3)
> Sean: gimme a test case? Synthesizing the XML data-model parts sounds like
> pain, but I'll keep an open mind.
Shaver: it'll all just work if you handle an id for which JSID_IS_OBJECT
evaluates to true.
/be
Reporter | ||
Comment 5•19 years ago
|
||
Now supports setters, and __define[GS]etter__(*, function(){}). Also should be XDR-friendly (haven't tested it yet). Sucks to not be able to remove getters or setters, but I bet there are good reasons for that, or something.
Need to figure out how having a default getter should interact with the 'in' operator, if at all.
Haven't tested Sean's testcase yet, but I don't think it'll work -- there is code in there to explicitly defend again object-named properties on non-XML objects, and I'm not sure I want to remove that check without a lot more auditing.
Attachment #199239 -
Attachment is obsolete: true
Reporter | ||
Updated•19 years ago
|
Attachment #200666 -
Flags: superreview?(brendan)
Attachment #200666 -
Flags: review?(mrbkap)
Comment 6•19 years ago
|
||
Comment on attachment 200666 [details] [diff] [review]
WIP 2
The anya/anyv code should be a common subroutine. But more important: why can't the special case, instead of slowing down the general js_SetProperty etc. control flow, be done under the hood, by a getter/setter pair defined just for the anyname object id?
/be
Reporter | ||
Comment 7•19 years ago
|
||
Another problem with this, beyond brendan's wholly unreasonable insistence that I make only users of this capability pay for it :), is that once you have a fallback setter you can't create a new "normal" property on such an object. You have to resort to defining getters/setters, which is pretty gross.
Object.prototype.__addProperty__(propName, initialValue) ? It would throw if the property already existed.
MOPs are hard, waah.
Updated•18 years ago
|
Attachment #200666 -
Flags: review?(mrbkap)
Updated•17 years ago
|
Attachment #200666 -
Flags: superreview?(brendan)
Updated•17 years ago
|
Alias: js-catchall
Summary: should support fallback getters/setters → should support fallback getters/setters (JS2/ES4 catchalls)
(In reply to comment #0)
> Don't you agree?
Much better if we can get...
js> o = {get *(){a=arguments; return a[2]+' in '+a[1]+' in '+a[0];}};
[object Object]
js> o.my.foo.bar
bar in foo in my
Reporter | ||
Comment 10•17 years ago
|
||
Important note: ES4 catchalls aren't _fallbacks_ -- they're always called, and before default behaviour. There is still discussion underway about how to signal that the default behaviour should be used, possibly by throwing a specific exception (like the iteration protocol).
I may also propose that when in get * for a property p, the catchall is skipped on a nested get of p.
Reporter | ||
Updated•17 years ago
|
Summary: should support fallback getters/setters (JS2/ES4 catchalls) → should support catchall getters/setters
Comment 11•17 years ago
|
||
(In reply to comment #10)
> Important note: ES4 catchalls aren't _fallbacks_ -- they're always called, and
> before default behaviour.
For dynamic properties (ES4 folks will know what this means), not for fixtures.
> There is still discussion underway about how to
> signal that the default behaviour should be used, possibly by throwing a
> specific exception (like the iteration protocol).
That's actually the proposal. It needs detailing but we are not likely to change to another out-of-band signal.
> I may also propose that when in get * for a property p, the catchall is skipped
> on a nested get of p.
We're against new syntax in object initialisers for catch-alls, as of today's ES4 working group meeting. We see no need given const in an object initialiser before the property label making a read-only, don't-delete property (a fixture), and property names allowing namespace qualifiers in initialisers:
var obj = { const meta::get: function (id) ...,
const meta::set: function (id, val) ...,
... };
SpiderMonkey has namespace qualifiers via E4X. It has const of a sort, but the details of const hoisting and use-before-set don't crop up here in initialisers.
/be
Comment 12•16 years ago
|
||
Adding this to the 1.9.1 triage queue by marking this wanted1.9.1?. If this should be a blocker, please mark accordingly.
Flags: wanted1.9.1?
Priority: -- → P2
Updated•16 years ago
|
Flags: wanted1.9.1? → wanted1.9.1+
Comment 13•16 years ago
|
||
Adding catchall getters could make it easier to steal information from certain sites. For example, consider a site that serves a text file containing only one word or hex string. With script src and a catchall getter, a script on another site could find out what the string is.
Comment 14•16 years ago
|
||
Why the focus around a * getter?
Isn't * a valid property name if you are using ['*']?
ie: Isn't this valid?
var o = {};
o.__defineGetter__('*', function() 'foo');
o['*']; // foo
IMHO, a catchall getter/setter should work more like __noSuchMethod__.
ie: __get__ and __set__.
o.__get__ = function(propName) ...;
o.__set__ = function(propName, value) ...;
(In reply to comment #9)
> (In reply to comment #0)
> > Don't you agree?
>
> Much better if we can get...
>
> js> o = {get *(){a=arguments; return a[2]+' in '+a[1]+' in '+a[0];}};
> [object Object]
> js> o.my.foo.bar
> bar in foo in my
I don't see to much need for that. Shouldn't using closures and getters together handle that?
var o = {
__get__: function(a) {
return {
__get__: function(b) {
return {
__get__: function(c) {
return c + ' in ' + b + ' in ' + a;
}
};
}
};
}
};
Comment 15•16 years ago
|
||
The use of * is new syntax, not a property name to be equated to "*". Using * will not conflict with any nameable property's id, including "*".
Catch-alls are out of favor in TG1, at least among a few heavy hitters. More on this in es-discuss when I have time (next few days).
/be
Comment 16•16 years ago
|
||
(In reply to comment #13)
> Adding catchall getters could make it easier to steal information from certain
> sites. For example, consider a site that serves a text file containing only
> one word or hex string. With script src and a catchall getter, a script on
> another site could find out what the string is.
That issue could be easily negated by disabling the ability to set a catchall getter or setter on the global object.
I see use for setting local getters and setters on the global object, however I see no logical use for setting a catchall getter or setter on the global object.
Of course, I recommend this being dependent on a not allowed by default option rather than being hardcoded as not permitted.
While this security issue you mention exists within the browser environment, it does not have any issue within a server environment. Afact jslibs already provides ObjEx which allows for absolute control over spying and modifying all property get/set/add/del actions on a special object. It would just be preferable for catchall getters/setters to be implemented as they would likely perform better for the majority of possible cases why ObjEx would be used.
Updated•15 years ago
|
Severity: normal → enhancement
Updated•15 years ago
|
Flags: wanted1.9.1+
Comment 17•14 years ago
|
||
We just ran into a case where this would help unimplemented methods in the window's console object called indirectly via apply or call fallback gracefully. Would be nice to have, but based on the date on the WIP patch, this hasn't been looked at for awhile.
Reporter | ||
Comment 18•14 years ago
|
||
I think you want to make the window.console object be a proxy instead, then. There are threads on es-discuss that show how to emulate __noSuchMethod__ in these cases using proxies.
I think this bug is WONTFIX: proxies are the way forward, catchalls have been dropped for all plans for ES/JS that I know of.
Status: NEW → RESOLVED
Closed: 14 years ago
Resolution: --- → WONTFIX
Comment 19•14 years ago
|
||
ok, thanks for the pointer.
Comment 20•14 years ago
|
||
I see 2 problems with PROXY
1. When you make a variable winProxy as a proxy for window object, all those place where somebody reference variable winProxy you get catchall mechanism but if some code refer window you dont have catchall mechanism.
2. When you make a variable winProxy as a proxy for window object, when ever somebody refer winProxy.document it execute few lines of JavaScript code even though "document" is a built-in/native property of "window" object. Hence resulting code become very inefficient.
PROXY are useful when you want to hide an object,
but not when you want add additional features for existing object.
Comment 21•14 years ago
|
||
Biju:
Re 1: don't do that, then. Confine the window object properly, expose only the proxy to all consumers who need to see the catchalls.
Re 2: "very inefficient" needs profiling data as proof. We use proxies for window objects in Firefox 4. They're efficient enough. Scripted handler traps are not yet trace-JIT-inlined but that's the plan, which will pretty much erase the cost.
/be
Comment 22•14 years ago
|
||
(In reply to comment #21)
> Re 2: "very inefficient" needs profiling data as proof. We use proxies for
> window objects in Firefox 4. They're efficient enough.
Good...
> Re 1: don't do that, then.
:(
Comment 23•14 years ago
|
||
Note for myself in the future, and anyone interested:
http://soft.vub.ac.be/~tvcutsem/proxies/ looks like it explains (pretty clearly, actually) how you can define a proxied catch-all getter or setter, through a handler.get or handler.set method. His "Hello, Proxy!" example literally generates a response for anything...
Comment 24•14 years ago
|
||
(In reply to comment #23)
> Note for myself in the future, and anyone interested:
>
> http://soft.vub.ac.be/~tvcutsem/proxies/ looks like it explains (pretty
> clearly, actually) how you can define a proxied catch-all getter or setter,
> through a handler.get or handler.set method. His "Hello, Proxy!" example
> literally generates a response for anything...
I've been cribbing from http://wiki.ecmascript.org/doku.php?id=harmony:proxies.
You need to log in
before you can comment on or make changes to this bug.
Description
•