~ubuntu-branches/ubuntu/edgy/k3d/edgy-proposed

« back to all changes in this revision

Viewing changes to modules/javascript/js/src/jsfun.c

  • Committer: Bazaar Package Importer
  • Author(s): David Martínez Moreno
  • Date: 2004-10-06 00:49:35 UTC
  • Revision ID: james.westby@ubuntu.com-20041006004935-54auamz54ve7kwf8
Tags: 0.4.3.0-3
_Really_ apply patch from #274172 (closes: #274172). Sorry. :-(

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2
2
 *
3
 
 * The contents of this file are subject to the Netscape Public
4
 
 * License Version 1.1 (the "License"); you may not use this file
5
 
 * except in compliance with the License. You may obtain a copy of
6
 
 * the License at http://www.mozilla.org/NPL/
7
 
 *
8
 
 * Software distributed under the License is distributed on an "AS
9
 
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
10
 
 * implied. See the License for the specific language governing
11
 
 * rights and limitations under the License.
 
3
 * ***** BEGIN LICENSE BLOCK *****
 
4
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 
5
 *
 
6
 * The contents of this file are subject to the Mozilla Public License Version
 
7
 * 1.1 (the "License"); you may not use this file except in compliance with
 
8
 * the License. You may obtain a copy of the License at
 
9
 * http://www.mozilla.org/MPL/
 
10
 *
 
11
 * Software distributed under the License is distributed on an "AS IS" basis,
 
12
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 
13
 * for the specific language governing rights and limitations under the
 
14
 * License.
12
15
 *
13
16
 * The Original Code is Mozilla Communicator client code, released
14
17
 * March 31, 1998.
15
18
 *
16
 
 * The Initial Developer of the Original Code is Netscape
17
 
 * Communications Corporation.  Portions created by Netscape are
18
 
 * Copyright (C) 1998 Netscape Communications Corporation. All
19
 
 * Rights Reserved.
 
19
 * The Initial Developer of the Original Code is
 
20
 * Netscape Communications Corporation.
 
21
 * Portions created by the Initial Developer are Copyright (C) 1998
 
22
 * the Initial Developer. All Rights Reserved.
20
23
 *
21
24
 * Contributor(s):
22
25
 *
23
 
 * Alternatively, the contents of this file may be used under the
24
 
 * terms of the GNU Public License (the "GPL"), in which case the
25
 
 * provisions of the GPL are applicable instead of those above.
26
 
 * If you wish to allow use of your version of this file only
27
 
 * under the terms of the GPL and not to allow others to use your
28
 
 * version of this file under the NPL, indicate your decision by
29
 
 * deleting the provisions above and replace them with the notice
30
 
 * and other provisions required by the GPL.  If you do not delete
31
 
 * the provisions above, a recipient may use your version of this
32
 
 * file under either the NPL or the GPL.
33
 
 */
 
26
 * Alternatively, the contents of this file may be used under the terms of
 
27
 * either of the GNU General Public License Version 2 or later (the "GPL"),
 
28
 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
29
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
30
 * of those above. If you wish to allow use of your version of this file only
 
31
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
32
 * use your version of this file under the terms of the MPL, indicate your
 
33
 * decision by deleting the provisions above and replace them with the notice
 
34
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
35
 * the provisions above, a recipient may use your version of this file under
 
36
 * the terms of any one of the MPL, the GPL or the LGPL.
 
37
 *
 
38
 * ***** END LICENSE BLOCK ***** */
34
39
 
