Merge from tracemonkey.
authorDavid Anderson <danderson@mozilla.com>
Fri, 17 Sep 2010 12:12:34 -0700
changeset 74588 c91290f1ee7eff6fa86f69228c2db39ec3b486bb
parent 74587 a5a255965167b428f4c45dd192187d32ca84269b (current diff)
parent 54415 eb0ceafa4af87f0ee7ef15fc955782db0299b373 (diff)
child 74589 a2ccd2c8e545299cbca6b55a8069253ee121cb2a
push id2
push userbsmedberg@mozilla.com
push dateFri, 19 Aug 2011 14:38:13 +0000
milestone2.0b6pre
Merge from tracemonkey.
js/src/jsfun.cpp
js/src/jsinterp.cpp
js/src/jsinterp.h
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jstracer.cpp
js/src/methodjit/Compiler.cpp
js/src/methodjit/Compiler.h
js/src/methodjit/FastOps.cpp
js/src/methodjit/FrameState.cpp
js/src/methodjit/InvokeHelpers.cpp
js/src/methodjit/MethodJIT.cpp
js/src/methodjit/MethodJIT.h
js/src/methodjit/MonoIC.cpp
js/src/methodjit/MonoIC.h
js/src/methodjit/StubCalls.h
js/src/methodjit/TrampolineCompiler.cpp
--- a/js/src/Makefile.in
+++ b/js/src/Makefile.in
@@ -326,16 +326,51 @@ ifeq (arm, $(TARGET_CPU))
 #CPPSRCS		+= only_on_arm.cpp
 endif
 #
 # END enclude sources for the method JIT
 #############################################
 
 endif
 
+###############################################
+# BEGIN include sources for V8 dtoa
+#
+VPATH += 	$(srcdir)/v8-dtoa \
+		$(NONE)
+
+CPPSRCS += 	checks.cc \
+		conversions.cc \
+		diy-fp.cc \
+		v8-dtoa.cc \
+		fast-dtoa.cc \
+		platform.cc \
+		utils.cc \
+		$(NONE)
+
+INSTALLED_HEADERS += \
+		cached-powers.h \
+		checks.h \
+		conversions.h \
+		diy-fp.h \
+		double.h \
+		dtoa.h \
+		fast-dtoa.h \
+		globals.h \
+		include-v8.h \
+		platform.h \
+		powers-ten.h \
+		utils.h \
+		v8.h \
+		$(NULL)
+
+#
+# END enclude sources for V8 dtoa
+#############################################
+
 ifeq (,$(filter-out powerpc sparc,$(TARGET_CPU)))
 
 VPATH +=	$(srcdir)/assembler \
 		$(srcdir)/assembler/wtf \
 		$(srcdir)/yarr/pcre \
 		$(NULL)
 
 CPPSRCS += 	pcre_compile.cpp \
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -4096,16 +4096,17 @@ dnl ====================================
 MOZ_ARG_ENABLE_BOOL(thumb2,
  [  --enable-thumb2         Enable Thumb2 instruction set],
     MOZ_THUMB2=1,)
 
 if test -n "$MOZ_THUMB2"; then
   case "$target_cpu" in
     arm*)
       if test "$GNU_CC"; then
+        AC_DEFINE(MOZ_THUMB2)
         CFLAGS="$CFLAGS -march=armv7-a -mthumb -Wa, -march=armv7-a -Wa, -mthumb"
         CXXFLAGS="$CXXFLAGS -march=armv7-a -mthumb -Wa, -march=armv7-a -Wa, -mthumb"
         ASFLAGS="$ASFLAGS -march=armv7-a -mthumb"
       else
         AC_MSG_ERROR([--enable-thumb2 is not supported for non-GNU toolchains])
       fi
     ;;
     *)
--- a/js/src/js.msg
+++ b/js/src/js.msg
@@ -93,19 +93,19 @@ MSG_DEF(JSMSG_CANT_ALIAS,              1
 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_READ_ONLY,               19, 1, JSEXN_TYPEERR, "{0} is read-only")
 MSG_DEF(JSMSG_BAD_FORMAL,              20, 0, JSEXN_SYNTAXERR, "malformed formal parameter")
-MSG_DEF(JSMSG_UNUSED21,                21, 0, JSEXN_NONE, "")
+MSG_DEF(JSMSG_CANT_DELETE,             21, 1, JSEXN_TYPEERR, "property '{0}' is non-configurable and cannot be deleted")
 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}=")
--- a/js/src/jsapi-tests/Makefile.in
+++ b/js/src/jsapi-tests/Makefile.in
@@ -64,16 +64,17 @@ CPPSRCS = \
   testNewObject.cpp \
   testOps.cpp \
   testPropCache.cpp \
   testTrap.cpp \
   testSameValue.cpp \
   testSeal.cpp \
   testXDR.cpp \
   testSetPropertyWithNativeGetterStubSetter.cpp \
+  testScriptObject.cpp \
   $(NULL)
 
 DEFINES         += -DEXPORT_JS_API
 
 LIBS      = $(NSPR_LIBS) $(DEPTH)/$(LIB_PREFIX)js_static.$(LIB_SUFFIX)
 
 LOCAL_INCLUDES += -I$(topsrcdir) -I..
 
new file mode 100644
--- /dev/null
+++ b/js/src/jsapi-tests/testScriptObject.cpp
@@ -0,0 +1,170 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sw=4 et tw=99:
+ */
+
+#include "tests.h"
+
+struct ScriptObjectFixture : public JSAPITest {
+    static const int code_size;
+    static const char code[];
+    static jschar uc_code[];
+
+    ScriptObjectFixture()
+    {
+        for (int i = 0; i <= code_size; i++)
+            uc_code[i] = code[i];
+    }
+
+    bool tryScript(JSScript *script)
+    {
+        CHECK(script);
+
+        /* We should have allocated a script object for the script already. */
+        jsvalRoot script_object(cx, OBJECT_TO_JSVAL(JS_GetScriptObject(script)));
+        CHECK(JSVAL_TO_OBJECT(script_object.value()));
+
+        /*
+         * JS_NewScriptObject just returns the object already created for the
+         * script. It was always a bug to call this more than once.
+         */
+        jsvalRoot second_script_object
+            (cx, OBJECT_TO_JSVAL(JS_NewScriptObject(cx, script)));
+        CHECK_SAME(second_script_object.value(), script_object.value());
+
+        JS_GC(cx);
+
+        /* After a garbage collection, the script should still work. */
+        jsval result;
+        CHECK(JS_ExecuteScript(cx, global, script, &result));
+
+        /* JS_DestroyScript must still be safe to call, whether or not it
+           actually has any effect. */
+        JS_DestroyScript(cx, script);
+
+        return true;
+    }
+};
+
+const char ScriptObjectFixture::code[] =
+    "(function(a, b){return a+' '+b;}('hello', 'world'))";
+const int ScriptObjectFixture::code_size = sizeof(ScriptObjectFixture::code) - 1;
+jschar ScriptObjectFixture::uc_code[ScriptObjectFixture::code_size];
+
+BEGIN_FIXTURE_TEST(ScriptObjectFixture, bug438633_CompileScript)
+{
+    return tryScript(JS_CompileScript(cx, global, code, code_size,
+                                      __FILE__, __LINE__));
+}
+END_FIXTURE_TEST(ScriptObjectFixture, bug438633_CompileScript)
+
+BEGIN_FIXTURE_TEST(ScriptObjectFixture, bug438633_CompileScript_empty)
+{
+    return tryScript(JS_CompileScript(cx, global, "", 0,
+                                      __FILE__, __LINE__));
+}
+END_FIXTURE_TEST(ScriptObjectFixture, bug438633_CompileScript_empty)
+
+BEGIN_FIXTURE_TEST(ScriptObjectFixture, bug438633_CompileScriptForPrincipals)
+{
+    return tryScript(JS_CompileScriptForPrincipals(cx, global, NULL,
+                                                   code, code_size,
+                                                   __FILE__, __LINE__));
+}
+END_FIXTURE_TEST(ScriptObjectFixture, bug438633_CompileScriptForPrincipals)
+
+BEGIN_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileUCScript)
+{
+    return tryScript(JS_CompileUCScript(cx, global,
+                                        uc_code, code_size,
+                                        __FILE__, __LINE__));
+}
+END_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileUCScript)
+
+BEGIN_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileUCScript_empty)
+{
+    return tryScript(JS_CompileUCScript(cx, global,
+                                        uc_code, 0,
+                                        __FILE__, __LINE__));
+}
+END_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileUCScript_empty)
+
+BEGIN_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileUCScriptForPrincipals)
+{
+    return tryScript(JS_CompileUCScriptForPrincipals(cx, global, NULL,
+                                                     uc_code, code_size,
+                                                     __FILE__, __LINE__));
+}
+END_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileUCScriptForPrincipals)
+
+BEGIN_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileFile)
+{
+    TempFile tempScript;
+    static const char script_filename[] = "temp-bug438633_JS_CompileFile";
+    FILE *script_stream = tempScript.open(script_filename);
+    CHECK(fputs(code, script_stream) != EOF);
+    tempScript.close();
+    JSScript *script = JS_CompileFile(cx, global, script_filename);
+    tempScript.remove();
+    return tryScript(script);
+}
+END_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileFile)
+
+BEGIN_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileFile_empty)
+{
+    TempFile tempScript;
+    static const char script_filename[] = "temp-bug438633_JS_CompileFile_empty";
+    tempScript.open(script_filename);
+    tempScript.close();
+    JSScript *script = JS_CompileFile(cx, global, script_filename);
+    tempScript.remove();
+    return tryScript(script);
+}
+END_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileFile_empty)
+
+BEGIN_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileFileHandle)
+{
+    TempFile tempScript;
+    FILE *script_stream = tempScript.open("temp-bug438633_JS_CompileFileHandle");
+    CHECK(fputs(code, script_stream) != EOF);
+    CHECK(fseek(script_stream, 0, SEEK_SET) != EOF);
+    return tryScript(JS_CompileFileHandle(cx, global, "temporary file",
+                                          script_stream));
+}
+END_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileFileHandle)
+
+BEGIN_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileFileHandle_empty)
+{
+    TempFile tempScript;
+    FILE *script_stream = tempScript.open("temp-bug438633_JS_CompileFileHandle_empty");
+    return tryScript(JS_CompileFileHandle(cx, global, "empty temporary file",
+                                          script_stream));
+}
+END_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileFileHandle_empty)
+
+BEGIN_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileFileHandleForPrincipals)
+{
+    TempFile tempScript;
+    FILE *script_stream = tempScript.open("temp-bug438633_JS_CompileFileHandleForPrincipals");
+    CHECK(fputs(code, script_stream) != EOF);
+    CHECK(fseek(script_stream, 0, SEEK_SET) != EOF);
+    return tryScript(JS_CompileFileHandleForPrincipals(cx, global,
+                                                       "temporary file",
+                                                       script_stream, NULL));
+}
+END_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileFileHandleForPrincipals)
+
+BEGIN_TEST(testScriptObject_ScriptlessScriptObjects)
+{
+    /* JS_NewScriptObject(cx, NULL) should return a fresh object each time. */
+    jsvalRoot script_object1(cx, OBJECT_TO_JSVAL(JS_NewScriptObject(cx, NULL)));
+    CHECK(!JSVAL_IS_PRIMITIVE(script_object1.value()));
+
+    jsvalRoot script_object2(cx, OBJECT_TO_JSVAL(JS_NewScriptObject(cx, NULL)));
+    CHECK(!JSVAL_IS_PRIMITIVE(script_object2.value()));
+
+    if (script_object1.value() == script_object2.value())
+        return false;
+
+    return true;
+}
+END_TEST(testScriptObject_ScriptlessScriptObjects)
--- a/js/src/jsapi-tests/tests.h
+++ b/js/src/jsapi-tests/tests.h
@@ -36,16 +36,17 @@
  * 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 ***** */
 
 #include "jsapi.h"
 #include "jsprvtd.h"
 #include "jsvector.h"
+#include <errno.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
 
 class jsvalRoot
 {
 public:
     explicit jsvalRoot(JSContext *context, jsval value = JSVAL_NULL)
@@ -299,9 +300,84 @@ protected:
     public:                                                             \
         virtual const char * name() { return #testname; }               \
         virtual bool run()
 
 #define END_TEST(testname)                                              \
     };                                                                  \
     static cls_##testname cls_##testname##_instance;
 
+/*
+ * A "fixture" is a subclass of JSAPITest that holds common definitions for a
+ * set of tests. Each test that wants to use the fixture should use
+ * BEGIN_FIXTURE_TEST and END_FIXTURE_TEST, just as one would use BEGIN_TEST and
+ * END_TEST, but include the fixture class as the first argument. The fixture
+ * class's declarations are then in scope for the test bodies.
+ */
 
+#define BEGIN_FIXTURE_TEST(fixture, testname)                           \
+    class cls_##testname : public fixture {                             \
+    public:                                                             \
+        virtual const char * name() { return #testname; }               \
+        virtual bool run()
+
+#define END_FIXTURE_TEST(fixture, testname)                             \
+    };                                                                  \
+    static cls_##testname cls_##testname##_instance;
+
+/*
+ * A class for creating and managing one temporary file.
+ * 
+ * We could use the ISO C temporary file functions here, but those try to
+ * create files in the root directory on Windows, which fails for users
+ * without Administrator privileges.
+ */
+class TempFile {
+    const char *name;
+    FILE *stream;
+
+  public:
+    TempFile() : name(), stream() { }
+    ~TempFile() {
+        if (stream)
+            close();
+        if (name)
+            remove();
+    }
+
+    /*
+     * Return a stream for a temporary file named |fileName|. Infallible.
+     * Use only once per TempFile instance. If the file is not explicitly
+     * closed and deleted via the member functions below, this object's
+     * destructor will clean them up.
+     */
+    FILE *open(const char *fileName)
+    {
+        stream = fopen(fileName, "wb+");
+        if (!stream) {
+            fprintf(stderr, "error opening temporary file '%s': %s\n",
+                    fileName, strerror(errno));
+            exit(1);
+        }            
+        name = fileName;
+        return stream;
+    }
+
+    /* Close the temporary file's stream. */
+    void close() {
+        if (fclose(stream) == EOF) {
+            fprintf(stderr, "error closing temporary file '%s': %s\n",
+                    name, strerror(errno));
+            exit(1);
+        }
+        stream = NULL;
+    }
+
+    /* Delete the temporary file. */
+    void remove() {
+        if (::remove(name) != 0) {
+            fprintf(stderr, "error deleting temporary file '%s': %s\n",
+                    name, strerror(errno));
+            exit(1);
+        }
+        name = NULL;
+    }
+};
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -3707,17 +3707,17 @@ JS_GetMethod(JSContext *cx, JSObject *ob
 }
 
 JS_PUBLIC_API(JSBool)
 JS_SetPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
 {
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, id);
     JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED | JSRESOLVE_ASSIGNING);
-    return obj->setProperty(cx, id, Valueify(vp));
+    return obj->setProperty(cx, id, Valueify(vp), false);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_SetElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp)
 {
     return JS_SetPropertyById(cx, obj, INT_TO_JSID(index), vp);
 }
 
@@ -3736,17 +3736,17 @@ JS_SetUCProperty(JSContext *cx, JSObject
 }
 
 JS_PUBLIC_API(JSBool)
 JS_DeletePropertyById2(JSContext *cx, JSObject *obj, jsid id, jsval *rval)
 {
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, id);
     JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED);
-    return obj->deleteProperty(cx, id, Valueify(rval));
+    return obj->deleteProperty(cx, id, Valueify(rval), false);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_DeleteElement2(JSContext *cx, JSObject *obj, jsint index, jsval *rval)
 {
     return JS_DeletePropertyById2(cx, obj, INT_TO_JSID(index), rval);
 }
 
@@ -4863,17 +4863,19 @@ JS_New(JSContext *cx, JSObject *ctor, ui
     if (!cx->stack().pushInvokeArgs(cx, argc, &args))
         return NULL;
 
     args.callee().setObject(*ctor);
     args.thisv().setNull();
     memcpy(args.argv(), argv, argc * sizeof(jsval));
 
     bool ok = InvokeConstructor(cx, args);
-    JSObject *obj = ok ? args.rval().toObjectOrNull() : NULL;
+    JSObject *obj = (ok && args.rval().isObject())
+                    ? &args.rval().toObject()
+                    : NULL;
 
     LAST_FRAME_CHECKS(cx, ok);
     return obj;
 }
 
 JS_PUBLIC_API(JSOperationCallback)
 JS_SetOperationCallback(JSContext *cx, JSOperationCallback callback)
 {
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -947,20 +947,20 @@ JS_LeaveCrossCompartmentCall(JSCrossComp
 
 extern JS_PUBLIC_API(void *)
 JS_SetCompartmentPrivate(JSContext *cx, JSCompartment *compartment, void *data);
 
 extern JS_PUBLIC_API(void *)
 JS_GetCompartmentPrivate(JSContext *cx, JSCompartment *compartment);
 
 extern JS_PUBLIC_API(JSBool)
-JS_RewrapObject(JSContext *cx, JSObject **objp);
+JS_WrapObject(JSContext *cx, JSObject **objp);
 
 extern JS_PUBLIC_API(JSBool)
-JS_RewrapValue(JSContext *cx, jsval *p);
+JS_WrapValue(JSContext *cx, jsval *vp);
 
 extern JS_FRIEND_API(JSCompartment *)
 js_SwitchToCompartment(JSContext *cx, JSCompartment *compartment);
 
 extern JS_FRIEND_API(JSCompartment *)
 js_SwitchToObjectCompartment(JSContext *cx, JSObject *obj);
 
 #ifdef __cplusplus
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -48,17 +48,17 @@
  *
  * We track these pieces of metadata for arrays in dense mode:
  *  - The array's length property as a uint32, accessible with
  *    getArrayLength(), setArrayLength().
  *  - The number of element slots (capacity), gettable with
  *    getDenseArrayCapacity().
  *
  * In dense mode, holes in the array are represented by (JS_ARRAY_HOLE) invalid
- * values.  The final two slot in fslots are unused.
+ * values.  The final slot in fslots is unused.
  *
  * NB: the capacity and length of a dense array are entirely unrelated!  The
  * length may be greater than, less than, or equal to the capacity.  See
  * array_length_setter for an explanation of how the first, most surprising
  * case may occur.
  *
  * Arrays are converted to use js_SlowArrayClass when any of these conditions
  * are met:
@@ -511,17 +511,17 @@ SetArrayElement(JSContext *cx, JSObject 
 
     AutoIdRooter idr(cx);
 
     if (!IndexToId(cx, obj, index, NULL, idr.addr(), JS_TRUE))
         return JS_FALSE;
     JS_ASSERT(!JSID_IS_VOID(idr.id()));
 
     Value tmp = v;
-    return obj->setProperty(cx, idr.id(), &tmp);
+    return obj->setProperty(cx, idr.id(), &tmp, true);
 }
 
 #ifdef JS_TRACER
 JSBool JS_FASTCALL
 js_EnsureDenseArrayCapacity(JSContext *cx, JSObject *obj, jsint i)
 {
     jsuint u = jsuint(i);
     jsuint capacity = obj->getDenseArrayCapacity();
@@ -532,17 +532,17 @@ js_EnsureDenseArrayCapacity(JSContext *c
     return obj->ensureDenseArrayElements(cx, u + 1);    
 
 }
 JS_DEFINE_CALLINFO_3(extern, BOOL, js_EnsureDenseArrayCapacity, CONTEXT, OBJECT, INT32, 0,
                      nanojit::ACCSET_STORE_ANY)
 #endif
 
 static JSBool
-DeleteArrayElement(JSContext *cx, JSObject *obj, jsdouble index)
+DeleteArrayElement(JSContext *cx, JSObject *obj, jsdouble index, JSBool strict)
 {
     JS_ASSERT(index >= 0);
     if (obj->isDenseArray()) {
         if (index <= jsuint(-1)) {
             jsuint idx = jsuint(index);
             if (idx < obj->getDenseArrayCapacity()) {
                 obj->setDenseArrayElement(idx, MagicValue(JS_ARRAY_HOLE));
                 return JS_TRUE;
@@ -554,43 +554,44 @@ DeleteArrayElement(JSContext *cx, JSObje
     AutoIdRooter idr(cx);
 
     if (!IndexToId(cx, obj, index, NULL, idr.addr()))
         return JS_FALSE;
     if (JSID_IS_VOID(idr.id()))
         return JS_TRUE;
 
     Value junk;
-    return obj->deleteProperty(cx, idr.id(), &junk);
+    return obj->deleteProperty(cx, idr.id(), &junk, strict);
 }
 
 /*
  * When hole is true, delete the property at the given index. Otherwise set
  * its value to v assuming v is rooted.
  */
 static JSBool
 SetOrDeleteArrayElement(JSContext *cx, JSObject *obj, jsdouble index,
                         JSBool hole, const Value &v)
 {
     if (hole) {
         JS_ASSERT(v.isUndefined());
-        return DeleteArrayElement(cx, obj, index);
+        return DeleteArrayElement(cx, obj, index, true);
     }
     return SetArrayElement(cx, obj, index, v);
 }
 
 JSBool
 js_SetLengthProperty(JSContext *cx, JSObject *obj, jsdouble length)
 {
     Value v;
     jsid id;
 
     v.setNumber(length);
     id = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
-    return obj->setProperty(cx, id, &v);
+    /* We don't support read-only array length yet. */
+    return obj->setProperty(cx, id, &v, false);
 }
 
 JSBool
 js_HasLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp)
 {
     JSErrorReporter older = JS_SetErrorReporter(cx, NULL);
     AutoValueRooter tvr(cx);
     jsid id = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
@@ -618,21 +619,28 @@ array_length_getter(JSContext *cx, JSObj
             vp->setNumber(obj->getArrayLength());
             return JS_TRUE;
         }
     } while ((obj = obj->getProto()) != NULL);
     return JS_TRUE;
 }
 
 static JSBool
-array_length_setter(JSContext *cx, JSObject *obj, jsid id, Value *vp)
+array_length_setter(JSContext *cx, JSObject *obj, jsid id, Value *vp, JSBool strict)
 {
     jsuint newlen, oldlen, gap, index;
     Value junk;
 
+    /* Check for a sealed object first. */
+    if (obj->sealed()) {
+        return js_ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_READ_ONLY,
+                                        JSDVG_IGNORE_STACK, IdToValue(id), NULL,
+                                        NULL, NULL);
+    }
+
     if (!obj->isArray()) {
         jsid lengthId = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
 
         return obj->defineProperty(cx, lengthId, *vp, NULL, NULL, JSPROP_ENUMERATE);
     }
 
     newlen = ValueIsLength(cx, vp);
     if (vp->isNull())
@@ -657,18 +665,27 @@ array_length_setter(JSContext *cx, JSObj
          */
         jsuint oldcap = obj->getDenseArrayCapacity();
         if (oldcap > newlen && !obj->shrinkDenseArrayElements(cx, newlen))
             return false;
         obj->setArrayLength(newlen);
     } else if (oldlen - newlen < (1 << 24)) {
         do {
             --oldlen;
-            if (!JS_CHECK_OPERATION_LIMIT(cx) || !DeleteArrayElement(cx, obj, oldlen))
+            if (!JS_CHECK_OPERATION_LIMIT(cx)) {
+                obj->setArrayLength(oldlen + 1);
                 return false;
+            }
+            if (!DeleteArrayElement(cx, obj, oldlen, true)) {
+                obj->setArrayLength(oldlen + 1);
+                if (strict)
+                    return false;
+                JS_ClearPendingException(cx);
+                return true;
+            }
         } while (oldlen != newlen);
         obj->setArrayLength(newlen);
     } else {
         /*
          * We are going to remove a lot of indexes in a presumably sparse
          * array. So instead of looping through indexes between newlen and
          * oldlen, we iterate through all properties and remove those that
          * correspond to indexes in the half-open range [newlen, oldlen).  See
@@ -683,17 +700,17 @@ array_length_setter(JSContext *cx, JSObj
 
         gap = oldlen - newlen;
         for (;;) {
             if (!JS_CHECK_OPERATION_LIMIT(cx) || !JS_NextProperty(cx, iter, &id))
                 return false;
             if (JSID_IS_VOID(id))
                 break;
             if (js_IdIsIndex(id, &index) && index - newlen < gap &&
-                !obj->deleteProperty(cx, id, &junk)) {
+                !obj->deleteProperty(cx, id, &junk, false)) {
                 return false;
             }
         }
         obj->setArrayLength(newlen);
     }
 
     return true;
 }
@@ -815,40 +832,51 @@ slowarray_addProperty(JSContext *cx, JSO
 
 static JSType
 array_typeOf(JSContext *cx, JSObject *obj)
 {
     return JSTYPE_OBJECT;
 }
 
 static JSBool
-array_setProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp)
+array_setProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp, JSBool strict)
 {
     uint32 i;
 
     if (JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom))
-        return array_length_setter(cx, obj, id, vp);
+        return array_length_setter(cx, obj, id, vp, strict);
 
     if (!obj->isDenseArray())
-        return js_SetProperty(cx, obj, id, vp);
+        return js_SetProperty(cx, obj, id, vp, strict);
 
     if (!js_IdIsIndex(id, &i) || js_PrototypeHasIndexedProperties(cx, obj) ||
         INDEX_TOO_SPARSE(obj, i)) {
         if (!obj->makeDenseArraySlow(cx))
-            return JS_FALSE;
-        return js_SetProperty(cx, obj, id, vp);
+            return false;
+        return js_SetProperty(cx, obj, id, vp, strict);
     }
 
     if (!obj->ensureDenseArrayElements(cx, i + 1))
-        return JS_FALSE;
+        return false;
 
     if (i >= obj->getArrayLength())
         obj->setArrayLength(i + 1);
     obj->setDenseArrayElement(i, *vp);
-    return JS_TRUE;
+    return true;
+}
+
+static JSBool
+slowarray_setProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp, JSBool strict)
+{
+    JS_ASSERT(obj->isSlowArray());
+
+    if (JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom))
+        return array_length_setter(cx, obj, id, vp, strict);
+
+    return js_SetProperty(cx, obj, id, vp, strict);
 }
 
 JSBool
 js_PrototypeHasIndexedProperties(JSContext *cx, JSObject *obj)
 {
     /*
      * Walk up the prototype chain and see if this indexed element already
      * exists. If we hit the end of the prototype chain, it's safe to set the
@@ -898,17 +926,17 @@ array_defineProperty(JSContext *cx, JSOb
     isIndex = js_IdIsIndex(id, &i);
     if (!isIndex || attrs != JSPROP_ENUMERATE || !obj->isDenseArray() || INDEX_TOO_SPARSE(obj, i)) {
         if (!ENSURE_SLOW_ARRAY(cx, obj))
             return JS_FALSE;
         return js_DefineProperty(cx, obj, id, value, getter, setter, attrs);
     }
 
     Value tmp = *value;
-    return array_setProperty(cx, obj, id, &tmp);
+    return array_setProperty(cx, obj, id, &tmp, false);
 }
 
 static JSBool
 array_getAttributes(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp)
 {
     *attrsp = JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom)
         ? JSPROP_PERMANENT : JSPROP_ENUMERATE;
     return JS_TRUE;
@@ -918,22 +946,22 @@ static JSBool
 array_setAttributes(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp)
 {
     JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
                          JSMSG_CANT_SET_ARRAY_ATTRS);
     return JS_FALSE;
 }
 
 static JSBool
-array_deleteProperty(JSContext *cx, JSObject *obj, jsid id, Value *rval)
+array_deleteProperty(JSContext *cx, JSObject *obj, jsid id, Value *rval, JSBool strict)
 {
     uint32 i;
 
     if (!obj->isDenseArray())
-        return js_DeleteProperty(cx, obj, id, rval);
+        return js_DeleteProperty(cx, obj, id, rval, strict);
 
     if (JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom)) {
         rval->setBoolean(false);
         return JS_TRUE;
     }
 
     if (js_IdIsIndex(id, &i) && i < obj->getDenseArrayCapacity())
         obj->setDenseArrayElement(i, MagicValue(JS_ARRAY_HOLE));
@@ -1017,17 +1045,44 @@ Class js_SlowArrayClass = {
     JSCLASS_HAS_PRIVATE |
     JSCLASS_HAS_CACHED_PROTO(JSProto_Array),
     slowarray_addProperty,
     PropertyStub,   /* delProperty */
     PropertyStub,   /* getProperty */
     PropertyStub,   /* setProperty */
     EnumerateStub,
     ResolveStub,
-    js_TryValueOf
+    js_TryValueOf,
+    NULL,           /* finalize    */
+    NULL,           /* reserved0   */
+    NULL,           /* checkAccess */
+    NULL,           /* call        */
+    NULL,           /* construct   */
+    NULL,           /* xdrObject   */
+    NULL,           /* hasInstance */
+    NULL,           /* mark        */
+    JS_NULL_CLASS_EXT,
+    {
+        NULL,       /* lookupProperty   */
+        NULL,       /* defineProperty   */
+        NULL,       /* getProperty      */
+        /*
+         * For assignments to 'length', we need to know the setter's strictness. A property's
+         * setter isn't passed that, but the ObjectOps member is, so use that.
+         */
+        slowarray_setProperty,
+        NULL,       /* getAttributes    */
+        NULL,       /* setAttributes    */
+        NULL,       /* deleteProperty   */
+        NULL,       /* enumerate        */
+        NULL,       /* typeOf           */
+        NULL,       /* trace            */
+        NULL,       /* thisObject       */
+        NULL,       /* clear            */
+    }
 };
 
 /*
  * Convert an array object from fast-and-dense to slow-and-flexible.
  */
 JSBool
 JSObject::makeDenseArraySlow(JSContext *cx)
 {
@@ -1057,17 +1112,17 @@ JSObject::makeDenseArraySlow(JSContext *
          * Array.prototype is constructed as a dense array, but is immediately slowified before
          * we have time to set capacity.
          */
         capacity = 0;
     }
 
     /* Begin with the length property to share more of the property tree. */
     if (!addProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.lengthAtom),
-                     array_length_getter, array_length_setter,
+                     array_length_getter, NULL,
                      JSSLOT_ARRAY_LENGTH, JSPROP_PERMANENT | JSPROP_SHARED, 0, 0)) {
         setMap(oldMap);
         return false;
     }
 
     /* Create new properties pointing to existing elements. */
     for (uint32 i = 0; i < capacity; i++) {
         jsid id;
@@ -1419,17 +1474,17 @@ InitArrayElements(JSContext *cx, JSObjec
 
     JS_ASSERT(start == MAXINDEX);
     AutoValueRooter tvr(cx);
     AutoIdRooter idr(cx);
     Value idval = DoubleValue(MAXINDEX);
     do {
         *tvr.addr() = *vector++;
         if (!js_ValueToStringId(cx, idval, idr.addr()) ||
-            !obj->setProperty(cx, idr.id(), tvr.addr())) {
+            !obj->setProperty(cx, idr.id(), tvr.addr(), true)) {
             return JS_FALSE;
         }
         idval.getDoubleRef() += 1;
     } while (vector != end);
 
     return JS_TRUE;
 }
 
@@ -1980,18 +2035,18 @@ js::array_sort(JSContext *cx, uintN argc
         if (!JS_CHECK_OPERATION_LIMIT(cx) ||
             !SetArrayElement(cx, obj, newlen++, UndefinedValue())) {
             return false;
         }
     }
 
     /* Re-create any holes that sorted to the end of the array. */
     while (len > newlen) {
-        if (!JS_CHECK_OPERATION_LIMIT(cx) || !DeleteArrayElement(cx, obj, --len))
-            return JS_FALSE;
+        if (!JS_CHECK_OPERATION_LIMIT(cx) || !DeleteArrayElement(cx, obj, --len, true))
+            return false;
     }
     vp->setObject(*obj);
     return true;
 }
 
 /*
  * Perl-inspired push, pop, shift, unshift, and splice methods.
  */
@@ -2092,17 +2147,17 @@ array_pop_slowly(JSContext *cx, JSObject
     if (index == 0) {
         vp->setUndefined();
     } else {
         index--;
 
         /* Get the to-be-deleted property's value into vp. */
         if (!GetArrayElement(cx, obj, index, &hole, vp))
             return JS_FALSE;
-        if (!hole && !DeleteArrayElement(cx, obj, index))
+        if (!hole && !DeleteArrayElement(cx, obj, index, true))
             return JS_FALSE;
     }
     return js_SetLengthProperty(cx, obj, index);
 }
 
 static JSBool
 array_pop_dense(JSContext *cx, JSObject* obj, Value *vp)
 {
@@ -2112,17 +2167,17 @@ array_pop_dense(JSContext *cx, JSObject*
     index = obj->getArrayLength();
     if (index == 0) {
         vp->setUndefined();
         return JS_TRUE;
     }
     index--;
     if (!GetArrayElement(cx, obj, index, &hole, vp))
         return JS_FALSE;
-    if (!hole && !DeleteArrayElement(cx, obj, index))
+    if (!hole && !DeleteArrayElement(cx, obj, index, true))
         return JS_FALSE;
     obj->setArrayLength(index);
     return JS_TRUE;
 }
 
 static JSBool
 array_pop(JSContext *cx, uintN argc, Value *vp)
 {
@@ -2171,17 +2226,17 @@ array_shift(JSContext *cx, uintN argc, V
             if (!JS_CHECK_OPERATION_LIMIT(cx) ||
                 !GetArrayElement(cx, obj, i + 1, &hole, tvr.addr()) ||
                 !SetOrDeleteArrayElement(cx, obj, i, hole, tvr.value())) {
                 return JS_FALSE;
             }
         }
 
         /* Delete the only or last element when it exists. */
-        if (!hole && !DeleteArrayElement(cx, obj, length))
+        if (!hole && !DeleteArrayElement(cx, obj, length, true))
             return JS_FALSE;
     }
     return js_SetLengthProperty(cx, obj, length);
 }
 
 static JSBool
 array_unshift(JSContext *cx, uintN argc, Value *vp)
 {
--- a/js/src/jsbuiltins.h
+++ b/js/src/jsbuiltins.h
@@ -226,16 +226,17 @@ struct ClosureVarInfo;
 #define _JS_CTYPE_SHAPE             _JS_CTYPE(js::Shape *,            _JS_PTR, --, --, INFALLIBLE)
 #define _JS_CTYPE_TRACERSTATE       _JS_CTYPE(TracerState *,          _JS_PTR, --, --, INFALLIBLE)
 #define _JS_CTYPE_FRAGMENT          _JS_CTYPE(nanojit::Fragment *,    _JS_PTR, --, --, INFALLIBLE)
 #define _JS_CTYPE_CLASS             _JS_CTYPE(js::Class *,            _JS_PTR, --, --, INFALLIBLE)
 #define _JS_CTYPE_DOUBLEPTR         _JS_CTYPE(double *,               _JS_PTR, --, --, INFALLIBLE)
 #define _JS_CTYPE_CHARPTR           _JS_CTYPE(char *,                 _JS_PTR, --, --, INFALLIBLE)
 #define _JS_CTYPE_CVIPTR            _JS_CTYPE(const ClosureVarInfo *, _JS_PTR, --, --, INFALLIBLE)
 #define _JS_CTYPE_FRAMEINFO         _JS_CTYPE(FrameInfo *,            _JS_PTR, --, --, INFALLIBLE)
+#define _JS_CTYPE_PICTABLE          _JS_CTYPE(PICTable *,             _JS_PTR, --, --, INFALLIBLE)
 
 /*
  * The "VALUE" type is used to indicate that a native takes a js::Value
  * parameter by value. Unfortunately, for technical reasons, we can't simply
  * have the parameter type be js::Value. Furthermore, the right thing to pass
  * differs based on word size. Thus, a native that declares a parameter of type
  * VALUE should have the corresponding argument type be:
  *  - on 32-bit: const Value*
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -70,16 +70,20 @@
 #include "jspubtd.h"
 #include "jsscan.h"
 #include "jsscope.h"
 #include "jsscript.h"
 #include "jsstaticcheck.h"
 #include "jsstr.h"
 #include "jstracer.h"
 
+#ifdef JS_METHODJIT
+# include "assembler/assembler/MacroAssembler.h"
+#endif
+
 #include "jscntxtinlines.h"
 #include "jsinterpinlines.h"
 #include "jsobjinlines.h"
 
 #ifdef XP_WIN
 # include "jswin.h"
 #elif defined(XP_OS2)
 # define INCL_DOSMEMMGR
@@ -2178,16 +2182,35 @@ FreeOldArenas(JSRuntime *rt, JSArenaPool
 void
 JSContext::purge()
 {
     FreeOldArenas(runtime, &regExpPool);
     /* FIXME: bug 586161 */
     compartment->purge(this);
 }
 
+void
+JSContext::updateJITEnabled()
+{
+#ifdef JS_TRACER
+    traceJitEnabled = ((options & JSOPTION_JIT) &&
+                       (debugHooks == &js_NullDebugHooks ||
+                        (debugHooks == &runtime->globalDebugHooks &&
+                         !runtime->debuggerInhibitsJIT())));
+#endif
+#ifdef JS_METHODJIT
+    methodJitEnabled = (options & JSOPTION_METHODJIT)
+# ifdef JS_CPU_X86
+                       && JSC::MacroAssemblerX86Common::getSSEState() >=
+                          JSC::MacroAssemblerX86Common::HasSSE2
+# endif
+                        ;
+#endif
+}
+
 namespace js {
 
 void
 SetPendingException(JSContext *cx, const Value &v)
 {
     cx->throwing = JS_TRUE;
     cx->exception = v;
 }
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -2286,37 +2286,34 @@ struct JSContext
      * State for the current tree execution.  bailExit is valid if the tree has
      * called back into native code via a _FAIL builtin and has not yet bailed,
      * else garbage (NULL in debug builds).
      */
     js::TracerState     *tracerState;
     js::VMSideExit      *bailExit;
 
     /*
-     * True if traces may be executed. Invariant: The value of jitEnabled is
-     * always equal to the expression in updateJITEnabled below.
+     * True if traces may be executed. Invariant: The value of traceJitenabled
+     * is always equal to the expression in updateJITEnabled below.
      *
      * This flag and the fields accessed by updateJITEnabled are written only
      * in runtime->gcLock, to avoid race conditions that would leave the wrong
-     * value in jitEnabled. (But the interpreter reads this without
+     * value in traceJitEnabled. (But the interpreter reads this without
      * locking. That can race against another thread setting debug hooks, but
      * we always read cx->debugHooks without locking anyway.)
      */
-    bool                 jitEnabled;
+    bool                 traceJitEnabled;
+#endif
+
+#ifdef JS_METHODJIT
+    bool                 methodJitEnabled;
 #endif
 
     /* Caller must be holding runtime->gcLock. */
-    void updateJITEnabled() {
-#ifdef JS_TRACER
-        jitEnabled = ((options & JSOPTION_JIT) &&
-                      (debugHooks == &js_NullDebugHooks ||
-                       (debugHooks == &runtime->globalDebugHooks &&
-                        !runtime->debuggerInhibitsJIT())));
-#endif
-    }
+    void updateJITEnabled();
 
 #ifdef MOZ_TRACE_JSCALLS
     /* Function entry/exit debugging callback. */
     JSFunctionCallback    functionCallback;
 
     void doFunctionCallback(const JSFunction *fun,
                             const JSScript *scr,
                             JSBool entering) const
--- a/js/src/jsdbgapi.cpp
+++ b/js/src/jsdbgapi.cpp
@@ -447,17 +447,17 @@ JITInhibitingHookChange(JSRuntime *rt, b
 {
     if (wasInhibited) {
         if (!rt->debuggerInhibitsJIT()) {
             for (JSCList *cl = rt->contextList.next; cl != &rt->contextList; cl = cl->next)
                 js_ContextFromLinkField(cl)->updateJITEnabled();
         }
     } else if (rt->debuggerInhibitsJIT()) {
         for (JSCList *cl = rt->contextList.next; cl != &rt->contextList; cl = cl->next)
-            js_ContextFromLinkField(cl)->jitEnabled = false;
+            js_ContextFromLinkField(cl)->traceJitEnabled = false;
     }
 }
 
 static void
 LeaveTraceRT(JSRuntime *rt)
 {
     JSThreadData *data = js_CurrentThreadData(rt);
     JSContext *cx = data ? data->traceMonitor.tracecx : NULL;
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -577,18 +577,18 @@ ArgSetter(JSContext *cx, JSObject *obj, 
 
     /*
      * For simplicity we use delete/set to replace the property with one
      * backed by the default Object getter and setter. Note that we rely on
      * args_delProperty to clear the corresponding reserved slot so the GC can
      * collect its value.
      */
     AutoValueRooter tvr(cx);
-    return js_DeleteProperty(cx, obj, id, tvr.addr()) &&
-           js_SetProperty(cx, obj, id, vp);
+    return js_DeleteProperty(cx, obj, id, tvr.addr(), false) &&
+           js_SetProperty(cx, obj, id, vp, false);
 }
 
 static JSBool
 args_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
              JSObject **objp)
 {
     JS_ASSERT(obj->isNormalArguments());
 
@@ -693,18 +693,18 @@ StrictArgSetter(JSContext *cx, JSObject 
 
     /*
      * For simplicity we use delete/set to replace the property with one
      * backed by the default Object getter and setter. Note that we rely on
      * args_delProperty to clear the corresponding reserved slot so the GC can
      * collect its value.
      */
     AutoValueRooter tvr(cx);
-    return js_DeleteProperty(cx, obj, id, tvr.addr()) &&
-           js_SetProperty(cx, obj, id, vp);
+    return js_DeleteProperty(cx, obj, id, tvr.addr(), true) &&
+           js_SetProperty(cx, obj, id, vp, true);
 }
 
 JSBool
 strictargs_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags, JSObject **objp)
 {
     JS_ASSERT(obj->isStrictArguments());
 
     *objp = NULL;
@@ -1641,18 +1641,18 @@ struct LazyFunctionDataProp {
 struct PoisonPillProp {
     uint16       atomOffset;
     int8         tinyid;
 };
 
 /* NB: no sentinels at ends -- use JS_ARRAY_LENGTH to bound loops. */
 
 const LazyFunctionDataProp lazyFunctionDataProps[] = {
-    {ATOM_OFFSET(arity),     FUN_ARITY,      JSPROP_PERMANENT},
-    {ATOM_OFFSET(name),      FUN_NAME,       JSPROP_PERMANENT},
+    {ATOM_OFFSET(arity),     FUN_ARITY,      JSPROP_PERMANENT|JSPROP_READONLY},
+    {ATOM_OFFSET(name),      FUN_NAME,       JSPROP_PERMANENT|JSPROP_READONLY},
 };
 
 /* Properties censored into [[ThrowTypeError]] in strict mode. */
 const PoisonPillProp poisonPillProps[] = {
     {ATOM_OFFSET(arguments), FUN_ARGUMENTS },
     {ATOM_OFFSET(caller),    FUN_CALLER    },
 };
 
@@ -1661,17 +1661,17 @@ const PoisonPillProp poisonPillProps[] =
 static JSBool
 fun_enumerate(JSContext *cx, JSObject *obj)
 {
     JS_ASSERT(obj->isFunction());
 
     jsid id;
     bool found;
 
-    if (!obj->getFunctionPrivate()->isBound()) {
+    if (!obj->isBoundFunction()) {
         id = ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom);
         if (!obj->hasProperty(cx, id, &found, JSRESOLVE_QUALIFIED))
             return false;
     }
 
     id = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
     if (!obj->hasProperty(cx, id, &found, JSRESOLVE_QUALIFIED))
         return false;
@@ -1702,17 +1702,17 @@ fun_resolve(JSContext *cx, JSObject *obj
 
     JSFunction *fun = obj->getFunctionPrivate();
 
     /*
      * No need to reflect fun.prototype in 'fun.prototype = ... '. Assert that
      * fun is not a compiler-created function object, which must never leak to
      * script or embedding code and then be mutated.
      */
-    if ((flags & JSRESOLVE_ASSIGNING) && !JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom)) {
+    if ((flags & JSRESOLVE_ASSIGNING) && JSID_IS_ATOM(id, cx->runtime->atomState.classPrototypeAtom)) {
         JS_ASSERT(!IsInternalFunctionObject(obj));
         return JS_TRUE;
     }
 
     /*
      * Ok, check whether id is 'prototype' and bootstrap the function object's
      * prototype property.
      */
@@ -1723,17 +1723,17 @@ fun_resolve(JSContext *cx, JSObject *obj
         /*
          * Beware of the wacky case of a user function named Object -- trying
          * to find a prototype for that will recur back here _ad perniciem_.
          */
         if (fun->atom == CLASS_ATOM(cx, Object))
             return JS_TRUE;
 
         /* ES5 15.3.4.5: bound functions don't have a prototype property. */
-        if (fun->isBound())
+        if (obj->isBoundFunction())
             return JS_TRUE;
 
         /*
          * Make the prototype object an instance of Object with the same parent
          * as the function object itself.
          */
         JSObject *parent = obj->getParent();
         JSObject *proto;
@@ -1792,17 +1792,17 @@ fun_resolve(JSContext *cx, JSObject *obj
         const PoisonPillProp &p = poisonPillProps[i];
 
         atom = OFFSET_TO_ATOM(cx->runtime, p.atomOffset);
         if (id == ATOM_TO_JSID(atom)) {
             JS_ASSERT(!IsInternalFunctionObject(obj));
 
             PropertyOp getter, setter;
             uintN attrs = JSPROP_PERMANENT;
-            if (fun->inStrictMode() || fun->isBound()) {
+            if (fun->inStrictMode() || obj->isBoundFunction()) {
                 JSObject *throwTypeError = obj->getThrowTypeError();
 
                 getter = CastAsPropertyOp(throwTypeError);
                 setter = CastAsPropertyOp(throwTypeError);
                 attrs |= JSPROP_GETTER | JSPROP_SETTER;
             } else {
                 getter = fun_getProperty;
                 setter = PropertyStub;
@@ -2018,17 +2018,17 @@ js_XDRFunctionObject(JSXDRState *xdr, JS
  * [[HasInstance]] internal method for Function objects: fetch the .prototype
  * property of its 'this' parameter, and walks the prototype chain of v (only
  * if v is an object) returning true if .prototype is found.
  */
 static JSBool
 fun_hasInstance(JSContext *cx, JSObject *obj, const Value *v, JSBool *bp)
 {
     while (obj->isFunction()) {
-        if (!obj->getFunctionPrivate()->isBound())
+        if (!obj->isBoundFunction())
             break;
         obj = obj->getBoundFunctionTarget();
     }
 
     jsid id = ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom);
     Value pval;
     if (!obj->getProperty(cx, id, &pval))
         return JS_FALSE;
@@ -2393,29 +2393,23 @@ js_fun_apply(JSContext *cx, uintN argc, 
 }
 
 namespace {
 
 JSBool
 CallOrConstructBoundFunction(JSContext *cx, uintN argc, Value *vp);
 }
 
-bool
-JSFunction::isBound() const
-{
-    return isNative() && u.n.native == CallOrConstructBoundFunction;
-}
-
 inline bool
 JSObject::initBoundFunction(JSContext *cx, const Value &thisArg,
                             const Value *args, uintN argslen)
 {
     JS_ASSERT(isFunction());
-    JS_ASSERT(getFunctionPrivate()->isBound());
-
+
+    flags |= JSObject::BOUND_FUNCTION;
     fslots[JSSLOT_BOUND_FUNCTION_THIS] = thisArg;
     fslots[JSSLOT_BOUND_FUNCTION_ARGS_COUNT].setPrivateUint32(argslen);
     if (argslen != 0) {
         /* FIXME? Burn memory on an empty scope whose shape covers the args slots. */
         EmptyShape *empty = EmptyShape::create(cx, clasp);
         if (!empty)
             return false;
 
@@ -2431,52 +2425,52 @@ JSObject::initBoundFunction(JSContext *c
     }
     return true;
 }
 
 inline JSObject *
 JSObject::getBoundFunctionTarget() const
 {
     JS_ASSERT(isFunction());
-    JS_ASSERT(getFunctionPrivate()->isBound());
+    JS_ASSERT(isBoundFunction());
 
     /* Bound functions abuse |parent| to store their target function. */
     return getParent();
 }
 
 inline const js::Value &
 JSObject::getBoundFunctionThis() const
 {
     JS_ASSERT(isFunction());
-    JS_ASSERT(getFunctionPrivate()->isBound());
+    JS_ASSERT(isBoundFunction());
 
     return fslots[JSSLOT_BOUND_FUNCTION_THIS];
 }
 
 inline const js::Value *
 JSObject::getBoundFunctionArguments(uintN &argslen) const
 {
     JS_ASSERT(isFunction());
-    JS_ASSERT(getFunctionPrivate()->isBound());
+    JS_ASSERT(isBoundFunction());
 
     argslen = fslots[JSSLOT_BOUND_FUNCTION_ARGS_COUNT].toPrivateUint32();
     JS_ASSERT_IF(argslen > 0, dslots);
     JS_ASSERT_IF(argslen > 0, dslots[-1].toPrivateUint32() >= argslen);
     return &dslots[0];
 }
 
 namespace {
 
 /* ES5 15.3.4.5.1 and 15.3.4.5.2. */
 JSBool
 CallOrConstructBoundFunction(JSContext *cx, uintN argc, Value *vp)
 {
     JSObject *obj = &vp[0].toObject();
     JS_ASSERT(obj->isFunction());
-    JS_ASSERT(obj->getFunctionPrivate()->isBound());
+    JS_ASSERT(obj->isBoundFunction());
 
     LeaveTrace(cx);
 
     bool constructing = IsConstructing(vp);
 
     /* 15.3.4.5.1 step 1, 15.3.4.5.2 step 3. */
     uintN argslen;
     const Value *boundArgs = obj->getBoundFunctionArguments(argslen);
--- a/js/src/jsfun.h
+++ b/js/src/jsfun.h
@@ -167,18 +167,16 @@ struct JSFunction : public JSObject
     bool needsWrapper()      const { return FUN_NULL_CLOSURE(this) && u.i.skipmin != 0; }
     bool isInterpreted()     const { return FUN_INTERPRETED(this); }
     bool isNative()          const { return !FUN_INTERPRETED(this); }
     bool isConstructor()     const { return flags & JSFUN_CONSTRUCTOR; }
     bool isHeavyweight()     const { return JSFUN_HEAVYWEIGHT_TEST(flags); }
 
     inline bool inStrictMode() const;
 
-    bool isBound() const;
-
     uintN countVars() const {
         JS_ASSERT(FUN_INTERPRETED(this));
         return u.i.nvars;
     }
 
     /* uint16 representation bounds number of call object dynamic slots. */
     enum { MAX_ARGS_AND_VARS = 2 * ((1U << 16) - 1) };
 
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -1910,17 +1910,17 @@ IteratorNext(JSContext *cx, JSObject *it
         }
     }
     return js_IteratorNext(cx, iterobj, rval);
 }
 
 
 namespace js {
 
-JS_REQUIRES_STACK bool
+JS_REQUIRES_STACK JS_NEVER_INLINE bool
 Interpret(JSContext *cx, JSStackFrame *entryFrame, uintN inlineCallCount, uintN interpFlags)
 {
 #ifdef MOZ_TRACEVIS
     TraceVisStateObj tvso(cx, S_INTERP);
 #endif
     JSAutoResolveFlags rf(cx, JSRESOLVE_INFER);
 
 # ifdef DEBUG
@@ -2818,17 +2818,17 @@ BEGIN_CASE(JSOP_FORNAME)
         goto error;
     if (prop)
         obj2->dropProperty(cx, prop);
     {
         AutoValueRooter tvr(cx);
         JS_ASSERT(regs.sp[-1].isObject());
         if (!IteratorNext(cx, &regs.sp[-1].toObject(), tvr.addr()))
             goto error;
-        if (!obj->setProperty(cx, id, tvr.addr()))
+        if (!obj->setProperty(cx, id, tvr.addr(), script->strictModeCode))
             goto error;
     }
 }
 END_CASE(JSOP_FORNAME)
 
 BEGIN_CASE(JSOP_FORPROP)
 {
     JS_ASSERT(regs.sp - 2 >= regs.fp->base());
@@ -2837,17 +2837,17 @@ BEGIN_CASE(JSOP_FORPROP)
     jsid id = ATOM_TO_JSID(atom);
     JSObject *obj;
     FETCH_OBJECT(cx, -1, obj);
     {
         AutoValueRooter tvr(cx);
         JS_ASSERT(regs.sp[-2].isObject());
         if (!IteratorNext(cx, &regs.sp[-2].toObject(), tvr.addr()))
             goto error;
-        if (!obj->setProperty(cx, id, tvr.addr()))
+        if (!obj->setProperty(cx, id, tvr.addr(), script->strictModeCode))
             goto error;
     }
     regs.sp--;
 }
 END_CASE(JSOP_FORPROP)
 
 BEGIN_CASE(JSOP_FORELEM)
     /*
@@ -3485,37 +3485,40 @@ BEGIN_CASE(JSOP_DELNAME)
     JSAtom *atom;
     LOAD_ATOM(0, atom);
     jsid id = ATOM_TO_JSID(atom);
     JSObject *obj, *obj2;
     JSProperty *prop;
     if (!js_FindProperty(cx, id, &obj, &obj2, &prop))
         goto error;
 
+    /* Strict mode code should never contain JSOP_DELNAME opcodes. */
+    JS_ASSERT(!script->strictModeCode);
+
     /* ECMA says to return true if name is undefined or inherited. */
     PUSH_BOOLEAN(true);
     if (prop) {
         obj2->dropProperty(cx, prop);
-        if (!obj->deleteProperty(cx, id, &regs.sp[-1]))
+        if (!obj->deleteProperty(cx, id, &regs.sp[-1], false))
             goto error;
     }
 }
 END_CASE(JSOP_DELNAME)
 
 BEGIN_CASE(JSOP_DELPROP)
 {
     JSAtom *atom;
     LOAD_ATOM(0, atom);
     jsid id = ATOM_TO_JSID(atom);
 
     JSObject *obj;
     FETCH_OBJECT(cx, -1, obj);
 
     Value rval;
-    if (!obj->deleteProperty(cx, id, &rval))
+    if (!obj->deleteProperty(cx, id, &rval, script->strictModeCode))
         goto error;
 
     regs.sp[-1] = rval;
 }
 END_CASE(JSOP_DELPROP)
 
 BEGIN_CASE(JSOP_DELELEM)
 {
@@ -3523,17 +3526,17 @@ BEGIN_CASE(JSOP_DELELEM)
     JSObject *obj;
     FETCH_OBJECT(cx, -2, obj);
 
     /* Fetch index and convert it to id suitable for use with obj. */
     jsid id;
     FETCH_ELEMENT_ID(obj, -1, id);
 
     /* Get or set the element. */
-    if (!obj->deleteProperty(cx, id, &regs.sp[-2]))
+    if (!obj->deleteProperty(cx, id, &regs.sp[-2], script->strictModeCode))
         goto error;
 
     regs.sp--;
 }
 END_CASE(JSOP_DELELEM)
 
 BEGIN_CASE(JSOP_TYPEOFEXPR)
 BEGIN_CASE(JSOP_TYPEOF)
@@ -3646,33 +3649,33 @@ do_incop:
     int32_t tmp;
     if (JS_LIKELY(ref.isInt32() && CanIncDecWithoutOverflow(tmp = ref.toInt32()))) {
         int incr = (cs->format & JOF_INC) ? 1 : -1;
         if (cs->format & JOF_POST)
             ref.getInt32Ref() = tmp + incr;
         else
             ref.getInt32Ref() = tmp += incr;
         regs.fp->setAssigning();
-        JSBool ok = obj->setProperty(cx, id, &ref);
+        JSBool ok = obj->setProperty(cx, id, &ref, script->strictModeCode);
         regs.fp->clearAssigning();
         if (!ok)
             goto error;
 
         /*
          * We must set regs.sp[-1] to tmp for both post and pre increments
          * as the setter overwrites regs.sp[-1].
          */
         ref.setInt32(tmp);
     } else {
         /* We need an extra root for the result. */
         PUSH_NULL();
         if (!js_DoIncDec(cx, cs, &regs.sp[-2], &regs.sp[-1]))
             goto error;
         regs.fp->setAssigning();
-        JSBool ok = obj->setProperty(cx, id, &regs.sp[-1]);
+        JSBool ok = obj->setProperty(cx, id, &regs.sp[-1], script->strictModeCode);
         regs.fp->clearAssigning();
         if (!ok)
             goto error;
         regs.sp--;
     }
 
     if (cs->nuses == 0) {
         /* regs.sp[-1] already contains the result of name increment. */
@@ -3738,17 +3741,16 @@ BEGIN_CASE(JSOP_LOCALINC)
   /*
    * do_local_incop comes right before do_int_fast_incop as we want to
    * avoid an extra jump for variable cases as local++ is more frequent
    * than arg++.
    */
   do_local_incop:
     slot = GET_SLOTNO(regs.pc);
     JS_ASSERT(slot < regs.fp->numSlots());
-    vp = regs.fp->slots() + slot;
     METER_SLOT_OP(op, slot);
     vp = regs.fp->slots() + slot;
 
   do_int_fast_incop:
     int32_t tmp;
     if (JS_LIKELY(vp->isInt32() && CanIncDecWithoutOverflow(tmp = vp->toInt32()))) {
         vp->getInt32Ref() = tmp + incr;
         JS_ASSERT(JSOP_INCARG_LENGTH == js_CodeSpec[op].length);
@@ -4168,20 +4170,20 @@ BEGIN_CASE(JSOP_SETMETHOD)
         if (entry && JS_LIKELY(!obj->getOps()->setProperty)) {
             uintN defineHow;
             if (op == JSOP_SETMETHOD)
                 defineHow = JSDNP_CACHE_RESULT | JSDNP_SET_METHOD;
             else if (op == JSOP_SETNAME)
                 defineHow = JSDNP_CACHE_RESULT | JSDNP_UNQUALIFIED;
             else
                 defineHow = JSDNP_CACHE_RESULT;
-            if (!js_SetPropertyHelper(cx, obj, id, defineHow, &rval))
+            if (!js_SetPropertyHelper(cx, obj, id, defineHow, &rval, script->strictModeCode))
                 goto error;
         } else {
-            if (!obj->setProperty(cx, id, &rval))
+            if (!obj->setProperty(cx, id, &rval, script->strictModeCode))
                 goto error;
             ABORT_RECORDING(cx, "Non-native set");
         }
     } while (0);
 }
 END_SET_CASE_STORE_RVAL(JSOP_SETPROP, 2);
 
 BEGIN_CASE(JSOP_GETELEM)
@@ -4304,31 +4306,31 @@ BEGIN_CASE(JSOP_SETELEM)
                         obj->setArrayLength(i + 1);
                 }
                 obj->setDenseArrayElement(i, regs.sp[-1]);
                 goto end_setelem;
             }
         }
     } while (0);
     rval = regs.sp[-1];
-    if (!obj->setProperty(cx, id, &rval))
+    if (!obj->setProperty(cx, id, &rval, script->strictModeCode))
         goto error;
   end_setelem:;
 }
 END_SET_CASE_STORE_RVAL(JSOP_SETELEM, 3)
 
 BEGIN_CASE(JSOP_ENUMELEM)
 {
     /* Funky: the value to set is under the [obj, id] pair. */
     JSObject *obj;
     FETCH_OBJECT(cx, -2, obj);
     jsid id;
     FETCH_ELEMENT_ID(obj, -1, id);
     Value rval = regs.sp[-3];
-    if (!obj->setProperty(cx, id, &rval))
+    if (!obj->setProperty(cx, id, &rval, script->strictModeCode))
         goto error;
     regs.sp -= 3;
 }
 END_CASE(JSOP_ENUMELEM)
 
 {
     JSFunction *newfun;
     JSObject *callee;
@@ -5095,21 +5097,16 @@ BEGIN_CASE(JSOP_SETGLOBAL)
 END_SET_CASE(JSOP_SETGLOBAL)
 
 BEGIN_CASE(JSOP_DEFCONST)
 BEGIN_CASE(JSOP_DEFVAR)
 {
     uint32 index = GET_INDEX(regs.pc);
     JSAtom *atom = atoms[index];
 
-    /*
-     * index is relative to atoms at this point but for global var
-     * code below we need the absolute value.
-     */
-    index += atoms - script->atomMap.vector;
     JSObject *obj = &regs.fp->varobj(cx);
     JS_ASSERT(!obj->getOps()->defineProperty);
     uintN attrs = JSPROP_ENUMERATE;
     if (!regs.fp->isEvalFrame())
         attrs |= JSPROP_PERMANENT;
     if (op == JSOP_DEFCONST)
         attrs |= JSPROP_READONLY;
 
@@ -5249,17 +5246,17 @@ BEGIN_CASE(JSOP_DEFFUN)
             JS_ASSERT(!(attrs & ~(JSPROP_ENUMERATE|JSPROP_PERMANENT)));
             JS_ASSERT(!(old & JSPROP_READONLY));
             doSet = true;
         }
         pobj->dropProperty(cx, prop);
     }
     Value rval = ObjectValue(*obj);
     ok = doSet
-         ? parent->setProperty(cx, id, &rval)
+         ? parent->setProperty(cx, id, &rval, script->strictModeCode)
          : parent->defineProperty(cx, id, rval, PropertyStub, PropertyStub, attrs);
     if (!ok)
         goto error;
 }
 END_CASE(JSOP_DEFFUN)
 
 BEGIN_CASE(JSOP_DEFFUN_FC)
 BEGIN_CASE(JSOP_DEFFUN_DBGFC)
@@ -5281,17 +5278,17 @@ BEGIN_CASE(JSOP_DEFFUN_DBGFC)
 
     JSObject &parent = regs.fp->varobj(cx);
 
     jsid id = ATOM_TO_JSID(fun->atom);
     if (!CheckRedeclaration(cx, &parent, id, attrs, NULL, NULL))
         goto error;
 
     if ((attrs == JSPROP_ENUMERATE)
-        ? !parent.setProperty(cx, id, &rval)
+        ? !parent.setProperty(cx, id, &rval, script->strictModeCode)
         : !parent.defineProperty(cx, id, rval, PropertyStub, PropertyStub, attrs)) {
         goto error;
     }
 }
 END_CASE(JSOP_DEFFUN_FC)
 
 BEGIN_CASE(JSOP_DEFLOCALFUN)
 {
@@ -5743,17 +5740,17 @@ BEGIN_CASE(JSOP_INITMETHOD)
         jsid id = ATOM_TO_JSID(atom);
 
         /* No need to check for duplicate property; the compiler already did. */
 
         uintN defineHow = (op == JSOP_INITMETHOD)
                           ? JSDNP_CACHE_RESULT | JSDNP_SET_METHOD
                           : JSDNP_CACHE_RESULT;
         if (!(JS_UNLIKELY(atom == cx->runtime->atomState.protoAtom)
-              ? js_SetPropertyHelper(cx, obj, id, defineHow, &rval)
+              ? js_SetPropertyHelper(cx, obj, id, defineHow, &rval, script->strictModeCode)
               : js_DefineNativeProperty(cx, obj, id, rval, NULL, NULL,
                                         JSPROP_ENUMERATE, 0, 0, NULL,
                                         defineHow))) {
             goto error;
         }
     }
 
     /* Common tail for property cache hit and miss cases. */
@@ -6140,17 +6137,17 @@ BEGIN_CASE(JSOP_BINDXMLNAME)
 END_CASE(JSOP_BINDXMLNAME)
 
 BEGIN_CASE(JSOP_SETXMLNAME)
 {
     JSObject *obj = &regs.sp[-3].toObject();
     Value rval = regs.sp[-1];
     jsid id;
     FETCH_ELEMENT_ID(obj, -2, id);
-    if (!obj->setProperty(cx, id, &rval))
+    if (!obj->setProperty(cx, id, &rval, script->strictModeCode))
         goto error;
     rval = regs.sp[-1];
     regs.sp -= 2;
     regs.sp[-1] = rval;
 }
 END_CASE(JSOP_SETXMLNAME)
 
 BEGIN_CASE(JSOP_CALLXMLNAME)
--- a/js/src/jsinterp.h
+++ b/js/src/jsinterp.h
@@ -936,17 +936,17 @@ InvokeConstructorWithGivenThis(JSContext
 extern JS_FORCES_STACK bool
 Execute(JSContext *cx, JSObject *chain, JSScript *script,
         JSStackFrame *prev, uintN flags, Value *result);
 
 /*
  * Execute the caller-initialized frame for a user-defined script or function
  * pointed to by cx->fp until completion or error.
  */
-extern JS_REQUIRES_STACK bool
+extern JS_REQUIRES_STACK JS_NEVER_INLINE bool
 Interpret(JSContext *cx, JSStackFrame *stopFp, uintN inlineCallCount = 0, uintN interpFlags = 0);
 
 extern JS_REQUIRES_STACK bool
 RunScript(JSContext *cx, JSScript *script, JSFunction *fun, JSObject &scopeChain);
 
 #define JSPROP_INITIALIZER 0x100   /* NB: Not a valid property attribute. */
 
 extern bool
--- a/js/src/jsnum.cpp
+++ b/js/src/jsnum.cpp
@@ -1027,31 +1027,54 @@ js_InitNumberClass(JSContext *cx, JSObje
     if (!JS_DefineProperty(cx, obj, js_Infinity_str, Jsvalify(rt->positiveInfinityValue),
                            JS_PropertyStub, JS_PropertyStub,
                            JSPROP_PERMANENT | JSPROP_READONLY)) {
         return NULL;
     }
     return proto;
 }
 
+namespace v8 {
+namespace internal {
+extern char* DoubleToCString(double v, char* buffer, int buflen);
+}
+}
+
 namespace js {
 
 static char *
 FracNumberToCString(JSContext *cx, ToCStringBuf *cbuf, jsdouble d, jsint base = 10)
 {
 #ifdef DEBUG
     {
         int32_t _;
         JS_ASSERT(!JSDOUBLE_IS_INT32(d, &_));
     }
 #endif
-    return (base == 10)
-           ? js_dtostr(JS_THREAD_DATA(cx)->dtoaState, cbuf->sbuf, cbuf->sbufSize,
-                       DTOSTR_STANDARD, 0, d)
-           : cbuf->dbuf = js_dtobasestr(JS_THREAD_DATA(cx)->dtoaState, base, d);
+
+    char* numStr;
+    if (base == 10) {
+        /*
+         * This is V8's implementation of the algorithm described in the
+         * following paper:
+         *
+         *   Printing floating-point numbers quickly and accurately with integers. 
+         *   Florian Loitsch, PLDI 2010.
+         *
+         * It fails on a small number of cases, whereupon we fall back to
+         * js_dtostr() (which uses David Gay's dtoa).
+         */
+        numStr = v8::internal::DoubleToCString(d, cbuf->sbuf, cbuf->sbufSize);
+        if (!numStr)
+            numStr = js_dtostr(JS_THREAD_DATA(cx)->dtoaState, cbuf->sbuf, cbuf->sbufSize,
+                               DTOSTR_STANDARD, 0, d);
+    } else {
+        numStr = cbuf->dbuf = js_dtobasestr(JS_THREAD_DATA(cx)->dtoaState, base, d);
+    }
+    return numStr;
 }
 
 char *
 NumberToCString(JSContext *cx, ToCStringBuf *cbuf, jsdouble d, jsint base/* = 10*/)
 {
     int32_t i;
     return (JSDOUBLE_IS_INT32(d, &i))
            ? IntToCString(cbuf, i, base)
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -2838,37 +2838,37 @@ with_LookupProperty(JSContext *cx, JSObj
 
 static JSBool
 with_GetProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp)
 {
     return obj->getProto()->getProperty(cx, id, vp);
 }
 
 static JSBool
-with_SetProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp)
-{
-    return obj->getProto()->setProperty(cx, id, vp);
+with_SetProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp, JSBool strict)
+{
+    return obj->getProto()->setProperty(cx, id, vp, strict);
 }
 
 static JSBool
 with_GetAttributes(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp)
 {
     return obj->getProto()->getAttributes(cx, id, attrsp);
 }
 
 static JSBool
 with_SetAttributes(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp)
 {
     return obj->getProto()->setAttributes(cx, id, attrsp);
 }
 
 static JSBool
-with_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, Value *rval)
-{
-    return obj->getProto()->deleteProperty(cx, id, rval);
+with_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, Value *rval, JSBool strict)
+{
+    return obj->getProto()->deleteProperty(cx, id, rval, strict);
 }
 
 static JSBool
 with_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
                Value *statep, jsid *idp)
 {
     return obj->getProto()->enumerate(cx, enum_op, statep, idp);
 }
@@ -3479,17 +3479,17 @@ js_InitClass(JSContext *cx, JSObject *ob
     if (key != JSProto_Null && !js_SetClassObject(cx, obj, key, ctor, proto))
         goto bad;
 
     return proto;
 
 bad:
     if (named) {
         Value rval;
-        obj->deleteProperty(cx, ATOM_TO_JSID(atom), &rval);
+        obj->deleteProperty(cx, ATOM_TO_JSID(atom), &rval, false);
     }
     return NULL;
 }
 
 bool
 JSObject::allocSlots(JSContext *cx, size_t nslots)
 {
     JS_ASSERT(!dslots);
@@ -3597,17 +3597,17 @@ JSObject::shrinkSlots(JSContext *cx, siz
         dslots[-1].setPrivateUint32(nslots);
     }
 }
 
 bool
 JSObject::ensureInstanceReservedSlots(JSContext *cx, size_t nreserved)
 {
     JS_ASSERT_IF(isNative(),
-                 isBlock() || isCall() || (isFunction() && getFunctionPrivate()->isBound()));
+                 isBlock() || isCall() || (isFunction() && isBoundFunction()));
 
     uintN nslots = JSSLOT_FREE(clasp) + nreserved;
     return nslots <= numSlots() || allocSlots(cx, nslots);
 }
 
 static JSObject *
 js_InitNullClass(JSContext *cx, JSObject *obj)
 {
@@ -4757,35 +4757,41 @@ js_NativeSet(JSContext *cx, JSObject *ob
             return false;
         }
         obj->lockedSetSlot(slot, *vp);
     }
 
     return true;
 }
 
-JSBool
-js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN getHow,
-                     Value *vp)
+static JS_ALWAYS_INLINE bool
+js_GetPropertyHelperWithShapeInline(JSContext *cx, JSObject *obj, jsid id,
+                                    uintN getHow, Value *vp,
+                                    const Shape **shapeOut, JSObject **holderOut)
 {
     JSObject *aobj, *obj2;
     int protoIndex;
     JSProperty *prop;
     const Shape *shape;
 
     JS_ASSERT_IF(getHow & JSGET_CACHE_RESULT, !JS_ON_TRACE(cx));
 
+    *shapeOut = NULL;
+
     /* Convert string indices to integers if appropriate. */
     id = js_CheckForStringIndex(id);
 
     aobj = js_GetProtoIfDenseArray(obj);
     protoIndex = js_LookupPropertyWithFlags(cx, aobj, id, cx->resolveFlags,
                                             &obj2, &prop);
     if (protoIndex < 0)
         return JS_FALSE;
+
+    *holderOut = obj2;
+
     if (!prop) {
         vp->setUndefined();
 
         if (!CallJSPropertyOp(cx, obj->getClass()->getProperty, obj, id, vp))
             return JS_FALSE;
 
         PCMETER(getHow & JSGET_CACHE_RESULT && JS_PROPERTY_CACHE(cx).nofills++);
 
@@ -4841,29 +4847,46 @@ js_GetPropertyHelper(JSContext *cx, JSOb
         }
         return JS_TRUE;
     }
 
     if (!obj2->isNative())
         return obj2->getProperty(cx, id, vp);
 
     shape = (Shape *) prop;
+    *shapeOut = shape;
 
     if (getHow & JSGET_CACHE_RESULT) {
         JS_ASSERT_NOT_ON_TRACE(cx);
         JS_PROPERTY_CACHE(cx).fill(cx, aobj, 0, protoIndex, obj2, shape);
     }
 
     if (!js_NativeGet(cx, obj, obj2, shape, getHow, vp))
         return JS_FALSE;
 
     JS_UNLOCK_OBJ(cx, obj2);
     return JS_TRUE;
 }
 
+extern bool
+js_GetPropertyHelperWithShape(JSContext *cx, JSObject *obj, jsid id,
+                              uint32 getHow, Value *vp,
+                              const Shape **shapeOut, JSObject **holderOut)
+{
+    return js_GetPropertyHelperWithShapeInline(cx, obj, id, getHow, vp, shapeOut, holderOut);
+}
+
+extern JSBool
+js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uint32 getHow, Value *vp)
+{
+    const Shape *shape;
+    JSObject *holder;
+    return js_GetPropertyHelperWithShapeInline(cx, obj, id, getHow, vp, &shape, &holder);
+}
+
 JSBool
 js_GetProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp)
 {
     return js_GetPropertyHelper(cx, obj, id, JSGET_METHOD_BARRIER, vp);
 }
 
 JSBool
 js_GetMethod(JSContext *cx, JSObject *obj, jsid id, uintN getHow, Value *vp)
@@ -4912,26 +4935,34 @@ namespace js {
 JSBool
 ReportReadOnly(JSContext* cx, jsid id, uintN flags)
 {
     return js_ReportValueErrorFlags(cx, flags, JSMSG_READ_ONLY,
                                     JSDVG_IGNORE_STACK, IdToValue(id), NULL,
                                     NULL, NULL);
 }
 
+JSBool
+ReportNotConfigurable(JSContext* cx, jsid id, uintN flags)
+{
+    return js_ReportValueErrorFlags(cx, flags, JSMSG_CANT_DELETE,
+                                    JSDVG_IGNORE_STACK, IdToValue(id), NULL,
+                                    NULL, NULL);
+}
+
 }
 
 /*
  * Note: all non-error exits in this function must notify the tracer using
  * SetPropHit when called from the interpreter, which is detected by testing
  * (defineHow & JSDNP_CACHE_RESULT).
  */
 JSBool
 js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN defineHow,
-                     Value *vp)
+                     Value *vp, JSBool strict)
 {
     int protoIndex;
     JSObject *pobj;
     JSProperty *prop;
     const Shape *shape;
     uintN attrs, flags;
     intN shortid;
     Class *clasp;
@@ -5000,17 +5031,19 @@ js_SetPropertyHelper(JSContext *cx, JSOb
                 JS_UNLOCK_OBJ(cx, pobj);
 
                 PCMETER((defineHow & JSDNP_CACHE_RESULT) && JS_PROPERTY_CACHE(cx).rofills++);
                 if (defineHow & JSDNP_CACHE_RESULT) {
                     JS_ASSERT_NOT_ON_TRACE(cx);
                     TRACE_2(SetPropHit, JS_NO_PROP_CACHE_FILL, shape);
                 }
 
-                /* Warn in strict mode, otherwise do nothing. */
+                /* Error in strict mode code, warn with strict option, otherwise do nothing. */
+                if (strict)
+                    return ReportReadOnly(cx, id, 0);
                 if (JS_HAS_STRICT_OPTION(cx))
                     return ReportReadOnly(cx, id, JSREPORT_STRICT | JSREPORT_WARNING);
                 return JS_TRUE;
 
 #ifdef JS_TRACER
               error: // TRACE_2 jumps here in case of error.
                 return JS_FALSE;
 #endif
@@ -5159,19 +5192,19 @@ js_SetPropertyHelper(JSContext *cx, JSOb
     if (!js_NativeSet(cx, obj, shape, added, vp))
         return NULL;
 
     JS_UNLOCK_OBJ(cx, obj);
     return JS_TRUE;
 }
 
 JSBool
-js_SetProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp)
-{
-    return js_SetPropertyHelper(cx, obj, id, 0, vp);
+js_SetProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp, JSBool strict)
+{
+    return js_SetPropertyHelper(cx, obj, id, 0, vp, strict);
 }
 
 JSBool
 js_GetAttributes(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp)
 {
     JSProperty *prop;
     if (!js_LookupProperty(cx, obj, id, &obj, &prop))
         return false;
@@ -5207,67 +5240,70 @@ js_SetAttributes(JSContext *cx, JSObject
     if (!prop)
         return true;
     return obj->isNative()
            ? js_SetNativeAttributes(cx, obj, (Shape *) prop, *attrsp)
            : obj->setAttributes(cx, id, attrsp);
 }
 
 JSBool
-js_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, Value *rval)
+js_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, Value *rval, JSBool strict)
 {
     JSObject *proto;
     JSProperty *prop;
     const Shape *shape;
     JSBool ok;
 
     rval->setBoolean(true);
 
     /* Convert string indices to integers if appropriate. */
     id = js_CheckForStringIndex(id);
 
     if (!js_LookupProperty(cx, obj, id, &proto, &prop))
-        return JS_FALSE;
+        return false;
     if (!prop || proto != obj) {
         /*
          * If the property was found in a native prototype, check whether it's
          * shared and permanent.  Such a property stands for direct properties
          * in all delegating objects, matching ECMA semantics without bloating
          * each delegating object.
          */
-        if (prop) {
-            if (proto->isNative()) {
-                shape = (Shape *)prop;
-                if (shape->isSharedPermanent())
-                    rval->setBoolean(false);
+        if (prop && proto->isNative()) {
+            shape = (Shape *)prop;
+            if (shape->isSharedPermanent()) {
                 JS_UNLOCK_OBJ(cx, proto);
+                if (strict)
+                    return ReportNotConfigurable(cx, id, 0);
+                rval->setBoolean(false);
+                return true;
             }
-            if (rval->isBoolean() && rval->toBoolean() == false)
-                return JS_TRUE;
+            JS_UNLOCK_OBJ(cx, proto);
         }
 
         /*
          * If no property, or the property comes unshared or impermanent from
          * a prototype, call the class's delProperty hook, passing rval as the
          * result parameter.
          */
         return CallJSPropertyOp(cx, obj->getClass()->delProperty, obj, id, rval);
     }
 
     shape = (Shape *)prop;
     if (!shape->configurable()) {
         JS_UNLOCK_OBJ(cx, obj);
+        if (strict)
+            return ReportNotConfigurable(cx, id, 0);
         rval->setBoolean(false);
-        return JS_TRUE;
+        return true;
     }
 
     /* XXXbe called with obj locked */
     if (!CallJSPropertyOp(cx, obj->getClass()->delProperty, obj, SHAPE_USERID(shape), rval)) {
         JS_UNLOCK_OBJ(cx, obj);
-        return JS_FALSE;
+        return false;
     }
 
     if (obj->containsSlot(shape->slot)) {
         const Value &v = obj->lockedGetSlot(shape->slot);
         GC_POKE(cx, v);
 
         /*
          * Delete is rare enough that we can take the hit of checking for an
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -210,26 +210,26 @@ js_LookupProperty(JSContext *cx, JSObjec
 extern JSBool
 js_DefineProperty(JSContext *cx, JSObject *obj, jsid id, const js::Value *value,
                   js::PropertyOp getter, js::PropertyOp setter, uintN attrs);
 
 extern JSBool
 js_GetProperty(JSContext *cx, JSObject *obj, jsid id, js::Value *vp);
 
 extern JSBool
-js_SetProperty(JSContext *cx, JSObject *obj, jsid id, js::Value *vp);
+js_SetProperty(JSContext *cx, JSObject *obj, jsid id, js::Value *vp, JSBool strict);
 
 extern JSBool
 js_GetAttributes(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp);
 
 extern JSBool
 js_SetAttributes(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp);
 
 extern JSBool
-js_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, js::Value *rval);
+js_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, js::Value *rval, JSBool strict);
 
 extern JS_FRIEND_API(JSBool)
 js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
              js::Value *statep, jsid *idp);
 
 extern JSType
 js_TypeOf(JSContext *cx, JSObject *obj);
 
@@ -316,24 +316,25 @@ struct JSObject {
 
     inline js::Shape **nativeSearch(jsid id, bool adding = false);
     inline const js::Shape *nativeLookup(jsid id);
 
     inline bool nativeContains(jsid id);
     inline bool nativeContains(const js::Shape &shape);
 
     enum {
-        DELEGATE        = 0x01,
-        SYSTEM          = 0x02,
-        SEALED          = 0x04,
-        BRANDED         = 0x08,
-        GENERIC         = 0x10,
-        METHOD_BARRIER  = 0x20,
-        INDEXED         = 0x40,
-        OWN_SHAPE       = 0x80
+        DELEGATE        =  0x01,
+        SYSTEM          =  0x02,
+        SEALED          =  0x04,
+        BRANDED         =  0x08,
+        GENERIC         =  0x10,
+        METHOD_BARRIER  =  0x20,
+        INDEXED         =  0x40,
+        OWN_SHAPE       =  0x80,
+        BOUND_FUNCTION  = 0x100
     };
 
     /*
      * Impose a sane upper bound, originally checked only for dense arrays, on
      * number of slots in an object.
      */
     enum {
         NSLOTS_BITS     = 29,
@@ -383,16 +384,18 @@ struct JSObject {
     uint32 shape() const {
         JS_ASSERT(objShape != JSObjectMap::INVALID_SHAPE);
         return objShape;
     }
 
     bool isDelegate() const     { return !!(flags & DELEGATE); }
     void setDelegate()          { flags |= DELEGATE; }
 
+    bool isBoundFunction() const { return !!(flags & BOUND_FUNCTION); }
+
     static void setDelegateNullSafe(JSObject *obj) {
         if (obj)
             obj->setDelegate();
     }
 
     bool isSystem() const       { return !!(flags & SYSTEM); }
     void setSystem()            { flags |= SYSTEM; }
 
@@ -1037,34 +1040,34 @@ struct JSObject {
         return (op ? op : js_DefineProperty)(cx, this, id, &value, getter, setter, attrs);
     }
 
     JSBool getProperty(JSContext *cx, jsid id, js::Value *vp) {
         js::PropertyIdOp op = getOps()->getProperty;
         return (op ? op : js_GetProperty)(cx, this, id, vp);
     }
 
-    JSBool setProperty(JSContext *cx, jsid id, js::Value *vp) {
-        js::PropertyIdOp op = getOps()->setProperty;
-        return (op ? op : js_SetProperty)(cx, this, id, vp);
+    JSBool setProperty(JSContext *cx, jsid id, js::Value *vp, JSBool strict) {
+        js::StrictPropertyIdOp op = getOps()->setProperty;
+        return (op ? op : js_SetProperty)(cx, this, id, vp, strict);
     }
 
     JSBool getAttributes(JSContext *cx, jsid id, uintN *attrsp) {
         JSAttributesOp op = getOps()->getAttributes;
         return (op ? op : js_GetAttributes)(cx, this, id, attrsp);
     }
 
     JSBool setAttributes(JSContext *cx, jsid id, uintN *attrsp) {
         JSAttributesOp op = getOps()->setAttributes;
         return (op ? op : js_SetAttributes)(cx, this, id, attrsp);
     }
 
-    JSBool deleteProperty(JSContext *cx, jsid id, js::Value *rval) {
-        js::PropertyIdOp op = getOps()->deleteProperty;
-        return (op ? op : js_DeleteProperty)(cx, this, id, rval);
+    JSBool deleteProperty(JSContext *cx, jsid id, js::Value *rval, JSBool strict) {
+        js::StrictPropertyIdOp op = getOps()->deleteProperty;
+        return (op ? op : js_DeleteProperty)(cx, this, id, rval, strict);
     }
 
     JSBool enumerate(JSContext *cx, JSIterateOp iterop, js::Value *statep, jsid *idp) {
         js::NewEnumerateOp op = getOps()->enumerate;
         return (op ? op : js_Enumerate)(cx, this, iterop, statep, idp);
     }
 
     JSType typeOf(JSContext *cx) {
@@ -1525,18 +1528,21 @@ extern JSBool
 js_NativeGet(JSContext *cx, JSObject *obj, JSObject *pobj, const js::Shape *shape, uintN getHow,
              js::Value *vp);
 
 extern JSBool
 js_NativeSet(JSContext *cx, JSObject *obj, const js::Shape *shape, bool added,
              js::Value *vp);
 
 extern JSBool
-js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN getHow,
-                     js::Value *vp);
+js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uint32 getHow, js::Value *vp);
+
+extern bool
+js_GetPropertyHelperWithShape(JSContext *cx, JSObject *obj, jsid id, uint32 getHow,
+                              js::Value *vp, const js::Shape **shapeOut, JSObject **holderOut);
 
 extern JSBool
 js_GetOwnPropertyDescriptor(JSContext *cx, JSObject *obj, jsid id, js::Value *vp);
 
 extern JSBool
 js_GetMethod(JSContext *cx, JSObject *obj, jsid id, uintN getHow, js::Value *vp);
 
 /*
@@ -1545,17 +1551,17 @@ js_GetMethod(JSContext *cx, JSObject *ob
  * an error if one needs to be reported (in particular in all cases
  * when it returns false).
  */
 extern JS_FRIEND_API(bool)
 js_CheckUndeclaredVarAssignment(JSContext *cx, JSString *propname);
 
 extern JSBool
 js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN defineHow,
-                     js::Value *vp);
+                     js::Value *vp, JSBool strict);
 
 /*
  * Change attributes for the given native property. The caller must ensure
  * that obj is locked and this function always unlocks obj on return.
  */
 extern JSBool
 js_SetNativeAttributes(JSContext *cx, JSObject *obj, js::Shape *shape,
                        uintN attrs);
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -117,17 +117,17 @@ JSObject::methodReadBarrier(JSContext *c
     JS_ASSERT(fun == funobj && FUN_NULL_CLOSURE(fun));
 
     funobj = CloneFunctionObject(cx, fun, funobj->getParent());
     if (!funobj)
         return false;
     funobj->setMethodObj(*this);
 
     vp->setObject(*funobj);
-    if (!js_SetPropertyHelper(cx, this, shape.id, 0, vp))
+    if (!js_SetPropertyHelper(cx, this, shape.id, 0, vp, false))
         return false;
 
 #ifdef DEBUG
     if (cx->runtime->functionMeterFilename) {
         JS_FUNCTION_METER(cx, mreadbarrier);
 
         typedef JSRuntime::FunctionCountMap HM;
         HM &h = cx->runtime->methodReadBarrierCountMap;
--- a/js/src/json.cpp
+++ b/js/src/json.cpp
@@ -611,17 +611,17 @@ Walk(JSContext *cx, jsid id, JSObject *h
             if (!GetPropertyNames(cx, obj, JSITER_OWNONLY, props))
                 return false;
 
             for (size_t i = 0, len = props.length(); i < len; i++) {
                 jsid idName = props[i];
                 if (!Walk(cx, idName, obj, reviver, propValue.addr()))
                     return false;
                 if (propValue.value().isUndefined()) {
-                    if (!js_DeleteProperty(cx, obj, idName, propValue.addr()))
+                    if (!js_DeleteProperty(cx, obj, idName, propValue.addr(), false))
                         return false;
                 } else {
                     if (!obj->defineProperty(cx, idName, propValue.value(), NULL, NULL,
                                              JSPROP_ENUMERATE)) {
                         return false;
                     }
                 }
             }
--- a/js/src/jsproxy.cpp
+++ b/js/src/jsproxy.cpp
@@ -115,59 +115,62 @@ JSProxyHandler::get(JSContext *cx, JSObj
     JS_ASSERT(OperationInProgress(cx, proxy));
     AutoPropertyDescriptorRooter desc(cx);
     if (!getPropertyDescriptor(cx, proxy, id, &desc))
         return false;
     if (!desc.obj) {
         vp->setUndefined();
         return true;
     }
-    if (!desc.getter) {
+    if (!desc.getter ||
+        (!(desc.attrs & JSPROP_GETTER) && desc.getter == PropertyStub)) {
         *vp = desc.value;
         return true;
     }
     if (desc.attrs & JSPROP_GETTER) {
         return ExternalGetOrSet(cx, proxy, id, CastAsObjectJsval(desc.getter),
-                                JSACC_READ, 0, 0, vp);
+                                JSACC_READ, 0, NULL, vp);
     }
+    if (!(desc.attrs & JSPROP_SHARED))
+        *vp = desc.value;
     if (desc.attrs & JSPROP_SHORTID)
         id = INT_TO_JSID(desc.shortid);
     return CallJSPropertyOp(cx, desc.getter, proxy, id, vp);
 }
 
 bool
 JSProxyHandler::set(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id, Value *vp)
 {
     JS_ASSERT(OperationInProgress(cx, proxy));
     AutoPropertyDescriptorRooter desc(cx);
     if (!getOwnPropertyDescriptor(cx, proxy, id, &desc))
         return false;
     /* The control-flow here differs from ::get() because of the fall-through case below. */
     if (desc.obj) {
-        if (desc.setter) {
+        if (desc.setter && ((desc.attrs & JSPROP_SETTER) || desc.setter != PropertyStub)) {
             if (desc.attrs & JSPROP_SETTER) {
                 return ExternalGetOrSet(cx, proxy, id, CastAsObjectJsval(desc.setter),
-                                        JSACC_READ, 0, 0, vp);
+                                        JSACC_WRITE, 1, vp, vp);
             }
             if (desc.attrs & JSPROP_SHORTID)
                 id = INT_TO_JSID(desc.shortid);
             return CallJSPropertyOpSetter(cx, desc.setter, proxy, id, vp);
         }
         if (desc.attrs & JSPROP_READONLY)
             return true;
         desc.value = *vp;
         return defineProperty(cx, proxy, id, &desc);
     }
     if (!getPropertyDescriptor(cx, proxy, id, &desc))
         return false;
     if (desc.obj) {
-        if (desc.setter) {
+        if (desc.setter && ((desc.attrs & JSPROP_SETTER) || desc.setter != PropertyStub)) {
             if (desc.attrs & JSPROP_SETTER) {
                 return ExternalGetOrSet(cx, proxy, id, CastAsObjectJsval(desc.setter),
-                                        JSACC_READ, 0, 0, vp);
+                                        JSACC_WRITE, 1, vp, vp);
             }
             if (desc.attrs & JSPROP_SHORTID)
                 id = INT_TO_JSID(desc.shortid);
             return CallJSPropertyOpSetter(cx, desc.setter, proxy, id, vp);
         }
         if (desc.attrs & JSPROP_READONLY)
             return true;
         /* fall through */
@@ -800,16 +803,22 @@ JSProxy::obj_toString(JSContext *cx, JSO
 
 JSString *
 JSProxy::fun_toString(JSContext *cx, JSObject *proxy, uintN indent)
 {
     AutoPendingProxyOperation pending(cx, proxy);
     return proxy->getProxyHandler()->fun_toString(cx, proxy, indent);
 }
 
+static JSObject *
+proxy_innerObject(JSContext *cx, JSObject *obj)
+{
+    return obj->getProxyPrivate().toObjectOrNull();
+}
+
 static JSBool
 proxy_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
                      JSProperty **propp)
 {
     bool found;
     if (!JSProxy::has(cx, obj, id, &found))
         return false;
 
@@ -839,18 +848,19 @@ proxy_DefineProperty(JSContext *cx, JSOb
 
 static JSBool
 proxy_GetProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp)
 {
     return JSProxy::get(cx, obj, obj, id, vp);
 }
 
 static JSBool
-proxy_SetProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp)
+proxy_SetProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp, JSBool strict)
 {
+    // TODO: throwing away strict
     return JSProxy::set(cx, obj, obj, id, vp);
 }
 
 static JSBool
 proxy_GetAttributes(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp)
 {
     AutoPropertyDescriptorRooter desc(cx);
     if (!JSProxy::getOwnPropertyDescriptor(cx, obj, id, &desc))
@@ -866,18 +876,19 @@ proxy_SetAttributes(JSContext *cx, JSObj
     AutoPropertyDescriptorRooter desc(cx);
     if (!JSProxy::getOwnPropertyDescriptor(cx, obj, id, &desc))
         return false;
     desc.attrs = (*attrsp & (~JSPROP_SHORTID));
     return JSProxy::defineProperty(cx, obj, id, &desc);
 }
 
 static JSBool
-proxy_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, Value *rval)
+proxy_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, Value *rval, JSBool strict)
 {
+    // TODO: throwing away strict
     bool deleted;
     if (!JSProxy::delete_(cx, obj, id, &deleted))
         return false;
     rval->setBoolean(deleted);
     return true;
 }
 
 static void
@@ -934,16 +945,56 @@ JS_FRIEND_API(Class) ObjectProxyClass = 
         NULL,       /* enumerate       */
         NULL,       /* typeof          */
         proxy_TraceObject,
         NULL,       /* thisObject      */
         proxy_Finalize, /* clear */
     }
 };
 
+JS_FRIEND_API(Class) OuterWindowProxyClass = {
+    "Proxy",
+    Class::NON_NATIVE | JSCLASS_HAS_RESERVED_SLOTS(2),
+    PropertyStub,   /* addProperty */
+    PropertyStub,   /* delProperty */
+    PropertyStub,   /* getProperty */
+    PropertyStub,   /* setProperty */
+    EnumerateStub,
+    ResolveStub,
+    ConvertStub,
+    NULL,           /* finalize */
+    NULL,           /* reserved0   */
+    NULL,           /* checkAccess */
+    NULL,           /* call        */
+    NULL,           /* construct   */
+    NULL,           /* xdrObject   */
+    NULL,           /* hasInstance */
+    NULL,           /* mark        */
+    {
+        NULL,       /* equality    */
+        NULL,       /* outerObject */
+        proxy_innerObject,
+        NULL,       /* wrappedObject */
+    },
+    {
+        proxy_LookupProperty,
+        proxy_DefineProperty,
+        proxy_GetProperty,
+        proxy_SetProperty,
+        proxy_GetAttributes,
+        proxy_SetAttributes,
+        proxy_DeleteProperty,
+        NULL,       /* enumerate       */
+        NULL,       /* typeof          */
+        proxy_TraceObject,
+        NULL,       /* thisObject      */
+        proxy_Finalize, /* clear */
+    }
+};
+
 JSBool
 proxy_Call(JSContext *cx, uintN argc, Value *vp)
 {
     JSObject *proxy = &JS_CALLEE(cx, vp).toObject();
     JS_ASSERT(proxy->isProxy());
     return JSProxy::call(cx, proxy, argc, vp);
 }
 
@@ -1001,17 +1052,21 @@ JS_FRIEND_API(Class) FunctionProxyClass 
     }
 };
 
 JS_FRIEND_API(JSObject *)
 NewProxyObject(JSContext *cx, JSProxyHandler *handler, const Value &priv, JSObject *proto,
                JSObject *parent, JSObject *call, JSObject *construct)
 {
     bool fun = call || construct;
-    Class *clasp = fun ? &FunctionProxyClass : &ObjectProxyClass;
+    Class *clasp;
+    if (fun)
+        clasp = &FunctionProxyClass;
+    else
+        clasp = handler->isOuterWindow() ? &OuterWindowProxyClass : &ObjectProxyClass;
     JSObject *obj = NewNonFunction<WithProto::Given>(cx, clasp, proto, parent);
     if (!obj || (construct && !obj->ensureInstanceReservedSlots(cx, 0)))
         return NULL;
     obj->setSlot(JSSLOT_PROXY_HANDLER, PrivateValue(handler));
     obj->setSlot(JSSLOT_PROXY_PRIVATE, priv);
     if (fun) {
         obj->setSlot(JSSLOT_PROXY_CALL, call ? ObjectValue(*call) : UndefinedValue());
         if (construct) {
--- a/js/src/jsproxy.h
+++ b/js/src/jsproxy.h
@@ -79,16 +79,20 @@ class JSProxyHandler {
     virtual JS_FRIEND_API(bool) call(JSContext *cx, JSObject *proxy, uintN argc, js::Value *vp);
     virtual JS_FRIEND_API(bool) construct(JSContext *cx, JSObject *proxy,
                                           uintN argc, js::Value *argv, js::Value *rval);
     virtual JS_FRIEND_API(JSString *) obj_toString(JSContext *cx, JSObject *proxy);
     virtual JS_FRIEND_API(JSString *) fun_toString(JSContext *cx, JSObject *proxy, uintN indent);
     virtual JS_FRIEND_API(void) finalize(JSContext *cx, JSObject *proxy);
     virtual JS_FRIEND_API(void) trace(JSTracer *trc, JSObject *proxy);
 
+    virtual bool isOuterWindow() {
+        return false;
+    }
+
     inline void *family() {
         return mFamily;
     }
 };
 
 /* Dispatch point for handlers that executes the appropriate C++ or scripted traps. */
 class JSProxy {
   public:
@@ -125,24 +129,26 @@ class JSProxy {
 const uint32 JSSLOT_PROXY_HANDLER = JSSLOT_PRIVATE + 0;
 const uint32 JSSLOT_PROXY_PRIVATE = JSSLOT_PRIVATE + 1;
 /* Function proxies only. */
 const uint32 JSSLOT_PROXY_CALL = JSSLOT_PRIVATE + 2;
 const uint32 JSSLOT_PROXY_CONSTRUCT = JSSLOT_PRIVATE + 3;
 
 extern JS_FRIEND_API(js::Class) ObjectProxyClass;
 extern JS_FRIEND_API(js::Class) FunctionProxyClass;
+extern JS_FRIEND_API(js::Class) OuterWindowProxyClass;
 extern js::Class CallableObjectClass;
 
 }
 
 inline bool
 JSObject::isObjectProxy() const
 {
-    return getClass() == &js::ObjectProxyClass;
+    return getClass() == &js::ObjectProxyClass ||
+           getClass() == &js::OuterWindowProxyClass;
 }
 
 inline bool
 JSObject::isFunctionProxy() const
 {
     return getClass() == &js::FunctionProxyClass;
 }
 
--- a/js/src/jsprvtd.h
+++ b/js/src/jsprvtd.h
@@ -299,35 +299,16 @@ typedef struct JSDebugHooks {
  * callers should not risk deadlock by nesting or interleaving other lookups
  * or any obj-bearing ops before dropping *propp.
  */
 typedef JSBool
 (* JSLookupPropOp)(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
                    JSProperty **propp);
 
 /*
- * Define obj[id], a direct property of obj named id, having the given initial
- * value, with the specified getter, setter, and attributes.
- */
-typedef JSBool
-(* JSDefinePropOp)(JSContext *cx, JSObject *obj, jsid id, const jsval *value,
-                   JSPropertyOp getter, JSPropertyOp setter, uintN attrs);
-
-/*
- * Get, set, or delete obj[id], returning false on error or exception, true
- * on success.  If getting or setting, the new value is returned in *vp on
- * success.  If deleting without error, *vp will be JSVAL_FALSE if obj[id] is
- * permanent, and JSVAL_TRUE if id named a direct property of obj that was in
- * fact deleted, or if id names no direct property of obj (id could name a
- * prototype property, or no property in obj or its prototype chain).
- */
-typedef JSBool
-(* JSPropertyIdOp)(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
-
-/*
  * Get or set attributes of the property obj[id]. Return false on error or
  * exception, true with current attributes in *attrsp.
  */
 typedef JSBool
 (* JSAttributesOp)(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp);
 
 /*
  * A generic type for functions mapping an object to another object, or null
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -805,17 +805,17 @@ str_enumerate(JSContext *cx, JSObject *o
                                UndefinedValue(), NULL, NULL,
                                JSPROP_PERMANENT | JSPROP_READONLY | JSPROP_SHARED);
 }
 
 static JSBool
 str_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
             JSObject **objp)
 {
-    if (!JSID_IS_INT(id) || (flags & JSRESOLVE_ASSIGNING))
+    if (!JSID_IS_INT(id))
         return JS_TRUE;
 
     JSString *str = obj->getPrimitiveThis().toString();
 
     jsint slot = JSID_TO_INT(id);
     if ((size_t)slot < str->length()) {
         JSString *str1 = JSString::getUnitString(cx, str, size_t(slot));
         if (!str1)
@@ -1636,16 +1636,17 @@ class FlatMatch
     JSString        *patstr;
     const jschar    *pat;
     size_t          patlen;
     int32           match_;
 
     friend class RegExpGuard;
 
   public:
+    FlatMatch() : patstr(NULL) {} /* Old GCC wants this initialization. */
     JSString *pattern() const { return patstr; }
     size_t patternLength() const { return patlen; }
 
     /*
      * @note    The match is -1 when the match is performed successfully,
      *          but no match is found.
      */
     int32 match() const { return match_; }
@@ -1875,17 +1876,17 @@ MatchCallback(JSContext *cx, RegExpStati
             return false;
     }
 
     Value v;
     if (!res->createLastMatch(cx, &v))
         return false;
 
     JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED | JSRESOLVE_ASSIGNING);
-    return !!arrayobj->setProperty(cx, INT_TO_JSID(count), &v);
+    return !!arrayobj->setProperty(cx, INT_TO_JSID(count), &v, false);
 }
 
 static JSBool
 str_match(JSContext *cx, uintN argc, Value *vp)
 {
     JSString *str;
     NORMALIZE_THIS(cx, vp, str);
 
--- a/js/src/jstracer.cpp
+++ b/js/src/jstracer.cpp
@@ -2030,17 +2030,17 @@ public:
 };
 
 static JS_REQUIRES_STACK JS_ALWAYS_INLINE unsigned
 CountStackAndArgs(JSStackFrame *next, Value *stack)
 {
     if (JS_LIKELY(!next->hasOverflowArgs()))
         return (Value *)next - stack;
     size_t nvals = (next->formalArgs() - 2 /* callee, this */) - stack;
-    JS_ASSERT(nvals == ((next->actualArgs() - 2) - stack) + (2 + next->numActualArgs()));
+    JS_ASSERT(nvals == unsigned((next->actualArgs() - 2) - stack) + (2 + next->numActualArgs()));
     return nvals;
 }
 
 static JS_ALWAYS_INLINE uintN
 NumSlotsBeforeFixed(JSStackFrame *fp)
 {
     uintN numArgs = fp->isEvalFrame() ? 0 : Max(fp->numActualArgs(), fp->numFormalArgs());
     return 2 + numArgs + SPECIAL_FRAME_SLOTS;
@@ -2311,16 +2311,17 @@ TraceRecorder::TraceRecorder(JSContext* 
     tracker(),
     nativeFrameTracker(),
     global_dslots(NULL),
     callDepth(anchor ? anchor->calldepth : 0),
     atoms(FrameAtomBase(cx, cx->fp())),
     consts(cx->fp()->script()->constOffset
            ? cx->fp()->script()->consts()->vector
            : NULL),
+    strictModeCode_ins(NULL),
     cfgMerges(&tempAlloc()),
     trashSelf(false),
     whichTreesToTrash(&tempAlloc()),
     guardedShapeTable(cx),
     rval_ins(NULL),
     native_rval_ins(NULL),
     newobj_ins(NULL),
     pendingSpecializedNative(NULL),
@@ -2448,16 +2449,18 @@ TraceRecorder::TraceRecorder(JSContext* 
         addName(lir->insLoad(LIR_ldp, lirbuf->state, offsetof(TracerState, rp), ACCSET_OTHER), "rp");
     InitConst(cx_ins) =
         addName(lir->insLoad(LIR_ldp, lirbuf->state, offsetof(TracerState, cx), ACCSET_OTHER), "cx");
     InitConst(eos_ins) =
         addName(lir->insLoad(LIR_ldp, lirbuf->state, offsetof(TracerState, eos), ACCSET_OTHER), "eos");
     InitConst(eor_ins) =
         addName(lir->insLoad(LIR_ldp, lirbuf->state, offsetof(TracerState, eor), ACCSET_OTHER), "eor");
 
+    strictModeCode_ins = addName(lir->insImmI(cx->fp()->script()->strictModeCode), "strict");
+
 #ifdef DEBUG
     // Need to update these before any stack/rstack loads/stores occur.
     extras[0] = lirbuf->sp;
     extras[1] = lirbuf->rp;
 #endif
 
     /* If we came from exit, we might not have enough global types. */
     if (tree->globalSlots->length() > tree->nGlobalTypes())
@@ -2476,17 +2479,17 @@ TraceRecorder::TraceRecorder(JSContext* 
         LIns* x = lir->insLoad(LIR_ldi, flagptr, 0, ACCSET_OTHER, LOAD_VOLATILE);
         guard(true, lir->insEqI_0(x), snapshot(TIMEOUT_EXIT));
 
         /*
          * Count the number of iterations run by a trace, so that we can blacklist if
          * the trace runs too few iterations to be worthwhile. Do this only if the methodjit
          * is on--otherwise we must try to trace as much as possible.
          */
-        if (JS_HAS_OPTION(cx, JSOPTION_METHODJIT)) {
+        if (cx->methodJitEnabled) {
             LIns* counterPtr = INS_CONSTPTR((void *) &JS_THREAD_DATA(cx)->iterationCounter);
             LIns* counterValue = lir->insLoad(LIR_ldi, counterPtr, 0, ACCSET_OTHER, LOAD_VOLATILE);
             LIns* test =  lir->ins2ImmI(LIR_lti, counterValue, MIN_LOOP_ITERS);
             LIns *branch = lir->insBranch(LIR_jf, test, NULL);
             counterValue = lir->ins2(LIR_addi, counterValue, INS_CONST(1));
             lir->insStore(counterValue, counterPtr, 0, ACCSET_OTHER);
             branch->setTarget(lir->ins0(LIR_label));
         }
@@ -4468,17 +4471,17 @@ ProhibitFlush(JSContext* cx)
             return true;
 #endif
     return false;
 }
 
 static void
 ResetJITImpl(JSContext* cx)
 {
-    if (!(cx->jitEnabled || (cx->options & JSOPTION_METHODJIT)))
+    if (!(cx->traceJitEnabled || cx->methodJitEnabled))
         return;
     TraceMonitor* tm = &JS_TRACE_MONITOR(cx);
     debug_only_print0(LC_TMTracer, "Flushing cache.\n");
     if (tm->recorder) {
         JS_ASSERT_NOT_ON_TRACE(cx);
         AbortRecording(cx, "flush cache");
     }
     if (ProhibitFlush(cx)) {
@@ -6624,17 +6627,17 @@ ExecuteTree(JSContext* cx, TreeFragment*
 
     /* Restore interpreter state. */
     LeaveTree(tm, state, lr);
 
     *lrp = state.innermost;
     bool ok = !(state.builtinStatus & BUILTIN_ERROR);
     JS_ASSERT_IF(cx->throwing, !ok);
 
-    if (JS_HAS_OPTION(cx, JSOPTION_METHODJIT)) {
+    if (cx->methodJitEnabled) {
         if (lr->exitType == LOOP_EXIT && JS_THREAD_DATA(cx)->iterationCounter < MIN_LOOP_ITERS) {
             debug_only_printf(LC_TMTracer, "tree %p executed only %d iterations, blacklisting\n",
                               (void*)f, f->execs);
             Blacklist((jsbytecode *)f->ip);
         }
     }
     return ok;
 }
@@ -7914,27 +7917,30 @@ JS_REQUIRES_STACK Value&
 TraceRecorder::stackval(int n) const
 {
     return cx->regs->sp[n];
 }
 
 JS_REQUIRES_STACK void
 TraceRecorder::updateAtoms()
 {
+    JSScript *script = cx->fp()->script();
     atoms = FrameAtomBase(cx, cx->fp());
-    consts = cx->fp()->hasImacropc() || cx->fp()->script()->constOffset == 0
+    consts = cx->fp()->hasImacropc() || script->constOffset == 0
            ? 0 
-           : cx->fp()->script()->consts()->vector;
+           : script->consts()->vector;
+    strictModeCode_ins = addName(lir->insImmI(script->strictModeCode), "strict");
 }
 
 JS_REQUIRES_STACK void
 TraceRecorder::updateAtoms(JSScript *script)
 {
     atoms = script->atomMap.vector;
     consts = script->constOffset == 0 ? 0 : script->consts()->vector;
+    strictModeCode_ins = addName(lir->insImmI(script->strictModeCode), "strict");
 }
 
 /*
  * Generate LIR to compute the scope chain.
  */
 JS_REQUIRES_STACK LIns*
 TraceRecorder::scopeChain()
 {
@@ -10065,27 +10071,29 @@ TraceRecorder::clearCurrentFrameSlotsFro
     if (fp->isGlobalFrame()) {
         Value *vp = fp->slots() + fp->globalScript()->nfixed;
         Value *vpend = fp->slots() + fp->globalScript()->nslots;
         for (; vp < vpend; ++vp)
             which.set(vp, (LIns*)0);
         return;
     }
 
-    /* For simplicitly, flush 'em all, even non-canonical arg slots. */
-    Value *vp = fp->actualArgs() - 2 /* callee, this */;
-    Value *vpend = fp->formalArgsEnd();
-    for (; vp < vpend; ++vp)
-        which.set(vp, (LIns*)0);
+    if (!fp->isEvalFrame()) {
+        /* For simplicitly, flush 'em all, even non-canonical arg slots. */
+        Value *vp = fp->actualArgs() - 2 /* callee, this */;
+        Value *vpend = fp->formalArgsEnd();
+        for (; vp < vpend; ++vp)
+            which.set(vp, (LIns*)0);
+    }
 
     which.set(fp->addressOfArgs(), (LIns*)0);
     which.set(fp->addressOfScopeChain(), (LIns*)0);
 
-    vp = fp->slots();
-    vpend = fp->slots() + fp->functionScript()->nslots;
+    Value *vp = fp->slots();
+    Value *vpend = fp->slots() + fp->functionScript()->nslots;
     for (; vp < vpend; ++vp)
         which.set(vp, (LIns*)0);
 }
 
 struct BoxArg
 {
     BoxArg(TraceRecorder *tr, ptrdiff_t offset, LIns *base_ins)
         : tr(tr), offset(offset), base_ins(base_ins) {}
@@ -11461,58 +11469,60 @@ TraceRecorder::record_JSOP_NEW()
 
 JS_REQUIRES_STACK AbortableRecordingStatus
 TraceRecorder::record_JSOP_DELNAME()
 {
     return ARECORD_STOP;
 }
 
 JSBool JS_FASTCALL
-DeleteIntKey(JSContext* cx, JSObject* obj, int32 i)
+DeleteIntKey(JSContext* cx, JSObject* obj, int32 i, JSBool strict)
 {
     LeaveTraceIfGlobalObject(cx, obj);
     Value v = BooleanValue(false);
     jsid id = INT_TO_JSID(i);
-    if (!obj->deleteProperty(cx, id, &v))
+    if (!obj->deleteProperty(cx, id, &v, strict))
         SetBuiltinError(cx);
     return v.toBoolean();
 }
-JS_DEFINE_CALLINFO_3(extern, BOOL_FAIL, DeleteIntKey, CONTEXT, OBJECT, INT32, 0, ACCSET_STORE_ANY)
+JS_DEFINE_CALLINFO_4(extern, BOOL_FAIL, DeleteIntKey, CONTEXT, OBJECT, INT32, BOOL,
+                     0, ACCSET_STORE_ANY)
 
 JSBool JS_FASTCALL
-DeleteStrKey(JSContext* cx, JSObject* obj, JSString* str)
+DeleteStrKey(JSContext* cx, JSObject* obj, JSString* str, JSBool strict)
 {
     LeaveTraceIfGlobalObject(cx, obj);
     Value v = BooleanValue(false);
     jsid id;
 
     /*
      * NB: JSOP_DELPROP does not need js_ValueToStringId to atomize, but (see
      * jsatominlines.h) that helper early-returns if the computed property name
      * string is already atomized, and we are *not* on a perf-critical path!
      */
-    if (!js_ValueToStringId(cx, StringValue(str), &id) || !obj->deleteProperty(cx, id, &v))
+    if (!js_ValueToStringId(cx, StringValue(str), &id) || !obj->deleteProperty(cx, id, &v, strict))
         SetBuiltinError(cx);
     return v.toBoolean();
 }
-JS_DEFINE_CALLINFO_3(extern, BOOL_FAIL, DeleteStrKey, CONTEXT, OBJECT, STRING, 0, ACCSET_STORE_ANY)
+JS_DEFINE_CALLINFO_4(extern, BOOL_FAIL, DeleteStrKey, CONTEXT, OBJECT, STRING, BOOL,
+                     0, ACCSET_STORE_ANY)
 
 JS_REQUIRES_STACK AbortableRecordingStatus
 TraceRecorder::record_JSOP_DELPROP()
 {
     Value& lval = stackval(-1);
     if (lval.isPrimitive())
         RETURN_STOP_A("JSOP_DELPROP on primitive base expression");
     if (&lval.toObject() == globalObj)
         RETURN_STOP_A("JSOP_DELPROP on global property");
 
     JSAtom* atom = atoms[GET_INDEX(cx->regs->pc)];
 
     enterDeepBailCall();
-    LIns* args[] = { INS_ATOM(atom), get(&lval), cx_ins };
+    LIns* args[] = { strictModeCode_ins, INS_ATOM(atom), get(&lval), cx_ins };
     LIns* rval_ins = lir->insCall(&DeleteStrKey_ci, args);
 
     LIns* status_ins = lir->insLoad(LIR_ldi,
                                     lirbuf->state,
                                     offsetof(TracerState, builtinStatus), ACCSET_OTHER);
     pendingGuardCondition = lir->insEqI_0(status_ins);
     leaveDeepBailCall();
 
@@ -11529,20 +11539,20 @@ TraceRecorder::record_JSOP_DELELEM()
     if (&lval.toObject() == globalObj)
         RETURN_STOP_A("JSOP_DELELEM on global property");
 
     Value& idx = stackval(-1);
     LIns* rval_ins;
 
     enterDeepBailCall();
     if (hasInt32Repr(idx)) {
-        LIns* args[] = { makeNumberInt32(get(&idx)), get(&lval), cx_ins };
+        LIns* args[] = { strictModeCode_ins, makeNumberInt32(get(&idx)), get(&lval), cx_ins };
         rval_ins = lir->insCall(&DeleteIntKey_ci, args);
     } else if (idx.isString()) {
-        LIns* args[] = { get(&idx), get(&lval), cx_ins };
+        LIns* args[] = { strictModeCode_ins, get(&idx), get(&lval), cx_ins };
         rval_ins = lir->insCall(&DeleteStrKey_ci, args);
     } else {
         RETURN_STOP_A("JSOP_DELELEM on non-int, non-string index");
     }
 
     LIns* status_ins = lir->insLoad(LIR_ldi,
                                     lirbuf->state,
                                     offsetof(TracerState, builtinStatus), ACCSET_OTHER);
@@ -12035,29 +12045,100 @@ RootedStringToId(JSContext* cx, JSString
     JSAtom* atom = js_AtomizeString(cx, name, 0);
     if (!atom)
         return false;
     *namep = ATOM_TO_STRING(atom); /* write back to GC root */
     *idp = ATOM_TO_JSID(atom);
     return true;
 }
 
+static const size_t PIC_TABLE_ENTRY_COUNT = 32;
+
+struct PICTableEntry
+{
+    jsid    id;
+    uint32  shape;
+    uint32  slot;
+};
+
+struct PICTable
+{
+    PICTable() : entryCount(0) {}
+
+    PICTableEntry   entries[PIC_TABLE_ENTRY_COUNT];
+    uint32          entryCount;
+
+    bool scan(uint32 shape, jsid id, uint32 *slotOut) {
+        for (size_t i = 0; i < entryCount; ++i) {
+            PICTableEntry &entry = entries[i];
+            if (entry.shape == shape && entry.id == id) {
+                *slotOut = entry.slot;
+                return true;
+            }
+        }
+        return false;
+    }
+
+    void update(uint32 shape, jsid id, uint32 slot) {
+        if (entryCount >= PIC_TABLE_ENTRY_COUNT)
+            return;
+        PICTableEntry &newEntry = entries[entryCount++];
+        newEntry.shape = shape;
+        newEntry.id = id;
+        newEntry.slot = slot;
+    }
+};
+
 static JSBool FASTCALL
-GetPropertyByName(JSContext* cx, JSObject* obj, JSString** namep, Value* vp)
+GetPropertyByName(JSContext* cx, JSObject* obj, JSString** namep, Value* vp, PICTable *picTable)
 {
     LeaveTraceIfGlobalObject(cx, obj);
 
     jsid id;
-    if (!RootedStringToId(cx, namep, &id) || !obj->getProperty(cx, id, vp)) {
+    if (!RootedStringToId(cx, namep, &id)) {
         SetBuiltinError(cx);
         return false;
     }
+    
+    /* Delegate to the op, if present. */
+    PropertyIdOp op = obj->getOps()->getProperty;
+    if (op) {
+        bool result = op(cx, obj, id, vp);
+        if (!result)
+            SetBuiltinError(cx);
+        return result;
+    }
+
+    /* Try to hit in the cache. */
+    uint32 slot;
+    if (picTable->scan(obj->shape(), id, &slot)) {
+        *vp = obj->getSlot(slot);
+        return cx->tracerState->builtinStatus == 0;
+    }
+
+    const Shape *shape;
+    JSObject *holder;
+    if (!js_GetPropertyHelperWithShape(cx, obj, id, JSGET_METHOD_BARRIER, vp, &shape, &holder)) {
+        SetBuiltinError(cx);
+        return false;
+    }
+
+    /* Only update the table when the object is the holder of the property. */
+    if (obj == holder && shape->hasSlot()) {
+        /*
+         * Note: we insert the non-normalized id into the table so you don't need to
+         * normalize it before hitting in the table (faster lookup).
+         */
+        picTable->update(obj->shape(), id, shape->slot);
+    }
+    
     return cx->tracerState->builtinStatus == 0;
 }
-JS_DEFINE_CALLINFO_4(static, BOOL_FAIL, GetPropertyByName, CONTEXT, OBJECT, STRINGPTR, VALUEPTR,
+JS_DEFINE_CALLINFO_5(static, BOOL_FAIL, GetPropertyByName, CONTEXT, OBJECT, STRINGPTR, VALUEPTR,
+                     PICTABLE,
                      0, ACCSET_STORE_ANY)
 
 // Convert the value in a slot to a string and store the resulting string back
 // in the slot (typically in order to root it).
 JS_REQUIRES_STACK RecordingStatus
 TraceRecorder::primitiveToStringInPlace(Value* vp)
 {
     Value v = *vp;
@@ -12086,17 +12167,19 @@ TraceRecorder::getPropertyByName(LIns* o
     CHECK_STATUS(primitiveToStringInPlace(idvalp));
     enterDeepBailCall();
 
     // Call GetPropertyByName. The vp parameter points to stack because this is
     // what the interpreter currently does. obj and id are rooted on the
     // interpreter stack, but the slot at vp is not a root.
     LIns* vp_ins = addName(lir->insAlloc(sizeof(Value)), "vp");
     LIns* idvalp_ins = addName(addr(idvalp), "idvalp");
-    LIns* args[] = {vp_ins, idvalp_ins, obj_ins, cx_ins};
+    PICTable *picTable = new (traceAlloc()) PICTable();
+    LIns* pic_ins = INS_CONSTPTR(picTable);
+    LIns* args[] = {pic_ins, vp_ins, idvalp_ins, obj_ins, cx_ins};
     LIns* ok_ins = lir->insCall(&GetPropertyByName_ci, args);
 
     // GetPropertyByName can assign to *idvalp, so the tracker has an incorrect
     // entry for that address. Correct it. (If the value in the address is
     // never used again, the usual case, Nanojit will kill this load.)
     // The AccSet could be made more precise with some effort (idvalp_ins may
     // equal 'sp+k'), but it's not worth it because this case is rare.
     tracker.set(idvalp, lir->insLoad(LIR_ldp, idvalp_ins, 0, ACCSET_STACK|ACCSET_OTHER));
@@ -12525,28 +12608,29 @@ TraceRecorder::record_JSOP_GETELEM()
     }
 
     return InjectStatus(getPropertyByIndex(obj_ins, idx_ins, &lval));
 }
 
 /* Functions used by JSOP_SETELEM */
 
 static JSBool FASTCALL
-SetPropertyByName(JSContext* cx, JSObject* obj, JSString** namep, Value* vp)
+SetPropertyByName(JSContext* cx, JSObject* obj, JSString** namep, Value* vp, JSBool strict)
 {
     LeaveTraceIfGlobalObject(cx, obj);
 
     jsid id;
-    if (!RootedStringToId(cx, namep, &id) || !obj->setProperty(cx, id, vp)) {
+    if (!RootedStringToId(cx, namep, &id) || !obj->setProperty(cx, id, vp, strict)) {
         SetBuiltinError(cx);
-        return JS_FALSE;
+        return false;
     }
     return cx->tracerState->builtinStatus == 0;
 }
-JS_DEFINE_CALLINFO_4(static, BOOL_FAIL, SetPropertyByName, CONTEXT, OBJECT, STRINGPTR, VALUEPTR,
+JS_DEFINE_CALLINFO_5(static, BOOL_FAIL, SetPropertyByName, 
+                     CONTEXT, OBJECT, STRINGPTR, VALUEPTR, BOOL,
                      0, ACCSET_STORE_ANY)
 
 static JSBool FASTCALL
 InitPropertyByName(JSContext* cx, JSObject* obj, JSString** namep, ValueArgType arg)
 {
     LeaveTraceIfGlobalObject(cx, obj);
 
     jsid id;
@@ -12571,37 +12655,37 @@ TraceRecorder::initOrSetPropertyByName(L
         LIns* idvalp_ins = addName(addr(idvalp), "idvalp");
         LIns* args[] = {v_ins, idvalp_ins, obj_ins, cx_ins};
         pendingGuardCondition = lir->insCall(&InitPropertyByName_ci, args);
     } else {
         // See note in getPropertyByName about vp.
         LIns* vp_ins = box_value_into_alloc(*rvalp, get(rvalp));
         enterDeepBailCall();
         LIns* idvalp_ins = addName(addr(idvalp), "idvalp");
-        LIns* args[] = {vp_ins, idvalp_ins, obj_ins, cx_ins};
+        LIns* args[] = { strictModeCode_ins, vp_ins, idvalp_ins, obj_ins, cx_ins };
         pendingGuardCondition = lir->insCall(&SetPropertyByName_ci, args);
     }
 
     leaveDeepBailCall();
     return RECORD_CONTINUE;
 }
 
 static JSBool FASTCALL
-SetPropertyByIndex(JSContext* cx, JSObject* obj, int32 index, Value* vp)
+SetPropertyByIndex(JSContext* cx, JSObject* obj, int32 index, Value* vp, JSBool strict)
 {
     LeaveTraceIfGlobalObject(cx, obj);
 
     AutoIdRooter idr(cx);
-    if (!js_Int32ToId(cx, index, idr.addr()) || !obj->setProperty(cx, idr.id(), vp)) {
+    if (!js_Int32ToId(cx, index, idr.addr()) || !obj->setProperty(cx, idr.id(), vp, strict)) {
         SetBuiltinError(cx);
-        return JS_FALSE;
+        return false;
     }
     return cx->tracerState->builtinStatus == 0;
 }
-JS_DEFINE_CALLINFO_4(static, BOOL_FAIL, SetPropertyByIndex, CONTEXT, OBJECT, INT32, VALUEPTR,
+JS_DEFINE_CALLINFO_5(static, BOOL_FAIL, SetPropertyByIndex, CONTEXT, OBJECT, INT32, VALUEPTR, BOOL,
                      0, ACCSET_STORE_ANY)
 
 static JSBool FASTCALL
 InitPropertyByIndex(JSContext* cx, JSObject* obj, int32 index, ValueArgType arg)
 {
     LeaveTraceIfGlobalObject(cx, obj);
 
     AutoIdRooter idr(cx);
@@ -12624,17 +12708,17 @@ TraceRecorder::initOrSetPropertyByIndex(
         LIns* rval_ins = box_value_for_native_call(*rvalp, get(rvalp));
         enterDeepBailCall();
         LIns* args[] = {rval_ins, index_ins, obj_ins, cx_ins};
         pendingGuardCondition = lir->insCall(&InitPropertyByIndex_ci, args);
     } else {
         // See note in getPropertyByName about vp.
         LIns* vp_ins = box_value_into_alloc(*rvalp, get(rvalp));
         enterDeepBailCall();
-        LIns* args[] = {vp_ins, index_ins, obj_ins, cx_ins};
+        LIns* args[] = {strictModeCode_ins, vp_ins, index_ins, obj_ins, cx_ins};
         pendingGuardCondition = lir->insCall(&SetPropertyByIndex_ci, args);
     }
 
     leaveDeepBailCall();
     return RECORD_CONTINUE;
 }
 
 JS_REQUIRES_STACK AbortableRecordingStatus
--- a/js/src/jstracer.h
+++ b/js/src/jstracer.h
@@ -922,16 +922,19 @@ class TraceRecorder
 
     /* The number of interpreted calls entered (and not yet left) since recording began. */
     unsigned                        callDepth;
 
     /* The current atom table, mirroring the interpreter loop's variable of the same name. */
     JSAtom**                        atoms;
     Value*                          consts;
 
+    /* An instruction yielding the current script's strict mode code flag.  */
+    nanojit::LIns*                  strictModeCode_ins;
+
     /* FIXME: Dead, but soon to be used for something or other. */
     Queue<jsbytecode*>              cfgMerges;
 
     /* Indicates whether the current tree should be trashed when the recording session ends. */
     bool                            trashSelf;
 
     /* A list of trees to trash at the end of the recording session. */
     Queue<TreeFragment*>            whichTreesToTrash;
@@ -1463,18 +1466,18 @@ public:
                                   nanojit::LIns *ins4, nanojit::LIns *ins5);
     JS_REQUIRES_STACK void tprint(const char *format, nanojit::LIns *ins1,
                                   nanojit::LIns *ins2, nanojit::LIns *ins3,
                                   nanojit::LIns *ins4, nanojit::LIns *ins5,
                                   nanojit::LIns *ins6);
 #endif
 };
 
-#define TRACING_ENABLED(cx)       ((cx)->jitEnabled)
-#define REGEX_JIT_ENABLED(cx)     ((cx)->jitEnabled || ((cx)->options & JSOPTION_METHODJIT))
+#define TRACING_ENABLED(cx)       ((cx)->traceJitEnabled)
+#define REGEX_JIT_ENABLED(cx)     ((cx)->traceJitEnabled || (cx)->methodJitEnabled)
 #define TRACE_RECORDER(cx)        (JS_TRACE_MONITOR(cx).recorder)
 #define SET_TRACE_RECORDER(cx,tr) (JS_TRACE_MONITOR(cx).recorder = (tr))
 
 #define JSOP_IN_RANGE(op,lo,hi)   (uintN((op) - (lo)) <= uintN((hi) - (lo)))
 #define JSOP_IS_BINARY(op)        JSOP_IN_RANGE(op, JSOP_BITOR, JSOP_MOD)
 #define JSOP_IS_UNARY(op)         JSOP_IN_RANGE(op, JSOP_NEG, JSOP_POS)
 #define JSOP_IS_EQUALITY(op)      JSOP_IN_RANGE(op, JSOP_EQ, JSOP_NE)
 
--- a/js/src/jstypedarray.cpp
+++ b/js/src/jstypedarray.cpp
@@ -530,17 +530,17 @@ class TypedArrayTemplate
                 }
             }
         }
 
         return true;
     }
 
     static JSBool
-    obj_setProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp)
+    obj_setProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp, JSBool strict)
     {
         ThisTypeArray *tarray = ThisTypeArray::fromJSObject(obj);
         JS_ASSERT(tarray);
 
         if (JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom)) {
             vp->setNumber(tarray->length);
             return true;
         }
@@ -615,21 +615,21 @@ class TypedArrayTemplate
     static JSBool
     obj_defineProperty(JSContext *cx, JSObject *obj, jsid id, const Value *v,
                        PropertyOp getter, PropertyOp setter, uintN attrs)
     {
         if (JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom))
             return true;
 
         Value tmp = *v;
-        return obj_setProperty(cx, obj, id, &tmp);
+        return obj_setProperty(cx, obj, id, &tmp, false);
     }
 
     static JSBool
-    obj_deleteProperty(JSContext *cx, JSObject *obj, jsid id, Value *rval)
+    obj_deleteProperty(JSContext *cx, JSObject *obj, jsid id, Value *rval, JSBool strict)
     {
         if (JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom)) {
             rval->setBoolean(false);
             return true;
         }
 
         TypedArray *tarray = TypedArray::fromJSObject(obj);
         JS_ASSERT(tarray);
--- a/js/src/jstypes.h
+++ b/js/src/jstypes.h
@@ -480,18 +480,18 @@ typedef JSUintPtr JSUword;
 **      ...
 **      scriptedGetter = JS_FUNC_TO_DATA_PTR(JSObject *, nativeGetter);
 **      ...
 **      nativeGetter = JS_DATA_TO_FUNC_PTR(JSPropertyOp, scriptedGetter);
 **
 ***********************************************************************/
 
 #ifdef __GNUC__
-# define JS_FUNC_TO_DATA_PTR(type, fun) (__extension__ (type) (fun))
-# define JS_DATA_TO_FUNC_PTR(type, ptr) (__extension__ (type) (ptr))
+# define JS_FUNC_TO_DATA_PTR(type, fun) (__extension__ (type) (size_t) (fun))
+# define JS_DATA_TO_FUNC_PTR(type, ptr) (__extension__ (type) (size_t) (ptr))
 #else
 /* Use an extra (void *) cast for MSVC. */
 # define JS_FUNC_TO_DATA_PTR(type, fun) ((type) (void *) (fun))
 # define JS_DATA_TO_FUNC_PTR(type, ptr) ((type) (void *) (ptr))
 #endif
 
 #ifdef __GNUC__
 # define JS_EXTENSION __extension__
--- a/js/src/jsvalue.h
+++ b/js/src/jsvalue.h
@@ -873,36 +873,34 @@ typedef JSBool
 typedef JSBool
 (* EqualityOp)(JSContext *cx, JSObject *obj, const Value *v, JSBool *bp);
 typedef JSBool
 (* DefinePropOp)(JSContext *cx, JSObject *obj, jsid id, const Value *value,
                  PropertyOp getter, PropertyOp setter, uintN attrs);
 typedef JSBool
 (* PropertyIdOp)(JSContext *cx, JSObject *obj, jsid id, Value *vp);
 typedef JSBool
+(* StrictPropertyIdOp)(JSContext *cx, JSObject *obj, jsid id, Value *vp, JSBool strict);
+typedef JSBool
 (* CallOp)(JSContext *cx, uintN argc, Value *vp);
 
 static inline Native            Valueify(JSNative f)          { return (Native)f; }
 static inline JSNative          Jsvalify(Native f)            { return (JSNative)f; }
 static inline PropertyOp        Valueify(JSPropertyOp f)      { return (PropertyOp)f; }
 static inline JSPropertyOp      Jsvalify(PropertyOp f)        { return (JSPropertyOp)f; }
 static inline ConvertOp         Valueify(JSConvertOp f)       { return (ConvertOp)f; }
 static inline JSConvertOp       Jsvalify(ConvertOp f)         { return (JSConvertOp)f; }
 static inline NewEnumerateOp    Valueify(JSNewEnumerateOp f)  { return (NewEnumerateOp)f; }
 static inline JSNewEnumerateOp  Jsvalify(NewEnumerateOp f)    { return (JSNewEnumerateOp)f; }
 static inline HasInstanceOp     Valueify(JSHasInstanceOp f)   { return (HasInstanceOp)f; }
 static inline JSHasInstanceOp   Jsvalify(HasInstanceOp f)     { return (JSHasInstanceOp)f; }
 static inline CheckAccessOp     Valueify(JSCheckAccessOp f)   { return (CheckAccessOp)f; }
 static inline JSCheckAccessOp   Jsvalify(CheckAccessOp f)     { return (JSCheckAccessOp)f; }
 static inline EqualityOp        Valueify(JSEqualityOp f);     /* Same type as JSHasInstanceOp */
 static inline JSEqualityOp      Jsvalify(EqualityOp f);       /* Same type as HasInstanceOp */
-static inline DefinePropOp      Valueify(JSDefinePropOp f)    { return (DefinePropOp)f; }
-static inline JSDefinePropOp    Jsvalify(DefinePropOp f)      { return (JSDefinePropOp)f; }
-static inline PropertyIdOp      Valueify(JSPropertyIdOp f);   /* Same type as JSPropertyOp */
-static inline JSPropertyIdOp    Jsvalify(PropertyIdOp f);     /* Same type as PropertyOp */
 
 static const PropertyOp    PropertyStub  = (PropertyOp)JS_PropertyStub;
 static const JSEnumerateOp EnumerateStub = JS_EnumerateStub;
 static const JSResolveOp   ResolveStub   = JS_ResolveStub;
 static const ConvertOp     ConvertStub   = (ConvertOp)JS_ConvertStub;
 static const JSFinalizeOp  FinalizeStub  = JS_FinalizeStub;
 
 #define JS_CLASS_MEMBERS                                                      \
@@ -944,28 +942,28 @@ struct ClassExtension {
     JSIteratorOp        iteratorObject;
     JSObjectOp          wrappedObject;  /* NB: infallible, null returns are
                                            treated as the original object */
 };
 
 #define JS_NULL_CLASS_EXT   {NULL,NULL,NULL,NULL,NULL}
 
 struct ObjectOps {
-    JSLookupPropOp      lookupProperty;
-    js::DefinePropOp    defineProperty;
-    js::PropertyIdOp    getProperty;
-    js::PropertyIdOp    setProperty;
-    JSAttributesOp      getAttributes;
-    JSAttributesOp      setAttributes;
-    js::PropertyIdOp    deleteProperty;
-    js::NewEnumerateOp  enumerate;
-    JSTypeOfOp          typeOf;
-    JSTraceOp           trace;
-    JSObjectOp          thisObject;
-    JSFinalizeOp        clear;
+    JSLookupPropOp          lookupProperty;
+    js::DefinePropOp        defineProperty;
+    js::PropertyIdOp        getProperty;
+    js::StrictPropertyIdOp  setProperty;
+    JSAttributesOp          getAttributes;
+    JSAttributesOp          setAttributes;
+    js::StrictPropertyIdOp  deleteProperty;
+    js::NewEnumerateOp      enumerate;
+    JSTypeOfOp              typeOf;
+    JSTraceOp               trace;
+    JSObjectOp              thisObject;
+    JSFinalizeOp            clear;
 };
 
 #define JS_NULL_OBJECT_OPS  {NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL}
 
 struct Class {
     JS_CLASS_MEMBERS;
     ClassExtension      ext;
     ObjectOps           ops;
--- a/js/src/jswrapper.cpp
+++ b/js/src/jswrapper.cpp
@@ -282,17 +282,18 @@ JSWrapper::New(JSContext *cx, JSObject *
 
 /* Compartments. */
 
 namespace js {
 
 extern JSObject *
 TransparentObjectWrapper(JSContext *cx, JSObject *obj, JSObject *wrappedProto, uintN flags)
 {
-    JS_ASSERT(!obj->isWrapper());
+    // Allow wrapping outer window proxies.
+    JS_ASSERT(!obj->isWrapper() || obj->getClass()->ext.innerObject);
     return JSWrapper::New(cx, obj, wrappedProto, NULL, &JSCrossCompartmentWrapper::singleton);
 }
 
 }
 
 JSCompartment::JSCompartment(JSRuntime *rt)
   : rt(rt), principals(NULL), data(NULL), marked(false), debugMode(false)
 {
@@ -323,18 +324,32 @@ JSCompartment::wrap(JSContext *cx, Value
         return true;
 
     /* Static strings do not have to be wrapped. */
     if (vp->isString() && JSString::isStatic(vp->toString()))
         return true;
 
     /* Unwrap incoming objects. */
     if (vp->isObject()) {
-        JSObject *obj = vp->toObject().unwrap(&flags);
-        vp->setObject(*obj);
+        JSObject *obj = &vp->toObject();
+
+        /* If the object is already in this compartment, we are done. */
+        if (obj->getCompartment(cx) == this)
+            return true;
+
+        /* Don't unwrap an outer window proxy. */
+        if (!obj->getClass()->ext.innerObject) {
+            obj = vp->toObject().unwrap(&flags);
+            OBJ_TO_OUTER_OBJECT(cx, obj);
+            if (!obj)
+                return false;
+
+            vp->setObject(*obj);
+        }
+
         /* If the wrapped object is already in this compartment, we are done. */
         if (obj->getCompartment(cx) == this)
             return true;
     }
 
     /* If we already have a wrapper for this value, use it. */
     if (WrapperMap::Ptr p = crossCompartmentWrappers.lookup(*vp)) {
         *vp = p->value;
@@ -382,18 +397,26 @@ JSCompartment::wrap(JSContext *cx, Value
 
     /*
      * Wrappers should really be parented to the wrapped parent of the wrapped
      * object, but in that case a wrapped global object would have a NULL
      * parent without being a proper global object (JSCLASS_IS_GLOBAL). Instead,
      * we parent all wrappers to the global object in their home compartment.
      * This loses us some transparency, and is generally very cheesy.
      */
-    JSObject *global =
-        cx->hasfp() ? cx->fp()->scopeChain().getGlobal() : cx->globalObject;
+    JSObject *global;
+    if (cx->hasfp()) {
+        global = cx->fp()->scopeChain().getGlobal();
+    } else {
+        global = cx->globalObject;
+        OBJ_TO_INNER_OBJECT(cx, global);
+        if (!global)
+            return false;
+    }
+
     wrapper->setParent(global);
     return true;
 }
 
 bool
 JSCompartment::wrap(JSContext *cx, JSString **strp)
 {
     AutoValueRooter tvr(cx, StringValue(*strp));
--- a/js/src/jsxml.cpp
+++ b/js/src/jsxml.cpp
@@ -4140,17 +4140,17 @@ PutProperty(JSContext *cx, JSObject *obj
     } else {
         /*
          * ECMA-357 9.2.1.2/9.1.1.2 qname case.
          */
         nameqn = ToXMLName(cx, IdToJsval(id), &funid);
         if (!nameqn)
             goto bad;
         if (!JSID_IS_VOID(funid)) {
-            ok = js_SetProperty(cx, obj, funid, Valueify(vp));
+            ok = js_SetProperty(cx, obj, funid, Valueify(vp), false);
             goto out;
         }
         nameobj = nameqn;
         roots[ID_ROOT] = OBJECT_TO_JSVAL(nameobj);
 
         if (xml->xml_class == JSXML_CLASS_LIST) {
             /*
              * Step 3 of 9.2.1.2.
@@ -4724,17 +4724,17 @@ xml_getProperty(JSContext *cx, JSObject 
         vp->setUndefined();
         return JS_TRUE;
     }
 
     return GetProperty(cx, obj, id, Jsvalify(vp));
 }
 
 static JSBool
-xml_setProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp)
+xml_setProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp, JSBool strict)
 {
     return PutProperty(cx, obj, id, Jsvalify(vp));
 }
 
 static JSBool
 xml_getAttributes(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp)
 {
     JSBool found;
@@ -4756,58 +4756,58 @@ xml_setAttributes(JSContext *cx, JSObjec
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
                              JSMSG_CANT_SET_XML_ATTRS);
         return false;
     }
     return true;
 }
 
 static JSBool
-xml_deleteProperty(JSContext *cx, JSObject *obj, jsid id, Value *rval)
+xml_deleteProperty(JSContext *cx, JSObject *obj, jsid id, Value *rval, JSBool strict)
 {
     JSXML *xml;
     jsval idval;
     uint32 index;
     JSObject *nameqn;
     jsid funid;
 
     idval = IdToJsval(id);
     xml = (JSXML *) obj->getPrivate();
     if (js_IdIsIndex(id, &index)) {
         if (xml->xml_class != JSXML_CLASS_LIST) {
             /* See NOTE in spec: this variation is reserved for future use. */
             ReportBadXMLName(cx, IdToValue(id));
-            return JS_FALSE;
+            return false;
         }
 
         /* ECMA-357 9.2.1.3. */
         DeleteListElement(cx, xml, index);
     } else {
         nameqn = ToXMLName(cx, idval, &funid);
         if (!nameqn)
-            return JS_FALSE;
+            return false;
         if (!JSID_IS_VOID(funid))
-            return js_DeleteProperty(cx, obj, funid, rval);
+            return js_DeleteProperty(cx, obj, funid, rval, false);
 
         DeleteNamedProperty(cx, xml, nameqn,
                             nameqn->getClass() == &js_AttributeNameClass);
     }
 
     /*
      * If this object has its own (mutable) scope,  then we may have added a
      * property to the scope in xml_lookupProperty for it to return to mean
      * "found" and to provide a handle for access operations to call the
      * property's getter or setter. But now it's time to remove any such
      * property, to purge the property cache and remove the scope entry.
      */
-    if (!obj->nativeEmpty() && !js_DeleteProperty(cx, obj, id, rval))
-        return JS_FALSE;
+    if (!obj->nativeEmpty() && !js_DeleteProperty(cx, obj, id, rval, false))
+        return false;
 
     rval->setBoolean(true);
-    return JS_TRUE;
+    return true;
 }
 
 JSBool
 xml_convert(JSContext *cx, JSObject *obj, JSType type, Value *rval)
 {
     return js_TryMethod(cx, obj, cx->runtime->atomState.toStringAtom, 0, NULL, rval);
 }
 
@@ -5733,17 +5733,17 @@ NamespacesToJSArray(JSContext *cx, JSXML
     *rval = OBJECT_TO_JSVAL(arrayobj);
 
     AutoValueRooter tvr(cx);
     for (uint32 i = 0, n = array->length; i < n; i++) {
         JSObject *ns = XMLARRAY_MEMBER(array, i, JSObject);
         if (!ns)
             continue;
         tvr.set(ObjectValue(*ns));
-        if (!arrayobj->setProperty(cx, INT_TO_JSID(i), tvr.addr()))
+        if (!arrayobj->setProperty(cx, INT_TO_JSID(i), tvr.addr(), false))
             return false;
     }
     return true;
 }
 
 static JSBool
 xml_inScopeNamespaces(JSContext *cx, uintN argc, jsval *vp)
 {
--- a/js/src/methodjit/Compiler.cpp
+++ b/js/src/methodjit/Compiler.cpp
@@ -82,17 +82,17 @@ mjit::Compiler::Compiler(JSContext *cx, 
 #if defined JS_POLYIC
     pics(ContextAllocPolicy(cx)), 
 #endif
     callSites(ContextAllocPolicy(cx)), 
     doubleList(ContextAllocPolicy(cx)),
     escapingList(ContextAllocPolicy(cx)),
     stubcc(cx, *this, frame, script)
 #if defined JS_TRACER
-    ,addTraceHints(cx->jitEnabled)
+    ,addTraceHints(cx->traceJitEnabled)
 #endif
 {
 }
 
 #define CHECK_STATUS(expr)              \
     JS_BEGIN_MACRO                      \
         CompileStatus status_ = (expr); \
         if (status_ != Compile_Okay)    \
@@ -469,16 +469,17 @@ mjit::Compiler::finishThisUp()
         JS_ASSERT(script->callICs[i].slowJoinOffset == offset);
 
         /* Compute the join point offset for continuing on the hot path. */
         offset = stubCode.locationOf(callICs[i].hotPathLabel) -
                  stubCode.locationOf(callICs[i].funGuard);
         script->callICs[i].hotPathOffset = offset;
         JS_ASSERT(script->callICs[i].hotPathOffset == offset);
 
+        script->callICs[i].pc = callICs[i].pc;
         script->callICs[i].argc = callICs[i].argc;
         script->callICs[i].funObjReg = callICs[i].funObjReg;
         script->callICs[i].funPtrReg = callICs[i].funPtrReg;
         script->callICs[i].frameDepth = callICs[i].frameDepth;
     }
 #endif /* JS_MONOIC */
 
 #if defined JS_POLYIC
@@ -879,100 +880,132 @@ mjit::Compiler::generateMethod()
             }
           }
           END_CASE(JSOP_NEG)
 
           BEGIN_CASE(JSOP_POS)
             jsop_pos();
           END_CASE(JSOP_POS)
 
+          BEGIN_CASE(JSOP_DELNAME)
+          {
+            uint32 index = fullAtomIndex(PC);
+            JSAtom *atom = script->getAtom(index);
+
+            prepareStubCall(Uses(0));
+            masm.move(ImmPtr(atom), Registers::ArgReg1);
+            stubCall(stubs::DelName);
+            frame.pushSynced();
+          }
+          END_CASE(JSOP_DELNAME)
+
+          BEGIN_CASE(JSOP_DELPROP)
+          {
+            uint32 index = fullAtomIndex(PC);
+            JSAtom *atom = script->getAtom(index);
+
+            prepareStubCall(Uses(1));
+            masm.move(ImmPtr(atom), Registers::ArgReg1);
+            stubCall(STRICT_VARIANT(stubs::DelProp));
+            frame.pop();
+            frame.pushSynced();
+          }
+          END_CASE(JSOP_DELPROP) 
+
+          BEGIN_CASE(JSOP_DELELEM)
+            prepareStubCall(Uses(2));
+            stubCall(STRICT_VARIANT(stubs::DelElem));
+            frame.popn(2);
+            frame.pushSynced();
+          END_CASE(JSOP_DELELEM)
+
           BEGIN_CASE(JSOP_TYPEOF)
           BEGIN_CASE(JSOP_TYPEOFEXPR)
             jsop_typeof();
           END_CASE(JSOP_TYPEOF)
 
           BEGIN_CASE(JSOP_VOID)
             frame.pop();
             frame.push(UndefinedValue());
           END_CASE(JSOP_VOID)
 
           BEGIN_CASE(JSOP_INCNAME)
-            jsop_nameinc(op, stubs::IncName, fullAtomIndex(PC));
+            jsop_nameinc(op, STRICT_VARIANT(stubs::IncName), fullAtomIndex(PC));
             break;
           END_CASE(JSOP_INCNAME)
 
           BEGIN_CASE(JSOP_INCGNAME)
-            jsop_gnameinc(op, stubs::IncGlobalName, fullAtomIndex(PC));
+            jsop_gnameinc(op, STRICT_VARIANT(stubs::IncGlobalName), fullAtomIndex(PC));
             break;
           END_CASE(JSOP_INCGNAME)
 
           BEGIN_CASE(JSOP_INCPROP)
-            jsop_propinc(op, stubs::IncProp, fullAtomIndex(PC));
+            jsop_propinc(op, STRICT_VARIANT(stubs::IncProp), fullAtomIndex(PC));
             break;
           END_CASE(JSOP_INCPROP)
 
           BEGIN_CASE(JSOP_INCELEM)
-            jsop_eleminc(op, stubs::IncElem);
+            jsop_eleminc(op, STRICT_VARIANT(stubs::IncElem));
           END_CASE(JSOP_INCELEM)
 
           BEGIN_CASE(JSOP_DECNAME)
-            jsop_nameinc(op, stubs::DecName, fullAtomIndex(PC));
+            jsop_nameinc(op, STRICT_VARIANT(stubs::DecName), fullAtomIndex(PC));
             break;
           END_CASE(JSOP_DECNAME)
 
           BEGIN_CASE(JSOP_DECGNAME)
-            jsop_gnameinc(op, stubs::DecGlobalName, fullAtomIndex(PC));
+            jsop_gnameinc(op, STRICT_VARIANT(stubs::DecGlobalName), fullAtomIndex(PC));
             break;
           END_CASE(JSOP_DECGNAME)
 
           BEGIN_CASE(JSOP_DECPROP)
-            jsop_propinc(op, stubs::DecProp, fullAtomIndex(PC));
+            jsop_propinc(op, STRICT_VARIANT(stubs::DecProp), fullAtomIndex(PC));
             break;
           END_CASE(JSOP_DECPROP)
 
           BEGIN_CASE(JSOP_DECELEM)
-            jsop_eleminc(op, stubs::DecElem);
+            jsop_eleminc(op, STRICT_VARIANT(stubs::DecElem));
           END_CASE(JSOP_DECELEM)
 
           BEGIN_CASE(JSOP_NAMEINC)
-            jsop_nameinc(op, stubs::NameInc, fullAtomIndex(PC));
+            jsop_nameinc(op, STRICT_VARIANT(stubs::NameInc), fullAtomIndex(PC));
             break;
           END_CASE(JSOP_NAMEINC)
 
           BEGIN_CASE(JSOP_GNAMEINC)
-            jsop_gnameinc(op, stubs::GlobalNameInc, fullAtomIndex(PC));
+            jsop_gnameinc(op, STRICT_VARIANT(stubs::GlobalNameInc), fullAtomIndex(PC));
             break;
           END_CASE(JSOP_GNAMEINC)
 
           BEGIN_CASE(JSOP_PROPINC)
-            jsop_propinc(op, stubs::PropInc, fullAtomIndex(PC));
+            jsop_propinc(op, STRICT_VARIANT(stubs::PropInc), fullAtomIndex(PC));
             break;
           END_CASE(JSOP_PROPINC)
 
           BEGIN_CASE(JSOP_ELEMINC)
-            jsop_eleminc(op, stubs::ElemInc);
+            jsop_eleminc(op, STRICT_VARIANT(stubs::ElemInc));
           END_CASE(JSOP_ELEMINC)
 
           BEGIN_CASE(JSOP_NAMEDEC)
-            jsop_nameinc(op, stubs::NameDec, fullAtomIndex(PC));
+            jsop_nameinc(op, STRICT_VARIANT(stubs::NameDec), fullAtomIndex(PC));
             break;
           END_CASE(JSOP_NAMEDEC)
 
           BEGIN_CASE(JSOP_GNAMEDEC)
-            jsop_gnameinc(op, stubs::GlobalNameDec, fullAtomIndex(PC));
+            jsop_gnameinc(op, STRICT_VARIANT(stubs::GlobalNameDec), fullAtomIndex(PC));
             break;
           END_CASE(JSOP_GNAMEDEC)
 
           BEGIN_CASE(JSOP_PROPDEC)
-            jsop_propinc(op, stubs::PropDec, fullAtomIndex(PC));
+            jsop_propinc(op, STRICT_VARIANT(stubs::PropDec), fullAtomIndex(PC));
             break;
           END_CASE(JSOP_PROPDEC)
 
           BEGIN_CASE(JSOP_ELEMDEC)
-            jsop_eleminc(op, stubs::ElemDec);
+            jsop_eleminc(op, STRICT_VARIANT(stubs::ElemDec));
           END_CASE(JSOP_ELEMDEC)
 
           BEGIN_CASE(JSOP_GETTHISPROP)
             /* Push thisv onto stack. */
             jsop_this();
             jsop_getprop(script->getAtom(fullAtomIndex(PC)));
           END_CASE(JSOP_GETTHISPROP);
 
@@ -1243,17 +1276,17 @@ mjit::Compiler::generateMethod()
                 PC += JSOP_POP_LENGTH;
             break;
           }
           END_CASE(JSOP_ARGDEC)
 
           BEGIN_CASE(JSOP_FORNAME)
             prepareStubCall(Uses(1));
             masm.move(ImmPtr(script->getAtom(fullAtomIndex(PC))), Registers::ArgReg1);
-            stubCall(stubs::ForName);
+            stubCall(STRICT_VARIANT(stubs::ForName));
           END_CASE(JSOP_FORNAME)
 
           BEGIN_CASE(JSOP_INCLOCAL)
           BEGIN_CASE(JSOP_DECLOCAL)
           BEGIN_CASE(JSOP_LOCALINC)
           BEGIN_CASE(JSOP_LOCALDEC)
           {
             jsbytecode *next = &PC[JSOP_LOCALINC_LENGTH];
@@ -1283,16 +1316,24 @@ mjit::Compiler::generateMethod()
           END_CASE(JSOP_SETNAME)
 
           BEGIN_CASE(JSOP_THROW)
             prepareStubCall(Uses(1));
             stubCall(stubs::Throw);
             frame.pop();
           END_CASE(JSOP_THROW)
 
+          BEGIN_CASE(JSOP_IN)
+            prepareStubCall(Uses(2));
+            stubCall(stubs::In);
+            frame.popn(2);
+            frame.takeReg(Registers::ReturnReg);
+            frame.pushTypedPayload(JSVAL_TYPE_BOOLEAN, Registers::ReturnReg);
+          END_CASE(JSOP_IN)
+
           BEGIN_CASE(JSOP_INSTANCEOF)
             jsop_instanceof();
           END_CASE(JSOP_INSTANCEOF)
 
           BEGIN_CASE(JSOP_EXCEPTION)
           {
             JS_STATIC_ASSERT(sizeof(cx->throwing) == 4);
             RegisterID reg = frame.allocReg();
@@ -1303,33 +1344,48 @@ mjit::Compiler::generateMethod()
             frame.freeReg(reg);
             frame.push(excn);
           }
           END_CASE(JSOP_EXCEPTION)
 
           BEGIN_CASE(JSOP_LINENO)
           END_CASE(JSOP_LINENO)
 
+          BEGIN_CASE(JSOP_CONDSWITCH)
+            /* No-op for the decompiler. */
+          END_CASE(JSOP_CONDSWITCH)
+
           BEGIN_CASE(JSOP_DEFFUN)
           {
             uint32 index = fullAtomIndex(PC);
             JSFunction *inner = script->getFunction(index);
 
             if (fun) {
                 JSLocalKind localKind = fun->lookupLocal(cx, inner->atom, NULL);
                 if (localKind != JSLOCAL_NONE)
                     frame.forgetEverything();
             }
 
             prepareStubCall(Uses(0));
             masm.move(ImmPtr(inner), Registers::ArgReg1);
-            stubCall(stubs::DefFun);
+            stubCall(STRICT_VARIANT(stubs::DefFun));
           }
           END_CASE(JSOP_DEFFUN)
 
+          BEGIN_CASE(JSOP_DEFVAR)
+          {
+            uint32 index = fullAtomIndex(PC);
+            JSAtom *atom = script->getAtom(index);
+
+            prepareStubCall(Uses(0));
+            masm.move(ImmPtr(atom), Registers::ArgReg1);
+            stubCall(stubs::DefVar);
+          }
+          END_CASE(JSOP_DEFVAR)
+
           BEGIN_CASE(JSOP_DEFLOCALFUN_FC)
           {
             uint32 slot = GET_SLOTNO(PC);
             JSFunction *fun = script->getFunction(fullAtomIndex(&PC[SLOTNO_LEN]));
             prepareStubCall(Uses(frame.frameDepth()));
             masm.move(ImmPtr(fun), Registers::ArgReg1);
             stubCall(stubs::DefLocalFun_FC);
             frame.takeReg(Registers::ReturnReg);
@@ -1533,16 +1589,20 @@ mjit::Compiler::generateMethod()
             masm.move(Imm32(len), Registers::ArgReg1);
             stubCall(stubs::NewArray);
             frame.popn(len);
             frame.takeReg(Registers::ReturnReg);
             frame.pushTypedPayload(JSVAL_TYPE_OBJECT, Registers::ReturnReg);
           }
           END_CASE(JSOP_NEWARRAY)
 
+          BEGIN_CASE(JSOP_HOLE)
+            frame.push(MagicValue(JS_ARRAY_HOLE));
+          END_CASE(JSOP_HOLE)
+
           BEGIN_CASE(JSOP_LAMBDA_FC)
           {
             JSFunction *fun = script->getFunction(fullAtomIndex(PC));
             prepareStubCall(Uses(frame.frameDepth()));
             masm.move(ImmPtr(fun), Registers::ArgReg1);
             stubCall(stubs::FlatLambda);
             frame.takeReg(Registers::ReturnReg);
             frame.pushTypedPayload(JSVAL_TYPE_OBJECT, Registers::ReturnReg);
@@ -1782,18 +1842,17 @@ mjit::Compiler::emitReturn()
      */
     masm.loadPtr(Address(JSFrameReg, JSStackFrame::offsetOfPrev()), Registers::ReturnReg);
     masm.storePtr(Registers::ReturnReg, FrameAddress(offsetof(VMFrame, regs.fp)));
 
     JS_STATIC_ASSERT(Registers::ReturnReg != JSReturnReg_Data);
     JS_STATIC_ASSERT(Registers::ReturnReg != JSReturnReg_Type);
 
     Address rval(JSFrameReg, JSStackFrame::offsetOfReturnValue());
-    masm.loadPayload(rval, JSReturnReg_Data);
-    masm.loadTypeTag(rval, JSReturnReg_Type);
+    masm.loadValueAsComponents(rval, JSReturnReg_Type, JSReturnReg_Data);
     masm.restoreReturnAddress();
     masm.move(Registers::ReturnReg, JSFrameReg);
 #ifdef DEBUG
     masm.storePtr(ImmPtr(JSStackFrame::sInvalidpc),
                   Address(JSFrameReg, JSStackFrame::offsetOfSavedpc()));
 #endif
     masm.ret();
 }
@@ -1839,18 +1898,17 @@ mjit::Compiler::interruptCheckHelper()
 
 void
 mjit::Compiler::emitPrimitiveTestForNew(uint32 argc)
 {
     Jump primitive = masm.testPrimitive(Assembler::Equal, JSReturnReg_Type);
     stubcc.linkExitDirect(primitive, stubcc.masm.label());
     FrameEntry *fe = frame.peek(-int(argc + 1));
     Address thisv(frame.addressOf(fe));
-    stubcc.masm.loadTypeTag(thisv, JSReturnReg_Type);
-    stubcc.masm.loadPayload(thisv, JSReturnReg_Data);
+    stubcc.masm.loadValueAsComponents(thisv, JSReturnReg_Type, JSReturnReg_Data);
     Jump primFix = stubcc.masm.jump();
     stubcc.crossJump(primFix, masm.label());
 }
 
 void
 mjit::Compiler::emitUncachedCall(uint32 argc, bool callingNew)
 {
     RegisterID r0 = Registers::ReturnReg;
@@ -1903,16 +1961,17 @@ mjit::Compiler::inlineCallHelper(uint32 
 
     CallGenInfo callIC(argc);
     uint32 callICIndex = callICs.length();
 
     /*
      * Save constant |this| to optimize thisv stores for common call cases
      * like CALL[LOCAL, GLOBAL, ARG] which push NULL.
      */
+    callIC.pc = PC;
     callIC.frameDepth = frame.frameDepth();
 
     /* Grab type and data registers up-front. */
     MaybeRegisterID typeReg;
     frame.ensureFullRegs(fe);
 
     if (!fe->isTypeKnown()) {
         typeReg = frame.tempRegForType(fe);
@@ -2052,17 +2111,17 @@ mjit::Compiler::inlineCallHelper(uint32 
         masm.move(Imm32(argc), Registers::ArgReg1);
         stubCall(stubs::NewObject);
     }
 
     uint32 flags = 0;
     if (callingNew)
         flags |= JSFRAME_CONSTRUCTING;
 
-    InlineFrameAssembler inlFrame(masm, callIC, PC, flags);
+    InlineFrameAssembler inlFrame(masm, callIC, flags);
     inlFrame.assemble();
 
     callIC.hotCall = masm.call();
     stubcc.crossJump(oolCallDone, masm.label());
 
     callIC.joinPoint = masm.label();
 
     /*
@@ -2200,17 +2259,17 @@ mjit::Compiler::emitStubCmpOp(BoolStub s
     }
 }
 
 void
 mjit::Compiler::jsop_setprop_slow(JSAtom *atom)
 {
     prepareStubCall(Uses(2));
     masm.move(ImmPtr(atom), Registers::ArgReg1);
-    stubCall(stubs::SetName);
+    stubCall(STRICT_VARIANT(stubs::SetName));
     JS_STATIC_ASSERT(JSOP_SETNAME_LENGTH == JSOP_SETPROP_LENGTH);
     frame.shimmy(1);
 }
 
 void
 mjit::Compiler::jsop_getprop_slow()
 {
     prepareStubCall(Uses(1));
@@ -2845,17 +2904,17 @@ mjit::Compiler::jsop_setprop(JSAtom *ato
         /*
          * This gets called from PROPINC/PROPDEC which aren't compatible with
          * the normal SETNAME property cache logic.
          */
         JSOp op = JSOp(*PC);
         if (op == JSOP_SETNAME || op == JSOP_SETPROP || op == JSOP_SETGNAME || op ==
             JSOP_SETMETHOD) {
             stubcc.masm.move(ImmPtr(atom), Registers::ArgReg1);
-            stubcc.call(stubs::SetName);
+            stubcc.call(STRICT_VARIANT(stubs::SetName));
         } else {
             stubcc.masm.move(Imm32(pics.length()), Registers::ArgReg1);
             stubcc.call(ic::SetPropDumb);
         }
 
         typeCheck = stubcc.masm.jump();
         pic.hasTypeCheck = true;
     } else {
@@ -3793,17 +3852,17 @@ mjit::Compiler::jsop_getgname(uint32 ind
 }
 
 void
 mjit::Compiler::jsop_setgname_slow(uint32 index)
 {
     JSAtom *atom = script->getAtom(index);
     prepareStubCall(Uses(2));
     masm.move(ImmPtr(atom), Registers::ArgReg1);
-    stubCall(stubs::SetGlobalName);
+    stubCall(STRICT_VARIANT(stubs::SetGlobalName));
     frame.popn(2);
     frame.pushSynced();
 }
 
 void
 mjit::Compiler::jsop_setgname(uint32 index)
 {
 #if defined JS_MONOIC
@@ -3941,17 +4000,17 @@ mjit::Compiler::jsop_setgname(uint32 ind
     jsop_setgname_slow(index);
 #endif
 }
 
 void
 mjit::Compiler::jsop_setelem_slow()
 {
     prepareStubCall(Uses(3));
-    stubCall(stubs::SetElem);
+    stubCall(STRICT_VARIANT(stubs::SetElem));
     frame.popn(3);
     frame.pushSynced();
 }
 
 void
 mjit::Compiler::jsop_getelem_slow()
 {
     prepareStubCall(Uses(2));
@@ -3985,33 +4044,42 @@ mjit::Compiler::jsop_instanceof()
 
     MaybeJump firstSlow;
     if (!rhs->isTypeKnown()) {
         Jump j = frame.testObject(Assembler::NotEqual, rhs);
         stubcc.linkExit(j, Uses(2));
         RegisterID reg = frame.tempRegForData(rhs);
         j = masm.testFunction(Assembler::NotEqual, reg);
         stubcc.linkExit(j, Uses(2));
+    }
+
+    /* Test for bound functions. */
+    RegisterID obj = frame.tempRegForData(rhs);
+    Jump isBound = masm.branchTest32(Assembler::NonZero, Address(obj, offsetof(JSObject, flags)),
+                                     Imm32(JSObject::BOUND_FUNCTION));
+    {
+        stubcc.linkExit(isBound, Uses(2));
         stubcc.leave();
         stubcc.call(stubs::InstanceOf);
         firstSlow = stubcc.masm.jump();
     }
+    
 
     /* This is sadly necessary because the error case needs the object. */
     frame.dup();
 
     jsop_getprop(cx->runtime->atomState.classPrototypeAtom, false);
 
     /* Primitive prototypes are invalid. */
     rhs = frame.peek(-1);
     Jump j = frame.testPrimitive(Assembler::Equal, rhs);
     stubcc.linkExit(j, Uses(3));
 
     /* Allocate registers up front, because of branchiness. */
-    RegisterID obj = frame.copyDataIntoReg(lhs);
+    obj = frame.copyDataIntoReg(lhs);
     RegisterID proto = frame.copyDataIntoReg(rhs);
     RegisterID temp = frame.allocReg();
 
     MaybeJump isFalse;
     if (!lhs->isTypeKnown())
         isFalse = frame.testPrimitive(Assembler::Equal, lhs);
 
     /* Quick test to avoid wrapped objects. */
--- a/js/src/methodjit/Compiler.h
+++ b/js/src/methodjit/Compiler.h
@@ -110,16 +110,17 @@ class Compiler
         CallGenInfo(uint32 argc)
           : argc(argc)
         { }
 
         /*
          * These members map to members in CallICInfo. See that structure for
          * more comments.
          */
+        jsbytecode   *pc;
         uint32       argc;
         DataLabelPtr funGuard;
         Jump         funJump;
         Call         hotCall;
         Call         oolCall;
         Label        joinPoint;
         Label        slowJoinPoint;
         Label        slowPathStart;
--- a/js/src/methodjit/FastOps.cpp
+++ b/js/src/methodjit/FastOps.cpp
@@ -1229,17 +1229,17 @@ mjit::Compiler::jsop_setelem()
         Jump notHole = masm.branch32(Assembler::Equal, masm.tagOf(slot), ImmType(JSVAL_TYPE_MAGIC));
 #elif defined JS_PUNBOX64
         masm.loadTypeTag(slot, Registers::ValueReg);
         Jump notHole = masm.branchPtr(Assembler::Equal, Registers::ValueReg, ImmType(JSVAL_TYPE_MAGIC));
 #endif
         stubcc.linkExit(notHole, Uses(3));
 
         stubcc.leave();
-        stubcc.call(stubs::SetElem);
+        stubcc.call(STRICT_VARIANT(stubs::SetElem));
 
         /* Infallible, start killing everything. */
         frame.eviscerate(obj);
         frame.eviscerate(id);
 
         /* Perform the store. */
         if (fe->isConstant()) {
             masm.storeValue(fe->getValue(), slot);
@@ -1311,17 +1311,17 @@ mjit::Compiler::jsop_setelem()
             stubcc.masm.loadPtr(Address(objReg, offsetof(JSObject, dslots)), objReg);
 
         /* Rejoin OOL path with inline path to do the store itself. */
         Jump jmpHoleExit = stubcc.masm.jump();
         Label lblRejoin = masm.label();
         stubcc.crossJump(jmpHoleExit, lblRejoin);
 
         stubcc.leave();
-        stubcc.call(stubs::SetElem);
+        stubcc.call(STRICT_VARIANT(stubs::SetElem));
 
         /* Infallible, start killing everything. */
         frame.eviscerate(obj);
         frame.eviscerate(id);
 
         /* Perform the store. */
         if (fe->isConstant()) {
             masm.storeValue(fe->getValue(), slot);
@@ -1371,39 +1371,36 @@ mjit::Compiler::jsop_getelem_dense(Frame
     Jump guardSlots = masm.branchTestPtr(Assembler::Zero, objReg, objReg);
     stubcc.linkExit(guardSlots, Uses(2));
 
     /* guard within capacity */
     if (id->isConstant()) {
         /* guard not a hole */
         Address slot(objReg, id->getValue().toInt32() * sizeof(Value));
 #if defined JS_NUNBOX32
-        Jump notHole = masm.branch32(Assembler::Equal, masm.tagOf(slot), ImmType(JSVAL_TYPE_MAGIC));
+        masm.loadTypeTag(slot, tmpReg);
+        Jump notHole = masm.branchPtr(Assembler::Equal, tmpReg, ImmType(JSVAL_TYPE_MAGIC));
+        masm.loadPayload(slot, objReg);
 #elif defined JS_PUNBOX64
-        masm.loadTypeTag(slot, Registers::ValueReg);
-        Jump notHole = masm.branchPtr(Assembler::Equal, Registers::ValueReg, ImmType(JSVAL_TYPE_MAGIC));
+        masm.loadValueAsComponents(slot, tmpReg, objReg);
+        Jump notHole = masm.branchPtr(Assembler::Equal, tmpReg, ImmType(JSVAL_TYPE_MAGIC));
 #endif
         stubcc.linkExit(notHole, Uses(2));
-
-        /* Load slot address into regs. */
-        masm.loadTypeTag(slot, tmpReg);
-        masm.loadPayload(slot, objReg);
     } else {
         /* guard not a hole */
         BaseIndex slot(objReg, idReg.reg(), Assembler::JSVAL_SCALE);
 #if defined JS_NUNBOX32
-        Jump notHole = masm.branch32(Assembler::Equal, masm.tagOf(slot), ImmType(JSVAL_TYPE_MAGIC));
+        masm.loadTypeTag(slot, tmpReg);
+        Jump notHole = masm.branchPtr(Assembler::Equal, tmpReg, ImmType(JSVAL_TYPE_MAGIC));
+        masm.loadPayload(slot, objReg);
 #elif defined JS_PUNBOX64
-        masm.loadTypeTag(slot, Registers::ValueReg);
-        Jump notHole = masm.branchPtr(Assembler::Equal, Registers::ValueReg, ImmType(JSVAL_TYPE_MAGIC));
+        masm.loadValueAsComponents(slot, tmpReg, objReg);
+        Jump notHole = masm.branchPtr(Assembler::Equal, tmpReg, ImmType(JSVAL_TYPE_MAGIC));
 #endif
         stubcc.linkExit(notHole, Uses(2));
-
-        masm.loadTypeTag(slot, tmpReg);
-        masm.loadPayload(slot, objReg);
     }
     /* Postcondition: type must be in tmpReg, data must be in objReg. */
 
     /* Note: linkExits will be hooked up to a leave() after this method completes. */
 }
 
 void
 mjit::Compiler::jsop_getelem_known_type(FrameEntry *obj, FrameEntry *id, RegisterID tmpReg)
--- a/js/src/methodjit/FrameState.cpp
+++ b/js/src/methodjit/FrameState.cpp
@@ -447,27 +447,22 @@ FrameState::merge(Assembler &masm, Chang
 
         /* Copies do not have registers. */
         if (fe->isCopy()) {
             JS_ASSERT(!fe->data.inRegister());
             JS_ASSERT(!fe->type.inRegister());
             continue;
         }
 
-#if defined JS_PUNBOX64
-        if (fe->data.inRegister() && fe->type.inRegister()) {
+        if (fe->data.inRegister() && fe->type.inRegister())
             masm.loadValueAsComponents(addressOf(fe), fe->type.reg(), fe->data.reg());
-        } else
-#endif
-        {
-            if (fe->data.inRegister())
-                masm.loadPayload(addressOf(fe), fe->data.reg());
-            if (fe->type.inRegister())
-                masm.loadTypeTag(addressOf(fe), fe->type.reg());
-        }
+        else if (fe->data.inRegister())
+            masm.loadPayload(addressOf(fe), fe->data.reg());
+        else if (fe->type.inRegister())
+            masm.loadTypeTag(addressOf(fe), fe->type.reg());
     }
 }
 
 JSC::MacroAssembler::RegisterID
 FrameState::copyDataIntoReg(FrameEntry *fe)
 {
     return copyDataIntoReg(this->masm, fe);
 }
--- a/js/src/methodjit/InlineFrameAssembler.h
+++ b/js/src/methodjit/InlineFrameAssembler.h
@@ -81,29 +81,28 @@ class InlineFrameAssembler {
 
   public:
     /*
      * Register state, so consumers of this class can restrict which registers
      * can and can't be clobbered.
      */
     Registers  tempRegs;
 
-    InlineFrameAssembler(Assembler &masm, JSContext *cx, ic::CallICInfo &ic, uint32 flags)
-      : masm(masm), flags(flags)
+    InlineFrameAssembler(Assembler &masm, ic::CallICInfo &ic, uint32 flags)
+      : masm(masm), pc(ic.pc), flags(flags)
     {
         frameDepth = ic.frameDepth;
         argc = ic.argc;
         funObjReg = ic.funObjReg;
-        pc = cx->regs->pc;
         tempRegs.takeReg(ic.funPtrReg);
         tempRegs.takeReg(funObjReg);
     }
 
-    InlineFrameAssembler(Assembler &masm, Compiler::CallGenInfo &gen, jsbytecode *pc, uint32 flags)
-      : masm(masm), pc(pc), flags(flags)
+    InlineFrameAssembler(Assembler &masm, Compiler::CallGenInfo &gen, uint32 flags)
+      : masm(masm), pc(gen.pc), flags(flags)
     {
         frameDepth = gen.frameDepth;
         argc = gen.argc;
         funObjReg = gen.funObjReg;
         tempRegs.takeReg(funObjReg);
     }
 
     inline void assemble()
--- a/js/src/methodjit/InvokeHelpers.cpp
+++ b/js/src/methodjit/InvokeHelpers.cpp
@@ -467,70 +467,86 @@ UncachedInlineCall(VMFrame &f, uint32 fl
 
     *pret = NULL;
     return ok;
 }
 
 void * JS_FASTCALL
 stubs::UncachedNew(VMFrame &f, uint32 argc)
 {
+    UncachedCallResult ucr;
+    UncachedNewHelper(f, argc, &ucr);
+    return ucr.codeAddr;
+}
+
+void
+stubs::UncachedNewHelper(VMFrame &f, uint32 argc, UncachedCallResult *ucr)
+{
+    ucr->init();
+
     JSContext *cx = f.cx;
     Value *vp = f.regs.sp - (argc + 2);
 
     /* Try to do a fast inline call before the general Invoke path. */
-    JSFunction *fun;
-    if (IsFunctionObject(*vp, &fun) && fun->isInterpreted() && !fun->script()->isEmpty()) {
-        void *ret;
-        if (!UncachedInlineCall(f, JSFRAME_CONSTRUCTING, &ret, argc))
-            THROWV(NULL);
-        return ret;
+    if (IsFunctionObject(*vp, &ucr->fun) && ucr->fun->isInterpreted() && 
+        !ucr->fun->script()->isEmpty()) {
+        ucr->callee = &vp->toObject();
+        if (!UncachedInlineCall(f, JSFRAME_CONSTRUCTING, &ucr->codeAddr, argc))
+            THROW();
+        return;
     }
 
     if (!InvokeConstructor(cx, InvokeArgsAlreadyOnTheStack(vp, argc)))
-        THROWV(NULL);
-    return NULL;
+        THROW();
+    return;
 }
 
 void * JS_FASTCALL
 stubs::UncachedCall(VMFrame &f, uint32 argc)
 {
+    UncachedCallResult ucr;
+    UncachedCallHelper(f, argc, &ucr);
+    return ucr.codeAddr;
+}
+
+void
+stubs::UncachedCallHelper(VMFrame &f, uint32 argc, UncachedCallResult *ucr)
+{
+    ucr->init();
+
     JSContext *cx = f.cx;
-
     Value *vp = f.regs.sp - (argc + 2);
 
-    JSObject *obj;
-    if (IsFunctionObject(*vp, &obj)) {
-        JSFunction *fun = GET_FUNCTION_PRIVATE(cx, obj);
+    if (IsFunctionObject(*vp, &ucr->callee)) {
+        ucr->callee = &vp->toObject();
+        ucr->fun = GET_FUNCTION_PRIVATE(cx, ucr->callee);
 
-        if (fun->isInterpreted()) {
-            void *ret;
-
-            if (fun->u.i.script->isEmpty()) {
+        if (ucr->fun->isInterpreted()) {
+            if (ucr->fun->u.i.script->isEmpty()) {
                 vp->setUndefined();
                 f.regs.sp = vp + 1;
-                return NULL;
+                return;
             }
 
-            if (!UncachedInlineCall(f, 0, &ret, argc))
-                THROWV(NULL);
-
-            return ret;
+            if (!UncachedInlineCall(f, 0, &ucr->codeAddr, argc))
+                THROW();
+            return;
         }
 
-        if (fun->isNative()) {
-            if (!fun->u.n.native(cx, argc, vp))
-                THROWV(NULL);
-            return NULL;
+        if (ucr->fun->isNative()) {
+            if (!ucr->fun->u.n.native(cx, argc, vp))
+                THROW();
+            return;
         }
     }
 
     if (!Invoke(f.cx, InvokeArgsAlreadyOnTheStack(vp, argc), 0))
-        THROWV(NULL);
+        THROW();
 
-    return NULL;
+    return;
 }
 
 void JS_FASTCALL
 stubs::PutCallObject(VMFrame &f)
 {
     JS_ASSERT(f.fp()->hasCallObj());
     js_PutCallObject(f.cx, f.fp());
 }
@@ -791,17 +807,17 @@ void *
 RunTracer(VMFrame &f)
 #endif
 {
     JSContext *cx = f.cx;
     JSStackFrame *entryFrame = f.fp();
     TracePointAction tpa;
 
     /* :TODO: nuke PIC? */
-    if (!cx->jitEnabled)
+    if (!cx->traceJitEnabled)
         return NULL;
 
     bool blacklist;
     uintN inlineCallCount = 0;
     tpa = MonitorTracePoint(f.cx, inlineCallCount, blacklist);
     JS_ASSERT(!TRACE_RECORDER(cx));
 
 #if JS_MONOIC
--- a/js/src/methodjit/MethodJIT.cpp
+++ b/js/src/methodjit/MethodJIT.cpp
@@ -424,30 +424,41 @@ JS_STATIC_ASSERT(offsetof(VMFrame, cx) =
 JS_STATIC_ASSERT(offsetof(VMFrame, regs.fp) ==          (4*7));
 JS_STATIC_ASSERT(offsetof(VMFrame, unused) ==           (4*4));
 JS_STATIC_ASSERT(offsetof(VMFrame, previous) ==         (4*3));
 
 JS_STATIC_ASSERT(JSFrameReg == JSC::ARMRegisters::r11);
 JS_STATIC_ASSERT(JSReturnReg_Data == JSC::ARMRegisters::r1);
 JS_STATIC_ASSERT(JSReturnReg_Type == JSC::ARMRegisters::r2);
 
+#ifdef MOZ_THUMB2
+#define FUNCTION_HEADER_EXTRA \
+  ".align 2\n" \
+  ".thumb\n" \
+  ".thumb_func\n"
+#else
+#define FUNCTION_HEADER_EXTRA
+#endif
+
 asm volatile (
 ".text\n"
+FUNCTION_HEADER_EXTRA
 ".globl " SYMBOL_STRING(InjectJaegerReturn) "\n"
 SYMBOL_STRING(InjectJaegerReturn) ":"       "\n"
     /* Restore frame regs. */
     "ldr lr, [r11, #44]"                    "\n" /* fp->ncode */
     "ldr r1, [r11, #24]"                    "\n" /* fp->rval data */
     "ldr r2, [r11, #28]"                    "\n" /* fp->rval type */
     "ldr r11, [sp, #28]"                    "\n" /* load f.fp */
     "bx  lr"                                "\n"
 );
 
 asm volatile (
 ".text\n"
+FUNCTION_HEADER_EXTRA
 ".globl " SYMBOL_STRING(SafePointTrampoline)  "\n"
 SYMBOL_STRING(SafePointTrampoline) ":"
     /*
      * On entry to SafePointTrampoline:
      *         r11 = fp
      *      sp[80] = safePoint
      */
     "ldr    ip, [sp, #80]"                  "\n"
@@ -455,16 +466,17 @@ SYMBOL_STRING(SafePointTrampoline) ":"
     "str    lr, [r11, #44]"                 "\n"
     /* Jump to 'safePoint' via 'ip' because a load into the PC from an address on
      * the stack looks like a return, and may upset return stack prediction. */
     "bx     ip"                             "\n"
 );
 
 asm volatile (
 ".text\n"
+FUNCTION_HEADER_EXTRA
 ".globl " SYMBOL_STRING(JaegerTrampoline)   "\n"
 SYMBOL_STRING(JaegerTrampoline) ":"         "\n"
     /*
      * On entry to JaegerTrampoline:
      *         r0 = cx
      *         r1 = fp
      *         r2 = code
      *         r3 = stackLimit
@@ -504,61 +516,63 @@ SYMBOL_STRING(JaegerTrampoline) ":"     
 "   sub     sp, sp, #(4*7)"                     "\n"
 
     /* Preserve 'code' (r2) in an arbitrary callee-saved register. */
 "   mov     r4, r2"                             "\n"
     /* Preserve 'fp' (r1) in r11 (JSFrameReg) for SafePointTrampoline. */
 "   mov     r11, r1"                            "\n"
 
 "   mov     r0, sp"                             "\n"
-"   bl  " SYMBOL_STRING_VMFRAME(SetVMFrameRegs)   "\n"
+"   blx  " SYMBOL_STRING_VMFRAME(SetVMFrameRegs)   "\n"
 "   mov     r0, sp"                             "\n"
-"   bl  " SYMBOL_STRING_VMFRAME(PushActiveVMFrame)"\n"
+"   blx  " SYMBOL_STRING_VMFRAME(PushActiveVMFrame)"\n"
 
     /* Call the compiled JavaScript function. */
 "   blx     r4"                                 "\n"
 
     /* Tidy up. */
 "   mov     r0, sp"                             "\n"
-"   bl  " SYMBOL_STRING_VMFRAME(PopActiveVMFrame) "\n"
+"   blx  " SYMBOL_STRING_VMFRAME(PopActiveVMFrame) "\n"
 
     /* Skip past the parameters we pushed (such as cx and the like). */
 "   add     sp, sp, #(4*7 + 4*4)"               "\n"
 
     /* Set a 'true' return value to indicate successful completion. */
 "   mov     r0, #1"                         "\n"
 "   pop     {r4-r11,pc}"                    "\n"
 );
 
 asm volatile (
 ".text\n"
+FUNCTION_HEADER_EXTRA
 ".globl " SYMBOL_STRING(JaegerThrowpoline)  "\n"
 SYMBOL_STRING(JaegerThrowpoline) ":"        "\n"
     /* Find the VMFrame pointer for js_InternalThrow. */
 "   mov     r0, sp"                         "\n"
 
     /* Call the utility function that sets up the internal throw routine. */
-"   bl  " SYMBOL_STRING_RELOC(js_InternalThrow) "\n"
+"   blx  " SYMBOL_STRING_RELOC(js_InternalThrow) "\n"
     
     /* If js_InternalThrow found a scripted handler, jump to it. Otherwise, tidy
      * up and return. */
 "   cmp     r0, #0"                         "\n"
 "   it      ne"                             "\n"
 "   bxne    r0"                             "\n"
 
     /* Tidy up, then return '0' to represent an unhandled exception. */
 "   mov     r0, sp"                             "\n"
-"   bl  " SYMBOL_STRING_VMFRAME(PopActiveVMFrame) "\n"
+"   blx  " SYMBOL_STRING_VMFRAME(PopActiveVMFrame) "\n"
 "   add     sp, sp, #(4*7 + 4*4)"               "\n"
 "   mov     r0, #0"                         "\n"
 "   pop     {r4-r11,pc}"                    "\n"
 );
 
 asm volatile (
 ".text\n"
+FUNCTION_HEADER_EXTRA
 ".globl " SYMBOL_STRING(JaegerStubVeneer)   "\n"
 SYMBOL_STRING(JaegerStubVeneer) ":"         "\n"
     /* We enter this function as a veneer between a compiled method and one of the js_ stubs. We
      * need to store the LR somewhere (so it can be modified in case on an exception) and then
      * branch to the js_ stub as if nothing had happened.
      * The arguments are identical to those for js_* except that the target function should be in
      * 'ip'. */
 "   push    {ip,lr}"                        "\n"
--- a/js/src/methodjit/MethodJIT.h
+++ b/js/src/methodjit/MethodJIT.h
@@ -205,17 +205,17 @@ void
 ReleaseScriptCode(JSContext *cx, JSScript *script);
 
 void
 SweepCallICs(JSContext *cx);
 
 static inline CompileStatus
 CanMethodJIT(JSContext *cx, JSScript *script, JSFunction *fun, JSObject *scopeChain)
 {
-    if (!(cx->options & JSOPTION_METHODJIT) || script->ncode == JS_UNJITTABLE_METHOD)
+    if (!cx->methodJitEnabled || script->ncode == JS_UNJITTABLE_METHOD)
         return Compile_Abort;
     if (script->ncode == NULL)
         return TryCompile(cx, script, fun, scopeChain);
     return Compile_Okay;
 }
 
 struct CallSite
 {
--- a/js/src/methodjit/MonoIC.cpp
+++ b/js/src/methodjit/MonoIC.cpp
@@ -126,36 +126,41 @@ ic::GetGlobalName(VMFrame &f, uint32 ind
 
     /* Do load anyway... this time. */
     stubs::GetGlobalName(f);
 }
 
 static void JS_FASTCALL
 SetGlobalNameSlow(VMFrame &f, uint32 index)
 {
-    JSAtom *atom = f.fp()->script()->getAtom(GET_INDEX(f.regs.pc));
-    stubs::SetGlobalName(f, atom);
+    JSScript *script = f.fp()->script();
+    JSAtom *atom = script->getAtom(GET_INDEX(f.regs.pc));
+    if (script->strictModeCode)
+        stubs::SetGlobalName<true>(f, atom);
+    else
+        stubs::SetGlobalName<false>(f, atom);
 }
 
 static void
 PatchSetFallback(VMFrame &f, ic::MICInfo &mic)
 {
     JSC::RepatchBuffer repatch(mic.stubEntry.executableAddress(), 64);
     JSC::FunctionPtr fptr(JS_FUNC_TO_DATA_PTR(void *, SetGlobalNameSlow));
     repatch.relink(mic.stubCall, fptr);
 }
 
 static VoidStubAtom
 GetStubForSetGlobalName(VMFrame &f)
 {
+    JSScript *script = f.fp()->script();
     // The property cache doesn't like inc ops, so we use a simpler
     // stub for that case.
     return js_CodeSpec[*f.regs.pc].format & (JOF_INC | JOF_DEC)
-         ? stubs::SetGlobalNameDumb
-         : stubs::SetGlobalName;
+         ? STRICT_VARIANT(stubs::SetGlobalNameDumb)
+         : STRICT_VARIANT(stubs::SetGlobalName);
 }
 
 void JS_FASTCALL
 ic::SetGlobalName(VMFrame &f, uint32 index)
 {
     JSObject *obj = f.fp()->scopeChain().getGlobal();
     ic::MICInfo &mic = f.fp()->script()->mics[index];
     JSAtom *atom = f.fp()->script()->getAtom(GET_INDEX(f.regs.pc));
@@ -303,17 +308,17 @@ class CallCompiler
     {
         /*
          * Create a stub that works with arity mismatches. Like the fast-path,
          * this allocates a frame on the caller side, but also performs extra
          * checks for compilability. Perhaps this should be a separate, shared
          * trampoline, but for now we generate it dynamically.
          */
         Assembler masm;
-        InlineFrameAssembler inlFrame(masm, cx, ic, flags);
+        InlineFrameAssembler inlFrame(masm, ic, flags);
         RegisterID t0 = inlFrame.tempRegs.takeAnyReg();
 
         /* Generate the inline frame creation. */
         inlFrame.assemble();
 
         /* funPtrReg is still valid. Check if a compilation is needed. */
         Address scriptAddr(ic.funPtrReg, offsetof(JSFunction, u) +
                            offsetof(JSFunction::U::Scripted, script));
@@ -592,98 +597,71 @@ class CallCompiler
 
         ic.fastGuardedNative = obj;
 
         return true;
     }
 
     void *update()
     {
-        JSObject *obj;
-        if (!IsFunctionObject(*vp, &obj) || !(cx->options & JSOPTION_METHODJIT)) {
-            /* Ugh. Can't do anything with this! */
-            if (callingNew)
-                stubs::SlowNew(f, ic.argc);
-            else
-                stubs::SlowCall(f, ic.argc);
-            return NULL;
-        }
-
-        JSFunction *fun = obj->getFunctionPrivate();
-        JSObject *scopeChain = obj->getParent();
+        stubs::UncachedCallResult ucr;
+        if (callingNew)
+            stubs::UncachedNewHelper(f, ic.argc, &ucr);
+        else
+            stubs::UncachedCallHelper(f, ic.argc, &ucr);
 
-        /* The slow path guards against natives. */
-        JS_ASSERT(fun->isInterpreted());
-        JSScript *script = fun->u.i.script;
-
-        if (!script->ncode && !script->isEmpty()) {
-            if (mjit::TryCompile(cx, script, fun, scopeChain) == Compile_Error)
-                THROWV(NULL);
-        }
-        JS_ASSERT(script->isEmpty() || script->ncode);
-
-        if (script->ncode == JS_UNJITTABLE_METHOD || script->isEmpty()) {
-            /* This should always go to a slow path, sadly. */
+        // If the function cannot be jitted (generally unjittable or empty script),
+        // patch this site to go to a slow path always.
+        if (!ucr.codeAddr) {
             JSC::CodeLocationCall oolCall = ic.slowPathStart.callAtOffset(ic.oolCallOffset);
             uint8 *start = (uint8 *)oolCall.executableAddress();
             JSC::RepatchBuffer repatch(start - 32, 64);
             JSC::FunctionPtr fptr = callingNew
                                     ? JSC::FunctionPtr(JS_FUNC_TO_DATA_PTR(void *, SlowNewFromIC))
                                     : JSC::FunctionPtr(JS_FUNC_TO_DATA_PTR(void *, SlowCallFromIC));
             repatch.relink(oolCall, fptr);
-            if (callingNew)
-                stubs::SlowNew(f, ic.argc);
-            else
-                stubs::SlowCall(f, ic.argc);
             return NULL;
         }
+            
+        JSFunction *fun = ucr.fun;
+        JS_ASSERT(fun);
+        JSScript *script = fun->script();
+        JS_ASSERT(script);
+        JSObject *callee = ucr.callee;
+        JS_ASSERT(callee);
+
+        uint32 flags = callingNew ? JSFRAME_CONSTRUCTING : 0;
+
+        if (!ic.hit) {
+            ic.hit = true;
+            return ucr.codeAddr;
+        }
 
-        uint32 flags = callingNew ? JSFRAME_CONSTRUCTING : 0;
-        if (callingNew)
-            stubs::NewObject(f, ic.argc);
-
-        if (!ic.hit) {
-            if (ic.argc != fun->nargs) {
-                if (!generateFullCallStub(script, flags))
+        if (ic.argc != fun->nargs) {
+            if (!generateFullCallStub(script, flags))
+                THROWV(NULL);
+        } else {
+            if (!ic.fastGuardedObject) {
+                patchInlinePath(script, callee);
+            } else if (!ic.hasJsFunCheck &&
+                       !ic.fastGuardedNative &&
+                       ic.fastGuardedObject->getFunctionPrivate() == fun) {
+                /*
+                 * Note: Multiple "function guard" stubs are not yet
+                 * supported, thus the fastGuardedNative check.
+                 */
+                if (!generateStubForClosures(callee))
                     THROWV(NULL);
             } else {
-                if (!ic.fastGuardedObject) {
-                    patchInlinePath(script, obj);
-                } else if (!ic.hasJsFunCheck &&
-                           !ic.fastGuardedNative &&
-                           ic.fastGuardedObject->getFunctionPrivate() == fun) {
-                    /*
-                     * Note: Multiple "function guard" stubs are not yet
-                     * supported, thus the fastGuardedNative check.
-                     */
-                    if (!generateStubForClosures(obj))
-                        THROWV(NULL);
-                } else {
-                    if (!generateFullCallStub(script, flags))
-                        THROWV(NULL);
-                }
+                if (!generateFullCallStub(script, flags))
+                    THROWV(NULL);
             }
-        } else {
-            ic.hit = true;
         }
 
-        /*
-         * We are about to jump into the callee's prologue, so push the frame as
-         * if we had been executing in the caller's inline call path. In theory,
-         * we could actually jump to the inline call path, but doing it from
-         * C++ allows JSStackFrame::initCallFrameCallerHalf to serve as a
-         * reference for what the jitted path should be doing.
-         */
-        JSStackFrame *fp = (JSStackFrame *)f.regs.sp;
-        fp->initCallFrameCallerHalf(cx, *scopeChain, ic.argc, flags);
-        f.regs.fp = fp;
-
-        if (ic.argc == fun->nargs)
-            return script->ncode;
-        return script->jit->arityCheck;
+        return ucr.codeAddr;
     }
 };
 
 void * JS_FASTCALL
 ic::Call(VMFrame &f, uint32 index)
 {
     JSScript *oldscript = f.fp()->script();
     CallICInfo &ic = oldscript->callICs[index];
--- a/js/src/methodjit/MonoIC.h
+++ b/js/src/methodjit/MonoIC.h
@@ -124,16 +124,19 @@ struct CallICInfo {
     };
 
     JSC::ExecutablePool *pools[Total_Pools];
 
     /* Used for rooting and reification. */
     JSObject *fastGuardedObject;
     JSObject *fastGuardedNative;
 
+    /* PC at the call site. */
+    jsbytecode *pc;
+
     uint32 argc : 16;
     uint32 frameDepth : 16;
 
     /* Function object identity guard. */
     JSC::CodeLocationDataLabelPtr funGuard;
 
     /* Starting point for all slow call paths. */
     JSC::CodeLocationLabel slowPathStart;
--- a/js/src/methodjit/NunboxAssembler.h
+++ b/js/src/methodjit/NunboxAssembler.h
@@ -146,16 +146,31 @@ class Assembler : public BaseAssembler
     void storePayload(RegisterID reg, BaseIndex address) {
         store32(reg, payloadOf(address));
     }
 
     void storePayload(Imm32 imm, Address address) {
         store32(imm, payloadOf(address));
     }
 
+    /* Loads type first, then payload, returning label after type load. */
+    Label loadValueAsComponents(Address address, RegisterID type, RegisterID payload) {
+        loadTypeTag(address, type);
+        Label l = label();
+        loadPayload(address, payload);
+        return l;
+    }
+
+    Label loadValueAsComponents(BaseIndex address, RegisterID type, RegisterID payload) {
+        loadTypeTag(address, type);
+        Label l = label();
+        loadPayload(address, payload);
+        return l;
+    }
+
     /*
      * Stores type first, then payload.
      */
     void storeValue(const Value &v, Address address) {
         jsval_layout jv;
         jv.asBits = JSVAL_BITS(Jsvalify(v));
 
         store32(ImmTag(jv.s.tag), tagOf(address));
--- a/js/src/methodjit/PolyIC.cpp
+++ b/js/src/methodjit/PolyIC.cpp
@@ -1794,18 +1794,19 @@ class ScopeNameCompiler : public PICStub
         escapedFrame.linkTo(masm.label(), &masm);
 
         {
             masm.loadPtr(Address(pic.objReg, offsetof(JSObject, dslots)), pic.objReg);
 
             if (kind == VAR)
                 slot += fun->nargs;
             Address dslot(pic.objReg, slot * sizeof(Value));
-            masm.loadTypeTag(dslot, pic.shapeReg);
-            masm.loadPayload(dslot, pic.objReg);
+
+            /* Safe because type is loaded first. */
+            masm.loadValueAsComponents(dslot, pic.shapeReg, pic.objReg);
         }
 
         skipOver.linkTo(masm.label(), &masm);
         Jump done = masm.jump();
 
         // All failures flow to here, so there is a common point to patch.
         for (Jump *pj = fails.begin(); pj != fails.end(); ++pj)
             pj->linkTo(masm.label(), &masm);
@@ -2116,30 +2117,31 @@ ic::SetPropDumb(VMFrame &f, uint32 index
     ic::PICInfo &pic = script->pics[index];
     JS_ASSERT(pic.isSet());
     JSAtom *atom = pic.atom;
 
     JSObject *obj = ValueToObject(f.cx, &f.regs.sp[-2]);
     if (!obj)
         THROW();
     Value rval = f.regs.sp[-1];
-    if (!obj->setProperty(f.cx, ATOM_TO_JSID(atom), &f.regs.sp[-1]))
+    if (!obj->setProperty(f.cx, ATOM_TO_JSID(atom), &f.regs.sp[-1],
+                          script->strictModeCode))
         THROW();
     f.regs.sp[-2] = rval;
 }
 
 static void JS_FASTCALL
 SetPropSlow(VMFrame &f, uint32 index)
 {
     JSScript *script = f.fp()->script();
     ic::PICInfo &pic = script->pics[index];
     JS_ASSERT(pic.isSet());
 
     JSAtom *atom = pic.atom;
-    stubs::SetName(f, atom);
+    STRICT_VARIANT(stubs::SetName)(f, atom);
 }
 
 void JS_FASTCALL
 ic::SetProp(VMFrame &f, uint32 index)
 {
     JSObject *obj = ValueToObject(f.cx, &f.regs.sp[-2]);
     if (!obj)
         THROW();
--- a/js/src/methodjit/PunboxAssembler.h
+++ b/js/src/methodjit/PunboxAssembler.h
@@ -127,16 +127,27 @@ class Assembler : public BaseAssembler
 
         move(Registers::PayloadMaskReg, payload);
         andPtr(type, payload);
         xorPtr(payload, type);
 
         return l;
     }
 
+    Label loadValueAsComponents(BaseIndex address, RegisterID type, RegisterID payload) {
+        loadValue(address, type);
+        Label l = label();
+
+        move(Registers::PayloadMaskReg, payload);
+        andPtr(type, payload);
+        xorPtr(payload, type);
+
+        return l;
+    }
+
     void loadTypeTag(Address address, RegisterID reg) {
         loadValue(address, reg);
         convertValueToType(reg);
     }
 
     void loadTypeTag(BaseIndex address, RegisterID reg) {
         loadValue(address, reg);
         convertValueToType(reg);
--- a/js/src/methodjit/StubCalls.cpp
+++ b/js/src/methodjit/StubCalls.cpp
@@ -98,16 +98,17 @@ stubs::BindName(VMFrame &f)
 }
 
 JSObject * JS_FASTCALL
 stubs::BindGlobalName(VMFrame &f)
 {
     return f.fp()->scopeChain().getGlobal();
 }
 
+template<JSBool strict>
 void JS_FASTCALL
 stubs::SetName(VMFrame &f, JSAtom *origAtom)
 {
     JSContext *cx = f.cx;
 
     Value rval = f.regs.sp[-1];
     Value &lref = f.regs.sp[-2];
     JSObject *obj = ValueToObject(cx, &lref);
@@ -261,50 +262,61 @@ stubs::SetName(VMFrame &f, JSAtom *origA
             uintN defineHow;
             JSOp op = JSOp(*f.regs.pc);
             if (op == JSOP_SETMETHOD)
                 defineHow = JSDNP_CACHE_RESULT | JSDNP_SET_METHOD;
             else if (op == JSOP_SETNAME)
                 defineHow = JSDNP_CACHE_RESULT | JSDNP_UNQUALIFIED;
             else
                 defineHow = JSDNP_CACHE_RESULT;
-            if (!js_SetPropertyHelper(cx, obj, id, defineHow, &rval))
+            if (!js_SetPropertyHelper(cx, obj, id, defineHow, &rval, strict))
                 THROW();
         } else {
-            if (!obj->setProperty(cx, id, &rval))
+            if (!obj->setProperty(cx, id, &rval, strict))
                 THROW();
         }
     } while (0);
 
     f.regs.sp[-2] = f.regs.sp[-1];
 }
 
+template void JS_FASTCALL stubs::SetName<true>(VMFrame &f, JSAtom *origAtom);
+template void JS_FASTCALL stubs::SetName<false>(VMFrame &f, JSAtom *origAtom);
+
+template<JSBool strict>
 void JS_FASTCALL
 stubs::SetGlobalNameDumb(VMFrame &f, JSAtom *atom)
 {
     JSContext *cx = f.cx;
 
     Value rval = f.regs.sp[-1];
     Value &lref = f.regs.sp[-2];
     JSObject *obj = ValueToObject(cx, &lref);
     if (!obj)
         THROW();
     jsid id = ATOM_TO_JSID(atom);
-    if (!obj->setProperty(cx, id, &rval))
+    if (!obj->setProperty(cx, id, &rval, strict))
         THROW();
 
     f.regs.sp[-2] = f.regs.sp[-1];
 }
 
+template void JS_FASTCALL stubs::SetGlobalNameDumb<true>(VMFrame &f, JSAtom *atom);
+template void JS_FASTCALL stubs::SetGlobalNameDumb<false>(VMFrame &f, JSAtom *atom);
+
+template<JSBool strict>
 void JS_FASTCALL
 stubs::SetGlobalName(VMFrame &f, JSAtom *atom)
 {
-    SetName(f, atom);
+    SetName<strict>(f, atom);
 }
 
+template void JS_FASTCALL stubs::SetGlobalName<true>(VMFrame &f, JSAtom *atom);
+template void JS_FASTCALL stubs::SetGlobalName<false>(VMFrame &f, JSAtom *atom);
+
 static JSObject *
 NameOp(VMFrame &f, JSObject *obj, bool callname = false)
 {
     JSContext *cx = f.cx;
 
     const Shape *shape;
     Value rval;
 
@@ -433,16 +445,17 @@ IteratorNext(JSContext *cx, JSObject *it
             *rval = *ni->currentValue();
             ni->incValueCursor();
             return true;
         }
     }
     return js_IteratorNext(cx, iterobj, rval);
 }
 
+template<JSBool strict>
 void JS_FASTCALL
 stubs::ForName(VMFrame &f, JSAtom *atom)
 {
     JSContext *cx = f.cx;
     JSFrameRegs &regs = f.regs;
 
     JS_ASSERT(regs.sp - 1 >= f.fp()->base());
     jsid id = ATOM_TO_JSID(atom);
@@ -452,21 +465,24 @@ stubs::ForName(VMFrame &f, JSAtom *atom)
         THROW();
     if (prop)
         obj2->dropProperty(cx, prop);
     {
         AutoValueRooter tvr(cx);
         JS_ASSERT(regs.sp[-1].isObject());
         if (!IteratorNext(cx, &regs.sp[-1].toObject(), tvr.addr()))
             THROW();
-        if (!obj->setProperty(cx, id, tvr.addr()))
+        if (!obj->setProperty(cx, id, tvr.addr(), strict))
             THROW();
     }
 }
 
+template void JS_FASTCALL stubs::ForName<true>(VMFrame &f, JSAtom *atom);
+template void JS_FASTCALL stubs::ForName<false>(VMFrame &f, JSAtom *atom);
+
 void JS_FASTCALL
 stubs::GetElem(VMFrame &f)
 {
     JSContext *cx = f.cx;
     JSFrameRegs &regs = f.regs;
 
     Value &lref = regs.sp[-2];
     Value &rref = regs.sp[-1];
@@ -577,16 +593,17 @@ stubs::CallElem(VMFrame &f)
             THROW();
     } else
 #endif
     {
         regs.sp[-1].setObject(*obj);
     }
 }
 
+template<JSBool strict>
 void JS_FASTCALL
 stubs::SetElem(VMFrame &f)
 {
     JSContext *cx = f.cx;
     JSFrameRegs &regs = f.regs;
 
     Value &objval = regs.sp[-3];
     Value &idval  = regs.sp[-2];
@@ -613,26 +630,29 @@ stubs::SetElem(VMFrame &f)
                     if ((jsuint)i >= obj->getArrayLength())
                         obj->setArrayLength(i + 1);
                 }
                 obj->setDenseArrayElement(i, regs.sp[-1]);
                 goto end_setelem;
             }
         }
     } while (0);
-    if (!obj->setProperty(cx, id, &retval))
+    if (!obj->setProperty(cx, id, &retval, strict))
         THROW();
   end_setelem:
     /* :FIXME: Moving the assigned object into the lowest stack slot
      * is a temporary hack. What we actually want is an implementation
      * of popAfterSet() that allows popping more than one value;
      * this logic can then be handled in Compiler.cpp. */
     regs.sp[-3] = retval;
 }
 
+template void JS_FASTCALL stubs::SetElem<true>(VMFrame &f);
+template void JS_FASTCALL stubs::SetElem<false>(VMFrame &f);
+
 void JS_FASTCALL
 stubs::CallName(VMFrame &f)
 {
     JSObject *obj = NameOp(f, &f.fp()->scopeChain(), true);
     if (!obj)
         THROW();
 }
 
@@ -818,16 +838,17 @@ stubs::DecLocal(VMFrame &f, uint32 slot)
 {
     double d;
     if (!ValueToNumber(f.cx, f.regs.sp[-1], &d))
         THROW();
     f.regs.sp[-1].setNumber(d - 1);
     f.fp()->slots()[slot] = f.regs.sp[-1];
 }
 
+template<JSBool strict>
 void JS_FASTCALL
 stubs::DefFun(VMFrame &f, JSFunction *fun)
 {
     JSObject *obj2;
 
     JSContext *cx = f.cx;
     JSStackFrame *fp = f.fp();
 
@@ -933,22 +954,25 @@ stubs::DefFun(VMFrame &f, JSFunction *fu
             JS_ASSERT(!(attrs & ~(JSPROP_ENUMERATE|JSPROP_PERMANENT)));
             JS_ASSERT(!(old & JSPROP_READONLY));
             doSet = true;
         }
         pobj->dropProperty(cx, prop);
     }
     Value rval = ObjectValue(*obj);
     ok = doSet
-         ? parent->setProperty(cx, id, &rval)
+         ? parent->setProperty(cx, id, &rval, strict)
          : parent->defineProperty(cx, id, rval, PropertyStub, PropertyStub, attrs);
     if (!ok)
         THROW();
 }
 
+template void JS_FASTCALL stubs::DefFun<true>(VMFrame &f, JSFunction *fun);
+template void JS_FASTCALL stubs::DefFun<false>(VMFrame &f, JSFunction *fun);
+
 #define DEFAULT_VALUE(cx, n, hint, v)                                         \
     JS_BEGIN_MACRO                                                            \
         JS_ASSERT(v.isObject());                                              \
         JS_ASSERT(v == regs.sp[n]);                                           \
         if (!DefaultValue(cx, &v.toObject(), hint, &regs.sp[n]))              \
             THROWV(JS_FALSE);                                                 \
         v = regs.sp[n];                                                       \
     JS_END_MACRO
@@ -1645,17 +1669,17 @@ stubs::Lambda(VMFrame &f, JSFunction *fu
 
 /* Test whether v is an int in the range [-2^31 + 1, 2^31 - 2] */
 static JS_ALWAYS_INLINE bool
 CanIncDecWithoutOverflow(int32_t i)
 {
     return (i > JSVAL_INT_MIN) && (i < JSVAL_INT_MAX);
 }
 
-template <int32 N, bool POST>
+template <int32 N, bool POST, JSBool strict>
 static inline bool
 ObjIncOp(VMFrame &f, JSObject *obj, jsid id)
 {
     JSContext *cx = f.cx;
     JSStackFrame *fp = f.fp();
 
     f.regs.sp[0].setNull();
     f.regs.sp++;
@@ -1665,17 +1689,17 @@ ObjIncOp(VMFrame &f, JSObject *obj, jsid
     Value &ref = f.regs.sp[-1];
     int32_t tmp;
     if (JS_LIKELY(ref.isInt32() && CanIncDecWithoutOverflow(tmp = ref.toInt32()))) {
         if (POST)
             ref.getInt32Ref() = tmp + N;
         else
             ref.getInt32Ref() = tmp += N;
         fp->setAssigning();
-        JSBool ok = obj->setProperty(cx, id, &ref);
+        JSBool ok = obj->setProperty(cx, id, &ref, strict);
         fp->clearAssigning();
         if (!ok)
             return false;
 
         /*
          * We must set regs.sp[-1] to tmp for both post and pre increments
          * as the setter overwrites regs.sp[-1].
          */
@@ -1689,26 +1713,26 @@ ObjIncOp(VMFrame &f, JSObject *obj, jsid
             ref.setDouble(d);
             d += N;
         } else {
             d += N;
             ref.setDouble(d);
         }
         v.setDouble(d);
         fp->setAssigning();
-        JSBool ok = obj->setProperty(cx, id, &v);
+        JSBool ok = obj->setProperty(cx, id, &v, strict);
         fp->clearAssigning();
         if (!ok)
             return false;
     }
 
     return true;
 }
 
-template <int32 N, bool POST>
+template <int32 N, bool POST, JSBool strict>
 static inline bool
 NameIncDec(VMFrame &f, JSObject *obj, JSAtom *origAtom)
 {
     JSContext *cx = f.cx;
 
     JSAtom *atom;
     JSObject *obj2;
     JSProperty *prop;
@@ -1735,183 +1759,247 @@ NameIncDec(VMFrame &f, JSObject *obj, JS
     jsid id = ATOM_TO_JSID(atom);
     if (!js_FindPropertyHelper(cx, id, true, &obj, &obj2, &prop))
         return false;
     if (!prop) {
         ReportAtomNotDefined(cx, atom);
         return false;
     }
     obj2->dropProperty(cx, prop);
-    return ObjIncOp<N, POST>(f, obj, id);
+    return ObjIncOp<N, POST, strict>(f, obj, id);
 }
 
+template<JSBool strict>
 void JS_FASTCALL
 stubs::PropInc(VMFrame &f, JSAtom *atom)
 {
     JSObject *obj = ValueToObject(f.cx, &f.regs.sp[-1]);
     if (!obj)
         THROW();
-    if (!ObjIncOp<1, true>(f, obj, ATOM_TO_JSID(atom)))
+    if (!ObjIncOp<1, true, strict>(f, obj, ATOM_TO_JSID(atom)))
         THROW();
     f.regs.sp[-2] = f.regs.sp[-1];
 }
 
+template void JS_FASTCALL stubs::PropInc<true>(VMFrame &f, JSAtom *atom);
+template void JS_FASTCALL stubs::PropInc<false>(VMFrame &f, JSAtom *atom);
+
+template<JSBool strict>
 void JS_FASTCALL
 stubs::PropDec(VMFrame &f, JSAtom *atom)
 {
     JSObject *obj = ValueToObject(f.cx, &f.regs.sp[-1]);
     if (!obj)
         THROW();
-    if (!ObjIncOp<-1, true>(f, obj, ATOM_TO_JSID(atom)))
+    if (!ObjIncOp<-1, true, strict>(f, obj, ATOM_TO_JSID(atom)))
         THROW();
     f.regs.sp[-2] = f.regs.sp[-1];
 }
 
+template void JS_FASTCALL stubs::PropDec<true>(VMFrame &f, JSAtom *atom);
+template void JS_FASTCALL stubs::PropDec<false>(VMFrame &f, JSAtom *atom);
+
+template<JSBool strict>
 void JS_FASTCALL
 stubs::IncProp(VMFrame &f, JSAtom *atom)
 {
     JSObject *obj = ValueToObject(f.cx, &f.regs.sp[-1]);
     if (!obj)
         THROW();
-    if (!ObjIncOp<1, false>(f, obj, ATOM_TO_JSID(atom)))
+    if (!ObjIncOp<1, false, strict>(f, obj, ATOM_TO_JSID(atom)))
         THROW();
     f.regs.sp[-2] = f.regs.sp[-1];
 }
 
+template void JS_FASTCALL stubs::IncProp<true>(VMFrame &f, JSAtom *atom);
+template void JS_FASTCALL stubs::IncProp<false>(VMFrame &f, JSAtom *atom);
+
+template<JSBool strict>
 void JS_FASTCALL
 stubs::DecProp(VMFrame &f, JSAtom *atom)
 {
     JSObject *obj = ValueToObject(f.cx, &f.regs.sp[-1]);
     if (!obj)
         THROW();
-    if (!ObjIncOp<-1, false>(f, obj, ATOM_TO_JSID(atom)))
+    if (!ObjIncOp<-1, false, strict>(f, obj, ATOM_TO_JSID(atom)))
         THROW();
     f.regs.sp[-2] = f.regs.sp[-1];
 }
 
+template void JS_FASTCALL stubs::DecProp<true>(VMFrame &f, JSAtom *atom);
+template void JS_FASTCALL stubs::DecProp<false>(VMFrame &f, JSAtom *atom);
+
+template<JSBool strict>
 void JS_FASTCALL
 stubs::ElemInc(VMFrame &f)
 {
     JSObject *obj = ValueToObject(f.cx, &f.regs.sp[-2]);
     if (!obj)
         THROW();
     jsid id;
     if (!FetchElementId(f, obj, f.regs.sp[-1], id, &f.regs.sp[-1]))
         THROW();
-    if (!ObjIncOp<1, true>(f, obj, id))
+    if (!ObjIncOp<1, true, strict>(f, obj, id))
         THROW();
     f.regs.sp[-3] = f.regs.sp[-1];
 }
 
+template void JS_FASTCALL stubs::ElemInc<true>(VMFrame &f);
+template void JS_FASTCALL stubs::ElemInc<false>(VMFrame &f);
+
+template<JSBool strict>
 void JS_FASTCALL
 stubs::ElemDec(VMFrame &f)
 {
     JSObject *obj = ValueToObject(f.cx, &f.regs.sp[-2]);
     if (!obj)
         THROW();
     jsid id;
     if (!FetchElementId(f, obj, f.regs.sp[-1], id, &f.regs.sp[-1]))
         THROW();
-    if (!ObjIncOp<-1, true>(f, obj, id))
+    if (!ObjIncOp<-1, true, strict>(f, obj, id))
         THROW();
     f.regs.sp[-3] = f.regs.sp[-1];
 }
 
+template void JS_FASTCALL stubs::ElemDec<true>(VMFrame &f);
+template void JS_FASTCALL stubs::ElemDec<false>(VMFrame &f);
+
+template<JSBool strict>
 void JS_FASTCALL
 stubs::IncElem(VMFrame &f)
 {
     JSObject *obj = ValueToObject(f.cx, &f.regs.sp[-2]);
     if (!obj)
         THROW();
     jsid id;
     if (!FetchElementId(f, obj, f.regs.sp[-1], id, &f.regs.sp[-1]))
         THROW();
-    if (!ObjIncOp<1, false>(f, obj, id))
+    if (!ObjIncOp<1, false, strict>(f, obj, id))
         THROW();
     f.regs.sp[-3] = f.regs.sp[-1];
 }
 
+template void JS_FASTCALL stubs::IncElem<true>(VMFrame &f);
+template void JS_FASTCALL stubs::IncElem<false>(VMFrame &f);
+
+template<JSBool strict>
 void JS_FASTCALL
 stubs::DecElem(VMFrame &f)
 {
     JSObject *obj = ValueToObject(f.cx, &f.regs.sp[-2]);
     if (!obj)
         THROW();
     jsid id;
     if (!FetchElementId(f, obj, f.regs.sp[-1], id, &f.regs.sp[-1]))
         THROW();
-    if (!ObjIncOp<-1, false>(f, obj, id))
+    if (!ObjIncOp<-1, false, strict>(f, obj, id))
         THROW();
     f.regs.sp[-3] = f.regs.sp[-1];
 }
 
+template void JS_FASTCALL stubs::DecElem<true>(VMFrame &f);
+template void JS_FASTCALL stubs::DecElem<false>(VMFrame &f);
+
+template<JSBool strict>
 void JS_FASTCALL
 stubs::NameInc(VMFrame &f, JSAtom *atom)
 {
     JSObject *obj = &f.fp()->scopeChain();
-    if (!NameIncDec<1, true>(f, obj, atom))
+    if (!NameIncDec<1, true, strict>(f, obj, atom))
         THROW();
 }
 
+template void JS_FASTCALL stubs::NameInc<true>(VMFrame &f, JSAtom *atom);
+template void JS_FASTCALL stubs::NameInc<false>(VMFrame &f, JSAtom *atom);
+
+template<JSBool strict>
 void JS_FASTCALL
 stubs::NameDec(VMFrame &f, JSAtom *atom)
 {
     JSObject *obj = &f.fp()->scopeChain();
-    if (!NameIncDec<-1, true>(f, obj, atom))
+    if (!NameIncDec<-1, true, strict>(f, obj, atom))
         THROW();
 }
 
+template void JS_FASTCALL stubs::NameDec<true>(VMFrame &f, JSAtom *atom);
+template void JS_FASTCALL stubs::NameDec<false>(VMFrame &f, JSAtom *atom);
+
+template<JSBool strict>
 void JS_FASTCALL
 stubs::IncName(VMFrame &f, JSAtom *atom)
 {
     JSObject *obj = &f.fp()->scopeChain();
-    if (!NameIncDec<1, false>(f, obj, atom))
+    if (!NameIncDec<1, false, strict>(f, obj, atom))
         THROW();
 }
 
+template void JS_FASTCALL stubs::IncName<true>(VMFrame &f, JSAtom *atom);
+template void JS_FASTCALL stubs::IncName<false>(VMFrame &f, JSAtom *atom);
+
+template<JSBool strict>
 void JS_FASTCALL
 stubs::DecName(VMFrame &f, JSAtom *atom)
 {
     JSObject *obj = &f.fp()->scopeChain();
-    if (!NameIncDec<-1, false>(f, obj, atom))
+    if (!NameIncDec<-1, false, strict>(f, obj, atom))
         THROW();
 }
 
+template void JS_FASTCALL stubs::DecName<true>(VMFrame &f, JSAtom *atom);
+template void JS_FASTCALL stubs::DecName<false>(VMFrame &f, JSAtom *atom);
+
+template<JSBool strict>
 void JS_FASTCALL
 stubs::GlobalNameInc(VMFrame &f, JSAtom *atom)
 {
     JSObject *obj = f.fp()->scopeChain().getGlobal();
-    if (!NameIncDec<1, true>(f, obj, atom))
+    if (!NameIncDec<1, true, strict>(f, obj, atom))
         THROW();
 }
 
+template void JS_FASTCALL stubs::GlobalNameInc<true>(VMFrame &f, JSAtom *atom);
+template void JS_FASTCALL stubs::GlobalNameInc<false>(VMFrame &f, JSAtom *atom);
+
+template<JSBool strict>
 void JS_FASTCALL
 stubs::GlobalNameDec(VMFrame &f, JSAtom *atom)
 {
     JSObject *obj = f.fp()->scopeChain().getGlobal();
-    if (!NameIncDec<-1, true>(f, obj, atom))
+    if (!NameIncDec<-1, true, strict>(f, obj, atom))
         THROW();
 }
 
+template void JS_FASTCALL stubs::GlobalNameDec<true>(VMFrame &f, JSAtom *atom);
+template void JS_FASTCALL stubs::GlobalNameDec<false>(VMFrame &f, JSAtom *atom);
+
+template<JSBool strict>
 void JS_FASTCALL
 stubs::IncGlobalName(VMFrame &f, JSAtom *atom)
 {
     JSObject *obj = f.fp()->scopeChain().getGlobal();
-    if (!NameIncDec<1, false>(f, obj, atom))
+    if (!NameIncDec<1, false, strict>(f, obj, atom))
         THROW();
 }
 
+template void JS_FASTCALL stubs::IncGlobalName<true>(VMFrame &f, JSAtom *atom);
+template void JS_FASTCALL stubs::IncGlobalName<false>(VMFrame &f, JSAtom *atom);
+
+template<JSBool strict>
 void JS_FASTCALL
 stubs::DecGlobalName(VMFrame &f, JSAtom *atom)
 {
     JSObject *obj = f.fp()->scopeChain().getGlobal();
-    if (!NameIncDec<-1, false>(f, obj, atom))
+    if (!NameIncDec<-1, false, strict>(f, obj, atom))
         THROW();
 }
 
+template void JS_FASTCALL stubs::DecGlobalName<true>(VMFrame &f, JSAtom *atom);
+template void JS_FASTCALL stubs::DecGlobalName<false>(VMFrame &f, JSAtom *atom);
+
 static bool JS_FASTCALL
 InlineGetProp(VMFrame &f)
 {
     JSContext *cx = f.cx;
     JSFrameRegs &regs = f.regs;
 
     Value *vp = &f.regs.sp[-1];
     JSObject *obj = ValueToObject(f.cx, vp);
@@ -2196,17 +2284,17 @@ InitPropOrMethod(VMFrame &f, JSAtom *ato
         jsid id = ATOM_TO_JSID(atom);
 
         /* No need to check for duplicate property; the compiler already did. */
 
         uintN defineHow = (op == JSOP_INITMETHOD)
                           ? JSDNP_CACHE_RESULT | JSDNP_SET_METHOD
                           : JSDNP_CACHE_RESULT;
         if (!(JS_UNLIKELY(atom == cx->runtime->atomState.protoAtom)
-              ? js_SetPropertyHelper(cx, obj, id, defineHow, &rval)
+              ? js_SetPropertyHelper(cx, obj, id, defineHow, &rval, false)
               : js_DefineNativeProperty(cx, obj, id, rval, NULL, NULL,
                                         JSPROP_ENUMERATE, 0, 0, NULL,
                                         defineHow))) {
             THROW();
         }
     }
 }
 
@@ -2572,8 +2660,136 @@ stubs::ArgSub(VMFrame &f, uint32 n)
 {
     jsid id = INT_TO_JSID(n);
     Value rval;
     if (!js_GetArgsProperty(f.cx, f.fp(), id, &rval))
         THROW();
     f.regs.sp[0] = rval;
 }
 
+void JS_FASTCALL
+stubs::DelName(VMFrame &f, JSAtom *atom)
+{
+    jsid id = ATOM_TO_JSID(atom);
+    JSObject *obj, *obj2;
+    JSProperty *prop;
+    if (!js_FindProperty(f.cx, id, &obj, &obj2, &prop))
+        THROW();
+
+    /* Strict mode code should never contain JSOP_DELNAME opcodes. */
+    JS_ASSERT(!f.fp()->script()->strictModeCode);
+
+    /* ECMA says to return true if name is undefined or inherited. */
+    f.regs.sp++;
+    f.regs.sp[-1] = BooleanValue(true);
+    if (prop) {
+        obj2->dropProperty(f.cx, prop);
+        if (!obj->deleteProperty(f.cx, id, &f.regs.sp[-1], false))
+            THROW();
+    }
+}
+
+template<JSBool strict>
+void JS_FASTCALL
+stubs::DelProp(VMFrame &f, JSAtom *atom)
+{
+    JSContext *cx = f.cx;
+
+    JSObject *obj = ValueToObject(cx, &f.regs.sp[-1]);
+    if (!obj)
+        THROW();
+
+    Value rval;
+    if (!obj->deleteProperty(cx, ATOM_TO_JSID(atom), &rval, strict))
+        THROW();
+
+    f.regs.sp[-1] = rval;
+}
+
+template void JS_FASTCALL stubs::DelProp<true>(VMFrame &f, JSAtom *atom);
+template void JS_FASTCALL stubs::DelProp<false>(VMFrame &f, JSAtom *atom);
+
+template<JSBool strict>
+void JS_FASTCALL
+stubs::DelElem(VMFrame &f)
+{
+    JSContext *cx = f.cx;
+
+    JSObject *obj = ValueToObject(cx, &f.regs.sp[-2]);
+    if (!obj)
+        THROW();
+
+    jsid id;
+    if (!FetchElementId(f, obj, f.regs.sp[-1], id, &f.regs.sp[-1]))
+        THROW();
+
+    if (!obj->deleteProperty(cx, id, &f.regs.sp[-2], strict))
+        THROW();
+}
+
+void JS_FASTCALL
+stubs::DefVar(VMFrame &f, JSAtom *atom)
+{
+    JSContext *cx = f.cx;
+    JSStackFrame *fp = f.fp();
+
+    JSObject *obj = &fp->varobj(cx);
+    JS_ASSERT(!obj->getOps()->defineProperty);
+    uintN attrs = JSPROP_ENUMERATE;
+    if (!fp->isEvalFrame())
+        attrs |= JSPROP_PERMANENT;
+
+    /* Lookup id in order to check for redeclaration problems. */
+    jsid id = ATOM_TO_JSID(atom);
+    JSProperty *prop = NULL;
+    JSObject *obj2;
+
+    /*
+     * Redundant declaration of a |var|, even one for a non-writable
+     * property like |undefined| in ES5, does nothing.
+     */
+    if (!obj->lookupProperty(cx, id, &obj2, &prop))
+        THROW();
+
+    /* Bind a variable only if it's not yet defined. */
+    if (!prop) {
+        if (!js_DefineNativeProperty(cx, obj, id, UndefinedValue(), PropertyStub, PropertyStub,
+                                     attrs, 0, 0, &prop)) {
+            THROW();
+        }
+        JS_ASSERT(prop);
+        obj2 = obj;
+    }
+
+    obj2->dropProperty(cx, prop);
+}
+
+JSBool JS_FASTCALL
+stubs::In(VMFrame &f)
+{
+    JSContext *cx = f.cx;
+
+    const Value &rref = f.regs.sp[-1];
+    if (!rref.isObject()) {
+        js_ReportValueError(cx, JSMSG_IN_NOT_OBJECT, -1, rref, NULL);
+        THROWV(JS_FALSE);
+    }
+
+    JSObject *obj = &rref.toObject();
+    jsid id;
+    if (!FetchElementId(f, obj, f.regs.sp[-2], id, &f.regs.sp[-2]))
+        THROWV(JS_FALSE);
+
+    JSObject *obj2;
+    JSProperty *prop;
+    if (!obj->lookupProperty(cx, id, &obj2, &prop))
+        THROWV(JS_FALSE);
+
+    JSBool cond = !!prop;
+    if (prop)
+        obj2->dropProperty(cx, prop);
+
+    return cond;
+}
+
+template void JS_FASTCALL stubs::DelElem<true>(VMFrame &f);
+template void JS_FASTCALL stubs::DelElem<false>(VMFrame &f);
+
--- a/js/src/methodjit/StubCalls.h
+++ b/js/src/methodjit/StubCalls.h
@@ -62,16 +62,47 @@ void JS_FASTCALL InitMethod(VMFrame &f, 
 void JS_FASTCALL HitStackQuota(VMFrame &f);
 void * JS_FASTCALL FixupArity(VMFrame &f, uint32 argc);
 void * JS_FASTCALL CompileFunction(VMFrame &f, uint32 argc);
 void JS_FASTCALL SlowNew(VMFrame &f, uint32 argc);
 void JS_FASTCALL SlowCall(VMFrame &f, uint32 argc);
 void * JS_FASTCALL UncachedNew(VMFrame &f, uint32 argc);
 void * JS_FASTCALL UncachedCall(VMFrame &f, uint32 argc);
 
+/*
+ * Result struct for UncachedXHelper.
+ *
+ * These functions can have one of two results:
+ *
+ *   (1) The function was executed in the interpreter. Then all fields
+ *       are NULL.
+ *
+ *   (2) The function was not executed, and the function has been compiled
+ *       to JM native code. Then all fields are non-NULL.
+ */
+struct UncachedCallResult {
+    JSObject   *callee;       // callee object
+    JSFunction *fun;          // callee function
+    void       *codeAddr;     // code address of compiled callee function
+
+    void init() {
+        callee = NULL;
+        fun = NULL;
+        codeAddr = NULL;
+    }        
+};
+
+/*
+ * Helper functions for stubs and IC functions for calling functions.
+ * These functions either execute the function, return a native code
+ * pointer that can be used to call the function, or throw.
+ */
+void UncachedCallHelper(VMFrame &f, uint32 argc, UncachedCallResult *ucr);
+void UncachedNewHelper(VMFrame &f, uint32 argc, UncachedCallResult *ucr);
+
 JSBool JS_FASTCALL NewObject(VMFrame &f, uint32 argc);
 void JS_FASTCALL Throw(VMFrame &f);
 void JS_FASTCALL PutCallObject(VMFrame &f);
 void JS_FASTCALL PutActivationObjects(VMFrame &f);
 void JS_FASTCALL GetCallObject(VMFrame &f);
 void JS_FASTCALL WrapPrimitiveThis(VMFrame &f);
 #if JS_MONOIC
 void * JS_FASTCALL InvokeTracer(VMFrame &f, uint32 index);
@@ -79,48 +110,53 @@ void * JS_FASTCALL InvokeTracer(VMFrame 
 void * JS_FASTCALL InvokeTracer(VMFrame &f);
 #endif
 
 void * JS_FASTCALL LookupSwitch(VMFrame &f, jsbytecode *pc);
 void * JS_FASTCALL TableSwitch(VMFrame &f, jsbytecode *origPc);
 
 void JS_FASTCALL BindName(VMFrame &f);
 JSObject * JS_FASTCALL BindGlobalName(VMFrame &f);
-void JS_FASTCALL SetName(VMFrame &f, JSAtom *atom);
-void JS_FASTCALL SetGlobalName(VMFrame &f, JSAtom *atom);
-void JS_FASTCALL SetGlobalNameDumb(VMFrame &f, JSAtom *atom);
+template<JSBool strict> void JS_FASTCALL SetName(VMFrame &f, JSAtom *atom);
+template<JSBool strict> void JS_FASTCALL SetGlobalName(VMFrame &f, JSAtom *atom);
+template<JSBool strict> void JS_FASTCALL SetGlobalNameDumb(VMFrame &f, JSAtom *atom);
 void JS_FASTCALL Name(VMFrame &f);
 void JS_FASTCALL GetProp(VMFrame &f);
 void JS_FASTCALL GetElem(VMFrame &f);
 void JS_FASTCALL CallElem(VMFrame &f);
-void JS_FASTCALL SetElem(VMFrame &f);
+template<JSBool strict> void JS_FASTCALL SetElem(VMFrame &f);
 void JS_FASTCALL Length(VMFrame &f);
 void JS_FASTCALL CallName(VMFrame &f);
 void JS_FASTCALL GetUpvar(VMFrame &f, uint32 index);
 void JS_FASTCALL GetGlobalName(VMFrame &f);
 
-void JS_FASTCALL NameInc(VMFrame &f, JSAtom *atom);
-void JS_FASTCALL NameDec(VMFrame &f, JSAtom *atom);
-void JS_FASTCALL IncName(VMFrame &f, JSAtom *atom);
-void JS_FASTCALL DecName(VMFrame &f, JSAtom *atom);
-void JS_FASTCALL GlobalNameInc(VMFrame &f, JSAtom *atom);
-void JS_FASTCALL GlobalNameDec(VMFrame &f, JSAtom *atom);
-void JS_FASTCALL IncGlobalName(VMFrame &f, JSAtom *atom);
-void JS_FASTCALL DecGlobalName(VMFrame &f, JSAtom *atom);
-void JS_FASTCALL PropInc(VMFrame &f, JSAtom *atom);
-void JS_FASTCALL PropDec(VMFrame &f, JSAtom *atom);
-void JS_FASTCALL IncProp(VMFrame &f, JSAtom *atom);
-void JS_FASTCALL DecProp(VMFrame &f, JSAtom *atom);
-void JS_FASTCALL ElemInc(VMFrame &f);
-void JS_FASTCALL ElemDec(VMFrame &f);
-void JS_FASTCALL IncElem(VMFrame &f);
-void JS_FASTCALL DecElem(VMFrame &f);
+template<JSBool strict> void JS_FASTCALL NameInc(VMFrame &f, JSAtom *atom);
+template<JSBool strict> void JS_FASTCALL NameDec(VMFrame &f, JSAtom *atom);
+template<JSBool strict> void JS_FASTCALL IncName(VMFrame &f, JSAtom *atom);
+template<JSBool strict> void JS_FASTCALL DecName(VMFrame &f, JSAtom *atom);
+template<JSBool strict> void JS_FASTCALL GlobalNameInc(VMFrame &f, JSAtom *atom);
+template<JSBool strict> void JS_FASTCALL GlobalNameDec(VMFrame &f, JSAtom *atom);
+template<JSBool strict> void JS_FASTCALL IncGlobalName(VMFrame &f, JSAtom *atom);
+template<JSBool strict> void JS_FASTCALL DecGlobalName(VMFrame &f, JSAtom *atom);
+template<JSBool strict> void JS_FASTCALL PropInc(VMFrame &f, JSAtom *atom);
+template<JSBool strict> void JS_FASTCALL PropDec(VMFrame &f, JSAtom *atom);
+template<JSBool strict> void JS_FASTCALL IncProp(VMFrame &f, JSAtom *atom);
+template<JSBool strict> void JS_FASTCALL DecProp(VMFrame &f, JSAtom *atom);
+template<JSBool strict> void JS_FASTCALL ElemInc(VMFrame &f);
+template<JSBool strict> void JS_FASTCALL ElemDec(VMFrame &f);
+template<JSBool strict> void JS_FASTCALL IncElem(VMFrame &f);
+template<JSBool strict> void JS_FASTCALL DecElem(VMFrame &f);
 void JS_FASTCALL CallProp(VMFrame &f, JSAtom *atom);
+template <JSBool strict> void JS_FASTCALL DelProp(VMFrame &f, JSAtom *atom);
+template <JSBool strict> void JS_FASTCALL DelElem(VMFrame &f);
+void JS_FASTCALL DelName(VMFrame &f, JSAtom *atom);
+JSBool JS_FASTCALL In(VMFrame &f);
 
-void JS_FASTCALL DefFun(VMFrame &f, JSFunction *fun);
+void JS_FASTCALL DefVar(VMFrame &f, JSAtom *atom);
+template<JSBool strict> void JS_FASTCALL DefFun(VMFrame &f, JSFunction *fun);
 JSObject * JS_FASTCALL DefLocalFun(VMFrame &f, JSFunction *fun);
 JSObject * JS_FASTCALL DefLocalFun_FC(VMFrame &f, JSFunction *fun);
 JSObject * JS_FASTCALL RegExp(VMFrame &f, JSObject *regex);
 JSObject * JS_FASTCALL Lambda(VMFrame &f, JSFunction *fun);
 JSObject * JS_FASTCALL LambdaForInit(VMFrame &f, JSFunction *fun);
 JSObject * JS_FASTCALL LambdaForSet(VMFrame &f, JSFunction *fun);
 JSObject * JS_FASTCALL LambdaJoinableForCall(VMFrame &f, JSFunction *fun);
 JSObject * JS_FASTCALL LambdaJoinableForNull(VMFrame &f, JSFunction *fun);
@@ -163,24 +199,42 @@ void JS_FASTCALL Pos(VMFrame &f);
 void JS_FASTCALL Not(VMFrame &f);
 void JS_FASTCALL StrictEq(VMFrame &f);
 void JS_FASTCALL StrictNe(VMFrame &f);
 
 void JS_FASTCALL Iter(VMFrame &f, uint32 flags);
 void JS_FASTCALL IterNext(VMFrame &f);
 JSBool JS_FASTCALL IterMore(VMFrame &f);
 void JS_FASTCALL EndIter(VMFrame &f);
-void JS_FASTCALL ForName(VMFrame &f, JSAtom *atom);
+template<JSBool strict> void JS_FASTCALL ForName(VMFrame &f, JSAtom *atom);
 
 JSBool JS_FASTCALL ValueToBoolean(VMFrame &f);
 JSString * JS_FASTCALL TypeOf(VMFrame &f);
 JSBool JS_FASTCALL InstanceOf(VMFrame &f);
 void JS_FASTCALL FastInstanceOf(VMFrame &f);
 void JS_FASTCALL ArgCnt(VMFrame &f);
 void JS_FASTCALL Unbrand(VMFrame &f);
 
-}}} /* namespace stubs,mjit,js */
+} /* namespace stubs */
+
+/* 
+ * If COND is true, return A; otherwise, return B. This allows us to choose between
+ * function template instantiations without running afoul of C++'s overload resolution
+ * rules. (Try simplifying, and you'll either see the problem --- or have found a
+ * better solution!)
+ */
+template<typename FuncPtr>
+inline FuncPtr FunctionTemplateConditional(bool cond, FuncPtr a, FuncPtr b) {
+    return cond ? a : b;
+}
+
+/* Return f<true> if the script is strict mode code, f<false> otherwise. */
+#define STRICT_VARIANT(f)                                                     \
+    (FunctionTemplateConditional(script->strictModeCode,                      \
+                                 f<true>, f<false>))
+
+}} /* namespace stubs,mjit,js */
 
 extern "C" void *
 js_InternalThrow(js::VMFrame &f);
 
 #endif /* jslogic_h__ */
 
--- a/js/src/methodjit/TrampolineCompiler.cpp
+++ b/js/src/methodjit/TrampolineCompiler.cpp
@@ -127,18 +127,17 @@ TrampolineCompiler::generateForceReturn(
     /*
      * r = fp->prev
      * f.fp = r
      */
     masm.loadPtr(Address(JSFrameReg, JSStackFrame::offsetOfPrev()), Registers::ReturnReg);
     masm.storePtr(Registers::ReturnReg, FrameAddress(offsetof(VMFrame, regs.fp)));
 
     Address rval(JSFrameReg, JSStackFrame::offsetOfReturnValue());
-    masm.loadPayload(rval, JSReturnReg_Data);
-    masm.loadTypeTag(rval, JSReturnReg_Type);
+    masm.loadValueAsComponents(rval, JSReturnReg_Type, JSReturnReg_Data);
 
     masm.restoreReturnAddress();
 
     masm.move(Registers::ReturnReg, JSFrameReg);
 #ifdef DEBUG
     masm.storePtr(ImmPtr(JSStackFrame::sInvalidpc),
                   Address(JSFrameReg, JSStackFrame::offsetOfSavedpc()));
 #endif
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -2782,17 +2782,17 @@ split_delProperty(JSContext *cx, JSObjec
 
     cpx = split_get_private(cx, obj);
     if (!cpx)
         return JS_TRUE;
     if (!cpx->isInner && cpx->inner) {
         /* Make sure to define this property on the inner object. */
         if (!JS_ValueToId(cx, *vp, &asId))
             return JS_FALSE;
-        return cpx->inner->deleteProperty(cx, asId, Valueify(vp));
+        return cpx->inner->deleteProperty(cx, asId, Valueify(vp), true);
     }
     return JS_TRUE;
 }
 
 static JSBool
 split_enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
                 jsval *statep, jsid *idp)
 {
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/15.4.4.11.js
@@ -0,0 +1,32 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+function arr() {
+  return Object.defineProperty([20, 10, 30], 0, {writable: false});
+}
+
+assertEq(testLenientAndStrict('var a = arr(); a.sort()',
+                              raisesException(TypeError),
+                              raisesException(TypeError)),
+         true);
+
+function obj() {
+  var o = {0: 20, 1: 10, 2: 30, length: 3};
+  Object.defineProperty(o, 0, {writable: false});
+  return o;
+}
+
+assertEq(testLenientAndStrict('var o = obj(); Array.prototype.sort.call(o)',
+                              raisesException(TypeError), 
+                              raisesException(TypeError)),
+         true);
+
+// The behavior of sort is implementation-defined if the object being
+// sorted is sparse, so I'm not sure how to test its behavior on
+// non-configurable properties.
+
+reportCompare(true, true);
--- a/js/src/tests/ecma_5/extensions/jstests.list
+++ b/js/src/tests/ecma_5/extensions/jstests.list
@@ -1,4 +1,5 @@
 url-prefix ../../jsreftest.html?test=ecma_5/extensions/
-script string-literal-getter-setter-decompilation.js
+script 15.4.4.11.js
 script 8.12.5-01.js
 script regress-bug567606.js
+script string-literal-getter-setter-decompilation.js
--- a/js/src/tests/ecma_5/extensions/shell.js
+++ b/js/src/tests/ecma_5/extensions/shell.js
@@ -1,7 +1,37 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 
 /*
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/licenses/publicdomain/
  */
 
+/*
+ * Return true if both of these return true:
+ * - LENIENT_PRED applied to CODE
+ * - STRICT_PRED applied to CODE with a use strict directive added to the front
+ *
+ * Run STRICT_PRED first, for testing code that affects the global environment
+ * in loose mode, but fails in strict mode.
+ */
+function testLenientAndStrict(code, lenient_pred, strict_pred) {
+  return (strict_pred("'use strict'; " + code) && 
+          lenient_pred(code));
+}
+
+/*
+ * raisesException(EXCEPTION)(CODE) returns true if evaluating CODE (as eval
+ * code) throws an exception object whose prototype is
+ * EXCEPTION.prototype, and returns false if it throws any other error
+ * or evaluates successfully. For example: raises(TypeError)("0()") ==
+ * true.
+ */
+function raisesException(exception) {
+  return function (code) {
+    try {
+      eval(code);
+      return false;
+    } catch (actual) {
+      return exception.prototype.isPrototypeOf(actual);
+    }
+  };
+};
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_5/strict/10.6.js
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+function callFunctionBody(expr) {
+  return (
+    '(function f() {\n'
+    + 'Object.defineProperties(arguments, {1: { writable: false },\n'
+    + '                                    2: { configurable: false },\n'
+    + '                                    3: { writable: false,\n'
+    + '                                        configurable: false }});\n'
+    + 'return (' + expr + ');\n'
+    + '})(0, 1, 2, 3);');
+}
+
+assertEq(testLenientAndStrict(callFunctionBody('arguments[0] = 42'),
+                              returns(42), returns(42)),
+         true);
+
+assertEq(testLenientAndStrict(callFunctionBody('delete arguments[0]'),
+                              returns(true), returns(true)),
+         true);
+
+
+assertEq(testLenientAndStrict(callFunctionBody('arguments[1] = 42'),
+                              returns(42), raisesException(TypeError)),
+         true);
+
+assertEq(testLenientAndStrict(callFunctionBody('delete arguments[1]'),
+                              returns(true), returns(true)),
+         true);
+
+
+assertEq(testLenientAndStrict(callFunctionBody('arguments[2] = 42'),
+                              returns(42), returns(42)),
+         true);
+
+assertEq(testLenientAndStrict(callFunctionBody('delete arguments[2]'),
+                              returns(false), raisesException(TypeError)),
+         true);
+
+
+assertEq(testLenientAndStrict(callFunctionBody('arguments[3] = 42'),
+                              returns(42), raisesException(TypeError)),
+         true);
+
+assertEq(testLenientAndStrict(callFunctionBody('delete arguments[3]'),
+                              returns(false), raisesException(TypeError)),
+         true);
+
+
+reportCompare(true, true);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_5/strict/15.10.7.js
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+assertEq(testLenientAndStrict('var r = /foo/; r.source = "bar"; r.source',
+                              returns("foo"), raisesException(TypeError)),
+         true);
+assertEq(testLenientAndStrict('var r = /foo/; delete r.source',
+                              returns(false), raisesException(TypeError)),
+         true);
+
+assertEq(testLenientAndStrict('var r = /foo/; r.global = true; r.global',
+                              returns(false), raisesException(TypeError)),
+         true);
+assertEq(testLenientAndStrict('var r = /foo/; delete r.global',
+                              returns(false), raisesException(TypeError)),
+         true);
+
+assertEq(testLenientAndStrict('var r = /foo/; r.ignoreCase = true; r.ignoreCase',
+                              returns(false), raisesException(TypeError)),
+         true);
+assertEq(testLenientAndStrict('var r = /foo/; delete r.ignoreCase',
+                              returns(false), raisesException(TypeError)),
+         true);
+
+assertEq(testLenientAndStrict('var r = /foo/; r.multiline = true; r.multiline',
+                              returns(false), raisesException(TypeError)),
+         true);
+assertEq(testLenientAndStrict('var r = /foo/; delete r.multiline',
+                              returns(false), raisesException(TypeError)),
+         true);
+
+assertEq(testLenientAndStrict('var r = /foo/; r.lastIndex = 42; r.lastIndex',
+                              returns(42), returns(42)),
+         true);
+assertEq(testLenientAndStrict('var r = /foo/; delete r.lastIndex',
+                              returns(false), raisesException(TypeError)),
+         true);
+
+reportCompare(true, true);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_5/strict/15.3.5.1.js
@@ -0,0 +1,19 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+function fn() {
+  return function(a, b, c) { };
+}
+
+assertEq(testLenientAndStrict('var f = fn(); f.length = 1; f.length',
+                              returns(3), raisesException(TypeError)),
+         true);
+assertEq(testLenientAndStrict('var f = fn(); delete f.length',
+                              returns(false), raisesException(TypeError)),
+         true);
+
+reportCompare(true, true);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_5/strict/15.3.5.2.js
@@ -0,0 +1,16 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+function fn() {
+  return function(a, b, c) { };
+}
+
+assertEq(testLenientAndStrict('var f = fn(); delete f.prototype',
+                              returns(false), raisesException(TypeError)),
+         true);
+
+reportCompare(true, true);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_5/strict/15.4.4.12.js
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+function arr() {
+  return Object.defineProperty([1, 2, 3], 0, {writable: false});
+}
+
+function obj() {
+  var o = {0: 1, 1: 2, 2: 3, length: 3};
+  Object.defineProperty(o, 0, {writable: false});
+  return o;
+}
+
+assertEq(testLenientAndStrict('var a = arr(); [a.splice(0, 1), a]',
+                              raisesException(TypeError),
+                              raisesException(TypeError)),
+         true);
+
+assertEq(testLenientAndStrict('var o = obj(); [Array.prototype.splice.call(o, 0, 1), o]',
+                              raisesException(TypeError),
+                              raisesException(TypeError)),
+         true);
+
+function agap() {
+  var a = [1, 2, , 4];
+  Object.defineProperty(a, 1, {configurable: false});
+  return a;
+}
+
+function ogap() {
+  var o = {0: 1, 1: 2, /* no 2 */ 3: 4, length: 4};
+  Object.defineProperty(o, 1, {configurable: false});
+  return o;
+}
+
+assertEq(testLenientAndStrict('var a = agap(); [a.splice(0, 1), a]',
+                              raisesException(TypeError),
+                              raisesException(TypeError)),
+         true);
+
+assertEq(testLenientAndStrict('var o = ogap(); [Array.prototype.splice.call(o, 0, 1), o]',
+                              raisesException(TypeError),
+                              raisesException(TypeError)),
+         true);
+
+reportCompare(true, true);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_5/strict/15.4.4.13.js
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+function arr() {
+  return Object.defineProperty([1, 2, 3], 0, {writable: false});
+}
+
+function obj() {
+  var o = {0: 1, 1: 2, 2: 3, length: 3};
+  Object.defineProperty(o, 0, {writable: false});
+  return o;
+}
+
+assertEq(testLenientAndStrict('var a = arr(); [a.unshift(40, 50), a]',
+                              raisesException(TypeError),
+                              raisesException(TypeError)),
+         true);
+
+assertEq(testLenientAndStrict('var o = obj(); [Array.prototype.unshift.call(o, 40, 50), o]',
+                              raisesException(TypeError),
+                              raisesException(TypeError)),
+         true);
+
+function agap() {
+  var a = [1, 2, , 4];
+  Object.defineProperty(a, 3, {configurable: false});
+  return a;
+}
+
+function ogap() {
+  var o = {0: 1, 1: 2, /* no 2 */ 3: 4, length: 4};
+  Object.defineProperty(o, 3, {configurable: false});
+  return o;
+}
+
+assertEq(testLenientAndStrict('var a = agap(); [a.unshift(9), a]',
+                              raisesException(TypeError),
+                              raisesException(TypeError)),
+         true);
+
+assertEq(testLenientAndStrict('var o = ogap(); [Array.prototype.unshift.call(o, 9), o]',
+                              raisesException(TypeError),
+                              raisesException(TypeError)),
+         true);
+
+reportCompare(true, true);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_5/strict/15.4.4.6.js
@@ -0,0 +1,28 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+function arr() {
+  return Object.defineProperty([1, 2, 3], 2, {configurable: false});
+}
+
+function obj() {
+  var o = {0: 1, 1: 2, 2: 3, length: 3};
+  Object.defineProperty(o, 2, {configurable: false});
+  return o;
+}
+
+assertEq(testLenientAndStrict('var a = arr(); [a.pop(), a]',
+                              raisesException(TypeError),
+                              raisesException(TypeError)),
+         true);
+
+assertEq(testLenientAndStrict('var o = obj(); [Array.prototype.pop.call(o), o]',
+                              raisesException(TypeError),
+                              raisesException(TypeError)),
+         true);
+
+reportCompare(true, true);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_5/strict/15.4.4.8.js
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+function arr() {
+  return Object.defineProperty([1, 2, 3], 0, {writable: false});
+}
+
+function obj() {
+  var o = {0: 1, 1: 2, 2: 3, length: 3};
+  Object.defineProperty(o, 0, {writable: false});
+  return o;
+}
+
+assertEq(testLenientAndStrict('var a = arr(); a.reverse()',
+                              raisesException(TypeError),
+                              raisesException(TypeError)),
+         true);
+
+assertEq(testLenientAndStrict('var o = obj(); Array.prototype.reverse.call(o)',
+                              raisesException(TypeError),
+                              raisesException(TypeError)),
+         true);
+
+function agap() {
+  var a = [1, 2, , 4];
+  Object.defineProperty(a, 1, {configurable: false});
+  return a;
+}
+
+function ogap() {
+  var o = {0: 1, 1: 2, /* no 2 */ 3: 4, length: 4};
+  Object.defineProperty(o, 1, {configurable: false});
+  return o;
+}
+
+assertEq(testLenientAndStrict('var a = agap(); a.reverse()',
+                              raisesException(TypeError),
+                              raisesException(TypeError)),
+         true);
+
+assertEq(testLenientAndStrict('var o = ogap(); Array.prototype.reverse.call(o)',
+                              raisesException(TypeError),
+                              raisesException(TypeError)),
+         true);
+
+reportCompare(true, true);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_5/strict/15.4.4.9.js
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+function arr() {
+  return Object.defineProperty([10, 20, 30], 0, {writable: false});
+}
+
+function obj() {
+  var o = {0: 10, 1: 20, 2: 30, length: 3};
+  Object.defineProperty(o, 0, {writable: false});
+  return o;
+}
+
+assertEq(testLenientAndStrict('var a = arr(); [a.shift(), a]',
+                              raisesException(TypeError),
+                              raisesException(TypeError)),
+         true);
+
+assertEq(testLenientAndStrict('var o = obj(); [Array.prototype.shift.call(o), o]',
+                              raisesException(TypeError),
+                              raisesException(TypeError)),
+         true);
+
+function agap() {
+  var a = [1, 2, , 4];
+  Object.defineProperty(a, 1, {configurable: false});
+  return a;
+}
+
+function ogap() {
+  var o = {0: 1, 1: 2, /* no 2 */ 3: 4, length: 4};
+  Object.defineProperty(o, 1, {configurable: false});
+  return o;
+}
+
+assertEq(testLenientAndStrict('var a = agap(); [a.shift(), a]',
+                              raisesException(TypeError),
+                              raisesException(TypeError)),
+         true);
+
+assertEq(testLenientAndStrict('var o = ogap(); [Array.prototype.shift.call(o), o]',
+                              raisesException(TypeError),
+                              raisesException(TypeError)),
+         true);
+
+reportCompare(true, true);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_5/strict/15.4.5.1.js
@@ -0,0 +1,30 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+function arr() {
+  return Object.defineProperty([1, 2, 3, 4], 2, {configurable: false});
+}
+
+assertEq(testLenientAndStrict('var a = arr(); a.length = 2; a',
+                              returnsCopyOf([1, 2, 3]),
+                              raisesException(TypeError)),
+         true);
+
+// Internally, SpiderMonkey has two representations for arrays:
+// fast-but-inflexible, and slow-but-flexible. Adding a non-index property
+// to an array turns it into the latter. We should test on both kinds.
+function addx(obj) {
+  obj.x = 5;
+  return obj;
+}
+
+assertEq(testLenientAndStrict('var a = addx(arr()); a.length = 2; a',
+                              returnsCopyOf(addx([1, 2, 3])),
+                              raisesException(TypeError)),
+         true);
+
+reportCompare(true, true);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_5/strict/15.5.5.1.js
@@ -0,0 +1,26 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+function str() {
+  return new String("foo");
+}
+
+assertEq(testLenientAndStrict('var s = str(); s.length = 1; s.length',
+                              returns(3), raisesException(TypeError)),
+         true);
+assertEq(testLenientAndStrict('var s = str(); delete s.length',
+                              returns(false), raisesException(TypeError)),
+         true);
+
+assertEq(testLenientAndStrict('"foo".length = 1',
+                              returns(1), raisesException(TypeError)),
+         true);
+assertEq(testLenientAndStrict('delete "foo".length',
+                              returns(false), raisesException(TypeError)),
+         true);
+
+reportCompare(true, true);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_5/strict/15.5.5.2.js
@@ -0,0 +1,15 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+assertEq(testLenientAndStrict('"foo"[0] = 1',
+                              returns(1), raisesException(TypeError)),
+         true);
+assertEq(testLenientAndStrict('delete "foo"[0]',
+                              returns(false), raisesException(TypeError)),
+         true);
+
+reportCompare(true, true);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_5/strict/8.12.5.js
@@ -0,0 +1,82 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+function obj() {
+  var o = {all: 1, nowrite: 1, noconfig: 1, noble: 1};
+  Object.defineProperty(o, 'nowrite', {writable: false});
+  Object.defineProperty(o, 'noconfig', {configurable: false});
+  Object.defineProperty(o, 'noble', {writable: false, configurable: false});
+  return o;
+}
+
+assertEq(testLenientAndStrict('var o = obj(); o.all = 2; o.all',
+                              returns(2), returns(2)),
+         true);
+
+assertEq(testLenientAndStrict('var o = obj(); o.nowrite = 2; o.nowrite',
+                              returns(1), raisesException(TypeError)),
+         true);
+
+assertEq(testLenientAndStrict('var o = obj(); o.noconfig = 2; o.noconfig',
+                              returns(2), returns(2)),
+         true);
+
+assertEq(testLenientAndStrict('var o = obj(); o.noble = 2; o.noble',
+                              returns(1), raisesException(TypeError)),
+         true);
+
+assertEq(testLenientAndStrict('obj().nowrite++',
+                              returns(1), raisesException(TypeError)),
+         true);
+assertEq(testLenientAndStrict('++obj().nowrite',
+                              returns(2), raisesException(TypeError)),
+         true);
+assertEq(testLenientAndStrict('obj().nowrite--',
+                              returns(1), raisesException(TypeError)),
+         true);
+assertEq(testLenientAndStrict('--obj().nowrite',
+                              returns(0), raisesException(TypeError)),
+         true);
+
+
+function arr() {
+  return Object.defineProperties([1, 1, 1, 1],
+                                 { 1: { writable: false },
+                                   2: { configurable: false },
+                                   3: { writable: false, configurable: false }});
+}
+
+assertEq(testLenientAndStrict('var a = arr(); a[0] = 2; a[0]',
+                              returns(2), returns(2)),
+         true);
+
+assertEq(testLenientAndStrict('var a = arr(); a[1] = 2; a[1]',
+                              returns(1), raisesException(TypeError)),
+         true);
+
+assertEq(testLenientAndStrict('var a = arr(); a[2] = 2; a[2]',
+                              returns(2), returns(2)),
+         true);
+
+assertEq(testLenientAndStrict('var a = arr(); a[3] = 2; a[3]',
+                              returns(1), raisesException(TypeError)),
+         true);
+
+assertEq(testLenientAndStrict('arr()[1]++',
+                              returns(1), raisesException(TypeError)),
+         true);
+assertEq(testLenientAndStrict('++arr()[1]',
+                              returns(2), raisesException(TypeError)),
+         true);
+assertEq(testLenientAndStrict('arr()[1]--',
+                              returns(1), raisesException(TypeError)),
+         true);
+assertEq(testLenientAndStrict('--arr()[1]',
+                              returns(0), raisesException(TypeError)),
+         true);
+
+reportCompare(true, true);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_5/strict/8.12.7.js
@@ -0,0 +1,32 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+function setup() {
+  var o = {all: 1, nowrite: 1, noconfig: 1, noble: 1};
+  Object.defineProperty(o, 'nowrite', {writable: false});
+  Object.defineProperty(o, 'noconfig', {configurable: false});
+  Object.defineProperty(o, 'noble', {writable: false, configurable: false});
+  return o;
+}
+
+assertEq(testLenientAndStrict('var o = setup(); delete o.all',
+                              returns(true), returns(true)),
+         true);
+
+assertEq(testLenientAndStrict('var o = setup(); delete o.nowrite',
+                              returns(true), returns(true)),
+         true);
+
+assertEq(testLenientAndStrict('var o = setup(); delete o.noconfig',
+                              returns(false), raisesException(TypeError)),
+         true);
+
+assertEq(testLenientAndStrict('var o = setup(); delete o.noble',
+                              returns(false), raisesException(TypeError)),
+         true);
+
+reportCompare(true, true);
--- a/js/src/tests/ecma_5/strict/8.7.2.js
+++ b/js/src/tests/ecma_5/strict/8.7.2.js
@@ -31,9 +31,26 @@ assertEq(testLenientAndStrict('var var_d
  * We mustn't report errors until the code is actually run; the variable
  * could be created in the mean time.
  */
 assertEq(testLenientAndStrict('undeclared_at_compiletime=1',
                               parsesSuccessfully,
                               parsesSuccessfully),
          true);
 
+function obj() {
+  var o = { x: 1, y: 1 };
+  Object.defineProperty(o, 'x', { writable: false });
+  return o;
+}
+
+/* Put EXPR in a strict mode code context with 'with' bindings in scope. */
+function in_strict_with(expr) {
+  return "with(obj()) { (function () { 'use strict'; " + expr + " })(); }";
+}
+
+assertEq(raisesException(TypeError)(in_strict_with('x = 2; y = 2;')), true);
+assertEq(raisesException(TypeError)(in_strict_with('x++;')), true);
+assertEq(raisesException(TypeError)(in_strict_with('++x;')), true);
+assertEq(raisesException(TypeError)(in_strict_with('x--;')), true);
+assertEq(raisesException(TypeError)(in_strict_with('--x;')), true);
+
 reportCompare(true, true);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_5/strict/function-name-arity.js
@@ -0,0 +1,26 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+function fn() {
+  return function f(a, b, c) { };
+}
+
+assertEq(testLenientAndStrict('var f = fn(); f.name = "g"; f.name',
+                              returns("f"), raisesException(TypeError)),
+         true);
+assertEq(testLenientAndStrict('var f = fn(); delete f.name',
+                              returns(false), raisesException(TypeError)),
+         true);
+
+assertEq(testLenientAndStrict('var f = fn(); f.arity = 4; f.arity',
+                              returns(3), raisesException(TypeError)),
+         true);
+assertEq(testLenientAndStrict('var f = fn(); delete f.arity',
+                              returns(false), raisesException(TypeError)),
+         true);
+
+reportCompare(true, true);
--- a/js/src/tests/ecma_5/strict/jstests.list
+++ b/js/src/tests/ecma_5/strict/jstests.list
@@ -1,19 +1,34 @@
 url-prefix ../../jsreftest.html?test=ecma_5/strict/
 script 8.7.2.js
+script 8.12.5.js
+script 8.12.7.js
 script 10.4.2.js
+script 10.6.js
 script 11.1.5.js
 script 11.3.1.js
 script 11.3.2.js
 script 11.4.1.js
 script 11.4.4.js
 script 11.4.5.js
 script 11.13.1.js
 script 11.13.2.js
 script 12.2.1.js
 script 12.10.1.js
 script 12.14.1.js
 script 13.1.js
+script 15.3.5.1.js
+script 15.3.5.2.js
+script 15.4.4.6.js
+script 15.4.4.8.js
+script 15.4.4.9.js
+script 15.4.4.12.js
+script 15.4.4.13.js
+script 15.4.5.1.js
+script 15.5.5.1.js
+script 15.5.5.2.js
+script 15.10.7.js
 script B.1.1.js
 script B.1.2.js
+script function-name-arity.js
 script regress-532254.js
 script regress-532041.js
--- a/js/src/tests/ecma_5/strict/shell.js
+++ b/js/src/tests/ecma_5/strict/shell.js
@@ -28,16 +28,46 @@ function completesNormally(code) {
     eval(code);
     return true;
   } catch (exception) {
     return false;
   }
 }
 
 /*
+ * returns(VALUE)(CODE) returns true if evaluating CODE (as eval code)
+ * completes normally (rather than throwing an exception), yielding a value
+ * strictly equal to VALUE.
+ */
+function returns(value) {
+  return function(code) {
+    try {
+      return eval(code) === value;
+    } catch (exception) {
+      return false;
+    }
+  }
+}
+
+/*
+ * returnsCopyOf(VALUE)(CODE) returns true if evaluating CODE (as eval code)
+ * completes normally (rather than throwing an exception), yielding a value
+ * that is deep_equal to VALUE.
+ */
+function returnsCopyOf(value) {
+  return function(code) {
+    try {
+      return deep_equal(eval(code), value);
+    } catch (exception) {
+      return false;
+    }
+  }
+}
+
+/*
  * raisesException(EXCEPTION)(CODE) returns true if evaluating CODE (as eval
  * code) throws an exception object whose prototype is
  * EXCEPTION.prototype, and returns false if it throws any other error
  * or evaluates successfully. For example: raises(TypeError)("0()") ==
  * true.
  */
 function raisesException(exception) {
   return function (code) {
@@ -81,8 +111,35 @@ function parseRaisesException(exception)
 /*
  * Return the result of applying uneval to VAL, and replacing all runs
  * of whitespace with a single horizontal space (poor man's
  * tokenization).
  */
 function clean_uneval(val) {
   return uneval(val).replace(/\s+/g, ' ');
 }
+
+/*
+ * Return true if A is equal to B, where equality on arrays and objects
+ * means that they have the same set of enumerable properties, the values
+ * of each property are deep_equal, and their 'length' properties are
+ * equal. Equality on other types is ==.
+ */
+function deep_equal(a, b) {
+  if (typeof a != typeof b)
+    return false;
+  if (typeof a == 'object') {
+    props = {}
+    // For every property of a, does b have that property with an equal value?
+    for (prop in a) {
+      if (!deep_equal(a[prop], b[prop]))
+        return false;
+      props[prop] = true;
+    }
+    // Are all of b's properties present on a?
+    for (prop in b)
+      if (!props[prop])
+        return false;
+    // length isn't enumerable, but we want to check it, too.
+    return a.length == b.length;
+  }
+  return a == b;
+}
--- a/js/src/tests/js1_5/extensions/regress-449657.js
+++ b/js/src/tests/js1_5/extensions/regress-449657.js
@@ -66,17 +66,17 @@ function test()
       seal(a);
     }
     catch(ex)
     {
       actual = ex + '';
     }
     reportCompare(expect, actual, summary + ': 1');
 
-    expect = 'Error: a.length is read-only';
+    expect = 'TypeError: a.length is read-only';
     actual = '';
     try
     {
       a = [1,2,3];
       a[4] = 2;
       seal(a);
       a.length = 5;
     }
--- a/js/src/tests/js1_6/Array/regress-304828.js
+++ b/js/src/tests/js1_6/Array/regress-304828.js
@@ -56,30 +56,30 @@ try
 catch(e)
 {
   actual = e + '';
 }
 reportCompare(expect, actual, summary + ': join');
 
 // reverse
 value  = '123';
-expect = '123';
+expect = 'TypeError: Array.prototype.reverse.call(value) is read-only';
 try
 {
   actual = Array.prototype.reverse.call(value) + '';
 }
 catch(e)
 {
   actual = e + '';
 }
 reportCompare(expect, actual, summary + ': reverse');
 
 // sort
 value  = 'cba';
-expect = 'cba';
+expect = 'TypeError: Array.prototype.sort.call(value) is read-only';
 try
 {
   actual = Array.prototype.sort.call(value) + '';
 }
 catch(e)
 {
   actual = e + '';
 }
@@ -96,59 +96,59 @@ catch(e)
 {
   actual = e + '';
 }
 reportCompare(expect, actual, summary + ': push');
 reportCompare('abc', value, summary + ': push');
 
 // pop
 value  = 'abc';
-expect = 'c';
+expect = "TypeError: property 'Array.prototype.pop.call(value)' is non-configurable and cannot be deleted";
 try
 {
   actual = Array.prototype.pop.call(value);
 }
 catch(e)
 {
   actual = e + '';
 }
 reportCompare(expect, actual, summary + ': pop');
 reportCompare('abc', value, summary + ': pop');
 
 // unshift
 value  = 'def';
-expect = 6;
+expect = 'TypeError: Array.prototype.unshift.call(value, "a", "b", "c") is read-only';
 try
 {
   actual = Array.prototype.unshift.call(value, 'a', 'b', 'c');
 }
 catch(e)
 {
   actual = e + '';
 }
 reportCompare(expect, actual, summary + ': unshift');
 reportCompare('def', value, summary + ': unshift');
 
 // shift
 value  = 'abc';
-expect = 'a';
+expect = 'TypeError: Array.prototype.shift.call(value) is read-only';
 try
 {
   actual = Array.prototype.shift.call(value);
 }
 catch(e)
 {
   actual = e + '';
 }
 reportCompare(expect, actual, summary + ': shift');
 reportCompare('abc', value, summary + ': shift');
 
 // splice
 value  = 'abc';
-expect = 'b';
+expect = 'TypeError: Array.prototype.splice.call(value, 1, 1) is read-only';
 try
 {
   actual = Array.prototype.splice.call(value, 1, 1) + '';
 }
 catch(e)
 {
   actual = e + '';
 }
new file mode 100644
--- /dev/null
+++ b/js/src/trace-test/tests/basic/testBug595916.js
@@ -0,0 +1,10 @@
+(function () {
+    try {
+        eval("\
+          for each(let d in[0,0,0,0,0,0,0,0]) {\
+            for(let b in[0,0]) {}\
+          }\
+        ")
+    } catch (e) {}
+})()
+
--- a/js/src/trace-test/tests/basic/testProxyConstructors.js
+++ b/js/src/trace-test/tests/basic/testProxyConstructors.js
@@ -1,6 +1,9 @@
 // proxies can return primitives
 assertEq(new (Proxy.createFunction({}, function(){}, function(){})), undefined);
 
+x = Proxy.createFunction((function () {}), Uint16Array, wrap)
+new(wrap(x))
+
 // proxies can return the callee
 var x = Proxy.createFunction({}, function (q) { return q; });
 new x(x);
new file mode 100644
--- /dev/null
+++ b/js/src/v8-dtoa/README
@@ -0,0 +1,34 @@
+This directory contains V8's fast dtoa conversion code.  The V8 revision
+imported was:
+
+   Repository Root: http://v8.googlecode.com/svn
+   Repository UUID: ce2b1a6d-e550-0410-aec6-3dcde31c8c00
+   Revision: 5322
+
+The function of interest, which is called by SpiderMonkey, is
+conversions.cc:DoubleToCString().  This is called from jsnum.cpp to provide a
+fast Number.toString(10) implementation.
+
+A great deal of code has been removed from the imported files.  The
+remaining code is more or less the bare minimum required to support this
+function in a straightforward, standalone manner.
+
+Two related functions in V8 are DoubleToExponentialCString() and
+DoubleToPrecisionString(), which can be used to implement
+Number.toExponential() and Number.toPrecision().  They have not been imported;
+they both call dtoa() and so are unlikely to be noticeably faster than the
+existing SpiderMonkey equivalents.
+
+Another related function in V8 is DoubleToRadixCString(), which can be used to
+implement Number.toString(base), where base != 10.  This has not been imported;
+it may well be faster than SpiderMonkey's implementation, but V8 generates its
+own definition of the modulo() function on Win64 and importing this would
+require also importing large chunks of the assembler, which is not worthwhile.
+
+Yet another related function in V8 is DoubleToFixedCString(), which can be used
+to implement Number.toFixed().  This has not been imported as it was measured
+as slower than SpiderMonkey's version.
+
+Comments preceded by the string "MOZ: " indicate places where the code has
+been changed significantly from the original code.
+
new file mode 100644
--- /dev/null
+++ b/js/src/v8-dtoa/cached-powers.h
@@ -0,0 +1,119 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_CACHED_POWERS_H_
+#define V8_CACHED_POWERS_H_
+
+#include "diy-fp.h"
+
+namespace v8 {
+namespace internal {
+
+struct CachedPower {
+  uint64_t significand;
+  int16_t binary_exponent;
+  int16_t decimal_exponent;
+};
+
+// The following defines implement the interface between this file and the
+// generated 'powers_ten.h'.
+// GRISU_CACHE_NAME(1) contains all possible cached powers.
+// GRISU_CACHE_NAME(i) contains GRISU_CACHE_NAME(1) where only every 'i'th
+// element is kept. More formally GRISU_CACHE_NAME(i) contains the elements j*i
+// with 0 <= j < k with k such that j*k < the size of GRISU_CACHE_NAME(1).
+// The higher 'i' is the fewer elements we use.
+// Given that there are less elements, the exponent-distance between two
+// elements in the cache grows. The variable GRISU_CACHE_MAX_DISTANCE(i) stores
+// the maximum distance between two elements.
+#define GRISU_CACHE_STRUCT CachedPower
+#define GRISU_CACHE_NAME(i) kCachedPowers##i
+#define GRISU_CACHE_MAX_DISTANCE(i) kCachedPowersMaxDistance##i
+#define GRISU_CACHE_OFFSET kCachedPowerOffset
+#define GRISU_UINT64_C V8_2PART_UINT64_C
+// The following include imports the precompiled cached powers.
+#include "powers-ten.h"  // NOLINT
+
+static const double kD_1_LOG2_10 = 0.30102999566398114;  //  1 / lg(10)
+
+// We can't use a function since we reference variables depending on the 'i'.
+// This way the compiler is able to see at compile time that only one
+// cache-array variable is used and thus can remove all the others.
+#define COMPUTE_FOR_CACHE(i) \
+  if (!found && (gamma - alpha + 1 >= GRISU_CACHE_MAX_DISTANCE(i))) {   \
+    int kQ = DiyFp::kSignificandSize;                                   \
+    double k = ceiling((alpha - e + kQ - 1) * kD_1_LOG2_10);            \
+    int index = (GRISU_CACHE_OFFSET + static_cast<int>(k) - 1) / i + 1; \
+    cached_power = GRISU_CACHE_NAME(i)[index];                          \
+    found = true;                                                       \
+  }                                                                     \
+
+static void GetCachedPower(int e, int alpha, int gamma, int* mk, DiyFp* c_mk) {
+  // The following if statement should be optimized by the compiler so that only
+  // one array is referenced and the others are not included in the object file.
+  bool found = false;
+  CachedPower cached_power;
+  COMPUTE_FOR_CACHE(20);
+  COMPUTE_FOR_CACHE(19);
+  COMPUTE_FOR_CACHE(18);
+  COMPUTE_FOR_CACHE(17);
+  COMPUTE_FOR_CACHE(16);
+  COMPUTE_FOR_CACHE(15);
+  COMPUTE_FOR_CACHE(14);
+  COMPUTE_FOR_CACHE(13);
+  COMPUTE_FOR_CACHE(12);
+  COMPUTE_FOR_CACHE(11);
+  COMPUTE_FOR_CACHE(10);
+  COMPUTE_FOR_CACHE(9);
+  COMPUTE_FOR_CACHE(8);
+  COMPUTE_FOR_CACHE(7);
+  COMPUTE_FOR_CACHE(6);
+  COMPUTE_FOR_CACHE(5);
+  COMPUTE_FOR_CACHE(4);
+  COMPUTE_FOR_CACHE(3);
+  COMPUTE_FOR_CACHE(2);
+  COMPUTE_FOR_CACHE(1);
+  if (!found) {
+    UNIMPLEMENTED();
+    // Silence compiler warnings.
+    cached_power.significand = 0;
+    cached_power.binary_exponent = 0;
+    cached_power.decimal_exponent = 0;
+  }
+  *c_mk = DiyFp(cached_power.significand, cached_power.binary_exponent);
+  *mk = cached_power.decimal_exponent;
+  ASSERT((alpha <= c_mk->e() + e) && (c_mk->e() + e <= gamma));
+}
+#undef GRISU_REDUCTION
+#undef GRISU_CACHE_STRUCT
+#undef GRISU_CACHE_NAME
+#undef GRISU_CACHE_MAX_DISTANCE
+#undef GRISU_CACHE_OFFSET
+#undef GRISU_UINT64_C
+
+} }  // namespace v8::internal
+
+#endif  // V8_CACHED_POWERS_H_
new file mode 100644
--- /dev/null
+++ b/js/src/v8-dtoa/checks.cc
@@ -0,0 +1,57 @@
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <stdarg.h>
+#include <signal.h>
+
+#include "v8.h"
+
+static int fatal_error_handler_nesting_depth = 0;
+
+// Contains protection against recursive calls (faults while handling faults).
+extern "C" void V8_Fatal(const char* file, int line, const char* format, ...) {
+  fflush(stdout);
+  fflush(stderr);
+  fatal_error_handler_nesting_depth++;
+  // First time we try to print an error message
+  //
+  // MOZ: lots of calls to printing functions within v8::internal::OS were
+  // replaced with simpler standard C calls, to avoid pulling in lots of
+  // platform-specific code.  As a result, in some cases the error message may
+  // not be printed as well or at all.
+  if (fatal_error_handler_nesting_depth < 2) {
+    fprintf(stderr, "\n\n#\n# Fatal error in %s, line %d\n# ", file, line);
+    va_list arguments;
+    va_start(arguments, format);
+    vfprintf(stderr, format, arguments);
+    va_end(arguments);
+    fprintf(stderr, "\n#\n\n");
+  }
+
+  i::OS::Abort();
+}
+
new file mode 100644
--- /dev/null
+++ b/js/src/v8-dtoa/checks.h
@@ -0,0 +1,93 @@
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_CHECKS_H_
+#define V8_CHECKS_H_
+
+#include <string.h>
+
+extern "C" void V8_Fatal(const char* file, int line, const char* format, ...);
+
+// The FATAL, UNREACHABLE and UNIMPLEMENTED macros are useful during
+// development, but they should not be relied on in the final product.
+
+#ifdef DEBUG
+#define FATAL(msg)                              \
+  V8_Fatal(__FILE__, __LINE__, "%s", (msg))
+#define UNIMPLEMENTED()                         \
+  V8_Fatal(__FILE__, __LINE__, "unimplemented code")
+#define UNREACHABLE()                           \
+  V8_Fatal(__FILE__, __LINE__, "unreachable code")
+#else
+#define FATAL(msg)                              \
+  V8_Fatal("", 0, "%s", (msg))
+#define UNIMPLEMENTED()                         \
+  V8_Fatal("", 0, "unimplemented code")
+#define UNREACHABLE() ((void) 0)
+#endif
+
+// Used by the CHECK macro -- should not be called directly.
+static inline void CheckHelper(const char* file,
+                               int line,
+                               const char* source,
+                               bool condition) {
+  if (!condition)
+    V8_Fatal(file, line, source);
+}
+
+
+// The CHECK macro checks that the given condition is true; if not, it
+// prints a message to stderr and aborts.
+#define CHECK(condition) CheckHelper(__FILE__, __LINE__, #condition, condition)
+
+
+// Helper function used by the CHECK_EQ function when given int
+// arguments.  Should not be called directly.
+static inline void CheckEqualsHelper(const char* file, int line,
+                                     const char* expected_source, int expected,
+                                     const char* value_source, int value) {
+  if (expected != value) {
+    V8_Fatal(file, line,
+             "CHECK_EQ(%s, %s) failed\n#   Expected: %i\n#   Found: %i",
+             expected_source, value_source, expected, value);
+  }
+}
+
+
+#define CHECK_EQ(expected, value) CheckEqualsHelper(__FILE__, __LINE__, \
+  #expected, expected, #value, value)
+
+
+// The ASSERT macro is equivalent to CHECK except that it only
+// generates code in debug builds.
+#ifdef DEBUG
+#define ASSERT(condition)    CHECK(condition)
+#else
+#define ASSERT(condition)      ((void) 0)
+#endif
+
+#endif  // V8_CHECKS_H_
new file mode 100644
--- /dev/null
+++ b/js/src/v8-dtoa/conversions.cc
@@ -0,0 +1,131 @@
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <math.h>
+
+#include "v8.h"
+#include "dtoa.h"
+
+namespace v8 {
+namespace internal {
+
+// MOZ: The return type was changed from 'const char*' to 'char*' to match the
+// usage within SpiderMonkey.
+//
+// MOZ: The arguments were modified to use a char buffer instead of
+// v8::internal::Vector, to save SpiderMonkey from having to know about that
+// type.
+//
+// MOZ: The function was modified to return NULL when it needs to fall back to
+// Gay's dtoa, rather than calling Gay's dtoa itself.  That's because
+// SpiderMonkey already has its own copy of Gay's dtoa.
+//
+char* DoubleToCString(double v, char* buffer, int buflen) {
+  StringBuilder builder(buffer, buflen);
+
+  switch (fpclassify(v)) {
+    case FP_NAN:
+      builder.AddString("NaN");
+      break;
+
+    case FP_INFINITE:
+      if (v < 0.0) {
+        builder.AddString("-Infinity");
+      } else {
+        builder.AddString("Infinity");
+      }
+      break;
+
+    case FP_ZERO:
+      builder.AddCharacter('0');
+      break;
+
+    default: {
+      int decimal_point;
+      int sign;
+      char* decimal_rep;
+      //bool used_gay_dtoa = false;	MOZ: see above
+      const int kV8DtoaBufferCapacity = kBase10MaximalLength + 1;
+      char v8_dtoa_buffer[kV8DtoaBufferCapacity];
+      int length;
+
+      if (DoubleToAscii(v, DTOA_SHORTEST, 0,
+                        Vector<char>(v8_dtoa_buffer, kV8DtoaBufferCapacity),
+                        &sign, &length, &decimal_point)) {
+        decimal_rep = v8_dtoa_buffer;
+      } else {
+        return NULL;    // MOZ: see above
+        //decimal_rep = dtoa(v, 0, 0, &decimal_point, &sign, NULL);
+        //used_gay_dtoa = true;
+        //length = StrLength(decimal_rep);
+      }
+
+      if (sign) builder.AddCharacter('-');
+
+      if (length <= decimal_point && decimal_point <= 21) {
+        // ECMA-262 section 9.8.1 step 6.
+        builder.AddString(decimal_rep);
+        builder.AddPadding('0', decimal_point - length);
+
+      } else if (0 < decimal_point && decimal_point <= 21) {
+        // ECMA-262 section 9.8.1 step 7.
+        builder.AddSubstring(decimal_rep, decimal_point);
+        builder.AddCharacter('.');
+        builder.AddString(decimal_rep + decimal_point);
+
+      } else if (decimal_point <= 0 && decimal_point > -6) {
+        // ECMA-262 section 9.8.1 step 8.
+        builder.AddString("0.");
+        builder.AddPadding('0', -decimal_point);
+        builder.AddString(decimal_rep);
+
+      } else {
+        // ECMA-262 section 9.8.1 step 9 and 10 combined.
+        builder.AddCharacter(decimal_rep[0]);
+        if (length != 1) {
+          builder.AddCharacter('.');
+          builder.AddString(decimal_rep + 1);
+        }
+        builder.AddCharacter('e');
+        builder.AddCharacter((decimal_point >= 0) ? '+' : '-');
+        int exponent = decimal_point - 1;
+        if (exponent < 0) exponent = -exponent;
+        // MOZ: This was a call to 'AddFormatted("%d", exponent)', which
+        // called onto vsnprintf().  Because this was the only call to
+        // AddFormatted in the imported code, it was replaced with this call
+        // to AddInteger, which is faster and doesn't require any
+        // platform-specific code.
+        builder.AddInteger(exponent);
+      }
+
+      //if (used_gay_dtoa) freedtoa(decimal_rep);   MOZ: see above
+    }
+  }
+  return builder.Finalize();
+}
+
+} }  // namespace v8::internal
new file mode 100644
--- /dev/null
+++ b/js/src/v8-dtoa/conversions.h
@@ -0,0 +1,41 @@
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_CONVERSIONS_H_
+#define V8_CONVERSIONS_H_
+
+namespace v8 {
+namespace internal {
+
+// Converts a double to a string value according to ECMA-262 9.8.1.
+// The buffer should be large enough for any floating point number.
+// 100 characters is enough.
+const char* DoubleToCString(double value, char* buffer, int buflen);
+
+} }  // namespace v8::internal
+
+#endif  // V8_CONVERSIONS_H_
new file mode 100644
--- /dev/null
+++ b/js/src/v8-dtoa/diy-fp.cc
@@ -0,0 +1,58 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "v8.h"
+
+#include "diy-fp.h"
+
+namespace v8 {
+namespace internal {
+
+void DiyFp::Multiply(const DiyFp& other) {
+  // Simply "emulates" a 128 bit multiplication.
+  // However: the resulting number only contains 64 bits. The least
+  // significant 64 bits are only used for rounding the most significant 64
+  // bits.
+  const uint64_t kM32 = 0xFFFFFFFFu;
+  uint64_t a = f_ >> 32;
+  uint64_t b = f_ & kM32;
+  uint64_t c = other.f_ >> 32;
+  uint64_t d = other.f_ & kM32;
+  uint64_t ac = a * c;
+  uint64_t bc = b * c;
+  uint64_t ad = a * d;
+  uint64_t bd = b * d;
+  uint64_t tmp = (bd >> 32) + (ad & kM32) + (bc & kM32);
+  // By adding 1U << 31 to tmp we round the final result.
+  // Halfway cases will be round up.
+  tmp += 1U << 31;
+  uint64_t result_f = ac + (ad >> 32) + (bc >> 32) + (tmp >> 32);
+  e_ += other.e_ + 64;
+  f_ = result_f;
+}
+
+} }  // namespace v8::internal
new file mode 100644
--- /dev/null
+++ b/js/src/v8-dtoa/diy-fp.h
@@ -0,0 +1,117 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_DIY_FP_H_
+#define V8_DIY_FP_H_
+
+namespace v8 {
+namespace internal {
+
+// This "Do It Yourself Floating Point" class implements a floating-point number
+// with a uint64 significand and an int exponent. Normalized DiyFp numbers will
+// have the most significant bit of the significand set.
+// Multiplication and Subtraction do not normalize their results.
+// DiyFp are not designed to contain special doubles (NaN and Infinity).
+class DiyFp {
+ public:
+  static const int kSignificandSize = 64;
+
+  DiyFp() : f_(0), e_(0) {}
+  DiyFp(uint64_t f, int e) : f_(f), e_(e) {}
+
+  // this = this - other.
+  // The exponents of both numbers must be the same and the significand of this
+  // must be bigger than the significand of other.
+  // The result will not be normalized.
+  void Subtract(const DiyFp& other) {
+    ASSERT(e_ == other.e_);
+    ASSERT(f_ >= other.f_);
+    f_ -= other.f_;
+  }
+
+  // Returns a - b.
+  // The exponents of both numbers must be the same and this must be bigger
+  // than other. The result will not be normalized.
+  static DiyFp Minus(const DiyFp& a, const DiyFp& b) {
+    DiyFp result = a;
+    result.Subtract(b);
+    return result;
+  }
+
+
+  // this = this * other.
+  void Multiply(const DiyFp& other);
+
+  // returns a * b;
+  static DiyFp Times(const DiyFp& a, const DiyFp& b) {
+    DiyFp result = a;
+    result.Multiply(b);
+    return result;
+  }
+
+  void Normalize() {
+    ASSERT(f_ != 0);
+    uint64_t f = f_;
+    int e = e_;
+
+    // This method is mainly called for normalizing boundaries. In general
+    // boundaries need to be shifted by 10 bits. We thus optimize for this case.
+    const uint64_t k10MSBits = V8_2PART_UINT64_C(0xFFC00000, 00000000);
+    while ((f & k10MSBits) == 0) {
+      f <<= 10;
+      e -= 10;
+    }
+    while ((f & kUint64MSB) == 0) {
+      f <<= 1;
+      e--;
+    }
+    f_ = f;
+    e_ = e;
+  }
+
+  static DiyFp Normalize(const DiyFp& a) {
+    DiyFp result = a;
+    result.Normalize();
+    return result;
+  }
+
+  uint64_t f() const { return f_; }
+  int e() const { return e_; }
+
+  void set_f(uint64_t new_value) { f_ = new_value; }
+  void set_e(int new_value) { e_ = new_value; }
+
+ private:
+  static const uint64_t kUint64MSB = V8_2PART_UINT64_C(0x80000000, 00000000);
+
+  uint64_t f_;
+  int e_;
+};
+
+} }  // namespace v8::internal
+
+#endif  // V8_DIY_FP_H_
new file mode 100644
--- /dev/null
+++ b/js/src/v8-dtoa/double.h
@@ -0,0 +1,169 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_DOUBLE_H_
+#define V8_DOUBLE_H_
+
+#include "diy-fp.h"
+
+namespace v8 {
+namespace internal {
+
+// We assume that doubles and uint64_t have the same endianness.
+static uint64_t double_to_uint64(double d) { return BitCast<uint64_t>(d); }
+static double uint64_to_double(uint64_t d64) { return BitCast<double>(d64); }
+
+// Helper functions for doubles.
+class Double {
+ public:
+  static const uint64_t kSignMask = V8_2PART_UINT64_C(0x80000000, 00000000);
+  static const uint64_t kExponentMask = V8_2PART_UINT64_C(0x7FF00000, 00000000);
+  static const uint64_t kSignificandMask =
+      V8_2PART_UINT64_C(0x000FFFFF, FFFFFFFF);
+  static const uint64_t kHiddenBit = V8_2PART_UINT64_C(0x00100000, 00000000);
+
+  Double() : d64_(0) {}
+  explicit Double(double d) : d64_(double_to_uint64(d)) {}
+  explicit Double(uint64_t d64) : d64_(d64) {}
+
+  DiyFp AsDiyFp() const {
+    ASSERT(!IsSpecial());
+    return DiyFp(Significand(), Exponent());
+  }
+
+  // this->Significand() must not be 0.
+  DiyFp AsNormalizedDiyFp() const {
+    uint64_t f = Significand();
+    int e = Exponent();
+
+    ASSERT(f != 0);
+
+    // The current double could be a denormal.
+    while ((f & kHiddenBit) == 0) {
+      f <<= 1;
+      e--;
+    }
+    // Do the final shifts in one go. Don't forget the hidden bit (the '-1').
+    f <<= DiyFp::kSignificandSize - kSignificandSize - 1;
+    e -= DiyFp::kSignificandSize - kSignificandSize - 1;
+    return DiyFp(f, e);
+  }
+
+  // Returns the double's bit as uint64.
+  uint64_t AsUint64() const {
+    return d64_;
+  }
+
+  int Exponent() const {
+    if (IsDenormal()) return kDenormalExponent;
+
+    uint64_t d64 = AsUint64();
+    int biased_e = static_cast<int>((d64 & kExponentMask) >> kSignificandSize);
+    return biased_e - kExponentBias;
+  }
+
+  uint64_t Significand() const {
+    uint64_t d64 = AsUint64();
+    uint64_t significand = d64 & kSignificandMask;
+    if (!IsDenormal()) {
+      return significand + kHiddenBit;
+    } else {
+      return significand;
+    }
+  }
+
+  // Returns true if the double is a denormal.
+  bool IsDenormal() const {
+    uint64_t d64 = AsUint64();
+    return (d64 & kExponentMask) == 0;
+  }
+
+  // We consider denormals not to be special.
+  // Hence only Infinity and NaN are special.
+  bool IsSpecial() const {
+    uint64_t d64 = AsUint64();
+    return (d64 & kExponentMask) == kExponentMask;
+  }
+
+  bool IsNan() const {
+    uint64_t d64 = AsUint64();
+    return ((d64 & kExponentMask) == kExponentMask) &&
+        ((d64 & kSignificandMask) != 0);
+  }
+
+
+  bool IsInfinite() const {
+    uint64_t d64 = AsUint64();
+    return ((d64 & kExponentMask) == kExponentMask) &&
+        ((d64 & kSignificandMask) == 0);
+  }
+
+
+  int Sign() const {
+    uint64_t d64 = AsUint64();
+    return (d64 & kSignMask) == 0? 1: -1;
+  }
+
+
+  // Returns the two boundaries of this.
+  // The bigger boundary (m_plus) is normalized. The lower boundary has the same
+  // exponent as m_plus.
+  void NormalizedBoundaries(DiyFp* out_m_minus, DiyFp* out_m_plus) const {
+    DiyFp v = this->AsDiyFp();
+    bool significand_is_zero = (v.f() == kHiddenBit);
+    DiyFp m_plus = DiyFp::Normalize(DiyFp((v.f() << 1) + 1, v.e() - 1));
+    DiyFp m_minus;
+    if (significand_is_zero && v.e() != kDenormalExponent) {
+      // The boundary is closer. Think of v = 1000e10 and v- = 9999e9.
+      // Then the boundary (== (v - v-)/2) is not just at a distance of 1e9 but
+      // at a distance of 1e8.
+      // The only exception is for the smallest normal: the largest denormal is
+      // at the same distance as its successor.
+      // Note: denormals have the same exponent as the smallest normals.
+      m_minus = DiyFp((v.f() << 2) - 1, v.e() - 2);
+    } else {
+      m_minus = DiyFp((v.f() << 1) - 1, v.e() - 1);
+    }
+    m_minus.set_f(m_minus.f() << (m_minus.e() - m_plus.e()));
+    m_minus.set_e(m_plus.e());
+    *out_m_plus = m_plus;
+    *out_m_minus = m_minus;
+  }
+
+  double value() const { return uint64_to_double(d64_); }
+
+ private:
+  static const int kSignificandSize = 52;  // Excludes the hidden bit.
+  static const int kExponentBias = 0x3FF + kSignificandSize;
+  static const int kDenormalExponent = -kExponentBias + 1;
+
+  uint64_t d64_;
+};
+
+} }  // namespace v8::internal
+
+#endif  // V8_DOUBLE_H_
new file mode 100644
--- /dev/null
+++ b/js/src/v8-dtoa/dtoa.h
@@ -0,0 +1,81 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_DTOA_H_
+#define V8_DTOA_H_
+
+namespace v8 {
+namespace internal {
+
+enum DtoaMode {
+  // 0.9999999999999999 becomes 0.1
+  DTOA_SHORTEST,
+  // Fixed number of digits after the decimal point.
+  // For instance fixed(0.1, 4) becomes 0.1000
+  // If the input number is big, the output will be big.
+  DTOA_FIXED,
+  // Fixed number of digits (independent of the decimal point).
+  DTOA_PRECISION
+};
+
+// The maximal length of digits a double can have in base 10.
+// Note that DoubleToAscii null-terminates its input. So the given buffer should
+// be at least kBase10MaximalLength + 1 characters long.
+static const int kBase10MaximalLength = 17;
+
+// Converts the given double 'v' to ascii.
+// The result should be interpreted as buffer * 10^(point-length).
+//
+// The output depends on the given mode:
+//  - SHORTEST: produce the least amount of digits for which the internal
+//   identity requirement is still satisfied. If the digits are printed
+//   (together with the correct exponent) then reading this number will give
+//   'v' again. The buffer will choose the representation that is closest to
+//   'v'. If there are two at the same distance, than the one farther away
+//   from 0 is chosen (halfway cases - ending with 5 - are rounded up).
+//   In this mode the 'requested_digits' parameter is ignored.
+//  - FIXED: produces digits necessary to print a given number with
+//   'requested_digits' digits after the decimal point. The produced digits
+//   might be too short in which case the caller has to fill the gaps with '0's.
+//   Example: toFixed(0.001, 5) is allowed to return buffer="1", point=-2.
+//   Halfway cases are rounded towards +/-Infinity (away from 0). The call
+//   toFixed(0.15, 2) thus returns buffer="2", point=0.
+//   The returned buffer may contain digits that would be truncated from the
+//   shortest representation of the input.
+//  - PRECISION: produces 'requested_digits' where the first digit is not '0'.
+//   Even though the length of produced digits usually equals
+//   'requested_digits', the function is allowed to return fewer digits, in
+//   which case the caller has to fill the missing digits with '0's.
+//   Halfway cases are again rounded away from 0.
+// 'DoubleToAscii' expects the given buffer to be big enough to hold all digits
+// and a terminating null-character.
+bool DoubleToAscii(double v, DtoaMode mode, int requested_digits,
+                   Vector<char> buffer, int* sign, int* length, int* point);
+
+} }  // namespace v8::internal
+
+#endif  // V8_DTOA_H_
new file mode 100644
--- /dev/null
+++ b/js/src/v8-dtoa/fast-dtoa.cc
@@ -0,0 +1,505 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "v8.h"
+
+#include "fast-dtoa.h"
+
+#include "cached-powers.h"
+#include "diy-fp.h"
+#include "double.h"
+
+namespace v8 {
+namespace internal {
+
+// The minimal and maximal target exponent define the range of w's binary
+// exponent, where 'w' is the result of multiplying the input by a cached power
+// of ten.
+//
+// A different range might be chosen on a different platform, to optimize digit
+// generation, but a smaller range requires more powers of ten to be cached.
+static const int minimal_target_exponent = -60;
+static const int maximal_target_exponent = -32;
+
+
+// Adjusts the last digit of the generated number, and screens out generated
+// solutions that may be inaccurate. A solution may be inaccurate if it is
+// outside the safe interval, or if we ctannot prove that it is closer to the
+// input than a neighboring representation of the same length.
+//
+// Input: * buffer containing the digits of too_high / 10^kappa
+//        * the buffer's length
+//        * distance_too_high_w == (too_high - w).f() * unit
+//        * unsafe_interval == (too_high - too_low).f() * unit
+//        * rest = (too_high - buffer * 10^kappa).f() * unit
+//        * ten_kappa = 10^kappa * unit
+//        * unit = the common multiplier
+// Output: returns true if the buffer is guaranteed to contain the closest
+//    representable number to the input.
+//  Modifies the generated digits in the buffer to approach (round towards) w.
+bool RoundWeed(Vector<char> buffer,
+               int length,
+               uint64_t distance_too_high_w,
+               uint64_t unsafe_interval,
+               uint64_t rest,
+               uint64_t ten_kappa,
+               uint64_t unit) {
+  uint64_t small_distance = distance_too_high_w - unit;
+  uint64_t big_distance = distance_too_high_w + unit;
+  // Let w_low  = too_high - big_distance, and
+  //     w_high = too_high - small_distance.
+  // Note: w_low < w < w_high
+  //
+  // The real w (* unit) must lie somewhere inside the interval
+  // ]w_low; w_low[ (often written as "(w_low; w_low)")
+
+  // Basically the buffer currently contains a number in the unsafe interval
+  // ]too_low; too_high[ with too_low < w < too_high
+  //
+  //  too_high - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  //                     ^v 1 unit            ^      ^                 ^      ^
+  //  boundary_high ---------------------     .      .                 .      .
+  //                     ^v 1 unit            .      .                 .      .
+  //   - - - - - - - - - - - - - - - - - - -  +  - - + - - - - - -     .      .
+  //                                          .      .         ^       .      .
+  //                                          .  big_distance  .       .      .
+  //                                          .      .         .       .    rest
+  //                              small_distance     .         .       .      .
+  //                                          v      .         .       .      .
+  //  w_high - - - - - - - - - - - - - - - - - -     .         .       .      .
+  //                     ^v 1 unit                   .         .       .      .
+  //  w ----------------------------------------     .         .       .      .
+  //                     ^v 1 unit                   v         .       .      .
+  //  w_low  - - - - - - - - - - - - - - - - - - - - -         .       .      .
+  //                                                           .       .      v
+  //  buffer --------------------------------------------------+-------+--------
+  //                                                           .       .
+  //                                                  safe_interval    .
+  //                                                           v       .
+  //   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -     .
+  //                     ^v 1 unit                                     .
+  //  boundary_low -------------------------                     unsafe_interval
+  //                     ^v 1 unit                                     v
+  //  too_low  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  //
+  //
+  // Note that the value of buffer could lie anywhere inside the range too_low
+  // to too_high.
+  //
+  // boundary_low, boundary_high and w are approximations of the real boundaries
+  // and v (the input number). They are guaranteed to be precise up to one unit.
+  // In fact the error is guaranteed to be strictly less than one unit.
+  //
+  // Anything that lies outside the unsafe interval is guaranteed not to round
+  // to v when read again.
+  // Anything that lies inside the safe interval is guaranteed to round to v
+  // when read again.
+  // If the number inside the buffer lies inside the unsafe interval but not
+  // inside the safe interval then we simply do not know and bail out (returning
+  // false).
+  //
+  // Similarly we have to take into account the imprecision of 'w' when rounding
+  // the buffer. If we have two potential representations we need to make sure
+  // that the chosen one is closer to w_low and w_high since v can be anywhere
+  // between them.
+  //
+  // By generating the digits of too_high we got the largest (closest to
+  // too_high) buffer that is still in the unsafe interval. In the case where
+  // w_high < buffer < too_high we try to decrement the buffer.
+  // This way the buffer approaches (rounds towards) w.
+  // There are 3 conditions that stop the decrementation process:
+  //   1) the buffer is already below w_high
+  //   2) decrementing the buffer would make it leave the unsafe interval
+  //   3) decrementing the buffer would yield a number below w_high and farther
+  //      away than the current number. In other words:
+  //              (buffer{-1} < w_high) && w_high - buffer{-1} > buffer - w_high
+  // Instead of using the buffer directly we use its distance to too_high.
+  // Conceptually rest ~= too_high - buffer
+  while (rest < small_distance &&  // Negated condition 1
+         unsafe_interval - rest >= ten_kappa &&  // Negated condition 2
+         (rest + ten_kappa < small_distance ||  // buffer{-1} > w_high
+          small_distance - rest >= rest + ten_kappa - small_distance)) {
+    buffer[length - 1]--;
+    rest += ten_kappa;
+  }
+
+  // We have approached w+ as much as possible. We now test if approaching w-
+  // would require changing the buffer. If yes, then we have two possible
+  // representations close to w, but we cannot decide which one is closer.
+  if (rest < big_distance &&
+      unsafe_interval - rest >= ten_kappa &&
+      (rest + ten_kappa < big_distance ||
+       big_distance - rest > rest + ten_kappa - big_distance)) {
+    return false;
+  }
+
+  // Weeding test.
+  //   The safe interval is [too_low + 2 ulp; too_high - 2 ulp]
+  //   Since too_low = too_high - unsafe_interval this is equivalent to
+  //      [too_high - unsafe_interval + 4 ulp; too_high - 2 ulp]
+  //   Conceptually we have: rest ~= too_high - buffer
+  return (2 * unit <= rest) && (rest <= unsafe_interval - 4 * unit);
+}
+
+
+
+static const uint32_t kTen4 = 10000;
+static const uint32_t kTen5 = 100000;
+static const uint32_t kTen6 = 1000000;
+static const uint32_t kTen7 = 10000000;
+static const uint32_t kTen8 = 100000000;
+static const uint32_t kTen9 = 1000000000;
+
+// Returns the biggest power of ten that is less than or equal than the given
+// number. We furthermore receive the maximum number of bits 'number' has.
+// If number_bits == 0 then 0^-1 is returned
+// The number of bits must be <= 32.
+// Precondition: (1 << number_bits) <= number < (1 << (number_bits + 1)).
+static void BiggestPowerTen(uint32_t number,
+                            int number_bits,
+                            uint32_t* power,
+                            int* exponent) {
+  switch (number_bits) {
+    case 32:
+    case 31:
+    case 30:
+      if (kTen9 <= number) {
+        *power = kTen9;
+        *exponent = 9;
+        break;
+      }  // else fallthrough
+    case 29:
+    case 28:
+    case 27:
+      if (kTen8 <= number) {
+        *power = kTen8;
+        *exponent = 8;
+        break;
+      }  // else fallthrough
+    case 26:
+    case 25:
+    case 24:
+      if (kTen7 <= number) {
+        *power = kTen7;
+        *exponent = 7;
+        break;
+      }  // else fallthrough
+    case 23:
+    case 22:
+    case 21:
+    case 20:
+      if (kTen6 <= number) {
+        *power = kTen6;
+        *exponent = 6;
+        break;
+      }  // else fallthrough
+    case 19:
+    case 18:
+    case 17:
+      if (kTen5 <= number) {
+        *power = kTen5;
+        *exponent = 5;
+        break;
+      }  // else fallthrough
+    case 16:
+    case 15:
+    case 14:
+      if (kTen4 <= number) {
+        *power = kTen4;
+        *exponent = 4;
+        break;
+      }  // else fallthrough
+    case 13:
+    case 12:
+    case 11:
+    case 10:
+      if (1000 <= number) {
+        *power = 1000;
+        *exponent = 3;
+        break;
+      }  // else fallthrough
+    case 9:
+    case 8:
+    case 7:
+      if (100 <= number) {
+        *power = 100;
+        *exponent = 2;
+        break;
+      }  // else fallthrough
+    case 6:
+    case 5:
+    case 4:
+      if (10 <= number) {
+        *power = 10;
+        *exponent = 1;
+        break;
+      }  // else fallthrough
+    case 3:
+    case 2:
+    case 1:
+      if (1 <= number) {
+        *power = 1;
+        *exponent = 0;
+        break;
+      }  // else fallthrough
+    case 0:
+      *power = 0;
+      *exponent = -1;
+      break;
+    default:
+      // Following assignments are here to silence compiler warnings.
+      *power = 0;
+      *exponent = 0;
+      UNREACHABLE();
+  }
+}
+
+
+// Generates the digits of input number w.
+// w is a floating-point number (DiyFp), consisting of a significand and an
+// exponent. Its exponent is bounded by minimal_target_exponent and
+// maximal_target_exponent.
+//       Hence -60 <= w.e() <= -32.
+//
+// Returns false if it fails, in which case the generated digits in the buffer
+// should not be used.
+// Preconditions:
+//  * low, w and high are correct up to 1 ulp (unit in the last place). That
+//    is, their error must be less that a unit of their last digits.
+//  * low.e() == w.e() == high.e()
+//  * low < w < high, and taking into account their error: low~ <= high~
+//  * minimal_target_exponent <= w.e() <= maximal_target_exponent
+// Postconditions: returns false if procedure fails.
+//   otherwise:
+//     * buffer is not null-terminated, but len contains the number of digits.
+//     * buffer contains the shortest possible decimal digit-sequence
+//       such that LOW < buffer * 10^kappa < HIGH, where LOW and HIGH are the
+//       correct values of low and high (without their error).
+//     * if more than one decimal representation gives the minimal number of
+//       decimal digits then the one closest to W (where W is the correct value
+//       of w) is chosen.
+// Remark: this procedure takes into account the imprecision of its input
+//   numbers. If the precision is not enough to guarantee all the postconditions
+//   then false is returned. This usually happens rarely (~0.5%).
+//
+// Say, for the sake of example, that
+//   w.e() == -48, and w.f() == 0x1234567890abcdef
+// w's value can be computed by w.f() * 2^w.e()
+// We can obtain w's integral digits by simply shifting w.f() by -w.e().
+//  -> w's integral part is 0x1234
+//  w's fractional part is therefore 0x567890abcdef.
+// Printing w's integral part is easy (simply print 0x1234 in decimal).
+// In order to print its fraction we repeatedly multiply the fraction by 10 and
+// get each digit. Example the first digit after the point would be computed by
+//   (0x567890abcdef * 10) >> 48. -> 3
+// The whole thing becomes slightly more complicated because we want to stop
+// once we have enough digits. That is, once the digits inside the buffer
+// represent 'w' we can stop. Everything inside the interval low - high
+// represents w. However we have to pay attention to low, high and w's
+// imprecision.
+bool DigitGen(DiyFp low,
+              DiyFp w,
+              DiyFp high,
+              Vector<char> buffer,
+              int* length,
+              int* kappa) {
+  ASSERT(low.e() == w.e() && w.e() == high.e());
+  ASSERT(low.f() + 1 <= high.f() - 1);
+  ASSERT(minimal_target_exponent <= w.e() && w.e() <= maximal_target_exponent);
+  // low, w and high are imprecise, but by less than one ulp (unit in the last
+  // place).
+  // If we remove (resp. add) 1 ulp from low (resp. high) we are certain that
+  // the new numbers are outside of the interval we want the final
+  // representation to lie in.
+  // Inversely adding (resp. removing) 1 ulp from low (resp. high) would yield
+  // numbers that are certain to lie in the interval. We will use this fact
+  // later on.
+  // We will now start by generating the digits within the uncertain
+  // interval. Later we will weed out representations that lie outside the safe
+  // interval and thus _might_ lie outside the correct interval.
+  uint64_t unit = 1;
+  DiyFp too_low = DiyFp(low.f() - unit, low.e());
+  DiyFp too_high = DiyFp(high.f() + unit, high.e());
+  // too_low and too_high are guaranteed to lie outside the interval we want the
+  // generated number in.
+  DiyFp unsafe_interval = DiyFp::Minus(too_high, too_low);
+  // We now cut the input number into two parts: the integral digits and the
+  // fractionals. We will not write any decimal separator though, but adapt
+  // kappa instead.
+  // Reminder: we are currently computing the digits (stored inside the buffer)
+  // such that:   too_low < buffer * 10^kappa < too_high
+  // We use too_high for the digit_generation and stop as soon as possible.
+  // If we stop early we effectively round down.
+  DiyFp one = DiyFp(static_cast<uint64_t>(1) << -w.e(), w.e());
+  // Division by one is a shift.
+  uint32_t integrals = static_cast<uint32_t>(too_high.f() >> -one.e());
+  // Modulo by one is an and.
+  uint64_t fractionals = too_high.f() & (one.f() - 1);
+  uint32_t divider;
+  int divider_exponent;
+  BiggestPowerTen(integrals, DiyFp::kSignificandSize - (-one.e()),
+                  &divider, &divider_exponent);
+  *kappa = divider_exponent + 1;
+  *length = 0;
+  // Loop invariant: buffer = too_high / 10^kappa  (integer division)
+  // The invariant holds for the first iteration: kappa has been initialized
+  // with the divider exponent + 1. And the divider is the biggest power of ten
+  // that is smaller than integrals.
+  while (*kappa > 0) {
+    int digit = integrals / divider;
+    buffer[*length] = '0' + digit;
+    (*length)++;
+    integrals %= divider;
+    (*kappa)--;
+    // Note that kappa now equals the exponent of the divider and that the
+    // invariant thus holds again.
+    uint64_t rest =
+        (static_cast<uint64_t>(integrals) << -one.e()) + fractionals;
+    // Invariant: too_high = buffer * 10^kappa + DiyFp(rest, one.e())
+    // Reminder: unsafe_interval.e() == one.e()
+    if (rest < unsafe_interval.f()) {
+      // Rounding down (by not emitting the remaining digits) yields a number
+      // that lies within the unsafe interval.
+      return RoundWeed(buffer, *length, DiyFp::Minus(too_high, w).f(),
+                       unsafe_interval.f(), rest,
+                       static_cast<uint64_t>(divider) << -one.e(), unit);
+    }
+    divider /= 10;
+  }
+
+  // The integrals have been generated. We are at the point of the decimal
+  // separator. In the following loop we simply multiply the remaining digits by
+  // 10 and divide by one. We just need to pay attention to multiply associated
+  // data (like the interval or 'unit'), too.
+  // Instead of multiplying by 10 we multiply by 5 (cheaper operation) and
+  // increase its (imaginary) exponent. At the same time we decrease the
+  // divider's (one's) exponent and shift its significand.
+  // Basically, if fractionals was a DiyFp (with fractionals.e == one.e):
+  //      fractionals.f *= 10;
+  //      fractionals.f >>= 1; fractionals.e++; // value remains unchanged.
+  //      one.f >>= 1; one.e++;                 // value remains unchanged.
+  //      and we have again fractionals.e == one.e which allows us to divide
+  //           fractionals.f() by one.f()
+  // We simply combine the *= 10 and the >>= 1.
+  while (true) {
+    fractionals *= 5;
+    unit *= 5;
+    unsafe_interval.set_f(unsafe_interval.f() * 5);
+    unsafe_interval.set_e(unsafe_interval.e() + 1);  // Will be optimized out.
+    one.set_f(one.f() >> 1);
+    one.set_e(one.e() + 1);
+    // Integer division by one.
+    int digit = static_cast<int>(fractionals >> -one.e());
+    buffer[*length] = '0' + digit;
+    (*length)++;
+    fractionals &= one.f() - 1;  // Modulo by one.
+    (*kappa)--;
+    if (fractionals < unsafe_interval.f()) {
+      return RoundWeed(buffer, *length, DiyFp::Minus(too_high, w).f() * unit,
+                       unsafe_interval.f(), fractionals, one.f(), unit);
+    }
+  }
+}
+
+
+// Provides a decimal representation of v.
+// Returns true if it succeeds, otherwise the result cannot be trusted.
+// There will be *length digits inside the buffer (not null-terminated).
+// If the function returns true then
+//        v == (double) (buffer * 10^decimal_exponent).
+// The digits in the buffer are the shortest representation possible: no
+// 0.09999999999999999 instead of 0.1. The shorter representation will even be
+// chosen even if the longer one would be closer to v.
+// The last digit will be closest to the actual v. That is, even if several
+// digits might correctly yield 'v' when read again, the closest will be
+// computed.
+bool grisu3(double v, Vector<char> buffer, int* length, int* decimal_exponent) {
+  DiyFp w = Double(v).AsNormalizedDiyFp();
+  // boundary_minus and boundary_plus are the boundaries between v and its
+  // closest floating-point neighbors. Any number strictly between
+  // boundary_minus and boundary_plus will round to v when convert to a double.
+  // Grisu3 will never output representations that lie exactly on a boundary.
+  DiyFp boundary_minus, boundary_plus;
+  Double(v).NormalizedBoundaries(&boundary_minus, &boundary_plus);
+  ASSERT(boundary_plus.e() == w.e());
+  DiyFp ten_mk;  // Cached power of ten: 10^-k
+  int mk;        // -k
+  GetCachedPower(w.e() + DiyFp::kSignificandSize, minimal_target_exponent,
+                 maximal_target_exponent, &mk, &ten_mk);
+  ASSERT(minimal_target_exponent <= w.e() + ten_mk.e() +
+         DiyFp::kSignificandSize &&
+         maximal_target_exponent >= w.e() + ten_mk.e() +
+         DiyFp::kSignificandSize);
+  // Note that ten_mk is only an approximation of 10^-k. A DiyFp only contains a
+  // 64 bit significand and ten_mk is thus only precise up to 64 bits.
+
+  // The DiyFp::Times procedure rounds its result, and ten_mk is approximated
+  // too. The variable scaled_w (as well as scaled_boundary_minus/plus) are now
+  // off by a small amount.
+  // In fact: scaled_w - w*10^k < 1ulp (unit in the last place) of scaled_w.
+  // In other words: let f = scaled_w.f() and e = scaled_w.e(), then
+  //           (f-1) * 2^e < w*10^k < (f+1) * 2^e
+  DiyFp scaled_w = DiyFp::Times(w, ten_mk);
+  ASSERT(scaled_w.e() ==
+         boundary_plus.e() + ten_mk.e() + DiyFp::kSignificandSize);
+  // In theory it would be possible to avoid some recomputations by computing
+  // the difference between w and boundary_minus/plus (a power of 2) and to
+  // compute scaled_boundary_minus/plus by subtracting/adding from
+  // scaled_w. However the code becomes much less readable and the speed
+  // enhancements are not terriffic.
+  DiyFp scaled_boundary_minus = DiyFp::Times(boundary_minus, ten_mk);
+  DiyFp scaled_boundary_plus  = DiyFp::Times(boundary_plus,  ten_mk);
+
+  // DigitGen will generate the digits of scaled_w. Therefore we have
+  // v == (double) (scaled_w * 10^-mk).
+  // Set decimal_exponent == -mk and pass it to DigitGen. If scaled_w is not an
+  // integer than it will be updated. For instance if scaled_w == 1.23 then
+  // the buffer will be filled with "123" und the decimal_exponent will be
+  // decreased by 2.
+  int kappa;
+  bool result = DigitGen(scaled_boundary_minus, scaled_w, scaled_boundary_plus,
+                         buffer, length, &kappa);
+  *decimal_exponent = -mk + kappa;
+  return result;
+}
+
+
+bool FastDtoa(double v,
+              Vector<char> buffer,
+              int* length,
+              int* point) {
+  ASSERT(v > 0);
+  ASSERT(!Double(v).IsSpecial());
+
+  int decimal_exponent;
+  bool result = grisu3(v, buffer, length, &decimal_exponent);
+  *point = *length + decimal_exponent;
+  buffer[*length] = '\0';
+  return result;
+}
+
+} }  // namespace v8::internal
new file mode 100644
--- /dev/null
+++ b/js/src/v8-dtoa/fast-dtoa.h
@@ -0,0 +1,58 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_FAST_DTOA_H_
+#define V8_FAST_DTOA_H_
+
+namespace v8 {
+namespace internal {
+
+// FastDtoa will produce at most kFastDtoaMaximalLength digits. This does not
+// include the terminating '\0' character.
+static const int kFastDtoaMaximalLength = 17;
+
+// Provides a decimal representation of v.
+// v must be a strictly positive finite double.
+// Returns true if it succeeds, otherwise the result can not be trusted.
+// There will be *length digits inside the buffer followed by a null terminator.
+// If the function returns true then
+//   v == (double) (buffer * 10^(point - length)).
+// The digits in the buffer are the shortest representation possible: no
+// 0.099999999999 instead of 0.1.
+// The last digit will be closest to the actual v. That is, even if several
+// digits might correctly yield 'v' when read again, the buffer will contain the
+// one closest to v.
+// The variable 'sign' will be '0' if the given number is positive, and '1'
+//   otherwise.
+bool FastDtoa(double d,
+              Vector<char> buffer,
+              int* length,
+              int* point);
+
+} }  // namespace v8::internal
+
+#endif  // V8_FAST_DTOA_H_
new file mode 100644
--- /dev/null
+++ b/js/src/v8-dtoa/globals.h
@@ -0,0 +1,69 @@
+// Copyright 2006-2009 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_GLOBALS_H_
+#define V8_GLOBALS_H_
+
+namespace v8 {
+namespace internal {
+
+
+// The following macro works on both 32 and 64-bit platforms.
+// Usage: instead of writing 0x1234567890123456
+//      write V8_2PART_UINT64_C(0x12345678,90123456);
+#define V8_2PART_UINT64_C(a, b) (((static_cast<uint64_t>(a) << 32) + 0x##b##u))
+
+// -----------------------------------------------------------------------------
+// Constants
+
+const int kCharSize     = sizeof(char);      // NOLINT
+
+
+// -----------------------------------------------------------------------------
+// Macros
+
+
+// A macro to disallow the evil copy constructor and operator= functions
+// This should be used in the private: declarations for a class
+#define DISALLOW_COPY_AND_ASSIGN(TypeName)      \
+  TypeName(const TypeName&);                    \
+  void operator=(const TypeName&)
+
+
+// A macro to disallow all the implicit constructors, namely the
+// default constructor, copy constructor and operator= functions.
+//
+// This should be used in the private: declarations for a class
+// that wants to prevent anyone from instantiating it. This is
+// especially useful for classes containing only static methods.
+#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
+  TypeName();                                    \
+  DISALLOW_COPY_AND_ASSIGN(TypeName)
+
+} }  // namespace v8::internal
+
+#endif  // V8_GLOBALS_H_
new file mode 100644
--- /dev/null
+++ b/js/src/v8-dtoa/include-v8.h
@@ -0,0 +1,59 @@
+// Copyright 2007-2009 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_H_
+#define V8_H_
+
+// MOZ: this file was called ../include/v8.h (that's relative to the V8's src/
+// directory).  It was renamed so that all V8 files could be put in one
+// directory within SpiderMonkey.  All #includes were modified accordingly.
+
+#include <stdio.h>
+
+#ifdef _WIN32
+// When compiling on MinGW stdint.h is available.
+#ifdef __MINGW32__
+#include <stdint.h>
+#else  // __MINGW32__
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+typedef short int16_t;  // NOLINT
+typedef unsigned short uint16_t;  // NOLINT
+typedef int int32_t;
+typedef unsigned int uint32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+// intptr_t and friends are defined in crtdefs.h through stdio.h.
+#endif  // __MINGW32__
+
+#else  // _WIN32
+
+#include <stdint.h>
+
+#endif  // _WIN32
+
+#endif  // V8_H_
new file mode 100644
--- /dev/null
+++ b/js/src/v8-dtoa/platform.cc
@@ -0,0 +1,111 @@
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// MOZ: This file is a merge of the relevant parts of all the platform-*.cc
+// files in v8;  the amount of code remaining was small enough that putting
+// everything in a single file was easier, particularly because it means we
+// can always compile this one file on every platform.
+
+#include <math.h>
+#include <signal.h>
+#include <stdlib.h>
+
+#include "v8.h"
+
+namespace v8 {
+namespace internal {
+
+double ceiling(double x) {
+#if defined(__APPLE__)
+  // Correct Mac OS X Leopard 'ceil' behavior.
+  //
+  // MOZ: This appears to be fixed in Mac OS X 10.5.8.
+  //
+  // MOZ: This fix is apprently also required for FreeBSD and OpenBSD, if we
+  // have to worry about them.
+  if (-1.0 < x && x < 0.0) {
+    return -0.0;
+  } else {
+    return ceil(x);
+  }
+#else
+  return ceil(x);
+#endif
+}
+
+
+// MOZ: These exit behaviours were copied from SpiderMonkey's JS_Assert()
+// function.
+void OS::Abort() {
+#if defined(WIN32)
+    /*
+     * We used to call DebugBreak() on Windows, but amazingly, it causes
+     * the MSVS 2010 debugger not to be able to recover a call stack.
+     */
+    *((int *) NULL) = 0;
+    exit(3);
+#elif defined(__APPLE__)
+    /*
+     * On Mac OS X, Breakpad ignores signals. Only real Mach exceptions are
+     * trapped.
+     */
+    *((int *) NULL) = 0;  /* To continue from here in GDB: "return" then "continue". */
+    raise(SIGABRT);  /* In case above statement gets nixed by the optimizer. */
+#else
+    raise(SIGABRT);  /* To continue from here in GDB: "signal 0". */
+#endif
+}
+
+} }  // namespace v8::internal
+
+// Extra POSIX/ANSI routines for Win32 when when using Visual Studio C++. Please
+// refer to The Open Group Base Specification for specification of the correct
+// semantics for these functions.
+// (http://www.opengroup.org/onlinepubs/000095399/)
+#ifdef _MSC_VER
+
+#include <float.h>
+
+// Classify floating point number - usually defined in math.h
+int fpclassify(double x) {
+  // Use the MS-specific _fpclass() for classification.
+  int flags = _fpclass(x);
+
+  // Determine class. We cannot use a switch statement because
+  // the _FPCLASS_ constants are defined as flags.
+  if (flags & (_FPCLASS_PN | _FPCLASS_NN)) return FP_NORMAL;
+  if (flags & (_FPCLASS_PZ | _FPCLASS_NZ)) return FP_ZERO;
+  if (flags & (_FPCLASS_PD | _FPCLASS_ND)) return FP_SUBNORMAL;
+  if (flags & (_FPCLASS_PINF | _FPCLASS_NINF)) return FP_INFINITE;
+
+  // All cases should be covered by the code above.
+  ASSERT(flags & (_FPCLASS_SNAN | _FPCLASS_QNAN));
+  return FP_NAN;
+}
+
+
+#endif  // _MSC_VER
new file mode 100644
--- /dev/null
+++ b/js/src/v8-dtoa/platform.h
@@ -0,0 +1,100 @@
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This module contains the platform-specific code. This make the rest of the
+// code less dependent on operating system, compilers and runtime libraries.
+// This module does specifically not deal with differences between different
+// processor architecture.
+// The platform classes have the same definition for all platforms. The
+// implementation for a particular platform is put in platform_<os>.cc.
+// The build system then uses the implementation for the target platform.
+//
+// This design has been chosen because it is simple and fast. Alternatively,
+// the platform dependent classes could have been implemented using abstract
+// superclasses with virtual methods and having specializations for each
+// platform. This design was rejected because it was more complicated and
+// slower. It would require factory methods for selecting the right
+// implementation and the overhead of virtual methods for performance
+// sensitive like mutex locking/unlocking.
+
+#ifndef V8_PLATFORM_H_
+#define V8_PLATFORM_H_
+
+// Windows specific stuff.
+#ifdef WIN32
+
+// Microsoft Visual C++ specific stuff.
+#ifdef _MSC_VER
+
+enum {
+  FP_NAN,
+  FP_INFINITE,
+  FP_ZERO,
+  FP_SUBNORMAL,
+  FP_NORMAL
+};
+
+int fpclassify(double x);
+
+int strncasecmp(const char* s1, const char* s2, int n);
+
+#endif  // _MSC_VER
+
+#endif  // WIN32
+
+
+// GCC specific stuff
+#ifdef __GNUC__
+
+// Needed for va_list on at least MinGW and Android.
+#include <stdarg.h>
+
+#define __GNUC_VERSION__ (__GNUC__ * 10000 + __GNUC_MINOR__ * 100)
+
+#endif  // __GNUC__
+
+namespace v8 {
+namespace internal {
+
+double ceiling(double x);
+
+// ----------------------------------------------------------------------------
+// OS
+//
+// This class has static methods for the different platform specific
+// functions. Add methods here to cope with differences between the
+// supported platforms.
+
+class OS {
+ public:
+  // Abort the current process.
+  static void Abort();
+};
+
+} }  // namespace v8::internal
+
+#endif  // V8_PLATFORM_H_
new file mode 100644
--- /dev/null
+++ b/js/src/v8-dtoa/powers-ten.h
@@ -0,0 +1,2461 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// ------------ GENERATED FILE ----------------
+// command used:
+//  tools/generate-ten-powers --from -308 --to 342 --mantissa-size 64 --round round -o src/powers-ten.h  // NOLINT
+
+// This file is intended to be included inside another .h or .cc files
+// with the following defines set:
+//  GRISU_CACHE_STRUCT: should expand to the name of a struct that will
+//   hold the cached powers of ten. Each entry will hold a 64-bit
+//   significand, a 16-bit signed binary exponent, and a 16-bit
+//   signed decimal exponent. Each entry will be constructed as follows:
+//      { significand, binary_exponent, decimal_exponent }.
+//  GRISU_CACHE_NAME(i): generates the name for the different caches.
+//   The parameter i will be a number in the range 1-20. A cache will
+//   hold every i'th element of a full cache. GRISU_CACHE_NAME(1) will
+//   thus hold all elements. The higher i the fewer elements it has.
+//   Ideally the user should only reference one cache and let the
+//   compiler remove the unused ones.
+//  GRISU_CACHE_MAX_DISTANCE(i): generates the name for the maximum
+//   binary exponent distance between all elements of a given cache.
+//  GRISU_CACHE_OFFSET: is used as variable name for the decimal
+//   exponent offset. It is equal to -cache[0].decimal_exponent.
+//  GRISU_UINT64_C: used to construct 64-bit values in a platform
+//   independent way. In order to encode 0x123456789ABCDEF0 the macro
+//   will be invoked as follows: GRISU_UINT64_C(0x12345678,9ABCDEF0).
+
+
+static const GRISU_CACHE_STRUCT GRISU_CACHE_NAME(1)[] = {
+  {GRISU_UINT64_C(0xe61acf03, 3d1a45df), -1087, -308},
+  {GRISU_UINT64_C(0x8fd0c162, 06306bac), -1083, -307},
+  {GRISU_UINT64_C(0xb3c4f1ba, 87bc8697), -1080, -306},
+  {GRISU_UINT64_C(0xe0b62e29, 29aba83c), -1077, -305},
+  {GRISU_UINT64_C(0x8c71dcd9, ba0b4926), -1073, -304},
+  {GRISU_UINT64_C(0xaf8e5410, 288e1b6f), -1070, -303},
+  {GRISU_UINT64_C(0xdb71e914, 32b1a24b), -1067, -302},
+  {GRISU_UINT64_C(0x892731ac, 9faf056f), -1063, -301},
+  {GRISU_UINT64_C(0xab70fe17, c79ac6ca), -1060, -300},
+  {GRISU_UINT64_C(0xd64d3d9d, b981787d), -1057, -299},
+  {GRISU_UINT64_C(0x85f04682, 93f0eb4e), -1053, -298},
+  {GRISU_UINT64_C(0xa76c5823, 38ed2622), -1050, -297},
+  {GRISU_UINT64_C(0xd1476e2c, 07286faa), -1047, -296},
+  {GRISU_UINT64_C(0x82cca4db, 847945ca), -1043, -295},
+  {GRISU_UINT64_C(0xa37fce12, 6597973d), -1040, -294},
+  {GRISU_UINT64_C(0xcc5fc196, fefd7d0c), -1037, -293},
+  {GRISU_UINT64_C(0xff77b1fc, bebcdc4f), -1034, -292},
+  {GRISU_UINT64_C(0x9faacf3d, f73609b1), -1030, -291},
+  {GRISU_UINT64_C(0xc795830d, 75038c1e), -1027, -290},
+  {GRISU_UINT64_C(0xf97ae3d0, d2446f25), -1024, -289},
+  {GRISU_UINT64_C(0x9becce62, 836ac577), -1020, -288},
+  {GRISU_UINT64_C(0xc2e801fb, 244576d5), -1017, -287},
+  {GRISU_UINT64_C(0xf3a20279, ed56d48a), -1014, -286},
+  {GRISU_UINT64_C(0x9845418c, 345644d7), -1010, -285},
+  {GRISU_UINT64_C(0xbe5691ef, 416bd60c), -1007, -284},
+  {GRISU_UINT64_C(0xedec366b, 11c6cb8f), -1004, -283},
+  {GRISU_UINT64_C(0x94b3a202, eb1c3f39), -1000, -282},
+  {GRISU_UINT64_C(0xb9e08a83, a5e34f08), -997, -281},
+  {GRISU_UINT64_C(0xe858ad24, 8f5c22ca), -994, -280},
+  {GRISU_UINT64_C(0x91376c36, d99995be), -990, -279},
+  {GRISU_UINT64_C(0xb5854744, 8ffffb2e), -987, -278},
+  {GRISU_UINT64_C(0xe2e69915, b3fff9f9), -984, -277},
+  {GRISU_UINT64_C(0x8dd01fad, 907ffc3c), -980, -276},
+  {GRISU_UINT64_C(0xb1442798, f49ffb4b), -977, -275},
+  {GRISU_UINT64_C(0xdd95317f, 31c7fa1d), -974, -274},
+  {GRISU_UINT64_C(0x8a7d3eef, 7f1cfc52), -970, -273},
+  {GRISU_UINT64_C(0xad1c8eab, 5ee43b67), -967, -272},
+  {GRISU_UINT64_C(0xd863b256, 369d4a41), -964, -271},
+  {GRISU_UINT64_C(0x873e4f75, e2224e68), -960, -270},
+  {GRISU_UINT64_C(0xa90de353, 5aaae202), -957, -269},
+  {GRISU_UINT64_C(0xd3515c28, 31559a83), -954, -268},
+  {GRISU_UINT64_C(0x8412d999, 1ed58092), -950, -267},
+  {GRISU_UINT64_C(0xa5178fff, 668ae0b6), -947, -266},
+  {GRISU_UINT64_C(0xce5d73ff, 402d98e4), -944, -265},
+  {GRISU_UINT64_C(0x80fa687f, 881c7f8e), -940, -264},
+  {GRISU_UINT64_C(0xa139029f, 6a239f72), -937, -263},
+  {GRISU_UINT64_C(0xc9874347, 44ac874f), -934, -262},
+  {GRISU_UINT64_C(0xfbe91419, 15d7a922), -931, -261},
+  {GRISU_UINT64_C(0x9d71ac8f, ada6c9b5), -927, -260},
+  {GRISU_UINT64_C(0xc4ce17b3, 99107c23), -924, -259},
+  {GRISU_UINT64_C(0xf6019da0, 7f549b2b), -921, -258},
+  {GRISU_UINT64_C(0x99c10284, 4f94e0fb), -917, -257},
+  {GRISU_UINT64_C(0xc0314325, 637a193a), -914, -256},
+  {GRISU_UINT64_C(0xf03d93ee, bc589f88), -911, -255},
+  {GRISU_UINT64_C(0x96267c75, 35b763b5), -907, -254},
+  {GRISU_UINT64_C(0xbbb01b92, 83253ca3), -904, -253},
+  {GRISU_UINT64_C(0xea9c2277, 23ee8bcb), -901, -252},
+  {GRISU_UINT64_C(0x92a1958a, 7675175f), -897, -251},
+  {GRISU_UINT64_C(0xb749faed, 14125d37), -894, -250},
+  {GRISU_UINT64_C(0xe51c79a8, 5916f485), -891, -249},
+  {GRISU_UINT64_C(0x8f31cc09, 37ae58d3), -887, -248},
+  {GRISU_UINT64_C(0xb2fe3f0b, 8599ef08), -884, -247},
+  {GRISU_UINT64_C(0xdfbdcece, 67006ac9), -881, -246},
+  {GRISU_UINT64_C(0x8bd6a141, 006042be), -877, -245},
+  {GRISU_UINT64_C(0xaecc4991, 4078536d), -874, -244},
+  {GRISU_UINT64_C(0xda7f5bf5, 90966849), -871, -243},
+  {GRISU_UINT64_C(0x888f9979, 7a5e012d), -867, -242},
+  {GRISU_UINT64_C(0xaab37fd7, d8f58179), -864, -241},
+  {GRISU_UINT64_C(0xd5605fcd, cf32e1d7), -861, -240},
+  {GRISU_UINT64_C(0x855c3be0, a17fcd26), -857, -239},
+  {GRISU_UINT64_C(0xa6b34ad8, c9dfc070), -854, -238},
+  {GRISU_UINT64_C(0xd0601d8e, fc57b08c), -851, -237},
+  {GRISU_UINT64_C(0x823c1279, 5db6ce57), -847, -236},
+  {GRISU_UINT64_C(0xa2cb1717, b52481ed), -844, -235},
+  {GRISU_UINT64_C(0xcb7ddcdd, a26da269), -841, -234},
+  {GRISU_UINT64_C(0xfe5d5415, 0b090b03), -838, -233},
+  {GRISU_UINT64_C(0x9efa548d, 26e5a6e2), -834, -232},
+  {GRISU_UINT64_C(0xc6b8e9b0, 709f109a), -831, -231},
+  {GRISU_UINT64_C(0xf867241c, 8cc6d4c1), -828, -230},
+  {GRISU_UINT64_C(0x9b407691, d7fc44f8), -824, -229},
+  {GRISU_UINT64_C(0xc2109436, 4dfb5637), -821, -228},
+  {GRISU_UINT64_C(0xf294b943, e17a2bc4), -818, -227},
+  {GRISU_UINT64_C(0x979cf3ca, 6cec5b5b), -814, -226},
+  {GRISU_UINT64_C(0xbd8430bd, 08277231), -811, -225},
+  {GRISU_UINT64_C(0xece53cec, 4a314ebe), -808, -224},
+  {GRISU_UINT64_C(0x940f4613, ae5ed137), -804, -223},
+  {GRISU_UINT64_C(0xb9131798, 99f68584), -801, -222},
+  {GRISU_UINT64_C(0xe757dd7e, c07426e5), -798, -221},
+  {GRISU_UINT64_C(0x9096ea6f, 3848984f), -794, -220},
+  {GRISU_UINT64_C(0xb4bca50b, 065abe63), -791, -219},
+  {GRISU_UINT64_C(0xe1ebce4d, c7f16dfc), -788, -218},
+  {GRISU_UINT64_C(0x8d3360f0, 9cf6e4bd), -784, -217},
+  {GRISU_UINT64_C(0xb080392c, c4349ded), -781, -216},
+  {GRISU_UINT64_C(0xdca04777, f541c568), -778, -215},
+  {GRISU_UINT64_C(0x89e42caa, f9491b61), -774, -214},
+  {GRISU_UINT64_C(0xac5d37d5, b79b6239), -771, -213},
+  {GRISU_UINT64_C(0xd77485cb, 25823ac7), -768, -212},
+  {GRISU_UINT64_C(0x86a8d39e, f77164bd), -764, -211},
+  {GRISU_UINT64_C(0xa8530886, b54dbdec), -761, -210},
+  {GRISU_UINT64_C(0xd267caa8, 62a12d67), -758, -209},
+  {GRISU_UINT64_C(0x8380dea9, 3da4bc60), -754, -208},
+  {GRISU_UINT64_C(0xa4611653, 8d0deb78), -751, -207},
+  {GRISU_UINT64_C(0xcd795be8, 70516656), -748, -206},
+  {GRISU_UINT64_C(0x806bd971, 4632dff6), -744, -205},
+  {GRISU_UINT64_C(0xa086cfcd, 97bf97f4), -741, -204},
+  {GRISU_UINT64_C(0xc8a883c0, fdaf7df0), -738, -203},
+  {GRISU_UINT64_C(0xfad2a4b1, 3d1b5d6c), -735, -202},
+  {GRISU_UINT64_C(0x9cc3a6ee, c6311a64), -731, -201},
+  {GRISU_UINT64_C(0xc3f490aa, 77bd60fd), -728, -200},
+  {GRISU_UINT64_C(0xf4f1b4d5, 15acb93c), -725, -199},
+  {GRISU_UINT64_C(0x99171105, 2d8bf3c5), -721, -198},
+  {GRISU_UINT64_C(0xbf5cd546, 78eef0b7), -718, -197},
+  {GRISU_UINT64_C(0xef340a98, 172aace5), -715, -196},
+  {GRISU_UINT64_C(0x9580869f, 0e7aac0f), -711, -195},
+  {GRISU_UINT64_C(0xbae0a846, d2195713), -708, -194},
+  {GRISU_UINT64_C(0xe998d258, 869facd7), -705, -193},
+  {GRISU_UINT64_C(0x91ff8377, 5423cc06), -701, -192},
+  {GRISU_UINT64_C(0xb67f6455, 292cbf08), -698, -191},
+  {GRISU_UINT64_C(0xe41f3d6a, 7377eeca), -695, -190},
+  {GRISU_UINT64_C(0x8e938662, 882af53e), -691, -189},
+  {GRISU_UINT64_C(0xb23867fb, 2a35b28e), -688, -188},
+  {GRISU_UINT64_C(0xdec681f9, f4c31f31), -685, -187},
+  {GRISU_UINT64_C(0x8b3c113c, 38f9f37f), -681, -186},
+  {GRISU_UINT64_C(0xae0b158b, 4738705f), -678, -185},
+  {GRISU_UINT64_C(0xd98ddaee, 19068c76), -675, -184},
+  {GRISU_UINT64_C(0x87f8a8d4, cfa417ca), -671, -183},
+  {GRISU_UINT64_C(0xa9f6d30a, 038d1dbc), -668, -182},
+  {GRISU_UINT64_C(0xd47487cc, 8470652b), -665, -181},
+  {GRISU_UINT64_C(0x84c8d4df, d2c63f3b), -661, -180},
+  {GRISU_UINT64_C(0xa5fb0a17, c777cf0a), -658, -179},
+  {GRISU_UINT64_C(0xcf79cc9d, b955c2cc), -655, -178},
+  {GRISU_UINT64_C(0x81ac1fe2, 93d599c0), -651, -177},
+  {GRISU_UINT64_C(0xa21727db, 38cb0030), -648, -176},
+  {GRISU_UINT64_C(0xca9cf1d2, 06fdc03c), -645, -175},
+  {GRISU_UINT64_C(0xfd442e46, 88bd304b), -642, -174},
+  {GRISU_UINT64_C(0x9e4a9cec, 15763e2f), -638, -173},
+  {GRISU_UINT64_C(0xc5dd4427, 1ad3cdba), -635, -172},
+  {GRISU_UINT64_C(0xf7549530, e188c129), -632, -171},
+  {GRISU_UINT64_C(0x9a94dd3e, 8cf578ba), -628, -170},
+  {GRISU_UINT64_C(0xc13a148e, 3032d6e8), -625, -169},
+  {GRISU_UINT64_C(0xf18899b1, bc3f8ca2), -622, -168},
+  {GRISU_UINT64_C(0x96f5600f, 15a7b7e5), -618, -167},
+  {GRISU_UINT64_C(0xbcb2b812, db11a5de), -615, -166},
+  {GRISU_UINT64_C(0xebdf6617, 91d60f56), -612, -165},
+  {GRISU_UINT64_C(0x936b9fce, bb25c996), -608, -164},
+  {GRISU_UINT64_C(0xb84687c2, 69ef3bfb), -605, -163},
+  {GRISU_UINT64_C(0xe65829b3, 046b0afa), -602, -162},
+  {GRISU_UINT64_C(0x8ff71a0f, e2c2e6dc), -598, -161},
+  {GRISU_UINT64_C(0xb3f4e093, db73a093), -595, -160},
+  {GRISU_UINT64_C(0xe0f218b8, d25088b8), -592, -159},
+  {GRISU_UINT64_C(0x8c974f73, 83725573), -588, -158},
+  {GRISU_UINT64_C(0xafbd2350, 644eead0), -585, -157},
+  {GRISU_UINT64_C(0xdbac6c24, 7d62a584), -582, -156},
+  {GRISU_UINT64_C(0x894bc396, ce5da772), -578, -155},
+  {GRISU_UINT64_C(0xab9eb47c, 81f5114f), -575, -154},
+  {GRISU_UINT64_C(0xd686619b, a27255a3), -572, -153},
+  {GRISU_UINT64_C(0x8613fd01, 45877586), -568, -152},
+  {GRISU_UINT64_C(0xa798fc41, 96e952e7), -565, -151},
+  {GRISU_UINT64_C(0xd17f3b51, fca3a7a1), -562, -150},
+  {GRISU_UINT64_C(0x82ef8513, 3de648c5), -558, -149},
+  {GRISU_UINT64_C(0xa3ab6658, 0d5fdaf6), -555, -148},
+  {GRISU_UINT64_C(0xcc963fee, 10b7d1b3), -552, -147},
+  {GRISU_UINT64_C(0xffbbcfe9, 94e5c620), -549, -146},
+  {GRISU_UINT64_C(0x9fd561f1, fd0f9bd4), -545, -145},
+  {GRISU_UINT64_C(0xc7caba6e, 7c5382c9), -542, -144},
+  {GRISU_UINT64_C(0xf9bd690a, 1b68637b), -539, -143},
+  {GRISU_UINT64_C(0x9c1661a6, 51213e2d), -535, -142},
+  {GRISU_UINT64_C(0xc31bfa0f, e5698db8), -532, -141},
+  {GRISU_UINT64_C(0xf3e2f893, dec3f126), -529, -140},
+  {GRISU_UINT64_C(0x986ddb5c, 6b3a76b8), -525, -139},
+  {GRISU_UINT64_C(0xbe895233, 86091466), -522, -138},
+  {GRISU_UINT64_C(0xee2ba6c0, 678b597f), -519, -137},
+  {GRISU_UINT64_C(0x94db4838, 40b717f0), -515, -136},
+  {GRISU_UINT64_C(0xba121a46, 50e4ddec), -512, -135},
+  {GRISU_UINT64_C(0xe896a0d7, e51e1566), -509, -134},
+  {GRISU_UINT64_C(0x915e2486, ef32cd60), -505, -133},
+  {GRISU_UINT64_C(0xb5b5ada8, aaff80b8), -502, -132},
+  {GRISU_UINT64_C(0xe3231912, d5bf60e6), -499, -131},
+  {GRISU_UINT64_C(0x8df5efab, c5979c90), -495, -130},
+  {GRISU_UINT64_C(0xb1736b96, b6fd83b4), -492, -129},
+  {GRISU_UINT64_C(0xddd0467c, 64bce4a1), -489, -128},
+  {GRISU_UINT64_C(0x8aa22c0d, bef60ee4), -485, -127},
+  {GRISU_UINT64_C(0xad4ab711, 2eb3929e), -482, -126},
+  {GRISU_UINT64_C(0xd89d64d5, 7a607745), -479, -125},
+  {GRISU_UINT64_C(0x87625f05, 6c7c4a8b), -475, -124},
+  {GRISU_UINT64_C(0xa93af6c6, c79b5d2e), -472, -123},
+  {GRISU_UINT64_C(0xd389b478, 79823479), -469, -122},
+  {GRISU_UINT64_C(0x843610cb, 4bf160cc), -465, -121},
+  {GRISU_UINT64_C(0xa54394fe, 1eedb8ff), -462, -120},
+  {GRISU_UINT64_C(0xce947a3d, a6a9273e), -459, -119},
+  {GRISU_UINT64_C(0x811ccc66, 8829b887), -455, -118},
+  {GRISU_UINT64_C(0xa163ff80, 2a3426a9), -452, -117},
+  {GRISU_UINT64_C(0xc9bcff60, 34c13053), -449, -116},
+  {GRISU_UINT64_C(0xfc2c3f38, 41f17c68), -446, -115},
+  {GRISU_UINT64_C(0x9d9ba783, 2936edc1), -442, -114},
+  {GRISU_UINT64_C(0xc5029163, f384a931), -439, -113},
+  {GRISU_UINT64_C(0xf64335bc, f065d37d), -436, -112},
+  {GRISU_UINT64_C(0x99ea0196, 163fa42e), -432, -111},
+  {GRISU_UINT64_C(0xc06481fb, 9bcf8d3a), -429, -110},
+  {GRISU_UINT64_C(0xf07da27a, 82c37088), -426, -109},
+  {GRISU_UINT64_C(0x964e858c, 91ba2655), -422, -108},
+  {GRISU_UINT64_C(0xbbe226ef, b628afeb), -419, -107},
+  {GRISU_UINT64_C(0xeadab0ab, a3b2dbe5), -416, -106},
+  {GRISU_UINT64_C(0x92c8ae6b, 464fc96f), -412, -105},
+  {GRISU_UINT64_C(0xb77ada06, 17e3bbcb), -409, -104},
+  {GRISU_UINT64_C(0xe5599087, 9ddcaabe), -406, -103},
+  {GRISU_UINT64_C(0x8f57fa54, c2a9eab7), -402, -102},
+  {GRISU_UINT64_C(0xb32df8e9, f3546564), -399, -101},
+  {GRISU_UINT64_C(0xdff97724, 70297ebd), -396, -100},
+  {GRISU_UINT64_C(0x8bfbea76, c619ef36), -392, -99},
+  {GRISU_UINT64_C(0xaefae514, 77a06b04), -389, -98},
+  {GRISU_UINT64_C(0xdab99e59, 958885c5), -386, -97},
+  {GRISU_UINT64_C(0x88b402f7, fd75539b), -382, -96},
+  {GRISU_UINT64_C(0xaae103b5, fcd2a882), -379, -95},
+  {GRISU_UINT64_C(0xd59944a3, 7c0752a2), -376, -94},
+  {GRISU_UINT64_C(0x857fcae6, 2d8493a5), -372, -93},
+  {GRISU_UINT64_C(0xa6dfbd9f, b8e5b88f), -369, -92},
+  {GRISU_UINT64_C(0xd097ad07, a71f26b2), -366, -91},
+  {GRISU_UINT64_C(0x825ecc24, c8737830), -362, -90},
+  {GRISU_UINT64_C(0xa2f67f2d, fa90563b), -359, -89},
+  {GRISU_UINT64_C(0xcbb41ef9, 79346bca), -356, -88},
+  {GRISU_UINT64_C(0xfea126b7, d78186bd), -353, -87},
+  {GRISU_UINT64_C(0x9f24b832, e6b0f436), -349, -86},
+  {GRISU_UINT64_C(0xc6ede63f, a05d3144), -346, -85},
+  {GRISU_UINT64_C(0xf8a95fcf, 88747d94), -343, -84},
+  {GRISU_UINT64_C(0x9b69dbe1, b548ce7d), -339, -83},
+  {GRISU_UINT64_C(0xc24452da, 229b021c), -336, -82},
+  {GRISU_UINT64_C(0xf2d56790, ab41c2a3), -333, -81},
+  {GRISU_UINT64_C(0x97c560ba, 6b0919a6), -329, -80},
+  {GRISU_UINT64_C(0xbdb6b8e9, 05cb600f), -326, -79},
+  {GRISU_UINT64_C(0xed246723, 473e3813), -323, -78},
+  {GRISU_UINT64_C(0x9436c076, 0c86e30c), -319, -77},
+  {GRISU_UINT64_C(0xb9447093, 8fa89bcf), -316, -76},
+  {GRISU_UINT64_C(0xe7958cb8, 7392c2c3), -313, -75},
+  {GRISU_UINT64_C(0x90bd77f3, 483bb9ba), -309, -74},
+  {GRISU_UINT64_C(0xb4ecd5f0, 1a4aa828), -306, -73},
+  {GRISU_UINT64_C(0xe2280b6c, 20dd5232), -303, -72},
+  {GRISU_UINT64_C(0x8d590723, 948a535f), -299, -71},
+  {GRISU_UINT64_C(0xb0af48ec, 79ace837), -296, -70},
+  {GRISU_UINT64_C(0xdcdb1b27, 98182245), -293, -69},
+  {GRISU_UINT64_C(0x8a08f0f8, bf0f156b), -289, -68},
+  {GRISU_UINT64_C(0xac8b2d36, eed2dac6), -286, -67},
+  {GRISU_UINT64_C(0xd7adf884, aa879177), -283, -66},
+  {GRISU_UINT64_C(0x86ccbb52, ea94baeb), -279, -65},
+  {GRISU_UINT64_C(0xa87fea27, a539e9a5), -276, -64},
+  {GRISU_UINT64_C(0xd29fe4b1, 8e88640f), -273, -63},
+  {GRISU_UINT64_C(0x83a3eeee, f9153e89), -269, -62},
+  {GRISU_UINT64_C(0xa48ceaaa, b75a8e2b), -266, -61},
+  {GRISU_UINT64_C(0xcdb02555, 653131b6), -263, -60},
+  {GRISU_UINT64_C(0x808e1755, 5f3ebf12), -259, -59},
+  {GRISU_UINT64_C(0xa0b19d2a, b70e6ed6), -256, -58},
+  {GRISU_UINT64_C(0xc8de0475, 64d20a8c), -253, -57},
+  {GRISU_UINT64_C(0xfb158592, be068d2f), -250, -56},
+  {GRISU_UINT64_C(0x9ced737b, b6c4183d), -246, -55},
+  {GRISU_UINT64_C(0xc428d05a, a4751e4d), -243, -54},
+  {GRISU_UINT64_C(0xf5330471, 4d9265e0), -240, -53},
+  {GRISU_UINT64_C(0x993fe2c6, d07b7fac), -236, -52},
+  {GRISU_UINT64_C(0xbf8fdb78, 849a5f97), -233, -51},
+  {GRISU_UINT64_C(0xef73d256, a5c0f77d), -230, -50},
+  {GRISU_UINT64_C(0x95a86376, 27989aae), -226, -49},
+  {GRISU_UINT64_C(0xbb127c53, b17ec159), -223, -48},
+  {GRISU_UINT64_C(0xe9d71b68, 9dde71b0), -220, -47},
+  {GRISU_UINT64_C(0x92267121, 62ab070e), -216, -46},
+  {GRISU_UINT64_C(0xb6b00d69, bb55c8d1), -213, -45},
+  {GRISU_UINT64_C(0xe45c10c4, 2a2b3b06), -210, -44},
+  {GRISU_UINT64_C(0x8eb98a7a, 9a5b04e3), -206, -43},
+  {GRISU_UINT64_C(0xb267ed19, 40f1c61c), -203, -42},
+  {GRISU_UINT64_C(0xdf01e85f, 912e37a3), -200, -41},
+  {GRISU_UINT64_C(0x8b61313b, babce2c6), -196, -40},
+  {GRISU_UINT64_C(0xae397d8a, a96c1b78), -193, -39},
+  {GRISU_UINT64_C(0xd9c7dced, 53c72256), -190, -38},
+  {GRISU_UINT64_C(0x881cea14, 545c7575), -186, -37},
+  {GRISU_UINT64_C(0xaa242499, 697392d3), -183, -36},
+  {GRISU_UINT64_C(0xd4ad2dbf, c3d07788), -180, -35},
+  {GRISU_UINT64_C(0x84ec3c97, da624ab5), -176, -34},
+  {GRISU_UINT64_C(0xa6274bbd, d0fadd62), -173, -33},
+  {GRISU_UINT64_C(0xcfb11ead, 453994ba), -170, -32},
+  {GRISU_UINT64_C(0x81ceb32c, 4b43fcf5), -166, -31},
+  {GRISU_UINT64_C(0xa2425ff7, 5e14fc32), -163, -30},
+  {GRISU_UINT64_C(0xcad2f7f5, 359a3b3e), -160, -29},
+  {GRISU_UINT64_C(0xfd87b5f2, 8300ca0e), -157, -28},
+  {GRISU_UINT64_C(0x9e74d1b7, 91e07e48), -153, -27},
+  {GRISU_UINT64_C(0xc6120625, 76589ddb), -150, -26},
+  {GRISU_UINT64_C(0xf79687ae, d3eec551), -147, -25},
+  {GRISU_UINT64_C(0x9abe14cd, 44753b53), -143, -24},
+  {GRISU_UINT64_C(0xc16d9a00, 95928a27), -140, -23},
+  {GRISU_UINT64_C(0xf1c90080, baf72cb1), -137, -22},
+  {GRISU_UINT64_C(0x971da050, 74da7bef), -133, -21},
+  {GRISU_UINT64_C(0xbce50864, 92111aeb), -130, -20},
+  {GRISU_UINT64_C(0xec1e4a7d, b69561a5), -127, -19},
+  {GRISU_UINT64_C(0x9392ee8e, 921d5d07), -123, -18},
+  {GRISU_UINT64_C(0xb877aa32, 36a4b449), -120, -17},
+  {GRISU_UINT64_C(0xe69594be, c44de15b), -117, -16},
+  {GRISU_UINT64_C(0x901d7cf7, 3ab0acd9), -113, -15},
+  {GRISU_UINT64_C(0xb424dc35, 095cd80f), -110, -14},
+  {GRISU_UINT64_C(0xe12e1342, 4bb40e13), -107, -13},
+  {GRISU_UINT64_C(0x8cbccc09, 6f5088cc), -103, -12},
+  {GRISU_UINT64_C(0xafebff0b, cb24aaff), -100, -11},
+  {GRISU_UINT64_C(0xdbe6fece, bdedd5bf), -97, -10},
+  {GRISU_UINT64_C(0x89705f41, 36b4a597), -93, -9},
+  {GRISU_UINT64_C(0xabcc7711, 8461cefd), -90, -8},
+  {GRISU_UINT64_C(0xd6bf94d5, e57a42bc), -87, -7},
+  {GRISU_UINT64_C(0x8637bd05, af6c69b6), -83, -6},
+  {GRISU_UINT64_C(0xa7c5ac47, 1b478423), -80, -5},
+  {GRISU_UINT64_C(0xd1b71758, e219652c), -77, -4},
+  {GRISU_UINT64_C(0x83126e97, 8d4fdf3b), -73, -3},
+  {GRISU_UINT64_C(0xa3d70a3d, 70a3d70a), -70, -2},
+  {GRISU_UINT64_C(0xcccccccc, cccccccd), -67, -1},
+  {GRISU_UINT64_C(0x80000000, 00000000), -63, 0},
+  {GRISU_UINT64_C(0xa0000000, 00000000), -60, 1},
+  {GRISU_UINT64_C(0xc8000000, 00000000), -57, 2},
+  {GRISU_UINT64_C(0xfa000000, 00000000), -54, 3},
+  {GRISU_UINT64_C(0x9c400000, 00000000), -50, 4},
+  {GRISU_UINT64_C(0xc3500000, 00000000), -47, 5},
+  {GRISU_UINT64_C(0xf4240000, 00000000), -44, 6},
+  {GRISU_UINT64_C(0x98968000, 00000000), -40, 7},
+  {GRISU_UINT64_C(0xbebc2000, 00000000), -37, 8},
+  {GRISU_UINT64_C(0xee6b2800, 00000000), -34, 9},
+  {GRISU_UINT64_C(0x9502f900, 00000000), -30, 10},
+  {GRISU_UINT64_C(0xba43b740, 00000000), -27, 11},
+  {GRISU_UINT64_C(0xe8d4a510, 00000000), -24, 12},
+  {GRISU_UINT64_C(0x9184e72a, 00000000), -20, 13},
+  {GRISU_UINT64_C(0xb5e620f4, 80000000), -17, 14},
+  {GRISU_UINT64_C(0xe35fa931, a0000000), -14, 15},
+  {GRISU_UINT64_C(0x8e1bc9bf, 04000000), -10, 16},
+  {GRISU_UINT64_C(0xb1a2bc2e, c5000000), -7, 17},
+  {GRISU_UINT64_C(0xde0b6b3a, 76400000), -4, 18},
+  {GRISU_UINT64_C(0x8ac72304, 89e80000), 0, 19},
+  {GRISU_UINT64_C(0xad78ebc5, ac620000), 3, 20},
+  {GRISU_UINT64_C(0xd8d726b7, 177a8000), 6, 21},
+  {GRISU_UINT64_C(0x87867832, 6eac9000), 10, 22},
+  {GRISU_UINT64_C(0xa968163f, 0a57b400), 13, 23},
+  {GRISU_UINT64_C(0xd3c21bce, cceda100), 16, 24},
+  {GRISU_UINT64_C(0x84595161, 401484a0), 20, 25},
+  {GRISU_UINT64_C(0xa56fa5b9, 9019a5c8), 23, 26},
+  {GRISU_UINT64_C(0xcecb8f27, f4200f3a), 26, 27},
+  {GRISU_UINT64_C(0x813f3978, f8940984), 30, 28},
+  {GRISU_UINT64_C(0xa18f07d7, 36b90be5), 33, 29},
+  {GRISU_UINT64_C(0xc9f2c9cd, 04674edf), 36, 30},
+  {GRISU_UINT64_C(0xfc6f7c40, 45812296), 39, 31},
+  {GRISU_UINT64_C(0x9dc5ada8, 2b70b59e), 43, 32},
+  {GRISU_UINT64_C(0xc5371912, 364ce305), 46, 33},
+  {GRISU_UINT64_C(0xf684df56, c3e01bc7), 49, 34},
+  {GRISU_UINT64_C(0x9a130b96, 3a6c115c), 53, 35},
+  {GRISU_UINT64_C(0xc097ce7b, c90715b3), 56, 36},
+  {GRISU_UINT64_C(0xf0bdc21a, bb48db20), 59, 37},
+  {GRISU_UINT64_C(0x96769950, b50d88f4), 63, 38},
+  {GRISU_UINT64_C(0xbc143fa4, e250eb31), 66, 39},
+  {GRISU_UINT64_C(0xeb194f8e, 1ae525fd), 69, 40},
+  {GRISU_UINT64_C(0x92efd1b8, d0cf37be), 73, 41},
+  {GRISU_UINT64_C(0xb7abc627, 050305ae), 76, 42},
+  {GRISU_UINT64_C(0xe596b7b0, c643c719), 79, 43},
+  {GRISU_UINT64_C(0x8f7e32ce, 7bea5c70), 83, 44},
+  {GRISU_UINT64_C(0xb35dbf82, 1ae4f38c), 86, 45},
+  {GRISU_UINT64_C(0xe0352f62, a19e306f), 89, 46},
+  {GRISU_UINT64_C(0x8c213d9d, a502de45), 93, 47},
+  {GRISU_UINT64_C(0xaf298d05, 0e4395d7), 96, 48},
+  {GRISU_UINT64_C(0xdaf3f046, 51d47b4c), 99, 49},
+  {GRISU_UINT64_C(0x88d8762b, f324cd10), 103, 50},
+  {GRISU_UINT64_C(0xab0e93b6, efee0054), 106, 51},
+  {GRISU_UINT64_C(0xd5d238a4, abe98068), 109, 52},
+  {GRISU_UINT64_C(0x85a36366, eb71f041), 113, 53},
+  {GRISU_UINT64_C(0xa70c3c40, a64e6c52), 116, 54},
+  {GRISU_UINT64_C(0xd0cf4b50, cfe20766), 119, 55},
+  {GRISU_UINT64_C(0x82818f12, 81ed44a0), 123, 56},
+  {GRISU_UINT64_C(0xa321f2d7, 226895c8), 126, 57},
+  {GRISU_UINT64_C(0xcbea6f8c, eb02bb3a), 129, 58},
+  {GRISU_UINT64_C(0xfee50b70, 25c36a08), 132, 59},
+  {GRISU_UINT64_C(0x9f4f2726, 179a2245), 136, 60},
+  {GRISU_UINT64_C(0xc722f0ef, 9d80aad6), 139, 61},
+  {GRISU_UINT64_C(0xf8ebad2b, 84e0d58c), 142, 62},
+  {GRISU_UINT64_C(0x9b934c3b, 330c8577), 146, 63},
+  {GRISU_UINT64_C(0xc2781f49, ffcfa6d5), 149, 64},
+  {GRISU_UINT64_C(0xf316271c, 7fc3908b), 152, 65},
+  {GRISU_UINT64_C(0x97edd871, cfda3a57), 156, 66},
+  {GRISU_UINT64_C(0xbde94e8e, 43d0c8ec), 159, 67},
+  {GRISU_UINT64_C(0xed63a231, d4c4fb27), 162, 68},
+  {GRISU_UINT64_C(0x945e455f, 24fb1cf9), 166, 69},
+  {GRISU_UINT64_C(0xb975d6b6, ee39e437), 169, 70},
+  {GRISU_UINT64_C(0xe7d34c64, a9c85d44), 172, 71},
+  {GRISU_UINT64_C(0x90e40fbe, ea1d3a4b), 176, 72},
+  {GRISU_UINT64_C(0xb51d13ae, a4a488dd), 179, 73},
+  {GRISU_UINT64_C(0xe264589a, 4dcdab15), 182, 74},
+  {GRISU_UINT64_C(0x8d7eb760, 70a08aed), 186, 75},
+  {GRISU_UINT64_C(0xb0de6538, 8cc8ada8), 189, 76},
+  {GRISU_UINT64_C(0xdd15fe86, affad912), 192, 77},
+  {GRISU_UINT64_C(0x8a2dbf14, 2dfcc7ab), 196, 78},
+  {GRISU_UINT64_C(0xacb92ed9, 397bf996), 199, 79},
+  {GRISU_UINT64_C(0xd7e77a8f, 87daf7fc), 202, 80},
+  {GRISU_UINT64_C(0x86f0ac99, b4e8dafd), 206, 81},
+  {GRISU_UINT64_C(0xa8acd7c0, 222311bd), 209, 82},
+  {GRISU_UINT64_C(0xd2d80db0, 2aabd62c), 212, 83},
+  {GRISU_UINT64_C(0x83c7088e, 1aab65db), 216, 84},
+  {GRISU_UINT64_C(0xa4b8cab1, a1563f52), 219, 85},
+  {GRISU_UINT64_C(0xcde6fd5e, 09abcf27), 222, 86},
+  {GRISU_UINT64_C(0x80b05e5a, c60b6178), 226, 87},
+  {GRISU_UINT64_C(0xa0dc75f1, 778e39d6), 229, 88},
+  {GRISU_UINT64_C(0xc913936d, d571c84c), 232, 89},
+  {GRISU_UINT64_C(0xfb587849, 4ace3a5f), 235, 90},
+  {GRISU_UINT64_C(0x9d174b2d, cec0e47b), 239, 91},
+  {GRISU_UINT64_C(0xc45d1df9, 42711d9a), 242, 92},
+  {GRISU_UINT64_C(0xf5746577, 930d6501), 245, 93},
+  {GRISU_UINT64_C(0x9968bf6a, bbe85f20), 249, 94},
+  {GRISU_UINT64_C(0xbfc2ef45, 6ae276e9), 252, 95},
+  {GRISU_UINT64_C(0xefb3ab16, c59b14a3), 255, 96},
+  {GRISU_UINT64_C(0x95d04aee, 3b80ece6), 259, 97},
+  {GRISU_UINT64_C(0xbb445da9, ca61281f), 262, 98},
+  {GRISU_UINT64_C(0xea157514, 3cf97227), 265, 99},
+  {GRISU_UINT64_C(0x924d692c, a61be758), 269, 100},
+  {GRISU_UINT64_C(0xb6e0c377, cfa2e12e), 272, 101},
+  {GRISU_UINT64_C(0xe498f455, c38b997a), 275, 102},
+  {GRISU_UINT64_C(0x8edf98b5, 9a373fec), 279, 103},
+  {GRISU_UINT64_C(0xb2977ee3, 00c50fe7), 282, 104},
+  {GRISU_UINT64_C(0xdf3d5e9b, c0f653e1), 285, 105},
+  {GRISU_UINT64_C(0x8b865b21, 5899f46d), 289, 106},
+  {GRISU_UINT64_C(0xae67f1e9, aec07188), 292, 107},
+  {GRISU_UINT64_C(0xda01ee64, 1a708dea), 295, 108},
+  {GRISU_UINT64_C(0x884134fe, 908658b2), 299, 109},
+  {GRISU_UINT64_C(0xaa51823e, 34a7eedf), 302, 110},
+  {GRISU_UINT64_C(0xd4e5e2cd, c1d1ea96), 305, 111},
+  {GRISU_UINT64_C(0x850fadc0, 9923329e), 309, 112},
+  {GRISU_UINT64_C(0xa6539930, bf6bff46), 312, 113},
+  {GRISU_UINT64_C(0xcfe87f7c, ef46ff17), 315, 114},
+  {GRISU_UINT64_C(0x81f14fae, 158c5f6e), 319, 115},
+  {GRISU_UINT64_C(0xa26da399, 9aef774a), 322, 116},
+  {GRISU_UINT64_C(0xcb090c80, 01ab551c), 325, 117},
+  {GRISU_UINT64_C(0xfdcb4fa0, 02162a63), 328, 118},
+  {GRISU_UINT64_C(0x9e9f11c4, 014dda7e), 332, 119},
+  {GRISU_UINT64_C(0xc646d635, 01a1511e), 335, 120},
+  {GRISU_UINT64_C(0xf7d88bc2, 4209a565), 338, 121},
+  {GRISU_UINT64_C(0x9ae75759, 6946075f), 342, 122},
+  {GRISU_UINT64_C(0xc1a12d2f, c3978937), 345, 123},
+  {GRISU_UINT64_C(0xf209787b, b47d6b85), 348, 124},
+  {GRISU_UINT64_C(0x9745eb4d, 50ce6333), 352, 125},
+  {GRISU_UINT64_C(0xbd176620, a501fc00), 355, 126},
+  {GRISU_UINT64_C(0xec5d3fa8, ce427b00), 358, 127},
+  {GRISU_UINT64_C(0x93ba47c9, 80e98ce0), 362, 128},
+  {GRISU_UINT64_C(0xb8a8d9bb, e123f018), 365, 129},
+  {GRISU_UINT64_C(0xe6d3102a, d96cec1e), 368, 130},
+  {GRISU_UINT64_C(0x9043ea1a, c7e41393), 372, 131},
+  {GRISU_UINT64_C(0xb454e4a1, 79dd1877), 375, 132},
+  {GRISU_UINT64_C(0xe16a1dc9, d8545e95), 378, 133},
+  {GRISU_UINT64_C(0x8ce2529e, 2734bb1d), 382, 134},
+  {GRISU_UINT64_C(0xb01ae745, b101e9e4), 385, 135},
+  {GRISU_UINT64_C(0xdc21a117, 1d42645d), 388, 136},
+  {GRISU_UINT64_C(0x899504ae, 72497eba), 392, 137},
+  {GRISU_UINT64_C(0xabfa45da, 0edbde69), 395, 138},
+  {GRISU_UINT64_C(0xd6f8d750, 9292d603), 398, 139},
+  {GRISU_UINT64_C(0x865b8692, 5b9bc5c2), 402, 140},
+  {GRISU_UINT64_C(0xa7f26836, f282b733), 405, 141},
+  {GRISU_UINT64_C(0xd1ef0244, af2364ff), 408, 142},
+  {GRISU_UINT64_C(0x8335616a, ed761f1f), 412, 143},
+  {GRISU_UINT64_C(0xa402b9c5, a8d3a6e7), 415, 144},
+  {GRISU_UINT64_C(0xcd036837, 130890a1), 418, 145},
+  {GRISU_UINT64_C(0x80222122, 6be55a65), 422, 146},
+  {GRISU_UINT64_C(0xa02aa96b, 06deb0fe), 425, 147},
+  {GRISU_UINT64_C(0xc83553c5, c8965d3d), 428, 148},
+  {GRISU_UINT64_C(0xfa42a8b7, 3abbf48d), 431, 149},
+  {GRISU_UINT64_C(0x9c69a972, 84b578d8), 435, 150},
+  {GRISU_UINT64_C(0xc38413cf, 25e2d70e), 438, 151},
+  {GRISU_UINT64_C(0xf46518c2, ef5b8cd1), 441, 152},
+  {GRISU_UINT64_C(0x98bf2f79, d5993803), 445, 153},
+  {GRISU_UINT64_C(0xbeeefb58, 4aff8604), 448, 154},
+  {GRISU_UINT64_C(0xeeaaba2e, 5dbf6785), 451, 155},
+  {GRISU_UINT64_C(0x952ab45c, fa97a0b3), 455, 156},
+  {GRISU_UINT64_C(0xba756174, 393d88e0), 458, 157},
+  {GRISU_UINT64_C(0xe912b9d1, 478ceb17), 461, 158},
+  {GRISU_UINT64_C(0x91abb422, ccb812ef), 465, 159},
+  {GRISU_UINT64_C(0xb616a12b, 7fe617aa), 468, 160},
+  {GRISU_UINT64_C(0xe39c4976, 5fdf9d95), 471, 161},
+  {GRISU_UINT64_C(0x8e41ade9, fbebc27d), 475, 162},
+  {GRISU_UINT64_C(0xb1d21964, 7ae6b31c), 478, 163},
+  {GRISU_UINT64_C(0xde469fbd, 99a05fe3), 481, 164},
+  {GRISU_UINT64_C(0x8aec23d6, 80043bee), 485, 165},
+  {GRISU_UINT64_C(0xada72ccc, 20054aea), 488, 166},
+  {GRISU_UINT64_C(0xd910f7ff, 28069da4), 491, 167},
+  {GRISU_UINT64_C(0x87aa9aff, 79042287), 495, 168},
+  {GRISU_UINT64_C(0xa99541bf, 57452b28), 498, 169},
+  {GRISU_UINT64_C(0xd3fa922f, 2d1675f2), 501, 170},
+  {GRISU_UINT64_C(0x847c9b5d, 7c2e09b7), 505, 171},
+  {GRISU_UINT64_C(0xa59bc234, db398c25), 508, 172},
+  {GRISU_UINT64_C(0xcf02b2c2, 1207ef2f), 511, 173},
+  {GRISU_UINT64_C(0x8161afb9, 4b44f57d), 515, 174},
+  {GRISU_UINT64_C(0xa1ba1ba7, 9e1632dc), 518, 175},
+  {GRISU_UINT64_C(0xca28a291, 859bbf93), 521, 176},
+  {GRISU_UINT64_C(0xfcb2cb35, e702af78), 524, 177},
+  {GRISU_UINT64_C(0x9defbf01, b061adab), 528, 178},
+  {GRISU_UINT64_C(0xc56baec2, 1c7a1916), 531, 179},
+  {GRISU_UINT64_C(0xf6c69a72, a3989f5c), 534, 180},
+  {GRISU_UINT64_C(0x9a3c2087, a63f6399), 538, 181},
+  {GRISU_UINT64_C(0xc0cb28a9, 8fcf3c80), 541, 182},
+  {GRISU_UINT64_C(0xf0fdf2d3, f3c30b9f), 544, 183},
+  {GRISU_UINT64_C(0x969eb7c4, 7859e744), 548, 184},
+  {GRISU_UINT64_C(0xbc4665b5, 96706115), 551, 185},
+  {GRISU_UINT64_C(0xeb57ff22, fc0c795a), 554, 186},
+  {GRISU_UINT64_C(0x9316ff75, dd87cbd8), 558, 187},
+  {GRISU_UINT64_C(0xb7dcbf53, 54e9bece), 561, 188},
+  {GRISU_UINT64_C(0xe5d3ef28, 2a242e82), 564, 189},
+  {GRISU_UINT64_C(0x8fa47579, 1a569d11), 568, 190},
+  {GRISU_UINT64_C(0xb38d92d7, 60ec4455), 571, 191},
+  {GRISU_UINT64_C(0xe070f78d, 3927556b), 574, 192},
+  {GRISU_UINT64_C(0x8c469ab8, 43b89563), 578, 193},
+  {GRISU_UINT64_C(0xaf584166, 54a6babb), 581, 194},
+  {GRISU_UINT64_C(0xdb2e51bf, e9d0696a), 584, 195},
+  {GRISU_UINT64_C(0x88fcf317, f22241e2), 588, 196},
+  {GRISU_UINT64_C(0xab3c2fdd, eeaad25b), 591, 197},
+  {GRISU_UINT64_C(0xd60b3bd5, 6a5586f2), 594, 198},
+  {GRISU_UINT64_C(0x85c70565, 62757457), 598, 199},
+  {GRISU_UINT64_C(0xa738c6be, bb12d16d), 601, 200},
+  {GRISU_UINT64_C(0xd106f86e, 69d785c8), 604, 201},
+  {GRISU_UINT64_C(0x82a45b45, 0226b39d), 608, 202},
+  {GRISU_UINT64_C(0xa34d7216, 42b06084), 611, 203},
+  {GRISU_UINT64_C(0xcc20ce9b, d35c78a5), 614, 204},
+  {GRISU_UINT64_C(0xff290242, c83396ce), 617, 205},
+  {GRISU_UINT64_C(0x9f79a169, bd203e41), 621, 206},
+  {GRISU_UINT64_C(0xc75809c4, 2c684dd1), 624, 207},
+  {GRISU_UINT64_C(0xf92e0c35, 37826146), 627, 208},
+  {GRISU_UINT64_C(0x9bbcc7a1, 42b17ccc), 631, 209},
+  {GRISU_UINT64_C(0xc2abf989, 935ddbfe), 634, 210},
+  {GRISU_UINT64_C(0xf356f7eb, f83552fe), 637, 211},
+  {GRISU_UINT64_C(0x98165af3, 7b2153df), 641, 212},
+  {GRISU_UINT64_C(0xbe1bf1b0, 59e9a8d6), 644, 213},
+  {GRISU_UINT64_C(0xeda2ee1c, 7064130c), 647, 214},
+  {GRISU_UINT64_C(0x9485d4d1, c63e8be8), 651, 215},
+  {GRISU_UINT64_C(0xb9a74a06, 37ce2ee1), 654, 216},
+  {GRISU_UINT64_C(0xe8111c87, c5c1ba9a), 657, 217},
+  {GRISU_UINT64_C(0x910ab1d4, db9914a0), 661, 218},
+  {GRISU_UINT64_C(0xb54d5e4a, 127f59c8), 664, 219},
+  {GRISU_UINT64_C(0xe2a0b5dc, 971f303a), 667, 220},
+  {GRISU_UINT64_C(0x8da471a9, de737e24), 671, 221},
+  {GRISU_UINT64_C(0xb10d8e14, 56105dad), 674, 222},
+  {GRISU_UINT64_C(0xdd50f199, 6b947519), 677, 223},
+  {GRISU_UINT64_C(0x8a5296ff, e33cc930), 681, 224},
+  {GRISU_UINT64_C(0xace73cbf, dc0bfb7b), 684, 225},
+  {GRISU_UINT64_C(0xd8210bef, d30efa5a), 687, 226},
+  {GRISU_UINT64_C(0x8714a775, e3e95c78), 691, 227},
+  {GRISU_UINT64_C(0xa8d9d153, 5ce3b396), 694, 228},
+  {GRISU_UINT64_C(0xd31045a8, 341ca07c), 697, 229},
+  {GRISU_UINT64_C(0x83ea2b89, 2091e44e), 701, 230},
+  {GRISU_UINT64_C(0xa4e4b66b, 68b65d61), 704, 231},
+  {GRISU_UINT64_C(0xce1de406, 42e3f4b9), 707, 232},
+  {GRISU_UINT64_C(0x80d2ae83, e9ce78f4), 711, 233},
+  {GRISU_UINT64_C(0xa1075a24, e4421731), 714, 234},
+  {GRISU_UINT64_C(0xc94930ae, 1d529cfd), 717, 235},
+  {GRISU_UINT64_C(0xfb9b7cd9, a4a7443c), 720, 236},
+  {GRISU_UINT64_C(0x9d412e08, 06e88aa6), 724, 237},
+  {GRISU_UINT64_C(0xc491798a, 08a2ad4f), 727, 238},
+  {GRISU_UINT64_C(0xf5b5d7ec, 8acb58a3), 730, 239},
+  {GRISU_UINT64_C(0x9991a6f3, d6bf1766), 734, 240},
+  {GRISU_UINT64_C(0xbff610b0, cc6edd3f), 737, 241},
+  {GRISU_UINT64_C(0xeff394dc, ff8a948f), 740, 242},
+  {GRISU_UINT64_C(0x95f83d0a, 1fb69cd9), 744, 243},
+  {GRISU_UINT64_C(0xbb764c4c, a7a44410), 747, 244},
+  {GRISU_UINT64_C(0xea53df5f, d18d5514), 750, 245},
+  {GRISU_UINT64_C(0x92746b9b, e2f8552c), 754, 246},
+  {GRISU_UINT64_C(0xb7118682, dbb66a77), 757, 247},
+  {GRISU_UINT64_C(0xe4d5e823, 92a40515), 760, 248},
+  {GRISU_UINT64_C(0x8f05b116, 3ba6832d), 764, 249},
+  {GRISU_UINT64_C(0xb2c71d5b, ca9023f8), 767, 250},
+  {GRISU_UINT64_C(0xdf78e4b2, bd342cf7), 770, 251},
+  {GRISU_UINT64_C(0x8bab8eef, b6409c1a), 774, 252},
+  {GRISU_UINT64_C(0xae9672ab, a3d0c321), 777, 253},
+  {GRISU_UINT64_C(0xda3c0f56, 8cc4f3e9), 780, 254},
+  {GRISU_UINT64_C(0x88658996, 17fb1871), 784, 255},
+  {GRISU_UINT64_C(0xaa7eebfb, 9df9de8e), 787, 256},
+  {GRISU_UINT64_C(0xd51ea6fa, 85785631), 790, 257},
+  {GRISU_UINT64_C(0x8533285c, 936b35df), 794, 258},
+  {GRISU_UINT64_C(0xa67ff273, b8460357), 797, 259},
+  {GRISU_UINT64_C(0xd01fef10, a657842c), 800, 260},
+  {GRISU_UINT64_C(0x8213f56a, 67f6b29c), 804, 261},
+  {GRISU_UINT64_C(0xa298f2c5, 01f45f43), 807, 262},
+  {GRISU_UINT64_C(0xcb3f2f76, 42717713), 810, 263},
+  {GRISU_UINT64_C(0xfe0efb53, d30dd4d8), 813, 264},
+  {GRISU_UINT64_C(0x9ec95d14, 63e8a507), 817, 265},
+  {GRISU_UINT64_C(0xc67bb459, 7ce2ce49), 820, 266},
+  {GRISU_UINT64_C(0xf81aa16f, dc1b81db), 823, 267},
+  {GRISU_UINT64_C(0x9b10a4e5, e9913129), 827, 268},
+  {GRISU_UINT64_C(0xc1d4ce1f, 63f57d73), 830, 269},
+  {GRISU_UINT64_C(0xf24a01a7, 3cf2dcd0), 833, 270},
+  {GRISU_UINT64_C(0x976e4108, 8617ca02), 837, 271},
+  {GRISU_UINT64_C(0xbd49d14a, a79dbc82), 840, 272},
+  {GRISU_UINT64_C(0xec9c459d, 51852ba3), 843, 273},
+  {GRISU_UINT64_C(0x93e1ab82, 52f33b46), 847, 274},
+  {GRISU_UINT64_C(0xb8da1662, e7b00a17), 850, 275},
+  {GRISU_UINT64_C(0xe7109bfb, a19c0c9d), 853, 276},
+  {GRISU_UINT64_C(0x906a617d, 450187e2), 857, 277},
+  {GRISU_UINT64_C(0xb484f9dc, 9641e9db), 860, 278},
+  {GRISU_UINT64_C(0xe1a63853, bbd26451), 863, 279},
+  {GRISU_UINT64_C(0x8d07e334, 55637eb3), 867, 280},
+  {GRISU_UINT64_C(0xb049dc01, 6abc5e60), 870, 281},
+  {GRISU_UINT64_C(0xdc5c5301, c56b75f7), 873, 282},
+  {GRISU_UINT64_C(0x89b9b3e1, 1b6329bb), 877, 283},
+  {GRISU_UINT64_C(0xac2820d9, 623bf429), 880, 284},
+  {GRISU_UINT64_C(0xd732290f, bacaf134), 883, 285},
+  {GRISU_UINT64_C(0x867f59a9, d4bed6c0), 887, 286},
+  {GRISU_UINT64_C(0xa81f3014, 49ee8c70), 890, 287},
+  {GRISU_UINT64_C(0xd226fc19, 5c6a2f8c), 893, 288},
+  {GRISU_UINT64_C(0x83585d8f, d9c25db8), 897, 289},
+  {GRISU_UINT64_C(0xa42e74f3, d032f526), 900, 290},
+  {GRISU_UINT64_C(0xcd3a1230, c43fb26f), 903, 291},
+  {GRISU_UINT64_C(0x80444b5e, 7aa7cf85), 907, 292},
+  {GRISU_UINT64_C(0xa0555e36, 1951c367), 910, 293},
+  {GRISU_UINT64_C(0xc86ab5c3, 9fa63441), 913, 294},
+  {GRISU_UINT64_C(0xfa856334, 878fc151), 916, 295},
+  {GRISU_UINT64_C(0x9c935e00, d4b9d8d2), 920, 296},
+  {GRISU_UINT64_C(0xc3b83581, 09e84f07), 923, 297},
+  {GRISU_UINT64_C(0xf4a642e1, 4c6262c9), 926, 298},
+  {GRISU_UINT64_C(0x98e7e9cc, cfbd7dbe), 930, 299},
+  {GRISU_UINT64_C(0xbf21e440, 03acdd2d), 933, 300},
+  {GRISU_UINT64_C(0xeeea5d50, 04981478), 936, 301},
+  {GRISU_UINT64_C(0x95527a52, 02df0ccb), 940, 302},
+  {GRISU_UINT64_C(0xbaa718e6, 8396cffe), 943, 303},
+  {GRISU_UINT64_C(0xe950df20, 247c83fd), 946, 304},
+  {GRISU_UINT64_C(0x91d28b74, 16cdd27e), 950, 305},
+  {GRISU_UINT64_C(0xb6472e51, 1c81471e), 953, 306},
+  {GRISU_UINT64_C(0xe3d8f9e5, 63a198e5), 956, 307},
+  {GRISU_UINT64_C(0x8e679c2f, 5e44ff8f), 960, 308},
+  {GRISU_UINT64_C(0xb201833b, 35d63f73), 963, 309},
+  {GRISU_UINT64_C(0xde81e40a, 034bcf50), 966, 310},
+  {GRISU_UINT64_C(0x8b112e86, 420f6192), 970, 311},
+  {GRISU_UINT64_C(0xadd57a27, d29339f6), 973, 312},
+  {GRISU_UINT64_C(0xd94ad8b1, c7380874), 976, 313},
+  {GRISU_UINT64_C(0x87cec76f, 1c830549), 980, 314},
+  {GRISU_UINT64_C(0xa9c2794a, e3a3c69b), 983, 315},
+  {GRISU_UINT64_C(0xd433179d, 9c8cb841), 986, 316},
+  {GRISU_UINT64_C(0x849feec2, 81d7f329), 990, 317},
+  {GRISU_UINT64_C(0xa5c7ea73, 224deff3), 993, 318},
+  {GRISU_UINT64_C(0xcf39e50f, eae16bf0), 996, 319},
+  {GRISU_UINT64_C(0x81842f29, f2cce376), 1000, 320},
+  {GRISU_UINT64_C(0xa1e53af4, 6f801c53), 1003, 321},
+  {GRISU_UINT64_C(0xca5e89b1, 8b602368), 1006, 322},
+  {GRISU_UINT64_C(0xfcf62c1d, ee382c42), 1009, 323},
+  {GRISU_UINT64_C(0x9e19db92, b4e31ba9), 1013, 324},
+  {GRISU_UINT64_C(0xc5a05277, 621be294), 1016, 325},
+  {GRISU_UINT64_C(0xf7086715, 3aa2db39), 1019, 326},
+  {GRISU_UINT64_C(0x9a65406d, 44a5c903), 1023, 327},
+  {GRISU_UINT64_C(0xc0fe9088, 95cf3b44), 1026, 328},
+  {GRISU_UINT64_C(0xf13e34aa, bb430a15), 1029, 329},
+  {GRISU_UINT64_C(0x96c6e0ea, b509e64d), 1033, 330},
+  {GRISU_UINT64_C(0xbc789925, 624c5fe1), 1036, 331},
+  {GRISU_UINT64_C(0xeb96bf6e, badf77d9), 1039, 332},
+  {GRISU_UINT64_C(0x933e37a5, 34cbaae8), 1043, 333},
+  {GRISU_UINT64_C(0xb80dc58e, 81fe95a1), 1046, 334},
+  {GRISU_UINT64_C(0xe61136f2, 227e3b0a), 1049, 335},
+  {GRISU_UINT64_C(0x8fcac257, 558ee4e6), 1053, 336},
+  {GRISU_UINT64_C(0xb3bd72ed, 2af29e20), 1056, 337},
+  {GRISU_UINT64_C(0xe0accfa8, 75af45a8), 1059, 338},
+  {GRISU_UINT64_C(0x8c6c01c9, 498d8b89), 1063, 339},
+  {GRISU_UINT64_C(0xaf87023b, 9bf0ee6b), 1066, 340},
+  {GRISU_UINT64_C(0xdb68c2ca, 82ed2a06), 1069, 341},
+  {GRISU_UINT64_C(0x892179be, 91d43a44), 1073, 342},
+  };
+static const int GRISU_CACHE_MAX_DISTANCE(1) = 4;
+// nb elements (1): 651
+static const GRISU_CACHE_STRUCT GRISU_CACHE_NAME(2)[] = {
+  {GRISU_UINT64_C(0xe61acf03, 3d1a45df), -1087, -308},
+  {GRISU_UINT64_C(0xb3c4f1ba, 87bc8697), -1080, -306},
+  {GRISU_UINT64_C(0x8c71dcd9, ba0b4926), -1073, -304},
+  {GRISU_UINT64_C(0xdb71e914, 32b1a24b), -1067, -302},
+  {GRISU_UINT64_C(0xab70fe17, c79ac6ca), -1060, -300},
+  {GRISU_UINT64_C(0x85f04682, 93f0eb4e), -1053, -298},
+  {GRISU_UINT64_C(0xd1476e2c, 07286faa), -1047, -296},
+  {GRISU_UINT64_C(0xa37fce12, 6597973d), -1040, -294},
+  {GRISU_UINT64_C(0xff77b1fc, bebcdc4f), -1034, -292},
+  {GRISU_UINT64_C(0xc795830d, 75038c1e), -1027, -290},
+  {GRISU_UINT64_C(0x9becce62, 836ac577), -1020, -288},
+  {GRISU_UINT64_C(0xf3a20279, ed56d48a), -1014, -286},
+  {GRISU_UINT64_C(0xbe5691ef, 416bd60c), -1007, -284},
+  {GRISU_UINT64_C(0x94b3a202, eb1c3f39), -1000, -282},
+  {GRISU_UINT64_C(0xe858ad24, 8f5c22ca), -994, -280},
+  {GRISU_UINT64_C(0xb5854744, 8ffffb2e), -987, -278},
+  {GRISU_UINT64_C(0x8dd01fad, 907ffc3c), -980, -276},
+  {GRISU_UINT64_C(0xdd95317f, 31c7fa1d), -974, -274},
+  {GRISU_UINT64_C(0xad1c8eab, 5ee43b67), -967, -272},
+  {GRISU_UINT64_C(0x873e4f75, e2224e68), -960, -270},
+  {GRISU_UINT64_C(0xd3515c28, 31559a83), -954, -268},
+  {GRISU_UINT64_C(0xa5178fff, 668ae0b6), -947, -266},
+  {GRISU_UINT64_C(0x80fa687f, 881c7f8e), -940, -264},
+  {GRISU_UINT64_C(0xc9874347, 44ac874f), -934, -262},
+  {GRISU_UINT64_C(0x9d71ac8f, ada6c9b5), -927, -260},
+  {GRISU_UINT64_C(0xf6019da0, 7f549b2b), -921, -258},
+  {GRISU_UINT64_C(0xc0314325, 637a193a), -914, -256},
+  {GRISU_UINT64_C(0x96267c75, 35b763b5), -907, -254},
+  {GRISU_UINT64_C(0xea9c2277, 23ee8bcb), -901, -252},
+  {GRISU_UINT64_C(0xb749faed, 14125d37), -894, -250},
+  {GRISU_UINT64_C(0x8f31cc09, 37ae58d3), -887, -248},
+  {GRISU_UINT64_C(0xdfbdcece, 67006ac9), -881, -246},
+  {GRISU_UINT64_C(0xaecc4991, 4078536d), -874, -244},
+  {GRISU_UINT64_C(0x888f9979, 7a5e012d), -867, -242},
+  {GRISU_UINT64_C(0xd5605fcd, cf32e1d7), -861, -240},
+  {GRISU_UINT64_C(0xa6b34ad8, c9dfc070), -854, -238},
+  {GRISU_UINT64_C(0x823c1279, 5db6ce57), -847, -236},
+  {GRISU_UINT64_C(0xcb7ddcdd, a26da269), -841, -234},
+  {GRISU_UINT64_C(0x9efa548d, 26e5a6e2), -834, -232},
+  {GRISU_UINT64_C(0xf867241c, 8cc6d4c1), -828, -230},
+  {GRISU_UINT64_C(0xc2109436, 4dfb5637), -821, -228},
+  {GRISU_UINT64_C(0x979cf3ca, 6cec5b5b), -814, -226},
+  {GRISU_UINT64_C(0xece53cec, 4a314ebe), -808, -224},
+  {GRISU_UINT64_C(0xb9131798, 99f68584), -801, -222},
+  {GRISU_UINT64_C(0x9096ea6f, 3848984f), -794, -220},
+  {GRISU_UINT64_C(0xe1ebce4d, c7f16dfc), -788, -218},
+  {GRISU_UINT64_C(0xb080392c, c4349ded), -781, -216},
+  {GRISU_UINT64_C(0x89e42caa, f9491b61), -774, -214},
+  {GRISU_UINT64_C(0xd77485cb, 25823ac7), -768, -212},
+  {GRISU_UINT64_C(0xa8530886, b54dbdec), -761, -210},
+  {GRISU_UINT64_C(0x8380dea9, 3da4bc60), -754, -208},
+  {GRISU_UINT64_C(0xcd795be8, 70516656), -748, -206},
+  {GRISU_UINT64_C(0xa086cfcd, 97bf97f4), -741, -204},
+  {GRISU_UINT64_C(0xfad2a4b1, 3d1b5d6c), -735, -202},
+  {GRISU_UINT64_C(0xc3f490aa, 77bd60fd), -728, -200},
+  {GRISU_UINT64_C(0x99171105, 2d8bf3c5), -721, -198},
+  {GRISU_UINT64_C(0xef340a98, 172aace5), -715, -196},
+  {GRISU_UINT64_C(0xbae0a846, d2195713), -708, -194},
+  {GRISU_UINT64_C(0x91ff8377, 5423cc06), -701, -192},
+  {GRISU_UINT64_C(0xe41f3d6a, 7377eeca), -695, -190},
+  {GRISU_UINT64_C(0xb23867fb, 2a35b28e), -688, -188},
+  {GRISU_UINT64_C(0x8b3c113c, 38f9f37f), -681, -186},
+  {GRISU_UINT64_C(0xd98ddaee, 19068c76), -675, -184},
+  {GRISU_UINT64_C(0xa9f6d30a, 038d1dbc), -668, -182},
+  {GRISU_UINT64_C(0x84c8d4df, d2c63f3b), -661, -180},
+  {GRISU_UINT64_C(0xcf79cc9d, b955c2cc), -655, -178},
+  {GRISU_UINT64_C(0xa21727db, 38cb0030), -648, -176},
+  {GRISU_UINT64_C(0xfd442e46, 88bd304b), -642, -174},
+  {GRISU_UINT64_C(0xc5dd4427, 1ad3cdba), -635, -172},
+  {GRISU_UINT64_C(0x9a94dd3e, 8cf578ba), -628, -170},
+  {GRISU_UINT64_C(0xf18899b1, bc3f8ca2), -622, -168},
+  {GRISU_UINT64_C(0xbcb2b812, db11a5de), -615, -166},
+  {GRISU_UINT64_C(0x936b9fce, bb25c996), -608, -164},
+  {GRISU_UINT64_C(0xe65829b3, 046b0afa), -602, -162},
+  {GRISU_UINT64_C(0xb3f4e093, db73a093), -595, -160},
+  {GRISU_UINT64_C(0x8c974f73, 83725573), -588, -158},
+  {GRISU_UINT64_C(0xdbac6c24, 7d62a584), -582, -156},
+  {GRISU_UINT64_C(0xab9eb47c, 81f5114f), -575, -154},
+  {GRISU_UINT64_C(0x8613fd01, 45877586), -568, -152},
+  {GRISU_UINT64_C(0xd17f3b51, fca3a7a1), -562, -150},
+  {GRISU_UINT64_C(0xa3ab6658, 0d5fdaf6), -555, -148},
+  {GRISU_UINT64_C(0xffbbcfe9, 94e5c620), -549, -146},
+  {GRISU_UINT64_C(0xc7caba6e, 7c5382c9), -542, -144},
+  {GRISU_UINT64_C(0x9c1661a6, 51213e2d), -535, -142},
+  {GRISU_UINT64_C(0xf3e2f893, dec3f126), -529, -140},
+  {GRISU_UINT64_C(0xbe895233, 86091466), -522, -138},
+  {GRISU_UINT64_C(0x94db4838, 40b717f0), -515, -136},
+  {GRISU_UINT64_C(0xe896a0d7, e51e1566), -509, -134},
+  {GRISU_UINT64_C(0xb5b5ada8, aaff80b8), -502, -132},
+  {GRISU_UINT64_C(0x8df5efab, c5979c90), -495, -130},
+  {GRISU_UINT64_C(0xddd0467c, 64bce4a1), -489, -128},
+  {GRISU_UINT64_C(0xad4ab711, 2eb3929e), -482, -126},
+  {GRISU_UINT64_C(0x87625f05, 6c7c4a8b), -475, -124},
+  {GRISU_UINT64_C(0xd389b478, 79823479), -469, -122},
+  {GRISU_UINT64_C(0xa54394fe, 1eedb8ff), -462, -120},
+  {GRISU_UINT64_C(0x811ccc66, 8829b887), -455, -118},
+  {GRISU_UINT64_C(0xc9bcff60, 34c13053), -449, -116},
+  {GRISU_UINT64_C(0x9d9ba783, 2936edc1), -442, -114},
+  {GRISU_UINT64_C(0xf64335bc, f065d37d), -436, -112},
+  {GRISU_UINT64_C(0xc06481fb, 9bcf8d3a), -429, -110},
+  {GRISU_UINT64_C(0x964e858c, 91ba2655), -422, -108},
+  {GRISU_UINT64_C(0xeadab0ab, a3b2dbe5), -416, -106},
+  {GRISU_UINT64_C(0xb77ada06, 17e3bbcb), -409, -104},
+  {GRISU_UINT64_C(0x8f57fa54, c2a9eab7), -402, -102},
+  {GRISU_UINT64_C(0xdff97724, 70297ebd), -396, -100},
+  {GRISU_UINT64_C(0xaefae514, 77a06b04), -389, -98},
+  {GRISU_UINT64_C(0x88b402f7, fd75539b), -382, -96},
+  {GRISU_UINT64_C(0xd59944a3, 7c0752a2), -376, -94},
+  {GRISU_UINT64_C(0xa6dfbd9f, b8e5b88f), -369, -92},
+  {GRISU_UINT64_C(0x825ecc24, c8737830), -362, -90},
+  {GRISU_UINT64_C(0xcbb41ef9, 79346bca), -356, -88},
+  {GRISU_UINT64_C(0x9f24b832, e6b0f436), -349, -86},
+  {GRISU_UINT64_C(0xf8a95fcf, 88747d94), -343, -84},
+  {GRISU_UINT64_C(0xc24452da, 229b021c), -336, -82},
+  {GRISU_UINT64_C(0x97c560ba, 6b0919a6), -329, -80},
+  {GRISU_UINT64_C(0xed246723, 473e3813), -323, -78},
+  {GRISU_UINT64_C(0xb9447093, 8fa89bcf), -316, -76},
+  {GRISU_UINT64_C(0x90bd77f3, 483bb9ba), -309, -74},
+  {GRISU_UINT64_C(0xe2280b6c, 20dd5232), -303, -72},
+  {GRISU_UINT64_C(0xb0af48ec, 79ace837), -296, -70},
+  {GRISU_UINT64_C(0x8a08f0f8, bf0f156b), -289, -68},
+  {GRISU_UINT64_C(0xd7adf884, aa879177), -283, -66},
+  {GRISU_UINT64_C(0xa87fea27, a539e9a5), -276, -64},
+  {GRISU_UINT64_C(0x83a3eeee, f9153e89), -269, -62},
+  {GRISU_UINT64_C(0xcdb02555, 653131b6), -263, -60},
+  {GRISU_UINT64_C(0xa0b19d2a, b70e6ed6), -256, -58},
+  {GRISU_UINT64_C(0xfb158592, be068d2f), -250, -56},
+  {GRISU_UINT64_C(0xc428d05a, a4751e4d), -243, -54},
+  {GRISU_UINT64_C(0x993fe2c6, d07b7fac), -236, -52},
+  {GRISU_UINT64_C(0xef73d256, a5c0f77d), -230, -50},
+  {GRISU_UINT64_C(0xbb127c53, b17ec159), -223, -48},
+  {GRISU_UINT64_C(0x92267121, 62ab070e), -216, -46},
+  {GRISU_UINT64_C(0xe45c10c4, 2a2b3b06), -210, -44},
+  {GRISU_UINT64_C(0xb267ed19, 40f1c61c), -203, -42},
+  {GRISU_UINT64_C(0x8b61313b, babce2c6), -196, -40},
+  {GRISU_UINT64_C(0xd9c7dced, 53c72256), -190, -38},
+  {GRISU_UINT64_C(0xaa242499, 697392d3), -183, -36},
+  {GRISU_UINT64_C(0x84ec3c97, da624ab5), -176, -34},
+  {GRISU_UINT64_C(0xcfb11ead, 453994ba), -170, -32},
+  {GRISU_UINT64_C(0xa2425ff7, 5e14fc32), -163, -30},
+  {GRISU_UINT64_C(0xfd87b5f2, 8300ca0e), -157, -28},
+  {GRISU_UINT64_C(0xc6120625, 76589ddb), -150, -26},
+  {GRISU_UINT64_C(0x9abe14cd, 44753b53), -143, -24},
+  {GRISU_UINT64_C(0xf1c90080, baf72cb1), -137, -22},
+  {GRISU_UINT64_C(0xbce50864, 92111aeb), -130, -20},
+  {GRISU_UINT64_C(0x9392ee8e, 921d5d07), -123, -18},
+  {GRISU_UINT64_C(0xe69594be, c44de15b), -117, -16},
+  {GRISU_UINT64_C(0xb424dc35, 095cd80f), -110, -14},
+  {GRISU_UINT64_C(0x8cbccc09, 6f5088cc), -103, -12},
+  {GRISU_UINT64_C(0xdbe6fece, bdedd5bf), -97, -10},
+  {GRISU_UINT64_C(0xabcc7711, 8461cefd), -90, -8},
+  {GRISU_UINT64_C(0x8637bd05, af6c69b6), -83, -6},
+  {GRISU_UINT64_C(0xd1b71758, e219652c), -77, -4},
+  {GRISU_UINT64_C(0xa3d70a3d, 70a3d70a), -70, -2},
+  {GRISU_UINT64_C(0x80000000, 00000000), -63, 0},
+  {GRISU_UINT64_C(0xc8000000, 00000000), -57, 2},
+  {GRISU_UINT64_C(0x9c400000, 00000000), -50, 4},
+  {GRISU_UINT64_C(0xf4240000, 00000000), -44, 6},
+  {GRISU_UINT64_C(0xbebc2000, 00000000), -37, 8},
+  {GRISU_UINT64_C(0x9502f900, 00000000), -30, 10},
+  {GRISU_UINT64_C(0xe8d4a510, 00000000), -24, 12},
+  {GRISU_UINT64_C(0xb5e620f4, 80000000), -17, 14},
+  {GRISU_UINT64_C(0x8e1bc9bf, 04000000), -10, 16},
+  {GRISU_UINT64_C(0xde0b6b3a, 76400000), -4, 18},
+  {GRISU_UINT64_C(0xad78ebc5, ac620000), 3, 20},
+  {GRISU_UINT64_C(0x87867832, 6eac9000), 10, 22},
+  {GRISU_UINT64_C(0xd3c21bce, cceda100), 16, 24},
+  {GRISU_UINT64_C(0xa56fa5b9, 9019a5c8), 23, 26},
+  {GRISU_UINT64_C(0x813f3978, f8940984), 30, 28},
+  {GRISU_UINT64_C(0xc9f2c9cd, 04674edf), 36, 30},
+  {GRISU_UINT64_C(0x9dc5ada8, 2b70b59e), 43, 32},
+  {GRISU_UINT64_C(0xf684df56, c3e01bc7), 49, 34},
+  {GRISU_UINT64_C(0xc097ce7b, c90715b3), 56, 36},
+  {GRISU_UINT64_C(0x96769950, b50d88f4), 63, 38},
+  {GRISU_UINT64_C(0xeb194f8e, 1ae525fd), 69, 40},
+  {GRISU_UINT64_C(0xb7abc627, 050305ae), 76, 42},
+  {GRISU_UINT64_C(0x8f7e32ce, 7bea5c70), 83, 44},
+  {GRISU_UINT64_C(0xe0352f62, a19e306f), 89, 46},
+  {GRISU_UINT64_C(0xaf298d05, 0e4395d7), 96, 48},
+  {GRISU_UINT64_C(0x88d8762b, f324cd10), 103, 50},
+  {GRISU_UINT64_C(0xd5d238a4, abe98068), 109, 52},
+  {GRISU_UINT64_C(0xa70c3c40, a64e6c52), 116, 54},
+  {GRISU_UINT64_C(0x82818f12, 81ed44a0), 123, 56},
+  {GRISU_UINT64_C(0xcbea6f8c, eb02bb3a), 129, 58},
+  {GRISU_UINT64_C(0x9f4f2726, 179a2245), 136, 60},
+  {GRISU_UINT64_C(0xf8ebad2b, 84e0d58c), 142, 62},
+  {GRISU_UINT64_C(0xc2781f49, ffcfa6d5), 149, 64},
+  {GRISU_UINT64_C(0x97edd871, cfda3a57), 156, 66},
+  {GRISU_UINT64_C(0xed63a231, d4c4fb27), 162, 68},
+  {GRISU_UINT64_C(0xb975d6b6, ee39e437), 169, 70},
+  {GRISU_UINT64_C(0x90e40fbe, ea1d3a4b), 176, 72},
+  {GRISU_UINT64_C(0xe264589a, 4dcdab15), 182, 74},
+  {GRISU_UINT64_C(0xb0de6538, 8cc8ada8), 189, 76},
+  {GRISU_UINT64_C(0x8a2dbf14, 2dfcc7ab), 196, 78},
+  {GRISU_UINT64_C(0xd7e77a8f, 87daf7fc), 202, 80},
+  {GRISU_UINT64_C(0xa8acd7c0, 222311bd), 209, 82},
+  {GRISU_UINT64_C(0x83c7088e, 1aab65db), 216, 84},
+  {GRISU_UINT64_C(0xcde6fd5e, 09abcf27), 222, 86},
+  {GRISU_UINT64_C(0xa0dc75f1, 778e39d6), 229, 88},
+  {GRISU_UINT64_C(0xfb587849, 4ace3a5f), 235, 90},
+  {GRISU_UINT64_C(0xc45d1df9, 42711d9a), 242, 92},
+  {GRISU_UINT64_C(0x9968bf6a, bbe85f20), 249, 94},
+  {GRISU_UINT64_C(0xefb3ab16, c59b14a3), 255, 96},
+  {GRISU_UINT64_C(0xbb445da9, ca61281f), 262, 98},
+  {GRISU_UINT64_C(0x924d692c, a61be758), 269, 100},
+  {GRISU_UINT64_C(0xe498f455, c38b997a), 275, 102},
+  {GRISU_UINT64_C(0xb2977ee3, 00c50fe7), 282, 104},
+  {GRISU_UINT64_C(0x8b865b21, 5899f46d), 289, 106},
+  {GRISU_UINT64_C(0xda01ee64, 1a708dea), 295, 108},
+  {GRISU_UINT64_C(0xaa51823e, 34a7eedf), 302, 110},
+  {GRISU_UINT64_C(0x850fadc0, 9923329e), 309, 112},
+  {GRISU_UINT64_C(0xcfe87f7c, ef46ff17), 315, 114},
+  {GRISU_UINT64_C(0xa26da399, 9aef774a), 322, 116},
+  {GRISU_UINT64_C(0xfdcb4fa0, 02162a63), 328, 118},
+  {GRISU_UINT64_C(0xc646d635, 01a1511e), 335, 120},
+  {GRISU_UINT64_C(0x9ae75759, 6946075f), 342, 122},
+  {GRISU_UINT64_C(0xf209787b, b47d6b85), 348, 124},
+  {GRISU_UINT64_C(0xbd176620, a501fc00), 355, 126},
+  {GRISU_UINT64_C(0x93ba47c9, 80e98ce0), 362, 128},
+  {GRISU_UINT64_C(0xe6d3102a, d96cec1e), 368, 130},
+  {GRISU_UINT64_C(0xb454e4a1, 79dd1877), 375, 132},
+  {GRISU_UINT64_C(0x8ce2529e, 2734bb1d), 382, 134},
+  {GRISU_UINT64_C(0xdc21a117, 1d42645d), 388, 136},
+  {GRISU_UINT64_C(0xabfa45da, 0edbde69), 395, 138},
+  {GRISU_UINT64_C(0x865b8692, 5b9bc5c2), 402, 140},
+  {GRISU_UINT64_C(0xd1ef0244, af2364ff), 408, 142},
+  {GRISU_UINT64_C(0xa402b9c5, a8d3a6e7), 415, 144},
+  {GRISU_UINT64_C(0x80222122, 6be55a65), 422, 146},
+  {GRISU_UINT64_C(0xc83553c5, c8965d3d), 428, 148},
+  {GRISU_UINT64_C(0x9c69a972, 84b578d8), 435, 150},
+  {GRISU_UINT64_C(0xf46518c2, ef5b8cd1), 441, 152},
+  {GRISU_UINT64_C(0xbeeefb58, 4aff8604), 448, 154},
+  {GRISU_UINT64_C(0x952ab45c, fa97a0b3), 455, 156},
+  {GRISU_UINT64_C(0xe912b9d1, 478ceb17), 461, 158},
+  {GRISU_UINT64_C(0xb616a12b, 7fe617aa), 468, 160},
+  {GRISU_UINT64_C(0x8e41ade9, fbebc27d), 475, 162},
+  {GRISU_UINT64_C(0xde469fbd, 99a05fe3), 481, 164},
+  {GRISU_UINT64_C(0xada72ccc, 20054aea), 488, 166},
+  {GRISU_UINT64_C(0x87aa9aff, 79042287), 495, 168},
+  {GRISU_UINT64_C(0xd3fa922f, 2d1675f2), 501, 170},
+  {GRISU_UINT64_C(0xa59bc234, db398c25), 508, 172},
+  {GRISU_UINT64_C(0x8161afb9, 4b44f57d), 515, 174},
+  {GRISU_UINT64_C(0xca28a291, 859bbf93), 521, 176},
+  {GRISU_UINT64_C(0x9defbf01, b061adab), 528, 178},
+  {GRISU_UINT64_C(0xf6c69a72, a3989f5c), 534, 180},
+  {GRISU_UINT64_C(0xc0cb28a9, 8fcf3c80), 541, 182},
+  {GRISU_UINT64_C(0x969eb7c4, 7859e744), 548, 184},
+  {GRISU_UINT64_C(0xeb57ff22, fc0c795a), 554, 186},
+  {GRISU_UINT64_C(0xb7dcbf53, 54e9bece), 561, 188},
+  {GRISU_UINT64_C(0x8fa47579, 1a569d11), 568, 190},
+  {GRISU_UINT64_C(0xe070f78d, 3927556b), 574, 192},
+  {GRISU_UINT64_C(0xaf584166, 54a6babb), 581, 194},
+  {GRISU_UINT64_C(0x88fcf317, f22241e2), 588, 196},
+  {GRISU_UINT64_C(0xd60b3bd5, 6a5586f2), 594, 198},
+  {GRISU_UINT64_C(0xa738c6be, bb12d16d), 601, 200},
+  {GRISU_UINT64_C(0x82a45b45, 0226b39d), 608, 202},
+  {GRISU_UINT64_C(0xcc20ce9b, d35c78a5), 614, 204},
+  {GRISU_UINT64_C(0x9f79a169, bd203e41), 621, 206},
+  {GRISU_UINT64_C(0xf92e0c35, 37826146), 627, 208},
+  {GRISU_UINT64_C(0xc2abf989, 935ddbfe), 634, 210},
+  {GRISU_UINT64_C(0x98165af3, 7b2153df), 641, 212},
+  {GRISU_UINT64_C(0xeda2ee1c, 7064130c), 647, 214},
+  {GRISU_UINT64_C(0xb9a74a06, 37ce2ee1), 654, 216},
+  {GRISU_UINT64_C(0x910ab1d4, db9914a0), 661, 218},
+  {GRISU_UINT64_C(0xe2a0b5dc, 971f303a), 667, 220},
+  {GRISU_UINT64_C(0xb10d8e14, 56105dad), 674, 222},
+  {GRISU_UINT64_C(0x8a5296ff, e33cc930), 681, 224},
+  {GRISU_UINT64_C(0xd8210bef, d30efa5a), 687, 226},
+  {GRISU_UINT64_C(0xa8d9d153, 5ce3b396), 694, 228},
+  {GRISU_UINT64_C(0x83ea2b89, 2091e44e), 701, 230},
+  {GRISU_UINT64_C(0xce1de406, 42e3f4b9), 707, 232},
+  {GRISU_UINT64_C(0xa1075a24, e4421731), 714, 234},
+  {GRISU_UINT64_C(0xfb9b7cd9, a4a7443c), 720, 236},
+  {GRISU_UINT64_C(0xc491798a, 08a2ad4f), 727, 238},
+  {GRISU_UINT64_C(0x9991a6f3, d6bf1766), 734, 240},
+  {GRISU_UINT64_C(0xeff394dc, ff8a948f), 740, 242},
+  {GRISU_UINT64_C(0xbb764c4c, a7a44410), 747, 244},
+  {GRISU_UINT64_C(0x92746b9b, e2f8552c), 754, 246},
+  {GRISU_UINT64_C(0xe4d5e823, 92a40515), 760, 248},
+  {GRISU_UINT64_C(0xb2c71d5b, ca9023f8), 767, 250},
+  {GRISU_UINT64_C(0x8bab8eef, b6409c1a), 774, 252},
+  {GRISU_UINT64_C(0xda3c0f56, 8cc4f3e9), 780, 254},
+  {GRISU_UINT64_C(0xaa7eebfb, 9df9de8e), 787, 256},
+  {GRISU_UINT64_C(0x8533285c, 936b35df), 794, 258},
+  {GRISU_UINT64_C(0xd01fef10, a657842c), 800, 260},
+  {GRISU_UINT64_C(0xa298f2c5, 01f45f43), 807, 262},
+  {GRISU_UINT64_C(0xfe0efb53, d30dd4d8), 813, 264},
+  {GRISU_UINT64_C(0xc67bb459, 7ce2ce49), 820, 266},
+  {GRISU_UINT64_C(0x9b10a4e5, e9913129), 827, 268},
+  {GRISU_UINT64_C(0xf24a01a7, 3cf2dcd0), 833, 270},
+  {GRISU_UINT64_C(0xbd49d14a, a79dbc82), 840, 272},
+  {GRISU_UINT64_C(0x93e1ab82, 52f33b46), 847, 274},
+  {GRISU_UINT64_C(0xe7109bfb, a19c0c9d), 853, 276},
+  {GRISU_UINT64_C(0xb484f9dc, 9641e9db), 860, 278},
+  {GRISU_UINT64_C(0x8d07e334, 55637eb3), 867, 280},
+  {GRISU_UINT64_C(0xdc5c5301, c56b75f7), 873, 282},
+  {GRISU_UINT64_C(0xac2820d9, 623bf429), 880, 284},
+  {GRISU_UINT64_C(0x867f59a9, d4bed6c0), 887, 286},
+  {GRISU_UINT64_C(0xd226fc19, 5c6a2f8c), 893, 288},
+  {GRISU_UINT64_C(0xa42e74f3, d032f526), 900, 290},
+  {GRISU_UINT64_C(0x80444b5e, 7aa7cf85), 907, 292},
+  {GRISU_UINT64_C(0xc86ab5c3, 9fa63441), 913, 294},
+  {GRISU_UINT64_C(0x9c935e00, d4b9d8d2), 920, 296},
+  {GRISU_UINT64_C(0xf4a642e1, 4c6262c9), 926, 298},
+  {GRISU_UINT64_C(0xbf21e440, 03acdd2d), 933, 300},
+  {GRISU_UINT64_C(0x95527a52, 02df0ccb), 940, 302},
+  {GRISU_UINT64_C(0xe950df20, 247c83fd), 946, 304},
+  {GRISU_UINT64_C(0xb6472e51, 1c81471e), 953, 306},
+  {GRISU_UINT64_C(0x8e679c2f, 5e44ff8f), 960, 308},
+  {GRISU_UINT64_C(0xde81e40a, 034bcf50), 966, 310},
+  {GRISU_UINT64_C(0xadd57a27, d29339f6), 973, 312},
+  {GRISU_UINT64_C(0x87cec76f, 1c830549), 980, 314},
+  {GRISU_UINT64_C(0xd433179d, 9c8cb841), 986, 316},
+  {GRISU_UINT64_C(0xa5c7ea73, 224deff3), 993, 318},
+  {GRISU_UINT64_C(0x81842f29, f2cce376), 1000, 320},
+  {GRISU_UINT64_C(0xca5e89b1, 8b602368), 1006, 322},
+  {GRISU_UINT64_C(0x9e19db92, b4e31ba9), 1013, 324},
+  {GRISU_UINT64_C(0xf7086715, 3aa2db39), 1019, 326},
+  {GRISU_UINT64_C(0xc0fe9088, 95cf3b44), 1026, 328},
+  {GRISU_UINT64_C(0x96c6e0ea, b509e64d), 1033, 330},
+  {GRISU_UINT64_C(0xeb96bf6e, badf77d9), 1039, 332},
+  {GRISU_UINT64_C(0xb80dc58e, 81fe95a1), 1046, 334},
+  {GRISU_UINT64_C(0x8fcac257, 558ee4e6), 1053, 336},
+  {GRISU_UINT64_C(0xe0accfa8, 75af45a8), 1059, 338},
+  {GRISU_UINT64_C(0xaf87023b, 9bf0ee6b), 1066, 340},
+  {GRISU_UINT64_C(0x892179be, 91d43a44), 1073, 342},
+  };
+static const int GRISU_CACHE_MAX_DISTANCE(2) = 7;
+// nb elements (2): 326
+static const GRISU_CACHE_STRUCT GRISU_CACHE_NAME(3)[] = {
+  {GRISU_UINT64_C(0xe61acf03, 3d1a45df), -1087, -308},
+  {GRISU_UINT64_C(0xe0b62e29, 29aba83c), -1077, -305},
+  {GRISU_UINT64_C(0xdb71e914, 32b1a24b), -1067, -302},
+  {GRISU_UINT64_C(0xd64d3d9d, b981787d), -1057, -299},
+  {GRISU_UINT64_C(0xd1476e2c, 07286faa), -1047, -296},
+  {GRISU_UINT64_C(0xcc5fc196, fefd7d0c), -1037, -293},
+  {GRISU_UINT64_C(0xc795830d, 75038c1e), -1027, -290},
+  {GRISU_UINT64_C(0xc2e801fb, 244576d5), -1017, -287},
+  {GRISU_UINT64_C(0xbe5691ef, 416bd60c), -1007, -284},
+  {GRISU_UINT64_C(0xb9e08a83, a5e34f08), -997, -281},
+  {GRISU_UINT64_C(0xb5854744, 8ffffb2e), -987, -278},
+  {GRISU_UINT64_C(0xb1442798, f49ffb4b), -977, -275},
+  {GRISU_UINT64_C(0xad1c8eab, 5ee43b67), -967, -272},
+  {GRISU_UINT64_C(0xa90de353, 5aaae202), -957, -269},
+  {GRISU_UINT64_C(0xa5178fff, 668ae0b6), -947, -266},
+  {GRISU_UINT64_C(0xa139029f, 6a239f72), -937, -263},
+  {GRISU_UINT64_C(0x9d71ac8f, ada6c9b5), -927, -260},
+  {GRISU_UINT64_C(0x99c10284, 4f94e0fb), -917, -257},
+  {GRISU_UINT64_C(0x96267c75, 35b763b5), -907, -254},
+  {GRISU_UINT64_C(0x92a1958a, 7675175f), -897, -251},
+  {GRISU_UINT64_C(0x8f31cc09, 37ae58d3), -887, -248},
+  {GRISU_UINT64_C(0x8bd6a141, 006042be), -877, -245},
+  {GRISU_UINT64_C(0x888f9979, 7a5e012d), -867, -242},
+  {GRISU_UINT64_C(0x855c3be0, a17fcd26), -857, -239},
+  {GRISU_UINT64_C(0x823c1279, 5db6ce57), -847, -236},
+  {GRISU_UINT64_C(0xfe5d5415, 0b090b03), -838, -233},
+  {GRISU_UINT64_C(0xf867241c, 8cc6d4c1), -828, -230},
+  {GRISU_UINT64_C(0xf294b943, e17a2bc4), -818, -227},
+  {GRISU_UINT64_C(0xece53cec, 4a314ebe), -808, -224},
+  {GRISU_UINT64_C(0xe757dd7e, c07426e5), -798, -221},
+  {GRISU_UINT64_C(0xe1ebce4d, c7f16dfc), -788, -218},
+  {GRISU_UINT64_C(0xdca04777, f541c568), -778, -215},
+  {GRISU_UINT64_C(0xd77485cb, 25823ac7), -768, -212},
+  {GRISU_UINT64_C(0xd267caa8, 62a12d67), -758, -209},
+  {GRISU_UINT64_C(0xcd795be8, 70516656), -748, -206},
+  {GRISU_UINT64_C(0xc8a883c0, fdaf7df0), -738, -203},
+  {GRISU_UINT64_C(0xc3f490aa, 77bd60fd), -728, -200},
+  {GRISU_UINT64_C(0xbf5cd546, 78eef0b7), -718, -197},
+  {GRISU_UINT64_C(0xbae0a846, d2195713), -708, -194},
+  {GRISU_UINT64_C(0xb67f6455, 292cbf08), -698, -191},
+  {GRISU_UINT64_C(0xb23867fb, 2a35b28e), -688, -188},
+  {GRISU_UINT64_C(0xae0b158b, 4738705f), -678, -185},
+  {GRISU_UINT64_C(0xa9f6d30a, 038d1dbc), -668, -182},
+  {GRISU_UINT64_C(0xa5fb0a17, c777cf0a), -658, -179},
+  {GRISU_UINT64_C(0xa21727db, 38cb0030), -648, -176},
+  {GRISU_UINT64_C(0x9e4a9cec, 15763e2f), -638, -173},
+  {GRISU_UINT64_C(0x9a94dd3e, 8cf578ba), -628, -170},
+  {GRISU_UINT64_C(0x96f5600f, 15a7b7e5), -618, -167},
+  {GRISU_UINT64_C(0x936b9fce, bb25c996), -608, -164},
+  {GRISU_UINT64_C(0x8ff71a0f, e2c2e6dc), -598, -161},
+  {GRISU_UINT64_C(0x8c974f73, 83725573), -588, -158},
+  {GRISU_UINT64_C(0x894bc396, ce5da772), -578, -155},
+  {GRISU_UINT64_C(0x8613fd01, 45877586), -568, -152},
+  {GRISU_UINT64_C(0x82ef8513, 3de648c5), -558, -149},
+  {GRISU_UINT64_C(0xffbbcfe9, 94e5c620), -549, -146},
+  {GRISU_UINT64_C(0xf9bd690a, 1b68637b), -539, -143},
+  {GRISU_UINT64_C(0xf3e2f893, dec3f126), -529, -140},
+  {GRISU_UINT64_C(0xee2ba6c0, 678b597f), -519, -137},
+  {GRISU_UINT64_C(0xe896a0d7, e51e1566), -509, -134},
+  {GRISU_UINT64_C(0xe3231912, d5bf60e6), -499, -131},
+  {GRISU_UINT64_C(0xddd0467c, 64bce4a1), -489, -128},
+  {GRISU_UINT64_C(0xd89d64d5, 7a607745), -479, -125},
+  {GRISU_UINT64_C(0xd389b478, 79823479), -469, -122},
+  {GRISU_UINT64_C(0xce947a3d, a6a9273e), -459, -119},
+  {GRISU_UINT64_C(0xc9bcff60, 34c13053), -449, -116},
+  {GRISU_UINT64_C(0xc5029163, f384a931), -439, -113},
+  {GRISU_UINT64_C(0xc06481fb, 9bcf8d3a), -429, -110},
+  {GRISU_UINT64_C(0xbbe226ef, b628afeb), -419, -107},
+  {GRISU_UINT64_C(0xb77ada06, 17e3bbcb), -409, -104},
+  {GRISU_UINT64_C(0xb32df8e9, f3546564), -399, -101},
+  {GRISU_UINT64_C(0xaefae514, 77a06b04), -389, -98},
+  {GRISU_UINT64_C(0xaae103b5, fcd2a882), -379, -95},
+  {GRISU_UINT64_C(0xa6dfbd9f, b8e5b88f), -369, -92},
+  {GRISU_UINT64_C(0xa2f67f2d, fa90563b), -359, -89},
+  {GRISU_UINT64_C(0x9f24b832, e6b0f436), -349, -86},
+  {GRISU_UINT64_C(0x9b69dbe1, b548ce7d), -339, -83},
+  {GRISU_UINT64_C(0x97c560ba, 6b0919a6), -329, -80},
+  {GRISU_UINT64_C(0x9436c076, 0c86e30c), -319, -77},
+  {GRISU_UINT64_C(0x90bd77f3, 483bb9ba), -309, -74},
+  {GRISU_UINT64_C(0x8d590723, 948a535f), -299, -71},
+  {GRISU_UINT64_C(0x8a08f0f8, bf0f156b), -289, -68},
+  {GRISU_UINT64_C(0x86ccbb52, ea94baeb), -279, -65},
+  {GRISU_UINT64_C(0x83a3eeee, f9153e89), -269, -62},
+  {GRISU_UINT64_C(0x808e1755, 5f3ebf12), -259, -59},
+  {GRISU_UINT64_C(0xfb158592, be068d2f), -250, -56},
+  {GRISU_UINT64_C(0xf5330471, 4d9265e0), -240, -53},
+  {GRISU_UINT64_C(0xef73d256, a5c0f77d), -230, -50},
+  {GRISU_UINT64_C(0xe9d71b68, 9dde71b0), -220, -47},
+  {GRISU_UINT64_C(0xe45c10c4, 2a2b3b06), -210, -44},
+  {GRISU_UINT64_C(0xdf01e85f, 912e37a3), -200, -41},
+  {GRISU_UINT64_C(0xd9c7dced, 53c72256), -190, -38},
+  {GRISU_UINT64_C(0xd4ad2dbf, c3d07788), -180, -35},
+  {GRISU_UINT64_C(0xcfb11ead, 453994ba), -170, -32},
+  {GRISU_UINT64_C(0xcad2f7f5, 359a3b3e), -160, -29},
+  {GRISU_UINT64_C(0xc6120625, 76589ddb), -150, -26},
+  {GRISU_UINT64_C(0xc16d9a00, 95928a27), -140, -23},
+  {GRISU_UINT64_C(0xbce50864, 92111aeb), -130, -20},
+  {GRISU_UINT64_C(0xb877aa32, 36a4b449), -120, -17},
+  {GRISU_UINT64_C(0xb424dc35, 095cd80f), -110, -14},
+  {GRISU_UINT64_C(0xafebff0b, cb24aaff), -100, -11},
+  {GRISU_UINT64_C(0xabcc7711, 8461cefd), -90, -8},
+  {GRISU_UINT64_C(0xa7c5ac47, 1b478423), -80, -5},
+  {GRISU_UINT64_C(0xa3d70a3d, 70a3d70a), -70, -2},
+  {GRISU_UINT64_C(0xa0000000, 00000000), -60, 1},
+  {GRISU_UINT64_C(0x9c400000, 00000000), -50, 4},
+  {GRISU_UINT64_C(0x98968000, 00000000), -40, 7},
+  {GRISU_UINT64_C(0x9502f900, 00000000), -30, 10},
+  {GRISU_UINT64_C(0x9184e72a, 00000000), -20, 13},
+  {GRISU_UINT64_C(0x8e1bc9bf, 04000000), -10, 16},
+  {GRISU_UINT64_C(0x8ac72304, 89e80000), 0, 19},
+  {GRISU_UINT64_C(0x87867832, 6eac9000), 10, 22},
+  {GRISU_UINT64_C(0x84595161, 401484a0), 20, 25},
+  {GRISU_UINT64_C(0x813f3978, f8940984), 30, 28},
+  {GRISU_UINT64_C(0xfc6f7c40, 45812296), 39, 31},
+  {GRISU_UINT64_C(0xf684df56, c3e01bc7), 49, 34},
+  {GRISU_UINT64_C(0xf0bdc21a, bb48db20), 59, 37},
+  {GRISU_UINT64_C(0xeb194f8e, 1ae525fd), 69, 40},
+  {GRISU_UINT64_C(0xe596b7b0, c643c719), 79, 43},
+  {GRISU_UINT64_C(0xe0352f62, a19e306f), 89, 46},
+  {GRISU_UINT64_C(0xdaf3f046, 51d47b4c), 99, 49},
+  {GRISU_UINT64_C(0xd5d238a4, abe98068), 109, 52},
+  {GRISU_UINT64_C(0xd0cf4b50, cfe20766), 119, 55},
+  {GRISU_UINT64_C(0xcbea6f8c, eb02bb3a), 129, 58},
+  {GRISU_UINT64_C(0xc722f0ef, 9d80aad6), 139, 61},
+  {GRISU_UINT64_C(0xc2781f49, ffcfa6d5), 149, 64},
+  {GRISU_UINT64_C(0xbde94e8e, 43d0c8ec), 159, 67},
+  {GRISU_UINT64_C(0xb975d6b6, ee39e437), 169, 70},
+  {GRISU_UINT64_C(0xb51d13ae, a4a488dd), 179, 73},
+  {GRISU_UINT64_C(0xb0de6538, 8cc8ada8), 189, 76},
+  {GRISU_UINT64_C(0xacb92ed9, 397bf996), 199, 79},
+  {GRISU_UINT64_C(0xa8acd7c0, 222311bd), 209, 82},
+  {GRISU_UINT64_C(0xa4b8cab1, a1563f52), 219, 85},
+  {GRISU_UINT64_C(0xa0dc75f1, 778e39d6), 229, 88},
+  {GRISU_UINT64_C(0x9d174b2d, cec0e47b), 239, 91},
+  {GRISU_UINT64_C(0x9968bf6a, bbe85f20), 249, 94},
+  {GRISU_UINT64_C(0x95d04aee, 3b80ece6), 259, 97},
+  {GRISU_UINT64_C(0x924d692c, a61be758), 269, 100},
+  {GRISU_UINT64_C(0x8edf98b5, 9a373fec), 279, 103},
+  {GRISU_UINT64_C(0x8b865b21, 5899f46d), 289, 106},
+  {GRISU_UINT64_C(0x884134fe, 908658b2), 299, 109},
+  {GRISU_UINT64_C(0x850fadc0, 9923329e), 309, 112},
+  {GRISU_UINT64_C(0x81f14fae, 158c5f6e), 319, 115},
+  {GRISU_UINT64_C(0xfdcb4fa0, 02162a63), 328, 118},
+  {GRISU_UINT64_C(0xf7d88bc2, 4209a565), 338, 121},
+  {GRISU_UINT64_C(0xf209787b, b47d6b85), 348, 124},
+  {GRISU_UINT64_C(0xec5d3fa8, ce427b00), 358, 127},
+  {GRISU_UINT64_C(0xe6d3102a, d96cec1e), 368, 130},
+  {GRISU_UINT64_C(0xe16a1dc9, d8545e95), 378, 133},
+  {GRISU_UINT64_C(0xdc21a117, 1d42645d), 388, 136},
+  {GRISU_UINT64_C(0xd6f8d750, 9292d603), 398, 139},
+  {GRISU_UINT64_C(0xd1ef0244, af2364ff), 408, 142},
+  {GRISU_UINT64_C(0xcd036837, 130890a1), 418, 145},
+  {GRISU_UINT64_C(0xc83553c5, c8965d3d), 428, 148},
+  {GRISU_UINT64_C(0xc38413cf, 25e2d70e), 438, 151},
+  {GRISU_UINT64_C(0xbeeefb58, 4aff8604), 448, 154},
+  {GRISU_UINT64_C(0xba756174, 393d88e0), 458, 157},
+  {GRISU_UINT64_C(0xb616a12b, 7fe617aa), 468, 160},
+  {GRISU_UINT64_C(0xb1d21964, 7ae6b31c), 478, 163},
+  {GRISU_UINT64_C(0xada72ccc, 20054aea), 488, 166},
+  {GRISU_UINT64_C(0xa99541bf, 57452b28), 498, 169},
+  {GRISU_UINT64_C(0xa59bc234, db398c25), 508, 172},
+  {GRISU_UINT64_C(0xa1ba1ba7, 9e1632dc), 518, 175},
+  {GRISU_UINT64_C(0x9defbf01, b061adab), 528, 178},
+  {GRISU_UINT64_C(0x9a3c2087, a63f6399), 538, 181},
+  {GRISU_UINT64_C(0x969eb7c4, 7859e744), 548, 184},
+  {GRISU_UINT64_C(0x9316ff75, dd87cbd8), 558, 187},
+  {GRISU_UINT64_C(0x8fa47579, 1a569d11), 568, 190},
+  {GRISU_UINT64_C(0x8c469ab8, 43b89563), 578, 193},
+  {GRISU_UINT64_C(0x88fcf317, f22241e2), 588, 196},
+  {GRISU_UINT64_C(0x85c70565, 62757457), 598, 199},
+  {GRISU_UINT64_C(0x82a45b45, 0226b39d), 608, 202},
+  {GRISU_UINT64_C(0xff290242, c83396ce), 617, 205},
+  {GRISU_UINT64_C(0xf92e0c35, 37826146), 627, 208},
+  {GRISU_UINT64_C(0xf356f7eb, f83552fe), 637, 211},
+  {GRISU_UINT64_C(0xeda2ee1c, 7064130c), 647, 214},
+  {GRISU_UINT64_C(0xe8111c87, c5c1ba9a), 657, 217},
+  {GRISU_UINT64_C(0xe2a0b5dc, 971f303a), 667, 220},
+  {GRISU_UINT64_C(0xdd50f199, 6b947519), 677, 223},
+  {GRISU_UINT64_C(0xd8210bef, d30efa5a), 687, 226},
+  {GRISU_UINT64_C(0xd31045a8, 341ca07c), 697, 229},
+  {GRISU_UINT64_C(0xce1de406, 42e3f4b9), 707, 232},
+  {GRISU_UINT64_C(0xc94930ae, 1d529cfd), 717, 235},
+  {GRISU_UINT64_C(0xc491798a, 08a2ad4f), 727, 238},
+  {GRISU_UINT64_C(0xbff610b0, cc6edd3f), 737, 241},
+  {GRISU_UINT64_C(0xbb764c4c, a7a44410), 747, 244},
+  {GRISU_UINT64_C(0xb7118682, dbb66a77), 757, 247},
+  {GRISU_UINT64_C(0xb2c71d5b, ca9023f8), 767, 250},
+  {GRISU_UINT64_C(0xae9672ab, a3d0c321), 777, 253},
+  {GRISU_UINT64_C(0xaa7eebfb, 9df9de8e), 787, 256},
+  {GRISU_UINT64_C(0xa67ff273, b8460357), 797, 259},
+  {GRISU_UINT64_C(0xa298f2c5, 01f45f43), 807, 262},
+  {GRISU_UINT64_C(0x9ec95d14, 63e8a507), 817, 265},
+  {GRISU_UINT64_C(0x9b10a4e5, e9913129), 827, 268},
+  {GRISU_UINT64_C(0x976e4108, 8617ca02), 837, 271},
+  {GRISU_UINT64_C(0x93e1ab82, 52f33b46), 847, 274},
+  {GRISU_UINT64_C(0x906a617d, 450187e2), 857, 277},
+  {GRISU_UINT64_C(0x8d07e334, 55637eb3), 867, 280},
+  {GRISU_UINT64_C(0x89b9b3e1, 1b6329bb), 877, 283},
+  {GRISU_UINT64_C(0x867f59a9, d4bed6c0), 887, 286},
+  {GRISU_UINT64_C(0x83585d8f, d9c25db8), 897, 289},
+  {GRISU_UINT64_C(0x80444b5e, 7aa7cf85), 907, 292},
+  {GRISU_UINT64_C(0xfa856334, 878fc151), 916, 295},
+  {GRISU_UINT64_C(0xf4a642e1, 4c6262c9), 926, 298},
+  {GRISU_UINT64_C(0xeeea5d50, 04981478), 936, 301},
+  {GRISU_UINT64_C(0xe950df20, 247c83fd), 946, 304},
+  {GRISU_UINT64_C(0xe3d8f9e5, 63a198e5), 956, 307},
+  {GRISU_UINT64_C(0xde81e40a, 034bcf50), 966, 310},
+  {GRISU_UINT64_C(0xd94ad8b1, c7380874), 976, 313},
+  {GRISU_UINT64_C(0xd433179d, 9c8cb841), 986, 316},
+  {GRISU_UINT64_C(0xcf39e50f, eae16bf0), 996, 319},
+  {GRISU_UINT64_C(0xca5e89b1, 8b602368), 1006, 322},
+  {GRISU_UINT64_C(0xc5a05277, 621be294), 1016, 325},
+  {GRISU_UINT64_C(0xc0fe9088, 95cf3b44), 1026, 328},
+  {GRISU_UINT64_C(0xbc789925, 624c5fe1), 1036, 331},
+  {GRISU_UINT64_C(0xb80dc58e, 81fe95a1), 1046, 334},
+  {GRISU_UINT64_C(0xb3bd72ed, 2af29e20), 1056, 337},
+  {GRISU_UINT64_C(0xaf87023b, 9bf0ee6b), 1066, 340},
+  };
+static const int GRISU_CACHE_MAX_DISTANCE(3) = 10;
+// nb elements (3): 217
+static const GRISU_CACHE_STRUCT GRISU_CACHE_NAME(4)[] = {
+  {GRISU_UINT64_C(0xe61acf03, 3d1a45df), -1087, -308},
+  {GRISU_UINT64_C(0x8c71dcd9, ba0b4926), -1073, -304},
+  {GRISU_UINT64_C(0xab70fe17, c79ac6ca), -1060, -300},
+  {GRISU_UINT64_C(0xd1476e2c, 07286faa), -1047, -296},
+  {GRISU_UINT64_C(0xff77b1fc, bebcdc4f), -1034, -292},
+  {GRISU_UINT64_C(0x9becce62, 836ac577), -1020, -288},
+  {GRISU_UINT64_C(0xbe5691ef, 416bd60c), -1007, -284},
+  {GRISU_UINT64_C(0xe858ad24, 8f5c22ca), -994, -280},
+  {GRISU_UINT64_C(0x8dd01fad, 907ffc3c), -980, -276},
+  {GRISU_UINT64_C(0xad1c8eab, 5ee43b67), -967, -272},
+  {GRISU_UINT64_C(0xd3515c28, 31559a83), -954, -268},
+  {GRISU_UINT64_C(0x80fa687f, 881c7f8e), -940, -264},
+  {GRISU_UINT64_C(0x9d71ac8f, ada6c9b5), -927, -260},
+  {GRISU_UINT64_C(0xc0314325, 637a193a), -914, -256},
+  {GRISU_UINT64_C(0xea9c2277, 23ee8bcb), -901, -252},
+  {GRISU_UINT64_C(0x8f31cc09, 37ae58d3), -887, -248},
+  {GRISU_UINT64_C(0xaecc4991, 4078536d), -874, -244},
+  {GRISU_UINT64_C(0xd5605fcd, cf32e1d7), -861, -240},
+  {GRISU_UINT64_C(0x823c1279, 5db6ce57), -847, -236},
+  {GRISU_UINT64_C(0x9efa548d, 26e5a6e2), -834, -232},
+  {GRISU_UINT64_C(0xc2109436, 4dfb5637), -821, -228},
+  {GRISU_UINT64_C(0xece53cec, 4a314ebe), -808, -224},
+  {GRISU_UINT64_C(0x9096ea6f, 3848984f), -794, -220},
+  {GRISU_UINT64_C(0xb080392c, c4349ded), -781, -216},
+  {GRISU_UINT64_C(0xd77485cb, 25823ac7), -768, -212},
+  {GRISU_UINT64_C(0x8380dea9, 3da4bc60), -754, -208},
+  {GRISU_UINT64_C(0xa086cfcd, 97bf97f4), -741, -204},
+  {GRISU_UINT64_C(0xc3f490aa, 77bd60fd), -728, -200},
+  {GRISU_UINT64_C(0xef340a98, 172aace5), -715, -196},
+  {GRISU_UINT64_C(0x91ff8377, 5423cc06), -701, -192},
+  {GRISU_UINT64_C(0xb23867fb, 2a35b28e), -688, -188},
+  {GRISU_UINT64_C(0xd98ddaee, 19068c76), -675, -184},
+  {GRISU_UINT64_C(0x84c8d4df, d2c63f3b), -661, -180},
+  {GRISU_UINT64_C(0xa21727db, 38cb0030), -648, -176},
+  {GRISU_UINT64_C(0xc5dd4427, 1ad3cdba), -635, -172},
+  {GRISU_UINT64_C(0xf18899b1, bc3f8ca2), -622, -168},
+  {GRISU_UINT64_C(0x936b9fce, bb25c996), -608, -164},
+  {GRISU_UINT64_C(0xb3f4e093, db73a093), -595, -160},
+  {GRISU_UINT64_C(0xdbac6c24, 7d62a584), -582, -156},
+  {GRISU_UINT64_C(0x8613fd01, 45877586), -568, -152},
+  {GRISU_UINT64_C(0xa3ab6658, 0d5fdaf6), -555, -148},
+  {GRISU_UINT64_C(0xc7caba6e, 7c5382c9), -542, -144},
+  {GRISU_UINT64_C(0xf3e2f893, dec3f126), -529, -140},
+  {GRISU_UINT64_C(0x94db4838, 40b717f0), -515, -136},
+  {GRISU_UINT64_C(0xb5b5ada8, aaff80b8), -502, -132},
+  {GRISU_UINT64_C(0xddd0467c, 64bce4a1), -489, -128},
+  {GRISU_UINT64_C(0x87625f05, 6c7c4a8b), -475, -124},
+  {GRISU_UINT64_C(0xa54394fe, 1eedb8ff), -462, -120},
+  {GRISU_UINT64_C(0xc9bcff60, 34c13053), -449, -116},
+  {GRISU_UINT64_C(0xf64335bc, f065d37d), -436, -112},
+  {GRISU_UINT64_C(0x964e858c, 91ba2655), -422, -108},
+  {GRISU_UINT64_C(0xb77ada06, 17e3bbcb), -409, -104},
+  {GRISU_UINT64_C(0xdff97724, 70297ebd), -396, -100},
+  {GRISU_UINT64_C(0x88b402f7, fd75539b), -382, -96},
+  {GRISU_UINT64_C(0xa6dfbd9f, b8e5b88f), -369, -92},
+  {GRISU_UINT64_C(0xcbb41ef9, 79346bca), -356, -88},
+  {GRISU_UINT64_C(0xf8a95fcf, 88747d94), -343, -84},
+  {GRISU_UINT64_C(0x97c560ba, 6b0919a6), -329, -80},
+  {GRISU_UINT64_C(0xb9447093, 8fa89bcf), -316, -76},
+  {GRISU_UINT64_C(0xe2280b6c, 20dd5232), -303, -72},
+  {GRISU_UINT64_C(0x8a08f0f8, bf0f156b), -289, -68},
+  {GRISU_UINT64_C(0xa87fea27, a539e9a5), -276, -64},
+  {GRISU_UINT64_C(0xcdb02555, 653131b6), -263, -60},
+  {GRISU_UINT64_C(0xfb158592, be068d2f), -250, -56},
+  {GRISU_UINT64_C(0x993fe2c6, d07b7fac), -236, -52},
+  {GRISU_UINT64_C(0xbb127c53, b17ec159), -223, -48},
+  {GRISU_UINT64_C(0xe45c10c4, 2a2b3b06), -210, -44},
+  {GRISU_UINT64_C(0x8b61313b, babce2c6), -196, -40},
+  {GRISU_UINT64_C(0xaa242499, 697392d3), -183, -36},
+  {GRISU_UINT64_C(0xcfb11ead, 453994ba), -170, -32},
+  {GRISU_UINT64_C(0xfd87b5f2, 8300ca0e), -157, -28},
+  {GRISU_UINT64_C(0x9abe14cd, 44753b53), -143, -24},
+  {GRISU_UINT64_C(0xbce50864, 92111aeb), -130, -20},
+  {GRISU_UINT64_C(0xe69594be, c44de15b), -117, -16},
+  {GRISU_UINT64_C(0x8cbccc09, 6f5088cc), -103, -12},
+  {GRISU_UINT64_C(0xabcc7711, 8461cefd), -90, -8},
+  {GRISU_UINT64_C(0xd1b71758, e219652c), -77, -4},
+  {GRISU_UINT64_C(0x80000000, 00000000), -63, 0},
+  {GRISU_UINT64_C(0x9c400000, 00000000), -50, 4},
+  {GRISU_UINT64_C(0xbebc2000, 00000000), -37, 8},
+  {GRISU_UINT64_C(0xe8d4a510, 00000000), -24, 12},
+  {GRISU_UINT64_C(0x8e1bc9bf, 04000000), -10, 16},
+  {GRISU_UINT64_C(0xad78ebc5, ac620000), 3, 20},
+  {GRISU_UINT64_C(0xd3c21bce, cceda100), 16, 24},
+  {GRISU_UINT64_C(0x813f3978, f8940984), 30, 28},
+  {GRISU_UINT64_C(0x9dc5ada8, 2b70b59e), 43, 32},
+  {GRISU_UINT64_C(0xc097ce7b, c90715b3), 56, 36},
+  {GRISU_UINT64_C(0xeb194f8e, 1ae525fd), 69, 40},
+  {GRISU_UINT64_C(0x8f7e32ce, 7bea5c70), 83, 44},
+  {GRISU_UINT64_C(0xaf298d05, 0e4395d7), 96, 48},
+  {GRISU_UINT64_C(0xd5d238a4, abe98068), 109, 52},
+  {GRISU_UINT64_C(0x82818f12, 81ed44a0), 123, 56},
+  {GRISU_UINT64_C(0x9f4f2726, 179a2245), 136, 60},
+  {GRISU_UINT64_C(0xc2781f49, ffcfa6d5), 149, 64},
+  {GRISU_UINT64_C(0xed63a231, d4c4fb27), 162, 68},
+  {GRISU_UINT64_C(0x90e40fbe, ea1d3a4b), 176, 72},
+  {GRISU_UINT64_C(0xb0de6538, 8cc8ada8), 189, 76},
+  {GRISU_UINT64_C(0xd7e77a8f, 87daf7fc), 202, 80},
+  {GRISU_UINT64_C(0x83c7088e, 1aab65db), 216, 84},
+  {GRISU_UINT64_C(0xa0dc75f1, 778e39d6), 229, 88},
+  {GRISU_UINT64_C(0xc45d1df9, 42711d9a), 242, 92},
+  {GRISU_UINT64_C(0xefb3ab16, c59b14a3), 255, 96},
+  {GRISU_UINT64_C(0x924d692c, a61be758), 269, 100},
+  {GRISU_UINT64_C(0xb2977ee3, 00c50fe7), 282, 104},
+  {GRISU_UINT64_C(0xda01ee64, 1a708dea), 295, 108},
+  {GRISU_UINT64_C(0x850fadc0, 9923329e), 309, 112},
+  {GRISU_UINT64_C(0xa26da399, 9aef774a), 322, 116},
+  {GRISU_UINT64_C(0xc646d635, 01a1511e), 335, 120},
+  {GRISU_UINT64_C(0xf209787b, b47d6b85), 348, 124},
+  {GRISU_UINT64_C(0x93ba47c9, 80e98ce0), 362, 128},
+  {GRISU_UINT64_C(0xb454e4a1, 79dd1877), 375, 132},
+  {GRISU_UINT64_C(0xdc21a117, 1d42645d), 388, 136},
+  {GRISU_UINT64_C(0x865b8692, 5b9bc5c2), 402, 140},
+  {GRISU_UINT64_C(0xa402b9c5, a8d3a6e7), 415, 144},
+  {GRISU_UINT64_C(0xc83553c5, c8965d3d), 428, 148},
+  {GRISU_UINT64_C(0xf46518c2, ef5b8cd1), 441, 152},
+  {GRISU_UINT64_C(0x952ab45c, fa97a0b3), 455, 156},
+  {GRISU_UINT64_C(0xb616a12b, 7fe617aa), 468, 160},
+  {GRISU_UINT64_C(0xde469fbd, 99a05fe3), 481, 164},
+  {GRISU_UINT64_C(0x87aa9aff, 79042287), 495, 168},
+  {GRISU_UINT64_C(0xa59bc234, db398c25), 508, 172},
+  {GRISU_UINT64_C(0xca28a291, 859bbf93), 521, 176},
+  {GRISU_UINT64_C(0xf6c69a72, a3989f5c), 534, 180},
+  {GRISU_UINT64_C(0x969eb7c4, 7859e744), 548, 184},
+  {GRISU_UINT64_C(0xb7dcbf53, 54e9bece), 561, 188},
+  {GRISU_UINT64_C(0xe070f78d, 3927556b), 574, 192},
+  {GRISU_UINT64_C(0x88fcf317, f22241e2), 588, 196},
+  {GRISU_UINT64_C(0xa738c6be, bb12d16d), 601, 200},
+  {GRISU_UINT64_C(0xcc20ce9b, d35c78a5), 614, 204},
+  {GRISU_UINT64_C(0xf92e0c35, 37826146), 627, 208},
+  {GRISU_UINT64_C(0x98165af3, 7b2153df), 641, 212},
+  {GRISU_UINT64_C(0xb9a74a06, 37ce2ee1), 654, 216},
+  {GRISU_UINT64_C(0xe2a0b5dc, 971f303a), 667, 220},
+  {GRISU_UINT64_C(0x8a5296ff, e33cc930), 681, 224},
+  {GRISU_UINT64_C(0xa8d9d153, 5ce3b396), 694, 228},
+  {GRISU_UINT64_C(0xce1de406, 42e3f4b9), 707, 232},
+  {GRISU_UINT64_C(0xfb9b7cd9, a4a7443c), 720, 236},
+  {GRISU_UINT64_C(0x9991a6f3, d6bf1766), 734, 240},
+  {GRISU_UINT64_C(0xbb764c4c, a7a44410), 747, 244},
+  {GRISU_UINT64_C(0xe4d5e823, 92a40515), 760, 248},
+  {GRISU_UINT64_C(0x8bab8eef, b6409c1a), 774, 252},
+  {GRISU_UINT64_C(0xaa7eebfb, 9df9de8e), 787, 256},
+  {GRISU_UINT64_C(0xd01fef10, a657842c), 800, 260},
+  {GRISU_UINT64_C(0xfe0efb53, d30dd4d8), 813, 264},
+  {GRISU_UINT64_C(0x9b10a4e5, e9913129), 827, 268},
+  {GRISU_UINT64_C(0xbd49d14a, a79dbc82), 840, 272},
+  {GRISU_UINT64_C(0xe7109bfb, a19c0c9d), 853, 276},
+  {GRISU_UINT64_C(0x8d07e334, 55637eb3), 867, 280},
+  {GRISU_UINT64_C(0xac2820d9, 623bf429), 880, 284},
+  {GRISU_UINT64_C(0xd226fc19, 5c6a2f8c), 893, 288},
+  {GRISU_UINT64_C(0x80444b5e, 7aa7cf85), 907, 292},
+  {GRISU_UINT64_C(0x9c935e00, d4b9d8d2), 920, 296},
+  {GRISU_UINT64_C(0xbf21e440, 03acdd2d), 933, 300},
+  {GRISU_UINT64_C(0xe950df20, 247c83fd), 946, 304},
+  {GRISU_UINT64_C(0x8e679c2f, 5e44ff8f), 960, 308},
+  {GRISU_UINT64_C(0xadd57a27, d29339f6), 973, 312},
+  {GRISU_UINT64_C(0xd433179d, 9c8cb841), 986, 316},
+  {GRISU_UINT64_C(0x81842f29, f2cce376), 1000, 320},
+  {GRISU_UINT64_C(0x9e19db92, b4e31ba9), 1013, 324},
+  {GRISU_UINT64_C(0xc0fe9088, 95cf3b44), 1026, 328},
+  {GRISU_UINT64_C(0xeb96bf6e, badf77d9), 1039, 332},
+  {GRISU_UINT64_C(0x8fcac257, 558ee4e6), 1053, 336},
+  {GRISU_UINT64_C(0xaf87023b, 9bf0ee6b), 1066, 340},
+  };
+static const int GRISU_CACHE_MAX_DISTANCE(4) = 14;
+// nb elements (4): 163
+static const GRISU_CACHE_STRUCT GRISU_CACHE_NAME(5)[] = {
+  {GRISU_UINT64_C(0xe61acf03, 3d1a45df), -1087, -308},
+  {GRISU_UINT64_C(0xaf8e5410, 288e1b6f), -1070, -303},
+  {GRISU_UINT64_C(0x85f04682, 93f0eb4e), -1053, -298},
+  {GRISU_UINT64_C(0xcc5fc196, fefd7d0c), -1037, -293},
+  {GRISU_UINT64_C(0x9becce62, 836ac577), -1020, -288},
+  {GRISU_UINT64_C(0xedec366b, 11c6cb8f), -1004, -283},
+  {GRISU_UINT64_C(0xb5854744, 8ffffb2e), -987, -278},
+  {GRISU_UINT64_C(0x8a7d3eef, 7f1cfc52), -970, -273},
+  {GRISU_UINT64_C(0xd3515c28, 31559a83), -954, -268},
+  {GRISU_UINT64_C(0xa139029f, 6a239f72), -937, -263},
+  {GRISU_UINT64_C(0xf6019da0, 7f549b2b), -921, -258},
+  {GRISU_UINT64_C(0xbbb01b92, 83253ca3), -904, -253},
+  {GRISU_UINT64_C(0x8f31cc09, 37ae58d3), -887, -248},
+  {GRISU_UINT64_C(0xda7f5bf5, 90966849), -871, -243},
+  {GRISU_UINT64_C(0xa6b34ad8, c9dfc070), -854, -238},
+  {GRISU_UINT64_C(0xfe5d5415, 0b090b03), -838, -233},
+  {GRISU_UINT64_C(0xc2109436, 4dfb5637), -821, -228},
+  {GRISU_UINT64_C(0x940f4613, ae5ed137), -804, -223},
+  {GRISU_UINT64_C(0xe1ebce4d, c7f16dfc), -788, -218},
+  {GRISU_UINT64_C(0xac5d37d5, b79b6239), -771, -213},
+  {GRISU_UINT64_C(0x8380dea9, 3da4bc60), -754, -208},
+  {GRISU_UINT64_C(0xc8a883c0, fdaf7df0), -738, -203},
+  {GRISU_UINT64_C(0x99171105, 2d8bf3c5), -721, -198},
+  {GRISU_UINT64_C(0xe998d258, 869facd7), -705, -193},
+  {GRISU_UINT64_C(0xb23867fb, 2a35b28e), -688, -188},
+  {GRISU_UINT64_C(0x87f8a8d4, cfa417ca), -671, -183},
+  {GRISU_UINT64_C(0xcf79cc9d, b955c2cc), -655, -178},
+  {GRISU_UINT64_C(0x9e4a9cec, 15763e2f), -638, -173},
+  {GRISU_UINT64_C(0xf18899b1, bc3f8ca2), -622, -168},
+  {GRISU_UINT64_C(0xb84687c2, 69ef3bfb), -605, -163},
+  {GRISU_UINT64_C(0x8c974f73, 83725573), -588, -158},
+  {GRISU_UINT64_C(0xd686619b, a27255a3), -572, -153},
+  {GRISU_UINT64_C(0xa3ab6658, 0d5fdaf6), -555, -148},
+  {GRISU_UINT64_C(0xf9bd690a, 1b68637b), -539, -143},
+  {GRISU_UINT64_C(0xbe895233, 86091466), -522, -138},
+  {GRISU_UINT64_C(0x915e2486, ef32cd60), -505, -133},
+  {GRISU_UINT64_C(0xddd0467c, 64bce4a1), -489, -128},
+  {GRISU_UINT64_C(0xa93af6c6, c79b5d2e), -472, -123},
+  {GRISU_UINT64_C(0x811ccc66, 8829b887), -455, -118},
+  {GRISU_UINT64_C(0xc5029163, f384a931), -439, -113},
+  {GRISU_UINT64_C(0x964e858c, 91ba2655), -422, -108},
+  {GRISU_UINT64_C(0xe5599087, 9ddcaabe), -406, -103},
+  {GRISU_UINT64_C(0xaefae514, 77a06b04), -389, -98},
+  {GRISU_UINT64_C(0x857fcae6, 2d8493a5), -372, -93},
+  {GRISU_UINT64_C(0xcbb41ef9, 79346bca), -356, -88},
+  {GRISU_UINT64_C(0x9b69dbe1, b548ce7d), -339, -83},
+  {GRISU_UINT64_C(0xed246723, 473e3813), -323, -78},
+  {GRISU_UINT64_C(0xb4ecd5f0, 1a4aa828), -306, -73},
+  {GRISU_UINT64_C(0x8a08f0f8, bf0f156b), -289, -68},
+  {GRISU_UINT64_C(0xd29fe4b1, 8e88640f), -273, -63},
+  {GRISU_UINT64_C(0xa0b19d2a, b70e6ed6), -256, -58},
+  {GRISU_UINT64_C(0xf5330471, 4d9265e0), -240, -53},
+  {GRISU_UINT64_C(0xbb127c53, b17ec159), -223, -48},
+  {GRISU_UINT64_C(0x8eb98a7a, 9a5b04e3), -206, -43},
+  {GRISU_UINT64_C(0xd9c7dced, 53c72256), -190, -38},
+  {GRISU_UINT64_C(0xa6274bbd, d0fadd62), -173, -33},
+  {GRISU_UINT64_C(0xfd87b5f2, 8300ca0e), -157, -28},
+  {GRISU_UINT64_C(0xc16d9a00, 95928a27), -140, -23},
+  {GRISU_UINT64_C(0x9392ee8e, 921d5d07), -123, -18},
+  {GRISU_UINT64_C(0xe12e1342, 4bb40e13), -107, -13},
+  {GRISU_UINT64_C(0xabcc7711, 8461cefd), -90, -8},
+  {GRISU_UINT64_C(0x83126e97, 8d4fdf3b), -73, -3},
+  {GRISU_UINT64_C(0xc8000000, 00000000), -57, 2},
+  {GRISU_UINT64_C(0x98968000, 00000000), -40, 7},
+  {GRISU_UINT64_C(0xe8d4a510, 00000000), -24, 12},
+  {GRISU_UINT64_C(0xb1a2bc2e, c5000000), -7, 17},
+  {GRISU_UINT64_C(0x87867832, 6eac9000), 10, 22},
+  {GRISU_UINT64_C(0xcecb8f27, f4200f3a), 26, 27},
+  {GRISU_UINT64_C(0x9dc5ada8, 2b70b59e), 43, 32},
+  {GRISU_UINT64_C(0xf0bdc21a, bb48db20), 59, 37},
+  {GRISU_UINT64_C(0xb7abc627, 050305ae), 76, 42},
+  {GRISU_UINT64_C(0x8c213d9d, a502de45), 93, 47},
+  {GRISU_UINT64_C(0xd5d238a4, abe98068), 109, 52},
+  {GRISU_UINT64_C(0xa321f2d7, 226895c8), 126, 57},
+  {GRISU_UINT64_C(0xf8ebad2b, 84e0d58c), 142, 62},
+  {GRISU_UINT64_C(0xbde94e8e, 43d0c8ec), 159, 67},
+  {GRISU_UINT64_C(0x90e40fbe, ea1d3a4b), 176, 72},
+  {GRISU_UINT64_C(0xdd15fe86, affad912), 192, 77},
+  {GRISU_UINT64_C(0xa8acd7c0, 222311bd), 209, 82},
+  {GRISU_UINT64_C(0x80b05e5a, c60b6178), 226, 87},
+  {GRISU_UINT64_C(0xc45d1df9, 42711d9a), 242, 92},
+  {GRISU_UINT64_C(0x95d04aee, 3b80ece6), 259, 97},
+  {GRISU_UINT64_C(0xe498f455, c38b997a), 275, 102},
+  {GRISU_UINT64_C(0xae67f1e9, aec07188), 292, 107},
+  {GRISU_UINT64_C(0x850fadc0, 9923329e), 309, 112},
+  {GRISU_UINT64_C(0xcb090c80, 01ab551c), 325, 117},
+  {GRISU_UINT64_C(0x9ae75759, 6946075f), 342, 122},
+  {GRISU_UINT64_C(0xec5d3fa8, ce427b00), 358, 127},
+  {GRISU_UINT64_C(0xb454e4a1, 79dd1877), 375, 132},
+  {GRISU_UINT64_C(0x899504ae, 72497eba), 392, 137},
+  {GRISU_UINT64_C(0xd1ef0244, af2364ff), 408, 142},
+  {GRISU_UINT64_C(0xa02aa96b, 06deb0fe), 425, 147},
+  {GRISU_UINT64_C(0xf46518c2, ef5b8cd1), 441, 152},
+  {GRISU_UINT64_C(0xba756174, 393d88e0), 458, 157},
+  {GRISU_UINT64_C(0x8e41ade9, fbebc27d), 475, 162},
+  {GRISU_UINT64_C(0xd910f7ff, 28069da4), 491, 167},
+  {GRISU_UINT64_C(0xa59bc234, db398c25), 508, 172},
+  {GRISU_UINT64_C(0xfcb2cb35, e702af78), 524, 177},
+  {GRISU_UINT64_C(0xc0cb28a9, 8fcf3c80), 541, 182},
+  {GRISU_UINT64_C(0x9316ff75, dd87cbd8), 558, 187},
+  {GRISU_UINT64_C(0xe070f78d, 3927556b), 574, 192},
+  {GRISU_UINT64_C(0xab3c2fdd, eeaad25b), 591, 197},
+  {GRISU_UINT64_C(0x82a45b45, 0226b39d), 608, 202},
+  {GRISU_UINT64_C(0xc75809c4, 2c684dd1), 624, 207},
+  {GRISU_UINT64_C(0x98165af3, 7b2153df), 641, 212},
+  {GRISU_UINT64_C(0xe8111c87, c5c1ba9a), 657, 217},
+  {GRISU_UINT64_C(0xb10d8e14, 56105dad), 674, 222},
+  {GRISU_UINT64_C(0x8714a775, e3e95c78), 691, 227},
+  {GRISU_UINT64_C(0xce1de406, 42e3f4b9), 707, 232},
+  {GRISU_UINT64_C(0x9d412e08, 06e88aa6), 724, 237},
+  {GRISU_UINT64_C(0xeff394dc, ff8a948f), 740, 242},
+  {GRISU_UINT64_C(0xb7118682, dbb66a77), 757, 247},
+  {GRISU_UINT64_C(0x8bab8eef, b6409c1a), 774, 252},
+  {GRISU_UINT64_C(0xd51ea6fa, 85785631), 790, 257},
+  {GRISU_UINT64_C(0xa298f2c5, 01f45f43), 807, 262},
+  {GRISU_UINT64_C(0xf81aa16f, dc1b81db), 823, 267},
+  {GRISU_UINT64_C(0xbd49d14a, a79dbc82), 840, 272},
+  {GRISU_UINT64_C(0x906a617d, 450187e2), 857, 277},
+  {GRISU_UINT64_C(0xdc5c5301, c56b75f7), 873, 282},
+  {GRISU_UINT64_C(0xa81f3014, 49ee8c70), 890, 287},
+  {GRISU_UINT64_C(0x80444b5e, 7aa7cf85), 907, 292},
+  {GRISU_UINT64_C(0xc3b83581, 09e84f07), 923, 297},
+  {GRISU_UINT64_C(0x95527a52, 02df0ccb), 940, 302},
+  {GRISU_UINT64_C(0xe3d8f9e5, 63a198e5), 956, 307},
+  {GRISU_UINT64_C(0xadd57a27,