home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / js / src / jsapi.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  44.7 KB  |  1,940 lines

  1. /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. /*
  20.  * JavaScript API.
  21.  */
  22. #include <stdarg.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include "prtypes.h"
  26. #ifndef NSPR20
  27. #include "prarena.h"
  28. #else
  29. #include "plarena.h"
  30. #endif
  31. #include "prlog.h"
  32. #include "prclist.h"
  33. #include "jsapi.h"
  34. #include "jsarray.h"
  35. #include "jsatom.h"
  36. #include "jsbool.h"
  37. #include "jsconfig.h"
  38. #include "jscntxt.h"
  39. #include "jsconfig.h"
  40. #include "jsdate.h"
  41. #include "jsemit.h"
  42. #include "jsfun.h"
  43. #include "jsgc.h"
  44. #include "jsinterp.h"
  45. #include "jslock.h"
  46. #include "jsmath.h"
  47. #include "jsnum.h"
  48. #include "jsobj.h"
  49. #include "jsopcode.h"
  50. #include "jsparse.h"
  51. #include "jsregexp.h"
  52. #include "jsscan.h"
  53. #include "jsscope.h"
  54. #include "jsscript.h"
  55. #include "jsstr.h"
  56.  
  57. PR_IMPLEMENT(jsval)
  58. JS_GetNaNValue(JSContext *cx)
  59. {
  60.     return DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
  61. }
  62.  
  63. PR_IMPLEMENT(jsval)
  64. JS_GetNegativeInfinityValue(JSContext *cx)
  65. {
  66.     return DOUBLE_TO_JSVAL(cx->runtime->jsNegativeInfinity);
  67. }
  68.  
  69. PR_IMPLEMENT(jsval)
  70. JS_GetPositiveInfinityValue(JSContext *cx)
  71. {
  72.     return DOUBLE_TO_JSVAL(cx->runtime->jsPositiveInfinity);
  73. }
  74.  
  75. PR_IMPLEMENT(jsval)
  76. JS_GetEmptyStringValue(JSContext *cx)
  77. {
  78.     return STRING_TO_JSVAL(cx->runtime->emptyString);
  79. }
  80.  
  81. PR_IMPLEMENT(JSBool)
  82. JS_ConvertValue(JSContext *cx, jsval v, JSType type, jsval *vp)
  83. {
  84.     JSBool ok, b;
  85.     JSObject *obj;
  86.     JSFunction *fun;
  87.     JSString *str;
  88.     jsdouble d, *dp;
  89.  
  90.     JS_LOCK(cx);
  91.     switch (type) {
  92.       case JSTYPE_VOID:
  93.     *vp = JSVAL_VOID;
  94.     break;
  95.       case JSTYPE_OBJECT:
  96.     ok = js_ValueToObject(cx, v, &obj);
  97.     if (ok)
  98.         *vp = OBJECT_TO_JSVAL(obj);
  99.     break;
  100.       case JSTYPE_FUNCTION:
  101.     fun = js_ValueToFunction(cx, v);
  102.     ok = (fun != NULL);
  103.     if (ok)
  104.         *vp = OBJECT_TO_JSVAL(fun->object);
  105.     break;
  106.       case JSTYPE_STRING:
  107.     str = js_ValueToString(cx, v);
  108.     ok = (str != NULL);
  109.     if (ok)
  110.         *vp = STRING_TO_JSVAL(str);
  111.     break;
  112.       case JSTYPE_NUMBER:
  113.     ok = js_ValueToNumber(cx, v, &d);
  114.     if (ok) {
  115.         dp = js_NewDouble(cx, d);
  116.         ok = (dp != NULL);
  117.         if (ok)
  118.         *vp = DOUBLE_TO_JSVAL(dp);
  119.     }
  120.     break;
  121.       case JSTYPE_BOOLEAN:
  122.     ok = js_ValueToBoolean(cx, v, &b);
  123.     if (ok)
  124.         *vp = BOOLEAN_TO_JSVAL(b);
  125.     break;
  126.       default:
  127.     JS_ReportError(cx, "unknown type %d", (int)type);
  128.     ok = JS_FALSE;
  129.     break;
  130.     }
  131.     JS_UNLOCK(cx);
  132.     return ok;
  133. }
  134.  
  135. PR_IMPLEMENT(JSBool)
  136. JS_ValueToObject(JSContext *cx, jsval v, JSObject **objp)
  137. {
  138.     JS_LOCK_AND_RETURN_BOOL(cx, js_ValueToObject(cx, v, objp));
  139. }
  140.  
  141. PR_IMPLEMENT(JSFunction *)
  142. JS_ValueToFunction(JSContext *cx, jsval v)
  143. {
  144.     JS_LOCK_AND_RETURN_TYPE(cx, JSFunction *, js_ValueToFunction(cx, v));
  145. }
  146.  
  147. PR_IMPLEMENT(JSString *)
  148. JS_ValueToString(JSContext *cx, jsval v)
  149. {
  150.     JS_LOCK_AND_RETURN_STRING(cx, js_ValueToString(cx, v));
  151. }
  152.  
  153. PR_IMPLEMENT(JSBool)
  154. JS_ValueToNumber(JSContext *cx, jsval v, jsdouble *dp)
  155. {
  156.     JS_LOCK_AND_RETURN_BOOL(cx, js_ValueToNumber(cx, v, dp));
  157. }
  158.  
  159. PR_IMPLEMENT(JSBool)
  160. JS_ValueToInt32(JSContext *cx, jsval v, int32 *ip)
  161. {
  162.     JS_LOCK_AND_RETURN_BOOL(cx, js_ValueToInt32(cx, v, ip));
  163. }
  164.  
  165. PR_IMPLEMENT(JSBool)
  166. JS_ValueToUint16(JSContext *cx, jsval v, uint16 *ip)
  167. {
  168.     JS_LOCK_AND_RETURN_BOOL(cx, js_ValueToUint16(cx, v, ip));
  169. }
  170.  
  171. PR_IMPLEMENT(JSBool)
  172. JS_ValueToBoolean(JSContext *cx, jsval v, JSBool *bp)
  173. {
  174.     JS_LOCK_AND_RETURN_BOOL(cx, js_ValueToBoolean(cx, v, bp));
  175. }
  176.  
  177. PR_IMPLEMENT(JSType)
  178. JS_TypeOfValue(JSContext *cx, jsval v)
  179. {
  180.     JSType type;
  181.     JSObject *obj;
  182.  
  183.     if (JSVAL_IS_VOID(v)) {
  184.     type = JSTYPE_VOID;
  185.     } else if (JSVAL_IS_OBJECT(v)) {
  186.     obj = JSVAL_TO_OBJECT(v);
  187.     if (obj &&
  188.         (obj->map->clasp == &js_FunctionClass
  189. #if JS_HAS_LEXICAL_CLOSURE
  190.          || obj->map->clasp == &js_ClosureClass
  191. #endif
  192.          )) {
  193.         type = JSTYPE_FUNCTION;
  194.     } else {
  195.         type = JSTYPE_OBJECT;
  196.     }
  197.     } else if (JSVAL_IS_NUMBER(v)) {
  198.     type = JSTYPE_NUMBER;
  199.     } else if (JSVAL_IS_STRING(v)) {
  200.     type = JSTYPE_STRING;
  201.     } else if (JSVAL_IS_BOOLEAN(v)) {
  202.     type = JSTYPE_BOOLEAN;
  203.     }
  204.     return type;
  205. }
  206.  
  207. PR_IMPLEMENT(const char *)
  208. JS_GetTypeName(JSContext *cx, JSType type)
  209. {
  210.     if ((uintN)type >= (uintN)JSTYPE_LIMIT)
  211.     return NULL;
  212.     return js_type_str[type];
  213. }
  214.  
  215. /************************************************************************/
  216.  
  217. PR_IMPLEMENT(JSRuntime *)
  218. JS_Init(uint32 maxbytes)
  219. {
  220.     JSRuntime *rt;
  221.  
  222.     rt = malloc(sizeof(JSRuntime));
  223.     if (!rt)
  224.     return NULL;
  225.     memset(rt, 0, sizeof(JSRuntime));
  226.     if (!js_InitGC(rt, maxbytes)) {
  227.     free(rt);
  228.     return NULL;
  229.     }
  230.     rt->propertyCache.empty = JS_TRUE;
  231.     PR_INIT_CLIST(&rt->contextList);
  232.     PR_INIT_CLIST(&rt->trapList);
  233.     PR_INIT_CLIST(&rt->watchPointList);
  234.     return rt;
  235. }
  236.  
  237. PR_IMPLEMENT(void)
  238. JS_Finish(JSRuntime *rt)
  239. {
  240.     js_FinishGC(rt);
  241.     free(rt);
  242. }
  243.  
  244. PR_IMPLEMENT(void)
  245. JS_Lock(JSRuntime *rt)
  246. {
  247.     JS_LOCK_RUNTIME(rt);
  248. }
  249.  
  250. PR_IMPLEMENT(void)
  251. JS_Unlock(JSRuntime *rt)
  252. {
  253.     JS_UNLOCK_RUNTIME(rt);
  254. }
  255.  
  256. PR_IMPLEMENT(JSContext *)
  257. JS_NewContext(JSRuntime *rt, size_t stacksize)
  258. {
  259.     JSContext *cx;
  260.  
  261.     JS_LOCK_RUNTIME(rt);
  262.     cx = js_NewContext(rt, stacksize);
  263.     JS_UNLOCK_RUNTIME(rt);
  264.     return cx;
  265. }
  266.  
  267. PR_IMPLEMENT(void)
  268. JS_DestroyContext(JSContext *cx)
  269. {
  270.     JS_LOCK_VOID(cx, js_DestroyContext(cx));
  271. }
  272.  
  273. PR_IMPLEMENT(JSRuntime *)
  274. JS_GetRuntime(JSContext *cx)
  275. {
  276.     return cx->runtime;
  277. }
  278.  
  279. PR_IMPLEMENT(JSContext *)
  280. JS_ContextIterator(JSRuntime *rt, JSContext **iterp)
  281. {
  282.     JSContext *cx;
  283.  
  284.     JS_LOCK_RUNTIME(rt);
  285.     cx = js_ContextIterator(rt, iterp);
  286.     JS_UNLOCK_RUNTIME(rt);
  287.     return cx;
  288. }
  289.  
  290. PR_IMPLEMENT(JSVersion)
  291. JS_GetVersion(JSContext *cx)
  292. {
  293.     return cx->version;
  294. }
  295.  
  296. PR_IMPLEMENT(JSVersion)
  297. JS_SetVersion(JSContext *cx, JSVersion version)
  298. {
  299.     JSVersion oldVersion;
  300.  
  301.     oldVersion = cx->version;
  302.     cx->version = version;
  303.  
  304. #if !JS_BUG_FALLIBLE_EQOPS
  305.     if (cx->version == JSVERSION_1_2) {
  306.     cx->jsop_eq = JSOP_NEW_EQ;
  307.     cx->jsop_ne = JSOP_NEW_NE;
  308.     } else {
  309.     cx->jsop_eq = JSOP_EQ;
  310.     cx->jsop_ne = JSOP_NE;
  311.     }
  312. #endif /* !JS_BUG_FALLIBLE_EQOPS */
  313.  
  314. #if JS_HAS_EXPORT_IMPORT
  315.     /* XXX this might fail due to low memory */
  316.     JS_LOCK_VOID(cx, js_InitScanner(cx));
  317. #endif /* JS_HAS_EXPORT_IMPORT */
  318.  
  319.     return oldVersion;
  320. }
  321.  
  322. PR_IMPLEMENT(JSObject *)
  323. JS_GetGlobalObject(JSContext *cx)
  324. {
  325.     return cx->globalObject;
  326. }
  327.  
  328. PR_IMPLEMENT(void)
  329. JS_SetGlobalObject(JSContext *cx, JSObject *obj)
  330. {
  331.     cx->globalObject = obj;
  332. }
  333.  
  334. PR_IMPLEMENT(JSBool)
  335. JS_InitStandardClasses(JSContext *cx, JSObject *obj)
  336. {
  337.     JSBool ok;
  338.     JSObject *proto, *fun_proto, *obj_proto, *array_proto;
  339.  
  340.     ok = JS_TRUE;
  341.     JS_LOCK(cx);
  342.  
  343.     /* If cx has no global object, use obj so prototypes can be found. */
  344.     if (!cx->globalObject)
  345.     cx->globalObject = obj;
  346.  
  347.     /* Initialize the function class first so constructors can be made. */
  348.     fun_proto = js_InitFunctionClass(cx, obj);
  349.     if (!fun_proto) {
  350.     ok = JS_FALSE;
  351.     goto out;
  352.     }
  353.  
  354.     /* Initialize the object class next so Object.prototype works. */
  355.     obj_proto = js_InitObjectClass(cx, obj);
  356.     if (!obj_proto) {
  357.     ok = JS_FALSE;
  358.     goto out;
  359.     }
  360.  
  361.     /* Link the global object and Function.prototype to Object.prototype. */
  362.     proto = OBJ_GET_PROTO(obj);
  363.     if (!proto)
  364.     OBJ_SET_PROTO(obj, obj_proto);
  365.     proto = OBJ_GET_PROTO(fun_proto);
  366.     if (!proto)
  367.     OBJ_SET_PROTO(fun_proto, obj_proto);
  368.  
  369.     /* Initialize the rest of the standard objects and functions. */
  370.     ok = (array_proto = js_InitArrayClass(cx, obj)) &&
  371.      js_InitCallAndClosureClasses(cx, obj, array_proto) &&
  372.      js_InitBooleanClass(cx, obj) &&
  373.      js_InitMathClass(cx, obj) &&
  374.      js_InitNumberClass(cx, obj) &&
  375.      js_InitStringClass(cx, obj) &&
  376. #if JS_HAS_REGEXPS
  377.      js_InitRegExpClass(cx, obj) &&
  378. #endif
  379.      js_InitDateClass(cx, obj);
  380.  
  381. out:
  382.     JS_UNLOCK(cx);
  383.     return ok;
  384. }
  385.  
  386. PR_IMPLEMENT(JSObject *)
  387. JS_GetScopeChain(JSContext *cx)
  388. {
  389.     return cx->fp ? cx->fp->scopeChain : NULL;
  390. }
  391.  
  392. PR_IMPLEMENT(void *)
  393. JS_malloc(JSContext *cx, size_t nbytes)
  394. {
  395.     void *p;
  396.  
  397. #ifdef XP_OS2
  398.     if (nbytes == 0) /*DSR072897 - this sucks, but Microsoft allows it!*/
  399.     nbytes = 1;
  400. #endif
  401. #ifdef TOO_MUCH_GC
  402.     p = NULL;
  403. #else
  404.     p = malloc(nbytes);
  405. #endif
  406.     if (!p) {
  407.     JS_LOCK_VOID(cx, js_GC(cx));
  408.     p = malloc(nbytes);
  409.     if (!p)
  410.         JS_ReportOutOfMemory(cx);
  411.     }
  412.     return p;
  413. }
  414.  
  415. PR_IMPLEMENT(void *)
  416. JS_realloc(JSContext *cx, void *p, size_t nbytes)
  417. {
  418. #ifndef TOO_MUCH_GC
  419.     p = realloc(p, nbytes);
  420.     if (!p) {
  421. #endif
  422.     JS_LOCK_VOID(cx, js_GC(cx));
  423.     p = realloc(p, nbytes);
  424.     if (!p)
  425.         JS_ReportOutOfMemory(cx);
  426. #ifndef TOO_MUCH_GC
  427.     }
  428. #endif
  429.     return p;
  430. }
  431.  
  432. PR_IMPLEMENT(void)
  433. JS_free(JSContext *cx, void *p)
  434. {
  435.     if (p)
  436.     free(p);
  437. }
  438.  
  439. PR_IMPLEMENT(char *)
  440. JS_strdup(JSContext *cx, const char *s)
  441. {
  442.     char *p = JS_malloc(cx, strlen(s) + 1);
  443.     if (!p)
  444.     return NULL;
  445.     return strcpy(p, s);
  446. }
  447.  
  448. PR_IMPLEMENT(jsdouble *)
  449. JS_NewDouble(JSContext *cx, jsdouble d)
  450. {
  451.     JS_LOCK_AND_RETURN_TYPE(cx, jsdouble *, js_NewDouble(cx, d));
  452. }
  453.  
  454. PR_IMPLEMENT(JSBool)
  455. JS_NewDoubleValue(JSContext *cx, jsdouble d, jsval *rval)
  456. {
  457.     JS_LOCK_AND_RETURN_BOOL(cx, js_NewDoubleValue(cx, d, rval));
  458. }
  459.  
  460. PR_IMPLEMENT(JSBool)
  461. JS_NewNumberValue(JSContext *cx, jsdouble d, jsval *rval)
  462. {
  463.     JS_LOCK_AND_RETURN_BOOL(cx, js_NewNumberValue(cx, d, rval));
  464. }
  465.  
  466. PR_IMPLEMENT(JSBool)
  467. JS_AddRoot(JSContext *cx, void *rp)
  468. {
  469.     JS_LOCK_AND_RETURN_BOOL(cx, js_AddRoot(cx, rp));
  470. }
  471.  
  472. PR_IMPLEMENT(JSBool)
  473. JS_RemoveRoot(JSContext *cx, void *rp)
  474. {
  475.     JS_LOCK_AND_RETURN_BOOL(cx, js_RemoveRoot(cx, rp));
  476. }
  477.  
  478. PR_IMPLEMENT(JSBool)
  479. JS_AddNamedRoot(JSContext *cx, void *rp, const char *name)
  480. {
  481.     JS_LOCK_AND_RETURN_BOOL(cx, js_AddNamedRoot(cx, rp, name));
  482. }
  483.  
  484. #ifdef DEBUG
  485.  
  486. #ifndef NSPR20
  487. #include "prhash.h"
  488. #else
  489. #include "plhash.h"
  490. #endif
  491.  
  492. typedef struct NamedRootDumpArgs {
  493.     void (*dump)(const char *name, void *rp, void *data);
  494.     void *data;
  495. } NamedRootDumpArgs;
  496.  
  497. PR_STATIC_CALLBACK(intN)
  498. js_named_root_dumper(PRHashEntry *he, intN i, void *arg)
  499. {
  500.     NamedRootDumpArgs *args = arg;
  501.  
  502.     args->dump(he->value, (void *)he->key, args->data);
  503.     return HT_ENUMERATE_NEXT;
  504. }
  505.  
  506. PR_IMPLEMENT(void)
  507. JS_DumpNamedRoots(JSRuntime *rt,
  508.           void (*dump)(const char *name, void *rp, void *data),
  509.           void *data)
  510. {
  511.     NamedRootDumpArgs args;
  512.  
  513.     args.dump = dump;
  514.     args.data = data;
  515.     JS_LOCK_RUNTIME(rt);
  516.     PR_HashTableEnumerateEntries(rt->gcRootsHash, js_named_root_dumper, &args);
  517.     JS_UNLOCK_RUNTIME(rt);
  518. }
  519.  
  520. #endif /* DEBUG */
  521.  
  522. PR_IMPLEMENT(JSBool)
  523. JS_LockGCThing(JSContext *cx, void *thing)
  524. {
  525.     JSBool ok;
  526.  
  527.     JS_LOCK_VOID(cx, ok = js_LockGCThing(cx, thing));
  528.     if (!ok)
  529.     JS_ReportError(cx, "can't lock memory");
  530.     return ok;
  531. }
  532.  
  533. PR_IMPLEMENT(JSBool)
  534. JS_UnlockGCThing(JSContext *cx, void *thing)
  535. {
  536.     JSBool ok;
  537.  
  538.     JS_LOCK_VOID(cx, ok = js_UnlockGCThing(cx, thing));
  539.     if (!ok)
  540.     JS_ReportError(cx, "can't unlock memory");
  541.     return ok;
  542. }
  543.  
  544. PR_IMPLEMENT(void)
  545. JS_GC(JSContext *cx)
  546. {
  547.     JS_LOCK(cx);
  548.     if (!cx->fp)
  549.     PR_FinishArenaPool(&cx->stackPool);
  550.     PR_FinishArenaPool(&cx->codePool);
  551.     PR_FinishArenaPool(&cx->tempPool);
  552.     js_ForceGC(cx);
  553.     JS_UNLOCK(cx);
  554. }
  555.  
  556. PR_IMPLEMENT(void)
  557. JS_MaybeGC(JSContext *cx)
  558. {
  559.     JSRuntime *rt;
  560.     uint32 bytes, lastBytes;
  561.  
  562.     rt = cx->runtime;
  563.     JS_LOCK_RUNTIME(rt);
  564.     bytes = rt->gcBytes;
  565.     lastBytes = rt->gcLastBytes;
  566.     if (bytes > 8192 && bytes > lastBytes + lastBytes / 2)
  567.     js_GC(cx);
  568.     JS_UNLOCK_RUNTIME(rt);
  569. }
  570.  
  571. /************************************************************************/
  572.  
  573. PR_IMPLEMENT(JSBool)
  574. JS_PropertyStub(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
  575. {
  576.     return JS_TRUE;
  577. }
  578.  
  579. PR_IMPLEMENT(JSBool)
  580. JS_EnumerateStub(JSContext *cx, JSObject *obj)
  581. {
  582.     return JS_TRUE;
  583. }
  584.  
  585. PR_IMPLEMENT(JSBool)
  586. JS_ResolveStub(JSContext *cx, JSObject *obj, jsval id)
  587. {
  588.     return JS_TRUE;
  589. }
  590.  
  591. PR_IMPLEMENT(JSBool)
  592. JS_ConvertStub(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
  593. {
  594. #if JS_BUG_EAGER_TOSTRING
  595.     if (type == JSTYPE_STRING)
  596.     return JS_TRUE;
  597. #endif
  598.     js_TryValueOf(cx, obj, type, vp);
  599.     return JS_TRUE;
  600. }
  601.  
  602. PR_IMPLEMENT(void)
  603. JS_FinalizeStub(JSContext *cx, JSObject *obj)
  604. {
  605. }
  606.  
  607. PR_IMPLEMENT(JSObject *)
  608. JS_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto,
  609.          JSClass *clasp, JSNative constructor, uintN nargs,
  610.          JSPropertySpec *ps, JSFunctionSpec *fs,
  611.          JSPropertySpec *static_ps, JSFunctionSpec *static_fs)
  612. {
  613.     JSAtom *atom;
  614.     JSObject *proto, *fun_proto;
  615.     JSFunction *fun;
  616.     jsval junk;
  617.  
  618.     JS_LOCK(cx);
  619.     atom = js_Atomize(cx, clasp->name, strlen(clasp->name), 0);
  620.     if (!atom) {
  621.     proto = NULL;
  622.     goto out;
  623.     }
  624.  
  625.     /* Define the constructor function in obj's scope. */
  626.     fun = js_DefineFunction(cx, obj, atom, constructor, nargs, 0);
  627.     if (!fun) {
  628.     proto = NULL;
  629.     goto out;
  630.     }
  631.  
  632.     /* Construct a proto object for this class. */
  633.     proto = js_NewObject(cx, clasp, parent_proto, fun->object);
  634.     if (!proto)
  635.     goto out;
  636.  
  637.     /* Bootstrap Function.prototype (see also JS_InitStandardClasses). */
  638.     if (fun->object->map->clasp == clasp) {
  639.     fun_proto = OBJ_GET_PROTO(fun->object);
  640.     if (!fun_proto)
  641.         OBJ_SET_PROTO(fun->object, proto);
  642.     }
  643.  
  644.     /* Add properties and methods to the prototype and the constructor. */
  645.     if (!js_SetClassPrototype(cx, fun, proto) ||
  646.     (ps && !JS_DefineProperties(cx, proto, ps)) ||
  647.     (fs && !JS_DefineFunctions(cx, proto, fs)) ||
  648.     (static_ps && !JS_DefineProperties(cx, fun->object, static_ps)) ||
  649.     (static_fs && !JS_DefineFunctions(cx, fun->object, static_fs))) {
  650.     cx->newborn[GCX_OBJECT] = NULL;
  651.     proto = NULL;
  652.     goto out;
  653.     }
  654.  
  655. out:
  656.     if (!proto)
  657.     (void) js_DeleteProperty(cx, obj, (jsval)atom, &junk);
  658.     if (atom)
  659.     js_DropAtom(cx, atom);
  660.     JS_UNLOCK(cx);
  661.     return proto;
  662. }
  663.  
  664. PR_IMPLEMENT(JSClass *)
  665. JS_GetClass(JSObject *obj)
  666. {
  667.     return obj->map->clasp;
  668. }
  669.  
  670. PR_IMPLEMENT(JSBool)
  671. JS_InstanceOf(JSContext *cx, JSObject *obj, JSClass *clasp, jsval *argv)
  672. {
  673.     JSFunction *fun;
  674.  
  675.     if (obj->map->clasp == clasp)
  676.     return JS_TRUE;
  677.     if (argv) {
  678.     JS_LOCK_VOID(cx, fun = js_ValueToFunction(cx, argv[-2]));
  679.     if (fun) {
  680.         JS_ReportError(cx, "method %s.%s called on incompatible %s",
  681.                clasp->name, JS_GetFunctionName(fun),
  682.                obj->map->clasp->name);
  683.     }
  684.     }
  685.     return JS_FALSE;
  686. }
  687.  
  688. PR_IMPLEMENT(void *)
  689. JS_GetPrivate(JSContext *cx, JSObject *obj)
  690. {
  691.     jsval v;
  692.  
  693.     PR_ASSERT(obj->map->clasp->flags & JSCLASS_HAS_PRIVATE);
  694.     JS_LOCK_VOID(cx, v = js_GetSlot(cx, obj, JSSLOT_PRIVATE));
  695.     if (!JSVAL_IS_INT(v))
  696.     return NULL;
  697.     return JSVAL_TO_PRIVATE(v);
  698. }
  699.  
  700. PR_IMPLEMENT(JSBool)
  701. JS_SetPrivate(JSContext *cx, JSObject *obj, void *data)
  702. {
  703.     PR_ASSERT(obj->map->clasp->flags & JSCLASS_HAS_PRIVATE);
  704.     JS_LOCK_AND_RETURN_BOOL(cx, js_SetSlot(cx, obj, JSSLOT_PRIVATE,
  705.                        PRIVATE_TO_JSVAL(data)));
  706. }
  707.  
  708. PR_IMPLEMENT(void *)
  709. JS_GetInstancePrivate(JSContext *cx, JSObject *obj, JSClass *clasp,
  710.               jsval *argv)
  711. {
  712.     if (!JS_InstanceOf(cx, obj, clasp, argv))
  713.     return NULL;
  714.     return JS_GetPrivate(cx, obj);
  715. }
  716.  
  717. PR_IMPLEMENT(JSObject *)
  718. JS_GetPrototype(JSContext *cx, JSObject *obj)
  719. {
  720.     JSObject *proto;
  721.  
  722.     JS_LOCK_VOID(cx,
  723.          proto = JSVAL_TO_OBJECT(js_GetSlot(cx, obj, JSSLOT_PROTO)));
  724.  
  725.     /* Beware ref to dead object (we may be called from obj's finalizer). */
  726.     return proto && proto->map ? proto : NULL;
  727. }
  728.  
  729. PR_IMPLEMENT(JSBool)
  730. JS_SetPrototype(JSContext *cx, JSObject *obj, JSObject *proto)
  731. {
  732.     JS_LOCK_AND_RETURN_BOOL(cx, js_SetSlot(cx, obj, JSSLOT_PROTO,
  733.                        OBJECT_TO_JSVAL(proto)));
  734. }
  735.  
  736. PR_IMPLEMENT(JSObject *)
  737. JS_GetParent(JSContext *cx, JSObject *obj)
  738. {
  739.     JSObject *parent;
  740.  
  741.     JS_LOCK_VOID(cx,
  742.          parent = JSVAL_TO_OBJECT(js_GetSlot(cx, obj, JSSLOT_PARENT)));
  743.  
  744.     /* Beware ref to dead object (we may be called from obj's finalizer). */
  745.     return parent && parent->map ? parent : NULL;
  746. }
  747.  
  748. PR_IMPLEMENT(JSBool)
  749. JS_SetParent(JSContext *cx, JSObject *obj, JSObject *parent)
  750. {
  751.     JS_LOCK_AND_RETURN_BOOL(cx, js_SetSlot(cx, obj, JSSLOT_PARENT,
  752.                        OBJECT_TO_JSVAL(parent)));
  753. }
  754.  
  755. PR_IMPLEMENT(JSObject *)
  756. JS_GetConstructor(JSContext *cx, JSObject *proto)
  757. {
  758.     JSProperty *prop;
  759.     jsval cval;
  760.  
  761.     JS_LOCK(cx);
  762.     prop = js_GetProperty(cx, proto,
  763.               (jsval)cx->runtime->atomState.constructorAtom,
  764.               &cval);
  765.     JS_UNLOCK(cx);
  766.     if (!prop)
  767.     return NULL;
  768.     if (!JSVAL_IS_FUNCTION(cval)) {
  769.     JS_ReportError(cx, "%s has no constructor", proto->map->clasp->name);
  770.     return NULL;
  771.     }
  772.     return JSVAL_TO_OBJECT(cval);
  773. }
  774.  
  775. PR_IMPLEMENT(JSObject *)
  776. JS_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent)
  777. {
  778.     JS_LOCK_AND_RETURN_TYPE(cx, JSObject *,
  779.                 js_NewObject(cx, clasp, proto, parent));
  780. }
  781.  
  782. PR_IMPLEMENT(JSObject *)
  783. JS_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto,
  784.            JSObject *parent)
  785. {
  786.     JS_LOCK_AND_RETURN_TYPE(cx, JSObject *,
  787.                 js_ConstructObject(cx, clasp, proto, parent));
  788. }
  789.  
  790. static JSProperty *
  791. DefineProperty(JSContext *cx, JSObject *obj, const char *name, jsval value,
  792.            JSPropertyOp getter, JSPropertyOp setter, uintN flags)
  793. {
  794.     jsval id;
  795.     JSAtom *atom;
  796.     JSProperty *prop;
  797.  
  798.     if (flags & JSPROP_INDEX) {
  799.     id = INT_TO_JSVAL((jsint)name);
  800.     atom = NULL;
  801.     } else {
  802.     atom = js_Atomize(cx, name, strlen(name), 0);
  803.     if (!atom)
  804.         return NULL;
  805.     id = (jsval)atom;
  806.     }
  807.     prop = js_DefineProperty(cx, obj, id, value, getter, setter, flags);
  808.     if (atom)
  809.     js_DropAtom(cx, atom);
  810.     return prop;
  811. }
  812.  
  813. PR_IMPLEMENT(JSObject *)
  814. JS_DefineObject(JSContext *cx, JSObject *obj, const char *name, JSClass *clasp,
  815.         JSObject *proto, uintN flags)
  816. {
  817.     JSObject *nobj;
  818.  
  819.     JS_LOCK(cx);
  820.     nobj = js_NewObject(cx, clasp, proto, obj);
  821.     if (nobj &&
  822.     !DefineProperty(cx, obj, name, OBJECT_TO_JSVAL(nobj), NULL, NULL, flags)) {
  823.     cx->newborn[GCX_OBJECT] = NULL;
  824.     nobj = NULL;
  825.     }
  826.     JS_UNLOCK(cx);
  827.     return nobj;
  828. }
  829.  
  830. PR_IMPLEMENT(JSBool)
  831. JS_DefineConstDoubles(JSContext *cx, JSObject *obj, JSConstDoubleSpec *cds)
  832. {
  833.     JSBool ok;
  834.     jsval value;
  835.  
  836.     JS_LOCK(cx);
  837.     for (ok = JS_TRUE; cds->name; cds++) {
  838. #if PR_ALIGN_OF_DOUBLE == 8
  839.     /*
  840.      * The GC ignores references outside its pool such as &cds->dval,
  841.      * so we don't need to GC-alloc constant doubles.
  842.      */
  843.     jsdouble d = cds->dval;
  844.     jsint i = (jsint)d;
  845.  
  846.     value = (JSDOUBLE_IS_INT(d, i) && INT_FITS_IN_JSVAL(i))
  847.         ? INT_TO_JSVAL(i)
  848.         : DOUBLE_TO_JSVAL(&cds->dval);
  849. #else
  850.     ok = js_NewNumberValue(cx, cds->dval, &value);
  851.     if (!ok)
  852.         break;
  853. #endif
  854.     ok = (DefineProperty(cx, obj, cds->name, value,
  855.                  NULL, NULL,
  856.                  /* XXX these should come from an API parameter */
  857.                  JSPROP_READONLY | JSPROP_PERMANENT)
  858.           != NULL);
  859.     if (!ok)
  860.         break;
  861.     }
  862.     JS_UNLOCK(cx);
  863.     return ok;
  864. }
  865.  
  866. PR_IMPLEMENT(JSBool)
  867. JS_DefineProperties(JSContext *cx, JSObject *obj, JSPropertySpec *ps)
  868. {
  869.     JSBool ok;
  870.     JSProperty *prop;
  871.  
  872.     JS_LOCK(cx);
  873.     for (ok = JS_TRUE; ps->name; ps++) {
  874.     prop = DefineProperty(cx, obj, ps->name, JSVAL_VOID,
  875.                   ps->getter, ps->setter, ps->flags);
  876.     if (!prop) {
  877.         ok = JS_FALSE;
  878.         break;
  879.     }
  880.     prop->id = INT_TO_JSVAL(ps->tinyid);
  881.     prop->flags |= JSPROP_TINYIDHACK;
  882.     }
  883.     JS_UNLOCK(cx);
  884.     return ok;
  885. }
  886.  
  887. PR_IMPLEMENT(JSBool)
  888. JS_DefineProperty(JSContext *cx, JSObject *obj, const char *name, jsval value,
  889.           JSPropertyOp getter, JSPropertyOp setter, uintN flags)
  890. {
  891.     JS_LOCK_AND_RETURN_BOOL(cx, DefineProperty(cx, obj, name, value,
  892.                            getter, setter, flags) != NULL);
  893. }
  894.  
  895. PR_IMPLEMENT(JSBool)
  896. JS_DefinePropertyWithTinyId(JSContext *cx, JSObject *obj, const char *name,
  897.                 int8 tinyid, jsval value,
  898.                 JSPropertyOp getter, JSPropertyOp setter,
  899.                 uintN flags)
  900. {
  901.     JSProperty *prop;
  902.  
  903.     JS_LOCK(cx);
  904.     prop = DefineProperty(cx, obj, name, value, getter, setter, flags);
  905.     if (prop) {
  906.     prop->id = INT_TO_JSVAL(tinyid);
  907.     prop->flags |= JSPROP_TINYIDHACK;
  908.     }
  909.     JS_UNLOCK(cx);
  910.     return prop != 0;
  911. }
  912.  
  913. static JSBool
  914. LookupProperty(JSContext *cx, JSObject *obj, const char *name,
  915.            JSProperty **propp)
  916. {
  917.     JSAtom *atom;
  918.     JSBool ok;
  919.  
  920.     atom = js_Atomize(cx, name, strlen(name), 0);
  921.     if (!atom)
  922.     return JS_FALSE;
  923.     ok = js_LookupProperty(cx, obj, (jsval)atom, NULL, propp);
  924.     js_DropAtom(cx, atom);
  925.     return ok;
  926. }
  927.  
  928. PR_IMPLEMENT(JSBool)
  929. JS_AliasProperty(JSContext *cx, JSObject *obj, const char *name,
  930.          const char *alias)
  931. {
  932.     JSBool ok;
  933.     JSProperty *prop;
  934.     JSScope *scope;
  935.     JSAtom *atom;
  936.  
  937.     JS_LOCK(cx);
  938.     ok = LookupProperty(cx, obj, name, &prop);
  939.     if (!ok)
  940.     goto out;
  941.     if (!prop) {
  942.     js_ReportIsNotDefined(cx, name);
  943.     ok = JS_FALSE;
  944.     goto out;
  945.     }
  946.     scope = js_GetMutableScope(cx, obj);
  947.     if (!scope) {
  948.     ok = JS_FALSE;
  949.     goto out;
  950.     }
  951.     atom = js_Atomize(cx, alias, strlen(alias), 0);
  952.     if (!atom) {
  953.     ok = JS_FALSE;
  954.     } else {
  955.     ok = (scope->ops->add(cx, scope, (jsval)atom, prop) != NULL);
  956.     js_DropAtom(cx, atom);
  957.     }
  958. out:
  959.     JS_UNLOCK(cx);
  960.     return ok;
  961. }
  962.  
  963. PR_IMPLEMENT(JSBool)
  964. JS_LookupProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp)
  965. {
  966.     JSBool ok;
  967.     JSProperty *prop;
  968.  
  969.     JS_LOCK(cx);
  970.     ok = LookupProperty(cx, obj, name, &prop);
  971.     if (ok) {
  972.     if (prop)
  973.         *vp = prop->object->slots[prop->slot];
  974.     else
  975.         *vp = JSVAL_VOID;
  976.     }
  977.     JS_UNLOCK(cx);
  978.     return ok;
  979. }
  980.  
  981. PR_IMPLEMENT(JSBool)
  982. JS_GetProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp)
  983. {
  984.     JSAtom *atom;
  985.     JSBool ok;
  986.  
  987.     JS_LOCK(cx);
  988.     atom = js_Atomize(cx, name, strlen(name), 0);
  989.     if (!atom) {
  990.     ok = JS_FALSE;
  991.     } else {
  992.     ok = (js_GetProperty(cx, obj, (jsval)atom, vp) != NULL);
  993.     js_DropAtom(cx, atom);
  994.     }
  995.     JS_UNLOCK(cx);
  996.     return ok;
  997. }
  998.  
  999. PR_IMPLEMENT(JSBool)
  1000. JS_SetProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp)
  1001. {
  1002.     JSAtom *atom;
  1003.     JSBool ok;
  1004.  
  1005.     JS_LOCK(cx);
  1006.     atom = js_Atomize(cx, name, strlen(name), 0);
  1007.     if (!atom) {
  1008.     ok = JS_FALSE;
  1009.     } else {
  1010.     ok = (js_SetProperty(cx, obj, (jsval)atom, vp) != NULL);
  1011.     js_DropAtom(cx, atom);
  1012.     }
  1013.     JS_UNLOCK(cx);
  1014.     return ok;
  1015. }
  1016.  
  1017. PR_IMPLEMENT(JSBool)
  1018. JS_DeleteProperty(JSContext *cx, JSObject *obj, const char *name)
  1019. {
  1020.     JSAtom *atom;
  1021.     JSBool ok;
  1022.     jsval rval;    /* XXX not in API */
  1023.  
  1024.     JS_LOCK(cx);
  1025.     atom = js_Atomize(cx, name, strlen(name), 0);
  1026.     if (!atom) {
  1027.     ok = JS_FALSE;
  1028.     } else {
  1029.     ok = js_DeleteProperty(cx, obj, (jsval)atom, &rval);
  1030.     js_DropAtom(cx, atom);
  1031.     }
  1032.     JS_UNLOCK(cx);
  1033.     return ok;
  1034. }
  1035.  
  1036. PR_IMPLEMENT(JSObject *)
  1037. JS_NewArrayObject(JSContext *cx, jsint length, jsval *vector)
  1038. {
  1039.     JS_LOCK_AND_RETURN_TYPE(cx, JSObject *,
  1040.                 js_NewArrayObject(cx, length, vector));
  1041. }
  1042.  
  1043. PR_IMPLEMENT(JSBool)
  1044. JS_IsArrayObject(JSContext *cx, JSObject *obj)
  1045. {
  1046.     return obj->map->clasp == &js_ArrayClass;
  1047. }
  1048.  
  1049. PR_IMPLEMENT(JSBool)
  1050. JS_GetArrayLength(JSContext *cx, JSObject *obj, jsint *lengthp)
  1051. {
  1052.     JS_LOCK_AND_RETURN_BOOL(cx, js_GetArrayLength(cx, obj, lengthp));
  1053. }
  1054.  
  1055. PR_IMPLEMENT(JSBool)
  1056. JS_SetArrayLength(JSContext *cx, JSObject *obj, jsint length)
  1057. {
  1058.     JS_LOCK_AND_RETURN_BOOL(cx, js_SetArrayLength(cx, obj, length));
  1059. }
  1060.  
  1061. PR_IMPLEMENT(JSBool)
  1062. JS_HasLengthProperty(JSContext *cx, JSObject *obj)
  1063. {
  1064.     JS_LOCK_AND_RETURN_BOOL(cx, js_HasLengthProperty(cx, obj) != NULL);
  1065. }
  1066.  
  1067. PR_IMPLEMENT(JSBool)
  1068. JS_DefineElement(JSContext *cx, JSObject *obj, jsint index, jsval value,
  1069.          JSPropertyOp getter, JSPropertyOp setter, uintN flags)
  1070. {
  1071.     JS_LOCK_AND_RETURN_BOOL(cx, js_DefineProperty(cx, obj, INT_TO_JSVAL(index),
  1072.                           value, getter, setter, flags)
  1073.                 != NULL);
  1074. }
  1075.  
  1076. PR_IMPLEMENT(JSBool)
  1077. JS_AliasElement(JSContext *cx, JSObject *obj, const char *name, jsint alias)
  1078. {
  1079.     JSBool ok;
  1080.     JSProperty *prop;
  1081.     JSScope *scope;
  1082.  
  1083.     JS_LOCK(cx);
  1084.     ok = LookupProperty(cx, obj, name, &prop);
  1085.     if (!ok)
  1086.     goto out;
  1087.     if (!prop) {
  1088.     js_ReportIsNotDefined(cx, name);
  1089.     ok = JS_FALSE;
  1090.     goto out;
  1091.     }
  1092.     scope = js_GetMutableScope(cx, obj);
  1093.     if (!scope)
  1094.     ok = JS_FALSE;
  1095.     else
  1096.     ok = (scope->ops->add(cx, scope, INT_TO_JSVAL(alias), prop) != NULL);
  1097. out:
  1098.     JS_UNLOCK(cx);
  1099.     return ok;
  1100. }
  1101.  
  1102. PR_IMPLEMENT(JSBool)
  1103. JS_LookupElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp)
  1104. {
  1105.     JSBool ok;
  1106.     JSProperty *prop;
  1107.  
  1108.     JS_LOCK(cx);
  1109.     ok = js_LookupProperty(cx, obj, INT_TO_JSVAL(index), NULL, &prop);
  1110.     if (ok) {
  1111.     if (prop)
  1112.         *vp = prop->object->slots[prop->slot];
  1113.     else
  1114.         *vp = JSVAL_VOID;
  1115.     }
  1116.     JS_UNLOCK(cx);
  1117.     return ok;
  1118. }
  1119.  
  1120. PR_IMPLEMENT(JSBool)
  1121. JS_GetElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp)
  1122. {
  1123.     JS_LOCK_AND_RETURN_BOOL(cx,
  1124.                 js_GetProperty(cx, obj, INT_TO_JSVAL(index), vp)
  1125.                 != NULL);
  1126. }
  1127.  
  1128. PR_IMPLEMENT(JSBool)
  1129. JS_SetElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp)
  1130. {
  1131.     JS_LOCK_AND_RETURN_BOOL(cx,
  1132.                 js_SetProperty(cx, obj, INT_TO_JSVAL(index), vp)
  1133.                 != NULL);
  1134. }
  1135.  
  1136. PR_IMPLEMENT(JSBool)
  1137. JS_DeleteElement(JSContext *cx, JSObject *obj, jsint index)
  1138. {
  1139.     jsval rval;    /* XXX not in API */
  1140.  
  1141.     JS_LOCK_AND_RETURN_BOOL(cx,
  1142.                 js_DeleteProperty(cx, obj, INT_TO_JSVAL(index),
  1143.                           &rval));
  1144. }
  1145.  
  1146. PR_IMPLEMENT(void)
  1147. JS_ClearScope(JSContext *cx, JSObject *obj)
  1148. {
  1149.     JSScope *scope;
  1150.  
  1151.     JS_LOCK(cx);
  1152.  
  1153.     /* Avoid lots of js_FlushPropertyCacheByProp activity. */
  1154.     js_FlushPropertyCache(cx);
  1155.  
  1156.     scope = (JSScope *)obj->map;
  1157.     scope->ops->clear(cx, scope);
  1158.  
  1159.     /* Reset freeslot so we're consistent. */
  1160.     if (scope->map.clasp->flags & JSCLASS_HAS_PRIVATE)
  1161.     scope->map.freeslot = JSSLOT_PRIVATE + 1;
  1162.     else
  1163.     scope->map.freeslot = JSSLOT_START;
  1164.  
  1165.     JS_UNLOCK(cx);
  1166. }
  1167.  
  1168. PR_IMPLEMENT(JSFunction *)
  1169. JS_NewFunction(JSContext *cx, JSNative call, uintN nargs, uintN flags,
  1170.            JSObject *parent, const char *name)
  1171. {
  1172.     JSAtom *atom;
  1173.     JSFunction *fun;
  1174.  
  1175.     JS_LOCK(cx);
  1176.     atom = js_Atomize(cx, name, strlen(name), 0);
  1177.     if (!atom) {
  1178.     fun = NULL;
  1179.     } else {
  1180.     fun = js_NewFunction(cx, call, nargs, flags, parent, atom);
  1181.     js_DropAtom(cx, atom);
  1182.     }
  1183.     JS_UNLOCK(cx);
  1184.     return fun;
  1185. }
  1186.  
  1187. PR_IMPLEMENT(JSObject *)
  1188. JS_GetFunctionObject(JSFunction *fun)
  1189. {
  1190.     return fun->object;
  1191. }
  1192.  
  1193. PR_IMPLEMENT(const char *)
  1194. JS_GetFunctionName(JSFunction *fun)
  1195. {
  1196.     return fun->atom
  1197.        ? JS_GetStringBytes(ATOM_TO_STRING(fun->atom))
  1198.        : js_anonymous_str;
  1199. }
  1200.  
  1201. PR_IMPLEMENT(JSBool)
  1202. JS_DefineFunctions(JSContext *cx, JSObject *obj, JSFunctionSpec *fs)
  1203. {
  1204.     JSFunction *fun;
  1205.  
  1206.     for (; fs->name; fs++) {
  1207.     fun = JS_DefineFunction(cx, obj, fs->name, fs->call, fs->nargs,
  1208.                 fs->flags);
  1209.     if (!fun)
  1210.         return JS_FALSE;
  1211.     }
  1212.     return JS_TRUE;
  1213. }
  1214.  
  1215. PR_IMPLEMENT(JSFunction *)
  1216. JS_DefineFunction(JSContext *cx, JSObject *obj, const char *name, JSNative call,
  1217.           uintN nargs, uintN flags)
  1218. {
  1219.     JSAtom *atom;
  1220.     JSFunction *fun;
  1221.  
  1222.     JS_LOCK(cx);
  1223.     atom = js_Atomize(cx, name, strlen(name), 0);
  1224.     if (!atom) {
  1225.     fun = NULL;
  1226.     } else {
  1227.     fun = js_DefineFunction(cx, obj, atom, call, nargs, flags);
  1228.     js_DropAtom(cx, atom);
  1229.     }
  1230.     JS_UNLOCK(cx);
  1231.     return fun;
  1232. }
  1233.  
  1234. static JSScript *
  1235. CompileTokenStream(JSContext *cx, JSObject *obj, JSTokenStream *ts,
  1236.            void *tempMark)
  1237. {
  1238.     void *codeMark;
  1239.     JSCodeGenerator cg;
  1240.     uintN lineno;
  1241.     JSScript *script;
  1242.  
  1243.     PR_ASSERT(JS_IS_LOCKED(cx));
  1244.     codeMark = PR_ARENA_MARK(&cx->codePool);
  1245.     if (!js_InitCodeGenerator(cx, &cg, &cx->codePool))
  1246.     return NULL;
  1247.     lineno = ts->lineno;
  1248.     if (js_Parse(cx, obj, ts, &cg))
  1249.     script = js_NewScript(cx, &cg, ts->filename, lineno,
  1250.                   ts->principals, NULL);
  1251.     else
  1252.     script = NULL;
  1253.     if (!js_CloseTokenStream(cx, ts) && script) {
  1254.     js_DestroyScript(cx, script);
  1255.     script = NULL;
  1256.     }
  1257.     PR_ARENA_RELEASE(&cx->codePool, codeMark);
  1258.     PR_ARENA_RELEASE(&cx->tempPool, tempMark);
  1259.     return script;
  1260. }
  1261.  
  1262. PR_IMPLEMENT(JSScript *)
  1263. JS_CompileScript(JSContext *cx, JSObject *obj,
  1264.          const char *bytes, size_t length,
  1265.          const char *filename, uintN lineno)
  1266. {
  1267.     jschar *chars;
  1268.     JSScript *script;
  1269.  
  1270.     chars = js_InflateString(cx, bytes, length);
  1271.     if (!chars)
  1272.     return NULL;
  1273.     script = JS_CompileUCScript(cx, obj, chars, length, filename, lineno);
  1274.     JS_free(cx, chars);
  1275.     return script;
  1276. }
  1277.  
  1278. PR_IMPLEMENT(JSScript *)
  1279. JS_CompileScriptForPrincipals(JSContext *cx, JSObject *obj,
  1280.                   JSPrincipals *principals,
  1281.                   const char *bytes, size_t length,
  1282.                   const char *filename, uintN lineno)
  1283. {
  1284.     jschar *chars;
  1285.     JSScript *script;
  1286.  
  1287.     chars = js_InflateString(cx, bytes, length);
  1288.     if (!chars)
  1289.     return NULL;
  1290.     script = JS_CompileUCScriptForPrincipals(cx, obj, principals,
  1291.                          chars, length, filename, lineno);
  1292.     JS_free(cx, chars);
  1293.     return script;
  1294. }
  1295.  
  1296. PR_IMPLEMENT(JSScript *)
  1297. JS_CompileUCScript(JSContext *cx, JSObject *obj,
  1298.            const jschar *chars, size_t length,
  1299.            const char *filename, uintN lineno)
  1300. {
  1301.     return JS_CompileUCScriptForPrincipals(cx, obj, NULL, chars, length,
  1302.                        filename, lineno);
  1303. }
  1304.  
  1305. PR_IMPLEMENT(JSScript *)
  1306. JS_CompileUCScriptForPrincipals(JSContext *cx, JSObject *obj,
  1307.                 JSPrincipals *principals,
  1308.                 const jschar *chars, size_t length,
  1309.                 const char *filename, uintN lineno)
  1310. {
  1311.     void *mark;
  1312.     JSTokenStream *ts;
  1313.     JSScript *script;
  1314.  
  1315.     JS_LOCK(cx);
  1316.     mark = PR_ARENA_MARK(&cx->tempPool);
  1317.     ts = js_NewTokenStream(cx, chars, length, filename, lineno, principals);
  1318.     if (ts)
  1319.     script = CompileTokenStream(cx, obj, ts, mark);
  1320.     else
  1321.     script = NULL;
  1322.     JS_UNLOCK(cx);
  1323.     return script;
  1324. }
  1325.  
  1326. #ifdef JSFILE
  1327. PR_IMPLEMENT(JSScript *)
  1328. JS_CompileFile(JSContext *cx, JSObject *obj, const char *filename)
  1329. {
  1330.     void *mark;
  1331.     JSTokenStream *ts;
  1332.     JSScript *script;
  1333.  
  1334.     JS_LOCK(cx);
  1335.     mark = PR_ARENA_MARK(&cx->tempPool);
  1336.     if (filename && strcmp(filename, "-") != 0) {
  1337.     ts = js_NewFileTokenStream(cx, filename);
  1338.     if (!ts) {
  1339.         script = NULL;
  1340.         goto out;
  1341.     }
  1342.     } else {
  1343.     ts = js_NewBufferTokenStream(cx, NULL, 0);
  1344.     if (!ts) {
  1345.         script = NULL;
  1346.         goto out;
  1347.     }
  1348.     ts->file = stdin;
  1349.     }
  1350.     script = CompileTokenStream(cx, obj, ts, mark);
  1351. out:
  1352.     JS_UNLOCK(cx);
  1353.     return script;
  1354. }
  1355. #endif
  1356.  
  1357. PR_IMPLEMENT(void)
  1358. JS_DestroyScript(JSContext *cx, JSScript *script)
  1359. {
  1360.     JS_LOCK_VOID(cx, js_DestroyScript(cx, script));
  1361. }
  1362.  
  1363. PR_IMPLEMENT(JSFunction *)
  1364. JS_CompileFunction(JSContext *cx, JSObject *obj, const char *name,
  1365.            uintN nargs, const char **argnames,
  1366.            const char *bytes, size_t length,
  1367.            const char *filename, uintN lineno)
  1368. {
  1369.     jschar *chars;
  1370.     JSFunction *fun;
  1371.  
  1372.     chars = js_InflateString(cx, bytes, length);
  1373.     if (!chars)
  1374.     return NULL;
  1375.     fun = JS_CompileUCFunction(cx, obj, name, nargs, argnames, chars, length,
  1376.                    filename, lineno);
  1377.     JS_free(cx, chars);
  1378.     return fun;
  1379. }
  1380.  
  1381. PR_IMPLEMENT(JSFunction *)
  1382. JS_CompileFunctionForPrincipals(JSContext *cx, JSObject *obj,
  1383.                 JSPrincipals *principals, const char *name,
  1384.                 uintN nargs, const char **argnames,
  1385.                 const char *bytes, size_t length,
  1386.                 const char *filename, uintN lineno)
  1387. {
  1388.     jschar *chars;
  1389.     JSFunction *fun;
  1390.  
  1391.     chars = js_InflateString(cx, bytes, length);
  1392.     if (!chars)
  1393.     return NULL;
  1394.     fun = JS_CompileUCFunctionForPrincipals(cx, obj, principals, name,
  1395.                         nargs, argnames, chars, length,
  1396.                         filename, lineno);
  1397.     JS_free(cx, chars);
  1398.     return fun;
  1399. }
  1400.  
  1401. PR_IMPLEMENT(JSFunction *)
  1402. JS_CompileUCFunction(JSContext *cx, JSObject *obj, const char *name,
  1403.              uintN nargs, const char **argnames,
  1404.              const jschar *chars, size_t length,
  1405.              const char *filename, uintN lineno)
  1406. {
  1407.     return JS_CompileUCFunctionForPrincipals(cx, obj, NULL, name,
  1408.                          nargs, argnames,
  1409.                          chars, length,
  1410.                          filename, lineno);
  1411. }
  1412.  
  1413. PR_IMPLEMENT(JSFunction *)
  1414. JS_CompileUCFunctionForPrincipals(JSContext *cx, JSObject *obj,
  1415.                   JSPrincipals *principals, const char *name,
  1416.                   uintN nargs, const char **argnames,
  1417.                   const jschar *chars, size_t length,
  1418.                   const char *filename, uintN lineno)
  1419. {
  1420.     void *mark;
  1421.     JSTokenStream *ts;
  1422.     JSFunction *fun;
  1423.     JSAtom *funAtom, *argAtom;
  1424.     JSSymbol *arg, *args, **argp;
  1425.     uintN i;
  1426.     JSProperty *prop;
  1427.     jsval junk;
  1428.  
  1429.     JS_LOCK(cx);
  1430.     mark = PR_ARENA_MARK(&cx->tempPool);
  1431.     ts = js_NewTokenStream(cx, chars, length, filename, lineno, principals);
  1432.     if (!ts) {
  1433.     fun = NULL;
  1434.     funAtom = NULL;
  1435.     goto out;
  1436.     }
  1437.     funAtom = js_Atomize(cx, name, strlen(name), 0);
  1438.     if (!funAtom) {
  1439.     fun = NULL;
  1440.     goto out;
  1441.     }
  1442.     fun = js_DefineFunction(cx, obj, funAtom, NULL, nargs, 0);
  1443.     if (!fun)
  1444.     goto out;
  1445.     args = NULL;
  1446.     if (nargs) {
  1447.     argp = &args;
  1448.     for (i = 0; i < nargs; i++) {
  1449.         argAtom = js_Atomize(cx, argnames[i], strlen(argnames[i]), 0);
  1450.         if (!argAtom)
  1451.         break;
  1452.         prop = js_DefineProperty(cx, fun->object, (jsval)argAtom,
  1453.                      JSVAL_VOID, js_GetArgument, js_SetArgument,
  1454.                      JSPROP_ENUMERATE|JSPROP_PERMANENT);
  1455.         js_DropAtom(cx, argAtom);
  1456.         if (!prop)
  1457.         break;
  1458.         prop->id = INT_TO_JSVAL(i);
  1459.         arg = prop->symbols;
  1460.         *argp = arg;
  1461.         argp = &arg->next;
  1462.     }
  1463.     if (i < nargs) {
  1464.         (void) js_DeleteProperty(cx, obj, (jsval)funAtom, &junk);
  1465.         fun = NULL;
  1466.         goto out;
  1467.     }
  1468.     }
  1469.     if (!js_ParseFunctionBody(cx, ts, fun, args)) {
  1470.     (void) js_DeleteProperty(cx, obj, (jsval)funAtom, &junk);
  1471.     fun = NULL;
  1472.     }
  1473. out:
  1474.     if (funAtom)
  1475.     js_DropAtom(cx, funAtom);
  1476.     if (ts)
  1477.         js_CloseTokenStream(cx, ts);
  1478.     PR_ARENA_RELEASE(&cx->tempPool, mark);
  1479.     JS_UNLOCK(cx);
  1480.     return fun;
  1481. }
  1482.  
  1483. PR_IMPLEMENT(JSString *)
  1484. JS_DecompileScript(JSContext *cx, JSScript *script, const char *name,
  1485.            uintN indent)
  1486. {
  1487.     JSPrinter *jp;
  1488.     JSString *str;
  1489.  
  1490.     JS_LOCK(cx);
  1491.     jp = js_NewPrinter(cx, name, indent);
  1492.     if (!jp) {
  1493.     str = NULL;
  1494.     } else {
  1495.     if (js_DecompileScript(jp, script))
  1496.         str = js_GetPrinterOutput(jp);
  1497.     else
  1498.         str = NULL;
  1499.     js_DestroyPrinter(jp);
  1500.     }
  1501.     JS_UNLOCK(cx);
  1502.     return str;
  1503. }
  1504.  
  1505. PR_IMPLEMENT(JSString *)
  1506. JS_DecompileFunction(JSContext *cx, JSFunction *fun, uintN indent)
  1507. {
  1508.     JSPrinter *jp;
  1509.     JSString *str;
  1510.  
  1511.     JS_LOCK(cx);
  1512.     jp = js_NewPrinter(cx, JS_GetFunctionName(fun), indent);
  1513.     if (!jp) {
  1514.     str = NULL;
  1515.     } else {
  1516.     if (js_DecompileFunction(jp, fun, JS_TRUE))
  1517.         str = js_GetPrinterOutput(jp);
  1518.     else
  1519.         str = NULL;
  1520.     js_DestroyPrinter(jp);
  1521.     }
  1522.     JS_UNLOCK(cx);
  1523.     return str;
  1524. }
  1525.  
  1526. PR_IMPLEMENT(JSString *)
  1527. JS_DecompileFunctionBody(JSContext *cx, JSFunction *fun, uintN indent)
  1528. {
  1529.     return JS_DecompileScript(cx, fun->script, JS_GetFunctionName(fun), indent);
  1530. }
  1531.  
  1532. PR_IMPLEMENT(JSBool)
  1533. JS_ExecuteScript(JSContext *cx, JSObject *obj, JSScript *script, jsval *rval)
  1534. {
  1535.     return js_Execute(cx, obj, script, NULL, rval);
  1536. }
  1537.  
  1538. PR_IMPLEMENT(JSBool)
  1539. JS_EvaluateScript(JSContext *cx, JSObject *obj,
  1540.           const char *bytes, uintN length,
  1541.           const char *filename, uintN lineno,
  1542.           jsval *rval)
  1543. {
  1544.     jschar *chars;
  1545.     JSBool ok;
  1546.  
  1547.     chars = js_InflateString(cx, bytes, length);
  1548.     if (!chars)
  1549.     return JS_FALSE;
  1550.     ok = JS_EvaluateUCScript(cx, obj, chars, length, filename, lineno, rval);
  1551.     JS_free(cx, chars);
  1552.     return ok;
  1553. }
  1554.  
  1555. PR_IMPLEMENT(JSBool)
  1556. JS_EvaluateScriptForPrincipals(JSContext *cx, JSObject *obj,
  1557.                    JSPrincipals *principals,
  1558.                    const char *bytes, uintN length,
  1559.                    const char *filename, uintN lineno,
  1560.                    jsval *rval)
  1561. {
  1562.     jschar *chars;
  1563.     JSBool ok;
  1564.  
  1565.     chars = js_InflateString(cx, bytes, length);
  1566.     if (!chars)
  1567.     return JS_FALSE;
  1568.     ok = JS_EvaluateUCScriptForPrincipals(cx, obj, principals, chars, length,
  1569.                       filename, lineno, rval);
  1570.     JS_free(cx, chars);
  1571.     return ok;
  1572. }
  1573.  
  1574. PR_IMPLEMENT(JSBool)
  1575. JS_EvaluateUCScript(JSContext *cx, JSObject *obj,
  1576.             const jschar *chars, uintN length,
  1577.             const char *filename, uintN lineno,
  1578.             jsval *rval)
  1579. {
  1580.     return JS_EvaluateUCScriptForPrincipals(cx, obj, NULL, chars, length,
  1581.                         filename, lineno, rval);
  1582. }
  1583.  
  1584. PR_IMPLEMENT(JSBool)
  1585. JS_EvaluateUCScriptForPrincipals(JSContext *cx, JSObject *obj,
  1586.                  JSPrincipals *principals,
  1587.                  const jschar *chars, uintN length,
  1588.                  const char *filename, uintN lineno,
  1589.                  jsval *rval)
  1590. {
  1591.     JSScript *script;
  1592.     JSBool ok;
  1593.  
  1594.     script = JS_CompileUCScriptForPrincipals(cx, obj, principals, chars, length,
  1595.                          filename, lineno);
  1596.     if (!script)
  1597.     return JS_FALSE;
  1598.     ok = js_Execute(cx, obj, script, NULL, rval);
  1599.     JS_DestroyScript(cx, script);
  1600.     return ok;
  1601. }
  1602.  
  1603. PR_IMPLEMENT(JSBool)
  1604. JS_CallFunction(JSContext *cx, JSObject *obj, JSFunction *fun, uintN argc,
  1605.         jsval *argv, jsval *rval)
  1606. {
  1607.     JS_LOCK_AND_RETURN_BOOL(cx,
  1608.                 js_Call(cx, obj, OBJECT_TO_JSVAL(fun->object),
  1609.                     argc, argv, rval));
  1610. }
  1611.  
  1612. PR_IMPLEMENT(JSBool)
  1613. JS_CallFunctionName(JSContext *cx, JSObject *obj, const char *name, uintN argc,
  1614.             jsval *argv, jsval *rval)
  1615. {
  1616.     jsval fval;
  1617.  
  1618.     if (!JS_GetProperty(cx, obj, name, &fval))
  1619.     return JS_FALSE;
  1620.     JS_LOCK_AND_RETURN_BOOL(cx, js_Call(cx, obj, fval, argc, argv, rval));
  1621. }
  1622.  
  1623. PR_IMPLEMENT(JSBool)
  1624. JS_CallFunctionValue(JSContext *cx, JSObject *obj, jsval fval, uintN argc,
  1625.              jsval *argv, jsval *rval)
  1626. {
  1627.     JS_LOCK_AND_RETURN_BOOL(cx, js_Call(cx, obj, fval, argc, argv, rval));
  1628. }
  1629.  
  1630. PR_IMPLEMENT(JSBranchCallback)
  1631. JS_SetBranchCallback(JSContext *cx, JSBranchCallback cb)
  1632. {
  1633.     JSBranchCallback oldcb;
  1634.  
  1635.     oldcb = cx->branchCallback;
  1636.     cx->branchCallback = cb;
  1637.     return oldcb;
  1638. }
  1639.  
  1640. PR_IMPLEMENT(JSBool)
  1641. JS_IsRunning(JSContext *cx)
  1642. {
  1643.     return cx->fp != NULL;
  1644. }
  1645.  
  1646. /************************************************************************/
  1647.  
  1648. PR_IMPLEMENT(JSString *)
  1649. JS_NewString(JSContext *cx, char *bytes, size_t length)
  1650. {
  1651.     jschar *chars;
  1652.     JSString *str;
  1653.  
  1654.     /* Make a Unicode vector from the 8-bit char codes in bytes. */
  1655.     chars = js_InflateString(cx, bytes, length);
  1656.     if (!chars)
  1657.     return NULL;
  1658.  
  1659.     /* Free chars (but not bytes, which caller frees on error) if we fail. */
  1660.     str = js_NewString(cx, chars, length, 0);
  1661.     if (!str) {
  1662.     JS_free(cx, chars);
  1663.     return NULL;
  1664.     }
  1665.  
  1666.     /* Hand off bytes to the deflated string cache, if possible. */
  1667.     if (!js_SetStringBytes(str, bytes, length))
  1668.     JS_free(cx, bytes);
  1669.     return str;
  1670. }
  1671.  
  1672. PR_IMPLEMENT(JSString *)
  1673. JS_NewStringCopyN(JSContext *cx, const char *s, size_t n)
  1674. {
  1675.     jschar *js;
  1676.     JSString *str;
  1677.  
  1678.     js = js_InflateString(cx, s, n);
  1679.     if (!js)
  1680.     return NULL;
  1681.     str = js_NewString(cx, js, n, 0);
  1682.     if (!str)
  1683.     JS_free(cx, js);
  1684.     return str;
  1685. }
  1686.  
  1687. PR_IMPLEMENT(JSString *)
  1688. JS_NewStringCopyZ(JSContext *cx, const char *s)
  1689. {
  1690.     size_t n;
  1691.     jschar *js;
  1692.     JSString *str;
  1693.  
  1694.     if (!s)
  1695.     return cx->runtime->emptyString;
  1696.     n = strlen(s);
  1697.     js = js_InflateString(cx, s, n);
  1698.     if (!js)
  1699.     return NULL;
  1700.     str = js_NewString(cx, js, n, 0);
  1701.     if (!str)
  1702.     JS_free(cx, js);
  1703.     return str;
  1704. }
  1705.  
  1706. PR_IMPLEMENT(JSString *)
  1707. JS_InternString(JSContext *cx, const char *s)
  1708. {
  1709.     JSAtom *atom;
  1710.  
  1711.     JS_LOCK_VOID(cx, atom = js_Atomize(cx, s, strlen(s), 0));
  1712.     if (!atom)
  1713.     return NULL;
  1714.     return ATOM_TO_STRING(atom);
  1715. }
  1716.  
  1717. PR_IMPLEMENT(JSString *)
  1718. JS_NewUCString(JSContext *cx, jschar *chars, size_t length)
  1719. {
  1720.     return js_NewString(cx, chars, length, 0);
  1721. }
  1722.  
  1723. PR_IMPLEMENT(JSString *)
  1724. JS_NewUCStringCopyN(JSContext *cx, const jschar *s, size_t n)
  1725. {
  1726.     return js_NewStringCopyN(cx, s, n, 0);
  1727. }
  1728.  
  1729. PR_IMPLEMENT(JSString *)
  1730. JS_NewUCStringCopyZ(JSContext *cx, const jschar *s)
  1731. {
  1732.     if (!s)
  1733.     return cx->runtime->emptyString;
  1734.     return js_NewStringCopyZ(cx, s, 0);
  1735. }
  1736.  
  1737. PR_IMPLEMENT(JSString *)
  1738. JS_InternUCString(JSContext *cx, const jschar *s)
  1739. {
  1740.     JSAtom *atom;
  1741.  
  1742.     JS_LOCK_VOID(cx, atom = js_AtomizeChars(cx, s, js_strlen(s), 0));
  1743.     if (!atom)
  1744.     return NULL;
  1745.     return ATOM_TO_STRING(atom);
  1746. }
  1747.  
  1748. PR_IMPLEMENT(char *)
  1749. JS_GetStringBytes(JSString *str)
  1750. {
  1751.     char *bytes = js_GetStringBytes(str);
  1752.     return bytes ? bytes : "";
  1753. }
  1754.  
  1755. PR_IMPLEMENT(jschar *)
  1756. JS_GetStringChars(JSString *str)
  1757. {
  1758.     return str->chars;
  1759. }
  1760.  
  1761. PR_IMPLEMENT(size_t)
  1762. JS_GetStringLength(JSString *str)
  1763. {
  1764.     return str->length;
  1765. }
  1766.  
  1767. PR_IMPLEMENT(intN)
  1768. JS_CompareStrings(JSString *str1, JSString *str2)
  1769. {
  1770.     return js_CompareStrings(str1, str2);
  1771. }
  1772.  
  1773. /************************************************************************/
  1774.  
  1775. PR_IMPLEMENT(void)
  1776. JS_ReportError(JSContext *cx, const char *format, ...)
  1777. {
  1778.     va_list ap;
  1779.  
  1780.     va_start(ap, format);
  1781.     js_ReportErrorVA(cx, format, ap);
  1782.     va_end(ap);
  1783. }
  1784.  
  1785. PR_IMPLEMENT(void)
  1786. JS_ReportOutOfMemory(JSContext *cx)
  1787. {
  1788.     JS_ReportError(cx, "out of memory");
  1789. }
  1790.  
  1791. PR_IMPLEMENT(JSErrorReporter)
  1792. JS_SetErrorReporter(JSContext *cx, JSErrorReporter er)
  1793. {
  1794.     JSErrorReporter older;
  1795.  
  1796.     older = cx->errorReporter;
  1797.     cx->errorReporter = er;
  1798.     return older;
  1799. }
  1800.  
  1801. /************************************************************************/
  1802.  
  1803. /*
  1804.  * Regular Expressions.
  1805.  */
  1806. PR_IMPLEMENT(JSObject *)
  1807. JS_NewRegExpObject(JSContext *cx, char *bytes, size_t length, uintN flags)
  1808. {
  1809. #if JS_HAS_REGEXPS
  1810.     jschar *chars;
  1811.     JSObject *obj;
  1812.  
  1813.     chars = js_InflateString(cx, bytes, length);
  1814.     if (!chars)
  1815.     return NULL;
  1816.     JS_LOCK_VOID(cx, obj = js_NewRegExpObject(cx, chars, length, flags));
  1817.     JS_free(cx, chars);
  1818.     return obj;
  1819. #else
  1820.     JS_ReportError(cx, "sorry, regular expression are not supported");
  1821.     return JS_FALSE;
  1822. #endif
  1823. }
  1824.  
  1825. PR_IMPLEMENT(JSObject *)
  1826. JS_NewUCRegExpObject(JSContext *cx, jschar *chars, size_t length, uintN flags)
  1827. {
  1828. #if JS_HAS_REGEXPS
  1829.     JS_LOCK_AND_RETURN_TYPE(cx, JSObject *,
  1830.                 js_NewRegExpObject(cx, chars, length, flags));
  1831. #else
  1832.     JS_ReportError(cx, "sorry, regular expression are not supported");
  1833.     return JS_FALSE;
  1834. #endif
  1835. }
  1836.  
  1837. PR_IMPLEMENT(void)
  1838. JS_SetRegExpInput(JSContext *cx, JSString *input, JSBool multiline)
  1839. {
  1840.     JSRegExpStatics *res;
  1841.  
  1842.     /* No locking required, cx is thread-private and input must be live. */
  1843.     res = &cx->regExpStatics;
  1844.     res->input = input;
  1845.     res->multiline = multiline;
  1846. }
  1847.  
  1848. PR_IMPLEMENT(void)
  1849. JS_ClearRegExpStatics(JSContext *cx)
  1850. {
  1851.     JSRegExpStatics *res;
  1852.  
  1853.     /* No locking required, cx is thread-private and input must be live. */
  1854.     res = &cx->regExpStatics;
  1855.     res->input = NULL;
  1856.     res->multiline = JS_FALSE;
  1857.     res->parenCount = 0;
  1858.     res->lastMatch = res->lastParen = js_EmptySubString;
  1859.     res->leftContext = res->rightContext = js_EmptySubString;
  1860. }
  1861.  
  1862. PR_IMPLEMENT(void)
  1863. JS_ClearRegExpRoots(JSContext *cx)
  1864. {
  1865.     JSRegExpStatics *res;
  1866.  
  1867.     /* No locking required, cx is thread-private and input must be live. */
  1868.     res = &cx->regExpStatics;
  1869.     res->input = NULL;
  1870.     res->execWrapper = NULL;
  1871. }
  1872.  
  1873. /* TODO: compile, execute, get/set other statics... */
  1874.  
  1875. /************************************************************************/
  1876.  
  1877. #ifdef NETSCAPE_INTERNAL
  1878. PR_IMPLEMENT(void)
  1879. JS_SetCharSetInfo(JSContext *cx, const char *csName, int csId,
  1880.           JSCharScanner scanner)
  1881. {
  1882.     cx->charSetName       = csName;
  1883.     cx->charSetNameLength = csName ? strlen(csName) : 0;
  1884.     cx->charSetId         = csId;
  1885.     cx->charScanner       = scanner;
  1886. }
  1887.  
  1888. PR_IMPLEMENT(JSBool)
  1889. JS_IsAssigning(JSContext *cx)
  1890. {
  1891.     JSStackFrame *fp;
  1892.     jsbytecode *pc;
  1893.  
  1894.     if (!(fp = cx->fp) || !(pc = fp->pc))
  1895.     return JS_FALSE;
  1896.     return (js_CodeSpec[*pc].format & JOF_SET) != 0;
  1897. }
  1898. #endif
  1899.  
  1900. /************************************************************************/
  1901.  
  1902. #ifdef XP_PC
  1903. #if defined(XP_OS2_HACK)
  1904. /*DSR031297 - the OS/2 equiv is dll_InitTerm, but I don't see the need for it*/
  1905. #else
  1906. /*
  1907.  * Initialization routine for the JS DLL...
  1908.  */
  1909.  
  1910. /*
  1911.  * Global Instance handle...
  1912.  * In Win32 this is the module handle of the DLL.
  1913.  *
  1914.  * In Win16 this is the instance handle of the application
  1915.  * which loaded the DLL.
  1916.  */
  1917.  
  1918. #ifdef _WIN32
  1919. BOOL WINAPI DllMain (HINSTANCE hDLL, DWORD dwReason, LPVOID lpReserved)
  1920. {
  1921.     return TRUE;
  1922. }
  1923.  
  1924. #else  /* !_WIN32 */
  1925.  
  1926. int CALLBACK LibMain( HINSTANCE hInst, WORD wDataSeg,
  1927.               WORD cbHeapSize, LPSTR lpszCmdLine )
  1928. {
  1929.     return TRUE;
  1930. }
  1931.  
  1932. BOOL CALLBACK __loadds WEP(BOOL fSystemExit)
  1933. {
  1934.     return TRUE;
  1935. }
  1936.  
  1937. #endif /* !_WIN32 */
  1938. #endif /* XP_OS2 */
  1939. #endif /* XP_PC */
  1940.