Skip to content
Browse files

iMonkey Initial Commit

  • Loading branch information...
0 parents commit 1e8d5d2194bc13c73ff003974d6835eb8e210211 @apage43 apage43 committed
Sorry, we could not display the entire diff because it was too big.
8 .gitignore
@@ -0,0 +1,8 @@
+.DS_Store
+*.swp
+*.pbxuser
+*.perspectivev3
+*.mode1v3
+xcuserdata
+*.xcworkspace
+build
1,110 iMonkey.xcodeproj/project.pbxproj
1,110 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
7 iMonkey_Prefix.pch
@@ -0,0 +1,7 @@
+//
+// Prefix header for all source files of the 'CocoaTouchStaticLibrary' target in the 'CocoaTouchStaticLibrary' project.
+//
+
+#ifdef __OBJC__
+ #import <Foundation/Foundation.h>
+#endif
91 src/js/src/builtins.tbl
@@ -0,0 +1,91 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sw=4 et tw=0 ft=C:
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released
+ * June 22, 2008.
+ *
+ * The Initial Developer of the Original Code is
+ * Andreas Gal <gal@uci.edu>
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * This file declares builtin functions that can be called from JITted code.
+ * Each line starts with "BUILTIN" and an integer, the number of arguments the
+ * builtin takes. Builtins with no arguments are not supported.
+ *
+ * The macro arguments are:
+ *
+ * - 'extern' to indicate extern linkage for these functions and the associated
+ * CallInfo.
+ *
+ * - The return type. This identifier must name one of the _JS_TYPEINFO_*
+ * macros defined in jsbuiltins.h.
+ *
+ * - The builtin name. Prefixed with "js_" this gives the native function name.
+ *
+ * - The parameter types.
+ *
+ * - The cse flag. 1 if the builtin call can be optimized away by common
+ * subexpression elimination; otherwise 0. This should be 1 only if the
+ * function is idempotent and the return value is determined solely by the
+ * arguments.
+ *
+ * - The fold flag. Reserved. The same as cse for now.
+ */
+
+/*
+ * NB: bool FASTCALL is not compatible with Nanojit's calling convention usage.
+ * Do not use bool FASTCALL, use JSBool only!
+ */
+
+BUILTIN2(extern, JSVAL, js_BoxDouble, CONTEXT, DOUBLE, 1, 1)
+BUILTIN2(extern, JSVAL, js_BoxInt32, CONTEXT, INT32, 1, 1)
+BUILTIN1(extern, DOUBLE, js_UnboxDouble, JSVAL, 1, 1)
+BUILTIN1(extern, INT32, js_UnboxInt32, JSVAL, 1, 1)
+BUILTIN2(extern, DOUBLE, js_dmod, DOUBLE, DOUBLE, 1, 1)
+BUILTIN2(extern, INT32, js_imod, INT32, INT32, 1, 1)
+BUILTIN1(extern, INT32, js_DoubleToInt32, DOUBLE, 1, 1)
+BUILTIN1(extern, UINT32, js_DoubleToUint32, DOUBLE, 1, 1)
+
+BUILTIN2(extern, DOUBLE, js_StringToNumber, CONTEXT, STRING, 1, 1)
+BUILTIN2(extern, INT32, js_StringToInt32, CONTEXT, STRING, 1, 1)
+BUILTIN2(FRIEND, BOOL, js_CloseIterator, CONTEXT, JSVAL, 0, 0)
+BUILTIN2(extern, SIDEEXIT, js_CallTree, INTERPSTATE, FRAGMENT, 0, 0)
+BUILTIN3(extern, BOOL, js_AddProperty, CONTEXT, OBJECT, SCOPEPROP, 0, 0)
+BUILTIN3(extern, BOOL, js_HasNamedProperty, CONTEXT, OBJECT, STRING, 0, 0)
+BUILTIN3(extern, BOOL, js_HasNamedPropertyInt32, CONTEXT, OBJECT, INT32, 0, 0)
+BUILTIN3(extern, JSVAL, js_CallGetter, CONTEXT, OBJECT, SCOPEPROP, 0, 0)
+BUILTIN2(extern, STRING, js_TypeOfObject, CONTEXT, OBJECT, 1, 1)
+BUILTIN2(extern, STRING, js_TypeOfBoolean, CONTEXT, INT32, 1, 1)
+BUILTIN2(extern, DOUBLE, js_BooleanOrUndefinedToNumber, CONTEXT, INT32, 1, 1)
+BUILTIN2(extern, STRING, js_BooleanOrUndefinedToString, CONTEXT, INT32, 1, 1)
+BUILTIN2(extern, OBJECT, js_Arguments, CONTEXT, OBJECT 0, 0)
+BUILTIN4(extern, OBJECT, js_NewNullClosure, CONTEXT, OBJECT, OBJECT, OBJECT, 0, 0)
3,336 src/js/src/dtoa.c
3,336 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
97 src/js/src/jitstats.tbl
@@ -0,0 +1,97 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sw=4 et tw=0 ft=C:
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released
+ * June 22, 2008.
+ *
+ * The Initial Developer of the Original Code is
+ * Brian Crowder <crowder@fiverocks.com>
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* NB: Keep this list synced with jitstatHandler in trace-test.js. */
+/**
+ * Proper use of this file: Consumers must define JITSTAT; they can optionally
+ * also define MONITOR_JITSTAT or RECORDER_JITSTAT or both to do separate
+ * things with stats that are monitor or recorder specific. If those are not
+ * defined, they will be automatically defined to JITSTAT.
+ */
+#ifdef DEFINED_MONITOR_JITSTAT
+#error "How did that happen?"
+#endif
+
+#ifdef DEFINED_RECORDER_JITSTAT
+#error "How did that happen?"
+#endif
+
+#ifndef MONITOR_JITSTAT
+#define MONITOR_JITSTAT(_ident, _name) JITSTAT(_ident)
+#define DEFINED_MONITOR_JITSTAT
+#endif
+
+#ifndef RECORDER_JITSTAT
+#define RECORDER_JITSTAT(_ident, _name) JITSTAT(_ident)
+#define DEFINED_RECORDER_JITSTAT
+#endif
+
+RECORDER_JITSTAT(recorderStarted, "started")
+RECORDER_JITSTAT(recorderAborted, "aborted")
+RECORDER_JITSTAT(traceCompleted, "completed")
+MONITOR_JITSTAT(sideExitIntoInterpreter, "exits")
+MONITOR_JITSTAT(timeoutIntoInterpreter, "timeouts")
+MONITOR_JITSTAT(typeMapMismatchAtEntry, "type mismatch")
+RECORDER_JITSTAT(returnToDifferentLoopHeader, "different header")
+MONITOR_JITSTAT(traceTriggered, "triggered")
+MONITOR_JITSTAT(globalShapeMismatchAtEntry, "global mismatch")
+RECORDER_JITSTAT(treesTrashed, "trees trashed")
+RECORDER_JITSTAT(slotPromoted, "slot promoted")
+RECORDER_JITSTAT(unstableLoopVariable, "unstable loop variable")
+RECORDER_JITSTAT(breakLoopExits, "breaks")
+RECORDER_JITSTAT(returnLoopExits, "returns")
+RECORDER_JITSTAT(mergedLoopExits, "merged loop exits")
+RECORDER_JITSTAT(noCompatInnerTrees, "unstableInnerCalls")
+RECORDER_JITSTAT(blacklisted, "blacklisted")
+MONITOR_JITSTAT(cacheFlushed, "flushed")
+JITSTAT(archIsIA32)
+JITSTAT(archIsAMD64)
+JITSTAT(archIs64BIT)
+JITSTAT(archIsARM)
+JITSTAT(archIsSPARC)
+JITSTAT(archIsPPC)
+
+#ifdef DEFINED_MONITOR_JITSTAT
+#undef DEFINED_MONITOR_JITSTAT
+#undef MONITOR_JITSTAT
+#endif
+
+#ifdef DEFINED_RECORDER_JITSTAT
+#undef DEFINED_RECORDER_JITSTAT
+#undef RECORDER_JITSTAT
+#endif
87 src/js/src/js-config.h
@@ -0,0 +1,87 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sw=4 et tw=78:
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef js_config_h___
+#define js_config_h___
+
+/* Definitions set at build time that affect SpiderMonkey's public API.
+ This header file is generated by the SpiderMonkey configure script,
+ and installed along with jsapi.h. */
+
+/* Define to 1 if SpiderMonkey should support multi-threaded clients. */
+//#undef JS_THREADSAFE
+#define JS_THREADSAFE 1
+/* Define to 1 if SpiderMonkey should support the ability to perform
+ entirely too much GC. */
+#undef JS_GC_ZEAL
+
+/* Define to 1 if the standard <stdint.h> header is present and
+ useable. See jstypes.h and jsstdint.h. */
+#undef JS_HAVE_STDINT_H
+
+/* Define to 1 if the N-byte __intN types are defined by the
+ compiler. */
+#undef JS_HAVE___INTN
+
+/* Define to 1 if #including <stddef.h> provides definitions for
+ intptr_t and uintptr_t. */
+#undef JS_STDDEF_H_HAS_INTPTR_T
+
+/* Define to 1 if #including <crtdefs.h> provides definitions for
+ intptr_t and uintptr_t. */
+#undef JS_CRTDEFS_H_HAS_INTPTR_T
+
+/* The configure script defines these if it doesn't #define
+ JS_HAVE_STDINT_H. */
+#define JS_INT8_TYPE char
+#define JS_INT16_TYPE short
+#define JS_INT32_TYPE int
+#define JS_INT64_TYPE long long
+#define JS_INTPTR_TYPE long
+#define JS_BYTES_PER_WORD 4
+
+/* Some mozilla code uses JS-friend APIs that depend on JS_TRACER being
+ correct. */
+#undef FEATURE_NANOJIT
+#undef NANOJIT_ARM
+#undef AVMPLUS_ARM
+#undef JS_TRACER
+
+#endif /* js_config_h___ */
319 src/js/src/js.msg
@@ -0,0 +1,319 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * This is the JavaScript error message file.
+ *
+ * The format for each JS error message is:
+ *
+ * MSG_DEF(<SYMBOLIC_NAME>, <ERROR_NUMBER>, <ARGUMENT_COUNT>, <EXCEPTION_NAME>,
+ * <FORMAT_STRING>)
+ *
+ * where ;
+ * <SYMBOLIC_NAME> is a legal C identifer that will be used in the
+ * JS engine source.
+ *
+ * <ERROR_NUMBER> is an unique integral value identifying this error.
+ *
+ * <ARGUMENT_COUNT> is an integer literal specifying the total number of
+ * replaceable arguments in the following format string.
+ *
+ * <EXCEPTION_NAME> is an exception index from the enum in jsexn.c;
+ * JSEXN_NONE for none. The given exception index will be raised by the
+ * engine when the corresponding error occurs.
+ *
+ * <FORMAT_STRING> is a string literal, optionally containing sequences
+ * {X} where X is an integer representing the argument number that will
+ * be replaced with a string value when the error is reported.
+ *
+ * e.g.
+ *
+ * MSG_DEF(JSMSG_NOT_A_SUBSPECIES, 73, JSEXN_NONE, 2,
+ * "{0} is not a member of the {1} family")
+ *
+ * can be used:
+ *
+ * JS_ReportErrorNumber(JSMSG_NOT_A_SUBSPECIES, "Rhino", "Monkey");
+ *
+ * to report:
+ *
+ * "Rhino is not a member of the Monkey family"
+ *
+ * Before adding a new MSG_DEF at the end, look for JSMSG_UNUSED<n> free
+ * index placeholders in the middle of the list.
+ */
+
+MSG_DEF(JSMSG_NOT_AN_ERROR, 0, 0, JSEXN_NONE, "<Error #0 is reserved>")
+MSG_DEF(JSMSG_NOT_DEFINED, 1, 1, JSEXN_REFERENCEERR, "{0} is not defined")
+MSG_DEF(JSMSG_INACTIVE, 2, 0, JSEXN_INTERNALERR, "nothing active on context")
+MSG_DEF(JSMSG_MORE_ARGS_NEEDED, 3, 3, JSEXN_TYPEERR, "{0} requires more than {1} argument{2}")
+MSG_DEF(JSMSG_BAD_CHAR, 4, 1, JSEXN_INTERNALERR, "invalid format character {0}")
+MSG_DEF(JSMSG_BAD_TYPE, 5, 1, JSEXN_TYPEERR, "unknown type {0}")
+MSG_DEF(JSMSG_ALLOC_OVERFLOW, 6, 0, JSEXN_INTERNALERR, "allocation size overflow")
+MSG_DEF(JSMSG_CANT_UNLOCK, 7, 0, JSEXN_INTERNALERR, "can't unlock memory")
+MSG_DEF(JSMSG_INCOMPATIBLE_PROTO, 8, 3, JSEXN_TYPEERR, "{0}.prototype.{1} called on incompatible {2}")
+MSG_DEF(JSMSG_NO_CONSTRUCTOR, 9, 1, JSEXN_TYPEERR, "{0} has no constructor")
+MSG_DEF(JSMSG_CANT_ALIAS, 10, 3, JSEXN_TYPEERR, "can't alias {0} to {1} in class {2}")
+MSG_DEF(JSMSG_NOT_SCRIPTED_FUNCTION, 11, 1, JSEXN_TYPEERR, "{0} is not a scripted function")
+MSG_DEF(JSMSG_BAD_SORT_ARG, 12, 0, JSEXN_TYPEERR, "invalid Array.prototype.sort argument")
+MSG_DEF(JSMSG_BAD_ATOMIC_NUMBER, 13, 1, JSEXN_INTERNALERR, "internal error: no index for atom {0}")
+MSG_DEF(JSMSG_TOO_MANY_LITERALS, 14, 0, JSEXN_INTERNALERR, "too many literals")
+MSG_DEF(JSMSG_CANT_WATCH, 15, 1, JSEXN_TYPEERR, "can't watch non-native objects of class {0}")
+MSG_DEF(JSMSG_STACK_UNDERFLOW, 16, 2, JSEXN_INTERNALERR, "internal error compiling {0}: stack underflow at pc {1}")
+MSG_DEF(JSMSG_NEED_DIET, 17, 1, JSEXN_INTERNALERR, "{0} too large")
+MSG_DEF(JSMSG_TOO_MANY_LOCAL_ROOTS, 18, 0, JSEXN_ERR, "out of local root space")
+MSG_DEF(JSMSG_READ_ONLY, 19, 1, JSEXN_ERR, "{0} is read-only")
+MSG_DEF(JSMSG_BAD_FORMAL, 20, 0, JSEXN_SYNTAXERR, "malformed formal parameter")
+MSG_DEF(JSMSG_BAD_ITERATOR, 21, 3, JSEXN_TYPEERR, "{0} has invalid {1} value {2}")
+MSG_DEF(JSMSG_NOT_FUNCTION, 22, 1, JSEXN_TYPEERR, "{0} is not a function")
+MSG_DEF(JSMSG_NOT_CONSTRUCTOR, 23, 1, JSEXN_TYPEERR, "{0} is not a constructor")
+MSG_DEF(JSMSG_SCRIPT_STACK_QUOTA, 24, 0, JSEXN_INTERNALERR, "script stack space quota is exhausted")
+MSG_DEF(JSMSG_TOO_DEEP, 25, 1, JSEXN_INTERNALERR, "{0} nested too deeply")
+MSG_DEF(JSMSG_OVER_RECURSED, 26, 0, JSEXN_INTERNALERR, "too much recursion")
+MSG_DEF(JSMSG_IN_NOT_OBJECT, 27, 1, JSEXN_TYPEERR, "invalid 'in' operand {0}")
+MSG_DEF(JSMSG_BAD_NEW_RESULT, 28, 1, JSEXN_TYPEERR, "invalid new expression result {0}")
+MSG_DEF(JSMSG_BAD_SHARP_DEF, 29, 1, JSEXN_ERR, "invalid sharp variable definition #{0}=")
+MSG_DEF(JSMSG_BAD_SHARP_USE, 30, 1, JSEXN_ERR, "invalid sharp variable use #{0}#")
+MSG_DEF(JSMSG_BAD_INSTANCEOF_RHS, 31, 1, JSEXN_TYPEERR, "invalid 'instanceof' operand {0}")
+MSG_DEF(JSMSG_BAD_BYTECODE, 32, 1, JSEXN_INTERNALERR, "unimplemented JavaScript bytecode {0}")
+MSG_DEF(JSMSG_BAD_RADIX, 33, 1, JSEXN_ERR, "illegal radix {0}")
+MSG_DEF(JSMSG_PAREN_BEFORE_LET, 34, 0, JSEXN_SYNTAXERR, "missing ( before let head")
+MSG_DEF(JSMSG_CANT_CONVERT, 35, 1, JSEXN_ERR, "can't convert {0} to an integer")
+MSG_DEF(JSMSG_CYCLIC_VALUE, 36, 1, JSEXN_ERR, "cyclic {0} value")
+MSG_DEF(JSMSG_COMPILE_EXECED_SCRIPT, 37, 0, JSEXN_TYPEERR, "cannot compile over a script that is currently executing")
+MSG_DEF(JSMSG_CANT_CONVERT_TO, 38, 2, JSEXN_TYPEERR, "can't convert {0} to {1}")
+MSG_DEF(JSMSG_NO_PROPERTIES, 39, 1, JSEXN_TYPEERR, "{0} has no properties")
+MSG_DEF(JSMSG_CANT_FIND_CLASS, 40, 1, JSEXN_TYPEERR, "can't find class id {0}")
+MSG_DEF(JSMSG_CANT_XDR_CLASS, 41, 1, JSEXN_TYPEERR, "can't XDR class {0}")
+MSG_DEF(JSMSG_BYTECODE_TOO_BIG, 42, 2, JSEXN_INTERNALERR, "bytecode {0} too large (limit {1})")
+MSG_DEF(JSMSG_UNKNOWN_FORMAT, 43, 1, JSEXN_INTERNALERR, "unknown bytecode format {0}")
+MSG_DEF(JSMSG_TOO_MANY_CON_ARGS, 44, 0, JSEXN_SYNTAXERR, "too many constructor arguments")
+MSG_DEF(JSMSG_TOO_MANY_FUN_ARGS, 45, 0, JSEXN_SYNTAXERR, "too many function arguments")
+MSG_DEF(JSMSG_BAD_QUANTIFIER, 46, 1, JSEXN_SYNTAXERR, "invalid quantifier {0}")
+MSG_DEF(JSMSG_MIN_TOO_BIG, 47, 1, JSEXN_SYNTAXERR, "overlarge minimum {0}")
+MSG_DEF(JSMSG_MAX_TOO_BIG, 48, 1, JSEXN_SYNTAXERR, "overlarge maximum {0}")
+MSG_DEF(JSMSG_OUT_OF_ORDER, 49, 1, JSEXN_SYNTAXERR, "maximum {0} less than minimum")
+MSG_DEF(JSMSG_BAD_DESTRUCT_DECL, 50, 0, JSEXN_SYNTAXERR, "missing = in destructuring declaration")
+MSG_DEF(JSMSG_BAD_DESTRUCT_ASS, 51, 0, JSEXN_SYNTAXERR, "invalid destructuring assignment operator")
+MSG_DEF(JSMSG_PAREN_AFTER_LET, 52, 0, JSEXN_SYNTAXERR, "missing ) after let head")
+MSG_DEF(JSMSG_CURLY_AFTER_LET, 53, 0, JSEXN_SYNTAXERR, "missing } after let block")
+MSG_DEF(JSMSG_MISSING_PAREN, 54, 0, JSEXN_SYNTAXERR, "unterminated parenthetical")
+MSG_DEF(JSMSG_UNTERM_CLASS, 55, 1, JSEXN_SYNTAXERR, "unterminated character class {0}")
+MSG_DEF(JSMSG_TRAILING_SLASH, 56, 0, JSEXN_SYNTAXERR, "trailing \\ in regular expression")
+MSG_DEF(JSMSG_BAD_CLASS_RANGE, 57, 0, JSEXN_SYNTAXERR, "invalid range in character class")
+MSG_DEF(JSMSG_BAD_REGEXP_FLAG, 58, 1, JSEXN_SYNTAXERR, "invalid regular expression flag {0}")
+MSG_DEF(JSMSG_NO_INPUT, 59, 5, JSEXN_SYNTAXERR, "no input for /{0}/{1}{2}{3}{4}")
+MSG_DEF(JSMSG_CANT_OPEN, 60, 2, JSEXN_ERR, "can't open {0}: {1}")
+MSG_DEF(JSMSG_BAD_STRING_MASK, 61, 1, JSEXN_ERR, "invalid string escape mask {0}")
+MSG_DEF(JSMSG_UNMATCHED_RIGHT_PAREN, 62, 0, JSEXN_SYNTAXERR, "unmatched ) in regular expression")
+MSG_DEF(JSMSG_END_OF_DATA, 63, 0, JSEXN_INTERNALERR, "unexpected end of data")
+MSG_DEF(JSMSG_SEEK_BEYOND_START, 64, 0, JSEXN_INTERNALERR, "illegal seek beyond start")
+MSG_DEF(JSMSG_SEEK_BEYOND_END, 65, 0, JSEXN_INTERNALERR, "illegal seek beyond end")
+MSG_DEF(JSMSG_END_SEEK, 66, 0, JSEXN_INTERNALERR, "illegal end-based seek")
+MSG_DEF(JSMSG_WHITHER_WHENCE, 67, 1, JSEXN_INTERNALERR, "unknown seek whence: {0}")
+MSG_DEF(JSMSG_BAD_SCRIPT_MAGIC, 68, 0, JSEXN_INTERNALERR, "bad script XDR magic number")
+MSG_DEF(JSMSG_PAREN_BEFORE_FORMAL, 69, 0, JSEXN_SYNTAXERR, "missing ( before formal parameters")
+MSG_DEF(JSMSG_MISSING_FORMAL, 70, 0, JSEXN_SYNTAXERR, "missing formal parameter")
+MSG_DEF(JSMSG_PAREN_AFTER_FORMAL, 71, 0, JSEXN_SYNTAXERR, "missing ) after formal parameters")
+MSG_DEF(JSMSG_CURLY_BEFORE_BODY, 72, 0, JSEXN_SYNTAXERR, "missing { before function body")
+MSG_DEF(JSMSG_CURLY_AFTER_BODY, 73, 0, JSEXN_SYNTAXERR, "missing } after function body")
+MSG_DEF(JSMSG_PAREN_BEFORE_COND, 74, 0, JSEXN_SYNTAXERR, "missing ( before condition")
+MSG_DEF(JSMSG_PAREN_AFTER_COND, 75, 0, JSEXN_SYNTAXERR, "missing ) after condition")
+MSG_DEF(JSMSG_DESTRUCT_DUP_ARG, 76, 0, JSEXN_SYNTAXERR, "duplicate argument is mixed with destructuring pattern")
+MSG_DEF(JSMSG_NAME_AFTER_DOT, 77, 0, JSEXN_SYNTAXERR, "missing name after . operator")
+MSG_DEF(JSMSG_BRACKET_IN_INDEX, 78, 0, JSEXN_SYNTAXERR, "missing ] in index expression")
+MSG_DEF(JSMSG_XML_WHOLE_PROGRAM, 79, 0, JSEXN_SYNTAXERR, "XML cannot be the whole program")
+MSG_DEF(JSMSG_PAREN_BEFORE_SWITCH, 80, 0, JSEXN_SYNTAXERR, "missing ( before switch expression")
+MSG_DEF(JSMSG_PAREN_AFTER_SWITCH, 81, 0, JSEXN_SYNTAXERR, "missing ) after switch expression")
+MSG_DEF(JSMSG_CURLY_BEFORE_SWITCH, 82, 0, JSEXN_SYNTAXERR, "missing { before switch body")
+MSG_DEF(JSMSG_COLON_AFTER_CASE, 83, 0, JSEXN_SYNTAXERR, "missing : after case label")
+MSG_DEF(JSMSG_WHILE_AFTER_DO, 84, 0, JSEXN_SYNTAXERR, "missing while after do-loop body")
+MSG_DEF(JSMSG_PAREN_AFTER_FOR, 85, 0, JSEXN_SYNTAXERR, "missing ( after for")
+MSG_DEF(JSMSG_SEMI_AFTER_FOR_INIT, 86, 0, JSEXN_SYNTAXERR, "missing ; after for-loop initializer")
+MSG_DEF(JSMSG_SEMI_AFTER_FOR_COND, 87, 0, JSEXN_SYNTAXERR, "missing ; after for-loop condition")
+MSG_DEF(JSMSG_PAREN_AFTER_FOR_CTRL, 88, 0, JSEXN_SYNTAXERR, "missing ) after for-loop control")
+MSG_DEF(JSMSG_CURLY_BEFORE_TRY, 89, 0, JSEXN_SYNTAXERR, "missing { before try block")
+MSG_DEF(JSMSG_CURLY_AFTER_TRY, 90, 0, JSEXN_SYNTAXERR, "missing } after try block")
+MSG_DEF(JSMSG_PAREN_BEFORE_CATCH, 91, 0, JSEXN_SYNTAXERR, "missing ( before catch")
+MSG_DEF(JSMSG_CATCH_IDENTIFIER, 92, 0, JSEXN_SYNTAXERR, "missing identifier in catch")
+MSG_DEF(JSMSG_PAREN_AFTER_CATCH, 93, 0, JSEXN_SYNTAXERR, "missing ) after catch")
+MSG_DEF(JSMSG_CURLY_BEFORE_CATCH, 94, 0, JSEXN_SYNTAXERR, "missing { before catch block")
+MSG_DEF(JSMSG_CURLY_AFTER_CATCH, 95, 0, JSEXN_SYNTAXERR, "missing } after catch block")
+MSG_DEF(JSMSG_CURLY_BEFORE_FINALLY, 96, 0, JSEXN_SYNTAXERR, "missing { before finally block")
+MSG_DEF(JSMSG_CURLY_AFTER_FINALLY, 97, 0, JSEXN_SYNTAXERR, "missing } after finally block")
+MSG_DEF(JSMSG_CATCH_OR_FINALLY, 98, 0, JSEXN_SYNTAXERR, "missing catch or finally after try")
+MSG_DEF(JSMSG_PAREN_BEFORE_WITH, 99, 0, JSEXN_SYNTAXERR, "missing ( before with-statement object")
+MSG_DEF(JSMSG_PAREN_AFTER_WITH, 100, 0, JSEXN_SYNTAXERR, "missing ) after with-statement object")
+MSG_DEF(JSMSG_CURLY_IN_COMPOUND, 101, 0, JSEXN_SYNTAXERR, "missing } in compound statement")
+MSG_DEF(JSMSG_NO_VARIABLE_NAME, 102, 0, JSEXN_SYNTAXERR, "missing variable name")
+MSG_DEF(JSMSG_COLON_IN_COND, 103, 0, JSEXN_SYNTAXERR, "missing : in conditional expression")
+MSG_DEF(JSMSG_PAREN_AFTER_ARGS, 104, 0, JSEXN_SYNTAXERR, "missing ) after argument list")
+MSG_DEF(JSMSG_BRACKET_AFTER_LIST, 105, 0, JSEXN_SYNTAXERR, "missing ] after element list")
+MSG_DEF(JSMSG_COLON_AFTER_ID, 106, 0, JSEXN_SYNTAXERR, "missing : after property id")
+MSG_DEF(JSMSG_CURLY_AFTER_LIST, 107, 0, JSEXN_SYNTAXERR, "missing } after property list")
+MSG_DEF(JSMSG_PAREN_IN_PAREN, 108, 0, JSEXN_SYNTAXERR, "missing ) in parenthetical")
+MSG_DEF(JSMSG_SEMI_BEFORE_STMNT, 109, 0, JSEXN_SYNTAXERR, "missing ; before statement")
+MSG_DEF(JSMSG_NO_RETURN_VALUE, 110, 1, JSEXN_TYPEERR, "function {0} does not always return a value")
+MSG_DEF(JSMSG_DUPLICATE_FORMAL, 111, 1, JSEXN_SYNTAXERR, "duplicate formal argument {0}")
+MSG_DEF(JSMSG_EQUAL_AS_ASSIGN, 112, 1, JSEXN_SYNTAXERR, "test for equality (==) mistyped as assignment (=)?{0}")
+MSG_DEF(JSMSG_OPTIMIZED_CLOSURE_LEAK, 113, 0, JSEXN_INTERNALERR, "cannot access optimized closure")
+MSG_DEF(JSMSG_TOO_MANY_DEFAULTS, 114, 0, JSEXN_SYNTAXERR, "more than one switch default")
+MSG_DEF(JSMSG_TOO_MANY_CASES, 115, 0, JSEXN_INTERNALERR, "too many switch cases")
+MSG_DEF(JSMSG_BAD_SWITCH, 116, 0, JSEXN_SYNTAXERR, "invalid switch statement")
+MSG_DEF(JSMSG_BAD_FOR_LEFTSIDE, 117, 0, JSEXN_SYNTAXERR, "invalid for/in left-hand side")
+MSG_DEF(JSMSG_CATCH_AFTER_GENERAL, 118, 0, JSEXN_SYNTAXERR, "catch after unconditional catch")
+MSG_DEF(JSMSG_CATCH_WITHOUT_TRY, 119, 0, JSEXN_SYNTAXERR, "catch without try")
+MSG_DEF(JSMSG_FINALLY_WITHOUT_TRY, 120, 0, JSEXN_SYNTAXERR, "finally without try")
+MSG_DEF(JSMSG_LABEL_NOT_FOUND, 121, 0, JSEXN_SYNTAXERR, "label not found")
+MSG_DEF(JSMSG_TOUGH_BREAK, 122, 0, JSEXN_SYNTAXERR, "unlabeled break must be inside loop or switch")
+MSG_DEF(JSMSG_BAD_CONTINUE, 123, 0, JSEXN_SYNTAXERR, "continue must be inside loop")
+MSG_DEF(JSMSG_BAD_RETURN_OR_YIELD, 124, 1, JSEXN_SYNTAXERR, "{0} not in function")
+MSG_DEF(JSMSG_BAD_LABEL, 125, 0, JSEXN_SYNTAXERR, "invalid label")
+MSG_DEF(JSMSG_DUPLICATE_LABEL, 126, 0, JSEXN_SYNTAXERR, "duplicate label")
+MSG_DEF(JSMSG_VAR_HIDES_ARG, 127, 1, JSEXN_TYPEERR, "variable {0} redeclares argument")
+MSG_DEF(JSMSG_BAD_VAR_INIT, 128, 0, JSEXN_SYNTAXERR, "invalid variable initialization")
+MSG_DEF(JSMSG_BAD_LEFTSIDE_OF_ASS, 129, 0, JSEXN_SYNTAXERR, "invalid assignment left-hand side")
+MSG_DEF(JSMSG_BAD_OPERAND, 130, 1, JSEXN_SYNTAXERR, "invalid {0} operand")
+MSG_DEF(JSMSG_BAD_PROP_ID, 131, 0, JSEXN_SYNTAXERR, "invalid property id")
+MSG_DEF(JSMSG_RESERVED_ID, 132, 1, JSEXN_SYNTAXERR, "{0} is a reserved identifier")
+MSG_DEF(JSMSG_SYNTAX_ERROR, 133, 0, JSEXN_SYNTAXERR, "syntax error")
+MSG_DEF(JSMSG_BAD_SHARP_VAR_DEF, 134, 0, JSEXN_SYNTAXERR, "invalid sharp variable definition")
+MSG_DEF(JSMSG_BAD_PROTOTYPE, 135, 1, JSEXN_TYPEERR, "'prototype' property of {0} is not an object")
+MSG_DEF(JSMSG_MISSING_EXPONENT, 136, 0, JSEXN_SYNTAXERR, "missing exponent")
+MSG_DEF(JSMSG_OUT_OF_MEMORY, 137, 0, JSEXN_ERR, "out of memory")
+MSG_DEF(JSMSG_UNTERMINATED_STRING, 138, 0, JSEXN_SYNTAXERR, "unterminated string literal")
+MSG_DEF(JSMSG_TOO_MANY_PARENS, 139, 0, JSEXN_INTERNALERR, "too many parentheses in regular expression")
+MSG_DEF(JSMSG_UNTERMINATED_COMMENT, 140, 0, JSEXN_SYNTAXERR, "unterminated comment")
+MSG_DEF(JSMSG_UNTERMINATED_REGEXP, 141, 0, JSEXN_SYNTAXERR, "unterminated regular expression literal")
+MSG_DEF(JSMSG_BAD_CLONE_FUNOBJ_SCOPE, 142, 0, JSEXN_TYPEERR, "bad cloned function scope chain")
+MSG_DEF(JSMSG_SHARPVAR_TOO_BIG, 143, 0, JSEXN_SYNTAXERR, "overlarge sharp variable number")
+MSG_DEF(JSMSG_ILLEGAL_CHARACTER, 144, 0, JSEXN_SYNTAXERR, "illegal character")
+MSG_DEF(JSMSG_BAD_OCTAL, 145, 1, JSEXN_SYNTAXERR, "{0} is not a legal ECMA-262 octal constant")
+MSG_DEF(JSMSG_BAD_INDIRECT_CALL, 146, 1, JSEXN_EVALERR, "function {0} must be called directly, and not by way of a function of another name")
+MSG_DEF(JSMSG_UNCAUGHT_EXCEPTION, 147, 1, JSEXN_INTERNALERR, "uncaught exception: {0}")
+MSG_DEF(JSMSG_INVALID_BACKREF, 148, 0, JSEXN_SYNTAXERR, "non-octal digit in an escape sequence that doesn't match a back-reference")
+MSG_DEF(JSMSG_BAD_BACKREF, 149, 0, JSEXN_SYNTAXERR, "back-reference exceeds number of capturing parentheses")
+MSG_DEF(JSMSG_PRECISION_RANGE, 150, 1, JSEXN_RANGEERR, "precision {0} out of range")
+MSG_DEF(JSMSG_BAD_GETTER_OR_SETTER, 151, 1, JSEXN_SYNTAXERR, "invalid {0} usage")
+MSG_DEF(JSMSG_BAD_ARRAY_LENGTH, 152, 0, JSEXN_RANGEERR, "invalid array length")
+MSG_DEF(JSMSG_CANT_DESCRIBE_PROPS, 153, 1, JSEXN_TYPEERR, "can't describe non-native properties of class {0}")
+MSG_DEF(JSMSG_BAD_APPLY_ARGS, 154, 1, JSEXN_TYPEERR, "second argument to Function.prototype.{0} must be an array")
+MSG_DEF(JSMSG_REDECLARED_VAR, 155, 2, JSEXN_TYPEERR, "redeclaration of {0} {1}")
+MSG_DEF(JSMSG_UNDECLARED_VAR, 156, 1, JSEXN_REFERENCEERR, "assignment to undeclared variable {0}")
+MSG_DEF(JSMSG_ANON_NO_RETURN_VALUE, 157, 0, JSEXN_TYPEERR, "anonymous function does not always return a value")
+MSG_DEF(JSMSG_DEPRECATED_USAGE, 158, 1, JSEXN_REFERENCEERR, "deprecated {0} usage")
+MSG_DEF(JSMSG_BAD_URI, 159, 0, JSEXN_URIERR, "malformed URI sequence")
+MSG_DEF(JSMSG_GETTER_ONLY, 160, 0, JSEXN_TYPEERR, "setting a property that has only a getter")
+MSG_DEF(JSMSG_IDSTART_AFTER_NUMBER, 161, 0, JSEXN_SYNTAXERR, "identifier starts immediately after numeric literal")
+MSG_DEF(JSMSG_UNDEFINED_PROP, 162, 1, JSEXN_REFERENCEERR, "reference to undefined property {0}")
+MSG_DEF(JSMSG_USELESS_EXPR, 163, 0, JSEXN_TYPEERR, "useless expression")
+MSG_DEF(JSMSG_REDECLARED_PARAM, 164, 1, JSEXN_TYPEERR, "redeclaration of formal parameter {0}")
+MSG_DEF(JSMSG_NEWREGEXP_FLAGGED, 165, 0, JSEXN_TYPEERR, "can't supply flags when constructing one RegExp from another")
+MSG_DEF(JSMSG_RESERVED_SLOT_RANGE, 166, 0, JSEXN_RANGEERR, "reserved slot index out of range")
+MSG_DEF(JSMSG_CANT_DECODE_PRINCIPALS, 167, 0, JSEXN_INTERNALERR, "can't decode JSPrincipals")
+MSG_DEF(JSMSG_CANT_SEAL_OBJECT, 168, 1, JSEXN_ERR, "can't seal {0} objects")
+MSG_DEF(JSMSG_TOO_MANY_CATCH_VARS, 169, 0, JSEXN_SYNTAXERR, "too many catch variables")
+MSG_DEF(JSMSG_BAD_XML_MARKUP, 170, 0, JSEXN_SYNTAXERR, "invalid XML markup")
+MSG_DEF(JSMSG_BAD_XML_CHARACTER, 171, 0, JSEXN_SYNTAXERR, "illegal XML character")
+MSG_DEF(JSMSG_BAD_DEFAULT_XML_NAMESPACE,172,0,JSEXN_SYNTAXERR, "invalid default XML namespace")
+MSG_DEF(JSMSG_BAD_XML_NAME_SYNTAX, 173, 0, JSEXN_SYNTAXERR, "invalid XML name")
+MSG_DEF(JSMSG_BRACKET_AFTER_ATTR_EXPR,174, 0, JSEXN_SYNTAXERR, "missing ] after attribute expression")
+MSG_DEF(JSMSG_NESTING_GENERATOR, 175, 1, JSEXN_TYPEERR, "already executing generator {0}")
+MSG_DEF(JSMSG_CURLY_IN_XML_EXPR, 176, 0, JSEXN_SYNTAXERR, "missing } in XML expression")
+MSG_DEF(JSMSG_BAD_XML_NAMESPACE, 177, 1, JSEXN_TYPEERR, "invalid XML namespace {0}")
+MSG_DEF(JSMSG_BAD_XML_ATTR_NAME, 178, 1, JSEXN_TYPEERR, "invalid XML attribute name {0}")
+MSG_DEF(JSMSG_BAD_XML_NAME, 179, 1, JSEXN_TYPEERR, "invalid XML name {0}")
+MSG_DEF(JSMSG_BAD_XML_CONVERSION, 180, 1, JSEXN_TYPEERR, "can't convert {0} to XML")
+MSG_DEF(JSMSG_BAD_XMLLIST_CONVERSION, 181, 1, JSEXN_TYPEERR, "can't convert {0} to XMLList")
+MSG_DEF(JSMSG_BAD_GENERATOR_SEND, 182, 1, JSEXN_TYPEERR, "attempt to send {0} to newborn generator")
+MSG_DEF(JSMSG_NO_ASSIGN_IN_XML_ATTR, 183, 0, JSEXN_SYNTAXERR, "missing = in XML attribute")
+MSG_DEF(JSMSG_BAD_XML_ATTR_VALUE, 184, 0, JSEXN_SYNTAXERR, "invalid XML attribute value")
+MSG_DEF(JSMSG_XML_TAG_NAME_MISMATCH, 185, 1, JSEXN_SYNTAXERR, "XML tag name mismatch (expected {0})")
+MSG_DEF(JSMSG_BAD_XML_TAG_SYNTAX, 186, 0, JSEXN_SYNTAXERR, "invalid XML tag syntax")
+MSG_DEF(JSMSG_BAD_XML_LIST_SYNTAX, 187, 0, JSEXN_SYNTAXERR, "invalid XML list syntax")
+MSG_DEF(JSMSG_INCOMPATIBLE_METHOD, 188, 3, JSEXN_TYPEERR, "{0} {1} called on incompatible {2}")
+MSG_DEF(JSMSG_CANT_SET_XML_ATTRS, 189, 0, JSEXN_INTERNALERR, "can't set XML property attributes")
+MSG_DEF(JSMSG_END_OF_XML_SOURCE, 190, 0, JSEXN_SYNTAXERR, "unexpected end of XML source")
+MSG_DEF(JSMSG_END_OF_XML_ENTITY, 191, 0, JSEXN_SYNTAXERR, "unexpected end of XML entity")
+MSG_DEF(JSMSG_BAD_XML_QNAME, 192, 0, JSEXN_SYNTAXERR, "invalid XML qualified name")
+MSG_DEF(JSMSG_BAD_FOR_EACH_LOOP, 193, 0, JSEXN_SYNTAXERR, "invalid for each loop")
+MSG_DEF(JSMSG_BAD_XMLLIST_PUT, 194, 1, JSEXN_TYPEERR, "can't set property {0} in XMLList")
+MSG_DEF(JSMSG_UNKNOWN_XML_ENTITY, 195, 1, JSEXN_TYPEERR, "unknown XML entity {0}")
+MSG_DEF(JSMSG_BAD_XML_NCR, 196, 1, JSEXN_TYPEERR, "malformed XML character {0}")
+MSG_DEF(JSMSG_UNDEFINED_XML_NAME, 197, 1, JSEXN_REFERENCEERR, "reference to undefined XML name {0}")
+MSG_DEF(JSMSG_DUPLICATE_XML_ATTR, 198, 1, JSEXN_TYPEERR, "duplicate XML attribute {0}")
+MSG_DEF(JSMSG_TOO_MANY_LOCALS, 199, 0, JSEXN_SYNTAXERR, "too many local variables")
+MSG_DEF(JSMSG_ARRAY_INIT_TOO_BIG, 200, 0, JSEXN_INTERNALERR, "array initialiser too large")
+MSG_DEF(JSMSG_REGEXP_TOO_COMPLEX, 201, 0, JSEXN_INTERNALERR, "regular expression too complex")
+MSG_DEF(JSMSG_BUFFER_TOO_SMALL, 202, 0, JSEXN_INTERNALERR, "buffer too small")
+MSG_DEF(JSMSG_BAD_SURROGATE_CHAR, 203, 1, JSEXN_TYPEERR, "bad surrogate character {0}")
+MSG_DEF(JSMSG_UTF8_CHAR_TOO_LARGE, 204, 1, JSEXN_TYPEERR, "UTF-8 character {0} too large")
+MSG_DEF(JSMSG_MALFORMED_UTF8_CHAR, 205, 1, JSEXN_TYPEERR, "malformed UTF-8 character sequence at offset {0}")
+MSG_DEF(JSMSG_USER_DEFINED_ERROR, 206, 0, JSEXN_ERR, "JS_ReportError was called")
+MSG_DEF(JSMSG_WRONG_CONSTRUCTOR, 207, 1, JSEXN_TYPEERR, "wrong constructor called for {0}")
+MSG_DEF(JSMSG_BAD_GENERATOR_RETURN, 208, 1, JSEXN_TYPEERR, "generator function {0} returns a value")
+MSG_DEF(JSMSG_BAD_ANON_GENERATOR_RETURN, 209, 0, JSEXN_TYPEERR, "anonymous generator function returns a value")
+MSG_DEF(JSMSG_NAME_AFTER_FOR_PAREN, 210, 0, JSEXN_SYNTAXERR, "missing name after for (")
+MSG_DEF(JSMSG_IN_AFTER_FOR_NAME, 211, 0, JSEXN_SYNTAXERR, "missing in after for")
+MSG_DEF(JSMSG_BAD_ITERATOR_RETURN, 212, 1, JSEXN_TYPEERR, "{0}.__iterator__ returned a primitive value")
+MSG_DEF(JSMSG_KEYWORD_NOT_NS, 213, 0, JSEXN_SYNTAXERR, "keyword is used as namespace")
+MSG_DEF(JSMSG_BAD_GENERATOR_YIELD, 214, 1, JSEXN_TYPEERR, "yield from closing generator {0}")
+MSG_DEF(JSMSG_BAD_GENERATOR_SYNTAX, 215, 1, JSEXN_SYNTAXERR, "{0} expression must be parenthesized")
+MSG_DEF(JSMSG_ARRAY_COMP_LEFTSIDE, 216, 0, JSEXN_SYNTAXERR, "invalid array comprehension left-hand side")
+MSG_DEF(JSMSG_NON_XML_FILTER, 217, 1, JSEXN_TYPEERR, "XML filter is applied to non-XML value {0}")
+MSG_DEF(JSMSG_EMPTY_ARRAY_REDUCE, 218, 0, JSEXN_TYPEERR, "reduce of empty array with no initial value")
+MSG_DEF(JSMSG_NON_LIST_XML_METHOD, 219, 2, JSEXN_TYPEERR, "cannot call {0} method on an XML list with {1} elements")
+MSG_DEF(JSMSG_BAD_DELETE_OPERAND, 220, 0, JSEXN_SYNTAXERR, "invalid delete operand")
+MSG_DEF(JSMSG_BAD_INCOP_OPERAND, 221, 0, JSEXN_SYNTAXERR, "invalid increment/decrement operand")
+MSG_DEF(JSMSG_UNEXPECTED_TYPE, 222, 2, JSEXN_TYPEERR, "{0} is {1}")
+MSG_DEF(JSMSG_LET_DECL_NOT_IN_BLOCK, 223, 0, JSEXN_SYNTAXERR, "let declaration not directly within block")
+MSG_DEF(JSMSG_BAD_OBJECT_INIT, 224, 0, JSEXN_SYNTAXERR, "invalid object initializer")
+MSG_DEF(JSMSG_CANT_SET_ARRAY_ATTRS, 225, 0, JSEXN_INTERNALERR, "can't set attributes on indexed array properties")
+MSG_DEF(JSMSG_EVAL_ARITY, 226, 0, JSEXN_TYPEERR, "eval accepts only one parameter")
+MSG_DEF(JSMSG_MISSING_FUN_ARG, 227, 2, JSEXN_TYPEERR, "missing argument {0} when calling function {1}")
+MSG_DEF(JSMSG_JSON_BAD_PARSE, 228, 0, JSEXN_SYNTAXERR, "JSON.parse")
+MSG_DEF(JSMSG_JSON_BAD_STRINGIFY, 229, 0, JSEXN_ERR, "JSON.stringify")
+MSG_DEF(JSMSG_XDR_CLOSURE_WRAPPER, 230, 1, JSEXN_INTERNALERR, "can't XDR closure wrapper for function {0}")
+MSG_DEF(JSMSG_NOT_NONNULL_OBJECT, 231, 0, JSEXN_TYPEERR, "value is not a non-null object")
+MSG_DEF(JSMSG_DEPRECATED_OCTAL, 232, 0, JSEXN_SYNTAXERR, "octal literals and octal escape sequences are deprecated")
+MSG_DEF(JSMSG_STRICT_CODE_WITH, 233, 0, JSEXN_SYNTAXERR, "strict mode code may not contain 'with' statements")
+MSG_DEF(JSMSG_DUPLICATE_PROPERTY, 234, 1, JSEXN_SYNTAXERR, "property name {0} appears more than once in object literal")
+MSG_DEF(JSMSG_DEPRECATED_DELETE_OPERAND, 235, 0, JSEXN_SYNTAXERR, "Applying the 'delete' operator to an unqualified name is deprecated")
+MSG_DEF(JSMSG_DEPRECATED_ASSIGN, 236, 1, JSEXN_SYNTAXERR, "assignment to {0} is deprecated")
+MSG_DEF(JSMSG_BAD_BINDING, 237, 1, JSEXN_SYNTAXERR, "redefining {0} is deprecated")
5,929 src/js/src/jsapi.cpp
5,929 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
2,833 src/js/src/jsapi.h
2,833 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
450 src/js/src/jsarena.cpp
@@ -0,0 +1,450 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * Lifetime-based fast allocation, inspired by much prior art, including
+ * "Fast Allocation and Deallocation of Memory Based on Object Lifetimes"
+ * David R. Hanson, Software -- Practice and Experience, Vol. 20(1).
+ */
+#include <stdlib.h>
+#include <string.h>
+#include "jstypes.h"
+#include "jsstdint.h"
+#include "jsbit.h"
+#include "jsarena.h" /* Added by JSIFY */
+#include "jsutil.h" /* Added by JSIFY */
+
+#ifdef JS_ARENAMETER
+static JSArenaStats *arena_stats_list;
+
+#define COUNT(pool,what) (pool)->stats.what++
+#else
+#define COUNT(pool,what) /* nothing */
+#endif
+
+#define JS_ARENA_DEFAULT_ALIGN sizeof(double)
+
+JS_PUBLIC_API(void)
+JS_InitArenaPool(JSArenaPool *pool, const char *name, size_t size,
+ size_t align, size_t *quotap)
+{
+ if (align == 0)
+ align = JS_ARENA_DEFAULT_ALIGN;
+ pool->mask = JS_BITMASK(JS_CeilingLog2(align));
+ pool->first.next = NULL;
+ pool->first.base = pool->first.avail = pool->first.limit =
+ JS_ARENA_ALIGN(pool, &pool->first + 1);
+ pool->current = &pool->first;
+ pool->arenasize = size;
+ pool->quotap = quotap;
+#ifdef JS_ARENAMETER
+ memset(&pool->stats, 0, sizeof pool->stats);
+ pool->stats.name = strdup(name);
+ pool->stats.next = arena_stats_list;
+ arena_stats_list = &pool->stats;
+#endif
+}
+
+/*
+ * An allocation that consumes more than pool->arenasize also has a header
+ * pointing back to its previous arena's next member. This header is not
+ * included in [a->base, a->limit), so its space can't be wrongly claimed.
+ *
+ * As the header is a pointer, it must be well-aligned. If pool->mask is
+ * greater than or equal to POINTER_MASK, the header just preceding a->base
+ * for an oversized arena a is well-aligned, because a->base is well-aligned.
+ * However, we may need to add more space to pad the JSArena ** back-pointer
+ * so that it lies just behind a->base, because a might not be aligned such
+ * that (jsuword)(a + 1) is on a pointer boundary.
+ *
+ * By how much must we pad? Let M be the alignment modulus for pool and P
+ * the modulus for a pointer. Given M >= P, the base of an oversized arena
+ * that satisfies M is well-aligned for P.
+ *
+ * On the other hand, if M < P, we must include enough space in the header
+ * size to align the back-pointer on a P boundary so that it can be found by
+ * subtracting P from a->base. This means a->base must be on a P boundary,
+ * even though subsequent allocations from a may be aligned on a lesser (M)
+ * boundary. Given powers of two M and P as above, the extra space needed
+ * when M < P is P-M or POINTER_MASK - pool->mask.
+ *
+ * The size of a header including padding is given by the HEADER_SIZE macro,
+ * below, for any pool (for any value of M).
+ *
+ * The mask to align a->base for any pool is (pool->mask | POINTER_MASK), or
+ * HEADER_BASE_MASK(pool).
+ *
+ * PTR_TO_HEADER computes the address of the back-pointer, given an oversized
+ * allocation at p. By definition, p must be a->base for the arena a that
+ * contains p. GET_HEADER and SET_HEADER operate on an oversized arena a, in
+ * the case of SET_HEADER with back-pointer ap.
+ */
+#define POINTER_MASK ((jsuword)(JS_ALIGN_OF_POINTER - 1))
+#define HEADER_SIZE(pool) (sizeof(JSArena **) \
+ + (((pool)->mask < POINTER_MASK) \
+ ? POINTER_MASK - (pool)->mask \
+ : 0))
+#define HEADER_BASE_MASK(pool) ((pool)->mask | POINTER_MASK)
+#define PTR_TO_HEADER(pool,p) (JS_ASSERT(((jsuword)(p) \
+ & HEADER_BASE_MASK(pool)) \
+ == 0), \
+ (JSArena ***)(p) - 1)
+#define GET_HEADER(pool,a) (*PTR_TO_HEADER(pool, (a)->base))
+#define SET_HEADER(pool,a,ap) (*PTR_TO_HEADER(pool, (a)->base) = (ap))
+
+JS_PUBLIC_API(void *)
+JS_ArenaAllocate(JSArenaPool *pool, size_t nb)
+{
+ JSArena **ap, *a, *b;
+ jsuword extra, hdrsz, gross;
+ void *p;
+
+ /*
+ * Search pool from current forward till we find or make enough space.
+ *
+ * NB: subtract nb from a->limit in the loop condition, instead of adding
+ * nb to a->avail, to avoid overflowing a 32-bit address space (possible
+ * when running a 32-bit program on a 64-bit system where the kernel maps
+ * the heap up against the top of the 32-bit address space).
+ *
+ * Thanks to Juergen Kreileder <jk@blackdown.de>, who brought this up in
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=279273.
+ */
+ JS_ASSERT((nb & pool->mask) == 0);
+ for (a = pool->current; nb > a->limit || a->avail > a->limit - nb;
+ pool->current = a) {
+ ap = &a->next;
+ if (!*ap) {
+ /* Not enough space in pool, so we must malloc. */
+ extra = (nb > pool->arenasize) ? HEADER_SIZE(pool) : 0;
+ hdrsz = sizeof *a + extra + pool->mask;
+ gross = hdrsz + JS_MAX(nb, pool->arenasize);
+ if (gross < nb)
+ return NULL;
+ if (pool->quotap) {
+ if (gross > *pool->quotap)
+ return NULL;
+ b = (JSArena *) js_malloc(gross);
+ if (!b)
+ return NULL;
+ *pool->quotap -= gross;
+ } else {
+ b = (JSArena *) js_malloc(gross);
+ if (!b)
+ return NULL;
+ }
+
+ b->next = NULL;
+ b->limit = (jsuword)b + gross;
+ JS_COUNT_ARENA(pool,++);
+ COUNT(pool, nmallocs);
+
+ /* If oversized, store ap in the header, just before a->base. */
+ *ap = a = b;
+ JS_ASSERT(gross <= JS_UPTRDIFF(a->limit, a));
+ if (extra) {
+ a->base = a->avail =
+ ((jsuword)a + hdrsz) & ~HEADER_BASE_MASK(pool);
+ SET_HEADER(pool, a, ap);
+ } else {
+ a->base = a->avail = JS_ARENA_ALIGN(pool, a + 1);
+ }
+ continue;
+ }
+ a = *ap; /* move to next arena */
+ }
+
+ p = (void *)a->avail;
+ a->avail += nb;
+ JS_ASSERT(a->base <= a->avail && a->avail <= a->limit);
+ return p;
+}
+
+JS_PUBLIC_API(void *)
+JS_ArenaRealloc(JSArenaPool *pool, void *p, size_t size, size_t incr)
+{
+ JSArena **ap, *a, *b;
+ jsuword boff, aoff, extra, hdrsz, gross, growth;
+
+ /*
+ * Use the oversized-single-allocation header to avoid searching for ap.
+ * See JS_ArenaAllocate, the SET_HEADER call.
+ */
+ if (size > pool->arenasize) {
+ ap = *PTR_TO_HEADER(pool, p);
+ a = *ap;
+ } else {
+ ap = &pool->first.next;
+ while ((a = *ap) != pool->current)
+ ap = &a->next;
+ }
+
+ JS_ASSERT(a->base == (jsuword)p);
+ boff = JS_UPTRDIFF(a->base, a);
+ aoff = JS_ARENA_ALIGN(pool, size + incr);
+ JS_ASSERT(aoff > pool->arenasize);
+ extra = HEADER_SIZE(pool); /* oversized header holds ap */
+ hdrsz = sizeof *a + extra + pool->mask; /* header and alignment slop */
+ gross = hdrsz + aoff;
+ JS_ASSERT(gross > aoff);
+ if (pool->quotap) {
+ growth = gross - (a->limit - (jsuword) a);
+ if (growth > *pool->quotap)
+ return NULL;
+ a = (JSArena *) js_realloc(a, gross);
+ if (!a)
+ return NULL;
+ *pool->quotap -= growth;
+ } else {
+ a = (JSArena *) js_realloc(a, gross);
+ if (!a)
+ return NULL;
+ }
+#ifdef JS_ARENAMETER
+ pool->stats.nreallocs++;
+#endif
+
+ if (a != *ap) {
+ /* Oops, realloc moved the allocation: update other pointers to a. */
+ if (pool->current == *ap)
+ pool->current = a;
+ b = a->next;
+ if (b && b->avail - b->base > pool->arenasize) {
+ JS_ASSERT(GET_HEADER(pool, b) == &(*ap)->next);
+ SET_HEADER(pool, b, &a->next);
+ }
+
+ /* Now update *ap, the next link of the arena before a. */
+ *ap = a;
+ }
+
+ a->base = ((jsuword)a + hdrsz) & ~HEADER_BASE_MASK(pool);
+ a->limit = (jsuword)a + gross;
+ a->avail = a->base + aoff;
+ JS_ASSERT(a->base <= a->avail && a->avail <= a->limit);
+
+ /* Check whether realloc aligned differently, and copy if necessary. */
+ if (boff != JS_UPTRDIFF(a->base, a))
+ memmove((void *)a->base, (char *)a + boff, size);
+
+ /* Store ap in the oversized-load arena header. */
+ SET_HEADER(pool, a, ap);
+ return (void *)a->base;
+}
+
+JS_PUBLIC_API(void *)
+JS_ArenaGrow(JSArenaPool *pool, void *p, size_t size, size_t incr)
+{
+ void *newp;
+
+ /*
+ * If p points to an oversized allocation, it owns an entire arena, so we
+ * can simply realloc the arena.
+ */
+ if (size > pool->arenasize)
+ return JS_ArenaRealloc(pool, p, size, incr);
+
+ JS_ARENA_ALLOCATE(newp, pool, size + incr);
+ if (newp)
+ memcpy(newp, p, size);
+ return newp;
+}
+
+/*
+ * Free tail arenas linked after head, which may not be the true list head.
+ * Reset pool->current to point to head in case it pointed at a tail arena.
+ */
+static void
+FreeArenaList(JSArenaPool *pool, JSArena *head)
+{
+ JSArena **ap, *a;
+
+ ap = &head->next;
+ a = *ap;
+ if (!a)
+ return;
+
+#ifdef DEBUG
+ do {
+ JS_ASSERT(a->base <= a->avail && a->avail <= a->limit);
+ a->avail = a->base;
+ JS_CLEAR_UNUSED(a);
+ } while ((a = a->next) != NULL);
+ a = *ap;
+#endif
+
+ do {
+ *ap = a->next;
+ if (pool->quotap)
+ *pool->quotap += a->limit - (jsuword) a;
+ JS_CLEAR_ARENA(a);
+ JS_COUNT_ARENA(pool,--);
+ js_free(a);
+ } while ((a = *ap) != NULL);
+
+ pool->current = head;
+}
+
+JS_PUBLIC_API(void)
+JS_ArenaRelease(JSArenaPool *pool, char *mark)
+{
+ JSArena *a;
+
+ for (a = &pool->first; a; a = a->next) {
+ JS_ASSERT(a->base <= a->avail && a->avail <= a->limit);
+
+ if (JS_ARENA_MARK_MATCH(a, mark)) {
+ a->avail = JS_ARENA_ALIGN(pool, mark);
+ JS_ASSERT(a->avail <= a->limit);
+ FreeArenaList(pool, a);
+ return;
+ }
+ }
+}
+
+JS_PUBLIC_API(void)
+JS_FreeArenaPool(JSArenaPool *pool)
+{
+ FreeArenaList(pool, &pool->first);
+ COUNT(pool, ndeallocs);
+}
+
+JS_PUBLIC_API(void)
+JS_FinishArenaPool(JSArenaPool *pool)
+{
+ FreeArenaList(pool, &pool->first);
+#ifdef JS_ARENAMETER
+ {
+ JSArenaStats *stats, **statsp;
+
+ if (pool->stats.name) {
+ js_free(pool->stats.name);
+ pool->stats.name = NULL;
+ }
+ for (statsp = &arena_stats_list; (stats = *statsp) != 0;
+ statsp = &stats->next) {
+ if (stats == &pool->stats) {
+ *statsp = stats->next;
+ return;
+ }
+ }
+ }
+#endif
+}
+
+JS_PUBLIC_API(void)
+JS_ArenaFinish()
+{
+}
+
+JS_PUBLIC_API(void)
+JS_ArenaShutDown(void)
+{
+}
+
+#ifdef JS_ARENAMETER
+JS_PUBLIC_API(void)
+JS_ArenaCountAllocation(JSArenaPool *pool, size_t nb)
+{
+ pool->stats.nallocs++;
+ pool->stats.nbytes += nb;
+ if (nb > pool->stats.maxalloc)
+ pool->stats.maxalloc = nb;
+ pool->stats.variance += nb * nb;
+}
+
+JS_PUBLIC_API(void)
+JS_ArenaCountInplaceGrowth(JSArenaPool *pool, size_t size, size_t incr)
+{
+ pool->stats.ninplace++;
+}
+
+JS_PUBLIC_API(void)
+JS_ArenaCountGrowth(JSArenaPool *pool, size_t size, size_t incr)
+{
+ pool->stats.ngrows++;
+ pool->stats.nbytes += incr;
+ pool->stats.variance -= size * size;
+ size += incr;
+ if (size > pool->stats.maxalloc)
+ pool->stats.maxalloc = size;
+ pool->stats.variance += size * size;
+}
+
+JS_PUBLIC_API(void)
+JS_ArenaCountRelease(JSArenaPool *pool, char *mark)
+{
+ pool->stats.nreleases++;
+}
+
+JS_PUBLIC_API(void)
+JS_ArenaCountRetract(JSArenaPool *pool, char *mark)
+{
+ pool->stats.nfastrels++;
+}
+
+#include <stdio.h>
+
+JS_PUBLIC_API(void)
+JS_DumpArenaStats(FILE *fp)
+{
+ JSArenaStats *stats;
+ double mean, sigma;
+
+ for (stats = arena_stats_list; stats; stats = stats->next) {
+ mean = JS_MeanAndStdDev(stats->nallocs, stats->nbytes, stats->variance,
+ &sigma);
+
+ fprintf(fp, "\n%s allocation statistics:\n", stats->name);
+ fprintf(fp, " number of arenas: %u\n", stats->narenas);
+ fprintf(fp, " number of allocations: %u\n", stats->nallocs);
+ fprintf(fp, " number of malloc calls: %u\n", stats->nmallocs);
+ fprintf(fp, " number of deallocations: %u\n", stats->ndeallocs);
+ fprintf(fp, " number of allocation growths: %u\n", stats->ngrows);
+ fprintf(fp, " number of in-place growths: %u\n", stats->ninplace);
+ fprintf(fp, " number of realloc'ing growths: %u\n", stats->nreallocs);
+ fprintf(fp, "number of released allocations: %u\n", stats->nreleases);
+ fprintf(fp, " number of fast releases: %u\n", stats->nfastrels);
+ fprintf(fp, " total bytes allocated: %u\n", stats->nbytes);
+ fprintf(fp, " mean allocation size: %g\n", mean);
+ fprintf(fp, " standard deviation: %g\n", sigma);
+ fprintf(fp, " maximum allocation size: %u\n", stats->maxalloc);
+ }
+}
+#endif /* JS_ARENAMETER */
289 src/js/src/jsarena.h
@@ -0,0 +1,289 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef jsarena_h___
+#define jsarena_h___
+/*
+ * Lifetime-based fast allocation, inspired by much prior art, including
+ * "Fast Allocation and Deallocation of Memory Based on Object Lifetimes"
+ * David R. Hanson, Software -- Practice and Experience, Vol. 20(1).
+ *
+ * Also supports LIFO allocation (JS_ARENA_MARK/JS_ARENA_RELEASE).
+ */
+#include <stdlib.h>
+#include "jstypes.h"
+#include "jscompat.h"
+
+JS_BEGIN_EXTERN_C
+
+typedef struct JSArena JSArena;
+typedef struct JSArenaPool JSArenaPool;
+
+struct JSArena {
+ JSArena *next; /* next arena for this lifetime */
+ jsuword base; /* aligned base address, follows this header */
+ jsuword limit; /* one beyond last byte in arena */
+ jsuword avail; /* points to next available byte */
+};
+
+#ifdef JS_ARENAMETER
+typedef struct JSArenaStats JSArenaStats;
+
+struct JSArenaStats {
+ JSArenaStats *next; /* next in arenaStats list */
+ char *name; /* name for debugging */
+ uint32 narenas; /* number of arenas in pool */
+ uint32 nallocs; /* number of JS_ARENA_ALLOCATE() calls */
+ uint32 nmallocs; /* number of malloc() calls */
+ uint32 ndeallocs; /* number of lifetime deallocations */
+ uint32 ngrows; /* number of JS_ARENA_GROW() calls */
+ uint32 ninplace; /* number of in-place growths */
+ uint32 nreallocs; /* number of arena grow extending reallocs */
+ uint32 nreleases; /* number of JS_ARENA_RELEASE() calls */
+ uint32 nfastrels; /* number of "fast path" releases */
+ size_t nbytes; /* total bytes allocated */
+ size_t maxalloc; /* maximum allocation size in bytes */
+ double variance; /* size variance accumulator */
+};
+#endif
+
+struct JSArenaPool {
+ JSArena first; /* first arena in pool list */
+ JSArena *current; /* arena from which to allocate space */
+ size_t arenasize; /* net exact size of a new arena */
+ jsuword mask; /* alignment mask (power-of-2 - 1) */
+ size_t *quotap; /* pointer to the quota on pool allocation
+ size or null if pool is unlimited */
+#ifdef JS_ARENAMETER
+ JSArenaStats stats;
+#endif
+};
+
+#define JS_ARENA_ALIGN(pool, n) (((jsuword)(n) + (pool)->mask) & ~(pool)->mask)
+
+#define JS_ARENA_ALLOCATE(p, pool, nb) \
+ JS_ARENA_ALLOCATE_CAST(p, void *, pool, nb)
+
+#define JS_ARENA_ALLOCATE_TYPE(p, type, pool) \
+ JS_ARENA_ALLOCATE_COMMON(p, type *, pool, sizeof(type), 0)
+
+#define JS_ARENA_ALLOCATE_CAST(p, type, pool, nb) \
+ JS_ARENA_ALLOCATE_COMMON(p, type, pool, nb, _nb > _a->limit)
+
+/*
+ * NB: In JS_ARENA_ALLOCATE_CAST and JS_ARENA_GROW_CAST, always subtract _nb
+ * from a->limit rather than adding _nb to _p, to avoid overflowing a 32-bit
+ * address space (possible when running a 32-bit program on a 64-bit system
+ * where the kernel maps the heap up against the top of the 32-bit address
+ * space).
+ *
+ * Thanks to Juergen Kreileder <jk@blackdown.de>, who brought this up in
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=279273.
+ */
+#define JS_ARENA_ALLOCATE_COMMON(p, type, pool, nb, guard) \
+ JS_BEGIN_MACRO \
+ JSArena *_a = (pool)->current; \
+ size_t _nb = JS_ARENA_ALIGN(pool, nb); \
+ jsuword _p = _a->avail; \
+ if ((guard) || _p > _a->limit - _nb) \
+ _p = (jsuword)JS_ArenaAllocate(pool, _nb); \
+ else \
+ _a->avail = _p + _nb; \
+ p = (type) _p; \
+ JS_ArenaCountAllocation(pool, nb); \
+ JS_END_MACRO
+
+#define JS_ARENA_GROW(p, pool, size, incr) \
+ JS_ARENA_GROW_CAST(p, void *, pool, size, incr)
+
+#define JS_ARENA_GROW_CAST(p, type, pool, size, incr) \
+ JS_BEGIN_MACRO \
+ JSArena *_a = (pool)->current; \
+ if (_a->avail == (jsuword)(p) + JS_ARENA_ALIGN(pool, size)) { \
+ size_t _nb = (size) + (incr); \
+ _nb = JS_ARENA_ALIGN(pool, _nb); \
+ if (_a->limit >= _nb && (jsuword)(p) <= _a->limit - _nb) { \
+ _a->avail = (jsuword)(p) + _nb; \
+ JS_ArenaCountInplaceGrowth(pool, size, incr); \
+ } else if ((jsuword)(p) == _a->base) { \
+ p = (type) JS_ArenaRealloc(pool, p, size, incr); \
+ } else { \
+ p = (type) JS_ArenaGrow(pool, p, size, incr); \
+ } \
+ } else { \
+ p = (type) JS_ArenaGrow(pool, p, size, incr); \
+ } \
+ JS_ArenaCountGrowth(pool, size, incr); \
+ JS_END_MACRO
+
+#define JS_ARENA_MARK(pool) ((void *) (pool)->current->avail)
+#define JS_UPTRDIFF(p,q) ((jsuword)(p) - (jsuword)(q))
+
+/*
+ * Check if the mark is inside arena's allocated area.
+ */
+#define JS_ARENA_MARK_MATCH(a, mark) \
+ (JS_UPTRDIFF(mark, (a)->base) <= JS_UPTRDIFF((a)->avail, (a)->base))
+
+#ifdef DEBUG
+#define JS_FREE_PATTERN 0xDA
+#define JS_CLEAR_UNUSED(a) (JS_ASSERT((a)->avail <= (a)->limit), \
+ memset((void*)(a)->avail, JS_FREE_PATTERN, \
+ (a)->limit - (a)->avail))
+#define JS_CLEAR_ARENA(a) memset((void*)(a), JS_FREE_PATTERN, \
+ (a)->limit - (jsuword)(a))
+#else
+#define JS_CLEAR_UNUSED(a) /* nothing */
+#define JS_CLEAR_ARENA(a) /* nothing */
+#endif
+
+#define JS_ARENA_RELEASE(pool, mark) \
+ JS_BEGIN_MACRO \
+ char *_m = (char *)(mark); \
+ JSArena *_a = (pool)->current; \
+ if (_a != &(pool)->first && JS_ARENA_MARK_MATCH(_a, _m)) { \
+ _a->avail = (jsuword)JS_ARENA_ALIGN(pool, _m); \
+ JS_ASSERT(_a->avail <= _a->limit); \
+ JS_CLEAR_UNUSED(_a); \
+ JS_ArenaCountRetract(pool, _m); \
+ } else { \
+ JS_ArenaRelease(pool, _m); \
+ } \
+ JS_ArenaCountRelease(pool, _m); \
+ JS_END_MACRO
+
+#ifdef JS_ARENAMETER
+#define JS_COUNT_ARENA(pool,op) ((pool)->stats.narenas op)
+#else
+#define JS_COUNT_ARENA(pool,op)
+#endif
+
+#define JS_ARENA_DESTROY(pool, a, pnext) \
+ JS_BEGIN_MACRO \
+ JS_COUNT_ARENA(pool,--); \
+ if ((pool)->current == (a)) (pool)->current = &(pool)->first; \
+ *(pnext) = (a)->next; \
+ JS_CLEAR_ARENA(a); \
+ free(a); \
+ (a) = NULL; \
+ JS_END_MACRO
+
+/*
+ * Initialize an arena pool with a minimum size per arena of size bytes.
+ */
+extern JS_PUBLIC_API(void)
+JS_InitArenaPool(JSArenaPool *pool, const char *name, size_t size,
+ size_t align, size_t *quotap);
+
+/*
+ * Free the arenas in pool. The user may continue to allocate from pool
+ * after calling this function. There is no need to call JS_InitArenaPool()
+ * again unless JS_FinishArenaPool(pool) has been called.
+ */
+extern JS_PUBLIC_API(void)
+JS_FreeArenaPool(JSArenaPool *pool);
+
+/*
+ * Free the arenas in pool and finish using it altogether.
+ */
+extern JS_PUBLIC_API(void)
+JS_FinishArenaPool(JSArenaPool *pool);
+
+/*
+ * Deprecated do-nothing function.
+ */
+extern JS_PUBLIC_API(void)
+JS_ArenaFinish(void);
+
+/*
+ * Deprecated do-nothing function.
+ */
+extern JS_PUBLIC_API(void)
+JS_ArenaShutDown(void);
+
+/*
+ * Friend functions used by the JS_ARENA_*() macros.
+ */
+extern JS_PUBLIC_API(void *)
+JS_ArenaAllocate(JSArenaPool *pool, size_t nb);
+
+extern JS_PUBLIC_API(void *)
+JS_ArenaRealloc(JSArenaPool *pool, void *p, size_t size, size_t incr);
+
+extern JS_PUBLIC_API(void *)
+JS_ArenaGrow(JSArenaPool *pool, void *p, size_t size, size_t incr);
+
+extern JS_PUBLIC_API(void)
+JS_ArenaRelease(JSArenaPool *pool, char *mark);
+
+#ifdef JS_ARENAMETER
+
+#include <stdio.h>
+
+extern JS_PUBLIC_API(void)
+JS_ArenaCountAllocation(JSArenaPool *pool, size_t nb);
+
+extern JS_PUBLIC_API(void)
+JS_ArenaCountInplaceGrowth(JSArenaPool *pool, size_t size, size_t incr);
+
+extern JS_PUBLIC_API(void)
+JS_ArenaCountGrowth(JSArenaPool *pool, size_t size, size_t incr);
+
+extern JS_PUBLIC_API(void)
+JS_ArenaCountRelease(JSArenaPool *pool, char *mark);
+
+extern JS_PUBLIC_API(void)
+JS_ArenaCountRetract(JSArenaPool *pool, char *mark);
+
+extern JS_PUBLIC_API(void)
+JS_DumpArenaStats(FILE *fp);
+
+#else /* !JS_ARENAMETER */
+
+#define JS_ArenaCountAllocation(ap, nb) /* nothing */
+#define JS_ArenaCountInplaceGrowth(ap, size, incr) /* nothing */
+#define JS_ArenaCountGrowth(ap, size, incr) /* nothing */
+#define JS_ArenaCountRelease(ap, mark) /* nothing */
+#define JS_ArenaCountRetract(ap, mark) /* nothing */
+
+#endif /* !JS_ARENAMETER */
+
+JS_END_EXTERN_C
+
+#endif /* jsarena_h___ */
3,627 src/js/src/jsarray.cpp
3,627 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
234 src/js/src/jsarray.h
@@ -0,0 +1,234 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef jsarray_h___
+#define jsarray_h___
+/*
+ * JS Array interface.
+ */
+#include "jsprvtd.h"
+#include "jspubtd.h"
+#include "jsobj.h"
+
+JS_BEGIN_EXTERN_C
+
+#define ARRAY_CAPACITY_MIN 7
+
+extern JSBool
+js_IdIsIndex(jsval id, jsuint *indexp);
+
+extern JSClass js_ArrayClass, js_SlowArrayClass;
+
+static JS_INLINE JSBool
+js_IsDenseArray(JSObject *obj)
+{
+ return STOBJ_GET_CLASS(obj) == &js_ArrayClass;
+}
+
+#define OBJ_IS_DENSE_ARRAY(cx, obj) js_IsDenseArray(obj)
+
+#define OBJ_IS_ARRAY(cx,obj) (OBJ_IS_DENSE_ARRAY(cx, obj) || \
+ OBJ_GET_CLASS(cx, obj) == &js_SlowArrayClass)
+
+/*
+ * Dense arrays are not native (OBJ_IS_NATIVE(cx, aobj) for a dense array aobj
+ * results in false, meaning aobj->map does not point to a JSScope).
+ *
+ * But Array methods are called via aobj.sort(), e.g., and the interpreter and
+ * the trace recorder must consult the property cache in order to perform well.
+ * The cache works only for native objects.
+ *
+ * Therefore the interpreter (js_Interpret in JSOP_GETPROP and JSOP_CALLPROP)
+ * and js_GetPropertyHelper use this inline function to skip up one link in the
+ * prototype chain when obj is a dense array, in order to find a native object
+ * (to wit, Array.prototype) in which to probe for cached methods.
+ *
+ * Note that setting aobj.__proto__ for a dense array aobj turns aobj into a
+ * slow array, avoiding the neede to skip.
+ *
+ * Callers of js_GetProtoIfDenseArray must take care to use the original object
+ * (obj) for the |this| value of a getter, setter, or method call (bug 476447).
+ */
+static JS_INLINE JSObject *
+js_GetProtoIfDenseArray(JSContext *cx, JSObject *obj)
+{
+ return OBJ_IS_DENSE_ARRAY(cx, obj) ? OBJ_GET_PROTO(cx, obj) : obj;
+}
+
+extern JSObject *
+js_InitArrayClass(JSContext *cx, JSObject *obj);
+
+extern bool
+js_InitContextBusyArrayTable(JSContext *cx);
+
+/*
+ * Creates a new array with the given length and proto (NB: NULL is not
+ * translated to Array.prototype), with len slots preallocated.
+ */
+extern JSObject * JS_FASTCALL
+js_NewArrayWithSlots(JSContext* cx, JSObject* proto, uint32 len);
+
+extern JSObject *
+js_NewArrayObject(JSContext *cx, jsuint length, jsval *vector,
+ JSBool holey = JS_FALSE);
+
+/* Create an array object that starts out already made slow/sparse. */
+extern JSObject *
+js_NewSlowArrayObject(JSContext *cx);
+
+extern JSBool
+js_MakeArraySlow(JSContext *cx, JSObject *obj);
+
+#define JSSLOT_ARRAY_LENGTH JSSLOT_PRIVATE
+#define JSSLOT_ARRAY_COUNT (JSSLOT_ARRAY_LENGTH + 1)
+#define JSSLOT_ARRAY_UNUSED (JSSLOT_ARRAY_COUNT + 1)
+
+static JS_INLINE uint32
+js_DenseArrayCapacity(JSObject *obj)
+{
+ JS_ASSERT(js_IsDenseArray(obj));
+ return obj->dslots ? (uint32) obj->dslots[-1] : 0;
+}
+
+static JS_INLINE void
+js_SetDenseArrayCapacity(JSObject *obj, uint32 capacity)
+{
+ JS_ASSERT(js_IsDenseArray(obj));
+ JS_ASSERT(obj->dslots);
+ obj->dslots[-1] = (jsval) capacity;
+}
+
+extern JSBool
+js_GetLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp);
+
+extern JSBool
+js_SetLengthProperty(JSContext *cx, JSObject *obj, jsdouble length);
+
+extern JSBool
+js_HasLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp);
+
+extern JSBool JS_FASTCALL
+js_IndexToId(JSContext *cx, jsuint index, jsid *idp);
+
+/*
+ * Test whether an object is "array-like". Currently this means whether obj
+ * is an Array or an arguments object. We would like an API, and probably a
+ * way in the language, to bless other objects as array-like: having indexed
+ * properties, and a 'length' property of uint32 value equal to one more than
+ * the greatest index.
+ */
+extern JSBool
+js_IsArrayLike(JSContext *cx, JSObject *obj, JSBool *answerp, jsuint *lengthp);
+
+/*
+ * JS-specific merge sort function.
+ */
+typedef JSBool (*JSComparator)(void *arg, const void *a, const void *b,
+ int *result);
+/*
+ * NB: vec is the array to be sorted, tmp is temporary space at least as big
+ * as vec. Both should be GC-rooted if appropriate.
+ *
+ * The sorted result is in vec. vec may be in an inconsistent state if the
+ * comparator function cmp returns an error inside a comparison, so remember
+ * to check the return value of this function.
+ */
+extern JSBool
+js_MergeSort(void *vec, size_t nel, size_t elsize, JSComparator cmp,
+ void *arg, void *tmp);
+
+#ifdef DEBUG_ARRAYS
+extern JSBool
+js_ArrayInfo(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
+#endif
+
+extern JSBool JS_FASTCALL
+js_ArrayCompPush(JSContext *cx, JSObject *obj, jsval v);
+
+/*
+ * Fast dense-array-to-buffer conversion for use by canvas.
+ *
+ * If the array is a dense array, fill [offset..offset+count] values into
+ * destination, assuming that types are consistent. Return JS_TRUE if
+ * successful, otherwise JS_FALSE -- note that the destination buffer may be
+ * modified even if JS_FALSE is returned (e.g. due to finding an inappropriate
+ * type later on in the array). If JS_FALSE is returned, no error conditions
+ * or exceptions are set on the context.
+ *
+ * This method succeeds if each element of the array is an integer or a double.
+ * Values outside the 0-255 range are clamped to that range. Double values are
+ * converted to integers in this range by clamping and then rounding to
+ * nearest, ties to even.
+ */
+
+JS_FRIEND_API(JSBool)
+js_CoerceArrayToCanvasImageData(JSObject *obj, jsuint offset, jsuint count,
+ JSUint8 *dest);
+
+JSBool
+js_PrototypeHasIndexedProperties(JSContext *cx, JSObject *obj);
+
+/*
+ * Utility to access the value from the id returned by array_lookupProperty.
+ */
+JSBool
+js_GetDenseArrayElementValue(JSContext *cx, JSObject *obj, JSProperty *prop,
+ jsval *vp);
+
+/* Array constructor native. Exposed only so the JIT can know its address. */
+JSBool
+js_Array(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval);
+
+/*
+ * Friend api function that allows direct creation of an array object with a
+ * given capacity. Non-null return value means allocation of the internal
+ * buffer for a capacity of at least |capacity| succeeded. A pointer to the
+ * first element of this internal buffer is returned in the |vector| out
+ * parameter. The caller promises to fill in the first |capacity| values
+ * starting from that pointer immediately after this function returns and
+ * without triggering GC (so this method is allowed to leave those
+ * uninitialized) and to set them to non-JSVAL_HOLE values, so that the
+ * resulting array has length and count both equal to |capacity|.
+ */
+JS_FRIEND_API(JSObject *)
+js_NewArrayObjectWithCapacity(JSContext *cx, jsuint capacity, jsval **vector);
+
+JS_END_EXTERN_C
+
+#endif /* jsarray_h___ */
1,269 src/js/src/jsatom.cpp
<
@@ -0,0 +1,1269 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * JS atom table.
+ */
+#include <stdlib.h>
+#include <string.h>
+#include "jstypes.h"
+#include "jsstdint.h"
+#include "jsutil.h" /* Added by JSIFY */
+#include "jshash.h" /* Added by JSIFY */
+#include "jsprf.h"
+#include "jsapi.h"
+#include "jsatom.h"
+#include "jsbit.h"
+#include "jscntxt.h"
+#include "jsgc.h"
+#include "jslock.h"
+#include "jsnum.h"
+#include "jsparse.h"
+#include "jsscan.h"
+#include "jsstr.h"
+#include "jsversion.h"
+#include "jsstrinlines.h"
+
+/*
+ * ATOM_HASH assumes that JSHashNumber is 32-bit even on 64-bit systems.
+ */
+JS_STATIC_ASSERT(sizeof(JSHashNumber) == 4);
+JS_STATIC_ASSERT(sizeof(JSAtom *) == JS_BYTES_PER_WORD);
+
+/*
+ * Start and limit offsets for atom pointers in JSAtomState must be aligned
+ * on the word boundary.
+ */
+JS_STATIC_ASSERT(ATOM_OFFSET_START % sizeof(JSAtom *) == 0);
+JS_STATIC_ASSERT(ATOM_OFFSET_LIMIT % sizeof(JSAtom *) == 0);
+
+/*
+ * JS_BOOLEAN_STR and JS_TYPE_STR assume that boolean names starts from the
+ * index 1 and type name starts from the index 1+2 atoms in JSAtomState.
+ */
+JS_STATIC_ASSERT(1 * sizeof(JSAtom *) ==
+ offsetof(JSAtomState, booleanAtoms) - ATOM_OFFSET_START);
+JS_STATIC_ASSERT((1 + 2) * sizeof(JSAtom *) ==
+ offsetof(JSAtomState, typeAtoms) - ATOM_OFFSET_START);
+
+const char *
+js_AtomToPrintableString(JSContext *cx, JSAtom *atom)
+{
+ return js_ValueToPrintableString(cx, ATOM_KEY(atom));
+}
+
+#define JS_PROTO(name,code,init) const char js_##name##_str[] = #name;
+#include "jsproto.tbl"
+#undef JS_PROTO
+
+/*
+ * String constants for common atoms defined in JSAtomState starting from
+ * JSAtomState.emptyAtom until JSAtomState.lazy.
+ *
+ * The elements of the array after the first empty string define strings
+ * corresponding to the two boolean literals, false and true, followed by the
+ * JSType enumerators from jspubtd.h starting with "undefined" for JSTYPE_VOID
+ * (which is special-value 2) and continuing as initialized below. The static
+ * asserts check these relations.
+ */
+JS_STATIC_ASSERT(JSTYPE_LIMIT == 8);
+JS_STATIC_ASSERT(JSTYPE_VOID == 0);
+
+const char *const js_common_atom_names[] = {
+ "", /* emptyAtom */
+ js_false_str, /* booleanAtoms[0] */
+ js_true_str, /* booleanAtoms[1] */
+ js_undefined_str, /* typeAtoms[JSTYPE_VOID] */
+ js_object_str, /* typeAtoms[JSTYPE_OBJECT] */
+ js_function_str, /* typeAtoms[JSTYPE_FUNCTION] */
+ "string", /* typeAtoms[JSTYPE_STRING] */
+ "number", /* typeAtoms[JSTYPE_NUMBER] */
+ "boolean", /* typeAtoms[JSTYPE_BOOLEAN] */
+ js_null_str, /* typeAtoms[JSTYPE_NULL] */
+ "xml", /* typeAtoms[JSTYPE_XML] */
+ js_null_str, /* nullAtom */
+
+#define JS_PROTO(name,code,init) js_##name##_str,
+#include "jsproto.tbl"
+#undef JS_PROTO
+
+ js_anonymous_str, /* anonymousAtom */
+ js_apply_str, /* applyAtom */
+ js_arguments_str, /* argumentsAtom */
+ js_arity_str, /* arityAtom */
+ js_call_str, /* callAtom */
+ js_callee_str, /* calleeAtom */
+ js_caller_str, /* callerAtom */
+ js_class_prototype_str, /* classPrototypeAtom */
+ js_constructor_str, /* constructorAtom */
+ js_count_str, /* countAtom */
+ js_each_str, /* eachAtom */
+ js_eval_str, /* evalAtom */
+ js_fileName_str, /* fileNameAtom */
+ js_get_str, /* getAtom */
+ js_getter_str, /* getterAtom */
+ js_index_str, /* indexAtom */
+ js_input_str, /* inputAtom */
+ js_iterator_str, /* iteratorAtom */
+ js_length_str, /* lengthAtom */
+ js_lineNumber_str, /* lineNumberAtom */
+ js_message_str, /* messageAtom */
+ js_name_str, /* nameAtom */
+ js_next_str, /* nextAtom */
+ js_noSuchMethod_str, /* noSuchMethodAtom */
+ js_parent_str, /* parentAtom */
+ js_proto_str, /* protoAtom */
+ js_set_str, /* setAtom */
+ js_setter_str, /* setterAtom */
+ js_stack_str, /* stackAtom */
+ js_toLocaleString_str, /* toLocaleStringAtom */
+ js_toSource_str, /* toSourceAtom */
+ js_toString_str, /* toStringAtom */
+ js_valueOf_str, /* valueOfAtom */
+ js_toJSON_str, /* toJSONAtom */
+ "(void 0)", /* void0Atom */
+ js_enumerable_str, /* enumerableAtom */
+ js_configurable_str, /* configurableAtom */
+ js_writable_str, /* writableAtom */
+ js_value_str, /* valueAtom */
+ "use strict", /* useStrictAtom */
+
+#if JS_HAS_XML_SUPPORT
+ js_etago_str, /* etagoAtom */
+ js_namespace_str, /* namespaceAtom */
+ js_ptagc_str, /* ptagcAtom */
+ js_qualifier_str, /* qualifierAtom */
+ js_space_str, /* spaceAtom */
+ js_stago_str, /* stagoAtom */
+ js_star_str, /* starAtom */
+ js_starQualifier_str, /* starQualifierAtom */
+ js_tagc_str, /* tagcAtom */
+ js_xml_str, /* xmlAtom */
+#endif
+
+#ifdef NARCISSUS
+ js___call___str, /* __call__Atom */
+ js___construct___str, /* __construct__Atom */
+ js___hasInstance___str, /* __hasInstance__Atom */
+ js_ExecutionContext_str, /* ExecutionContextAtom */
+ js_current_str, /* currentAtom */
+#endif
+};
+
+JS_STATIC_ASSERT(JS_ARRAY_LENGTH(js_common_atom_names) * sizeof(JSAtom *) ==
+ LAZY_ATOM_OFFSET_START - ATOM_OFFSET_START);
+
+/*
+ * Interpreter macros called by the trace recorder assume common atom indexes
+ * fit in one byte of immediate operand.
+ */
+JS_STATIC_ASSERT(JS_ARRAY_LENGTH(js_common_atom_names) < 256);
+
+const size_t js_common_atom_count = JS_ARRAY_LENGTH(js_common_atom_names);
+
+const char js_anonymous_str[] = "anonymous";
+const char js_apply_str[] = "apply";
+const char js_arguments_str[] = "arguments";
+const char js_arity_str[] = "arity";
+const char js_call_str[] = "call";
+const char js_callee_str[] = "callee";
+const char js_caller_str[] = "caller";
+const char js_class_prototype_str[] = "prototype";
+const char js_constructor_str[] = "constructor";
+const char js_count_str[] = "__count__";
+const char js_each_str[] = "each";
+const char js_eval_str[] = "eval";
+const char js_fileName_str[] = "fileName";
+const char js_get_str[] = "get";
+const char js_getter_str[] = "getter";
+const char js_index_str[] = "index";
+const char js_input_str[] = "input";
+const char js_iterator_str[] = "__iterator__";
+const char js_length_str[] = "length";
+const char js_lineNumber_str[] = "lineNumber";
+const char js_message_str[] = "message";
+const char js_name_str[] = "name";
+const char js_next_str[] = "next";
+const char js_noSuchMethod_str[] = "__noSuchMethod__";
+const char js_object_str[] = "object";
+const char js_parent_str[] = "__parent__";
+const char js_proto_str[] = "__proto__";
+const char js_setter_str[] = "setter";
+const char js_set_str[] = "set";
+const char js_stack_str[] = "stack";
+const char js_toSource_str[] = "toSource";
+const char js_toString_str[] = "toString";
+const char js_toLocaleString_str[] = "toLocaleString";
+const char js_undefined_str[] = "undefined";
+const char js_valueOf_str[] = "valueOf";
+const char js_toJSON_str[] = "toJSON";
+const char js_enumerable_str[] = "enumerable";
+const char js_configurable_str[] = "configurable";
+const char js_writable_str[] = "writable";
+const char js_value_str[] = "value";
+
+#if JS_HAS_XML_SUPPORT
+const char js_etago_str[] = "</";
+const char js_namespace_str[] = "namespace";
+const char js_ptagc_str[] = "/>";
+const char js_qualifier_str[] = "::";
+const char js_space_str[] = " ";
+const char js_stago_str[] = "<";
+const char js_star_str[] = "*";
+const char js_starQualifier_str[] = "*::";
+const char js_tagc_str[] = ">";
+const char js_xml_str[] = "xml";
+#endif
+
+#if JS_HAS_GENERATORS
+const char js_close_str[] = "close";
+const char js_send_str[] = "send";
+#endif
+
+#ifdef NARCISSUS
+const char js___call___str[] = "__call__";
+const char js___construct___str[] = "__construct__";
+const char js___hasInstance___str[] = "__hasInstance__";
+const char js_ExecutionContext_str[] = "ExecutionContext";
+const char js_current_str[] = "current";
+#endif
+
+/*
+ * JSAtomState.doubleAtoms and JSAtomState.stringAtoms hashtable entry. To
+ * support pinned and interned string atoms, we use the lowest bits of the
+ * keyAndFlags field to store ATOM_PINNED and ATOM_INTERNED flags.
+ */
+typedef struct JSAtomHashEntry {
+ JSDHashEntryHdr hdr;
+ jsuword keyAndFlags;
+} JSAtomHashEntry;
+
+#define ATOM_ENTRY_FLAG_MASK (ATOM_PINNED | ATOM_INTERNED)
+
+JS_STATIC_ASSERT(ATOM_ENTRY_FLAG_MASK < JSVAL_ALIGN);
+
+/*
+ * Helper macros to access and modify JSAtomHashEntry.
+ */
+#define TO_ATOM_ENTRY(hdr) ((JSAtomHashEntry *) hdr)
+#define ATOM_ENTRY_KEY(entry) \
+ ((void *)((entry)->keyAndFlags & ~ATOM_ENTRY_FLAG_MASK))
+#define ATOM_ENTRY_FLAGS(entry) \
+ ((uintN)((entry)->keyAndFlags & ATOM_ENTRY_FLAG_MASK))
+#define INIT_ATOM_ENTRY(entry, key) \
+ ((void)((entry)->keyAndFlags = (jsuword)(key)))
+#define ADD_ATOM_ENTRY_FLAGS(entry, flags) \
+ ((void)((entry)->keyAndFlags |= (jsuword)(flags)))
+#define CLEAR_ATOM_ENTRY_FLAGS(entry, flags) \
+ ((void)((entry)->keyAndFlags &= ~(jsuword)(flags)))
+
+static JSDHashNumber
+HashDouble(JSDHashTable *table, const void *key);
+
+static JSBool
+MatchDouble(JSDHashTable *table, const JSDHashEntryHdr *hdr, const void *key);
+
+static JSDHashNumber
+HashString(JSDHashTable *table, const void *key);
+
+static JSBool
+MatchString(JSDHashTable *table, const JSDHashEntryHdr *hdr, const void *key);
+
+static const JSDHashTableOps DoubleHashOps = {
+ JS_DHashAllocTable,
+ JS_DHashFreeTable,
+ HashDouble,
+ MatchDouble,
+ JS_DHashMoveEntryStub,
+ JS_DHashClearEntryStub,
+ JS_DHashFinalizeStub,
+ NULL
+};
+
+static const JSDHashTableOps StringHashOps = {
+ JS_DHashAllocTable,
+ JS_DHashFreeTable,
+ HashString,
+ MatchString,
+ JS_DHashMoveEntryStub,
+ JS_DHashClearEntryStub,
+ JS_DHashFinalizeStub,
+ NULL
+};
+
+#define IS_DOUBLE_TABLE(table) ((table)->ops == &DoubleHashOps)
+#define IS_STRING_TABLE(table) ((table)->ops == &StringHashOps)
+
+#define IS_INITIALIZED_STATE(state) IS_DOUBLE_TABLE(&(state)->doubleAtoms)
+
+static JSDHashNumber
+HashDouble(JSDHashTable *table, const void *key)
+{
+ JS_ASSERT(IS_DOUBLE_TABLE(table));
+ return JS_HASH_DOUBLE(*(jsdouble *)key);
+}
+
+static JSDHashNumber
+HashString(JSDHashTable *table, const void *key)
+{
+ JS_ASSERT(IS_STRING_TABLE(table));
+ return js_HashString((JSString *)key);
+}
+
+static JSBool
+MatchDouble(JSDHashTable *table, const JSDHashEntryHdr *hdr, const void *key)
+{
+ JSAtomHashEntry *entry = TO_ATOM_ENTRY(hdr);
+ jsdouble d1, d2;
+
+ JS_ASSERT(IS_DOUBLE_TABLE(table));
+ if (entry->keyAndFlags == 0) {
+ /* See comments in MatchString. */
+ return JS_FALSE;
+ }
+
+ d1 = *(jsdouble *)ATOM_ENTRY_KEY(entry);
+ d2 = *(jsdouble *)key;
+ if (JSDOUBLE_IS_NaN(d1))
+ return JSDOUBLE_IS_NaN(d2);
+#if defined(XP_WIN)
+ /* XXX MSVC miscompiles such that (NaN == 0) */
+ if (JSDOUBLE_IS_NaN(d2))
+ return JS_FALSE;
+#endif
+ return d1 == d2;
+}
+
+static JSBool
+MatchString(JSDHashTable *table, const JSDHashEntryHdr *hdr, const void *key)
+{
+ JSAtomHashEntry *entry = TO_ATOM_ENTRY(hdr);
+
+ JS_ASSERT(IS_STRING_TABLE(table));
+ if (entry->keyAndFlags == 0) {
+ /*
+ * This happens when js_AtomizeString adds a new hash entry and
+ * releases the lock but before it takes the lock the second time to
+ * initialize keyAndFlags for the entry.
+ *
+ * We always return false for such entries so JS_DHashTableOperate
+ * never finds them. We clean them during GC's sweep phase.
+ *
+ * It means that with a contested lock or when GC is triggered outside
+ * the lock we may end up adding two entries, but this is a price for
+ * simpler code.
+ */
+ return JS_FALSE;
+ }
+ return js_EqualStrings((JSString *)ATOM_ENTRY_KEY(entry), (JSString *)key);
+}
+
+/*
+ * For a browser build from 2007-08-09 after the browser starts up there are
+ * just 55 double atoms, but over 15000 string atoms. Not to penalize more
+ * economical embeddings allocating too much memory initially we initialize
+ * atomized strings with just 1K entries.
+ */
+#define JS_STRING_HASH_COUNT 1024
+#define JS_DOUBLE_HASH_COUNT 64
+
+JSBool
+js_InitAtomState(JSRuntime *rt)
+{
+ JSAtomState *state = &rt->atomState;
+
+ /*
+ * The caller must zero the state before calling this function.
+ */
+ JS_ASSERT(!state->stringAtoms.ops);
+ JS_ASSERT(!state->doubleAtoms.ops);
+
+ if (!JS_DHashTableInit(&state->stringAtoms, &StringHashOps,
+ NULL, sizeof(JSAtomHashEntry),
+ JS_DHASH_DEFAULT_CAPACITY(JS_STRING_HASH_COUNT))) {
+ state->stringAtoms.ops = NULL;
+ return JS_FALSE;
+ }
+ JS_ASSERT(IS_STRING_TABLE(&state->stringAtoms));
+
+ if (!JS_DHashTableInit(&state->doubleAtoms, &DoubleHashOps,
+ NULL, sizeof(JSAtomHashEntry),
+ JS_DHASH_DEFAULT_CAPACITY(JS_DOUBLE_HASH_COUNT))) {
+ state->doubleAtoms.ops = NULL;
+ JS_DHashTableFinish(&state->stringAtoms);
+ state->stringAtoms.ops = NULL;
+ return JS_FALSE;
+ }
+ JS_ASSERT(IS_DOUBLE_TABLE(&state->doubleAtoms));
+
+#ifdef JS_THREADSAFE
+ js_InitLock(&state->lock);
+#endif
+ JS_ASSERT(IS_INITIALIZED_STATE(state));
+ return JS_TRUE;
+}
+
+static JSDHashOperator
+js_string_uninterner(JSDHashTable *table, JSDHashEntryHdr *hdr,
+ uint32 number, void *arg)
+{
+ JSAtomHashEntry *entry = TO_ATOM_ENTRY(hdr);
+ JSRuntime *rt = (JSRuntime *)arg;
+ JSString *str;
+
+ /*
+ * Any string entry that remains at this point must be initialized, as the
+ * last GC should clean any uninitialized ones.
+ */
+ JS_ASSERT(IS_STRING_TABLE(table));
+ JS_ASSERT(entry->keyAndFlags != 0);
+ str = (JSString *)ATOM_ENTRY_KEY(entry);
+
+ js_FinalizeStringRT(rt, str);
+ return JS_DHASH_NEXT;
+}
+
+void
+js_FinishAtomState(JSRuntime *rt)
+{
+ JSAtomState *state = &rt->atomState;
+
+ if (!IS_INITIALIZED_STATE(state)) {
+ /*
+ * We are called with uninitialized state when JS_NewRuntime fails and
+ * calls JS_DestroyRuntime on a partially initialized runtime.
+ */
+ return;
+ }
+
+ JS_DHashTableEnumerate(&state->stringAtoms, js_string_uninterner, rt);
+ JS_DHashTableFinish(&state->stringAtoms);
+ JS_DHashTableFinish(&state->doubleAtoms);
+
+#ifdef JS_THREADSAFE
+ js_FinishLock(&state->lock);
+#endif
+#ifdef DEBUG
+ memset(state, JS_FREE_PATTERN, sizeof *state);
+#endif
+}
+
+JSBool
+js_InitCommonAtoms(JSContext *cx)
+{
+ JSAtomState *state = &cx->runtime->atomState;
+ uintN i;
+ JSAtom **atoms;
+
+ atoms = COMMON_ATOMS_START(state);
+ for (i = 0; i < JS_ARRAY_LENGTH(js_common_atom_names); i++, atoms++) {
+ *atoms = js_Atomize(cx, js_common_atom_names[i],
+ strlen(js_common_atom_names[i]), ATOM_PINNED);
+ if (!*atoms)
+ return JS_FALSE;
+ }
+ JS_ASSERT((uint8 *)atoms - (uint8 *)state == LAZY_ATOM_OFFSET_START);
+ memset(atoms, 0, ATOM_OFFSET_LIMIT - LAZY_ATOM_OFFSET_START);
+
+ return JS_TRUE;
+}
+
+static JSDHashOperator
+js_atom_unpinner(JSDHashTable *table, JSDHashEntryHdr *hdr,
+ uint32 number, void *arg)
+{
+ JS_ASSERT(IS_STRING_TABLE(table));
+ CLEAR_ATOM_ENTRY_FLAGS(TO_ATOM_ENTRY(hdr), ATOM_PINNED);
+ return JS_DHASH_NEXT;
+}
+
+void
+js_FinishCommonAtoms(JSContext *cx)
+{
+ JSAtomState *state = &cx->runtime->atomState;
+
+ JS_DHashTableEnumerate(&state->stringAtoms, js_atom_unpinner, NULL);
+#ifdef DEBUG
+ memset(COMMON_ATOMS_START(state), JS_FREE_PATTERN,
+ ATOM_OFFSET_LIMIT - ATOM_OFFSET_START);
+#endif
+}
+
+static JSDHashOperator
+js_locked_atom_tracer(JSDHashTable *table, JSDHashEntryHdr *hdr,
+ uint32 number, void *arg)
+{
+ JSAtomHashEntry *entry = TO_ATOM_ENTRY(hdr);
+ JSTracer *trc = (JSTracer *)arg;
+
+ if (entry->keyAndFlags == 0) {
+ /* Ignore uninitialized entries during tracing. */
+ return JS_DHASH_NEXT;
+ }
+ JS_SET_TRACING_INDEX(trc, "locked_atom", (size_t)number);
+ JS_CallTracer(trc, ATOM_ENTRY_KEY(entry),
+ IS_STRING_TABLE(table) ? JSTRACE_STRING : JSTRACE_DOUBLE);
+ return JS_DHASH_NEXT;
+}
+
+static JSDHashOperator
+js_pinned_atom_tracer(JSDHashTable *table, JSDHashEntryHdr *hdr,
+ uint32 number, void *arg)
+{
+ JSAtomHashEntry *entry = TO_ATOM_ENTRY(hdr);
+ JSTracer *trc = (JSTracer *)arg;
+ uintN flags = ATOM_ENTRY_FLAGS(entry);
+
+ JS_ASSERT(IS_STRING_TABLE(table));
+ if (flags & (ATOM_PINNED | ATOM_INTERNED)) {
+ JS_SET_TRACING_INDEX(trc,
+ flags & ATOM_PINNED
+ ? "pinned_atom"
+ : "interned_atom",
+ (size_t)number);
+ JS_CallTracer(trc, ATOM_ENTRY_KEY(entry), JSTRACE_STRING);
+ }
+ return JS_DHASH_NEXT;
+}
+
+void
+js_TraceAtomState(JSTracer *trc, JSBool allAtoms)
+{
+ JSRuntime *rt = trc->context->runtime;
+ JSAtomState *state = &rt->atomState;
+
+ if (allAtoms) {
+ JS_DHashTableEnumerate(&state->doubleAtoms, js_locked_atom_tracer, trc);
+ JS_DHashTableEnumerate(&state->stringAtoms, js_locked_atom_tracer, trc);
+ } else {
+ JS_DHashTableEnumerate(&state->stringAtoms, js_pinned_atom_tracer, trc);
+ }
+}
+
+static JSDHashOperator
+js_atom_sweeper(JSDHashTable *table, JSDHashEntryHdr *hdr,
+ uint32 number, void *arg)
+{
+ JSAtomHashEntry *entry = TO_ATOM_ENTRY(hdr);
+ JSContext *cx = (JSContext *)arg;
+
+ /* Remove uninitialized entries. */
+ if (entry->keyAndFlags == 0)
+ return JS_DHASH_REMOVE;
+
+ if (ATOM_ENTRY_FLAGS(entry) & (ATOM_PINNED | ATOM_INTERNED)) {
+ /* Pinned or interned key cannot be finalized. */
+ JS_ASSERT(!js_IsAboutToBeFinalized(cx, ATOM_ENTRY_KEY(entry)));
+ } else if (js_IsAboutToBeFinalized(cx, ATOM_ENTRY_KEY(entry))) {
+ /* Remove entries with things about to be GC'ed. */
+ return JS_DHASH_REMOVE;
+ }
+ return JS_DHASH_NEXT;
+}
+
+void
+js_SweepAtomState(JSContext *cx)
+{
+ JSAtomState *state = &cx->runtime->atomState;
+
+ JS_DHashTableEnumerate(&state->doubleAtoms, js_atom_sweeper, cx);
+ JS_DHashTableEnumerate(&state->stringAtoms, js_atom_sweeper, cx);
+
+ /*
+ * Optimize for simplicity and mutate table generation numbers even if the
+ * sweeper has not removed any entries.
+ */
+ state->doubleAtoms.generation++;
+ state->stringAtoms.generation++;
+}
+
+JSAtom *
+js_AtomizeDouble(JSContext *cx, jsdouble d)
+{
+ JSAtomState *state;
+ JSDHashTable *table;
+ JSAtomHashEntry *entry;
+ uint32 gen;
+ jsdouble *key;
+ jsval v;
+
+ state = &cx->runtime->atomState;
+ table = &state->doubleAtoms;
+
+ JS_LOCK(cx, &state->lock);
+ entry = TO_ATOM_ENTRY(JS_DHashTableOperate(table, &d, JS_DHASH_ADD));
+ if (!entry)
+ goto failed_hash_add;
+ if (entry->keyAndFlags == 0) {
+ gen = ++table->generation;
+ JS_UNLOCK(cx, &state->lock);
+
+ key = js_NewWeaklyRootedDouble(cx, d);
+ if (!key)
+ return NULL;
+
+ JS_LOCK(cx, &state->lock);
+ if (table->generation == gen) {
+ JS_ASSERT(entry->keyAndFlags == 0);
+ } else {
+ entry = TO_ATOM_ENTRY(JS_DHashTableOperate(table, key,
+ JS_DHASH_ADD));
+ if (!entry)
+ goto failed_hash_add;
+ if (entry->keyAndFlags != 0)
+ goto finish;
+ ++table->generation;
+ }
+ INIT_ATOM_ENTRY(entry, key);
+ }
+
+ finish:
+ v = DOUBLE_TO_JSVAL((jsdouble *)ATOM_ENTRY_KEY(entry));
+ cx->weakRoots.lastAtom = v;
+ JS_UNLOCK(cx, &state->lock);
+
+ return (JSAtom *)v;
+
+ failed_hash_add:
+ JS_UNLOCK(cx, &state->lock);
+ JS_ReportOutOfMemory(cx);
+ return NULL;
+}
+
+JSAtom *
+js_AtomizeString(JSContext *cx, JSString *str, uintN flags)
+{
+ jsval v;
+ JSAtomState *state;
+ JSDHashTable *table;
+ JSAtomHashEntry *entry;
+ JSString *key;
+ uint32 gen;
+
+ JS_ASSERT(!(flags & ~(ATOM_PINNED|ATOM_INTERNED|ATOM_TMPSTR|ATOM_NOCOPY)));
+ JS_ASSERT_IF(flags & ATOM_NOCOPY, flags & ATOM_TMPSTR);
+
+ if (str->isAtomized())
+ return (JSAtom *) STRING_TO_JSVAL(str);
+
+ size_t length = str->length();
+ if (length == 1) {
+ jschar c = str->chars()[0];
+ if (c < UNIT_STRING_LIMIT)
+ return (JSAtom *) STRING_TO_JSVAL(JSString::unitString(c));
+ }
+
+ /*
+ * Here we know that JSString::intStringTable covers only 256 (or at least
+ * not 1000 or more) chars. We rely on order here to resolve the unit vs.
+ * int string atom identity issue by giving priority to unit strings for
+ * '0' through '9' (see JSString::intString in jsstrinlines.h).
+ */
+ JS_STATIC_ASSERT(INT_STRING_LIMIT <= 999);
+ if (2 <= length && length <= 3) {
+ const jschar *chars = str->chars();
+
+ if ('1' <= chars[0] && chars[0] <= '9' &&
+ '0' <= chars[1] && chars[1] <= '9' &&
+ (length == 2 || ('0' <= chars[2] && chars[2] <= '9'))) {
+ jsint i = (chars[0] - '0') * 10 + chars[1] - '0';
+
+ if (length == 3)
+ i = i * 10 + chars[2] - '0';
+ if (jsuint(i) < INT_STRING_LIMIT)
+ return (JSAtom *) STRING_TO_JSVAL(JSString::intString(i));
+ }
+ }
+
+ state = &cx->runtime->atomState;
+ table = &state->stringAtoms;
+
+ JS_LOCK(cx, &state->lock);
+ entry = TO_ATOM_ENTRY(JS_DHashTableOperate(table, str, JS_DHASH_ADD));
+ if (!entry)
+ goto failed_hash_add;
+ if (entry->keyAndFlags != 0) {
+ key = (JSString *)ATOM_ENTRY_KEY(entry);
+ } else {
+ /*
+ * We created a new hashtable entry. Unless str is already allocated
+ * from the GC heap and flat, we have to release state->lock as
+ * string construction is a complex operation. For example, it can
+ * trigger GC which may rehash the table and make the entry invalid.
+ */
+ ++table->generation;
+ if (!(flags & ATOM_TMPSTR) && str->isFlat()) {
+ str->flatClearMutable();
+ key = str;
+ } else {
+ gen = table->generation;
+ JS_UNLOCK(cx, &state->lock);
+
+ if (flags & ATOM_TMPSTR) {
+ if (flags & ATOM_NOCOPY) {
+ key = js_NewString(cx, str->flatChars(), str->flatLength());
+ if (!key)
+ return NULL;
+
+ /* Finish handing off chars to the GC'ed key string. */
+ str->mChars = NULL;
+ } else {
+ key = js_NewStringCopyN(cx, str->flatChars(), str->flatLength());
+ if (!key)
+ return NULL;
+ }
+ } else {