35
40
/*
36
41
 * JS function support.
45
50
#include "jsatom.h"
46
51
#include "jscntxt.h"
47
52
#include "jsconfig.h"
 
53
#include "jsdbgapi.h"
48
54
#include "jsfun.h"
49
55
#include "jsgc.h"
50
56
#include "jsinterp.h"
100
106
    return JS_TRUE;
101
107
}
102
108
 
 
109
#define MAXARGS(fp)     ((fp)->fun ? JS_MAX((fp)->argc, (fp)->fun->nargs)     \
 
110
                                   : (fp)->argc)
 
111
 
103
112
static JSBool
104
113
MarkArgDeleted(JSContext *cx, JSStackFrame *fp, uintN slot)
105
114
{
110
119
 
111
120
    argsobj = fp->argsobj;
112
121
    (void) JS_GetReservedSlot(cx, argsobj, 0, &bmapval);
113
 
    nbits = JS_MAX(fp->argc, fp->fun->nargs);
 
122
    nbits = MAXARGS(fp);
114
123
    JS_ASSERT(slot < nbits);
115
124
    if (JSVAL_IS_VOID(bmapval)) {
116
125
        if (nbits <= JSVAL_INT_BITS) {
153
162
    (void) JS_GetReservedSlot(cx, argsobj, 0, &bmapval);
154
163
    if (JSVAL_IS_VOID(bmapval))
155
164
        return JS_FALSE;
156
 
    if (JS_MAX(fp->argc, fp->fun->nargs) <= JSVAL_INT_BITS) {
 
165
    if (MAXARGS(fp) <= JSVAL_INT_BITS) {
157
166
        bmapint = JSVAL_TO_INT(bmapval);
158
167
        bitmap = (jsbitmap *) &bmapint;
159
168
    } else {
192
201
    *vp = JSVAL_VOID;
193
202
    if (JSVAL_IS_INT(id)) {
194
203
        slot = (uintN) JSVAL_TO_INT(id);
195
 
        if (slot < JS_MAX(fp->argc, fp->fun->nargs)) {
 
204
        if (slot < MAXARGS(fp)) {
196
205
            if (fp->argsobj && ArgWasDeleted(cx, fp, slot))
197
206
                return OBJ_GET_PROPERTY(cx, fp->argsobj, id, vp);
198
207
            *vp = fp->argv[slot];
213
222
    JSObject *argsobj;
214
223
 
215
224
    /* Create an arguments object for fp only if it lacks one. */
216
 
    JS_ASSERT(fp->fun);
217
225
    argsobj = fp->argsobj;
218
226
    if (argsobj)
219
227
        return argsobj;
254
262
    (void) JS_GetReservedSlot(cx, argsobj, 0, &bmapval);
255
263
    if (!JSVAL_IS_VOID(bmapval)) {
256
264
        JS_SetReservedSlot(cx, argsobj, 0, JSVAL_VOID);
257
 
        if (JS_MAX(fp->argc, fp->fun->nargs) > JSVAL_INT_BITS)
 
265
        if (MAXARGS(fp) > JSVAL_INT_BITS)
258
266
            JS_free(cx, JSVAL_TO_PRIVATE(bmapval));
259
267
    }
260
268
 
291
299
    if (!fp)
292
300
        return JS_TRUE;
293
301
    JS_ASSERT(fp->argsobj);
294
 
    JS_ASSERT(fp->fun);
295
302
 
296
303
    slot = JSVAL_TO_INT(id);
297
304
    switch (slot) {
301
308
        break;
302
309
 
303
310
      default:
304
 
        if ((uintN)slot < JS_MAX(fp->argc, fp->fun->nargs) &&
305
 
            !MarkArgDeleted(cx, fp, slot)) {
 
311
        if ((uintN)slot < MAXARGS(fp) && !MarkArgDeleted(cx, fp, slot))
306
312
            return JS_FALSE;
307
 
        }
308
313
        break;
309
314
    }
310
315
    return JS_TRUE;
323
328
    if (!fp)
324
329
        return JS_TRUE;
325
330
    JS_ASSERT(fp->argsobj);
326
 
    JS_ASSERT(fp->fun);
327
331
 
328
332
    slot = JSVAL_TO_INT(id);
