__noSuchMethod__ not available on the anonynous global object




11 years ago
3 years ago


(Reporter: geekfreak, Unassigned)


Firefox Tracking Flags

(Not tracked)



(1 attachment, 2 obsolete attachments)



11 years ago
User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv: Gecko/2008102920 Firefox/3.0.4 FirePHP/0.2.1
Build Identifier: 

A __noSuchMethod__ handler can be attached to the window object, but as a result of the way resolution happens against the anonymous global no test for the availability of __noSuchMethod__ occurs when the code takes the JSOP_CALLNAME path.

File: mozila/js/src/jsinterp.c

"new window.Bogus()" - JSOP_CALLPROP has js_OnUnknownMethod call at the end which handles __noSuchMethod__.
"new Bogus()" - JSOP_CALLNAME - doesn't.

As esoteric as this appears, I'd like to be able to use this to provide a facility equivalent to the __autoload feature of PHP in our Jaxer project. This would enable class file to be dynamically loaded by intercepting the 'new MyObj()' call, currently it will work for 'new window.MyObj()' but not for objects on that pesky anonymous global.

I realise this may be by design. but looking at the code, it just appears as if the support for __noSuchMethod__ was added to the JSOP_CALLPROP path and not the JSOP_CALLNAME.

Reproducible: Always

Steps to Reproduce:
autoHandler = function autoHandler(id,args){
	function dummy(arghh){
		this.aProperty = "not Bogus anymore "+arghh
	return new dummy(args);


window.__noSuchMethod__ = autoHandler;

var foo = new window.Bogus('foo');
alert("!! "+foo.aProperty);

var foo2 = new Bogus2('foo');
alert("!! "+foo2.aProperty);

Actual Results:  
first call to new window.Bogus() succeeds
second call to new Bogus2() throws 'Bogus2 not defined'

Expected Results:  
call to new Bogus() should trigger the __noSuchMethod__ handler.

I can assign getters and setters to the window object and have them fire from the anonymous global, so my expectation would be the same for __noSuchMethod__

Comment 1

11 years ago
davey:  Care to take a stab at a patch?
Severity: normal → enhancement
Ever confirmed: true

Comment 2

11 years ago
I've set one of our top Mozilla wranglers (Max Stepanov) on it. Should get you a patch early next week.

Comment 3

11 years ago
Here is the patch. Heavily tested in Jaxer environment.

Comment 5

11 years ago
Comment on attachment 350102 [details] [diff] [review]
Handle __noSuchMethod__ for JSOP_CALLNAME

>diff -r 5d1fbada8589 js/src/jsinterp.cpp
>+				if (JS_UNLIKELY(op == JSOP_CALLNAME)) {
>+					jsval vp[2];
>+					LOAD_ATOM(0);
>+					vp[0] = ATOM_KEY(atom);
>+					vp[1] = OBJECT_TO_JSVAL(fp->thisp);
>+					if (!js_OnUnknownMethod(cx, vp))
>+						goto error;

This is wrong since js_OnUnknownMethod assumes that the array passed to it is rooted.

Comment 6

11 years ago
Igor, your comment makes sense. Thanks!
See fixed version attached.


11 years ago
Attachment #350102 - Attachment is obsolete: true

Comment 7

11 years ago
The patch is just a halve-measure. Since it tries to look up __noSuchMethod__ in fp->scopeChain, it will miss __noSuchMethod__ if it is only defined in the parent of the scope chain. I.e. try with it something like:

window.__noSuchMethod__ = autoHandler;

function x()
    var foo2 = Bogus2('foo');
    alert("!! "+foo2.aProperty);


Now, there are 2 different strategies to resolve that. The first is to look for __noSuchMethod__ only in the top-most scope. The second is to look for it in each and every member of the scope chain. That is, should the following example alert "window" or "object"?

this.__noSuchMethod__ = function() { alert("window"); };

var obj = { __noSuchMethod__: function() { alert("object"); } };

with (obj) {

Comment 8

11 years ago
Thanks for suggestions, Igor.  We had a talk with Davey right before submitting v2 patch about looking for __noSuchMethod__ in the scope chain.
Here is the updated patch.
Attachment #350188 - Attachment is obsolete: true

Comment 9

11 years ago
(In reply to comment #8)
> Created an attachment (id=350258) [details]
> Handle __noSuchMethod__ for JSOP_CALLNAME (v3)

The patch does not do the proper lookup. For example, in the case like:

function handler() { alert(1); }

function f()
    var __noSuchMethod__ = handler;

the handler would not be called. 

Now, I am not sure that this is what you want. My preference would be to look up the noSuchMethod only in the top-most scope on the basis that a property is created there when one does nameThatDoesNotExist = someValue; But this is just a preference.

Comment 10

11 years ago
We don't think it should work in case of local__noSuchMethod__ variable.
What we really want to achieve is to be able to resolve nameThatDoesNotExist() as if it would be in context of 'this' (e.g new this.nameThatDoesNotExist())

We have tested variations of the following code example, and the v3 patch satisfies our needs.
this.__noSuchMethod__ = function() { alert("Level 0"); };
var level1 = { __noSuchMethod__: function() { alert("Level 1"); }};
with (level1) {
  (function() {
    var level2 = { __noSuchMethod__: function() { alert("Level 2"); }};
    with (level2) {
      (function() {
        var foo = new Bogus('foo');

Comment 11

8 years ago
(In reply to comment #8)
> Created attachment 350258 [details] [diff] [review]
> Handle __noSuchMethod__ for JSOP_CALLNAME (v3)
> Thanks for suggestions, Igor.  We had a talk with Davey right before submitting
> v2 patch about looking for __noSuchMethod__ in the scope chain.
> Here is the updated patch.

Can you please advise any  analogue of this patch for the latest version ?

Comment 12

8 years ago
The patch changes for Firefox 3.6 could be found at https://github.com/mstepanov/Jaxer/blob/firefox_3.6/server/src/mozilla/js/src/jsops.cpp#L2351
No efforts has been made to make it to work in Firefox 4.0 yet.
Assignee: general → nobody

Comment 13

5 years ago
Given bug 683218 this should probably be WONTFIX.
Resolving as Won't Fix, because __noSuchMethod__ has been removed (bug 683218).
Closed: 3 years ago
Resolution: --- → WONTFIX
You need to log in before you can comment on or make changes to this bug.