329
333
    switch (slot) {
338
342
        break;
339
343
 
340
344
      default:
341
 
        if ((uintN)slot < JS_MAX(fp->argc, fp->fun->nargs) &&
342
 
            !ArgWasDeleted(cx, fp, slot)) {
 
345
        if ((uintN)slot < MAXARGS(fp) && !ArgWasDeleted(cx, fp, slot))
343
346
            *vp = fp->argv[slot];
344
 
        }
345
347
        break;
346
348
    }
347
349
    return JS_TRUE;
360
362
    if (!fp)
361
363
        return JS_TRUE;
362
364
    JS_ASSERT(fp->argsobj);
363
 
    JS_ASSERT(fp->fun);
364
365
 
365
366
    slot = JSVAL_TO_INT(id);
366
367
    switch (slot) {
370
371
        break;
371
372
 
372
373
      default:
373
 
        if ((uintN)slot < JS_MAX(fp->argc, fp->fun->nargs) &&
374
 
            !ArgWasDeleted(cx, fp, slot)) {
 
374
        if ((uintN)slot < MAXARGS(fp) && !ArgWasDeleted(cx, fp, slot))
375
375
            fp->argv[slot] = *vp;
376
 
        }
377
376
        break;
378
377
    }
379
378
    return JS_TRUE;
396
395
    if (!fp)
397
396
        return JS_TRUE;
398
397
    JS_ASSERT(fp->argsobj);
399
 
    JS_ASSERT(fp->fun);
400
398
 
401
399
    if (JSVAL_IS_INT(id)) {
402
400
        slot = JSVAL_TO_INT(id);
403
 
        if (slot < JS_MAX(fp->argc, fp->fun->nargs) &&
404
 
            !ArgWasDeleted(cx, fp, slot)) {
 
401
        if (slot < MAXARGS(fp) && !ArgWasDeleted(cx, fp, slot)) {
405
402
            /* XXX ECMA specs DontEnum, contrary to other array-like objects */
406
403
            if (!js_DefineProperty(cx, obj, (jsid) id, fp->argv[slot],
407
404
                                   args_getProperty, args_setProperty,
460
457
    if (!fp)
461
458
        return JS_TRUE;
462
459
    JS_ASSERT(fp->argsobj);
463
 
    JS_ASSERT(fp->fun);
464
460
 
465
461
    /*
466
462
     * Trigger reflection with value snapshot in args_resolve using a series
483
479
    if (prop)
484
480
        OBJ_DROP_PROPERTY(cx, pobj, prop);
485
481
 
486
 
    nargs = JS_MAX(fp->argc, fp->fun->nargs);
 
482
    nargs = MAXARGS(fp);
487
483
    for (slot = 0; slot < nargs; slot++) {
488
484
        if (!js_LookupProperty(cx, obj, (jsid) INT_TO_JSVAL((jsint)slot),
489
485
                               &pobj, &prop)) {
701
697
    JSStackFrame *fp;
702
698
    JSObject *funobj;
703
699
    JSScope *scope;
704
 
    JSScopeProperty *sprop;
 
700
    JSScopeProperty *sprop, *cprop;
705
701
    JSPropertyOp getter;
 
702
    jsval *vec;
706
703
    JSProperty *prop;
707
704
 
708
705
    fp = (JSStackFrame *) JS_GetPrivate(cx, obj);
733
730
    scope = OBJ_SCOPE(funobj);
734
731
    for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) {
735
732
        getter = sprop->getter;
736
 
        if (getter != js_GetArgument && getter != js_GetLocalVariable)
 
733
        if (getter == js_GetArgument)
 
734
            vec = fp->argv;
 
735
        else if (getter == js_GetLocalVariable)
 
736
            vec = fp->vars;
 
737
        else
737
738
            continue;
738
739
 
739
740
        /* Trigger reflection in call_resolve by doing a lookup. */
740
741
        if (!js_LookupProperty(cx, obj, sprop->id, &obj, &prop))
741
742
            return JS_FALSE;
742
743
        JS_ASSERT(obj && prop);
 
744
        cprop = (JSScopeProperty *)prop;
 
745
        LOCKED_OBJ_SET_SLOT(obj, cprop->slot, vec[sprop->shortid]);
743
746
        OBJ_DROP_PROPERTY(cx, obj, prop);
744
747
    }
745
748
 
865
868
    jsint slot;
866
869
    JSFunction *fun;
867
870
    JSStackFrame *fp;
868
 
#if defined XP_PC && defined _MSC_VER &&_MSC_VER <= 800
 
871
#if defined _MSC_VER &&_MSC_VER <= 800
869
872
    /* MSVC1.5 coredumps */
870
873
    jsval bogus = *vp;
871
874
#endif
923
926
        break;
924
927
 
925
928
      case FUN_CALLER:
 
929
        while (fp && (fp->flags & JSFRAME_SKIP_CALLER) && fp->down)
 
930
            fp = fp->down;
926
931
        if (fp && fp->down && fp->down->fun && fp->down->argv)
927
932
            *vp = fp->down->argv[-2];
928
933
        else
937
942
      default:
938
943
        /* XXX fun[0] and fun.arguments[0] are equivalent. */
939
944
        if (fp && fp->fun && (uintN)slot < fp->fun->nargs)
940
 
#if defined XP_PC && defined _MSC_VER &&_MSC_VER <= 800
 
945
#if defined _MSC_VER &&_MSC_VER <= 800
941
946
          /* MSVC1.5 coredumps */
942
947
          if (bogus == *vp)
943
948
#endif
1008
1013
            return JS_FALSE;
1009
1014
 
1010
1015
        /*
1011
 
         * ECMA says that constructor.prototype is DontEnum | DontDelete for
 
1016
         * ECMA (15.3.5.2) says that constructor.prototype is DontDelete for
1012
1017
         * user-defined functions, but DontEnum | ReadOnly | DontDelete for
1013
1018
         * native "system" constructors such as Object or Function.  So lazily
1014
1019
         * set the former here in fun_resolve, but eagerly define the latter
1015
1020
         * in JS_InitClass, with the right attributes.
1016
1021
         */
1017
 
        if (!js_SetClassPrototype(cx, obj, proto, JSPROP_PERMANENT)) {
 
1022
        if (!js_SetClassPrototype(cx, obj, proto,
 
1023
                                  JSPROP_ENUMERATE | JSPROP_PERMANENT)) {
1018
1024
            cx->newborn[GCX_OBJECT] = NULL;
1019
1025
            return JS_FALSE;
1020
1026
        }
1074
1080
    JSString *atomstr;
1075
1081
    char *propname;
1076
1082
    JSScopeProperty *sprop;
1077
 
    jsid userid;
 
1083
    uint32 userid;              /* NB: holds a signed int-tagged jsval */
1078
1084
    JSAtom *atom;
1079
1085
    uintN i, n, dupflag;
1080
1086
    uint32 type;
1148
1154
                       ? JSXDR_FUNCONST
1149
1155
                       : JSXDR_FUNVAR;
1150
1156
                userid = INT_TO_JSVAL(sprop->shortid);
1151
 
                propname = ATOM_BYTES((JSAtom *)sprop->id);
1152
 
                if (!JS_XDRUint32(xdr, &type) ||
1153
 
                    !JS_XDRUint32(xdr, (uint32 *)&userid) ||
 
1157
                /* XXX lossy conversion, need new XDR version for ECMAv3 */
 
1158
                propname = JS_GetStringBytes(ATOM_TO_STRING((JSAtom *)sprop->id));
 
1159
                if (!propname ||
 
1160
                    !JS_XDRUint32(xdr, &type) ||
 
1161
                    !JS_XDRUint32(xdr, &userid) ||
1154
1162
                    !JS_XDRCString(xdr, &propname)) {
1155
1163
                    if (mark)
1156
1164
                        JS_ARENA_RELEASE(&cx->tempPool, mark);
1166
1174
                uintN attrs = JSPROP_ENUMERATE | JSPROP_PERMANENT;
1167
1175
 
1168
1176
                if (!JS_XDRUint32(xdr, &type) ||
1169
 
                    !JS_XDRUint32(xdr, (uint32 *)&userid) ||
 
1177
                    !JS_XDRUint32(xdr, &userid) ||
1170
1178
                    !JS_XDRCString(xdr, &propname)) {
1171
1179
                    return JS_FALSE;
1172
1180
                }
1275
1283
    if (!js_IsDelegate(cx, proto, v, bp))
1276
1284
        return JS_FALSE;
1277
1285
 
1278
 
    if (!*bp && !JSVAL_IS_PRIMITIVE(v)) {
 
1286
    if (!*bp && !JSVAL_IS_PRIMITIVE(v) && v != pval) {
1279
1287
        /*
1280
1288
         * Extension for "brutal sharing" of standard class constructors: if
1281
1289
         * a script is compiled using a single, shared set of constructors, in
1468
1476
    fp = cx->fp;
1469
1477
    oldsp = fp->sp;
1470
1478
    fp->sp = sp;
1471
 
    ok = js_Invoke(cx, argc, JSINVOKE_INTERNAL);
 
1479
    ok = js_Invoke(cx, argc, JSINVOKE_INTERNAL | JSINVOKE_SKIP_CALLER);
1472
1480
 
1473
1481
    /* Store rval and pop stack back to our frame's sp. */
1474
1482
    *rval = fp->sp[-1];
1491
1499
    JSStackFrame *fp;
1492
1500
 
1493
1501
    if (argc == 0) {
1494
 
        /* Will get globalObject as 'this' and no other agurments. */
 
1502
        /* Will get globalObject as 'this' and no other arguments. */
1495
1503
        return fun_call(cx, obj, argc, argv, rval);
1496
1504
    }
1497
1505
 
1536
1544
        return JS_FALSE;
1537
1545
 
1538
1546
    /* Allocate stack space for fval, obj, and the args. */
1539
 
    argc = (uintN)length;
 
1547
    argc = (uintN)JS_MIN(length, ARGC_LIMIT - 1);
1540
1548
    sp = js_AllocStack(cx, 2 + argc, &mark);
1541
1549
    if (!sp)
1542
1550
        return JS_FALSE;
1555
1563
    fp = cx->fp;
1556
1564
    oldsp = fp->sp;
1557
1565
    fp->sp = sp;
1558
 
    ok = js_Invoke(cx, argc, JSINVOKE_INTERNAL);
 
1566
    ok = js_Invoke(cx, argc, JSINVOKE_INTERNAL | JSINVOKE_SKIP_CALLER);
1559
1567
 
1560
1568
    /* Store rval and pop stack back to our frame's sp. */
1561
1569
    *rval = fp->sp[-1];
1587
1595
    jschar *s, c;
1588
1596
 
1589
1597
    n = JSSTRING_LENGTH(str);
 
1598
    if (n == 0)
 
1599
        return JS_FALSE;
1590
1600
    s = JSSTRING_CHARS(str);
1591
1601
    c = *s;
1592
 
    /*
1593
 
     * We don't handle unicode escape sequences here
1594
 
     * because they won't be in the input string.
1595
 
     * (Right?)
1596
 
     */
1597
 
    if (n == 0 || !JS_ISIDENT_START(c))
 
1602
    if (!JS_ISIDENT_START(c))
1598
1603
        return JS_FALSE;
1599
1604
    for (n--; n != 0; n--) {
1600
1605
        c = *++s;
1607
1612
static JSBool
1608
1613
Function(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1609
1614
{
 
1615
    JSStackFrame *fp, *caller;
1610
1616
    JSFunction *fun;
1611
1617
    JSObject *parent;
1612
1618
    uintN i, n, lineno, dupflag;
1615
1621
    JSObject *obj2;
1616
1622
    JSScopeProperty *sprop;
1617
1623
    JSString *str, *arg;
1618
 
    JSStackFrame *fp;
1619
1624
    void *mark;
1620
1625
    JSTokenStream *ts;
1621
1626
    JSPrincipals *principals;
1624
1629
    JSTokenType tt;
1625
1630
    JSBool ok;
1626
1631
 
1627
 
    if (cx->fp && !(cx->fp->flags & JSFRAME_CONSTRUCTING)) {
 
1632
    fp = cx->fp;
 
1633
    if (fp && !(fp->flags & JSFRAME_CONSTRUCTING)) {
1628
1634
        obj = js_NewObject(cx, &js_FunctionClass, NULL, NULL);
1629
1635
        if (!obj)
1630
1636
            return JS_FALSE;
1652
1658
#endif
1653
1659
 
1654
1660
    fun = js_NewFunction(cx, obj, NULL, 0, JSFUN_LAMBDA, parent,
1655
 
                         (JSVERSION_IS_ECMA(cx->version))
 
1661
                         JSVERSION_IS_ECMA(cx->version)
1656
1662
                         ? cx->runtime->atomState.anonymousAtom
1657
1663
                         : NULL);
1658
1664
 
1666
1672
     * are built for Function.prototype.call or .apply activations that invoke
1667
1673
     * Function indirectly from a script.
1668
1674
     */
1669
 
    fp = cx->fp;
1670
1675
    JS_ASSERT(!fp->script && fp->fun && fp->fun->native == Function);
1671
 
    for (;;) {
1672
 
        fp = fp->down;
1673
 
        if (!fp) {
1674
 
            filename = NULL;
1675
 
            lineno = 0;
1676
 
            principals = NULL;
1677
 
            break;
1678
 
        }
1679
 
        if (fp->script) {
1680
 
            /*
1681
 
             * Load fp->script->* before calling js_PCToLineNumber, to avoid
1682
 
             * a pessimal reload of fp->script.
1683
 
             */
1684
 
            principals = fp->script->principals;
1685
 
            filename = fp->script->filename;
1686
 
            lineno = js_PCToLineNumber(fp->script, fp->pc);
1687
 
            break;
1688
 
        }
 
1676
    caller = JS_GetScriptedCaller(cx, fp);
 
1677
    if (caller) {
 
1678
        filename = caller->script->filename;
 
1679
        lineno = js_PCToLineNumber(cx, caller->script, caller->pc);
 
1680
        principals = JS_EvalFramePrincipals(cx, fp, caller);
 
1681
    } else {
 
1682
        filename = NULL;
 
1683
        lineno = 0;
 
1684
        principals = NULL;
1689
1685
    }
1690
1686
 
1691
1687
    n = argc ? argc - 1 : 0;
1751
1747
        /* The argument string may be empty or contain no tokens. */
1752
1748
        tt = js_GetToken(cx, ts);
1753
1749
        if (tt != TOK_EOF) {
1754
 
            while (1) {
 
1750
            for (;;) {
1755
1751
                /*
1756
1752
                 * Check that it's a name.  This also implicitly guards against
1757
1753
                 * TOK_ERROR, which was already reported.
1772
1768
                if (sprop) {
1773
1769
                    ok = JS_TRUE;
1774
1770
                    if (obj2 == obj) {
 
1771
                        const char *name = js_AtomToPrintableString(cx, atom);
 
1772
 
1775
1773
                        /*
1776
1774
                         * A duplicate parameter name. We force a duplicate
1777
1775
                         * node on the SCOPE_LAST_PROP(scope) list with the
1779
1777
                         * flag, and not mapped by an entry in scope.
1780
1778
                         */
1781
1779
                        JS_ASSERT(sprop->getter == js_GetArgument);
1782
 
                        ok = js_ReportCompileErrorNumber(cx, ts, NULL,
 
1780
                        ok = name &&
 
1781
                             js_ReportCompileErrorNumber(cx, ts, NULL,
1783
1782
                                                         JSREPORT_WARNING |
1784
1783
                                                         JSREPORT_STRICT,
1785
1784
                                                         JSMSG_DUPLICATE_FORMAL,
1786
 
                                                         ATOM_BYTES(atom));
 
1785
                                                         name);
1787
1786
 
1788
1787
                        dupflag = SPROP_IS_DUPLICATE;
1789
1788
                    }
1883
1882
    fun = js_NewFunction(cx, proto, NULL, 0, 0, obj, NULL);
1884
1883
    if (!fun)
1885
1884
        goto bad;
1886
 
    fun->script = js_NewScript(cx, 0);
 
1885
    fun->script = js_NewScript(cx, 0, 0, 0);
1887
1886
    if (!fun->script)
1888
1887
        goto bad;
1889
1888
    return proto;
1991
1990
    return fun;
1992
1991
}
1993
1992
 
 
1993
#if (JSV2F_CONSTRUCT & JSV2F_SEARCH_STACK)
 
1994
# error "JSINVOKE_CONSTRUCT and JSV2F_SEARCH_STACK are not disjoint!"
 
1995
#endif
 
1996
 
1994
1997
JSFunction *
1995
 
js_ValueToFunction(JSContext *cx, jsval *vp, JSBool constructing)
 
1998
js_ValueToFunction(JSContext *cx, jsval *vp, uintN flags)
1996
1999
{
1997
2000
    jsval v;
1998
2001
    JSObject *obj;
2008
2011
        }
2009
2012
    }
2010
2013
    if (!obj) {
2011
 
        js_ReportIsNotFunction(cx, vp, constructing);
 
2014
        js_ReportIsNotFunction(cx, vp, flags);
2012
2015
        return NULL;
2013
2016
    }
2014
2017
    return (JSFunction *) JS_GetPrivate(cx, obj);
2015
2018
}
2016
2019
 
2017
2020
void
2018
 
js_ReportIsNotFunction(JSContext *cx, jsval *vp, JSBool constructing)
 
2021
js_ReportIsNotFunction(JSContext *cx, jsval *vp, uintN flags)
2019
2022
{
2020
2023
    JSType type;
2021
2024
    JSString *fallback;
2022
 
    JSStackFrame *fp;
2023
2025
    JSString *str;
2024
2026
 
2025
2027
    /*
2030
2032
     */
2031
2033
    type = JS_TypeOfValue(cx, *vp);
2032
2034
    fallback = ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[type]);
2033
 
    fp = cx->fp;
2034
 
    str = js_DecompileValueGenerator(cx, fp ? vp - fp->sp : JSDVG_IGNORE_STACK,
2035
 
                                     *vp, fallback);
 
2035
    str = js_DecompileValueGenerator(cx,
 
2036
                                     (flags & JSV2F_SEARCH_STACK)
 
2037
                                     ? JSDVG_SEARCH_STACK
 
2038
                                     : cx->fp
 
2039
                                     ? vp - cx->fp->sp
 
2040
                                     : JSDVG_IGNORE_STACK,
 
2041
                                     *vp,
 
2042
                                     fallback);
2036
2043
    if (str) {
2037
2044
        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
2038
 
                             (uintN)(constructing ? JSMSG_NOT_CONSTRUCTOR
2039
 
                                                  : JSMSG_NOT_FUNCTION),
 
2045
                             (uintN)((flags & JSV2F_CONSTRUCT)
 
2046
                                     ? JSMSG_NOT_CONSTRUCTOR
 
2047
                                     : JSMSG_NOT_FUNCTION),
2040
2048
                             JS_GetStringBytes(str));
2041
2049
    }
2042
2050
}