diff -r /Volumes/Swap/js-14-2-2008/js/src /Volumes/Swap/js_D11/src > /Volumes/Swap/jdiff.txt
Only in /Volumes/Swap/js-14-2-2008/js/src: .cvsignore
Only in /Volumes/Swap/js-14-2-2008/js/src: CVS
Only in /Volumes/Swap/js-14-2-2008/js/src: Makefile.in
Only in /Volumes/Swap/js-14-2-2008/js/src: Makefile.ref
Only in /Volumes/Swap/js-14-2-2008/js/src: README.html
Only in /Volumes/Swap/js-14-2-2008/js/src: SpiderMonkey.rsp
Only in /Volumes/Swap/js-14-2-2008/js/src: Y.js
Only in /Volumes/Swap/js_D11/src: _optimize.h
Only in /Volumes/Swap/js-14-2-2008/js/src: build.mk
Only in /Volumes/Swap/js-14-2-2008/js/src: config
Only in /Volumes/Swap/js-14-2-2008/js/src: config.mk
Only in /Volumes/Swap/js-14-2-2008/js/src: editline
Only in /Volumes/Swap/js-14-2-2008/js/src/fdlibm: .cvsignore
Only in /Volumes/Swap/js-14-2-2008/js/src/fdlibm: CVS
Only in /Volumes/Swap/js-14-2-2008/js/src/fdlibm: Makefile.in
Only in /Volumes/Swap/js-14-2-2008/js/src/fdlibm: Makefile.ref
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/e_acos.c /Volumes/Swap/js_D11/src/fdlibm/e_acos.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/e_acosh.c /Volumes/Swap/js_D11/src/fdlibm/e_acosh.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/e_asin.c /Volumes/Swap/js_D11/src/fdlibm/e_asin.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/e_atan2.c /Volumes/Swap/js_D11/src/fdlibm/e_atan2.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/e_atanh.c /Volumes/Swap/js_D11/src/fdlibm/e_atanh.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/e_cosh.c /Volumes/Swap/js_D11/src/fdlibm/e_cosh.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/e_exp.c /Volumes/Swap/js_D11/src/fdlibm/e_exp.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/e_fmod.c /Volumes/Swap/js_D11/src/fdlibm/e_fmod.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/e_gamma.c /Volumes/Swap/js_D11/src/fdlibm/e_gamma.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/e_gamma_r.c /Volumes/Swap/js_D11/src/fdlibm/e_gamma_r.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/e_hypot.c /Volumes/Swap/js_D11/src/fdlibm/e_hypot.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/e_j0.c /Volumes/Swap/js_D11/src/fdlibm/e_j0.c
3,4c3,6
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
6,14c8,11
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,24c16,19
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
26,36c21
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
---
>  * Contributor(s): 
38c23,33
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/e_j1.c /Volumes/Swap/js_D11/src/fdlibm/e_j1.c
3,4c3,6
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
6,14c8,11
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,24c16,19
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
26,36c21
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
---
>  * Contributor(s): 
38c23,33
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/e_jn.c /Volumes/Swap/js_D11/src/fdlibm/e_jn.c
3,4c3,6
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
6,14c8,11
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,24c16,19
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
26,36c21
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
---
>  * Contributor(s): 
38c23,33
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/e_lgamma.c /Volumes/Swap/js_D11/src/fdlibm/e_lgamma.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/e_lgamma_r.c /Volumes/Swap/js_D11/src/fdlibm/e_lgamma_r.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/e_log.c /Volumes/Swap/js_D11/src/fdlibm/e_log.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/e_log10.c /Volumes/Swap/js_D11/src/fdlibm/e_log10.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/e_pow.c /Volumes/Swap/js_D11/src/fdlibm/e_pow.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
99,103d93
< #if defined(_MSC_VER)
< /* Microsoft Compiler */
< #pragma warning( disable : 4723 ) /* disables potential divide by 0 warning */
< #endif
< 
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/e_rem_pio2.c /Volumes/Swap/js_D11/src/fdlibm/e_rem_pio2.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
129,130c124
<         double z = 0;
< 	double w,t,r,fn;
---
> 	double z,w,t,r,fn;
133a128,129
> 	z = 0; // 2003.09.09 jht : z not inited warning
> 	
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/e_remainder.c /Volumes/Swap/js_D11/src/fdlibm/e_remainder.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/e_scalb.c /Volumes/Swap/js_D11/src/fdlibm/e_scalb.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/e_sinh.c /Volumes/Swap/js_D11/src/fdlibm/e_sinh.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/e_sqrt.c /Volumes/Swap/js_D11/src/fdlibm/e_sqrt.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
61c56
<  *		sqrt(y) = 2^k * sqrt(x)
---
>  *		sqrt(x) = 2^k * sqrt(y)
123,127d117
< #if defined(_MSC_VER)
< /* Microsoft Compiler */
< #pragma warning( disable : 4723 ) /* disables potential divide by 0 warning */
< #endif
< 
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/fdlibm.h /Volumes/Swap/js_D11/src/fdlibm/fdlibm.h
3,4c3,6
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
6,14c8,11
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,24c16,19
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
26,36c21
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
---
>  * Contributor(s): 
38c23,33
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
64c59
< #if defined(linux) && (defined(__i386__) || defined(__x86_64__) || defined(__ia64) || (defined(__mips) && defined(__MIPSEL__)))
---
> #if defined(linux) && defined(__i386__)
70c65
< #ifdef SOLARIS	/* special setup for Sun test regime */
---
> #ifdef __NEWVALID	/* special setup for Sun test regime */
Only in /Volumes/Swap/js-14-2-2008/js/src/fdlibm: fdlibm.mak
Only in /Volumes/Swap/js-14-2-2008/js/src/fdlibm: fdlibm.mdp
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/k_cos.c /Volumes/Swap/js_D11/src/fdlibm/k_cos.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
110,111c105
<         double qx = 0;
< 	double a,hz,z,r;
---
> 	double a,hz,z,r,qx;
113a108
>         qx = 0; // 2003.09.09 jht: qx not init warning
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/k_rem_pio2.c /Volumes/Swap/js_D11/src/fdlibm/k_rem_pio2.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/k_sin.c /Volumes/Swap/js_D11/src/fdlibm/k_sin.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/k_standard.c /Volumes/Swap/js_D11/src/fdlibm/k_standard.c
3,4c3,6
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
6,14c8,11
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,24c16,19
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
26,36c21
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
---
>  * Contributor(s): 
38c23,33
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/k_tan.c /Volumes/Swap/js_D11/src/fdlibm/k_tan.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/s_asinh.c /Volumes/Swap/js_D11/src/fdlibm/s_asinh.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/s_atan.c /Volumes/Swap/js_D11/src/fdlibm/s_atan.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/s_cbrt.c /Volumes/Swap/js_D11/src/fdlibm/s_cbrt.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/s_ceil.c /Volumes/Swap/js_D11/src/fdlibm/s_ceil.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/s_copysign.c /Volumes/Swap/js_D11/src/fdlibm/s_copysign.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/s_cos.c /Volumes/Swap/js_D11/src/fdlibm/s_cos.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/s_erf.c /Volumes/Swap/js_D11/src/fdlibm/s_erf.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/s_expm1.c /Volumes/Swap/js_D11/src/fdlibm/s_expm1.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/s_fabs.c /Volumes/Swap/js_D11/src/fdlibm/s_fabs.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/s_finite.c /Volumes/Swap/js_D11/src/fdlibm/s_finite.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/s_floor.c /Volumes/Swap/js_D11/src/fdlibm/s_floor.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/s_frexp.c /Volumes/Swap/js_D11/src/fdlibm/s_frexp.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/s_ilogb.c /Volumes/Swap/js_D11/src/fdlibm/s_ilogb.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/s_isnan.c /Volumes/Swap/js_D11/src/fdlibm/s_isnan.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/s_ldexp.c /Volumes/Swap/js_D11/src/fdlibm/s_ldexp.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/s_lib_version.c /Volumes/Swap/js_D11/src/fdlibm/s_lib_version.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/s_log1p.c /Volumes/Swap/js_D11/src/fdlibm/s_log1p.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/s_logb.c /Volumes/Swap/js_D11/src/fdlibm/s_logb.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/s_matherr.c /Volumes/Swap/js_D11/src/fdlibm/s_matherr.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/s_modf.c /Volumes/Swap/js_D11/src/fdlibm/s_modf.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/s_nextafter.c /Volumes/Swap/js_D11/src/fdlibm/s_nextafter.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/s_rint.c /Volumes/Swap/js_D11/src/fdlibm/s_rint.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/s_scalbn.c /Volumes/Swap/js_D11/src/fdlibm/s_scalbn.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/s_signgam.c /Volumes/Swap/js_D11/src/fdlibm/s_signgam.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/s_significand.c /Volumes/Swap/js_D11/src/fdlibm/s_significand.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/s_sin.c /Volumes/Swap/js_D11/src/fdlibm/s_sin.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/s_tan.c /Volumes/Swap/js_D11/src/fdlibm/s_tan.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/s_tanh.c /Volumes/Swap/js_D11/src/fdlibm/s_tanh.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/w_acos.c /Volumes/Swap/js_D11/src/fdlibm/w_acos.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/w_acosh.c /Volumes/Swap/js_D11/src/fdlibm/w_acosh.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/w_asin.c /Volumes/Swap/js_D11/src/fdlibm/w_asin.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/w_atan2.c /Volumes/Swap/js_D11/src/fdlibm/w_atan2.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/w_atanh.c /Volumes/Swap/js_D11/src/fdlibm/w_atanh.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/w_cosh.c /Volumes/Swap/js_D11/src/fdlibm/w_cosh.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/w_exp.c /Volumes/Swap/js_D11/src/fdlibm/w_exp.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/w_fmod.c /Volumes/Swap/js_D11/src/fdlibm/w_fmod.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/w_gamma.c /Volumes/Swap/js_D11/src/fdlibm/w_gamma.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/w_gamma_r.c /Volumes/Swap/js_D11/src/fdlibm/w_gamma_r.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/w_hypot.c /Volumes/Swap/js_D11/src/fdlibm/w_hypot.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/w_j0.c /Volumes/Swap/js_D11/src/fdlibm/w_j0.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/w_j1.c /Volumes/Swap/js_D11/src/fdlibm/w_j1.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/w_jn.c /Volumes/Swap/js_D11/src/fdlibm/w_jn.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/w_lgamma.c /Volumes/Swap/js_D11/src/fdlibm/w_lgamma.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/w_lgamma_r.c /Volumes/Swap/js_D11/src/fdlibm/w_lgamma_r.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/w_log.c /Volumes/Swap/js_D11/src/fdlibm/w_log.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/w_log10.c /Volumes/Swap/js_D11/src/fdlibm/w_log10.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/w_pow.c /Volumes/Swap/js_D11/src/fdlibm/w_pow.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/w_remainder.c /Volumes/Swap/js_D11/src/fdlibm/w_remainder.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/w_scalb.c /Volumes/Swap/js_D11/src/fdlibm/w_scalb.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/w_sinh.c /Volumes/Swap/js_D11/src/fdlibm/w_sinh.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/fdlibm/w_sqrt.c /Volumes/Swap/js_D11/src/fdlibm/w_sqrt.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Sun Microsystems, Inc.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Sun Microsystems,
>  * Inc.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
Only in /Volumes/Swap/js-14-2-2008/js/src: javascript-trace.d
Only in /Volumes/Swap/js-14-2-2008/js/src: js.c
Only in /Volumes/Swap/js-14-2-2008/js/src: js.mak
Only in /Volumes/Swap/js-14-2-2008/js/src: js.mdp
diff -r /Volumes/Swap/js-14-2-2008/js/src/js.msg /Volumes/Swap/js_D11/src/js.msg
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
41,80c36,73
<  * This is the JavaScript error message file.
<  *
<  * The format for each JS error message is:
<  *
<  * MSG_DEF(<SYMBOLIC_NAME>, <ERROR_NUMBER>, <ARGUMENT_COUNT>, <EXCEPTION_NAME>,
<  *         <FORMAT_STRING>)
<  *
<  * where ;
<  * <SYMBOLIC_NAME> is a legal C identifer that will be used in the
<  * JS engine source.
<  *
<  * <ERROR_NUMBER> is an unique integral value identifying this error.
<  *
<  * <ARGUMENT_COUNT> is an integer literal specifying the total number of
<  * replaceable arguments in the following format string.
<  *
<  * <EXCEPTION_NAME> is an exception index from the enum in jsexn.c;
<  * JSEXN_NONE for none.  The given exception index will be raised by the
<  * engine when the corresponding error occurs.
<  *
<  * <FORMAT_STRING> is a string literal, optionally containing sequences
<  * {X} where X  is an integer representing the argument number that will
<  * be replaced with a string value when the error is reported.
<  *
<  * e.g.
<  *
<  * MSG_DEF(JSMSG_NOT_A_SUBSPECIES, 73, JSEXN_NONE, 2,
<  *         "{0} is not a member of the {1} family")
<  *
<  * can be used:
<  *
<  * JS_ReportErrorNumber(JSMSG_NOT_A_SUBSPECIES, "Rhino", "Monkey");
<  *
<  * to report:
<  *
<  * "Rhino is not a member of the Monkey family"
<  *
<  * Before adding a new MSG_DEF at the end, look for JSMSG_UNUSED<n> free
<  * index placeholders in the middle of the list.
<  */
---
> 	This is the JavaScript error message file.
> 
> 	The format for each JS error message is:
> 
> MSG_DEF(<SYMBOLIC_NAME>, <ERROR_NUMBER>, <ARGUMENT_COUNT>, <EXCEPTION_NAME>,
> 	<FORMAT_STRING>)
> 
> 	where ;
> 	<SYMBOLIC_NAME> is a legal C identifer that will be used in the
> 	JS engine source.
> 
> 	<ERROR_NUMBER> is an unique integral value identifying this error.
> 
> 	<ARGUMENT_COUNT> is an integer literal specifying the total number of
> 	replaceable arguments in the following format string.
> 
> 	<EXCEPTION_NAME> is an exception index from the enum in jsexn.c;
> 	JSEXN_NONE for none.  The given exception index will be raised by the
> 	engine when the corresponding error occurs.
> 
> 	<FORMAT_STRING> is a string literal, optionally containing sequences
> 	{X} where X  is an integer representing the argument number that will
> 	be replaced with a string value when the error is reported.
> 
> 	e.g.
> 
> 	MSG_DEF(JSMSG_NOT_A_SUBSPECIES, 73, JSEXN_NONE, 2,
> 		"{0} is not a member of the {1} family")
> 
> 	can be used :
> 
> 	JS_ReportErrorNumber(JSMSG_NOT_A_SUBSPECIES, "Rhino", "Monkey");
> 
> 	to report :
> 
> 	"Rhino is not a member of the Monkey family"
> 
> */
84,89c77,82
< MSG_DEF(JSMSG_INACTIVE,                 2, 0, JSEXN_INTERNALERR, "nothing active on context")
< MSG_DEF(JSMSG_MORE_ARGS_NEEDED,         3, 3, JSEXN_TYPEERR, "{0} requires more than {1} argument{2}")
< MSG_DEF(JSMSG_BAD_CHAR,                 4, 1, JSEXN_INTERNALERR, "invalid format character {0}")
< MSG_DEF(JSMSG_BAD_TYPE,                 5, 1, JSEXN_TYPEERR, "unknown type {0}")
< MSG_DEF(JSMSG_CANT_LOCK,                6, 0, JSEXN_INTERNALERR, "can't lock memory")
< MSG_DEF(JSMSG_CANT_UNLOCK,              7, 0, JSEXN_INTERNALERR, "can't unlock memory")
---
> MSG_DEF(JSMSG_NO_REG_EXPS,              2, 1, JSEXN_INTERNALERR, "sorry, regular expression are not supported")
> MSG_DEF(JSMSG_MORE_ARGS_NEEDED,         3, 3, JSEXN_NONE, "{0} requires more than {1} argument{2}")
> MSG_DEF(JSMSG_BAD_CHAR,                 4, 1, JSEXN_NONE, "invalid format character {0}")
> MSG_DEF(JSMSG_BAD_TYPE,                 5, 1, JSEXN_NONE, "unknown type {0}")
> MSG_DEF(JSMSG_CANT_LOCK,                6, 0, JSEXN_NONE, "can't lock memory")
> MSG_DEF(JSMSG_CANT_UNLOCK,              7, 0, JSEXN_NONE, "can't unlock memory")
91,93c84,86
< MSG_DEF(JSMSG_NO_CONSTRUCTOR,           9, 1, JSEXN_TYPEERR, "{0} has no constructor")
< MSG_DEF(JSMSG_CANT_ALIAS,              10, 3, JSEXN_TYPEERR, "can't alias {0} to {1} in class {2}")
< MSG_DEF(JSMSG_NOT_SCRIPTED_FUNCTION,   11, 1, JSEXN_TYPEERR, "{0} is not a scripted function")
---
> MSG_DEF(JSMSG_NO_CONSTRUCTOR,           9, 1, JSEXN_NONE, "{0} has no constructor")
> MSG_DEF(JSMSG_CANT_ALIAS,              10, 3, JSEXN_NONE, "can't alias {0} to {1} in class {2}")
> MSG_DEF(JSMSG_NO_PROTO,                11, 1, JSEXN_INTERNALERR, "sorry, Array.prototype.{0} is not yet implemented")
97c90
< MSG_DEF(JSMSG_CANT_WATCH,              15, 1, JSEXN_TYPEERR, "can't watch non-native objects of class {0}")
---
> MSG_DEF(JSMSG_CANT_WATCH,              15, 1, JSEXN_NONE, "can't watch non-native objects of class {0}")
100c93
< MSG_DEF(JSMSG_TOO_MANY_LOCAL_ROOTS,    18, 0, JSEXN_ERR, "out of local root space")
---
> MSG_DEF(JSMSG_UNUSED18,                18, 0, JSEXN_NONE, "<Error #18 is currently unused>")
103c96
< MSG_DEF(JSMSG_BAD_ITERATOR,            21, 3, JSEXN_TYPEERR, "{0} has invalid {1} value {2}")
---
> MSG_DEF(JSMSG_SAME_FORMAL,             21, 1, JSEXN_NONE, "duplicate formal argument {0}")
106,107c99,100
< MSG_DEF(JSMSG_SCRIPT_STACK_QUOTA,      24, 0, JSEXN_INTERNALERR, "script stack space quota is exhausted")
< MSG_DEF(JSMSG_NOT_EXPORTED,            25, 1, JSEXN_TYPEERR, "{0} is not exported")
---
> MSG_DEF(JSMSG_STACK_OVERFLOW,          24, 1, JSEXN_INTERNALERR, "stack overflow in {0}")
> MSG_DEF(JSMSG_NOT_EXPORTED,            25, 1, JSEXN_NONE, "{0} is not exported")
110c103
< MSG_DEF(JSMSG_BAD_NEW_RESULT,          28, 1, JSEXN_TYPEERR, "invalid new expression result {0}")
---
> MSG_DEF(JSMSG_BAD_NEW_RESULT,          28, 1, JSEXN_NONE, "invalid new expression result {0}")
116,117c109,110
< MSG_DEF(JSMSG_PAREN_BEFORE_LET,        34, 0, JSEXN_SYNTAXERR, "missing ( before let head")
< MSG_DEF(JSMSG_CANT_CONVERT,            35, 1, JSEXN_ERR, "can't convert {0} to an integer")
---
> MSG_DEF(JSMSG_NAN,                     34, 1, JSEXN_ERR, "{0} is not a number")
> MSG_DEF(JSMSG_CANT_CONVERT,            35, 1, JSEXN_NONE, "can't convert {0} to an integer")
119c112
< MSG_DEF(JSMSG_COMPILE_EXECED_SCRIPT,   37, 0, JSEXN_TYPEERR, "cannot compile over a script that is currently executing")
---
> MSG_DEF(JSMSG_PERMANENT,               37, 1, JSEXN_ERR, "{0} is permanent")
122,123c115,116
< MSG_DEF(JSMSG_CANT_FIND_CLASS,         40, 1, JSEXN_TYPEERR, "can't find class id {0}")
< MSG_DEF(JSMSG_CANT_XDR_CLASS,          41, 1, JSEXN_TYPEERR, "can't XDR class {0}")
---
> MSG_DEF(JSMSG_CANT_FIND_CLASS,         40, 1, JSEXN_NONE, "can't find class id {0}")
> MSG_DEF(JSMSG_CANT_XDR_CLASS,          41, 1, JSEXN_NONE, "can't XDR class {0}")
132,136c125,129
< MSG_DEF(JSMSG_BAD_DESTRUCT_DECL,       50, 0, JSEXN_SYNTAXERR, "missing = in destructuring declaration")
< MSG_DEF(JSMSG_BAD_DESTRUCT_ASS,        51, 0, JSEXN_SYNTAXERR, "invalid destructuring assignment operator")
< MSG_DEF(JSMSG_PAREN_AFTER_LET,         52, 0, JSEXN_SYNTAXERR, "missing ) after let head")
< MSG_DEF(JSMSG_CURLY_AFTER_LET,         53, 0, JSEXN_SYNTAXERR, "missing } after let block")
< MSG_DEF(JSMSG_MISSING_PAREN,           54, 0, JSEXN_SYNTAXERR, "unterminated parenthetical")
---
> MSG_DEF(JSMSG_ZERO_QUANTIFIER,         50, 1, JSEXN_SYNTAXERR, "zero quantifier {0}")
> MSG_DEF(JSMSG_UNTERM_QUANTIFIER,       51, 1, JSEXN_SYNTAXERR, "unterminated quantifier {0}")
> MSG_DEF(JSMSG_EMPTY_BEFORE_STAR,       52, 0, JSEXN_SYNTAXERR, "regular expression before * could be empty")
> MSG_DEF(JSMSG_EMPTY_BEFORE_PLUS,       53, 0, JSEXN_SYNTAXERR, "regular expression before + could be empty")
> MSG_DEF(JSMSG_MISSING_PAREN,           54, 1, JSEXN_SYNTAXERR, "unterminated parenthetical {0}")
141,142c134,135
< MSG_DEF(JSMSG_NO_INPUT,                59, 5, JSEXN_SYNTAXERR, "no input for /{0}/{1}{2}{3}{4}")
< MSG_DEF(JSMSG_CANT_OPEN,               60, 2, JSEXN_ERR, "can't open {0}: {1}")
---
> MSG_DEF(JSMSG_NO_INPUT,                59, 3, JSEXN_SYNTAXERR, "no input for /{0}/{1}{2}")
> MSG_DEF(JSMSG_CANT_OPEN,               60, 2, JSEXN_NONE, "can't open {0}: {1}")
144,150c137,143
< MSG_DEF(JSMSG_UNMATCHED_RIGHT_PAREN,   62, 0, JSEXN_SYNTAXERR, "unmatched ) in regular expression")
< MSG_DEF(JSMSG_END_OF_DATA,             63, 0, JSEXN_INTERNALERR, "unexpected end of data")
< MSG_DEF(JSMSG_SEEK_BEYOND_START,       64, 0, JSEXN_INTERNALERR, "illegal seek beyond start")
< MSG_DEF(JSMSG_SEEK_BEYOND_END,         65, 0, JSEXN_INTERNALERR, "illegal seek beyond end")
< MSG_DEF(JSMSG_END_SEEK,                66, 0, JSEXN_INTERNALERR, "illegal end-based seek")
< MSG_DEF(JSMSG_WHITHER_WHENCE,          67, 1, JSEXN_INTERNALERR, "unknown seek whence: {0}")
< MSG_DEF(JSMSG_BAD_SCRIPT_MAGIC,        68, 0, JSEXN_INTERNALERR, "bad script XDR magic number")
---
> MSG_DEF(JSMSG_NO_STRING_PROTO,         62, 1, JSEXN_INTERNALERR, "sorry, String.prototype.{0} is not yet implemented")
> MSG_DEF(JSMSG_END_OF_DATA,             63, 0, JSEXN_NONE, "unexpected end of data")
> MSG_DEF(JSMSG_SEEK_BEYOND_START,       64, 0, JSEXN_NONE, "illegal seek beyond start")
> MSG_DEF(JSMSG_SEEK_BEYOND_END,         65, 0, JSEXN_NONE, "illegal seek beyond end")
> MSG_DEF(JSMSG_END_SEEK,                66, 0, JSEXN_NONE, "illegal end-based seek")
> MSG_DEF(JSMSG_WHITHER_WHENCE,          67, 1, JSEXN_NONE, "unknown seek whence: {0}")
> MSG_DEF(JSMSG_BAD_SCRIPT_MAGIC,        68, 0, JSEXN_NONE, "bad script XDR magic number")
194c187
< MSG_DEF(JSMSG_EQUAL_AS_ASSIGN,        112, 1, JSEXN_SYNTAXERR, "test for equality (==) mistyped as assignment (=)?{0}")
---
> MSG_DEF(JSMSG_EQUAL_AS_ASSIGN,        112, 1, JSEXN_NONE, "test for equality (==) mistyped as assignment (=)?{0}")
204,206c197,199
< MSG_DEF(JSMSG_TOUGH_BREAK,            122, 0, JSEXN_SYNTAXERR, "unlabeled break must be inside loop or switch")
< MSG_DEF(JSMSG_BAD_CONTINUE,           123, 0, JSEXN_SYNTAXERR, "continue must be inside loop")
< MSG_DEF(JSMSG_BAD_RETURN_OR_YIELD,    124, 1, JSEXN_SYNTAXERR, "{0} not in function")
---
> MSG_DEF(JSMSG_TOUGH_BREAK,            122, 0, JSEXN_SYNTAXERR, "invalid break")
> MSG_DEF(JSMSG_BAD_CONTINUE,           123, 0, JSEXN_SYNTAXERR, "invalid continue")
> MSG_DEF(JSMSG_BAD_RETURN,             124, 0, JSEXN_SYNTAXERR, "invalid return")
209c202
< MSG_DEF(JSMSG_VAR_HIDES_ARG,          127, 1, JSEXN_TYPEERR, "variable {0} redeclares argument")
---
> MSG_DEF(JSMSG_VAR_HIDES_ARG,          127, 1, JSEXN_TYPEERR, "variable {0} hides argument")
221c214
< MSG_DEF(JSMSG_TOO_MANY_PARENS,        139, 0, JSEXN_INTERNALERR, "too many parentheses in regular expression")
---
> MSG_DEF(JSMSG_UNUSED139,              139, 0, JSEXN_NONE, "<Error #139 is currently unused>")
227,229c220,222
< MSG_DEF(JSMSG_BAD_OCTAL,              145, 1, JSEXN_SYNTAXERR, "{0} is not a legal ECMA-262 octal constant")
< MSG_DEF(JSMSG_BAD_INDIRECT_CALL,      146, 1, JSEXN_EVALERR, "function {0} must be called directly, and not by way of a function of another name")
< MSG_DEF(JSMSG_UNCAUGHT_EXCEPTION,     147, 1, JSEXN_INTERNALERR, "uncaught exception: {0}")
---
> MSG_DEF(JSMSG_BAD_OCTAL,              145, 1, JSEXN_NONE, "{0} is not a legal ECMA-262 octal constant")
> MSG_DEF(JSMSG_BAD_INDIRECT_CALL,      146, 1, JSEXN_EVALERR, "function {0} must be called directly, and not by way of a function of another name.")
> MSG_DEF(JSMSG_UNCAUGHT_EXCEPTION,     147, 1, JSEXN_NONE, "uncaught exception: {0}")
235,236c228,229
< MSG_DEF(JSMSG_CANT_DESCRIBE_PROPS,    153, 1, JSEXN_TYPEERR, "can't describe non-native properties of class {0}")
< MSG_DEF(JSMSG_BAD_APPLY_ARGS,         154, 1, JSEXN_TYPEERR, "second argument to Function.prototype.{0} must be an array")
---
> MSG_DEF(JSMSG_CANT_DESCRIBE_PROPS,    153, 1, JSEXN_NONE, "can't describe non-native properties of class {0}")
> MSG_DEF(JSMSG_BAD_APPLY_ARGS,         154, 0, JSEXN_TYPEERR, "second argument to Function.prototype.apply must be an array")
244c237
< MSG_DEF(JSMSG_UNDEFINED_PROP,         162, 1, JSEXN_REFERENCEERR, "reference to undefined property {0}")
---
> MSG_DEF(JSMSG_UNDEFINED_PROP,         162, 1, JSEXN_TYPEERR, "reference to undefined property {0}")
251,306c244,245
< MSG_DEF(JSMSG_TOO_MANY_CATCH_VARS,    169, 0, JSEXN_SYNTAXERR, "too many catch variables")
< MSG_DEF(JSMSG_BAD_XML_MARKUP,         170, 0, JSEXN_SYNTAXERR, "invalid XML markup")
< MSG_DEF(JSMSG_BAD_XML_CHARACTER,      171, 0, JSEXN_SYNTAXERR, "illegal XML character")
< MSG_DEF(JSMSG_BAD_DEFAULT_XML_NAMESPACE,172,0,JSEXN_SYNTAXERR, "invalid default XML namespace")
< MSG_DEF(JSMSG_BAD_XML_NAME_SYNTAX,    173, 0, JSEXN_SYNTAXERR, "invalid XML name")
< MSG_DEF(JSMSG_BRACKET_AFTER_ATTR_EXPR,174, 0, JSEXN_SYNTAXERR, "missing ] after attribute expression")
< MSG_DEF(JSMSG_NESTING_GENERATOR,      175, 1, JSEXN_TYPEERR, "already executing generator {0}")
< MSG_DEF(JSMSG_CURLY_IN_XML_EXPR,      176, 0, JSEXN_SYNTAXERR, "missing } in XML expression")
< MSG_DEF(JSMSG_BAD_XML_NAMESPACE,      177, 1, JSEXN_TYPEERR, "invalid XML namespace {0}")
< MSG_DEF(JSMSG_BAD_XML_ATTR_NAME,      178, 1, JSEXN_TYPEERR, "invalid XML attribute name {0}")
< MSG_DEF(JSMSG_BAD_XML_NAME,           179, 1, JSEXN_TYPEERR, "invalid XML name {0}")
< MSG_DEF(JSMSG_BAD_XML_CONVERSION,     180, 1, JSEXN_TYPEERR, "can't convert {0} to XML")
< MSG_DEF(JSMSG_BAD_XMLLIST_CONVERSION, 181, 1, JSEXN_TYPEERR, "can't convert {0} to XMLList")
< MSG_DEF(JSMSG_BAD_GENERATOR_SEND,     182, 1, JSEXN_TYPEERR, "attempt to send {0} to newborn generator")
< MSG_DEF(JSMSG_NO_ASSIGN_IN_XML_ATTR,  183, 0, JSEXN_SYNTAXERR, "missing = in XML attribute")
< MSG_DEF(JSMSG_BAD_XML_ATTR_VALUE,     184, 0, JSEXN_SYNTAXERR, "invalid XML attribute value")
< MSG_DEF(JSMSG_XML_TAG_NAME_MISMATCH,  185, 1, JSEXN_SYNTAXERR, "XML tag name mismatch (expected {0})")
< MSG_DEF(JSMSG_BAD_XML_TAG_SYNTAX,     186, 0, JSEXN_SYNTAXERR, "invalid XML tag syntax")
< MSG_DEF(JSMSG_BAD_XML_LIST_SYNTAX,    187, 0, JSEXN_SYNTAXERR, "invalid XML list syntax")
< MSG_DEF(JSMSG_INCOMPATIBLE_METHOD,    188, 3, JSEXN_TYPEERR, "{0} {1} called on incompatible {2}")
< MSG_DEF(JSMSG_CANT_SET_XML_ATTRS,     189, 0, JSEXN_INTERNALERR, "can't set XML property attributes")
< MSG_DEF(JSMSG_END_OF_XML_SOURCE,      190, 0, JSEXN_SYNTAXERR, "unexpected end of XML source")
< MSG_DEF(JSMSG_END_OF_XML_ENTITY,      191, 0, JSEXN_SYNTAXERR, "unexpected end of XML entity")
< MSG_DEF(JSMSG_BAD_XML_QNAME,          192, 0, JSEXN_SYNTAXERR, "invalid XML qualified name")
< MSG_DEF(JSMSG_BAD_FOR_EACH_LOOP,      193, 0, JSEXN_SYNTAXERR, "invalid for each loop")
< MSG_DEF(JSMSG_BAD_XMLLIST_PUT,        194, 1, JSEXN_TYPEERR, "can't set property {0} in XMLList")
< MSG_DEF(JSMSG_UNKNOWN_XML_ENTITY,     195, 1, JSEXN_TYPEERR, "unknown XML entity {0}")
< MSG_DEF(JSMSG_BAD_XML_NCR,            196, 1, JSEXN_TYPEERR, "malformed XML character {0}")
< MSG_DEF(JSMSG_UNDEFINED_XML_NAME,     197, 1, JSEXN_REFERENCEERR, "reference to undefined XML name {0}")
< MSG_DEF(JSMSG_DUPLICATE_XML_ATTR,     198, 1, JSEXN_TYPEERR, "duplicate XML attribute {0}")
< MSG_DEF(JSMSG_TOO_MANY_FUN_VARS,      199, 0, JSEXN_SYNTAXERR, "too many local variables")
< MSG_DEF(JSMSG_ARRAY_INIT_TOO_BIG,     200, 0, JSEXN_INTERNALERR, "array initialiser too large")
< MSG_DEF(JSMSG_REGEXP_TOO_COMPLEX,     201, 0, JSEXN_INTERNALERR, "regular expression too complex")
< MSG_DEF(JSMSG_BUFFER_TOO_SMALL,       202, 0, JSEXN_INTERNALERR, "buffer too small")
< MSG_DEF(JSMSG_BAD_SURROGATE_CHAR,     203, 1, JSEXN_TYPEERR, "bad surrogate character {0}")
< MSG_DEF(JSMSG_UTF8_CHAR_TOO_LARGE,    204, 1, JSEXN_TYPEERR, "UTF-8 character {0} too large")
< MSG_DEF(JSMSG_MALFORMED_UTF8_CHAR,    205, 1, JSEXN_TYPEERR, "malformed UTF-8 character sequence at offset {0}")
< MSG_DEF(JSMSG_USER_DEFINED_ERROR,     206, 0, JSEXN_ERR, "JS_ReportError was called")
< MSG_DEF(JSMSG_WRONG_CONSTRUCTOR,      207, 1, JSEXN_TYPEERR, "wrong constructor called for {0}")
< MSG_DEF(JSMSG_BAD_GENERATOR_RETURN,   208, 1, JSEXN_TYPEERR, "generator function {0} returns a value")
< MSG_DEF(JSMSG_BAD_ANON_GENERATOR_RETURN, 209, 0, JSEXN_TYPEERR, "anonymous generator function returns a value")
< MSG_DEF(JSMSG_NAME_AFTER_FOR_PAREN,   210, 0, JSEXN_SYNTAXERR, "missing name after for (")
< MSG_DEF(JSMSG_IN_AFTER_FOR_NAME,      211, 0, JSEXN_SYNTAXERR, "missing in after for")
< MSG_DEF(JSMSG_BAD_ITERATOR_RETURN,    212, 2, JSEXN_TYPEERR, "{0}.{1} returned a primitive value")
< MSG_DEF(JSMSG_KEYWORD_NOT_NS,         213, 0, JSEXN_SYNTAXERR, "keyword is used as namespace")
< MSG_DEF(JSMSG_BAD_GENERATOR_YIELD,    214, 1, JSEXN_TYPEERR, "yield from closing generator {0}")
< MSG_DEF(JSMSG_BAD_GENERATOR_SYNTAX,   215, 1, JSEXN_SYNTAXERR, "{0} expression must be parenthesized")
< MSG_DEF(JSMSG_ARRAY_COMP_LEFTSIDE,    216, 0, JSEXN_SYNTAXERR, "invalid array comprehension left-hand side")
< MSG_DEF(JSMSG_NON_XML_FILTER,         217, 1, JSEXN_TYPEERR, "XML filter is applied to non-XML value {0}")
< MSG_DEF(JSMSG_EMPTY_ARRAY_REDUCE,     218, 0, JSEXN_TYPEERR, "reduce of empty array with no initial value")
< MSG_DEF(JSMSG_NON_LIST_XML_METHOD,    219, 2, JSEXN_TYPEERR, "cannot call {0} method on an XML list with {1} elements")
< MSG_DEF(JSMSG_BAD_DELETE_OPERAND,     220, 0, JSEXN_SYNTAXERR, "invalid delete operand")
< MSG_DEF(JSMSG_BAD_INCOP_OPERAND,      221, 0, JSEXN_SYNTAXERR, "invalid increment/decrement operand")
< MSG_DEF(JSMSG_NULL_OR_UNDEFINED,      222, 2, JSEXN_TYPEERR, "{0} is {1}")
< MSG_DEF(JSMSG_LET_DECL_NOT_IN_BLOCK,  223, 0, JSEXN_SYNTAXERR, "let declaration not directly within block")
< MSG_DEF(JSMSG_BAD_OBJECT_INIT,        224, 0, JSEXN_SYNTAXERR, "invalid object initializer")
---
> MSG_DEF(JSMSG_CANT_UNSEAL_OBJECT,     169, 1, JSEXN_ERR, "can't unseal {0} objects")
> MSG_DEF(JSMSG_HOST_ERROR,     		  170, 0, JSEXN_ERR, "other")	// !!dp
Only in /Volumes/Swap/js-14-2-2008/js/src: js.pkg
Only in /Volumes/Swap/js-14-2-2008/js/src: js3240.rc
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsOS240.def /Volumes/Swap/js_D11/src/jsOS240.def
1,12c1,9
< ; ***** BEGIN LICENSE BLOCK *****
< ; Version: MPL 1.1/GPL 2.0/LGPL 2.1
< ;
< ; The contents of this file are subject to the Mozilla Public License Version
< ; 1.1 (the "License"); you may not use this file except in compliance with
< ; the License. You may obtain a copy of the License at
< ; http://www.mozilla.org/MPL/
< ;
< ; Software distributed under the License is distributed on an "AS IS" basis,
< ; WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
< ; for the specific language governing rights and limitations under the
< ; License.
---
> ; The contents of this file are subject to the Netscape Public
> ; License Version 1.1 (the "License"); you may not use this file
> ; except in compliance with the License. You may obtain a copy of
> ; the License at http://www.mozilla.org/NPL/
> ;
> ; Software distributed under the License is distributed on an "AS
> ; IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
> ; implied. See the License for the specific language governing
> ; rights and limitations under the License.
17,36c14,30
< ; The Initial Developer of the Original Code is
< ; Netscape Communications Corporation.
< ; Portions created by the Initial Developer are Copyright (C) 1998
< ; the Initial Developer. All Rights Reserved.
< ;
< ; Contributor(s):
< ;
< ; Alternatively, the contents of this file may be used under the terms of
< ; either of the GNU General Public License Version 2 or later (the "GPL"),
< ; or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
< ; in which case the provisions of the GPL or the LGPL are applicable instead
< ; of those above. If you wish to allow use of your version of this file only
< ; under the terms of either the GPL or the LGPL, and not to allow others to
< ; use your version of this file under the terms of the MPL, indicate your
< ; decision by deleting the provisions above and replace them with the notice
< ; and other provisions required by the GPL or the LGPL. If you do not delete
< ; the provisions above, a recipient may use your version of this file under
< ; the terms of any one of the MPL, the GPL or the LGPL.
< ;
< ; ***** END LICENSE BLOCK *****
---
> ; The Initial Developer of the Original Code is Netscape
> ; Communications Corporation.  Portions created by Netscape are
> ; Copyright (C) 1998 Netscape Communications Corporation. All
> ; Rights Reserved.
> ;
> ; Contributor(s): 
> ;
> ; Alternatively, the contents of this file may be used under the
> ; terms of the GNU Public License (the "GPL"), in which case the
> ; provisions of the GPL are applicable instead of those above.
> ; If you wish to allow use of your version of this file only
> ; under the terms of the GPL and not to allow others to use your
> ; version of this file under the NPL, indicate your decision by
> ; deleting the provisions above and replace them with the notice
> ; and other provisions required by the GPL.  If you do not delete
> ; the provisions above, a recipient may use your version of this
> ; file under either the NPL or the GPL.
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsapi.c /Volumes/Swap/js_D11/src/jsapi.c
2d1
<  * vim: set ts=8 sw=4 et tw=78:
4,5c3,6
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
7,15c8,11
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
20,23c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
27,39c23,33
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
47c41
< #include <stdlib.h>
---
> #include "xstdlib.h"
68d61
< #include "jsiter.h"
86,89d78
< #if JS_HAS_XML_SUPPORT
< #include "jsxml.h"
< #endif
< 
91c80
< #define JS_ADDRESSOF_VA_LIST(ap) ((va_list *)(ap))
---
> #define JS_ADDRESSOF_VA_LIST(ap) (ap)
96,98c85,86
< #if defined(JS_THREADSAFE)
< #define CHECK_REQUEST(cx)                                                   \
<     JS_ASSERT((cx)->requestDepth || (cx)->thread == (cx)->runtime->gcThread)
---
> #if defined(JS_PARANOID_REQUEST) && defined(JS_THREADSAFE)
> #define CHECK_REQUEST(cx)       JS_ASSERT(cx->requestDepth)
102a91,92
> //#include "_optimize.h"
> 
188c178
<                 fun = js_ValueToFunction(cx, &argv[-2], 0);
---
>                 fun = js_ValueToFunction(cx, &argv[-2], JS_FALSE);
203c193,194
<             *va_arg(ap, JSBool *) = js_ValueToBoolean(*sp);
---
>             if (!js_ValueToBoolean(cx, *sp, va_arg(ap, JSBool *)))
>                 return JS_FALSE;
237,247c228,232
<             if (c == 's') {
<                 const char *bytes = js_GetStringBytes(cx, str);
<                 if (!bytes)
<                     return JS_FALSE;
<                 *va_arg(ap, const char **) = bytes;
<             } else if (c == 'W') {
<                 const jschar *chars = js_GetStringChars(cx, str);
<                 if (!chars)
<                     return JS_FALSE;
<                 *va_arg(ap, const jschar **) = chars;
<             } else {
---
>             if (c == 's')
>                 *va_arg(ap, char **) = JS_GetStringBytes(str);
>             else if (c == 'W')
>                 *va_arg(ap, jschar **) = JS_GetStringChars(str);
>             else
249d233
<             }
258,259c242,243
<             obj = js_ValueToFunctionObject(cx, sp, 0);
<             if (!obj)
---
>             fun = js_ValueToFunction(cx, sp, JS_FALSE);
>             if (!fun)
261,262c245,246
<             *sp = OBJECT_TO_JSVAL(obj);
<             *va_arg(ap, JSFunction **) = (JSFunction *) JS_GetPrivate(cx, obj);
---
>             *sp = OBJECT_TO_JSVAL(fun->object);
>             *va_arg(ap, JSFunction **) = fun;
428a413
> 	XMEMTAG("JS_AddArgumentFormatter");
462c447
<     JSBool ok;
---
>     JSBool ok, b;
463a449
>     JSFunction *fun;
479,481c465,468
<         *vp = v;
<         obj = js_ValueToFunctionObject(cx, vp, JSV2F_SEARCH_STACK);
<         ok = (obj != NULL);
---
>         fun = js_ValueToFunction(cx, &v, JS_FALSE);
>         ok = (fun != NULL);
>         if (ok)
>             *vp = OBJECT_TO_JSVAL(fun->object);
492c479
<             dp = js_NewDouble(cx, d, 0);
---
>             dp = js_NewDouble(cx, d);
499,500c486,489
<         *vp = js_ValueToBoolean(v);
<         return JS_TRUE;
---
>         ok = js_ValueToBoolean(cx, v, &b);
>         if (ok)
>             *vp = BOOLEAN_TO_JSVAL(b);
>         break;
524c513
<     return js_ValueToFunction(cx, &v, JSV2F_SEARCH_STACK);
---
>     return js_ValueToFunction(cx, &v, JS_FALSE);
531c520
<     return js_ValueToFunction(cx, &v, JSV2F_SEARCH_STACK);
---
>     return js_ValueToFunction(cx, &v, JS_TRUE);
580,581c569
<     *bp = js_ValueToBoolean(v);
<     return JS_TRUE;
---
>     return js_ValueToBoolean(cx, v, bp);
594c582
<         type = JSTYPE_OBJECT;           /* XXXbe JSTYPE_NULL for JS2 */
---
>         /* XXX JSVAL_IS_OBJECT(v) is true for null too! Can we change ECMA? */
596,629c584,592
<         if (obj) {
<             ops = obj->map->ops;
< #if JS_HAS_XML_SUPPORT
<             if (ops == &js_XMLObjectOps.base) {
<                 type = JSTYPE_XML;
<             } else
< #endif
<             {
<                 /*
<                  * ECMA 262, 11.4.3 says that any native object that implements
<                  * [[Call]] should be of type "function". Note that RegExp and
<                  * Script are both of type "function" for compatibility with
<                  * older SpiderMonkeys.
<                  */
<                 clasp = OBJ_GET_CLASS(cx, obj);
<                 if ((ops == &js_ObjectOps)
<                     ? (clasp->call
<                        ? clasp == &js_ScriptClass
<                        : clasp == &js_FunctionClass)
<                     : ops->call != NULL) {
<                     type = JSTYPE_FUNCTION;
<                 } else {
< #ifdef NARCISSUS
<                     if (!OBJ_GET_PROPERTY(cx, obj,
<                                           ATOM_TO_JSID(cx->runtime->atomState
<                                                        .callAtom),
<                                           &v)) {
<                         JS_ClearPendingException(cx);
<                     } else if (VALUE_IS_FUNCTION(cx, v)) {
<                         type = JSTYPE_FUNCTION;
<                     }
< #endif
<                 }
<             }
---
>         if (obj &&
>             (ops = obj->map->ops,
>              ops == &js_ObjectOps
>              ? (clasp = OBJ_GET_CLASS(cx, obj),
>                 clasp->call || clasp == &js_FunctionClass)
>              : ops->call != 0)) {
>             type = JSTYPE_FUNCTION;
>         } else {
>             type = JSTYPE_OBJECT;
648c611
<     return JS_TYPE_STR(type);
---
>     return js_type_str[type];
653,660c616
< /*
<  * Has a new runtime ever been created?  This flag is used to detect unsafe
<  * changes to js_CStringsAreUTF8 after a runtime has been created, and to
<  * ensure that "first checks" on runtime creation are run only once.
<  */
< #ifdef DEBUG
< static JSBool js_NewRuntimeWasCalled = JS_FALSE;
< #endif
---
> //LMemHookProcs *js_memHooks;		// !!dp
666c622
< 
---
> 	
668,676c624,632
<     if (!js_NewRuntimeWasCalled) {
<         /*
<          * This code asserts that the numbers associated with the error names
<          * in jsmsg.def are monotonically increasing.  It uses values for the
<          * error names enumerated in jscntxt.c.  It's not a compile-time check
<          * but it's better than nothing.
<          */
<         int errorNumber = 0;
< #define MSG_DEF(name, number, count, exception, format)                       \
---
>     JS_BEGIN_MACRO
>     /*
>      * This code asserts that the numbers associated with the error names in
>      * jsmsg.def are monotonically increasing.  It uses values for the error
>      * names enumerated in jscntxt.c.  It's not a compiletime check, but it's
>      * better than nothing.
>      */
>     int errorNumber = 0;
> #define MSG_DEF(name, number, count, exception, format) \
680,689d635
< 
< #define MSG_DEF(name, number, count, exception, format)                       \
<     JS_BEGIN_MACRO                                                            \
<         uintN numfmtspecs = 0;                                                \
<         const char *fmt;                                                      \
<         for (fmt = format; *fmt != '\0'; fmt++) {                             \
<             if (*fmt == '{' && isdigit(fmt[1]))                               \
<                 ++numfmtspecs;                                                \
<         }                                                                     \
<         JS_ASSERT(count == numfmtspecs);                                      \
691,695d636
< #include "js.msg"
< #undef MSG_DEF
< 
<         js_NewRuntimeWasCalled = JS_TRUE;
<     }
697,698c638,642
< 
<     rt = (JSRuntime *) malloc(sizeof(JSRuntime));
---
> 	
>     if (!js_InitStringGlobals())
>         return NULL;
>     XMEMTAG("JSRuntime");
>     rt = (JSRuntime *) xmalloc(sizeof(JSRuntime));
701,702d644
< 
<     /* Initialize infallibly first, so we can goto bad and JS_DestroyRuntime. */
704,707d645
<     JS_INIT_CLIST(&rt->contextList);
<     JS_INIT_CLIST(&rt->trapList);
<     JS_INIT_CLIST(&rt->watchPointList);
< 
710,713d647
<     if (!js_InitAtomState(rt))
<         goto bad;
<     if (!js_InitDeflatedStringCache(rt))
<         goto bad;
715,716d648
<     if (!js_InitThreadPrivateIndex(js_ThreadDestructorCB))
<         goto bad;
726,728c658
<     /* this is asymmetric with JS_ShutDown: */
<     if (!js_SetupLocks(8, 16))
<         goto bad;
---
>     js_SetupLocks(8, 16);       /* this is asymmetric with JS_ShutDown. */
734a665,670
>     rt->setSlotLock = JS_NEW_LOCK();
>     if (!rt->setSlotLock)
>         goto bad;
>     rt->setSlotDone = JS_NEW_CONDVAR(rt->setSlotLock);
>     if (!rt->setSlotDone)
>         goto bad;
739,741d674
<     rt->debuggerLock = JS_NEW_LOCK();
<     if (!rt->debuggerLock)
<         goto bad;
742a676
>     rt->propertyCache.empty = JS_TRUE;
744a679,681
>     JS_INIT_CLIST(&rt->contextList);
>     JS_INIT_CLIST(&rt->trapList);
>     JS_INIT_CLIST(&rt->watchPointList);
768,782c705
<     js_FreeRuntimeScriptState(rt);
<     js_FinishAtomState(rt);
< 
<     /*
<      * Free unit string storage only after all strings have been finalized, so
<      * that js_FinalizeString can detect unit strings and avoid calling free
<      * on their chars storage.
<      */
<     js_FinishUnitStrings(rt);
< 
<     /*
<      * Finish the deflated string cache after the last GC and after
<      * calling js_FinishAtomState, which finalizes strings.
<      */
<     js_FinishDeflatedStringCache(rt);
---
>     js_FinishAtomState(&rt->atomState);
794a718,721
>     if (rt->setSlotLock)
>         JS_DESTROY_LOCK(rt->setSlotLock);
>     if (rt->setSlotDone)
>         JS_DESTROY_CONDVAR(rt->setSlotDone);
797,800d723
<     if (rt->debuggerLock)
<         JS_DESTROY_LOCK(rt->debuggerLock);
< #else
<     GSN_CACHE_CLEAR(&rt->gsnCache);
803c726
<     free(rt);
---
>     xfree(rt);
809,815c732,733
< #ifdef JS_OPMETER
<     extern void js_DumpOpMeters();
< 
<     js_DumpOpMeters();
< #endif
< 
<     js_FinishDtoa();
---
>     JS_ArenaShutDown();
>     js_FreeStringGlobals();
817a736,737
> #else
>     js_FinishDtoa();
819d738
<     PRMJ_NowShutdown();
833a753,754
> #ifdef JS_THREADSAFE
> 
837d757
< #ifdef JS_THREADSAFE
840c760
<     JS_ASSERT(cx->thread->id == js_CurrentThreadId());
---
>     JS_ASSERT(cx->thread);
846c766
<         /* NB: we use cx->thread here, not js_GetCurrentThread(). */
---
>         /* NB: we use cx->thread here, not js_CurrentThreadId(). */
855d774
<         cx->outstandingRequests++;
860,861d778
<     cx->outstandingRequests++;
< #endif
867d783
< #ifdef JS_THREADSAFE
874d789
<     JS_ASSERT(cx->outstandingRequests > 0);
880d794
<         cx->outstandingRequests--;
897,898c811,812
<              * requires that the GC ran (e.g., from an operation callback)
<              * during this request, but possible.
---
>              * requires that the GC ran (e.g., from a branch callback) during
>              * this request, but possible.
903c817
<                 js_FinishSharingScope(cx, scope);   /* set ownercx = NULL */
---
>                 js_FinishSharingScope(rt, scope);   /* set ownercx = NULL */
921,922d834
<     cx->outstandingRequests--;
< #endif
929c841,842
< #ifdef JS_THREADSAFE
---
>     JSRuntime *rt;
> 
932,933c845,857
<     JS_ResumeRequest(cx, JS_SuspendRequest(cx));
< #endif
---
> 
>     rt = cx->runtime;
>     JS_LOCK_GC(rt);
>     JS_ASSERT(rt->requestCount > 0);
>     rt->requestCount--;
>     if (rt->requestCount == 0)
>         JS_NOTIFY_REQUEST_DONE(rt);
>     JS_UNLOCK_GC(rt);
>     /* XXXbe give the GC or another request calling it a chance to run here?
>              Assumes FIFO scheduling */
>     JS_LOCK_GC(rt);
>     rt->requestCount++;
>     JS_UNLOCK_GC(rt);
939d862
< #ifdef JS_THREADSAFE
942,943c865
<     while (cx->requestDepth) {
<         cx->outstandingRequests++;  /* compensate for JS_EndRequest */
---
>     while (cx->requestDepth)
945d866
<     }
947,949d867
< #else
<     return 0;
< #endif
955d872
< #ifdef JS_THREADSAFE
957c874
<     while (--saveDepth >= 0) {
---
>     while (--saveDepth >= 0)
959,961d875
<         cx->outstandingRequests--;  /* compensate for JS_BeginRequest */
<     }
< #endif
963a878,879
> #endif /* JS_THREADSAFE */
> 
976,985d891
< JS_PUBLIC_API(JSContextCallback)
< JS_SetContextCallback(JSRuntime *rt, JSContextCallback cxCallback)
< {
<     JSContextCallback old;
< 
<     old = rt->cxCallback;
<     rt->cxCallback = cxCallback;
<     return old;
< }
< 
995c901
<     js_DestroyContext(cx, JSDCM_FORCE_GC);
---
>     js_DestroyContext(cx, JS_FORCE_GC);
1001c907
<     js_DestroyContext(cx, JSDCM_NO_GC);
---
>     js_DestroyContext(cx, JS_NO_GC);
1007c913
<     js_DestroyContext(cx, JSDCM_MAYBE_GC);
---
>     js_DestroyContext(cx, JS_MAYBE_GC);
1037c943
<     return JSVERSION_NUMBER(cx);
---
>     return cx->version;
1045,1048c951
<     JS_ASSERT(version != JSVERSION_UNKNOWN);
<     JS_ASSERT((version & ~JSVERSION_MASK) == 0);
< 
<     oldVersion = JSVERSION_NUMBER(cx);
---
>     oldVersion = cx->version;
1052,1054c955,965
<     /* We no longer support 1.4 or below. */
<     if (version != JSVERSION_DEFAULT && version <= JSVERSION_1_4)
<         return oldVersion;
---
>     cx->version = version;
> 
> #if !JS_BUG_FALLIBLE_EQOPS
>     if (cx->version == JSVERSION_1_2) {
>         cx->jsop_eq = JSOP_NEW_EQ;
>         cx->jsop_ne = JSOP_NEW_NE;
>     } else {
>         cx->jsop_eq = JSOP_EQ;
>         cx->jsop_ne = JSOP_NE;
>     }
> #endif /* !JS_BUG_FALLIBLE_EQOPS */
1056,1057d966
<     cx->version = (cx->version & ~JSVERSION_MASK) | version;
<     js_OnVersionChange(cx);
1070d978
<     {JSVERSION_ECMA_3,  "ECMAv3"},
1072,1075c980
<     {JSVERSION_1_6,     "1.6"},
<     {JSVERSION_1_7,     "1.7"},
<     {JSVERSION_1_8,     "1.8"},
<     {JSVERSION_DEFAULT, js_default_str},
---
>     {JSVERSION_DEFAULT, "default"},
1107,1114d1011
< #define SYNC_OPTIONS_TO_VERSION(cx)                                           \
<     JS_BEGIN_MACRO                                                            \
<         if ((cx)->options & JSOPTION_XML)                                     \
<             (cx)->version |= JSVERSION_HAS_XML;                               \
<         else                                                                  \
<             (cx)->version &= ~JSVERSION_HAS_XML;                              \
<     JS_END_MACRO
< 
1120d1016
<     SYNC_OPTIONS_TO_VERSION(cx);
1129d1024
<     SYNC_OPTIONS_TO_VERSION(cx);
1136c1031
<     return "JavaScript-C 1.8.0 pre-release 1 2007-10-03";
---
>     return "JavaScript-C 1.5 pre-release 5a 2003-05-29";
1150,1153d1044
< 
< #if JS_HAS_XML_SUPPORT
<     cx->xmlSettingFlags = 0;
< #endif
1156,1159c1047,1048
< JS_BEGIN_EXTERN_C
< 
< JSObject *
< js_InitFunctionAndObjectClasses(JSContext *cx, JSObject *obj)
---
> static JSObject *
> InitFunctionAndObjectClasses(JSContext *cx, JSObject *obj)
1161d1049
<     JSDHashTable *table;
1162a1051
>     JSDHashTable *table;
1165c1054
<     JSResolvingEntry *entry;
---
>     JSDHashEntryHdr *entry;
1170c1059
<         JS_SetGlobalObject(cx, obj);
---
>         cx->globalObject = obj;
1173,1176c1062,1063
<     table = cx->resolvingTable;
<     resolving = (table && table->entryCount);
<     rt = cx->runtime;
<     key.obj = obj;
---
>     resolving = (cx->resolving != 0);
>     table = NULL;       /* quell GCC overwarning */
1178,1187c1065,1073
<         key.id = ATOM_TO_JSID(rt->atomState.classAtoms[JSProto_Function]);
<         entry = (JSResolvingEntry *)
<                 JS_DHashTableOperate(table, &key, JS_DHASH_ADD);
<         if (entry && entry->key.obj && (entry->flags & JSRESFLAG_LOOKUP)) {
<             /* Already resolving Function, record Object too. */
<             JS_ASSERT(entry->key.obj == obj);
<             key.id = ATOM_TO_JSID(rt->atomState.classAtoms[JSProto_Object]);
<             entry = (JSResolvingEntry *)
<                     JS_DHashTableOperate(table, &key, JS_DHASH_ADD);
<         }
---
>         table = cx->resolvingTable;
>         rt = cx->runtime;
>         key.obj = obj;
>         key.id = (jsid) rt->atomState.FunctionAtom;
>         entry = JS_DHashTableOperate(table, &key, JS_DHASH_LOOKUP);
>         if (JS_DHASH_ENTRY_IS_BUSY(entry))
>             key.id = (jsid) rt->atomState.ObjectAtom;
> 
>         entry = JS_DHashTableOperate(table, &key, JS_DHASH_ADD);
1192,1207c1078
<         JS_ASSERT(!entry->key.obj && entry->flags == 0);
<         entry->key = key;
<         entry->flags = JSRESFLAG_LOOKUP;
<     } else {
<         key.id = ATOM_TO_JSID(rt->atomState.classAtoms[JSProto_Object]);
<         if (!js_StartResolving(cx, &key, JSRESFLAG_LOOKUP, &entry))
<             return NULL;
< 
<         key.id = ATOM_TO_JSID(rt->atomState.classAtoms[JSProto_Function]);
<         if (!js_StartResolving(cx, &key, JSRESFLAG_LOOKUP, &entry)) {
<             key.id = ATOM_TO_JSID(rt->atomState.classAtoms[JSProto_Object]);
<             JS_DHashTableOperate(table, &key, JS_DHASH_REMOVE);
<             return NULL;
<         }
< 
<         table = cx->resolvingTable;
---
>         ((JSResolvingEntry *)entry)->key = key;
1213c1084
<         goto out;
---
>         return NULL;
1217,1220c1088,1089
<     if (!obj_proto) {
<         fun_proto = NULL;
<         goto out;
<     }
---
>     if (!obj_proto)
>         return NULL;
1227d1095
< out:
1229,1234c1097
<     JS_DHashTableOperate(table, &key, JS_DHASH_REMOVE);
<     if (!resolving) {
<         /* If not resolving, remove the first entry added above, for Object. */
<         JS_ASSERT(key.id ==                                                   \
<                   ATOM_TO_JSID(rt->atomState.classAtoms[JSProto_Function]));
<         key.id = ATOM_TO_JSID(rt->atomState.classAtoms[JSProto_Object]);
---
>     if (resolving)
1236d1098
<     }
1240,1241d1101
< JS_END_EXTERN_C
< 
1245,1246d1104
<     JSAtom *atom;
< 
1248a1107,1108
> #if JS_HAS_UNDEFINED
> {
1250,1252c1110,1112
<     atom = cx->runtime->atomState.typeAtoms[JSTYPE_VOID];
<     if (!OBJ_DEFINE_PROPERTY(cx, obj, ATOM_TO_JSID(atom), JSVAL_VOID,
<                              NULL, NULL, JSPROP_PERMANENT, NULL)) {
---
>     JSAtom *atom = cx->runtime->atomState.typeAtoms[JSTYPE_VOID];
>     if (!OBJ_DEFINE_PROPERTY(cx, obj, (jsid)atom, JSVAL_VOID, NULL, NULL,
>                              JSPROP_PERMANENT, NULL)) {
1254a1115,1116
> }
> #endif
1257c1119
<     if (!js_InitFunctionAndObjectClasses(cx, obj))
---
>     if (!InitFunctionAndObjectClasses(cx, obj))
1262d1123
<            js_InitBlockClass(cx, obj) &&
1264,1265d1124
<            js_InitCallClass(cx, obj) &&
<            js_InitExceptionClasses(cx, obj) &&
1268d1126
<            js_InitRegExpClass(cx, obj) &&
1269a1128,1133
> #if JS_HAS_CALL_OBJECT
>            js_InitCallClass(cx, obj) &&
> #endif
> #if JS_HAS_REGEXPS
>            js_InitRegExpClass(cx, obj) &&
> #endif
1273,1274c1137,1138
< #if JS_HAS_XML_SUPPORT
<            js_InitXMLClasses(cx, obj) &&
---
> #if JS_HAS_ERROR_EXCEPTIONS
>            js_InitExceptionClasses(cx, obj) &&
1277,1280c1141
<            js_InitFileClass(cx, obj) &&
< #endif
< #if JS_HAS_GENERATORS
<            js_InitIteratorClasses(cx, obj) &&
---
>            js_InitFileClass(cx, obj, JS_TRUE) &&
1285,1289c1146,1178
< #define CLASP(name)                 ((JSClass *)&js_##name##Class)
< #define EAGER_ATOM(name)            ATOM_OFFSET(name), NULL
< #define EAGER_CLASS_ATOM(name)      CLASS_ATOM_OFFSET(name), NULL
< #define EAGER_ATOM_AND_CLASP(name)  EAGER_CLASS_ATOM(name), CLASP(name)
< #define LAZY_ATOM(name)             ATOM_OFFSET(lazy.name), js_##name##_str
---
> #define ATOM_OFFSET(name)       offsetof(JSAtomState, name##Atom)
> #define OFFSET_TO_ATOM(rt,off)  (*(JSAtom **)((char*)&(rt)->atomState + (off)))
> 
> /*
>  * Table of class initializers and their atom offsets in rt->atomState.
>  * If you add a "standard" class, remember to update this table.
>  */
> static struct {
>     JSObjectOp  init;
>     size_t      atomOffset;
> } standard_class_atoms[] = {
>     {InitFunctionAndObjectClasses,  ATOM_OFFSET(Function)},
>     {InitFunctionAndObjectClasses,  ATOM_OFFSET(Object)},
>     {js_InitArrayClass,             ATOM_OFFSET(Array)},
>     {js_InitBooleanClass,           ATOM_OFFSET(Boolean)},
>     {js_InitDateClass,              ATOM_OFFSET(Date)},
>     {js_InitMathClass,              ATOM_OFFSET(Math)},
>     {js_InitNumberClass,            ATOM_OFFSET(Number)},
>     {js_InitStringClass,            ATOM_OFFSET(String)},
> #if JS_HAS_CALL_OBJECT
>     {js_InitCallClass,              ATOM_OFFSET(Call)},
> #endif
> #if JS_HAS_ERROR_EXCEPTIONS
>     {js_InitExceptionClasses,       ATOM_OFFSET(Error)},
> #endif
> #if JS_HAS_REGEXPS
>     {js_InitRegExpClass,            ATOM_OFFSET(RegExp)},
> #endif
> #if JS_HAS_SCRIPT_OBJECT
>     {js_InitScriptClass,            ATOM_OFFSET(Script)},
> #endif
>     {NULL,                          0}
> };
1290a1180,1184
> /*
>  * Table of top-level function and constant names and their init functions.
>  * If you add a "standard" global function or property, remember to update
>  * this table.
>  */
1295d1188
<     JSClass     *clasp;
1317,1349c1210,1211
< /*
<  * Table of class initializers and their atom offsets in rt->atomState.
<  * If you add a "standard" class, remember to update this table.
<  */
< static JSStdName standard_class_atoms[] = {
<     {js_InitFunctionAndObjectClasses,   EAGER_ATOM_AND_CLASP(Function)},
<     {js_InitFunctionAndObjectClasses,   EAGER_ATOM_AND_CLASP(Object)},
<     {js_InitArrayClass,                 EAGER_ATOM_AND_CLASP(Array)},
<     {js_InitBlockClass,                 EAGER_ATOM_AND_CLASP(Block)},
<     {js_InitBooleanClass,               EAGER_ATOM_AND_CLASP(Boolean)},
<     {js_InitDateClass,                  EAGER_ATOM_AND_CLASP(Date)},
<     {js_InitMathClass,                  EAGER_ATOM_AND_CLASP(Math)},
<     {js_InitNumberClass,                EAGER_ATOM_AND_CLASP(Number)},
<     {js_InitStringClass,                EAGER_ATOM_AND_CLASP(String)},
<     {js_InitCallClass,                  EAGER_ATOM_AND_CLASP(Call)},
<     {js_InitExceptionClasses,           EAGER_ATOM_AND_CLASP(Error)},
<     {js_InitRegExpClass,                EAGER_ATOM_AND_CLASP(RegExp)},
< #if JS_HAS_SCRIPT_OBJECT
<     {js_InitScriptClass,                EAGER_ATOM_AND_CLASP(Script)},
< #endif
< #if JS_HAS_XML_SUPPORT
<     {js_InitXMLClass,                   EAGER_ATOM_AND_CLASP(XML)},
<     {js_InitNamespaceClass,             EAGER_ATOM_AND_CLASP(Namespace)},
<     {js_InitQNameClass,                 EAGER_ATOM_AND_CLASP(QName)},
< #endif
< #if JS_HAS_FILE_OBJECT
<     {js_InitFileClass,                  EAGER_ATOM_AND_CLASP(File)},
< #endif
< #if JS_HAS_GENERATORS
<     {js_InitIteratorClasses,            EAGER_ATOM_AND_CLASP(StopIteration)},
< #endif
<     {NULL,                              0, NULL, NULL}
< };
---
> #define EAGERLY_PINNED_ATOM(name)   ATOM_OFFSET(name), NULL
> #define LAZILY_PINNED_ATOM(name)    ATOM_OFFSET(lazy.name), js_##name##_str
1351,1355d1212
< /*
<  * Table of top-level function and constant names and their init functions.
<  * If you add a "standard" global function or property, remember to update
<  * this table.
<  */
1358c1215
<     {js_InitObjectClass,        EAGER_ATOM(eval), NULL},
---
>     {js_InitObjectClass,        EAGERLY_PINNED_ATOM(eval)},
1361,1366c1218,1223
<     {js_InitNumberClass,        LAZY_ATOM(NaN), NULL},
<     {js_InitNumberClass,        LAZY_ATOM(Infinity), NULL},
<     {js_InitNumberClass,        LAZY_ATOM(isNaN), NULL},
<     {js_InitNumberClass,        LAZY_ATOM(isFinite), NULL},
<     {js_InitNumberClass,        LAZY_ATOM(parseFloat), NULL},
<     {js_InitNumberClass,        LAZY_ATOM(parseInt), NULL},
---
>     {js_InitNumberClass,        LAZILY_PINNED_ATOM(NaN)},
>     {js_InitNumberClass,        LAZILY_PINNED_ATOM(Infinity)},
>     {js_InitNumberClass,        LAZILY_PINNED_ATOM(isNaN)},
>     {js_InitNumberClass,        LAZILY_PINNED_ATOM(isFinite)},
>     {js_InitNumberClass,        LAZILY_PINNED_ATOM(parseFloat)},
>     {js_InitNumberClass,        LAZILY_PINNED_ATOM(parseInt)},
1369,1374c1226,1234
<     {js_InitStringClass,        LAZY_ATOM(escape), NULL},
<     {js_InitStringClass,        LAZY_ATOM(unescape), NULL},
<     {js_InitStringClass,        LAZY_ATOM(decodeURI), NULL},
<     {js_InitStringClass,        LAZY_ATOM(encodeURI), NULL},
<     {js_InitStringClass,        LAZY_ATOM(decodeURIComponent), NULL},
<     {js_InitStringClass,        LAZY_ATOM(encodeURIComponent), NULL},
---
> #ifndef MOZILLA_CLIENT
>     /* These two are predefined in a backward-compatible way by the DOM. */
>     {js_InitStringClass,        LAZILY_PINNED_ATOM(escape)},
>     {js_InitStringClass,        LAZILY_PINNED_ATOM(unescape)},
> #endif
>     {js_InitStringClass,        LAZILY_PINNED_ATOM(decodeURI)},
>     {js_InitStringClass,        LAZILY_PINNED_ATOM(encodeURI)},
>     {js_InitStringClass,        LAZILY_PINNED_ATOM(decodeURIComponent)},
>     {js_InitStringClass,        LAZILY_PINNED_ATOM(encodeURIComponent)},
1376c1236
<     {js_InitStringClass,        LAZY_ATOM(uneval), NULL},
---
>     {js_InitStringClass,        LAZILY_PINNED_ATOM(uneval)},
1380,1398c1240,1248
<     {js_InitExceptionClasses,   EAGER_CLASS_ATOM(Error), CLASP(Error)},
<     {js_InitExceptionClasses,   EAGER_CLASS_ATOM(InternalError), CLASP(Error)},
<     {js_InitExceptionClasses,   EAGER_CLASS_ATOM(EvalError), CLASP(Error)},
<     {js_InitExceptionClasses,   EAGER_CLASS_ATOM(RangeError), CLASP(Error)},
<     {js_InitExceptionClasses,   EAGER_CLASS_ATOM(ReferenceError), CLASP(Error)},
<     {js_InitExceptionClasses,   EAGER_CLASS_ATOM(SyntaxError), CLASP(Error)},
<     {js_InitExceptionClasses,   EAGER_CLASS_ATOM(TypeError), CLASP(Error)},
<     {js_InitExceptionClasses,   EAGER_CLASS_ATOM(URIError), CLASP(Error)},
< 
< #if JS_HAS_XML_SUPPORT
<     {js_InitAnyNameClass,       EAGER_ATOM_AND_CLASP(AnyName)},
<     {js_InitAttributeNameClass, EAGER_ATOM_AND_CLASP(AttributeName)},
<     {js_InitXMLClass,           LAZY_ATOM(XMLList), &js_XMLClass},
<     {js_InitXMLClass,           LAZY_ATOM(isXMLName), NULL},
< #endif
< 
< #if JS_HAS_GENERATORS
<     {js_InitIteratorClasses,    EAGER_ATOM_AND_CLASP(Iterator)},
<     {js_InitIteratorClasses,    EAGER_ATOM_AND_CLASP(Generator)},
---
> #if JS_HAS_ERROR_EXCEPTIONS
>     {js_InitExceptionClasses,   EAGERLY_PINNED_ATOM(Error)},
>     {js_InitExceptionClasses,   LAZILY_PINNED_ATOM(InternalError)},
>     {js_InitExceptionClasses,   LAZILY_PINNED_ATOM(EvalError)},
>     {js_InitExceptionClasses,   LAZILY_PINNED_ATOM(RangeError)},
>     {js_InitExceptionClasses,   LAZILY_PINNED_ATOM(ReferenceError)},
>     {js_InitExceptionClasses,   LAZILY_PINNED_ATOM(SyntaxError)},
>     {js_InitExceptionClasses,   LAZILY_PINNED_ATOM(TypeError)},
>     {js_InitExceptionClasses,   LAZILY_PINNED_ATOM(URIError)},
1401c1251
<     {NULL,                      0, NULL, NULL}
---
>     {NULL,                      0, NULL}
1406,1408c1256,1258
<     {js_InitObjectClass,        EAGER_ATOM(proto), NULL},
<     {js_InitObjectClass,        EAGER_ATOM(parent), NULL},
<     {js_InitObjectClass,        EAGER_ATOM(count), NULL},
---
>     {js_InitObjectClass,        EAGERLY_PINNED_ATOM(proto)},
>     {js_InitObjectClass,        EAGERLY_PINNED_ATOM(parent)},
>     {js_InitObjectClass,        EAGERLY_PINNED_ATOM(count)},
1410c1260
<     {js_InitObjectClass,        EAGER_ATOM(toSource), NULL},
---
>     {js_InitObjectClass,        EAGERLY_PINNED_ATOM(toSource)},
1412,1414c1262,1264
<     {js_InitObjectClass,        EAGER_ATOM(toString), NULL},
<     {js_InitObjectClass,        EAGER_ATOM(toLocaleString), NULL},
<     {js_InitObjectClass,        EAGER_ATOM(valueOf), NULL},
---
>     {js_InitObjectClass,        EAGERLY_PINNED_ATOM(toString)},
>     {js_InitObjectClass,        EAGERLY_PINNED_ATOM(toLocaleString)},
>     {js_InitObjectClass,        EAGERLY_PINNED_ATOM(valueOf)},
1416,1417c1266,1272
<     {js_InitObjectClass,        LAZY_ATOM(watch), NULL},
<     {js_InitObjectClass,        LAZY_ATOM(unwatch), NULL},
---
>     {js_InitObjectClass,        LAZILY_PINNED_ATOM(watch)},
>     {js_InitObjectClass,        LAZILY_PINNED_ATOM(unwatch)},
> #endif
> #if JS_HAS_NEW_OBJ_METHODS
>     {js_InitObjectClass,        LAZILY_PINNED_ATOM(hasOwnProperty)},
>     {js_InitObjectClass,        LAZILY_PINNED_ATOM(isPrototypeOf)},
>     {js_InitObjectClass,        LAZILY_PINNED_ATOM(propertyIsEnumerable)},
1419,1421d1273
<     {js_InitObjectClass,        LAZY_ATOM(hasOwnProperty), NULL},
<     {js_InitObjectClass,        LAZY_ATOM(isPrototypeOf), NULL},
<     {js_InitObjectClass,        LAZY_ATOM(propertyIsEnumerable), NULL},
1423,1426c1275,1278
<     {js_InitObjectClass,        LAZY_ATOM(defineGetter), NULL},
<     {js_InitObjectClass,        LAZY_ATOM(defineSetter), NULL},
<     {js_InitObjectClass,        LAZY_ATOM(lookupGetter), NULL},
<     {js_InitObjectClass,        LAZY_ATOM(lookupSetter), NULL},
---
>     {js_InitObjectClass,        LAZILY_PINNED_ATOM(defineGetter)},
>     {js_InitObjectClass,        LAZILY_PINNED_ATOM(defineSetter)},
>     {js_InitObjectClass,        LAZILY_PINNED_ATOM(lookupGetter)},
>     {js_InitObjectClass,        LAZILY_PINNED_ATOM(lookupSetter)},
1429c1281
<     {NULL,                      0, NULL, NULL}
---
>     {NULL,                      0, NULL}
1431a1284,1286
> #undef EAGERLY_PINNED_ATOM
> #undef LAZILY_PINNED_ATOM
> 
1439c1294
<     JSStdName *stdnm;
---
>     JSObjectOp init;
1445,1447c1300
<     rt = cx->runtime;
<     JS_ASSERT(rt->state != JSRTS_DOWN);
<     if (rt->state == JSRTS_LANDING || !JSVAL_IS_STRING(id))
---
>     if (!JSVAL_IS_STRING(id))
1449d1301
< 
1450a1303
>     rt = cx->runtime;
1452c1305,1306
<     /* Check whether we're resolving 'undefined', and define it if so. */
---
> #if JS_HAS_UNDEFINED
>     /* See if we're resolving 'undefined', and define it if so. */
1456,1457c1310,1311
<         return OBJ_DEFINE_PROPERTY(cx, obj, ATOM_TO_JSID(atom), JSVAL_VOID,
<                                    NULL, NULL, JSPROP_PERMANENT, NULL);
---
>         return OBJ_DEFINE_PROPERTY(cx, obj, (jsid)atom, JSVAL_VOID, NULL, NULL,
>                                    JSPROP_PERMANENT, NULL);
1458a1313
> #endif
1461c1316
<     stdnm = NULL;
---
>     init = NULL;
1465c1320
<             stdnm = &standard_class_atoms[i];
---
>             init = standard_class_atoms[i].init;
1470c1325
<     if (!stdnm) {
---
>     if (!init) {
1477c1332
<                 stdnm = &standard_class_names[i];
---
>                 init = standard_class_names[i].init;
1482c1337
<         if (!stdnm && !OBJ_GET_PROTO(cx, obj)) {
---
>         if (!init && !OBJ_GET_PROTO(cx, obj)) {
1493c1348
<                     stdnm = &standard_class_names[i];
---
>                     init = standard_class_names[i].init;
1500,1516c1355,1356
<     if (stdnm) {
<         /*
<          * If this standard class is anonymous and obj advertises itself as a
<          * global object (in order to reserve slots for standard class object
<          * pointers), then we don't want to resolve by name.
<          *
<          * If inversely, either id does not name a class, or id does not name
<          * an anonymous class, or the global does not reserve slots for class
<          * objects, then we must call the init hook here.
<          */
<         if (stdnm->clasp &&
<             (stdnm->clasp->flags & JSCLASS_IS_ANONYMOUS) &&
<             (OBJ_GET_CLASS(cx, obj)->flags & JSCLASS_IS_GLOBAL)) {
<             return JS_TRUE;
<         }
< 
<         if (!stdnm->init(cx, obj))
---
>     if (init) {
>         if (!init(cx, obj))
1524c1364
< AlreadyHasOwnProperty(JSContext *cx, JSObject *obj, JSAtom *atom)
---
> HasOwnProperty(JSContext *cx, JSObject *obj, JSAtom *atom, JSBool *ownp)
1526,1527c1366,1367
<     JSScopeProperty *sprop;
<     JSScope *scope;
---
>     JSObject *pobj;
>     JSProperty *prop;
1529,1534c1369,1374
<     JS_ASSERT(OBJ_IS_NATIVE(obj));
<     JS_LOCK_OBJ(cx, obj);
<     scope = OBJ_SCOPE(obj);
<     sprop = SCOPE_GET_PROPERTY(scope, ATOM_TO_JSID(atom));
<     JS_UNLOCK_SCOPE(cx, scope);
<     return sprop != NULL;
---
>     if (!OBJ_LOOKUP_PROPERTY(cx, obj, (jsid)atom, &pobj, &prop))
>         return JS_FALSE;
>     if (prop)
>         OBJ_DROP_PROPERTY(cx, pobj, prop);
>     *ownp = (pobj == obj && prop);
>     return JS_TRUE;
1541a1382
>     JSBool found;
1547c1388,1389
<     /* Check whether we need to bind 'undefined' and define it if so. */
---
> #if JS_HAS_UNDEFINED
>     /* See if we need to bind 'undefined' and define it if so. */
1549,1551c1391,1395
<     if (!AlreadyHasOwnProperty(cx, obj, atom) &&
<         !OBJ_DEFINE_PROPERTY(cx, obj, ATOM_TO_JSID(atom), JSVAL_VOID,
<                              NULL, NULL, JSPROP_PERMANENT, NULL)) {
---
>     if (!HasOwnProperty(cx, obj, atom, &found))
>         return JS_FALSE;
>     if (!found &&
>         !OBJ_DEFINE_PROPERTY(cx, obj, (jsid)atom, JSVAL_VOID, NULL, NULL,
>                             JSPROP_PERMANENT, NULL)) {
1553a1398
> #endif
1558,1559c1403,1405
<         if (!AlreadyHasOwnProperty(cx, obj, atom) &&
<             !standard_class_atoms[i].init(cx, obj)) {
---
>         if (!HasOwnProperty(cx, obj, atom, &found))
>             return JS_FALSE;
>         if (!found && !standard_class_atoms[i].init(cx, obj))
1561d1406
<         }
1567,1668c1412,1413
< static JSIdArray *
< AddAtomToArray(JSContext *cx, JSAtom *atom, JSIdArray *ida, jsint *ip)
< {
<     jsint i, length;
< 
<     i = *ip;
<     length = ida->length;
<     if (i >= length) {
<         ida = js_SetIdArrayLength(cx, ida, JS_MAX(length * 2, 8));
<         if (!ida)
<             return NULL;
<         JS_ASSERT(i < ida->length);
<     }
<     ida->vector[i] = ATOM_TO_JSID(atom);
<     *ip = i + 1;
<     return ida;
< }
< 
< static JSIdArray *
< EnumerateIfResolved(JSContext *cx, JSObject *obj, JSAtom *atom, JSIdArray *ida,
<                     jsint *ip, JSBool *foundp)
< {
<     *foundp = AlreadyHasOwnProperty(cx, obj, atom);
<     if (*foundp)
<         ida = AddAtomToArray(cx, atom, ida, ip);
<     return ida;
< }
< 
< JS_PUBLIC_API(JSIdArray *)
< JS_EnumerateResolvedStandardClasses(JSContext *cx, JSObject *obj,
<                                     JSIdArray *ida)
< {
<     JSRuntime *rt;
<     jsint i, j, k;
<     JSAtom *atom;
<     JSBool found;
<     JSObjectOp init;
< 
<     CHECK_REQUEST(cx);
<     rt = cx->runtime;
<     if (ida) {
<         i = ida->length;
<     } else {
<         ida = js_NewIdArray(cx, 8);
<         if (!ida)
<             return NULL;
<         i = 0;
<     }
< 
<     /* Check whether 'undefined' has been resolved and enumerate it if so. */
<     atom = rt->atomState.typeAtoms[JSTYPE_VOID];
<     ida = EnumerateIfResolved(cx, obj, atom, ida, &i, &found);
<     if (!ida)
<         return NULL;
< 
<     /* Enumerate only classes that *have* been resolved. */
<     for (j = 0; standard_class_atoms[j].init; j++) {
<         atom = OFFSET_TO_ATOM(rt, standard_class_atoms[j].atomOffset);
<         ida = EnumerateIfResolved(cx, obj, atom, ida, &i, &found);
<         if (!ida)
<             return NULL;
< 
<         if (found) {
<             init = standard_class_atoms[j].init;
< 
<             for (k = 0; standard_class_names[k].init; k++) {
<                 if (standard_class_names[k].init == init) {
<                     atom = StdNameToAtom(cx, &standard_class_names[k]);
<                     ida = AddAtomToArray(cx, atom, ida, &i);
<                     if (!ida)
<                         return NULL;
<                 }
<             }
< 
<             if (init == js_InitObjectClass) {
<                 for (k = 0; object_prototype_names[k].init; k++) {
<                     atom = StdNameToAtom(cx, &object_prototype_names[k]);
<                     ida = AddAtomToArray(cx, atom, ida, &i);
<                     if (!ida)
<                         return NULL;
<                 }
<             }
<         }
<     }
< 
<     /* Trim to exact length via js_SetIdArrayLength. */
<     return js_SetIdArrayLength(cx, ida, i);
< }
< 
< #undef CLASP
< #undef EAGER_ATOM
< #undef EAGER_CLASS_ATOM
< #undef EAGER_ATOM_CLASP
< #undef LAZY_ATOM
< 
< JS_PUBLIC_API(JSBool)
< JS_GetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key,
<                   JSObject **objp)
< {
<     CHECK_REQUEST(cx);
<     return js_GetClassObject(cx, obj, key, objp);
< }
---
> #undef ATOM_OFFSET
> #undef OFFSET_TO_ATOM
1673,1706c1418
<     JSStackFrame *fp;
< 
<     fp = cx->fp;
<     if (!fp) {
<         /*
<          * There is no code active on this context. In place of an actual
<          * scope chain, use the context's global object, which is set in
<          * js_InitFunctionAndObjectClasses, and which represents the default
<          * scope chain for the embedding. See also js_FindClassObject.
<          *
<          * For embeddings that use the inner and outer object hooks, the inner
<          * object represents the ultimate global object, with the outer object
<          * acting as a stand-in.
<          */
<         JSObject *obj = cx->globalObject;
<         if (!obj) {
<             JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INACTIVE);
<             return NULL;
<         }
< 
<         OBJ_TO_INNER_OBJECT(cx, obj);
<         return obj;
<     }
<     return js_GetScopeChain(cx, fp);
< }
< 
< JS_PUBLIC_API(JSObject *)
< JS_GetGlobalForObject(JSContext *cx, JSObject *obj)
< {
<     JSObject *parent;
< 
<     while ((parent = OBJ_GET_PARENT(cx, obj)) != NULL)
<         obj = parent;
<     return obj;
---
>     return cx->fp ? cx->fp->scopeChain : NULL;
1715d1426
<     JS_COUNT_OPERATION(cx, JSOW_ALLOCATION);
1718,1720c1429,1432
< 
<     p = malloc(nbytes);
<     if (!p) {
---
>     cx->runtime->gcMallocBytes += nbytes;
>     XMEMTAG("JS_malloc");
>     p = xmalloc(nbytes);
>     if (!p)
1722,1725d1433
<         return NULL;
<     }
<     js_UpdateMallocCounter(cx, nbytes);
< 
1732,1733c1440,1441
<     JS_COUNT_OPERATION(cx, JSOW_ALLOCATION);
<     p = realloc(p, nbytes);
---
>     XMEMTAG("JS_realloc");
>     p = xrealloc(p, nbytes);
1743c1451
<         free(p);
---
>         xfree(p);
1752a1461
> 	XMEMTAG("JS_strdup");
1763c1472
<     return js_NewDouble(cx, d, 0);
---
>     return js_NewDouble(cx, d);
1817,1818c1526
<     JS_CLEAR_WEAK_ROOTS(&cx->weakRoots);
< }
---
>     uintN i;
1820,1824c1528,1530
< JS_PUBLIC_API(JSBool)
< JS_EnterLocalRootScope(JSContext *cx)
< {
<     CHECK_REQUEST(cx);
<     return js_EnterLocalRootScope(cx);
---
>     for (i = 0; i < GCX_NTYPES; i++)
>         cx->newborn[i] = NULL;
>     cx->lastAtom = NULL;
1827,1832c1533
< JS_PUBLIC_API(void)
< JS_LeaveLocalRootScope(JSContext *cx)
< {
<     CHECK_REQUEST(cx);
<     js_LeaveLocalRootScope(cx);
< }
---
> #include "jshash.h" /* Added by JSIFY */
1834,1839c1535
< JS_PUBLIC_API(void)
< JS_LeaveLocalRootScopeWithResult(JSContext *cx, jsval rval)
< {
<     CHECK_REQUEST(cx);
<     js_LeaveLocalRootScopeWithResult(cx, rval);
< }
---
> #ifdef DEBUG
1841,1845c1537,1551
< JS_PUBLIC_API(void)
< JS_ForgetLocalRoot(JSContext *cx, void *thing)
< {
<     CHECK_REQUEST(cx);
<     js_ForgetLocalRoot(cx, (jsval) thing);
---
> typedef struct NamedRootDumpArgs {
>     void (*dump)(const char *name, void *rp, void *data);
>     void *data;
> } NamedRootDumpArgs;
> 
> JS_STATIC_DLL_CALLBACK(JSDHashOperator)
> js_named_root_dumper(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 number,
>                      void *arg)
> {
>     NamedRootDumpArgs *args = (NamedRootDumpArgs *) arg;
>     JSGCRootHashEntry *rhe = (JSGCRootHashEntry *)hdr;
> 
>     if (rhe->name)
>         args->dump(rhe->name, rhe->root, args->data);
>     return JS_DHASH_NEXT;
1848,1849d1553
< #ifdef DEBUG
< 
1855c1559,1563
<     js_DumpNamedRoots(rt, dump, data);
---
>     NamedRootDumpArgs args;
> 
>     args.dump = dump;
>     args.data = data;
>     JS_DHashTableEnumerate(&rt->gcRootsHash, js_named_root_dumper, &args);
1859a1568,1598
> typedef struct GCRootMapArgs {
>     JSGCRootMapFun map;
>     void *data;
> } GCRootMapArgs;
> 
> JS_STATIC_DLL_CALLBACK(JSDHashOperator)
> js_gcroot_mapper(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 number,
>                  void *arg)
> {
>     GCRootMapArgs *args = (GCRootMapArgs *) arg;
>     JSGCRootHashEntry *rhe = (JSGCRootHashEntry *)hdr;
>     intN mapflags;
>     JSDHashOperator op;
> 
>     mapflags = args->map(rhe->root, rhe->name, args->data);
> 
> #if JS_MAP_GCROOT_NEXT == JS_DHASH_NEXT &&                                     \
>     JS_MAP_GCROOT_STOP == JS_DHASH_STOP &&                                     \
>     JS_MAP_GCROOT_REMOVE == JS_DHASH_REMOVE
>     op = (JSDHashOperator)mapflags;
> #else
>     op = JS_DHASH_NEXT;
>     if (mapflags & JS_MAP_GCROOT_STOP)
>         op |= JS_DHASH_STOP;
>     if (mapflags & JS_MAP_GCROOT_REMOVE)
>         op |= JS_DHASH_REMOVE;
> #endif
> 
>     return op;
> }
> 
1863c1602,1610
<     return js_MapGCRoots(rt, map, data);
---
>     GCRootMapArgs args;
>     uint32 rv;
> 
>     args.map = map;
>     args.data = data;
>     JS_LOCK_GC(rt);
>     rv = JS_DHashTableEnumerate(&rt->gcRootsHash, js_gcroot_mapper, &args);
>     JS_UNLOCK_GC(rt);
>     return rv;
1903,2348d1649
< JS_SetExtraGCRoots(JSRuntime *rt, JSTraceDataOp traceOp, void *data)
< {
<     rt->gcExtraRootsTraceOp = traceOp;
<     rt->gcExtraRootsData = data;
< }
< 
< JS_PUBLIC_API(void)
< JS_TraceRuntime(JSTracer *trc)
< {
<     JSBool allAtoms = trc->context->runtime->gcKeepAtoms != 0;
< 
<     js_TraceRuntime(trc, allAtoms);
< }
< 
< #ifdef DEBUG
< 
< #ifdef HAVE_XPCONNECT
< #include "dump_xpc.h"
< #endif
< 
< JS_PUBLIC_API(void)
< JS_PrintTraceThingInfo(char *buf, size_t bufsize, JSTracer *trc,
<                        void *thing, uint32 kind, JSBool details)
< {
<     const char *name;
<     size_t n;
< 
<     if (bufsize == 0)
<         return;
< 
<     switch (kind) {
<       case JSTRACE_OBJECT:
<       {
<         JSObject *obj = (JSObject *)thing;
<         JSClass *clasp = STOBJ_GET_CLASS(obj);
< 
<         name = clasp->name;
< #ifdef HAVE_XPCONNECT
<         if (clasp->flags & JSCLASS_PRIVATE_IS_NSISUPPORTS) {
<             jsval privateValue = STOBJ_GET_SLOT(obj, JSSLOT_PRIVATE);
< 
<             JS_ASSERT(clasp->flags & JSCLASS_HAS_PRIVATE);
<             if (!JSVAL_IS_VOID(privateValue)) {
<                 void  *privateThing = JSVAL_TO_PRIVATE(privateValue);
<                 const char *xpcClassName = GetXPCObjectClassName(privateThing);
< 
<                 if (xpcClassName)
<                     name = xpcClassName;
<             }
<         }
< #endif
<         break;
<       }
< 
<       case JSTRACE_STRING:
<         name = JSSTRING_IS_DEPENDENT((JSString *)thing)
<                ? "substring"
<                : "string";
<         break;
< 
<       case JSTRACE_DOUBLE:
<         name = "double";
<         break;
< 
<       case JSTRACE_FUNCTION:
<         name = "function";
<         break;
< 
< #if JS_HAS_XML_SUPPORT
<       case JSTRACE_NAMESPACE:
<         name = "namespace";
<         break;
< 
<       case JSTRACE_QNAME:
<         name = "qname";
<         break;
< 
<       case JSTRACE_XML:
<         name = "xml";
<         break;
< #endif
<       default:
<         JS_ASSERT(0);
<         return;
<         break;
<     }
< 
<     n = strlen(name);
<     if (n > bufsize - 1)
<         n = bufsize - 1;
<     memcpy(buf, name, n + 1);
<     buf += n;
<     bufsize -= n;
< 
<     if (details && bufsize > 2) {
<         *buf++ = ' ';
<         bufsize--;
< 
<         switch (kind) {
<           case JSTRACE_OBJECT:
<           {
<             JSObject  *obj = (JSObject *)thing;
<             jsval     privateValue = STOBJ_GET_SLOT(obj, JSSLOT_PRIVATE);
<             void      *privateThing = JSVAL_IS_VOID(privateValue)
<                                       ? NULL
<                                       : JSVAL_TO_PRIVATE(privateValue);
< 
<             JS_snprintf(buf, bufsize, "%p", privateThing);
<             break;
<           }
< 
<           case JSTRACE_STRING:
<             js_PutEscapedString(buf, bufsize, (JSString *)thing, 0);
<             break;
< 
<           case JSTRACE_DOUBLE:
<             JS_snprintf(buf, bufsize, "%g", *(jsdouble *)thing);
<             break;
< 
<           case JSTRACE_FUNCTION:
<           {
<             JSFunction *fun = (JSFunction *)thing;
< 
<             if (fun->atom && ATOM_IS_STRING(fun->atom))
<                 js_PutEscapedString(buf, bufsize, ATOM_TO_STRING(fun->atom), 0);
<             break;
<           }
< 
< #if JS_HAS_XML_SUPPORT
<           case JSTRACE_NAMESPACE:
<           {
<             JSXMLNamespace *ns = (JSXMLNamespace *)thing;
< 
<             if (ns->prefix) {
<                 n = js_PutEscapedString(buf, bufsize, ns->prefix, 0);
<                 buf += n;
<                 bufsize -= n;
<             }
<             if (bufsize > 2) {
<                 *buf++ = ':';
<                 bufsize--;
<                 js_PutEscapedString(buf, bufsize, ns->uri, 0);
<             }
<             break;
<           }
< 
<           case JSTRACE_QNAME:
<           {
<             JSXMLQName *qn = (JSXMLQName *)thing;
< 
<             if (qn->prefix) {
<                 n = js_PutEscapedString(buf, bufsize, qn->prefix, 0);
<                 buf += n;
<                 bufsize -= n;
<             }
<             if (bufsize > 2) {
<                 *buf++ = '(';
<                 bufsize--;
<                 n = js_PutEscapedString(buf, bufsize, qn->uri, 0);
<                 buf += n;
<                 bufsize -= n;
<                 if (bufsize > 3) {
<                     *buf++ = ')';
<                     *buf++ = ':';
<                     bufsize -= 2;
<                     js_PutEscapedString(buf, bufsize, qn->localName, 0);
<                 }
<             }
<             break;
<           }
< 
<           case JSTRACE_XML:
<           {
<             extern const char *js_xml_class_str[];
<             JSXML *xml = (JSXML *)thing;
< 
<             JS_snprintf(buf, bufsize, "%s", js_xml_class_str[xml->xml_class]);
<             break;
<           }
< #endif
<           default:
<             JS_ASSERT(0);
<             break;
<         }
<     }
<     buf[bufsize - 1] = '\0';
< }
< 
< typedef struct JSHeapDumpNode JSHeapDumpNode;
< 
< struct JSHeapDumpNode {
<     void            *thing;
<     uint32          kind;
<     JSHeapDumpNode  *next;          /* next sibling */
<     JSHeapDumpNode  *parent;        /* node with the thing that refer to thing
<                                        from this node */
<     char            edgeName[1];    /* name of the edge from parent->thing
<                                        into thing */
< };
< 
< typedef struct JSDumpingTracer {
<     JSTracer            base;
<     JSDHashTable        visited;
<     JSBool              ok;
<     void                *startThing;
<     void                *thingToFind;
<     void                *thingToIgnore;
<     JSHeapDumpNode      *parentNode;
<     JSHeapDumpNode      **lastNodep;
<     char                buffer[200];
< } JSDumpingTracer;
< 
< static void
< DumpNotify(JSTracer *trc, void *thing, uint32 kind)
< {
<     JSDumpingTracer *dtrc;
<     JSContext *cx;
<     JSDHashEntryStub *entry;
<     JSHeapDumpNode *node;
<     const char *edgeName;
<     size_t edgeNameSize;
< 
<     JS_ASSERT(trc->callback == DumpNotify);
<     dtrc = (JSDumpingTracer *)trc;
< 
<     if (!dtrc->ok || thing == dtrc->thingToIgnore)
<         return;
< 
<     cx = trc->context;
< 
<     /*
<      * Check if we have already seen thing unless it is thingToFind to include
<      * it to the graph each time we reach it and print all live things that
<      * refer to thingToFind.
<      *
<      * This does not print all possible paths leading to thingToFind since
<      * when a thing A refers directly or indirectly to thingToFind and A is
<      * present several times in the graph, we will print only the first path
<      * leading to A and thingToFind, other ways to reach A will be ignored.
<      */
<     if (dtrc->thingToFind != thing) {
<         /*
<          * The startThing check allows to avoid putting startThing into the
<          * hash table before tracing startThing in JS_DumpHeap.
<          */
<         if (thing == dtrc->startThing)
<             return;
<         entry = (JSDHashEntryStub *)
<             JS_DHashTableOperate(&dtrc->visited, thing, JS_DHASH_ADD);
<         if (!entry) {
<             JS_ReportOutOfMemory(cx);
<             dtrc->ok = JS_FALSE;
<             return;
<         }
<         if (entry->key)
<             return;
<         entry->key = thing;
<     }
< 
<     if (dtrc->base.debugPrinter) {
<         dtrc->base.debugPrinter(trc, dtrc->buffer, sizeof(dtrc->buffer));
<         edgeName = dtrc->buffer;
<     } else if (dtrc->base.debugPrintIndex != (size_t)-1) {
<         JS_snprintf(dtrc->buffer, sizeof(dtrc->buffer), "%s[%lu]",
<                     (const char *)dtrc->base.debugPrintArg,
<                     dtrc->base.debugPrintIndex);
<         edgeName = dtrc->buffer;
<     } else {
<         edgeName = (const char*)dtrc->base.debugPrintArg;
<     }
< 
<     edgeNameSize = strlen(edgeName) + 1;
<     node = (JSHeapDumpNode *)
<         JS_malloc(cx, offsetof(JSHeapDumpNode, edgeName) + edgeNameSize);
<     if (!node) {
<         dtrc->ok = JS_FALSE;
<         return;
<     }
< 
<     node->thing = thing;
<     node->kind = kind;
<     node->next = NULL;
<     node->parent = dtrc->parentNode;
<     memcpy(node->edgeName, edgeName, edgeNameSize);
< 
<     JS_ASSERT(!*dtrc->lastNodep);
<     *dtrc->lastNodep = node;
<     dtrc->lastNodep = &node->next;
< }
< 
< /* Dump node and the chain that leads to thing it contains. */
< static JSBool
< DumpNode(JSDumpingTracer *dtrc, FILE* fp, JSHeapDumpNode *node)
< {
<     JSHeapDumpNode *prev, *following;
<     size_t chainLimit;
<     JSBool ok;
<     enum { MAX_PARENTS_TO_PRINT = 10 };
< 
<     JS_PrintTraceThingInfo(dtrc->buffer, sizeof dtrc->buffer,
<                            &dtrc->base, node->thing, node->kind, JS_TRUE);
<     if (fprintf(fp, "%p %-22s via ", node->thing, dtrc->buffer) < 0)
<         return JS_FALSE;
< 
<     /*
<      * We need to print the parent chain in the reverse order. To do it in
<      * O(N) time where N is the chain length we first reverse the chain while
<      * searching for the top and then print each node while restoring the
<      * chain order.
<      */
<     chainLimit = MAX_PARENTS_TO_PRINT;
<     prev = NULL;
<     for (;;) {
<         following = node->parent;
<         node->parent = prev;
<         prev = node;
<         node = following;
<         if (!node)
<             break;
<         if (chainLimit == 0) {
<             if (fputs("...", fp) < 0)
<                 return JS_FALSE;
<             break;
<         }
<         --chainLimit;
<     }
< 
<     node = prev;
<     prev = following;
<     ok = JS_TRUE;
<     do {
<         /* Loop must continue even when !ok to restore the parent chain. */
<         if (ok) {
<             if (!prev) {
<                 /* Print edge from some runtime root or startThing. */
<                 if (fputs(node->edgeName, fp) < 0)
<                     ok = JS_FALSE;
<             } else {
<                 JS_PrintTraceThingInfo(dtrc->buffer, sizeof dtrc->buffer,
<                                        &dtrc->base, prev->thing, prev->kind,
<                                        JS_FALSE);
<                 if (fprintf(fp, "(%p %s).%s",
<                            prev->thing, dtrc->buffer, node->edgeName) < 0) {
<                     ok = JS_FALSE;
<                 }
<             }
<         }
<         following = node->parent;
<         node->parent = prev;
<         prev = node;
<         node = following;
<     } while (node);
< 
<     return ok && putc('\n', fp) >= 0;
< }
< 
< JS_PUBLIC_API(JSBool)
< JS_DumpHeap(JSContext *cx, FILE *fp, void* startThing, uint32 startKind,
<             void *thingToFind, size_t maxDepth, void *thingToIgnore)
< {
<     JSDumpingTracer dtrc;
<     JSHeapDumpNode *node, *children, *next, *parent;
<     size_t depth;
<     JSBool thingToFindWasTraced;
< 
<     if (maxDepth == 0)
<         return JS_TRUE;
< 
<     JS_TRACER_INIT(&dtrc.base, cx, DumpNotify);
<     if (!JS_DHashTableInit(&dtrc.visited, JS_DHashGetStubOps(),
<                            NULL, sizeof(JSDHashEntryStub),
<                            JS_DHASH_DEFAULT_CAPACITY(100))) {
<         JS_ReportOutOfMemory(cx);
<         return JS_FALSE;
<     }
<     dtrc.ok = JS_TRUE;
<     dtrc.startThing = startThing;
<     dtrc.thingToFind = thingToFind;
<     dtrc.thingToIgnore = thingToIgnore;
<     dtrc.parentNode = NULL;
<     node = NULL;
<     dtrc.lastNodep = &node;
<     if (!startThing) {
<         JS_ASSERT(startKind == 0);
<         JS_TraceRuntime(&dtrc.base);
<     } else {
<         JS_TraceChildren(&dtrc.base, startThing, startKind);
<     }
< 
<     depth = 1;
<     if (!node)
<         goto dump_out;
< 
<     thingToFindWasTraced = thingToFind && thingToFind == startThing;
<     for (;;) {
<         /*
<          * Loop must continue even when !dtrc.ok to free all nodes allocated
<          * so far.
<          */
<         if (dtrc.ok) {
<             if (thingToFind == NULL || thingToFind == node->thing)
<                 dtrc.ok = DumpNode(&dtrc, fp, node);
< 
<             /* Descend into children. */
<             if (dtrc.ok &&
<                 depth < maxDepth &&
<                 (thingToFind != node->thing || !thingToFindWasTraced)) {
<                 dtrc.parentNode = node;
<                 children = NULL;
<                 dtrc.lastNodep = &children;
<                 JS_TraceChildren(&dtrc.base, node->thing, node->kind);
<                 if (thingToFind == node->thing)
<                     thingToFindWasTraced = JS_TRUE;
<                 if (children != NULL) {
<                     ++depth;
<                     node = children;
<                     continue;
<                 }
<             }
<         }
< 
<         /* Move to next or parents next and free the node. */
<         for (;;) {
<             next = node->next;
<             parent = node->parent;
<             JS_free(cx, node);
<             node = next;
<             if (node)
<                 break;
<             if (!parent)
<                 goto dump_out;
<             JS_ASSERT(depth > 1);
<             --depth;
<             node = parent;
<         }
<     }
< 
<   dump_out:
<     JS_ASSERT(depth == 1);
<     JS_DHashTableFinish(&dtrc.visited);
<     return dtrc.ok;
< }
< 
< #endif /* DEBUG */
< 
< JS_PUBLIC_API(void)
2351,2358c1652
<     JSTracer *trc;
< 
<     trc = (JSTracer *)arg;
<     if (!trc)
<         trc = cx->runtime->gcMarkingTracer;
<     else
<         JS_ASSERT(trc == cx->runtime->gcMarkingTracer);
< 
---
>     JS_ASSERT(cx->runtime->gcLevel > 0);
2360c1654
<     JS_ASSERT(cx->runtime->gcThread == trc->context->thread);
---
>     JS_ASSERT(cx->runtime->gcThread == js_CurrentThreadId());
2362,2364d1655
<     JS_SET_TRACING_NAME(trc, name ? name : "unknown");
<     js_CallValueTracerIfGCThing(trc, (jsval)thing);
< }
2366,2369c1657
< extern JS_PUBLIC_API(JSBool)
< JS_IsGCMarkingTracer(JSTracer *trc)
< {
<     return IS_GC_MARKING_TRACER(trc);
---
>     GC_MARK(cx, thing, name, arg);
2375c1663,1665
<     /* Don't nuke active arenas if executing or compiling. */
---
>     if (cx->runtime->gcDisabled)
>         return;
> 
2378,2380c1668,1670
<     if (cx->tempPool.current == &cx->tempPool.first)
<         JS_FinishArenaPool(&cx->tempPool);
<     js_GC(cx, GC_NORMAL);
---
>     JS_FinishArenaPool(&cx->codePool);
>     JS_FinishArenaPool(&cx->tempPool);
>     js_ForceGC(cx, 0);
2390,2397d1679
< 
< #ifdef JS_GC_ZEAL
<     if (rt->gcZeal > 0) {
<         JS_GC(cx);
<         return;
<     }
< #endif
< 
2400,2449c1682,1688
< 
<     /*
<      * We run the GC if we used all available free GC cells and had to
<      * allocate extra 1/3 of GC arenas since the last run of GC, or if
<      * we have malloc'd more bytes through JS_malloc than we were told
<      * to allocate by JS_NewRuntime.
<      *
<      * The reason for
<      *   bytes > 4/3 lastBytes
<      * condition is the following. Bug 312238 changed bytes and lastBytes
<      * to mean the total amount of memory that the GC uses now and right
<      * after the last GC.
<      *
<      * Before the bug the variables meant the size of allocated GC things
<      * now and right after the last GC. That size did not include the
<      * memory taken by free GC cells and the condition was
<      *   bytes > 3/2 lastBytes.
<      * That is, we run the GC if we have half again as many bytes of
<      * GC-things as the last time we GC'd. To be compatible we need to
<      * express that condition through the new meaning of bytes and
<      * lastBytes.
<      *
<      * We write the original condition as
<      *   B*(1-F) > 3/2 Bl*(1-Fl)
<      * where B is the total memory size allocated by GC and F is the free
<      * cell density currently and Sl and Fl are the size and the density
<      * right after GC. The density by definition is memory taken by free
<      * cells divided by total amount of memory. In other words, B and Bl
<      * are bytes and lastBytes with the new meaning and B*(1-F) and
<      * Bl*(1-Fl) are bytes and lastBytes with the original meaning.
<      *
<      * Our task is to exclude F and Fl from the last statement. According
<      * to the stats from bug 331966 comment 23, Fl is about 10-25% for a
<      * typical run of the browser. It means that the original condition
<      * implied that we did not run GC unless we exhausted the pool of
<      * free cells. Indeed if we still have free cells, then B == Bl since
<      * we did not yet allocated any new arenas and the condition means
<      *   1 - F > 3/2 (1-Fl) or 3/2Fl > 1/2 + F
<      * That implies 3/2 Fl > 1/2 or Fl > 1/3. That can not be fulfilled
<      * for the state described by the stats. So we can write the original
<      * condition as:
<      *   F == 0 && B > 3/2 Bl(1-Fl)
<      * Again using the stats we see that Fl is about 11% when the browser
<      * starts up and when we are far from hitting rt->gcMaxBytes. With
<      * this F we have
<      * F == 0 && B > 3/2 Bl(1-0.11)
<      * or approximately F == 0 && B > 4/3 Bl.
<      */
<     if ((bytes > 8192 && bytes > lastBytes + lastBytes / 3) ||
<         rt->gcMallocBytes >= rt->gcMaxMallocBytes) {
---
>     if ((bytes > 8192 && bytes > lastBytes + lastBytes / 2) ||
>         rt->gcMallocBytes > rt->gcMaxBytes) {
>         /*
>          * Run the GC if we have half again as many bytes of GC-things as
>          * the last time we GC'd, or if we have malloc'd more bytes through
>          * JS_malloc than we were told to allocate by JS_NewRuntime.
>          */
2457d1695
<     CHECK_REQUEST(cx);
2478,2493d1715
< JS_PUBLIC_API(void)
< JS_SetGCParameter(JSRuntime *rt, JSGCParamKey key, uint32 value)
< {
<     switch (key) {
<       case JSGC_MAX_BYTES:
<         rt->gcMaxBytes = value;
<         break;
<       case JSGC_MAX_MALLOC_BYTES:
<         rt->gcMaxMallocBytes = value;
<         break;
<       case JSGC_STACKPOOL_LIFESPAN:
<         rt->gcStackPoolLifespan = value;
<         break;
<     }
< }
< 
2512c1734
<     JS_ASSERT((uintN) type < (uintN) (GCX_NTYPES - GCX_EXTERNAL_STRING));
---
>     JS_ASSERT(GCX_EXTERNAL_STRING <= type && type < (intN) GCX_NTYPES);
2514,2515c1736
<     str = (JSString *) js_NewGCThing(cx, (uintN) type + GCX_EXTERNAL_STRING,
<                                      sizeof(JSString));
---
>     str = (JSString *) js_AllocGCThing(cx, (uintN) type);
2518c1739,1740
<     JSFLATSTR_INIT(str, chars, length);
---
>     str->length = length;
>     str->chars = chars;
2525,2536c1747
<     return js_GetExternalStringGCType(str);
< }
< 
< JS_PUBLIC_API(void)
< JS_SetThreadStackLimit(JSContext *cx, jsuword limitAddr)
< {
< #if JS_STACK_GROWTH_DIRECTION > 0
<     if (limitAddr == 0)
<         limitAddr = (jsuword)-1;
< #endif
<     cx->stackLimit = limitAddr;
< }
---
>     uint8 type = (uint8) (*js_GetGCThingFlags(str) & GCF_TYPEMASK);
2538,2541c1749,1752
< JS_PUBLIC_API(void)
< JS_SetScriptStackQuota(JSContext *cx, size_t quota)
< {
<     cx->scriptStackQuota = quota;
---
>     if (type >= GCX_EXTERNAL_STRING)
>         return (intN)type;
>     JS_ASSERT(type == GCX_STRING || type == GCX_MUTABLE_STRING);
>     return -1;
2554a1766,1767
>     JSAtom *atom;
> 
2556,2563c1769,1776
<     if (JSVAL_IS_INT(v))
<         *idp = INT_JSVAL_TO_JSID(v);
< #if JS_HAS_XML_SUPPORT
<     else if (!JSVAL_IS_PRIMITIVE(v))
<         *idp = OBJECT_JSVAL_TO_JSID(v);
< #endif
<     else
<         return js_ValueToStringId(cx, v, idp);
---
>     if (JSVAL_IS_INT(v)) {
>         *idp = v;
>     } else {
>         atom = js_ValueToStringAtom(cx, v);
>         if (!atom)
>             return JS_FALSE;
>         *idp = (jsid)atom;
>     }
2595a1809,1812
> #if JS_BUG_EAGER_TOSTRING
>     if (type == JSTYPE_STRING)
>         return JS_TRUE;
> #endif
2611d1827
<     JSProtoKey key;
2613,2614d1828
<     JSTempValueRooter tvr;
<     jsval cval, rval;
2616a1831
>     jsval junk;
2623,2644d1837
<     /*
<      * When initializing a standard class, if no parent_proto (grand-proto of
<      * instances of the class, parent-proto of the class's prototype object)
<      * is given, we must use Object.prototype if it is available.  Otherwise,
<      * we could look up the wrong binding for a class name in obj.  Example:
<      *
<      *   String = Array;
<      *   print("hi there".join);
<      *
<      * should print undefined, not Array.prototype.join.  This is required by
<      * ECMA-262, alas.  It might have been better to make String readonly and
<      * permanent in the global object, instead -- but that's too big a change
<      * to swallow at this point.
<      */
<     key = JSCLASS_CACHED_PROTO_KEY(clasp);
<     if (key != JSProto_Null &&
<         !parent_proto &&
<         !js_GetClassPrototype(cx, obj, INT_TO_JSID(JSProto_Object),
<                               &parent_proto)) {
<         return NULL;
<     }
< 
2650,2652d1842
<     /* After this point, control must exit via label bad or out. */
<     JS_PUSH_TEMP_ROOT_OBJECT(cx, proto, &tvr);
< 
2654,2677c1844,1848
<         /*
<          * Lacking a constructor, name the prototype (e.g., Math) unless this
<          * class (a) is anonymous, i.e. for internal use only; (b) the class
<          * of obj (the global object) is has a reserved slot indexed by key;
<          * and (c) key is not the null key.
<          */
<         if ((clasp->flags & JSCLASS_IS_ANONYMOUS) &&
<             (OBJ_GET_CLASS(cx, obj)->flags & JSCLASS_IS_GLOBAL) &&
<             key != JSProto_Null) {
<             named = JS_FALSE;
<         } else {
<             named = OBJ_DEFINE_PROPERTY(cx, obj, ATOM_TO_JSID(atom),
<                                         OBJECT_TO_JSVAL(proto),
<                                         NULL, NULL,
<                                         (clasp->flags &
<                                          (JSCLASS_IS_ANONYMOUS |
<                                           JSCLASS_FIXED_BINDING))
<                                         ? JSPROP_READONLY | JSPROP_PERMANENT
<                                         : 0,
<                                         NULL);
<             if (!named)
<                 goto bad;
<         }
< 
---
>         /* Lacking a constructor, name the prototype (e.g., Math). */
>         named = OBJ_DEFINE_PROPERTY(cx, obj, (jsid)atom, OBJECT_TO_JSVAL(proto),
>                                     NULL, NULL, 0, NULL);
>         if (!named)
>             goto bad;
2681,2684c1852
<         fun = js_DefineFunction(cx, obj, atom, constructor, nargs,
<                                 (clasp->flags & JSCLASS_FIXED_BINDING)
<                                 ? JSPROP_READONLY | JSPROP_PERMANENT
<                                 : 0);
---
>         fun = js_DefineFunction(cx, obj, atom, constructor, nargs, 0);
2694,2709c1862
<         fun->u.n.clasp = clasp;
< 
<         /*
<          * Optionally construct the prototype object, before the class has
<          * been fully initialized.  Allow the ctor to replace proto with a
<          * different object, as is done for operator new -- and as at least
<          * XML support requires.
<          */
<         ctor = fun->object;
<         if (clasp->flags & JSCLASS_CONSTRUCT_PROTOTYPE) {
<             cval = OBJECT_TO_JSVAL(ctor);
<             if (!js_InternalConstruct(cx, proto, cval, 0, NULL, &rval))
<                 goto bad;
<             if (!JSVAL_IS_PRIMITIVE(rval) && JSVAL_TO_OBJECT(rval) != proto)
<                 proto = JSVAL_TO_OBJECT(rval);
<         }
---
>         fun->clasp = clasp;
2711a1865
>         ctor = fun->object;
2719c1873,1876
<             JS_ASSERT(!OBJ_GET_PROTO(cx, ctor));
---
>             /* XXXMLM - this fails in framesets that are writing over
>              *           themselves!
>              * JS_ASSERT(!OBJ_GET_PROTO(cx, ctor));
>              */
2731,2737d1887
< 
<     /* If this is a standard class, cache its prototype. */
<     if (key != JSProto_Null && !js_SetClassObject(cx, obj, key, ctor))
<         goto bad;
< 
< out:
<     JS_POP_TEMP_ROOT(cx, &tvr);
2742,2744c1892,1894
<         (void) OBJ_DELETE_PROPERTY(cx, obj, ATOM_TO_JSID(atom), &rval);
<     proto = NULL;
<     goto out;
---
>         (void) OBJ_DELETE_PROPERTY(cx, obj, (jsid)atom, &junk);
>     cx->newborn[GCX_OBJECT] = NULL;
>     return NULL;
2751c1901,1902
<     return OBJ_GET_CLASS(cx, obj);
---
>     return (JSClass *)
>         JSVAL_TO_PRIVATE(GC_AWARE_GET_SLOT(cx, obj, JSSLOT_CLASS));
2770c1921
<         fun = js_ValueToFunction(cx, &argv[-2], 0);
---
>         fun = js_ValueToFunction(cx, &argv[-2], JS_FALSE);
2781,2786d1931
< JS_PUBLIC_API(JSBool)
< JS_HasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp)
< {
<     return js_HasInstance(cx, obj, v, bp);
< }
< 
2793c1938
<     v = obj->fslots[JSSLOT_PRIVATE];
---
>     v = GC_AWARE_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
2803c1948
<     obj->fslots[JSSLOT_PRIVATE] = PRIVATE_TO_JSVAL(data);
---
>     OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, PRIVATE_TO_JSVAL(data));
2822c1967
<     proto = OBJ_GET_PROTO(cx, obj);
---
>     proto = JSVAL_TO_OBJECT(GC_AWARE_GET_SLOT(cx, obj, JSSLOT_PROTO));
2832,2841d1976
< #ifdef DEBUG
<     /*
<      * FIXME: bug 408416. The cycle-detection required for script-writeable
<      * __proto__ lives in js_SetProtoOrParent over in jsobj.c, also known as
<      * js_ObjectOps.setProto. This hook must detect cycles, to prevent scripts
<      * from ilooping SpiderMonkey trivially. But the overhead of detecting
<      * cycles is high enough, and the threat from JS-API-calling C++ code is
<      * low enough, that it's not worth burdening the non-DEBUG callers. Same
<      * goes for JS_SetParent, below.
<      */
2844,2853c1979
<     OBJ_SET_PROTO(cx, obj, proto);
< #else
<     JS_LOCK_OBJ(cx, obj);
<     if (OBJ_IS_NATIVE(obj) && !js_GetMutableScope(cx, obj)) {
<         JS_UNLOCK_OBJ(cx, obj);
<         return JS_FALSE;
<     }
<     LOCKED_OBJ_SET_PROTO(obj, proto);
<     JS_UNLOCK_OBJ(cx, obj);
< #endif
---
>     OBJ_SET_SLOT(cx, obj, JSSLOT_PROTO, OBJECT_TO_JSVAL(proto));
2862c1988
<     parent = OBJ_GET_PARENT(cx, obj);
---
>     parent = JSVAL_TO_OBJECT(GC_AWARE_GET_SLOT(cx, obj, JSSLOT_PARENT));
2872,2873d1997
< #ifdef DEBUG
<     /* FIXME: bug 408416, see JS_SetPrototype just above. */
2876,2877c2000
< #endif
<     OBJ_SET_PARENT(cx, obj, parent);
---
>     OBJ_SET_SLOT(cx, obj, JSSLOT_PARENT, OBJECT_TO_JSVAL(parent));
2888c2011
<                           ATOM_TO_JSID(cx->runtime->atomState.constructorAtom),
---
>                           (jsid)cx->runtime->atomState.constructorAtom,
2892c2015
<     if (!VALUE_IS_FUNCTION(cx, cval)) {
---
>     if (!JSVAL_IS_FUNCTION(cx, cval)) {
2900,2907d2022
< JS_PUBLIC_API(JSBool)
< JS_GetObjectId(JSContext *cx, JSObject *obj, jsid *idp)
< {
<     JS_ASSERT(JSID_IS_OBJECT(obj));
<     *idp = OBJECT_TO_JSID(obj);
<     return JS_TRUE;
< }
< 
2917,2926d2031
< JS_PUBLIC_API(JSObject *)
< JS_NewObjectWithGivenProto(JSContext *cx, JSClass *clasp, JSObject *proto,
<                            JSObject *parent)
< {
<     CHECK_REQUEST(cx);
<     if (!clasp)
<         clasp = &js_ObjectClass;    /* default class is Object */
<     return js_NewObjectWithGivenProto(cx, clasp, proto, parent);
< }
< 
2932,2933c2037,2038
<     uint32 nslots, i;
<     jsval v;
---
>     uint32 nslots;
>     jsval v, *vp, *end;
2941a2047
>     /* Nothing to do if obj's scope is already sealed. */
2943,2951c2049,2050
< 
< #if defined JS_THREADSAFE && defined DEBUG
<     /* Insist on scope being used exclusively by cx's thread. */
<     if (scope->ownercx != cx) {
<         JS_LOCK_OBJ(cx, obj);
<         JS_ASSERT(OBJ_SCOPE(obj) == scope);
<         JS_ASSERT(scope->ownercx == cx);
<         JS_UNLOCK_SCOPE(cx, scope);
<     }
---
> #ifdef JS_THREADSAFE
>     JS_ASSERT(scope->ownercx == cx);
2953,2954d2051
< 
<     /* Nothing to do if obj's scope is already sealed. */
2967c2064
<     if (scope) {
---
>     if (scope)
2969,2971c2066
<         SCOPE_GENERATE_PCTYPE(cx, scope);
<     }
<     JS_UNLOCK_OBJ(cx, obj);
---
>     JS_UNLOCK_SCOPE(cx, scope);
2979,2982c2074,2077
<     /* Walk slots in obj and if any value is a non-null object, seal it. */
<     nslots = LOCKED_OBJ_NSLOTS(obj);
<     for (i = 0; i != nslots; ++i) {
<         v = STOBJ_GET_SLOT(obj, i);
---
>     /* Walk obj->slots and if any value is a non-null object, seal it. */
>     nslots = JS_MIN(scope->map.freeslot, scope->map.nslots);
>     for (vp = obj->slots, end = vp + nslots; vp < end; vp++) {
>         v = *vp;
2990a2086,2125
> JS_PUBLIC_API(JSBool)
> JS_UnsealObject(JSContext *cx, JSObject *obj, JSBool deep)
> {
>     JSScope *scope;
>     uint32 nslots;
>     jsval v, *vp, *end;
> 
>     if (!OBJ_IS_NATIVE(obj)) {
>         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
>                              JSMSG_CANT_UNSEAL_OBJECT,
>                              OBJ_GET_CLASS(cx, obj)->name);
>         return JS_FALSE;
>     }
> 
>     scope = OBJ_SCOPE(obj);
> #ifdef JS_THREADSAFE
>     JS_ASSERT(scope->ownercx == cx);
> #endif
>     if (!SCOPE_IS_SEALED(scope))
>         return JS_TRUE;
> 
>     JS_ASSERT(scope == OBJ_SCOPE(obj));
>     JS_LOCK_SCOPE(cx, scope);
>     SCOPE_CLR_SEALED(scope);
>     JS_UNLOCK_SCOPE(cx, scope);
> 
>     if (!deep)
>         return JS_TRUE;
> 
>     nslots = JS_MIN(scope->map.freeslot, scope->map.nslots);
>     for (vp = obj->slots, end = vp + nslots; vp < end; vp++) {
>         v = *vp;
>         if (JSVAL_IS_PRIMITIVE(v))
>             continue;
>         if (!JS_UnsealObject(cx, JSVAL_TO_OBJECT(v), deep))
>             return JS_FALSE;
>     }
>     return JS_TRUE;
> }
> 
3020c2155
<         id = INT_TO_JSID(JS_PTR_TO_INT32(name));
---
>         id = INT_TO_JSVAL((jsint)name);
3027c2162
<         id = ATOM_TO_JSID(atom);
---
>         id = (jsid)atom;
3047c2182
<     atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
---
>     atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name,namelen), 0);
3051c2186
<         return js_DefineNativeProperty(cx, obj, ATOM_TO_JSID(atom), value,
---
>         return js_DefineNativeProperty(cx, obj, (jsid)atom, value,
3055,3056c2190,2191
<     return OBJ_DEFINE_PROPERTY(cx, obj, ATOM_TO_JSID(atom), value,
<                                getter, setter, attrs, NULL);
---
>     return OBJ_DEFINE_PROPERTY(cx, obj, (jsid)atom, value, getter, setter,
>                                attrs, NULL);
3073c2208
<         cx->weakRoots.newborn[GCX_OBJECT] = NULL;
---
>         cx->newborn[GCX_OBJECT] = NULL;
3145c2280
<     return OBJ_LOOKUP_PROPERTY(cx, obj, ATOM_TO_JSID(atom), objp, propp);
---
>     return OBJ_LOOKUP_PROPERTY(cx, obj, (jsid)atom, objp, propp);
3155c2290
<     atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
---
>     atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name,namelen), 0);
3158c2293
<     return OBJ_LOOKUP_PROPERTY(cx, obj, ATOM_TO_JSID(atom), objp, propp);
---
>     return OBJ_LOOKUP_PROPERTY(cx, obj, (jsid)atom, objp, propp);
3189c2324
<         ok = (js_AddNativeProperty(cx, obj, ATOM_TO_JSID(atom),
---
>         ok = (js_AddNativeProperty(cx, obj, (jsid)atom,
3225,3226c2360
<                       uintN *attrsp, JSBool *foundp,
<                       JSPropertyOp *getterp, JSPropertyOp *setterp)
---
>                       uintN *attrsp, JSBool *foundp)
3234c2368
<     if (!OBJ_LOOKUP_PROPERTY(cx, obj, ATOM_TO_JSID(atom), &obj2, &prop))
---
>     if (!OBJ_LOOKUP_PROPERTY(cx, obj, (jsid)atom, &obj2, &prop))
3236d2369
< 
3238d2370
<         *attrsp = 0;
3240,3243d2371
<         if (getterp)
<             *getterp = NULL;
<         if (setterp)
<             *setterp = NULL;
3250,3258c2378
<     ok = OBJ_GET_ATTRIBUTES(cx, obj, ATOM_TO_JSID(atom), prop, attrsp);
<     if (ok && OBJ_IS_NATIVE(obj)) {
<         JSScopeProperty *sprop = (JSScopeProperty *) prop;
< 
<         if (getterp)
<             *getterp = sprop->getter;
<         if (setterp)
<             *setterp = sprop->setter;
<     }
---
>     ok = OBJ_GET_ATTRIBUTES(cx, obj, (jsid)atom, prop, attrsp);
3273c2393
<     if (!OBJ_LOOKUP_PROPERTY(cx, obj, ATOM_TO_JSID(atom), &obj2, &prop))
---
>     if (!OBJ_LOOKUP_PROPERTY(cx, obj, (jsid)atom, &obj2, &prop))
3283c2403
<     ok = OBJ_SET_ATTRIBUTES(cx, obj, ATOM_TO_JSID(atom), prop, &attrs);
---
>     ok = OBJ_SET_ATTRIBUTES(cx, obj, (jsid)atom, prop, &attrs);
3287a2408
> 
3295,3308c2416
<                                  attrsp, foundp, NULL, NULL);
< }
< 
< JS_PUBLIC_API(JSBool)
< JS_GetPropertyAttrsGetterAndSetter(JSContext *cx, JSObject *obj,
<                                    const char *name,
<                                    uintN *attrsp, JSBool *foundp,
<                                    JSPropertyOp *getterp,
<                                    JSPropertyOp *setterp)
< {
<     CHECK_REQUEST(cx);
<     return GetPropertyAttributes(cx, obj,
<                                  js_Atomize(cx, name, strlen(name), 0),
<                                  attrsp, foundp, getterp, setterp);
---
>                                  attrsp, foundp);
3321,3375d2428
< static JSBool
< AlreadyHasOwnPropertyHelper(JSContext *cx, JSObject *obj, jsid id,
<                             JSBool *foundp)
< {
<     JSScope *scope;
< 
<     if (!OBJ_IS_NATIVE(obj)) {
<         JSObject *obj2;
<         JSProperty *prop;
< 
<         if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop))
<             return JS_FALSE;
<         *foundp = (obj == obj2);
<         if (prop)
<             OBJ_DROP_PROPERTY(cx, obj2, prop);
<         return JS_TRUE;
<     }
< 
<     JS_LOCK_OBJ(cx, obj);
<     scope = OBJ_SCOPE(obj);
<     *foundp = (scope->object == obj && SCOPE_GET_PROPERTY(scope, id));
<     JS_UNLOCK_SCOPE(cx, scope);
<     return JS_TRUE;
< }
< 
< JS_PUBLIC_API(JSBool)
< JS_AlreadyHasOwnProperty(JSContext *cx, JSObject *obj, const char *name,
<                          JSBool *foundp)
< {
<     JSAtom *atom;
< 
<     CHECK_REQUEST(cx);
<     atom = js_Atomize(cx, name, strlen(name), 0);
<     if (!atom)
<         return JS_FALSE;
<     return AlreadyHasOwnPropertyHelper(cx, obj, ATOM_TO_JSID(atom), foundp);
< }
< 
< JS_PUBLIC_API(JSBool)
< JS_HasProperty(JSContext *cx, JSObject *obj, const char *name, JSBool *foundp)
< {
<     JSBool ok;
<     JSObject *obj2;
<     JSProperty *prop;
< 
<     CHECK_REQUEST(cx);
<     ok = LookupProperty(cx, obj, name, &obj2, &prop);
<     if (ok) {
<         *foundp = (prop != NULL);
<         if (prop)
<             OBJ_DROP_PROPERTY(cx, obj2, prop);
<     }
<     return ok;
< }
< 
3391,3412d2443
< JS_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, const char *name,
<                            uintN flags, jsval *vp)
< {
<     JSAtom *atom;
<     JSBool ok;
<     JSObject *obj2;
<     JSProperty *prop;
< 
<     CHECK_REQUEST(cx);
<     atom = js_Atomize(cx, name, strlen(name), 0);
<     if (!atom)
<         return JS_FALSE;
<     ok = OBJ_IS_NATIVE(obj)
<          ? js_LookupPropertyWithFlags(cx, obj, ATOM_TO_JSID(atom), flags,
<                                       &obj2, &prop) >= 0
<          : OBJ_LOOKUP_PROPERTY(cx, obj, ATOM_TO_JSID(atom), &obj2, &prop);
<     if (ok)
<         *vp = LookupResult(cx, obj, obj2, prop);
<     return ok;
< }
< 
< JS_PUBLIC_API(JSBool)
3421,3458c2452
<     return OBJ_GET_PROPERTY(cx, obj, ATOM_TO_JSID(atom), vp);
< }
< 
< JS_PUBLIC_API(JSBool)
< JS_GetMethodById(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
<                  jsval *vp)
< {
<     CHECK_REQUEST(cx);
< 
< #if JS_HAS_XML_SUPPORT
<     if (OBJECT_IS_XML(cx, obj)) {
<         JSXMLObjectOps *ops;
< 
<         ops = (JSXMLObjectOps *) obj->map->ops;
<         obj = ops->getMethod(cx, obj, id, vp);
<         if (!obj)
<             return JS_FALSE;
<     } else
< #endif
<     {
<         if (!OBJ_GET_PROPERTY(cx, obj, id, vp))
<             return JS_FALSE;
<     }
< 
<     *objp = obj;
<     return JS_TRUE;
< }
< 
< JS_PUBLIC_API(JSBool)
< JS_GetMethod(JSContext *cx, JSObject *obj, const char *name, JSObject **objp,
<              jsval *vp)
< {
<     JSAtom *atom;
< 
<     atom = js_Atomize(cx, name, strlen(name), 0);
<     if (!atom)
<         return JS_FALSE;
<     return JS_GetMethodById(cx, obj, ATOM_TO_JSID(atom), objp, vp);
---
>     return OBJ_GET_PROPERTY(cx, obj, (jsid)atom, vp);
3470c2464
<     return OBJ_SET_PROPERTY(cx, obj, ATOM_TO_JSID(atom), vp);
---
>     return OBJ_SET_PROPERTY(cx, obj, (jsid)atom, vp);
3492c2486
<     return OBJ_DELETE_PROPERTY(cx, obj, ATOM_TO_JSID(atom), rval);
---
>     return OBJ_DELETE_PROPERTY(cx, obj, (jsid)atom, rval);
3513,3527c2507,2508
<                     js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0),
<                     attrsp, foundp, NULL, NULL);
< }
< 
< JS_PUBLIC_API(JSBool)
< JS_GetUCPropertyAttrsGetterAndSetter(JSContext *cx, JSObject *obj,
<                                      const jschar *name, size_t namelen,
<                                      uintN *attrsp, JSBool *foundp,
<                                      JSPropertyOp *getterp,
<                                      JSPropertyOp *setterp)
< {
<     CHECK_REQUEST(cx);
<     return GetPropertyAttributes(cx, obj,
<                     js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0),
<                     attrsp, foundp, getterp, setterp);
---
>                     js_AtomizeChars(cx, name, AUTO_NAMELEN(name,namelen), 0),
>                     attrsp, foundp);
3537c2518
<                     js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0),
---
>                     js_AtomizeChars(cx, name, AUTO_NAMELEN(name,namelen), 0),
3554,3586d2534
< JS_AlreadyHasOwnUCProperty(JSContext *cx, JSObject *obj,
<                            const jschar *name, size_t namelen,
<                            JSBool *foundp)
< {
<     JSAtom *atom;
< 
<     CHECK_REQUEST(cx);
<     atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
<     if (!atom)
<         return JS_FALSE;
<     return AlreadyHasOwnPropertyHelper(cx, obj, ATOM_TO_JSID(atom), foundp);
< }
< 
< JS_PUBLIC_API(JSBool)
< JS_HasUCProperty(JSContext *cx, JSObject *obj,
<                  const jschar *name, size_t namelen,
<                  JSBool *vp)
< {
<     JSBool ok;
<     JSObject *obj2;
<     JSProperty *prop;
< 
<     CHECK_REQUEST(cx);
<     ok = LookupUCProperty(cx, obj, name, namelen, &obj2, &prop);
<     if (ok) {
<         *vp = (prop != NULL);
<         if (prop)
<             OBJ_DROP_PROPERTY(cx, obj2, prop);
<     }
<     return ok;
< }
< 
< JS_PUBLIC_API(JSBool)
3610c2558
<     atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
---
>     atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name,namelen), 0);
3613c2561
<     return OBJ_GET_PROPERTY(cx, obj, ATOM_TO_JSID(atom), vp);
---
>     return OBJ_GET_PROPERTY(cx, obj, (jsid)atom, vp);
3624c2572
<     atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
---
>     atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name,namelen), 0);
3627c2575
<     return OBJ_SET_PROPERTY(cx, obj, ATOM_TO_JSID(atom), vp);
---
>     return OBJ_SET_PROPERTY(cx, obj, (jsid)atom, vp);
3638c2586
<     atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
---
>     atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name,namelen), 0);
3641c2589
<     return OBJ_DELETE_PROPERTY(cx, obj, ATOM_TO_JSID(atom), rval);
---
>     return OBJ_DELETE_PROPERTY(cx, obj, (jsid)atom, rval);
3684c2632
<     return OBJ_DEFINE_PROPERTY(cx, obj, INT_TO_JSID(index), value,
---
>     return OBJ_DEFINE_PROPERTY(cx, obj, INT_TO_JSVAL(index), value,
3712c2660
<     ok = (js_AddNativeProperty(cx, obj, INT_TO_JSID(alias),
---
>     ok = (js_AddNativeProperty(cx, obj, INT_TO_JSVAL(alias),
3722,3745d2669
< JS_AlreadyHasOwnElement(JSContext *cx, JSObject *obj, jsint index,
<                         JSBool *foundp)
< {
<     return AlreadyHasOwnPropertyHelper(cx, obj, INT_TO_JSID(index), foundp);
< }
< 
< JS_PUBLIC_API(JSBool)
< JS_HasElement(JSContext *cx, JSObject *obj, jsint index, JSBool *foundp)
< {
<     JSBool ok;
<     JSObject *obj2;
<     JSProperty *prop;
< 
<     CHECK_REQUEST(cx);
<     ok = OBJ_LOOKUP_PROPERTY(cx, obj, INT_TO_JSID(index), &obj2, &prop);
<     if (ok) {
<         *foundp = (prop != NULL);
<         if (prop)
<             OBJ_DROP_PROPERTY(cx, obj2, prop);
<     }
<     return ok;
< }
< 
< JS_PUBLIC_API(JSBool)
3753c2677
<     ok = OBJ_LOOKUP_PROPERTY(cx, obj, INT_TO_JSID(index), &obj2, &prop);
---
>     ok = OBJ_LOOKUP_PROPERTY(cx, obj, INT_TO_JSVAL(index), &obj2, &prop);
3763c2687
<     return OBJ_GET_PROPERTY(cx, obj, INT_TO_JSID(index), vp);
---
>     return OBJ_GET_PROPERTY(cx, obj, INT_TO_JSVAL(index), vp);
3770c2694
<     return OBJ_SET_PROPERTY(cx, obj, INT_TO_JSID(index), vp);
---
>     return OBJ_SET_PROPERTY(cx, obj, INT_TO_JSVAL(index), vp);
3786c2710
<     return OBJ_DELETE_PROPERTY(cx, obj, INT_TO_JSID(index), rval);
---
>     return OBJ_DELETE_PROPERTY(cx, obj, INT_TO_JSVAL(index), rval);
3796,3803d2719
< 
<     /* Clear cached class objects on the global object. */
<     if (OBJ_GET_CLASS(cx, obj)->flags & JSCLASS_IS_GLOBAL) {
<         int key;
< 
<         for (key = JSProto_Null; key < JSProto_LIMIT; key++)
<             JS_SetReservedSlot(cx, obj, key, JSVAL_VOID);
<     }
3840c2756,2765
<     for (;;) {
---
>     while (1) {
>         if (i == ida->length) {
>             /* Grow length by factor of 1.5 instead of doubling. */
>             jsint newlen = ida->length + (((jsuint)ida->length + 1) >> 1);
>             ida = js_GrowIdArray(cx, ida, newlen);
>             if (!ida)
>                 goto error;
>             vector = &ida->vector[0];
>         }
> 
3847,3853d2771
< 
<         if (i == ida->length) {
<             ida = js_SetIdArrayLength(cx, ida, ida->length * 2);
<             if (!ida)
<                 goto error;
<             vector = &ida->vector[0];
<         }
3856c2774,2775
<     return js_SetIdArrayLength(cx, ida, i);
---
>     ida->length = i;
>     return ida;
3866,3880c2785,2787
< /*
<  * XXX reverse iterator for properties, unreverse and meld with jsinterp.c's
<  *     prop_iterator_class somehow...
<  * + preserve the OBJ_ENUMERATE API while optimizing the native object case
<  * + native case here uses a JSScopeProperty *, but that iterates in reverse!
<  * + so we make non-native match, by reverse-iterating after JS_Enumerating
<  */
< #define JSSLOT_ITER_INDEX       (JSSLOT_PRIVATE + 1)
< 
< #if JSSLOT_ITER_INDEX >= JS_INITIAL_NSLOTS
< # error "JSSLOT_ITER_INDEX botch!"
< #endif
< 
< static void
< prop_iter_finalize(JSContext *cx, JSObject *obj)
---
> JS_PUBLIC_API(JSBool)
> JS_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
>                jsval *vp, uintN *attrsp)
3882,3896c2789,2790
<     jsval v;
<     jsint i;
<     JSIdArray *ida;
< 
<     v = obj->fslots[JSSLOT_ITER_INDEX];
<     if (JSVAL_IS_VOID(v))
<         return;
< 
<     i = JSVAL_TO_INT(v);
<     if (i >= 0) {
<         /* Non-native case: destroy the ida enumerated when obj was created. */
<         ida = (JSIdArray *) JS_GetPrivate(cx, obj);
<         if (ida)
<             JS_DestroyIdArray(cx, ida);
<     }
---
>     CHECK_REQUEST(cx);
>     return OBJ_CHECK_ACCESS(cx, obj, id, mode, vp, attrsp);
3899,3900c2793,2794
< static void
< prop_iter_trace(JSTracer *trc, JSObject *obj)
---
> JS_PUBLIC_API(JSCheckAccessOp)
> JS_SetCheckObjectAccessCallback(JSRuntime *rt, JSCheckAccessOp acb)
3902,3909c2796
<     jsval v;
<     jsint i, n;
<     JSScopeProperty *sprop;
<     JSIdArray *ida;
<     jsid id;
< 
<     v = obj->fslots[JSSLOT_PRIVATE];
<     JS_ASSERT(!JSVAL_IS_VOID(v));
---
>     JSCheckAccessOp oldacb;
3911,3924c2798,2800
<     i = JSVAL_TO_INT(obj->fslots[JSSLOT_ITER_INDEX]);
<     if (i < 0) {
<         /* Native case: just mark the next property to visit. */
<         sprop = (JSScopeProperty *) JSVAL_TO_PRIVATE(v);
<         if (sprop)
<             TRACE_SCOPE_PROPERTY(trc, sprop);
<     } else {
<         /* Non-native case: mark each id in the JSIdArray private. */
<         ida = (JSIdArray *) JSVAL_TO_PRIVATE(v);
<         for (i = 0, n = ida->length; i < n; i++) {
<             id = ida->vector[i];
<             TRACE_ID(trc, id);
<         }
<     }
---
>     oldacb = rt->checkObjectAccess;
>     rt->checkObjectAccess = acb;
>     return oldacb;
3927,3938c2803,2804
< static JSClass prop_iter_class = {
<     "PropertyIterator",
<     JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(1) |
<     JSCLASS_MARK_IS_TRACE,
<     JS_PropertyStub,  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
<     JS_EnumerateStub, JS_ResolveStub,  JS_ConvertStub,  prop_iter_finalize,
<     NULL,             NULL,            NULL,            NULL,
<     NULL,             NULL,            JS_CLASS_TRACE(prop_iter_trace), NULL
< };
< 
< JS_PUBLIC_API(JSObject *)
< JS_NewPropertyIterator(JSContext *cx, JSObject *obj)
---
> JS_PUBLIC_API(JSBool)
> JS_GetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, jsval *vp)
3940,3944c2806,2807
<     JSObject *iterobj;
<     JSScope *scope;
<     void *pdata;
<     jsint index;
<     JSIdArray *ida;
---
>     JSClass *clasp;
>     uint32 slot;
3947,4064c2810,2811
<     iterobj = js_NewObject(cx, &prop_iter_class, NULL, obj);
<     if (!iterobj)
<         return NULL;
< 
<     if (OBJ_IS_NATIVE(obj)) {
<         /* Native case: start with the last property in obj's own scope. */
<         scope = OBJ_SCOPE(obj);
<         pdata = (scope->object == obj) ? scope->lastProp : NULL;
<         index = -1;
<     } else {
<         JSTempValueRooter tvr;
< 
<         /*
<          * Non-native case: enumerate a JSIdArray and keep it via private.
<          *
<          * Note: we have to make sure that we root obj around the call to
<          * JS_Enumerate to protect against multiple allocations under it.
<          */
<         JS_PUSH_SINGLE_TEMP_ROOT(cx, OBJECT_TO_JSVAL(iterobj), &tvr);
<         ida = JS_Enumerate(cx, obj);
<         JS_POP_TEMP_ROOT(cx, &tvr);
<         if (!ida)
<             goto bad;
<         pdata = ida;
<         index = ida->length;
<     }
< 
<     /* iterobj can not escape to other threads here. */
<     STOBJ_SET_SLOT(iterobj, JSSLOT_PRIVATE, PRIVATE_TO_JSVAL(pdata));
<     STOBJ_SET_SLOT(iterobj, JSSLOT_ITER_INDEX, INT_TO_JSVAL(index));
<     return iterobj;
< 
< bad:
<     cx->weakRoots.newborn[GCX_OBJECT] = NULL;
<     return NULL;
< }
< 
< JS_PUBLIC_API(JSBool)
< JS_NextProperty(JSContext *cx, JSObject *iterobj, jsid *idp)
< {
<     jsint i;
<     JSObject *obj;
<     JSScope *scope;
<     JSScopeProperty *sprop;
<     JSIdArray *ida;
< 
<     CHECK_REQUEST(cx);
<     i = JSVAL_TO_INT(OBJ_GET_SLOT(cx, iterobj, JSSLOT_ITER_INDEX));
<     if (i < 0) {
<         /* Native case: private data is a property tree node pointer. */
<         obj = OBJ_GET_PARENT(cx, iterobj);
<         JS_ASSERT(OBJ_IS_NATIVE(obj));
<         scope = OBJ_SCOPE(obj);
<         JS_ASSERT(scope->object == obj);
<         sprop = (JSScopeProperty *) JS_GetPrivate(cx, iterobj);
< 
<         /*
<          * If the next property mapped by scope in the property tree ancestor
<          * line is not enumerable, or it's an alias, or one or more properties
<          * were deleted from the "middle" of the scope-mapped ancestor line
<          * and the next property was among those deleted, skip it and keep on
<          * trying to find an enumerable property that is still in scope.
<          */
<         while (sprop &&
<                (!(sprop->attrs & JSPROP_ENUMERATE) ||
<                 (sprop->flags & SPROP_IS_ALIAS) ||
<                 (SCOPE_HAD_MIDDLE_DELETE(scope) &&
<                  !SCOPE_HAS_PROPERTY(scope, sprop)))) {
<             sprop = sprop->parent;
<         }
< 
<         if (!sprop) {
<             *idp = JSVAL_VOID;
<         } else {
<             if (!JS_SetPrivate(cx, iterobj, sprop->parent))
<                 return JS_FALSE;
<             *idp = sprop->id;
<         }
<     } else {
<         /* Non-native case: use the ida enumerated when iterobj was created. */
<         ida = (JSIdArray *) JS_GetPrivate(cx, iterobj);
<         JS_ASSERT(i <= ida->length);
<         if (i == 0) {
<             *idp = JSVAL_VOID;
<         } else {
<             *idp = ida->vector[--i];
<             STOBJ_SET_SLOT(iterobj, JSSLOT_ITER_INDEX, INT_TO_JSVAL(i));
<         }
<     }
<     return JS_TRUE;
< }
< 
< JS_PUBLIC_API(JSBool)
< JS_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
<                jsval *vp, uintN *attrsp)
< {
<     CHECK_REQUEST(cx);
<     return OBJ_CHECK_ACCESS(cx, obj, id, mode, vp, attrsp);
< }
< 
< JS_PUBLIC_API(JSCheckAccessOp)
< JS_SetCheckObjectAccessCallback(JSRuntime *rt, JSCheckAccessOp acb)
< {
<     JSCheckAccessOp oldacb;
< 
<     oldacb = rt->checkObjectAccess;
<     rt->checkObjectAccess = acb;
<     return oldacb;
< }
< 
< static JSBool
< ReservedSlotIndexOK(JSContext *cx, JSObject *obj, JSClass *clasp,
<                     uint32 index, uint32 limit)
< {
<     /* Check the computed, possibly per-instance, upper bound. */
<     if (clasp->reserveSlots)
<         JS_LOCK_OBJ_VOID(cx, obj, limit += clasp->reserveSlots(cx, obj));
<     if (index >= limit) {
---
>     clasp = OBJ_GET_CLASS(cx, obj);
>     if (index >= JSCLASS_RESERVED_SLOTS(clasp)) {
4069,4082d2815
<     return JS_TRUE;
< }
< 
< JS_PUBLIC_API(JSBool)
< JS_GetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, jsval *vp)
< {
<     JSClass *clasp;
<     uint32 limit, slot;
< 
<     CHECK_REQUEST(cx);
<     clasp = OBJ_GET_CLASS(cx, obj);
<     limit = JSCLASS_RESERVED_SLOTS(clasp);
<     if (index >= limit && !ReservedSlotIndexOK(cx, obj, clasp, index, limit))
<         return JS_FALSE;
4092c2825
<     uint32 limit, slot;
---
>     uint32 slot;
4096,4097c2829,2831
<     limit = JSCLASS_RESERVED_SLOTS(clasp);
<     if (index >= limit && !ReservedSlotIndexOK(cx, obj, clasp, index, limit))
---
>     if (index >= JSCLASS_RESERVED_SLOTS(clasp)) {
>         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
>                              JSMSG_RESERVED_SLOT_RANGE);
4098a2833
>     }
4100,4116c2835,2836
<     return OBJ_SET_REQUIRED_SLOT(cx, obj, slot, v);
< }
< 
< #ifdef JS_THREADSAFE
< JS_PUBLIC_API(jsrefcount)
< JS_HoldPrincipals(JSContext *cx, JSPrincipals *principals)
< {
<     return JS_ATOMIC_INCREMENT(&principals->refcount);
< }
< 
< JS_PUBLIC_API(jsrefcount)
< JS_DropPrincipals(JSContext *cx, JSPrincipals *principals)
< {
<     jsrefcount rc = JS_ATOMIC_DECREMENT(&principals->refcount);
<     if (rc == 0)
<         principals->destroy(cx, principals);
<     return rc;
---
>     OBJ_SET_REQUIRED_SLOT(cx, obj, slot, v);
>     return JS_TRUE;
4118d2837
< #endif
4130,4139d2848
< JS_PUBLIC_API(JSObjectPrincipalsFinder)
< JS_SetObjectPrincipalsFinder(JSRuntime *rt, JSObjectPrincipalsFinder fop)
< {
<     JSObjectPrincipalsFinder oldfop;
< 
<     oldfop = rt->findObjectPrincipals;
<     rt->findObjectPrincipals = fop;
<     return oldfop;
< }
< 
4192,4200d2900
< #ifdef MOZILLA_1_8_BRANCH
<     uintN flags = fun->flags;
< 
<     return JSFUN_DISJOINT_FLAGS(flags) |
<            (JSFUN_GETTER_TEST(flags) ? JSFUN_GETTER : 0) |
<            (JSFUN_SETTER_TEST(flags) ? JSFUN_SETTER : 0) |
<            (JSFUN_BOUND_METHOD_TEST(flags) ? JSFUN_BOUND_METHOD : 0) |
<            (JSFUN_HEAVYWEIGHT_TEST(flags) ? JSFUN_HEAVYWEIGHT : 0);
< #else
4202,4208d2901
< #endif
< }
< 
< JS_PUBLIC_API(uint16)
< JS_GetFunctionArity(JSFunction *fun)
< {
<     return fun->nargs;
4217,4327d2909
< JS_STATIC_DLL_CALLBACK(JSBool)
< js_generic_fast_native_method_dispatcher(JSContext *cx, uintN argc, jsval *vp)
< {
<     jsval fsv;
<     JSFunctionSpec *fs;
<     JSObject *tmp;
< 
<     if (!JS_GetReservedSlot(cx, JSVAL_TO_OBJECT(*vp), 0, &fsv))
<         return JS_FALSE;
<     fs = (JSFunctionSpec *) JSVAL_TO_PRIVATE(fsv);
<     JS_ASSERT((~fs->flags & (JSFUN_FAST_NATIVE | JSFUN_GENERIC_NATIVE)) == 0);
< 
<     /*
<      * We know that vp[2] is valid because JS_DefineFunctions, which is our
<      * only (indirect) referrer, defined us as requiring at least one argument
<      * (notice how it passes fs->nargs + 1 as the next-to-last argument to
<      * JS_DefineFunction).
<      */
<     if (JSVAL_IS_PRIMITIVE(vp[2])) {
<         /*
<          * Make sure that this is an object or null, as required by the generic
<          * functions.
<          */
<         if (!js_ValueToObject(cx, vp[2], &tmp))
<             return JS_FALSE;
<         vp[2] = OBJECT_TO_JSVAL(tmp);
<     }
< 
<     /*
<      * Copy all actual (argc) arguments down over our |this| parameter, vp[1],
<      * which is almost always the class constructor object, e.g. Array.  Then
<      * call the corresponding prototype native method with our first argument
<      * passed as |this|.
<      */
<     memmove(vp + 1, vp + 2, argc * sizeof(jsval));
< 
<     /*
<      * Follow Function.prototype.apply and .call by using the global object as
<      * the 'this' param if no args.
<      */
<     if (!js_ComputeThis(cx, vp + 2))
<         return JS_FALSE;
<     /*
<      * Protect against argc underflowing. By calling js_ComputeThis, we made
<      * it as if the static was called with one parameter, the explicit |this|
<      * object.
<      */
<     if (argc != 0)
<         --argc;
< 
<     return ((JSFastNative) fs->call)(cx, argc, vp);
< }
< 
< JS_STATIC_DLL_CALLBACK(JSBool)
< js_generic_native_method_dispatcher(JSContext *cx, JSObject *obj,
<                                     uintN argc, jsval *argv, jsval *rval)
< {
<     jsval fsv;
<     JSFunctionSpec *fs;
<     JSObject *tmp;
< 
<     if (!JS_GetReservedSlot(cx, JSVAL_TO_OBJECT(argv[-2]), 0, &fsv))
<         return JS_FALSE;
<     fs = (JSFunctionSpec *) JSVAL_TO_PRIVATE(fsv);
<     JS_ASSERT((fs->flags & (JSFUN_FAST_NATIVE | JSFUN_GENERIC_NATIVE)) ==
<               JSFUN_GENERIC_NATIVE);
< 
<     /*
<      * We know that argv[0] is valid because JS_DefineFunctions, which is our
<      * only (indirect) referrer, defined us as requiring at least one argument
<      * (notice how it passes fs->nargs + 1 as the next-to-last argument to
<      * JS_DefineFunction).
<      */
<     if (JSVAL_IS_PRIMITIVE(argv[0])) {
<         /*
<          * Make sure that this is an object or null, as required by the generic
<          * functions.
<          */
<         if (!js_ValueToObject(cx, argv[0], &tmp))
<             return JS_FALSE;
<         argv[0] = OBJECT_TO_JSVAL(tmp);
<     }
< 
<     /*
<      * Copy all actual (argc) arguments down over our |this| parameter,
<      * argv[-1], which is almost always the class constructor object, e.g.
<      * Array.  Then call the corresponding prototype native method with our
<      * first argument passed as |this|.
<      */
<     memmove(argv - 1, argv, argc * sizeof(jsval));
< 
<     /*
<      * Follow Function.prototype.apply and .call by using the global object as
<      * the 'this' param if no args.
<      */
<     JS_ASSERT(cx->fp->argv == argv);
<     if (!js_ComputeThis(cx, argv))
<         return JS_FALSE;
<     cx->fp->thisp = JSVAL_TO_OBJECT(argv[-1]);
< 
<     /*
<      * Protect against argc underflowing. By calling js_ComputeThis, we made
<      * it as if the static was called with one parameter, the explicit |this|
<      * object.
<      */
<     if (argc != 0)
<         --argc;
< 
<     return fs->call(cx, JSVAL_TO_OBJECT(argv[-1]), argc, argv, rval);
< }
< 
4331,4332d2912
<     uintN flags;
<     JSObject *ctor;
4336d2915
<     ctor = NULL;
4338,4373c2917,2918
<         flags = fs->flags;
< 
<         /*
<          * Define a generic arity N+1 static method for the arity N prototype
<          * method if flags contains JSFUN_GENERIC_NATIVE.
<          */
<         if (flags & JSFUN_GENERIC_NATIVE) {
<             if (!ctor) {
<                 ctor = JS_GetConstructor(cx, obj);
<                 if (!ctor)
<                     return JS_FALSE;
<             }
< 
<             flags &= ~JSFUN_GENERIC_NATIVE;
<             fun = JS_DefineFunction(cx, ctor, fs->name,
<                                     (flags & JSFUN_FAST_NATIVE)
<                                     ? (JSNative)
<                                       js_generic_fast_native_method_dispatcher
<                                     : js_generic_native_method_dispatcher,
<                                     fs->nargs + 1, flags);
<             if (!fun)
<                 return JS_FALSE;
<             fun->u.n.extra = (uint16)fs->extra;
<             fun->u.n.minargs = (uint16)(fs->extra >> 16);
< 
<             /*
<              * As jsapi.h notes, fs must point to storage that lives as long
<              * as fun->object lives.
<              */
<             if (!JS_SetReservedSlot(cx, fun->object, 0, PRIVATE_TO_JSVAL(fs)))
<                 return JS_FALSE;
<         }
< 
<         JS_ASSERT(!(flags & JSFUN_FAST_NATIVE) ||
<                   (uint16)(fs->extra >> 16) <= fs->nargs);
<         fun = JS_DefineFunction(cx, obj, fs->name, fs->call, fs->nargs, flags);
---
>         fun = JS_DefineFunction(cx, obj, fs->name, fs->call, fs->nargs,
>                                 fs->flags);
4376,4377c2921
<         fun->u.n.extra = (uint16)fs->extra;
<         fun->u.n.minargs = (uint16)(fs->extra >> 16);
---
>         fun->extra = fs->extra;
4395,4398c2939,2941
< JS_PUBLIC_API(JSFunction *)
< JS_DefineUCFunction(JSContext *cx, JSObject *obj,
<                     const jschar *name, size_t namelen, JSNative call,
<                     uintN nargs, uintN attrs)
---
> static JSScript *
> CompileTokenStream(JSContext *cx, JSObject *obj, JSTokenStream *ts,
>                    void *tempMark, JSBool *eofp)
4400c2943,2945
<     JSAtom *atom;
---
>     JSBool eof;
>     JSCodeGenerator cg;
>     JSScript *script;
4402,4403c2947,2986
<     atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
<     if (!atom)
---
>     CHECK_REQUEST(cx);
>     eof = JS_FALSE;
>     if (!js_InitCodeGenerator(cx, &cg, ts->filename, ts->lineno,
>                               ts->principals)) {
>         script = NULL;
>         goto out;
>     }
>     if (!js_CompileTokenStream(cx, obj, ts, &cg)) {
>         script = NULL;
>         eof = (ts->flags & TSF_EOF) != 0;
>         goto out;
>     }
>     script = js_NewScriptFromCG(cx, &cg, NULL);
> out:
>     if (eofp)
>         *eofp = eof;
>     if (!js_CloseTokenStream(cx, ts)) {
>         if (script)
>             js_DestroyScript(cx, script);
>         script = NULL;
>     }
>     cg.tempMark = tempMark;
>     js_FinishCodeGenerator(cx, &cg);
>     return script;
> }
> 
> 
> #ifdef _UTF8
> JS_PUBLIC_API(JSScript *)
> JS_CompileScript(JSContext *cx, JSObject *obj,
>                  const char *bytes, size_t length,
>                  const char *filename, uintN lineno)
> {
>     jschar *chars;
>     JSScript *script;
> 	size_t wLength;
> 
>     CHECK_REQUEST(cx);
>     chars = js_InflateString(cx, bytes, length, &wLength);
>     if (!chars)
4405c2988,2990
<     return js_DefineFunction(cx, obj, atom, call, nargs, attrs);
---
>     script = JS_CompileUCScript(cx, obj, chars, wLength, filename, lineno);
>     JS_free(cx, chars);
>     return script;
4407a2993
> #else //#ifdef _UTF8
4417c3003
<     chars = js_InflateString(cx, bytes, &length);
---
>     chars = js_InflateString(cx, bytes, length);
4423a3010,3022
> #endif //#ifdef _UTF8
> 
> 
> #ifdef _UTF8
> JS_PUBLIC_API(JSScript *)
> JS_CompileScriptForPrincipals(JSContext *cx, JSObject *obj,
>                               JSPrincipals *principals,
>                               const char *bytes, size_t length,
>                               const char *filename, uintN lineno)
> {
>     jschar *chars;
>     JSScript *script;
> 	size_t wLength;
4424a3024,3033
>     CHECK_REQUEST(cx);
>     chars = js_InflateString(cx, bytes, length, &wLength);
>     if (!chars)
>         return NULL;
>     script = JS_CompileUCScriptForPrincipals(cx, obj, principals,
>                                              chars, wLength, filename, lineno);
>     JS_free(cx, chars);
>     return script;
> }
> #else //#ifdef _UTF8
4435c3044
<     chars = js_InflateString(cx, bytes, &length);
---
>     chars = js_InflateString(cx, bytes, length);
4442a3052
> #endif //#ifdef _UTF8
4454,4467d3063
< #define LAST_FRAME_EXCEPTION_CHECK(cx,result)                                 \
<     JS_BEGIN_MACRO                                                            \
<         if (!(result) && !((cx)->options & JSOPTION_DONT_REPORT_UNCAUGHT))    \
<             js_ReportUncaughtException(cx);                                   \
<     JS_END_MACRO
< 
< #define LAST_FRAME_CHECKS(cx,result)                                          \
<     JS_BEGIN_MACRO                                                            \
<         if (!(cx)->fp) {                                                      \
<             (cx)->weakRoots.lastInternalResult = JSVAL_NULL;                  \
<             LAST_FRAME_EXCEPTION_CHECK(cx, result);                           \
<         }                                                                     \
<     JS_END_MACRO
< 
4474c3070,3071
<     uint32 tcflags;
---
>     void *mark;
>     JSTokenStream *ts;
4478,4481c3075,3083
<     tcflags = JS_HAS_COMPILE_N_GO_OPTION(cx) ? TCF_COMPILE_N_GO : 0;
<     script = js_CompileScript(cx, obj, principals, tcflags,
<                               chars, length, NULL, filename, lineno);
<     LAST_FRAME_CHECKS(cx, script);
---
>     mark = JS_ARENA_MARK(&cx->tempPool);
>     ts = js_NewTokenStream(cx, chars, length, filename, lineno, principals);
>     if (!ts)
>         return NULL;
>     script = CompileTokenStream(cx, obj, ts, mark, NULL);
> #if JS_HAS_EXCEPTIONS
>     if (!script && !cx->fp)
>         js_ReportUncaughtException(cx);
> #endif
4484a3087,3133
> #ifdef _UTF8
> JS_PUBLIC_API(JSBool)
> JS_BufferIsCompilableUnit(JSContext *cx, JSObject *obj,
>                           const char *bytes, size_t length)
> {
>     jschar *chars;
>     JSBool result;
>     JSExceptionState *exnState;
>     void *tempMark;
>     JSTokenStream *ts;
>     JSErrorReporter older;
> 	size_t wLength;
> 
>     CHECK_REQUEST(cx);
>     chars = js_InflateString(cx, bytes, length, &wLength);
>     if (!chars)
>         return JS_TRUE;
> 
>     /*
>      * Return true on any out-of-memory error, so our caller doesn't try to
>      * collect more buffered source.
>      */
>     result = JS_TRUE;
>     exnState = JS_SaveExceptionState(cx);
>     tempMark = JS_ARENA_MARK(&cx->tempPool);
>     ts = js_NewTokenStream(cx, chars, wLength, NULL, 0, NULL);
>     if (ts) {
>         older = JS_SetErrorReporter(cx, NULL);
>         if (!js_ParseTokenStream(cx, obj, ts)) {
>             /*
>              * We ran into an error.  If it was because we ran out of source,
>              * we return false, so our caller will know to try to collect more
>              * buffered source.
>              */
>             result = (ts->flags & TSF_EOF) == 0;
>         }
> 
>         JS_SetErrorReporter(cx, older);
>         js_CloseTokenStream(cx, ts);
>         JS_ARENA_RELEASE(&cx->tempPool, tempMark);
>     }
> 
>     JS_free(cx, chars);
>     JS_RestoreExceptionState(cx, exnState);
>     return result;
> }
> #else //#ifdef _UTF8
4492c3141,3142
<     JSParseContext pc;
---
>     void *tempMark;
>     JSTokenStream *ts;
4496c3146
<     chars = js_InflateString(cx, bytes, &length);
---
>     chars = js_InflateString(cx, bytes, length);
4506c3156,3158
<     if (js_InitParseContext(cx, &pc, NULL, chars, length, NULL, NULL, 1)) {
---
>     tempMark = JS_ARENA_MARK(&cx->tempPool);
>     ts = js_NewTokenStream(cx, chars, length, NULL, 0, NULL);
>     if (ts) {
4508,4509c3160
<         if (!js_ParseScript(cx, obj, &pc) &&
<             (pc.tokenStream.flags & TSF_UNEXPECTED_EOF)) {
---
>         if (!js_ParseTokenStream(cx, obj, ts)) {
4515c3166
<             result = JS_FALSE;
---
>             result = (ts->flags & TSF_EOF) == 0;
4516a3168
> 
4518c3170,3171
<         js_FinishParseContext(cx, &pc);
---
>         js_CloseTokenStream(cx, ts);
>         JS_ARENA_RELEASE(&cx->tempPool, tempMark);
4519a3173
> 
4524a3179
> #endif //#ifdef _UTF8
4528,4529c3183,3184
<     FILE *fp;
<     uint32 tcflags;
---
>     void *mark;
>     JSTokenStream *ts;
4533,4549c3188,3196
<     if (!filename || strcmp(filename, "-") == 0) {
<         fp = stdin;
<     } else {
<         fp = fopen(filename, "r");
<         if (!fp) {
<             JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_OPEN,
<                                  filename, "No such file or directory");
<             return NULL;
<         }
<     }
< 
<     tcflags = JS_HAS_COMPILE_N_GO_OPTION(cx) ? TCF_COMPILE_N_GO : 0;
<     script = js_CompileScript(cx, obj, NULL, tcflags,
<                               NULL, 0, fp, filename, 1);
<     if (fp != stdin)
<         fclose(fp);
<     LAST_FRAME_CHECKS(cx, script);
---
>     mark = JS_ARENA_MARK(&cx->tempPool);
>     ts = js_NewFileTokenStream(cx, filename, stdin);
>     if (!ts)
>         return NULL;
>     script = CompileTokenStream(cx, obj, ts, mark, NULL);
> #if JS_HAS_EXCEPTIONS
>     if (!script && !cx->fp)
>         js_ReportUncaughtException(cx);
> #endif
4565c3212,3213
<     uint32 tcflags;
---
>     void *mark;
>     JSTokenStream *ts;
4569,4572c3217,3231
<     tcflags = JS_HAS_COMPILE_N_GO_OPTION(cx) ? TCF_COMPILE_N_GO : 0;
<     script = js_CompileScript(cx, obj, principals, tcflags,
<                               NULL, 0, file, filename, 1);
<     LAST_FRAME_CHECKS(cx, script);
---
>     mark = JS_ARENA_MARK(&cx->tempPool);
>     ts = js_NewFileTokenStream(cx, NULL, file);
>     if (!ts)
>         return NULL;
>     ts->filename = filename;
>     /* XXXshaver js_NewFileTokenStream should do this, because it drops */
>     if (principals) {
>         ts->principals = principals;
>         JSPRINCIPALS_HOLD(cx, ts->principals);
>     }
>     script = CompileTokenStream(cx, obj, ts, mark, NULL);
> #if JS_HAS_EXCEPTIONS
>     if (!script && !cx->fp)
>         js_ReportUncaughtException(cx);
> #endif
4579d3237
<     JSTempValueRooter tvr;
4582,4583c3240,3255
<     if (!script)
<         return js_NewObject(cx, &js_ScriptClass, NULL, NULL);
---
>     /*
>      * We use a dummy stack frame to protect the script from a GC caused
>      * by debugger-hook execution.
>      *
>      * XXX We really need a way to manage local roots and such more
>      * XXX automatically, at which point we can remove this one-off hack
>      * XXX and others within the engine.  See bug 40757 for discussion.
>      */
>     JSStackFrame dummy;
> 
>     CHECK_REQUEST(cx);
> 
>     memset(&dummy, 0, sizeof dummy);
>     dummy.down = cx->fp;
>     dummy.script = script;
>     cx->fp = &dummy;
4585d3256
<     JS_PUSH_TEMP_ROOT_SCRIPT(cx, script, &tvr);
4587,4588c3258,3265
<     if (obj) {
<         JS_SetPrivate(cx, obj, script);
---
> 
>     cx->fp = dummy.down;
>     if (!obj)
>         return NULL;
> 
>     if (script) {
>         if (!JS_SetPrivate(cx, obj, script))
>             return NULL;
4590,4592d3266
< #ifdef CHECK_SCRIPT_OWNER
<         script->owner = NULL;
< #endif
4594d3267
<     JS_POP_TEMP_ROOT(cx, &tvr);
4610a3284
> #ifdef _UTF8
4618a3293
> 	size_t wLength;
4621c3296,3315
<     chars = js_InflateString(cx, bytes, &length);
---
>     chars = js_InflateString(cx, bytes, length, &wLength);
>     if (!chars)
>         return NULL;
>     fun = JS_CompileUCFunction(cx, obj, name, nargs, argnames, chars, wLength,
>                                filename, lineno);
>     JS_free(cx, chars);
>     return fun;
> }
> #else //#ifdef _UTF8
> JS_PUBLIC_API(JSFunction *)
> JS_CompileFunction(JSContext *cx, JSObject *obj, const char *name,
>                    uintN nargs, const char **argnames,
>                    const char *bytes, size_t length,
>                    const char *filename, uintN lineno)
> {
>     jschar *chars;
>     JSFunction *fun;
> 
>     CHECK_REQUEST(cx);
>     chars = js_InflateString(cx, bytes, length);
4628a3323,3335
> #endif //#ifdef _UTF8
> 
> #ifdef _UTF8
> JS_PUBLIC_API(JSFunction *)
> JS_CompileFunctionForPrincipals(JSContext *cx, JSObject *obj,
>                                 JSPrincipals *principals, const char *name,
>                                 uintN nargs, const char **argnames,
>                                 const char *bytes, size_t length,
>                                 const char *filename, uintN lineno)
> {
>     jschar *chars;
>     JSFunction *fun;
> 	size_t wLength;
4629a3337,3347
>     CHECK_REQUEST(cx);
>     chars = js_InflateString(cx, bytes, length, &wLength);
>     if (!chars)
>         return NULL;
>     fun = JS_CompileUCFunctionForPrincipals(cx, obj, principals, name,
>                                             nargs, argnames, chars, wLength,
>                                             filename, lineno);
>     JS_free(cx, chars);
>     return fun;
> }
> #else //#ifdef _UTF8
4641c3359
<     chars = js_InflateString(cx, bytes, &length);
---
>     chars = js_InflateString(cx, bytes, length);
4649a3368
> #endif //#ifdef _UTF8
4670a3390,3391
>     void *mark;
>     JSTokenStream *ts;
4672d3392
<     JSTempValueRooter tvr;
4676a3397,3402
>     mark = JS_ARENA_MARK(&cx->tempPool);
>     ts = js_NewTokenStream(cx, chars, length, filename, lineno, principals);
>     if (!ts) {
>         fun = NULL;
>         goto out;
>     }
4683c3409
<             goto out2;
---
>             goto out;
4686c3412
<     fun = js_NewFunction(cx, NULL, NULL, 0, JSFUN_INTERPRETED, obj, funAtom);
---
>     fun = js_NewFunction(cx, NULL, NULL, nargs, 0, obj, funAtom);
4688,4696c3414,3427
<         goto out2;
< 
<     /* From this point the control must flow through the label out. */
<     JS_PUSH_TEMP_ROOT_FUNCTION(cx, fun, &tvr);
<     for (i = 0; i < nargs; i++) {
<         argAtom = js_Atomize(cx, argnames[i], strlen(argnames[i]), 0);
<         if (!argAtom) {
<             fun = NULL;
<             goto out;
---
>         goto out;
>     if (nargs) {
>         for (i = 0; i < nargs; i++) {
>             argAtom = js_Atomize(cx, argnames[i], strlen(argnames[i]), 0);
>             if (!argAtom)
>                 break;
>             if (!js_AddNativeProperty(cx, fun->object, (jsid)argAtom,
>                                       js_GetArgument, js_SetArgument,
>                                       SPROP_INVALID_SLOT,
>                                       JSPROP_ENUMERATE | JSPROP_PERMANENT |
>                                       JSPROP_SHARED,
>                                       SPROP_HAS_SHORTID, i)) {
>                 break;
>             }
4698c3429
<         if (!js_AddLocal(cx, fun, argAtom, JSLOCAL_ARG)) {
---
>         if (i < nargs) {
4703,4705c3434
< 
<     if (!js_CompileFunctionBody(cx, fun, principals, chars, length,
<                                 filename, lineno)) {
---
>     if (!js_CompileFunctionBody(cx, ts, fun)) {
4709,4725c3438,3443
< 
<     if (obj &&
<         funAtom &&
<         !OBJ_DEFINE_PROPERTY(cx, obj, ATOM_TO_JSID(funAtom),
<                              OBJECT_TO_JSVAL(fun->object),
<                              NULL, NULL, JSPROP_ENUMERATE, NULL)) {
<         fun = NULL;
<     }
< 
< #ifdef JS_SCOPE_DEPTH_METER
<     if (fun && obj) {
<         JSObject *pobj = obj;
<         uintN depth = 1;
< 
<         while ((pobj = OBJ_GET_PARENT(cx, pobj)) != NULL)
<             ++depth;
<         JS_BASIC_STATS_ACCUM(&cx->runtime->hostenvScopeDepthStats, depth);
---
>     if (obj && funAtom) {
>         if (!OBJ_DEFINE_PROPERTY(cx, obj, (jsid)funAtom,
>                                  OBJECT_TO_JSVAL(fun->object),
>                                  NULL, NULL, 0, NULL)) {
>             return NULL;
>         }
4726a3445,3451
> out:
>     if (ts)
>         js_CloseTokenStream(cx, ts);
>     JS_ARENA_RELEASE(&cx->tempPool, mark);
> #if JS_HAS_EXCEPTIONS
>     if (!fun && !cx->fp)
>         js_ReportUncaughtException(cx);
4728,4734d3452
< 
<   out:
<     cx->weakRoots.newborn[JSTRACE_FUNCTION] = fun;
<     JS_POP_TEMP_ROOT(cx, &tvr);
< 
<   out2:
<     LAST_FRAME_CHECKS(cx, fun);
4746,4748c3464,3466
<     jp = JS_NEW_PRINTER(cx, name, NULL,
<                         indent & ~JS_DONT_PRETTY_PRINT,
<                         !(indent & JS_DONT_PRETTY_PRINT));
---
>     jp = js_NewPrinter(cx, name,
>                        indent & ~JS_DONT_PRETTY_PRINT,
>                        !(indent & JS_DONT_PRETTY_PRINT));
4766,4768c3484,3486
<     jp = JS_NEW_PRINTER(cx, "JS_DecompileFunction", fun,
<                         indent & ~JS_DONT_PRETTY_PRINT,
<                         !(indent & JS_DONT_PRETTY_PRINT));
---
>     jp = js_NewPrinter(cx, JS_GetFunctionName(fun),
>                        indent & ~JS_DONT_PRETTY_PRINT,
>                        !(indent & JS_DONT_PRETTY_PRINT));
4771c3489
<     if (js_DecompileFunction(jp))
---
>     if (js_DecompileFunction(jp, fun))
4786,4788c3504,3506
<     jp = JS_NEW_PRINTER(cx, "JS_DecompileFunctionBody", fun,
<                         indent & ~JS_DONT_PRETTY_PRINT,
<                         !(indent & JS_DONT_PRETTY_PRINT));
---
>     jp = js_NewPrinter(cx, JS_GetFunctionName(fun),
>                        indent & ~JS_DONT_PRETTY_PRINT,
>                        !(indent & JS_DONT_PRETTY_PRINT));
4791c3509
<     if (js_DecompileFunctionBody(jp))
---
>     if (js_DecompileFunctionBody(jp, fun))
4802,4803d3519
<     JSBool ok;
< 
4805,4807c3521,3528
<     ok = js_Execute(cx, obj, script, NULL, 0, rval);
<     LAST_FRAME_CHECKS(cx, ok);
<     return ok;
---
>     if (!js_Execute(cx, obj, script, NULL, 0, rval)) {
> #if JS_HAS_EXCEPTIONS
>         if (!cx->fp)
>             js_ReportUncaughtException(cx);
> #endif
>         return JS_FALSE;
>     }
>     return JS_TRUE;
4815c3536
<     JSDebugHooks *hooks;
---
>     JSRuntime *rt;
4828,4831c3549,3552
<     hooks = cx->debugHooks;
<     if (hooks->newScriptHook) {
<         hooks->newScriptHook(cx, tmp.filename, tmp.lineno, &tmp, NULL,
<                              hooks->newScriptHookData);
---
>     rt = cx->runtime;
>     if (rt->newScriptHook) {
>         rt->newScriptHook(cx, tmp.filename, tmp.lineno, &tmp, NULL,
>                           rt->newScriptHookData);
4836,4837c3557,3596
<     if (hooks->destroyScriptHook)
<         hooks->destroyScriptHook(cx, &tmp, hooks->destroyScriptHookData);
---
>     if (rt->destroyScriptHook)
>         rt->destroyScriptHook(cx, &tmp, rt->destroyScriptHookData);
>     return ok;
> }
> 
> #ifdef _UTF8
> JS_PUBLIC_API(JSBool)
> JS_EvaluateScript(JSContext *cx, JSObject *obj,
>                   const char *bytes, uintN length,
>                   const char *filename, uintN lineno,
>                   jsval *rval)
> {
>     jschar *chars;
>     JSBool ok;
> 	size_t wLength;
> 
>     CHECK_REQUEST(cx);
>     chars = js_InflateString(cx, bytes, length, &wLength);
>     if (!chars)
>         return JS_FALSE;
>     ok = JS_EvaluateUCScript(cx, obj, chars, wLength, filename, lineno, rval);
>     JS_free(cx, chars);
>     return ok;
> }
> #else //#ifdef _UTF8
> JS_PUBLIC_API(JSBool)
> JS_EvaluateScript(JSContext *cx, JSObject *obj,
>                   const char *bytes, uintN length,
>                   const char *filename, uintN lineno,
>                   jsval *rval)
> {
>     jschar *chars;
>     JSBool ok;
> 
>     CHECK_REQUEST(cx);
>     chars = js_InflateString(cx, bytes, length);
>     if (!chars)
>         return JS_FALSE;
>     ok = JS_EvaluateUCScript(cx, obj, chars, length, filename, lineno, rval);
>     JS_free(cx, chars);
4839a3599
> #endif //#ifdef _UTF8
4841c3601
< /* Ancient uintN nbytes is part of API/ABI, so use size_t length local. */
---
> #ifdef _UTF8
4843,4846c3603,3607
< JS_EvaluateScript(JSContext *cx, JSObject *obj,
<                   const char *bytes, uintN nbytes,
<                   const char *filename, uintN lineno,
<                   jsval *rval)
---
> JS_EvaluateScriptForPrincipals(JSContext *cx, JSObject *obj,
>                                JSPrincipals *principals,
>                                const char *bytes, uintN length,
>                                const char *filename, uintN lineno,
>                                jsval *rval)
4848d3608
<     size_t length = nbytes;
4850a3611
> 	size_t wLength;
4853c3614
<     chars = js_InflateString(cx, bytes, &length);
---
>     chars = js_InflateString(cx, bytes, length, &wLength);
4856c3617,3618
<     ok = JS_EvaluateUCScript(cx, obj, chars, length, filename, lineno, rval);
---
>     ok = JS_EvaluateUCScriptForPrincipals(cx, obj, principals, chars, wLength,
>                                           filename, lineno, rval);
4860,4861c3622
< 
< /* Ancient uintN nbytes is part of API/ABI, so use size_t length local. */
---
> #else //#ifdef _UTF8
4865c3626
<                                const char *bytes, uintN nbytes,
---
>                                const char *bytes, uintN length,
4869d3629
<     size_t length = nbytes;
4874c3634
<     chars = js_InflateString(cx, bytes, &length);
---
>     chars = js_InflateString(cx, bytes, length);
4881a3642
> #endif //#ifdef _UTF8
4905,4906c3666,3667
<     script = js_CompileScript(cx, obj, principals, TCF_COMPILE_N_GO,
<                               chars, length, NULL, filename, lineno);
---
>     script = JS_CompileUCScriptForPrincipals(cx, obj, principals, chars, length,
>                                              filename, lineno);
4910c3671,3674
<     LAST_FRAME_CHECKS(cx, ok);
---
> #if JS_HAS_EXCEPTIONS
>     if (!ok && !cx->fp)
>         js_ReportUncaughtException(cx);
> #endif
4919,4920d3682
<     JSBool ok;
< 
4922,4925c3684,3692
<     ok = js_InternalCall(cx, obj, OBJECT_TO_JSVAL(fun->object), argc, argv,
<                          rval);
<     LAST_FRAME_CHECKS(cx, ok);
<     return ok;
---
>     if (!js_InternalCall(cx, obj, OBJECT_TO_JSVAL(fun->object), argc, argv,
>                          rval)) {
> #if JS_HAS_EXCEPTIONS
>         if (!cx->fp)
>             js_ReportUncaughtException(cx);
> #endif
>         return JS_FALSE;
>     }
>     return JS_TRUE;
4932d3698
<     JSBool ok;
4936,4949d3701
< #if JS_HAS_XML_SUPPORT
<     if (OBJECT_IS_XML(cx, obj)) {
<         JSXMLObjectOps *ops;
<         JSAtom *atom;
< 
<         ops = (JSXMLObjectOps *) obj->map->ops;
<         atom = js_Atomize(cx, name, strlen(name), 0);
<         if (!atom)
<             return JS_FALSE;
<         obj = ops->getMethod(cx, obj, ATOM_TO_JSID(atom), &fval);
<         if (!obj)
<             return JS_FALSE;
<     } else
< #endif
4952,4954c3704,3711
<     ok = js_InternalCall(cx, obj, fval, argc, argv, rval);
<     LAST_FRAME_CHECKS(cx, ok);
<     return ok;
---
>     if (!js_InternalCall(cx, obj, fval, argc, argv, rval)) {
> #if JS_HAS_EXCEPTIONS
>         if (!cx->fp)
>             js_ReportUncaughtException(cx);
> #endif
>         return JS_FALSE;
>     }
>     return JS_TRUE;
4961,4962d3717
<     JSBool ok;
< 
4964,5015c3719,3726
<     ok = js_InternalCall(cx, obj, fval, argc, argv, rval);
<     LAST_FRAME_CHECKS(cx, ok);
<     return ok;
< }
< 
< JS_PUBLIC_API(void)
< JS_SetOperationCallback(JSContext *cx, JSOperationCallback callback,
<                         uint32 operationLimit)
< {
<     JS_ASSERT(callback);
<     JS_ASSERT(operationLimit <= JS_MAX_OPERATION_LIMIT);
<     JS_ASSERT(operationLimit > 0);
< 
<     cx->operationCount = (int32) operationLimit;
<     cx->operationLimit = operationLimit;
<     cx->operationCallbackIsSet = 1;
<     cx->operationCallback = callback;
< }
< 
< JS_PUBLIC_API(void)
< JS_ClearOperationCallback(JSContext *cx)
< {
<     cx->operationCount = (int32) JS_MAX_OPERATION_LIMIT;
<     cx->operationLimit = JS_MAX_OPERATION_LIMIT;
<     cx->operationCallbackIsSet = 0;
<     cx->operationCallback = NULL;
< }
< 
< JS_PUBLIC_API(JSOperationCallback)
< JS_GetOperationCallback(JSContext *cx)
< {
<     JS_ASSERT(cx->operationCallbackIsSet || !cx->operationCallback);
<     return cx->operationCallback;
< }
< 
< JS_PUBLIC_API(uint32)
< JS_GetOperationLimit(JSContext *cx)
< {
<     JS_ASSERT(cx->operationCallbackIsSet);
<     return cx->operationLimit;
< }
< 
< JS_PUBLIC_API(void)
< JS_SetOperationLimit(JSContext *cx, uint32 operationLimit)
< {
<     JS_ASSERT(operationLimit <= JS_MAX_OPERATION_LIMIT);
<     JS_ASSERT(operationLimit > 0);
<     JS_ASSERT(cx->operationCallbackIsSet);
< 
<     cx->operationLimit = operationLimit;
<     if (cx->operationCount > (int32) operationLimit)
<         cx->operationCount = (int32) operationLimit;
---
>     if (!js_InternalCall(cx, obj, fval, argc, argv, rval)) {
> #if JS_HAS_EXCEPTIONS
>         if (!cx->fp)
>             js_ReportUncaughtException(cx);
> #endif
>         return JS_FALSE;
>     }
>     return JS_TRUE;
5023,5041c3734,3735
<     if (cx->operationCallbackIsSet) {
< #ifdef DEBUG
<         fprintf(stderr,
< "JS API usage error: call to JS_SetOperationCallback is followed by\n"
< "invocation of deprecated JS_SetBranchCallback\n");
<         JS_ASSERT(0);
< #endif
<         cx->operationCallbackIsSet = 0;
<         oldcb = NULL;
<     } else {
<         oldcb = (JSBranchCallback) cx->operationCallback;
<     }
<     if (cb) {
<         cx->operationCount = JSOW_SCRIPT_JUMP;
<         cx->operationLimit = JSOW_SCRIPT_JUMP;
<         cx->operationCallback = (JSOperationCallback) cb;
<     } else {
<         JS_ClearOperationCallback(cx);
<     }
---
>     oldcb = cx->branchCallback;
>     cx->branchCallback = cb;
5079,5093c3773
< JS_PUBLIC_API(JSStackFrame *)
< JS_SaveFrameChain(JSContext *cx)
< {
<     JSStackFrame *fp;
< 
<     fp = cx->fp;
<     if (!fp)
<         return fp;
< 
<     JS_ASSERT(!fp->dormantNext);
<     fp->dormantNext = cx->dormantFrameChain;
<     cx->dormantFrameChain = fp;
<     cx->fp = NULL;
<     return fp;
< }
---
> /************************************************************************/
5095,5096c3775,3777
< JS_PUBLIC_API(void)
< JS_RestoreFrameChain(JSContext *cx, JSStackFrame *fp)
---
> #ifdef _UTF8
> JS_PUBLIC_API(JSString *)
> JS_NewString(JSContext *cx, char *bytes, size_t length)
5098,5100c3779,3781
<     JS_ASSERT(!cx->fp);
<     if (!fp)
<         return;
---
>     jschar *chars;
>     JSString *str;
> 	size_t wLength;
5102,5106c3783,3787
<     JS_ASSERT(fp == cx->dormantFrameChain);
<     cx->fp = fp;
<     cx->dormantFrameChain = fp->dormantNext;
<     fp->dormantNext = NULL;
< }
---
>     CHECK_REQUEST(cx);
>     /* Make a Unicode vector from the 8-bit char codes in bytes. */
>     chars = js_InflateString(cx, bytes, length, &wLength);
>     if (!chars)
>         return NULL;
5108c3789,3794
< /************************************************************************/
---
>     /* Free chars (but not bytes, which caller frees on error) if we fail. */
>     str = js_NewString(cx, chars, wLength, 0);
>     if (!str) {
>         JS_free(cx, chars);
>         return NULL;
>     }
5109a3796,3801
>     /* Hand off bytes to the deflated string cache, if possible. */
>     if (!js_SetStringBytes(str, bytes, length))
>         JS_free(cx, bytes);
>     return str;
> }
> #else //#ifdef _UTF8
5111c3803
< JS_NewString(JSContext *cx, char *bytes, size_t nbytes)
---
> JS_NewString(JSContext *cx, char *bytes, size_t length)
5113d3804
<     size_t length = nbytes;
5118,5120c3809,3810
< 
<     /* Make a UTF-16 vector from the 8-bit char codes in bytes. */
<     chars = js_InflateString(cx, bytes, &length);
---
>     /* Make a Unicode vector from the 8-bit char codes in bytes. */
>     chars = js_InflateString(cx, bytes, length);
5125c3815
<     str = js_NewString(cx, chars, length);
---
>     str = js_NewString(cx, chars, length, 0);
5132c3822
<     if (!js_SetStringBytes(cx, str, bytes, nbytes))
---
>     if (!js_SetStringBytes(str, bytes, length))
5135a3826,3835
> #endif //#ifdef _UTF8
> 
> 
> #ifdef _UTF8
> JS_PUBLIC_API(JSString *)
> JS_NewStringCopyN(JSContext *cx, const char *s, size_t n)
> {
>     jschar *js;
>     JSString *str;
> 	size_t wN;
5136a3837,3846
>     CHECK_REQUEST(cx);
>     js = js_InflateString(cx, s, n, &wN);
>     if (!js)
>         return NULL;
>     str = js_NewString(cx, js, wN, 0);
>     if (!str)
>         JS_free(cx, js);
>     return str;
> }
> #else //#ifdef _UTF8
5144c3854
<     js = js_InflateString(cx, s, &n);
---
>     js = js_InflateString(cx, s, n);
5147c3857
<     str = js_NewString(cx, js, n);
---
>     str = js_NewString(cx, js, n, 0);
5151a3862,3871
> #endif //#ifdef _UTF8
> 
> #ifdef _UTF8
> JS_PUBLIC_API(JSString *)
> JS_NewStringCopyZ(JSContext *cx, const char *s)
> {
>     size_t n;
>     jschar *js;
>     JSString *str;
> 	size_t wN;
5152a3873,3885
>     CHECK_REQUEST(cx);
>     if (!s)
>         return cx->runtime->emptyString;
>     n = strlen(s);
>     js = js_InflateString(cx, s, n, &wN);
>     if (!js)
>         return NULL;
>     str = js_NewString(cx, js, wN, 0);
>     if (!str)
>         JS_free(cx, js);
>     return str;
> }
> #else //#ifdef _UTF8
5164c3897
<     js = js_InflateString(cx, s, &n);
---
>     js = js_InflateString(cx, s, n);
5167c3900
<     str = js_NewString(cx, js, n);
---
>     str = js_NewString(cx, js, n, 0);
5171a3905
> #endif //#ifdef _UTF8
5189c3923
<     return js_NewString(cx, chars, length);
---
>     return js_NewString(cx, chars, length, 0);
5196c3930
<     return js_NewStringCopyN(cx, s, n);
---
>     return js_NewStringCopyN(cx, s, n, 0);
5205c3939
<     return js_NewStringCopyZ(cx, s);
---
>     return js_NewStringCopyZ(cx, s, 0);
5229c3963
<     const char *bytes;
---
>     char *bytes;
5231,5232c3965,3967
<     bytes = js_GetStringBytes(NULL, str);
<     return (char *)(bytes ? bytes : "");
---
>     CHECK_REQUEST(cx);
>     bytes = js_GetStringBytes(str);
>     return bytes ? bytes : "";
5238,5240d3972
<     size_t n, size;
<     jschar *s;
< 
5242,5246c3974,3977
<      * API botch (again, shades of JS_GetStringBytes): we have no cx to report
<      * out-of-memory when undepending strings, so we replace js_UndependString
<      * with explicit malloc call and ignore its errors.
<      *
<      * If we fail to convert a dependent string into an independent one, our
---
>      * API botch (again, shades of JS_GetStringBytes): we have no cx to pass
>      * to js_UndependString (called by js_GetStringChars) for out-of-memory
>      * error reports, so js_UndependString passes NULL and suppresses errors.
>      * If it fails to convert a dependent string into an independent one, our
5254,5269c3985,3989
<     if (JSSTRING_IS_DEPENDENT(str)) {
<         n = JSSTRDEP_LENGTH(str);
<         size = (n + 1) * sizeof(jschar);
<         s = (jschar *) malloc(size);
<         if (s) {
<             memcpy(s, JSSTRDEP_CHARS(str), n * sizeof *s);
<             s[n] = 0;
<             JSFLATSTR_INIT(str, s, n);
<         } else {
<             s = JSSTRDEP_CHARS(str);
<         }
<     } else {
<         JSFLATSTR_CLEAR_MUTABLE(str);
<         s = JSFLATSTR_CHARS(str);
<     }
<     return s;
---
>     jschar *chars;
> 
>     CHECK_REQUEST(cx);
>     chars = js_GetStringChars(str);
>     return chars ? chars : JSSTRING_CHARS(str);
5274a3995
>     CHECK_REQUEST(cx);
5280a4002
>     CHECK_REQUEST(cx);
5287,5288d4008
<     JSString *str;
< 
5290,5294c4010
<     str = js_NewString(cx, chars, length);
<     if (!str)
<         return str;
<     JSFLATSTR_SET_MUTABLE(str);
<     return str;
---
>     return js_NewString(cx, chars, length, GCF_MUTABLE);
5302c4018
<     return js_NewDependentString(cx, str, start, length);
---
>     return js_NewDependentString(cx, str, start, length, 0);
5323,5376c4039,4040
<     return js_MakeStringImmutable(cx, str);
< }
< 
< JS_PUBLIC_API(JSBool)
< JS_EncodeCharacters(JSContext *cx, const jschar *src, size_t srclen, char *dst,
<                     size_t *dstlenp)
< {
<     size_t n;
< 
<     if (!dst) {
<         n = js_GetDeflatedStringLength(cx, src, srclen);
<         if (n == (size_t)-1) {
<             *dstlenp = 0;
<             return JS_FALSE;
<         }
<         *dstlenp = n;
<         return JS_TRUE;
<     }
< 
<     return js_DeflateStringToBuffer(cx, src, srclen, dst, dstlenp);
< }
< 
< JS_PUBLIC_API(JSBool)
< JS_DecodeBytes(JSContext *cx, const char *src, size_t srclen, jschar *dst,
<                size_t *dstlenp)
< {
<     return js_InflateStringToBuffer(cx, src, srclen, dst, dstlenp);
< }
< 
< JS_PUBLIC_API(char *)
< JS_EncodeString(JSContext *cx, JSString *str)
< {
<     return js_DeflateString(cx, JSSTRING_CHARS(str), JSSTRING_LENGTH(str));
< }
< 
< /*
<  * The following determines whether C Strings are to be treated as UTF-8
<  * or ISO-8859-1.  For correct operation, it must be set prior to the
<  * first call to JS_NewRuntime.
<  */
< #ifndef JS_C_STRINGS_ARE_UTF8
< JSBool js_CStringsAreUTF8 = JS_FALSE;
< #endif
< 
< JS_PUBLIC_API(JSBool)
< JS_CStringsAreUTF8()
< {
<     return js_CStringsAreUTF8;
< }
< 
< JS_PUBLIC_API(void)
< JS_SetCStringsAreUTF8()
< {
<     JS_ASSERT(!js_NewRuntimeWasCalled);
---
>     if (!js_UndependString(cx, str))
>         return JS_FALSE;
5378,5380c4042,4043
< #ifndef JS_C_STRINGS_ARE_UTF8
<     js_CStringsAreUTF8 = JS_TRUE;
< #endif
---
>     *js_GetGCThingFlags(str) &= ~GCF_MUTABLE;
>     return JS_TRUE;
5464c4127
<     js_ReportOutOfMemory(cx);
---
>     js_ReportOutOfMemory(cx, js_GetErrorMessage);
5481a4145,4167
> 
> #ifdef _UTF8
> JS_PUBLIC_API(JSObject *)
> JS_NewRegExpObject(JSContext *cx, char *bytes, size_t length, uintN flags)
> {
> #if JS_HAS_REGEXPS
>     jschar *chars;
>     JSObject *obj;
> 	size_t wLength;
> 
>     CHECK_REQUEST(cx);
>     chars = js_InflateString(cx, bytes, length, &wLength);
>     if (!chars)
>         return NULL;
>     obj = js_NewRegExpObject(cx, NULL, chars, wLength, flags);
>     JS_free(cx, chars);
>     return obj;
> #else
>     JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NO_REG_EXPS);
>     return NULL;
> #endif
> }
> #else //#ifdef _UTF8
5484a4171
> #if JS_HAS_REGEXPS
5489c4176
<     chars = js_InflateString(cx, bytes, &length);
---
>     chars = js_InflateString(cx, bytes, length);
5494a4182,4185
> #else
>     JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NO_REG_EXPS);
>     return NULL;
> #endif
5495a4187
> #endif //#ifdef _UTF8
5500a4193
> #if JS_HAS_REGEXPS
5501a4195,4198
> #else
>     JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NO_REG_EXPS);
>     return NULL;
> #endif
5563a4261
> #if JS_HAS_EXCEPTIONS
5564a4263,4265
> #else
>     return JS_FALSE;
> #endif
5569a4271
> #if JS_HAS_EXCEPTIONS
5574a4277,4279
> #else
>     return JS_FALSE;
> #endif
5580a4286
> #if JS_HAS_EXCEPTIONS
5582a4289
> #endif
5587a4295
> #if JS_HAS_EXCEPTIONS
5589,5609c4297
<     cx->exception = JSVAL_VOID;
< }
< 
< JS_PUBLIC_API(JSBool)
< JS_ReportPendingException(JSContext *cx)
< {
<     JSBool save, ok;
< 
<     CHECK_REQUEST(cx);
< 
<     /*
<      * Set cx->generatingError to suppress the standard error-to-exception
<      * conversion done by all {js,JS}_Report* functions except for OOM.  The
<      * cx->generatingError flag was added to suppress recursive divergence
<      * under js_ErrorToException, but it serves for our purposes here too.
<      */
<     save = cx->generatingError;
<     cx->generatingError = JS_TRUE;
<     ok = js_ReportUncaughtException(cx);
<     cx->generatingError = save;
<     return ok;
---
> #endif
5611a4300
> #if JS_HAS_EXCEPTIONS
5615a4305
> #endif
5619a4310
> #if JS_HAS_EXCEPTIONS
5622a4314
>     XMEMTAG("JS_SaveExceptionState");
5629a4322,4324
> #else
>     return NULL;
> #endif
5634a4330
> #if JS_HAS_EXCEPTIONS
5642a4339
> #endif
5647a4345
> #if JS_HAS_EXCEPTIONS
5653a4352
> #endif
5658a4358
> #if JS_HAS_EXCEPTIONS
5661,5673c4361,4363
< }
< 
< JS_PUBLIC_API(JSBool)
< JS_ThrowReportedError(JSContext *cx, const char *message,
<                       JSErrorReport *reportp)
< {
<     return js_ErrorToException(cx, message, reportp);
< }
< 
< JS_PUBLIC_API(JSBool)
< JS_ThrowStopIteration(JSContext *cx)
< {
<     return js_ThrowStopIteration(cx);
---
> #else
>     return NULL;
> #endif
5677,5680d4366
< /*
<  * Get the owning thread id of a context. Returns 0 if the context is not
<  * owned by any thread.
<  */
5684c4370
<     return JS_THREAD_ID(cx);
---
>     return cx->thread;
5687,5690d4372
< /*
<  * Set the current thread as the owning thread of a context. Returns the
<  * old owning thread id, or -1 if the operation failed.
<  */
5694,5696c4376,4377
<     jsword old = JS_THREAD_ID(cx);
<     if (!js_SetContextThread(cx))
<         return -1;
---
>     intN old = cx->thread;
>     cx->thread = js_CurrentThreadId();
5700c4381
< JS_PUBLIC_API(jsword)
---
> JS_PUBLIC_API(intN)
5703,5704c4384,4385
<     jsword old = JS_THREAD_ID(cx);
<     js_ClearContextThread(cx);
---
>     intN old = cx->thread;
>     cx->thread = 0;
5709,5716d4389
< #ifdef JS_GC_ZEAL
< JS_PUBLIC_API(void)
< JS_SetGCZeal(JSContext *cx, uint8 zeal)
< {
<     cx->runtime->gcZeal = zeal;
< }
< #endif
< 
5719c4392,4393
< #if !defined(STATIC_JS_API) && defined(XP_WIN)
---
> /* !!@!! jht: disable dll */
> #if 0
5720a4395,4397
> #if defined(XP_OS2)
> /*DSR031297 - the OS/2 equiv is dll_InitTerm, but I don't see the need for it*/
> #elif defined(XP_WIN)
5721a4399,4401
> /*
>  * Initialization routine for the JS DLL...
>  */
5724c4404,4408
<  * Initialization routine for the JS DLL.
---
>  * Global Instance handle...
>  * In Win32 this is the module handle of the DLL.
>  *
>  * In Win16 this is the instance handle of the application
>  * which loaded the DLL.
5725a4410,4411
> 
> #ifdef _WIN32
5730a4417,4432
> #else  /* !_WIN32 */
> 
> int CALLBACK LibMain( HINSTANCE hInst, WORD wDataSeg,
>                       WORD cbHeapSize, LPSTR lpszCmdLine )
> {
>     return TRUE;
> }
> 
> BOOL CALLBACK __loadds WEP(BOOL fSystemExit)
> {
>     return TRUE;
> }
> 
> #endif /* !_WIN32 */
> #endif /* XP_OS2 || XP_WIN */
> 
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsapi.h /Volumes/Swap/js_D11/src/jsapi.h
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,22c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
26,38c23,33
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
48d42
< #include "jsutil.h"
136,163d129
< 
< #define JSFUN_DISJOINT_FLAGS(f) ((f) & 0x0f)
< #define JSFUN_GSFLAGS(f)        ((f) & (JSFUN_GETTER | JSFUN_SETTER))
< 
< #ifdef MOZILLA_1_8_BRANCH
< 
< /*
<  * Squeeze three more bits into existing 8-bit flags by taking advantage of
<  * the invalid combination (JSFUN_GETTER | JSFUN_SETTER).
<  */
< #define JSFUN_GETTER_TEST(f)       (JSFUN_GSFLAGS(f) == JSFUN_GETTER)
< #define JSFUN_SETTER_TEST(f)       (JSFUN_GSFLAGS(f) == JSFUN_SETTER)
< #define JSFUN_FLAGS_TEST(f,t)      (JSFUN_GSFLAGS(~(f)) ? (f) & (t) : 0)
< #define JSFUN_BOUND_METHOD_TEST(f) JSFUN_FLAGS_TEST(f, JSFUN_BOUND_METHOD)
< #define JSFUN_HEAVYWEIGHT_TEST(f)  JSFUN_FLAGS_TEST(f, JSFUN_HEAVYWEIGHT)
< 
< #define JSFUN_GSFLAG2ATTR(f)       (JSFUN_GETTER_TEST(f) ? JSPROP_GETTER :    \
<                                     JSFUN_SETTER_TEST(f) ? JSPROP_SETTER : 0)
< 
< #define JSFUN_THISP_FLAGS(f)    (JSFUN_GSFLAGS(~(f)) ? 0 :                    \
<                                  (f) & JSFUN_THISP_PRIMITIVE)
< #define JSFUN_THISP_TEST(f,t)   ((f) == (t) || (f) == JSFUN_THISP_PRIMITIVE)
< 
< #define JSFUN_THISP_STRING      0x30    /* |this| may be a primitive string */
< #define JSFUN_THISP_NUMBER      0x70    /* |this| may be a primitive number */
< #define JSFUN_THISP_BOOLEAN     0xb0    /* |this| may be a primitive boolean */
< #define JSFUN_THISP_PRIMITIVE   0xf0    /* |this| may be any primitive value */
< 
166,207d131
< #else
< 
< #define JSFUN_GETTER_TEST(f)       ((f) & JSFUN_GETTER)
< #define JSFUN_SETTER_TEST(f)       ((f) & JSFUN_SETTER)
< #define JSFUN_BOUND_METHOD_TEST(f) ((f) & JSFUN_BOUND_METHOD)
< #define JSFUN_HEAVYWEIGHT_TEST(f)  ((f) & JSFUN_HEAVYWEIGHT)
< 
< #define JSFUN_GSFLAG2ATTR(f)       JSFUN_GSFLAGS(f)
< 
< #define JSFUN_THISP_FLAGS(f)  (f)
< #define JSFUN_THISP_TEST(f,t) ((f) & t)
< 
< #define JSFUN_THISP_STRING    0x0100    /* |this| may be a primitive string */
< #define JSFUN_THISP_NUMBER    0x0200    /* |this| may be a primitive number */
< #define JSFUN_THISP_BOOLEAN   0x0400    /* |this| may be a primitive boolean */
< #define JSFUN_THISP_PRIMITIVE 0x0700    /* |this| may be any primitive value */
< 
< #define JSFUN_FAST_NATIVE     0x0800    /* JSFastNative needs no JSStackFrame */
< 
< #define JSFUN_FLAGS_MASK      0x0ff8    /* overlay JSFUN_* attributes --
<                                            note that bit #15 is used internally
<                                            to flag interpreted functions */
< 
< #define JSFUN_STUB_GSOPS      0x1000    /* use JS_PropertyStub getter/setter
<                                            instead of defaulting to class gsops
<                                            for property holding function */
< 
< #endif
< 
< /*
<  * Re-use JSFUN_LAMBDA, which applies only to scripted functions, for use in
<  * JSFunctionSpec arrays that specify generic native prototype methods, i.e.,
<  * methods of a class prototype that are exposed as static methods taking an
<  * extra leading argument: the generic |this| parameter.
<  *
<  * If you set this flag in a JSFunctionSpec struct's flags initializer, then
<  * that struct must live at least as long as the native static method object
<  * created due to this flag by JS_DefineFunctions or JS_InitClass.  Typically
<  * JSFunctionSpec structs are allocated in static arrays.
<  */
< #define JSFUN_GENERIC_NATIVE    JSFUN_LAMBDA
< 
224c148
< JS_Now(void);
---
> JS_Now();
412,415d335
<  *
<  * It is important that the first runtime and first context be created in a
<  * single-threaded fashion, otherwise the behavior of the library is undefined.
<  * See: http://developer.mozilla.org/en/docs/Category:JSAPI_Reference
436a357,358
> #ifdef JS_THREADSAFE
> 
453,484c375
< #ifdef __cplusplus
< JS_END_EXTERN_C
< 
< class JSAutoRequest {
<   public:
<     JSAutoRequest(JSContext *cx) : mContext(cx), mSaveDepth(0) {
<         JS_BeginRequest(mContext);
<     }
<     ~JSAutoRequest() {
<         JS_EndRequest(mContext);
<     }
< 
<     void suspend() {
<         mSaveDepth = JS_SuspendRequest(mContext);
<     }
<     void resume() {
<         JS_ResumeRequest(mContext, mSaveDepth);
<     }
< 
<   protected:
<     JSContext *mContext;
<     jsrefcount mSaveDepth;
< 
< #if 0
<   private:
<     static void *operator new(size_t) CPP_THROW_NEW { return 0; };
<     static void operator delete(void *, size_t) { };
< #endif
< };
< 
< JS_BEGIN_EXTERN_C
< #endif
---
> #endif /* JS_THREADSAFE */
492,494d382
< extern JS_PUBLIC_API(JSContextCallback)
< JS_SetContextCallback(JSRuntime *rt, JSContextCallback cxCallback);
< 
547,584d434
< #define JSOPTION_COMPILE_N_GO   JS_BIT(4)       /* caller of JS_Compile*Script
<                                                    promises to execute compiled
<                                                    script once only; enables
<                                                    compile-time scope chain
<                                                    resolution of consts. */
< #define JSOPTION_ATLINE         JS_BIT(5)       /* //@line number ["filename"]
<                                                    option supported for the
<                                                    XUL preprocessor and kindred
<                                                    beasts. */
< #define JSOPTION_XML            JS_BIT(6)       /* EMCAScript for XML support:
<                                                    parse <!-- --> as a token,
<                                                    not backward compatible with
<                                                    the comment-hiding hack used
<                                                    in HTML script tags. */
< #define JSOPTION_NATIVE_BRANCH_CALLBACK \
<                                 JS_BIT(7)       /* the branch callback set by
<                                                    JS_SetBranchCallback may be
<                                                    called with a null script
<                                                    parameter, by native code
<                                                    that loops intensively.
<                                                    Deprecated, use
<                                                    JS_SetOperationCallback
<                                                    instead */
< #define JSOPTION_DONT_REPORT_UNCAUGHT \
<                                 JS_BIT(8)       /* When returning from the
<                                                    outermost API call, prevent
<                                                    uncaught exceptions from
<                                                    being converted to error
<                                                    reports */
< 
< #define JSOPTION_RELIMIT        JS_BIT(9)       /* Throw exception on any
<                                                    regular expression which
<                                                    backtracks more than n^3
<                                                    times, where n is length
<                                                    of the input string */
< #define JSOPTION_ANONFUNFIX     JS_BIT(10)      /* Disallow function () {} in
<                                                    statement context per
<                                                    ECMA-262 Edition 3. */
634,646d483
< /*
<  * Enumerate any already-resolved standard class ids into ida, or into a new
<  * JSIdArray if ida is null.  Return the augmented array on success, null on
<  * failure with ida (if it was non-null on entry) destroyed.
<  */
< extern JS_PUBLIC_API(JSIdArray *)
< JS_EnumerateResolvedStandardClasses(JSContext *cx, JSObject *obj,
<                                     JSIdArray *ida);
< 
< extern JS_PUBLIC_API(JSBool)
< JS_GetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key,
<                   JSObject **objp);
< 
650,675d486
< extern JS_PUBLIC_API(JSObject *)
< JS_GetGlobalForObject(JSContext *cx, JSObject *obj);
< 
< /*
<  * Macros to hide interpreter stack layout details from a JSFastNative using
<  * its jsval *vp parameter. The stack layout underlying invocation can't change
<  * without breaking source and binary compatibility (argv[-2] is well-known to
<  * be the callee jsval, and argv[-1] is as well known to be |this|).
<  *
<  * NB: there is an anti-dependency between JS_CALLEE and JS_SET_RVAL: native
<  * methods that may inspect their callee must defer setting their return value
<  * until after any such possible inspection. Otherwise the return value will be
<  * inspected instead of the callee function object.
<  *
<  * WARNING: These are not (yet) mandatory macros, but new code outside of the
<  * engine should use them. In the Mozilla 2.0 milestone their definitions may
<  * change incompatibly.
<  */
< #define JS_CALLEE(cx,vp)        ((vp)[0])
< #define JS_ARGV_CALLEE(argv)    ((argv)[-2])
< #define JS_THIS(cx,vp)          ((vp)[1])
< #define JS_THIS_OBJECT(cx,vp)   ((JSObject *) JS_THIS(cx,vp))
< #define JS_ARGV(cx,vp)          ((vp) + 2)
< #define JS_RVAL(cx,vp)          (*(vp))
< #define JS_SET_RVAL(cx,vp,v)    (*(vp) = (v))
< 
745,751c556,558
<  * See the scoped local root API immediately below for a better way to manage
<  * newborns in cases where native hooks (functions, getters, setters, etc.)
<  * create many GC-things, potentially without connecting them to predefined
<  * local roots such as *rval or argv[i] in an active native function.  Using
<  * JS_EnterLocalRootScope disables updating of the context's per-gc-thing-type
<  * newborn roots, until control flow unwinds and leaves the outermost nesting
<  * local root scope.
---
>  * XXXbe See bug 40757 (http://bugzilla.mozilla.org/show_bug.cgi?id=40757),
>  * which proposes switching (with an #ifdef, alas, if we want to maintain API
>  * compatibility) to a JNI-like extensible local root frame stack model.
756,841d562
< /*
<  * Scoped local root management allows native functions, getter/setters, etc.
<  * to avoid worrying about the newborn root pigeon-holes, overloading local
<  * roots allocated in argv and *rval, or ending up having to call JS_Add*Root
<  * and JS_RemoveRoot to manage global roots temporarily.
<  *
<  * Instead, calling JS_EnterLocalRootScope and JS_LeaveLocalRootScope around
<  * the body of the native hook causes the engine to allocate a local root for
<  * each newborn created in between the two API calls, using a local root stack
<  * associated with cx.  For example:
<  *
<  *    JSBool
<  *    my_GetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
<  *    {
<  *        JSBool ok;
<  *
<  *        if (!JS_EnterLocalRootScope(cx))
<  *            return JS_FALSE;
<  *        ok = my_GetPropertyBody(cx, obj, id, vp);
<  *        JS_LeaveLocalRootScope(cx);
<  *        return ok;
<  *    }
<  *
<  * NB: JS_LeaveLocalRootScope must be called once for every prior successful
<  * call to JS_EnterLocalRootScope.  If JS_EnterLocalRootScope fails, you must
<  * not make the matching JS_LeaveLocalRootScope call.
<  *
<  * JS_LeaveLocalRootScopeWithResult(cx, rval) is an alternative way to leave
<  * a local root scope that protects a result or return value, by effectively
<  * pushing it in the caller's local root scope.
<  *
<  * In case a native hook allocates many objects or other GC-things, but the
<  * native protects some of those GC-things by storing them as property values
<  * in an object that is itself protected, the hook can call JS_ForgetLocalRoot
<  * to free the local root automatically pushed for the now-protected GC-thing.
<  *
<  * JS_ForgetLocalRoot works on any GC-thing allocated in the current local
<  * root scope, but it's more time-efficient when called on references to more
<  * recently created GC-things.  Calling it successively on other than the most
<  * recently allocated GC-thing will tend to average the time inefficiency, and
<  * may risk O(n^2) growth rate, but in any event, you shouldn't allocate too
<  * many local roots if you can root as you go (build a tree of objects from
<  * the top down, forgetting each latest-allocated GC-thing immediately upon
<  * linking it to its parent).
<  */
< extern JS_PUBLIC_API(JSBool)
< JS_EnterLocalRootScope(JSContext *cx);
< 
< extern JS_PUBLIC_API(void)
< JS_LeaveLocalRootScope(JSContext *cx);
< 
< extern JS_PUBLIC_API(void)
< JS_LeaveLocalRootScopeWithResult(JSContext *cx, jsval rval);
< 
< extern JS_PUBLIC_API(void)
< JS_ForgetLocalRoot(JSContext *cx, void *thing);
< 
< #ifdef __cplusplus
< JS_END_EXTERN_C
< 
< class JSAutoLocalRootScope {
<   public:
<     JSAutoLocalRootScope(JSContext *cx) : mContext(cx) {
<         JS_EnterLocalRootScope(mContext);
<     }
<     ~JSAutoLocalRootScope() {
<         JS_LeaveLocalRootScope(mContext);
<     }
< 
<     void forget(void *thing) {
<         JS_ForgetLocalRoot(mContext, thing);
<     }
< 
<   protected:
<     JSContext *mContext;
< 
< #if 0
<   private:
<     static void *operator new(size_t) CPP_THROW_NEW { return 0; };
<     static void operator delete(void *, size_t) { };
< #endif
< };
< 
< JS_BEGIN_EXTERN_C
< #endif
< 
890c611,619
<  * Register externally maintained GC roots.
---
>  * For implementors of JSObjectOps.mark, to mark a GC-thing reachable via a
>  * property or other strong ref identified for debugging purposes by name.
>  * The name argument's storage needs to live only as long as the call to
>  * this routine.
>  *
>  * The final arg is used by GC_MARK_DEBUG code to build a ref path through
>  * the GC's live thing graph.  Implementors of JSObjectOps.mark should pass
>  * its final arg through to this function when marking all GC-things that are
>  * directly reachable from the object being marked.
892,901c621
<  * traceOp: the trace operation. For each root the implementation should call
<  *          JS_CallTracer whenever the root contains a traceable thing.
<  * data:    the data argument to pass to each invocation of traceOp.
<  */
< extern JS_PUBLIC_API(void)
< JS_SetExtraGCRoots(JSRuntime *rt, JSTraceDataOp traceOp, void *data);
< 
< /*
<  * For implementors of JSMarkOp. All new code should implement JSTraceOp
<  * instead.
---
>  * See the JSMarkOp typedef in jspubtd.h, and the JSObjectOps struct below.
906,1084d625
< /*
<  * JS_CallTracer API and related macros for implementors of JSTraceOp, to
<  * enumerate all references to traceable things reachable via a property or
<  * other strong ref identified for debugging purposes by name or index or
<  * a naming callback.
<  *
<  * By definition references to traceable things include non-null pointers
<  * to JSObject, JSString and jsdouble and corresponding jsvals.
<  *
<  * See the JSTraceOp typedef in jspubtd.h.
<  */
< 
< /* Trace kinds to pass to JS_Tracing. */
< #define JSTRACE_OBJECT  0
< #define JSTRACE_DOUBLE  1
< #define JSTRACE_STRING  2
< 
< /*
<  * Use the following macros to check if a particular jsval is a traceable
<  * thing and to extract the thing and its kind to pass to JS_CallTracer.
<  */
< #define JSVAL_IS_TRACEABLE(v)   (JSVAL_IS_GCTHING(v) && !JSVAL_IS_NULL(v))
< #define JSVAL_TO_TRACEABLE(v)   (JSVAL_TO_GCTHING(v))
< #define JSVAL_TRACE_KIND(v)     (JSVAL_TAG(v) >> 1)
< 
< JS_STATIC_ASSERT(JSVAL_TRACE_KIND(JSVAL_OBJECT) == JSTRACE_OBJECT);
< JS_STATIC_ASSERT(JSVAL_TRACE_KIND(JSVAL_DOUBLE) == JSTRACE_DOUBLE);
< JS_STATIC_ASSERT(JSVAL_TRACE_KIND(JSVAL_STRING) == JSTRACE_STRING);
< 
< struct JSTracer {
<     JSContext           *context;
<     JSTraceCallback     callback;
< #ifdef DEBUG
<     JSTraceNamePrinter  debugPrinter;
<     const void          *debugPrintArg;
<     size_t              debugPrintIndex;
< #endif
< };
< 
< /*
<  * The method to call on each reference to a traceable thing stored in a
<  * particular JSObject or other runtime structure. With DEBUG defined the
<  * caller before calling JS_CallTracer must initialize JSTracer fields
<  * describing the reference using the macros below.
<  */
< extern JS_PUBLIC_API(void)
< JS_CallTracer(JSTracer *trc, void *thing, uint32 kind);
< 
< /*
<  * Set debugging information about a reference to a traceable thing to prepare
<  * for the following call to JS_CallTracer.
<  *
<  * When printer is null, arg must be const char * or char * C string naming
<  * the reference and index must be either (size_t)-1 indicating that the name
<  * alone describes the reference or it must be an index into some array vector
<  * that stores the reference.
<  *
<  * When printer callback is not null, the arg and index arguments are
<  * available to the callback as debugPrinterArg and debugPrintIndex fields
<  * of JSTracer.
<  *
<  * The storage for name or callback's arguments needs to live only until
<  * the following call to JS_CallTracer returns.
<  */
< #ifdef DEBUG
< # define JS_SET_TRACING_DETAILS(trc, printer, arg, index)                     \
<     JS_BEGIN_MACRO                                                            \
<         (trc)->debugPrinter = (printer);                                      \
<         (trc)->debugPrintArg = (arg);                                         \
<         (trc)->debugPrintIndex = (index);                                     \
<     JS_END_MACRO
< #else
< # define JS_SET_TRACING_DETAILS(trc, printer, arg, index)                     \
<     JS_BEGIN_MACRO                                                            \
<     JS_END_MACRO
< #endif
< 
< /*
<  * Convenience macro to describe the argument of JS_CallTracer using C string
<  * and index.
<  */
< # define JS_SET_TRACING_INDEX(trc, name, index)                               \
<     JS_SET_TRACING_DETAILS(trc, NULL, name, index)
< 
< /*
<  * Convenience macro to describe the argument of JS_CallTracer using C string.
<  */
< # define JS_SET_TRACING_NAME(trc, name)                                       \
<     JS_SET_TRACING_DETAILS(trc, NULL, name, (size_t)-1)
< 
< /*
<  * Convenience macro to invoke JS_CallTracer using C string as the name for
<  * the reference to a traceable thing.
<  */
< # define JS_CALL_TRACER(trc, thing, kind, name)                               \
<     JS_BEGIN_MACRO                                                            \
<         JS_SET_TRACING_NAME(trc, name);                                       \
<         JS_CallTracer((trc), (thing), (kind));                                \
<     JS_END_MACRO
< 
< /*
<  * Convenience macros to invoke JS_CallTracer when jsval represents a
<  * reference to a traceable thing.
<  */
< #define JS_CALL_VALUE_TRACER(trc, val, name)                                  \
<     JS_BEGIN_MACRO                                                            \
<         if (JSVAL_IS_TRACEABLE(val)) {                                        \
<             JS_CALL_TRACER((trc), JSVAL_TO_GCTHING(val),                      \
<                            JSVAL_TRACE_KIND(val), name);                      \
<         }                                                                     \
<     JS_END_MACRO
< 
< #define JS_CALL_OBJECT_TRACER(trc, object, name)                              \
<     JS_BEGIN_MACRO                                                            \
<         JSObject *obj_ = (object);                                            \
<         JS_ASSERT(obj_);                                                      \
<         JS_CALL_TRACER((trc), obj_, JSTRACE_OBJECT, name);                    \
<     JS_END_MACRO
< 
< #define JS_CALL_STRING_TRACER(trc, string, name)                              \
<     JS_BEGIN_MACRO                                                            \
<         JSString *str_ = (string);                                            \
<         JS_ASSERT(str_);                                                      \
<         JS_CALL_TRACER((trc), str_, JSTRACE_STRING, name);                    \
<     JS_END_MACRO
< 
< #define JS_CALL_DOUBLE_TRACER(trc, number, name)                              \
<     JS_BEGIN_MACRO                                                            \
<         jsdouble *num_ = (number);                                            \
<         JS_ASSERT(num_);                                                      \
<         JS_CALL_TRACER((trc), num_, JSTRACE_DOUBLE, name);                    \
<     JS_END_MACRO
< 
< /*
<  * API for JSTraceCallback implementations.
<  */
< # define JS_TRACER_INIT(trc, cx_, callback_)                                  \
<     JS_BEGIN_MACRO                                                            \
<         (trc)->context = (cx_);                                               \
<         (trc)->callback = (callback_);                                        \
<         JS_SET_TRACING_DETAILS(trc, NULL, NULL, (size_t)-1);                  \
<     JS_END_MACRO
< 
< extern JS_PUBLIC_API(void)
< JS_TraceChildren(JSTracer *trc, void *thing, uint32 kind);
< 
< extern JS_PUBLIC_API(void)
< JS_TraceRuntime(JSTracer *trc);
< 
< #ifdef DEBUG
< 
< extern JS_PUBLIC_API(void)
< JS_PrintTraceThingInfo(char *buf, size_t bufsize, JSTracer *trc,
<                        void *thing, uint32 kind, JSBool includeDetails);
< 
< /*
<  * DEBUG-only method to dump the object graph of heap-allocated things.
<  *
<  * fp:              file for the dump output.
<  * start:           when non-null, dump only things reachable from start
<  *                  thing. Otherwise dump all things reachable from the
<  *                  runtime roots.
<  * startKind:       trace kind of start if start is not null. Must be 0 when
<  *                  start is null.
<  * thingToFind:     dump only paths in the object graph leading to thingToFind
<  *                  when non-null.
<  * maxDepth:        the upper bound on the number of edges to descend from the
<  *                  graph roots.
<  * thingToIgnore:   thing to ignore during the graph traversal when non-null.
<  */
< extern JS_PUBLIC_API(JSBool)
< JS_DumpHeap(JSContext *cx, FILE *fp, void* startThing, uint32 startKind,
<             void *thingToFind, size_t maxDepth, void *thingToIgnore);
< 
< #endif
< 
< /*
<  * Garbage collector API.
<  */
1098,1100d638
< JS_IsGCMarkingTracer(JSTracer *trc);
< 
< extern JS_PUBLIC_API(JSBool)
1103,1116d640
< typedef enum JSGCParamKey {
<     /* Maximum nominal heap before last ditch GC. */
<     JSGC_MAX_BYTES          = 0,
< 
<     /* Number of JS_malloc bytes before last ditch GC. */
<     JSGC_MAX_MALLOC_BYTES   = 1,
< 
<     /* Hoard stackPools for this long, in ms, default is 30 seconds. */
<     JSGC_STACKPOOL_LIFESPAN = 2
< } JSGCParamKey;
< 
< extern JS_PUBLIC_API(void)
< JS_SetGCParameter(JSRuntime *rt, JSGCParamKey key, uint32 value);
< 
1118c642
<  * Add a finalizer for external strings created by JS_NewExternalString (see
---
>  * Add an external string finalizer, one created by JS_NewExternalString (see
1163,1185d686
< /*
<  * Sets maximum (if stack grows upward) or minimum (downward) legal stack byte
<  * address in limitAddr for the thread or process stack used by cx.  To disable
<  * stack size checking, pass 0 for limitAddr.
<  */
< extern JS_PUBLIC_API(void)
< JS_SetThreadStackLimit(JSContext *cx, jsuword limitAddr);
< 
< /*
<  * Set the quota on the number of bytes that stack-like data structures can
<  * use when the runtime compiles and executes scripts. These structures
<  * consume heap space, so JS_SetThreadStackLimit does not bound their size.
<  * The default quota is 32MB which is quite generous.
<  *
<  * The function must be called before any script compilation or execution API
<  * calls, i.e. either immediately after JS_NewContext or from JSCONTEXT_NEW
<  * context callback.
<  */
< extern JS_PUBLIC_API(void)
< JS_SetScriptStackQuota(JSContext *cx, size_t quota);
< 
< #define JS_DEFAULT_SCRIPT_STACK_QUOTA   ((size_t) 0x2000000)
< 
1215,1229c716
<     JSReserveSlotsOp    reserveSlots;
< };
< 
< struct JSExtendedClass {
<     JSClass             base;
<     JSEqualityOp        equality;
<     JSObjectOp          outerObject;
<     JSObjectOp          innerObject;
<     JSIteratorOp        iteratorObject;
<     JSObjectOp          wrappedObject;          /* NB: infallible, null
<                                                    returns are treated as
<                                                    the original object */
<     void                (*reserved0)(void);
<     void                (*reserved1)(void);
<     void                (*reserved2)(void);
---
>     jsword              spare;
1241,1243d727
< #define JSCLASS_CONSTRUCT_PROTOTYPE     (1<<6)  /* call constructor on class
<                                                    prototype */
< #define JSCLASS_DOCUMENT_OBSERVER       (1<<7)  /* DOM document observer */
1253c737
< #define JSCLASS_HAS_RESERVED_SLOTS(n)   (((n) & JSCLASS_RESERVED_SLOTS_MASK)  \
---
> #define JSCLASS_HAS_RESERVED_SLOTS(n)   (((n) & JSCLASS_RESERVED_SLOTS_MASK)   \
1256c740
<                                           >> JSCLASS_RESERVED_SLOTS_SHIFT)    \
---
>                                           >> JSCLASS_RESERVED_SLOTS_SHIFT)     \
1259,1301d742
< #define JSCLASS_HIGH_FLAGS_SHIFT        (JSCLASS_RESERVED_SLOTS_SHIFT +       \
<                                          JSCLASS_RESERVED_SLOTS_WIDTH)
< 
< /* True if JSClass is really a JSExtendedClass. */
< #define JSCLASS_IS_EXTENDED             (1<<(JSCLASS_HIGH_FLAGS_SHIFT+0))
< #define JSCLASS_IS_ANONYMOUS            (1<<(JSCLASS_HIGH_FLAGS_SHIFT+1))
< #define JSCLASS_IS_GLOBAL               (1<<(JSCLASS_HIGH_FLAGS_SHIFT+2))
< 
< /* Indicates that JSClass.mark is a tracer with JSTraceOp type. */
< #define JSCLASS_MARK_IS_TRACE           (1<<(JSCLASS_HIGH_FLAGS_SHIFT+3))
< 
< /*
<  * Indicates that the class object defined on the object provided to
<  * JS_InitClass should be readonly and permanent.
<  */
< #define JSCLASS_FIXED_BINDING           (1<<(JSCLASS_HIGH_FLAGS_SHIFT+4))
< 
< /*
<  * ECMA-262 requires that most constructors used internally create objects
<  * with "the original Foo.prototype value" as their [[Prototype]] (__proto__)
<  * member initial value.  The "original ... value" verbiage is there because
<  * in ECMA-262, global properties naming class objects are read/write and
<  * deleteable, for the most part.
<  *
<  * Implementing this efficiently requires that global objects have classes
<  * with the following flags.  Failure to use JSCLASS_GLOBAL_FLAGS won't break
<  * anything except the ECMA-262 "original prototype value" behavior, which was
<  * broken for years in SpiderMonkey.  In other words, without these flags you
<  * get backward compatibility.
<  */
< #define JSCLASS_GLOBAL_FLAGS \
<     (JSCLASS_IS_GLOBAL | JSCLASS_HAS_RESERVED_SLOTS(JSProto_LIMIT))
< 
< /* Fast access to the original value of each standard class's prototype. */
< #define JSCLASS_CACHED_PROTO_SHIFT      (JSCLASS_HIGH_FLAGS_SHIFT + 8)
< #define JSCLASS_CACHED_PROTO_WIDTH      8
< #define JSCLASS_CACHED_PROTO_MASK       JS_BITMASK(JSCLASS_CACHED_PROTO_WIDTH)
< #define JSCLASS_HAS_CACHED_PROTO(key)   ((key) << JSCLASS_CACHED_PROTO_SHIFT)
< #define JSCLASS_CACHED_PROTO_KEY(clasp) ((JSProtoKey)                         \
<                                          (((clasp)->flags                     \
<                                            >> JSCLASS_CACHED_PROTO_SHIFT)     \
<                                           & JSCLASS_CACHED_PROTO_MASK))
< 
1304d744
< #define JSCLASS_NO_RESERVED_MEMBERS     0,0,0
1331c771
<     JSTraceOp           trace;
---
>     JSMarkOp            mark;
1337,1345d776
< struct JSXMLObjectOps {
<     JSObjectOps         base;
<     JSGetMethodOp       getMethod;
<     JSSetMethodOp       setMethod;
<     JSEnumerateValuesOp enumerateValues;
<     JSEqualityOp        equality;
<     JSConcatenateOp     concatenate;
< };
< 
1374,1383d804
< /*
<  * The magic XML namespace id is int-tagged, but not a valid integer jsval.
<  * Global object classes in embeddings that enable JS_HAS_XML_SUPPORT (E4X)
<  * should handle this id specially before converting id via JSVAL_TO_INT.
<  */
< #define JS_DEFAULT_XML_NAMESPACE_ID ((jsid) JSVAL_VOID)
< 
< /*
<  * JSNewResolveOp flag bits.
<  */
1386,1388d806
< #define JSRESOLVE_DETECTING     0x04    /* 'if (o.p)...' or '(o.p) ?...:...' */
< #define JSRESOLVE_DECLARING     0x08    /* var, const, or function prolog op */
< #define JSRESOLVE_CLASSNAME     0x10    /* class name used when constructing */
1428d845
< #ifdef MOZILLA_1_8_BRANCH
1431,1443c848
<     uint16          extra;
< #else
<     uint16          nargs;
<     uint16          flags;
< 
<     /*
<      * extra & 0xFFFF:  Number of extra argument slots for local GC roots.
<      *                  If fast native, must be zero.
<      * extra >> 16:     If slow native, reserved for future use (must be 0).
<      *                  If fast native, minimum required argc.
<      */
<     uint32          extra;
< #endif
---
>     uint16          extra;      /* number of arg slots for local GC roots */
1446,1470d850
< /*
<  * Terminating sentinel initializer to put at the end of a JSFunctionSpec array
<  * that's passed to JS_DefineFunctions or JS_InitClass.
<  */
< #define JS_FS_END JS_FS(NULL,NULL,0,0,0)
< 
< /*
<  * Initializer macro for a JSFunctionSpec array element. This is the original
<  * kind of native function specifier initializer. Use JS_FN ("fast native", see
<  * JSFastNative in jspubtd.h) for all functions that do not need a stack frame
<  * when activated.
<  */
< #define JS_FS(name,call,nargs,flags,extra)                                    \
<     {name, call, nargs, flags, extra}
< 
< /*
<  * "Fast native" initializer macro for a JSFunctionSpec array element. Use this
<  * in preference to JS_FS if the native in question does not need its own stack
<  * frame when activated.
<  */
< #define JS_FN(name,fastcall,minargs,nargs,flags)                              \
<     {name, (JSNative)(fastcall), nargs,                                       \
<      (flags) | JSFUN_FAST_NATIVE | JSFUN_STUB_GSOPS,                          \
<      (minargs) << 16}
< 
1492,1494d871
< extern JS_PUBLIC_API(JSBool)
< JS_HasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp);
< 
1520,1527d896
< /*
<  * Get a unique identifier for obj, good for the lifetime of obj (even if it
<  * is moved by a copying GC).  Return false on failure (likely out of memory),
<  * and true with *idp containing the unique id on success.
<  */
< extern JS_PUBLIC_API(JSBool)
< JS_GetObjectId(JSContext *cx, JSObject *obj, jsid *idp);
< 
1531,1538d899
< /*
<  * Unlike JS_NewObject, JS_NewObjectWithGivenProto does not compute a default
<  * proto if proto's actual parameter value is null.
<  */
< extern JS_PUBLIC_API(JSObject *)
< JS_NewObjectWithGivenProto(JSContext *cx, JSClass *clasp, JSObject *proto,
<                            JSObject *parent);
< 
1541a903,905
> extern JS_PUBLIC_API(JSBool)
> JS_UnsealObject(JSContext *cx, JSObject *obj, JSBool deep);
> 
1575,1586d938
<  * The same, but if the property is native, return its getter and setter via
<  * *getterp and *setterp, respectively (and only if the out parameter pointer
<  * is not null).
<  */
< extern JS_PUBLIC_API(JSBool)
< JS_GetPropertyAttrsGetterAndSetter(JSContext *cx, JSObject *obj,
<                                    const char *name,
<                                    uintN *attrsp, JSBool *foundp,
<                                    JSPropertyOp *getterp,
<                                    JSPropertyOp *setterp);
< 
< /*
1607,1613d958
< JS_AlreadyHasOwnProperty(JSContext *cx, JSObject *obj, const char *name,
<                          JSBool *foundp);
< 
< extern JS_PUBLIC_API(JSBool)
< JS_HasProperty(JSContext *cx, JSObject *obj, const char *name, JSBool *foundp);
< 
< extern JS_PUBLIC_API(JSBool)
1617,1620d961
< JS_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, const char *name,
<                            uintN flags, jsval *vp);
< 
< extern JS_PUBLIC_API(JSBool)
1624,1631d964
< JS_GetMethodById(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
<                  jsval *vp);
< 
< extern JS_PUBLIC_API(JSBool)
< JS_GetMethod(JSContext *cx, JSObject *obj, const char *name, JSObject **objp,
<              jsval *vp);
< 
< extern JS_PUBLIC_API(JSBool)
1659,1670d991
<  * The same, but if the property is native, return its getter and setter via
<  * *getterp and *setterp, respectively (and only if the out parameter pointer
<  * is not null).
<  */
< extern JS_PUBLIC_API(JSBool)
< JS_GetUCPropertyAttrsGetterAndSetter(JSContext *cx, JSObject *obj,
<                                      const jschar *name, size_t namelen,
<                                      uintN *attrsp, JSBool *foundp,
<                                      JSPropertyOp *getterp,
<                                      JSPropertyOp *setterp);
< 
< /*
1690,1698d1010
< JS_AlreadyHasOwnUCProperty(JSContext *cx, JSObject *obj, const jschar *name,
<                            size_t namelen, JSBool *foundp);
< 
< extern JS_PUBLIC_API(JSBool)
< JS_HasUCProperty(JSContext *cx, JSObject *obj,
<                  const jschar *name, size_t namelen,
<                  JSBool *vp);
< 
< extern JS_PUBLIC_API(JSBool)
1741,1747d1052
< JS_AlreadyHasOwnElement(JSContext *cx, JSObject *obj, jsint index,
<                         JSBool *foundp);
< 
< extern JS_PUBLIC_API(JSBool)
< JS_HasElement(JSContext *cx, JSObject *obj, jsint index, JSBool *foundp);
< 
< extern JS_PUBLIC_API(JSBool)
1768,1783d1072
< /*
<  * Create an object to iterate over enumerable properties of obj, in arbitrary
<  * property definition order.  NB: This differs from longstanding for..in loop
<  * order, which uses order of property definition in obj.
<  */
< extern JS_PUBLIC_API(JSObject *)
< JS_NewPropertyIterator(JSContext *cx, JSObject *obj);
< 
< /*
<  * Return true on success with *idp containing the id of the next enumerable
<  * property to visit using iterobj, or JSVAL_VOID if there is no such property
<  * left to visit.  Return false on error.
<  */
< extern JS_PUBLIC_API(JSBool)
< JS_NextProperty(JSContext *cx, JSObject *iterobj, jsid *idp);
< 
1804,1805d1092
< 
<     /* XXX unspecified and unused by Mozilla code -- can we remove these? */
1810,1813c1097,1098
<     jsrefcount refcount;
< 
<     void   (* JS_DLL_CALLBACK destroy)(JSContext *cx, JSPrincipals *);
<     JSBool (* JS_DLL_CALLBACK subsume)(JSPrincipals *, JSPrincipals *);
---
>     uintN refcount;
>     void (* JS_DLL_CALLBACK destroy)(JSContext *cx, struct JSPrincipals *);
1816,1832c1101,1106
< #ifdef JS_THREADSAFE
< #define JSPRINCIPALS_HOLD(cx, principals)   JS_HoldPrincipals(cx,principals)
< #define JSPRINCIPALS_DROP(cx, principals)   JS_DropPrincipals(cx,principals)
< 
< extern JS_PUBLIC_API(jsrefcount)
< JS_HoldPrincipals(JSContext *cx, JSPrincipals *principals);
< 
< extern JS_PUBLIC_API(jsrefcount)
< JS_DropPrincipals(JSContext *cx, JSPrincipals *principals);
< 
< #else
< #define JSPRINCIPALS_HOLD(cx, principals)   (++(principals)->refcount)
< #define JSPRINCIPALS_DROP(cx, principals)                                     \
<     ((--(principals)->refcount == 0)                                          \
<      ? ((*(principals)->destroy)((cx), (principals)), 0)                      \
<      : (principals)->refcount)
< #endif
---
> #define JSPRINCIPALS_HOLD(cx, principals)               \
>     ((principals)->refcount++)
> #define JSPRINCIPALS_DROP(cx, principals)               \
>     ((--((principals)->refcount) == 0)                  \
>         ? (*(principals)->destroy)((cx), (principals))  \
>         : (void) 0)
1837,1839d1110
< extern JS_PUBLIC_API(JSObjectPrincipalsFinder)
< JS_SetObjectPrincipalsFinder(JSRuntime *rt, JSObjectPrincipalsFinder fop);
< 
1879,1884d1149
<  * Return the arity (length) of fun.
<  */
< extern JS_PUBLIC_API(uint16)
< JS_GetFunctionArity(JSFunction *fun);
< 
< /*
1900,1904d1164
< extern JS_PUBLIC_API(JSFunction *)
< JS_DefineUCFunction(JSContext *cx, JSObject *obj,
<                     const jschar *name, size_t namelen, JSNative call,
<                     uintN nargs, uintN attrs);
< 
2117,2171d1376
< /*
<  * The maximum value of the operation limit to pass to JS_SetOperationCallback
<  * and JS_SetOperationLimit.
<  */
< #define JS_MAX_OPERATION_LIMIT ((uint32) 0x7FFFFFFF)
< 
< #define JS_OPERATION_WEIGHT_BASE 4096
< 
< /*
<  * Set the operation callback that the engine calls periodically after
<  * the internal operation count reaches the specified limit.
<  *
<  * When operationLimit is JS_OPERATION_WEIGHT_BASE, the callback will be
<  * called at least after each backward jump in the interpreter. To minimize
<  * the overhead of the callback invocation we suggest at least
<  *
<  *   100 * JS_OPERATION_WEIGHT_BASE
<  *
<  * as a value for operationLimit.
<  */
< extern JS_PUBLIC_API(void)
< JS_SetOperationCallback(JSContext *cx, JSOperationCallback callback,
<                         uint32 operationLimit);
< 
< extern JS_PUBLIC_API(void)
< JS_ClearOperationCallback(JSContext *cx);
< 
< extern JS_PUBLIC_API(JSOperationCallback)
< JS_GetOperationCallback(JSContext *cx);
< 
< /*
<  * Get the operation limit associated with the operation callback. This API
<  * function may be called only when the result of JS_GetOperationCallback(cx)
<  * is not null.
<  */
< extern JS_PUBLIC_API(uint32)
< JS_GetOperationLimit(JSContext *cx);
< 
< /*
<  * Change the operation limit associated with the operation callback. This API
<  * function may be called only when the result of JS_GetOperationCallback(cx)
<  * is not null.
<  */
< extern JS_PUBLIC_API(void)
< JS_SetOperationLimit(JSContext *cx, uint32 operationLimit);
< 
< /*
<  * Note well: JS_SetBranchCallback is deprecated. It is similar to
<  *
<  *   JS_SetOperationCallback(cx, callback, 4096, NULL);
<  *
<  * except that the callback will not be called from a long-running native
<  * function when JSOPTION_NATIVE_BRANCH_CALLBACK is not set and the top-most
<  * frame is native.
<  */
2200,2218d1404
< /*
<  * Saving and restoring frame chains.
<  *
<  * These two functions are used to set aside cx's call stack while that stack
<  * is inactive. After a call to JS_SaveFrameChain, it looks as if there is no
<  * code running on cx. Before calling JS_RestoreFrameChain, cx's call stack
<  * must be balanced and all nested calls to JS_SaveFrameChain must have had
<  * matching JS_RestoreFrameChain calls.
<  *
<  * JS_SaveFrameChain deals with cx not having any code running on it. A null
<  * return does not signify an error, and JS_RestoreFrameChain handles a null
<  * frame pointer argument safely.
<  */
< extern JS_PUBLIC_API(JSStackFrame *)
< JS_SaveFrameChain(JSContext *cx);
< 
< extern JS_PUBLIC_API(void)
< JS_RestoreFrameChain(JSContext *cx, JSStackFrame *fp);
< 
2324,2374d1509
< /*
<  * Return JS_TRUE if C (char []) strings passed via the API and internally
<  * are UTF-8.
<  */
< JS_PUBLIC_API(JSBool)
< JS_CStringsAreUTF8(void);
< 
< /*
<  * Update the value to be returned by JS_CStringsAreUTF8(). Once set, it
<  * can never be changed. This API must be called before the first call to
<  * JS_NewRuntime.
<  */
< JS_PUBLIC_API(void)
< JS_SetCStringsAreUTF8(void);
< 
< /*
<  * Character encoding support.
<  *
<  * For both JS_EncodeCharacters and JS_DecodeBytes, set *dstlenp to the size
<  * of the destination buffer before the call; on return, *dstlenp contains the
<  * number of bytes (JS_EncodeCharacters) or jschars (JS_DecodeBytes) actually
<  * stored.  To determine the necessary destination buffer size, make a sizing
<  * call that passes NULL for dst.
<  *
<  * On errors, the functions report the error. In that case, *dstlenp contains
<  * the number of characters or bytes transferred so far.  If cx is NULL, no
<  * error is reported on failure, and the functions simply return JS_FALSE.
<  *
<  * NB: Neither function stores an additional zero byte or jschar after the
<  * transcoded string.
<  *
<  * If JS_CStringsAreUTF8() is true then JS_EncodeCharacters encodes to
<  * UTF-8, and JS_DecodeBytes decodes from UTF-8, which may create additional
<  * errors if the character sequence is malformed.  If UTF-8 support is
<  * disabled, the functions deflate and inflate, respectively.
<  */
< JS_PUBLIC_API(JSBool)
< JS_EncodeCharacters(JSContext *cx, const jschar *src, size_t srclen, char *dst,
<                     size_t *dstlenp);
< 
< JS_PUBLIC_API(JSBool)
< JS_DecodeBytes(JSContext *cx, const char *src, size_t srclen, jschar *dst,
<                size_t *dstlenp);
< 
< /*
<  * A variation on JS_EncodeCharacters where a null terminated string is
<  * returned that you are expected to call JS_free on when done.
<  */
< JS_PUBLIC_API(char *)
< JS_EncodeString(JSContext *cx, JSString *str);
< 
2378c1513
<  * Locale specific string conversion and error message callbacks.
---
>  * Locale specific string conversion callback.
2384,2385d1518
<     JSLocaleToUnicode       localeToUnicode;
<     JSErrorCallback         localeGetErrorMessage;
2466a1600,1603
>     #if 1 // !!dp
>     int				count;			// !!dp call back count
>     void			*lscript;		// Reference to lingo script
>     #endif
2499d1635
< #define JSREG_STICKY    0x08    /* only match starting at lastIndex */
2532,2534d1667
< extern JS_PUBLIC_API(JSBool)
< JS_ReportPendingException(JSContext *cx);
< 
2565,2578d1697
< /*
<  * Given a reported error's message and JSErrorReport struct pointer, throw
<  * the corresponding exception on cx.
<  */
< extern JS_PUBLIC_API(JSBool)
< JS_ThrowReportedError(JSContext *cx, const char *message,
<                       JSErrorReport *reportp);
< 
< /*
<  * Throws a StopIteration exception on cx.
<  */
< extern JS_PUBLIC_API(JSBool)
< JS_ThrowStopIteration(JSContext *cx);
< 
2596c1715
< extern JS_PUBLIC_API(jsword)
---
> extern JS_PUBLIC_API(intN)
2603,2611d1721
< #ifdef DEBUG
< #define JS_GC_ZEAL 1
< #endif
< 
< #ifdef JS_GC_ZEAL
< extern JS_PUBLIC_API(void)
< JS_SetGCZeal(JSContext *cx, uint8 zeal);
< #endif
< 
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsarena.c /Volumes/Swap/js_D11/src/jsarena.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,22c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
26,38c23,33
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
46c41
< #include <stdlib.h>
---
> #include "xstdlib.h"
51a47,56
> #include "jslock.h"
> #include "jsapi.h"
> 
> //#include "_optimize.h"
> 
> static JSArena *arena_freelist;
> 
> #ifdef JS_THREADSAFE
> static JSLock *arena_freelist_lock;
> #endif
64,65c69
< JS_INIT_NAMED_ARENA_POOL(JSArenaPool *pool, const char *name, size_t size,
<                          size_t align, size_t *quotap)
---
> JS_InitArenaPool(JSArenaPool *pool, const char *name, size_t size, size_t align)
66a71,77
> #ifdef JS_THREADSAFE
>     /* Must come through here once in primordial thread to init safely! */
>     if (!arena_freelist_lock) {
>         arena_freelist_lock = JS_NEW_LOCK();
>         JS_ASSERT(arena_freelist_lock);
>     }
> #endif
68c79
<         align = JS_ARENA_DEFAULT_ALIGN;
---
> 	align = JS_ARENA_DEFAULT_ALIGN;
72c83
<         JS_ARENA_ALIGN(pool, &pool->first + 1);
---
> 	JS_ARENA_ALIGN(pool, &pool->first + 1);
75d85
<     pool->quotap = quotap;
97,105c107,127
<  * the modulus for a pointer.  Given M >= P, the base of an oversized arena
<  * that satisfies M is well-aligned for P.
<  *
<  * On the other hand, if M < P, we must include enough space in the header
<  * size to align the back-pointer on a P boundary so that it can be found by
<  * subtracting P from a->base.  This means a->base must be on a P boundary,
<  * even though subsequent allocations from a may be aligned on a lesser (M)
<  * boundary.  Given powers of two M and P as above, the extra space needed
<  * when M < P is P-M or POINTER_MASK - pool->mask.
---
>  * the modulus for a pointer.  Given M >= P, the greatest distance between a
>  * pointer aligned on an M boundary and one aligned on a P boundary is M-P.
>  * If M and P are powers of two, then M-P = (pool->mask - POINTER_MASK).
>  *
>  * How much extra padding might spill over unused into the remainder of the
>  * allocation, in the worst case (where M > P)?
>  *
>  * If we add M-P to the nominal back-pointer address and then round down to
>  * align on a P boundary, we will use at most M-P bytes of padding, and at
>  * least P (M > P => M >= 2P; M == 2P gives the least padding, P).  So if we
>  * use P bytes of padding, then we will overallocate a by P+M-1 bytes, as we
>  * also add M-1 to the estimated size in case malloc returns an odd pointer.
>  * a->limit must include this overestimation to satisfy a->avail in [a->base,
>  * a->limit].
>  *
>  * Similarly, if pool->mask is less than POINTER_MASK, we must include enough
>  * space in the header size to align the back-pointer on a P boundary so that
>  * it can be found by subtracting P from a->base.  This means a->base must be
>  * on a P boundary, even though subsequent allocations from a may be aligned
>  * on a lesser (M) boundary.  Given powers of two M and P as above, the extra
>  * space needed when P > M is P-M or POINTER_MASK - pool->mask.
122c144
<                                     : 0))
---
>                                     : (pool)->mask - POINTER_MASK))
134,135c156,157
<     JSArena **ap, *a, *b;
<     jsuword extra, hdrsz, gross;
---
>     JSArena **ap, **bp, *a, *b;
>     jsuword extra, hdrsz, gross, sz;
138,148c160
<     /*
<      * Search pool from current forward till we find or make enough space.
<      *
<      * NB: subtract nb from a->limit in the loop condition, instead of adding
<      * nb to a->avail, to avoid overflowing a 32-bit address space (possible
<      * when running a 32-bit program on a 64-bit system where the kernel maps
<      * the heap up against the top of the 32-bit address space).
<      *
<      * Thanks to Juergen Kreileder <jk@blackdown.de>, who brought this up in
<      * https://bugzilla.mozilla.org/show_bug.cgi?id=279273.
<      */
---
>     /* Search pool from current forward till we find or make enough space. */
150,151c162
<     for (a = pool->current; nb > a->limit || a->avail > a->limit - nb;
<          pool->current = a) {
---
>     for (a = pool->current; a->avail + nb > a->limit; pool->current = a) {
154c165
<             /* Not enough space in pool, so we must malloc. */
---
>             /* Not enough space in pool -- try to reclaim a free arena. */
158,170c169,187
<             if (gross < nb)
<                 return NULL;
<             if (pool->quotap) {
<                 if (gross > *pool->quotap)
<                     return NULL;
<                 b = (JSArena *) malloc(gross);
<                 if (!b)
<                     return NULL;
<                 *pool->quotap -= gross;
<             } else {
<                 b = (JSArena *) malloc(gross);
<                 if (!b)
<                     return NULL;
---
>             bp = &arena_freelist;
>             JS_ACQUIRE_LOCK(arena_freelist_lock);
>             while ((b = *bp) != NULL) {
>                 /*
>                  * Insist on exact arenasize match if nb is not greater than
>                  * arenasize.  Otherwise take any arena big enough, but not by
>                  * more than gross + arenasize.
>                  */
>                 sz = JS_UPTRDIFF(b->limit, b);
>                 if (extra
>                     ? sz >= gross && sz <= gross + pool->arenasize
>                     : sz == gross) {
>                     *bp = b->next;
>                     JS_RELEASE_LOCK(arena_freelist_lock);
>                     b->next = NULL;
>                     COUNT(pool, nreclaims);
>                     goto claim;
>                 }
>                 bp = &b->next;
172a190,195
>             /* Nothing big enough on the freelist, so we must malloc. */
>             JS_RELEASE_LOCK(arena_freelist_lock);
>             XMEMTAG("JSArena");
>             b = (JSArena *) xmalloc(gross);
>             if (!b)
>                 return 0;
177a201
>         claim:
203c227
<     jsuword boff, aoff, extra, hdrsz, gross, growth;
---
>     jsuword boff, aoff, extra, hdrsz, gross;
220c244
<     aoff = JS_ARENA_ALIGN(pool, size + incr);
---
>     aoff = size + incr;
225,238c249,252
<     JS_ASSERT(gross > aoff);
<     if (pool->quotap) {
<         growth = gross - (a->limit - (jsuword) a);
<         if (growth > *pool->quotap)
<             return NULL;
<         a = (JSArena *) realloc(a, gross);
<         if (!a)
<             return NULL;
<         *pool->quotap -= growth;
<     } else {
<         a = (JSArena *) realloc(a, gross);
<         if (!a)
<             return NULL;
<     }
---
>     XMEMTAG("JS_ArenaRealloc");
>     a = (JSArena *) xrealloc(a, gross);
>     if (!a)
>         return NULL;
259c273
<     a->avail = a->base + aoff;
---
>     a->avail = JS_ARENA_ALIGN(pool, a->base + aoff);
294c308
< FreeArenaList(JSArenaPool *pool, JSArena *head)
---
> FreeArenaList(JSArenaPool *pool, JSArena *head, JSBool reallyFree)
301c315
<         return;
---
> 	return;
305,307c319,321
<         JS_ASSERT(a->base <= a->avail && a->avail <= a->limit);
<         a->avail = a->base;
<         JS_CLEAR_UNUSED(a);
---
> 	JS_ASSERT(a->base <= a->avail && a->avail <= a->limit);
> 	a->avail = a->base;
> 	JS_CLEAR_UNUSED(a);
312,319c326,343
<     do {
<         *ap = a->next;
<         if (pool->quotap)
<             *pool->quotap += a->limit - (jsuword) a;
<         JS_CLEAR_ARENA(a);
<         JS_COUNT_ARENA(pool,--);
<         free(a);
<     } while ((a = *ap) != NULL);
---
>     if (reallyFree) {
> 	do {
> 	    *ap = a->next;
> 	    JS_CLEAR_ARENA(a);
> 	    JS_COUNT_ARENA(pool,--);
> 	    xfree(a);
> 	} while ((a = *ap) != NULL);
>     } else {
> 	/* Insert the whole arena chain at the front of the freelist. */
> 	do {
> 	    ap = &(*ap)->next;
> 	} while (*ap);
>         JS_ACQUIRE_LOCK(arena_freelist_lock);
> 	*ap = arena_freelist;
> 	arena_freelist = a;
>         JS_RELEASE_LOCK(arena_freelist_lock);
> 	head->next = NULL;
>     }
330c354
<         JS_ASSERT(a->base <= a->avail && a->avail <= a->limit);
---
> 	JS_ASSERT(a->base <= a->avail && a->avail <= a->limit);
332,333c356,357
<         if (JS_ARENA_MARK_MATCH(a, mark)) {
<             a->avail = JS_ARENA_ALIGN(pool, mark);
---
> 	if (JS_UPTRDIFF(mark, a->base) <= JS_UPTRDIFF(a->avail, a->base)) {
> 	    a->avail = JS_ARENA_ALIGN(pool, mark);
335,337c359,361
<             FreeArenaList(pool, a);
<             return;
<         }
---
> 	    FreeArenaList(pool, a, JS_TRUE);
> 	    return;
> 	}
383,386c407,408
<      * at it.  We must preserve LIFO order of mark/release cursors, so we use
<      * the oversized-allocation arena's back pointer (or if not oversized, we
<      * use the result of searching the entire pool) to compute the address of
<      * the arena that precedes a.
---
>      * at it.  What's more, force future allocations to scavenge all arenas on
>      * pool, in case some have free space.
389c411
<         pool->current = (JSArena *) ((char *)ap - offsetof(JSArena, next));
---
>         pool->current = &pool->first;
400,401d421
<     if (pool->quotap)
<         *pool->quotap += a->limit - (jsuword) a;
404c424
<     free(a);
---
>     xfree(a);
410c430
<     FreeArenaList(pool, &pool->first);
---
>     FreeArenaList(pool, &pool->first, JS_FALSE);
417c437
<     FreeArenaList(pool, &pool->first);
---
>     FreeArenaList(pool, &pool->first, JS_TRUE);
420c440
<         JSArenaStats *stats, **statsp;
---
> 	JSArenaStats *stats, **statsp;
422,432c442,450
<         if (pool->stats.name) {
<             free(pool->stats.name);
<             pool->stats.name = NULL;
<         }
<         for (statsp = &arena_stats_list; (stats = *statsp) != 0;
<              statsp = &stats->next) {
<             if (stats == &pool->stats) {
<                 *statsp = stats->next;
<                 return;
<             }
<         }
---
> 	if (pool->stats.name)
> 	    xfree(pool->stats.name);
> 	for (statsp = &arena_stats_list; (stats = *statsp) != 0;
> 	     statsp = &stats->next) {
> 	    if (stats == &pool->stats) {
> 		*statsp = stats->next;
> 		return;
> 	    }
> 	}
439a458,467
>     JSArena *a, *next;
> 
>     JS_ACQUIRE_LOCK(arena_freelist_lock);
>     a = arena_freelist;
>     arena_freelist = NULL;
>     JS_RELEASE_LOCK(arena_freelist_lock);
>     for (; a; a = next) {
>         next = a->next;
>         xfree(a);
>     }
444a473,479
> #ifdef JS_THREADSAFE
>     /* Must come through here once in the process's last thread! */
>     if (arena_freelist_lock) {
>         JS_DESTROY_LOCK(arena_freelist_lock);
>         arena_freelist_lock = NULL;
>     }
> #endif
487a523
> #include <math.h>
494c530,531
<     double mean, sigma;
---
>     uint32 nallocs, nbytes;
>     double mean, variance, sigma;
497,498c534,546
<         mean = JS_MeanAndStdDev(stats->nallocs, stats->nbytes, stats->variance,
<                                 &sigma);
---
>         nallocs = stats->nallocs;
>         if (nallocs != 0) {
>             nbytes = stats->nbytes;
>             mean = (double)nbytes / nallocs;
>             variance = stats->variance * nallocs - nbytes * nbytes;
>             if (variance < 0 || nallocs == 1)
>                 variance = 0;
>             else
>                 variance /= nallocs * (nallocs - 1);
>             sigma = sqrt(variance);
> 	} else {
> 	    mean = variance = sigma = 0;
> 	}
502a551
>         fprintf(fp, " number of free arena reclaims: %u\n", stats->nreclaims);
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsarena.h /Volumes/Swap/js_D11/src/jsarena.h
3,4c3,6
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
6,14c8,11
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,24c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
26,36c21
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
---
>  * Contributor(s): 
38c23,33
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
49c44
< #include <stdlib.h>
---
> #include "xstdlib.h"
72a68
>     uint32      nreclaims;      /* number of reclaims from freeArenas */
91,92d86
<     size_t      *quotap;        /* pointer to the quota on pool allocation
<                                    size or null if pool is unlimited */
98,105d91
< #ifdef JS_ARENAMETER
< #define JS_INIT_NAMED_ARENA_POOL(pool, name, size, align, quotap)             \
<     JS_InitArenaPool(pool, name, size, align, quotap)
< #else
< #define JS_INIT_NAMED_ARENA_POOL(pool, name, size, align, quotap)             \
<     JS_InitArenaPool(pool, size, align, quotap)
< #endif
< 
113,117c99
<                                  & ~(jsuword)JS_ARENA_CONST_ALIGN_MASK)
< 
< #define JS_INIT_ARENA_POOL(pool, name, size, quotap)                          \
<     JS_INIT_NAMED_ARENA_POOL(pool, name, size, JS_ARENA_CONST_ALIGN_MASK + 1, \
<                              quotap)
---
> 				 & ~(jsuword)JS_ARENA_CONST_ALIGN_MASK)
118a101,102
> #define JS_INIT_ARENA_POOL(pool, name, size) \
> 	JS_InitArenaPool(pool, name, size, JS_ARENA_CONST_ALIGN_MASK + 1)
121,124d104
< 
< #define JS_INIT_ARENA_POOL(pool, name, size, align, quotap)                   \
<     JS_INIT_NAMED_ARENA_POOL(pool, name, size, align, quotap)
< 
131c111
<     JS_ARENA_ALLOCATE_COMMON(p, type *, pool, sizeof(type), 0)
---
>     JS_ARENA_ALLOCATE_CAST(p, type *, pool, sizeof(type))
134,146d113
<     JS_ARENA_ALLOCATE_COMMON(p, type, pool, nb, _nb > _a->limit)
< 
< /*
<  * NB: In JS_ARENA_ALLOCATE_CAST and JS_ARENA_GROW_CAST, always subtract _nb
<  * from a->limit rather than adding _nb to _p, to avoid overflowing a 32-bit
<  * address space (possible when running a 32-bit program on a 64-bit system
<  * where the kernel maps the heap up against the top of the 32-bit address
<  * space).
<  *
<  * Thanks to Juergen Kreileder <jk@blackdown.de>, who brought this up in
<  * https://bugzilla.mozilla.org/show_bug.cgi?id=279273.
<  */
< #define JS_ARENA_ALLOCATE_COMMON(p, type, pool, nb, guard)                    \
148,156c115,124
<         JSArena *_a = (pool)->current;                                        \
<         size_t _nb = JS_ARENA_ALIGN(pool, nb);                                \
<         jsuword _p = _a->avail;                                               \
<         if ((guard) || _p > _a->limit - _nb)                                  \
<             _p = (jsuword)JS_ArenaAllocate(pool, _nb);                        \
<         else                                                                  \
<             _a->avail = _p + _nb;                                             \
<         p = (type) _p;                                                        \
<         JS_ArenaCountAllocation(pool, nb);                                    \
---
> 	JSArena *_a = (pool)->current;                                        \
> 	size_t _nb = JS_ARENA_ALIGN(pool, nb);                                \
> 	jsuword _p = _a->avail;                                               \
> 	jsuword _q = _p + _nb;                                                \
> 	if (_q > _a->limit)                                                   \
> 	    _p = (jsuword)JS_ArenaAllocate(pool, _nb);                        \
> 	else                                                                  \
> 	    _a->avail = _q;                                                   \
> 	p = (type) _p;                                                        \
> 	JS_ArenaCountAllocation(pool, nb);                                    \
167,169c135,137
<             _nb = JS_ARENA_ALIGN(pool, _nb);                                  \
<             if (_a->limit >= _nb && (jsuword)(p) <= _a->limit - _nb) {        \
<                 _a->avail = (jsuword)(p) + _nb;                               \
---
>             jsuword _q = (jsuword)(p) + JS_ARENA_ALIGN(pool, _nb);            \
>             if (_q <= _a->limit) {                                            \
>                 _a->avail = _q;                                               \
185,190d152
< /*
<  * Check if the mark is inside arena's allocated area.
<  */
< #define JS_ARENA_MARK_MATCH(a, mark)                                          \
<     (JS_UPTRDIFF(mark, (a)->base) <= JS_UPTRDIFF((a)->avail, (a)->base))
< 
207c169,170
<         if (_a != &(pool)->first && JS_ARENA_MARK_MATCH(_a, _m)) {            \
---
>         if (_a != &(pool)->first &&                                           \
>             JS_UPTRDIFF(_m, _a->base) <= JS_UPTRDIFF(_a->avail, _a->base)) {  \
230c193
<         free(a);                                                              \
---
>         xfree(a);                                                              \
235,237c198,199
<  * Initialize an arena pool with a minimum size per arena of size bytes.
<  * Always call JS_SET_ARENA_METER_NAME before calling this or use
<  * JS_INIT_ARENA_POOL macro to provide a name for for debugging and metering.
---
>  * Initialize an arena pool with the given name for debugging and metering,
>  * with a minimum size per arena of size bytes.
240,241c202,203
< JS_INIT_NAMED_ARENA_POOL(JSArenaPool *pool, const char *name, size_t size,
<                          size_t align, size_t *quotap);
---
> JS_InitArenaPool(JSArenaPool *pool, const char *name, size_t size,
>                  size_t align);
258c220,221
<  * Deprecated do-nothing function.
---
>  * Finish using arenas, freeing all memory associated with them except for
>  * any locks needed for thread safety.
264c227,235
<  * Deprecated do-nothing function.
---
>  * Free any locks or other memory needed for thread safety, just before
>  * shutting down.  At that point, we must be called by a single thread.
>  *
>  * After shutting down, the next thread to call JS_InitArenaPool must not
>  * race with any other thread.  Once a pool has been initialized, threads
>  * may safely call jsarena.c functions on thread-local pools.  The upshot
>  * is that pools are per-thread, but the underlying global freelist is
>  * thread-safe, provided that both the first pool initialization and the
>  * shut-down call are single-threaded.
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsarray.c /Volumes/Swap/js_D11/src/jsarray.c
2d1
<  * vim: set sw=4 ts=8 et tw=78:
4,5c3,6
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
7,15c8,11
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
20,23c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
27,39c23,33
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
45c39
< #include <stdlib.h>
---
> #include "xstdlib.h"
52d45
< #include "jsbool.h"
55d47
< #include "jsdtoa.h"
62a55,58
> #include "jsapi.h"
> 
> 
> #include "_optimize.h"
69c65
<  * Determine if the id represents an array index or an XML property index.
---
>  * Determine if the id represents an array index.
84,85c80,81
< JSBool
< js_IdIsIndex(jsval id, jsuint *indexp)
---
> static JSBool
> IdIsIndex(jsid id, jsuint *indexp)
91,96c87,92
<         jsint i;
<         i = JSVAL_TO_INT(id);
<         if (i < 0)
<             return JS_FALSE;
<         *indexp = (jsuint)i;
<         return JS_TRUE;
---
> 	jsint i;
> 	i = JSVAL_TO_INT(id);
> 	if (i < 0)
> 	    return JS_FALSE;
> 	*indexp = (jsuint)i;
> 	return JS_TRUE;
99,102c95
<     /* NB: id should be a string, but jsxml.c may call us with an object id. */
<     if (!JSVAL_IS_STRING(id))
<         return JS_FALSE;
< 
---
>     /* It must be a string. */
106,125c99,119
<         jsuint index = JS7_UNDEC(*cp++);
<         jsuint oldIndex = 0;
<         jsuint c = 0;
<         if (index != 0) {
<             while (JS7_ISDEC(*cp)) {
<                 oldIndex = index;
<                 c = JS7_UNDEC(*cp);
<                 index = 10*index + c;
<                 cp++;
<             }
<         }
< 
<         /* Ensure that all characters were consumed and we didn't overflow. */
<         if (*cp == 0 &&
<              (oldIndex < (MAXINDEX / 10) ||
<               (oldIndex == (MAXINDEX / 10) && c < (MAXINDEX % 10))))
<         {
<             *indexp = index;
<             return JS_TRUE;
<         }
---
> 	jsuint index = JS7_UNDEC(*cp++);
> 	jsuint oldIndex = 0;
> 	jsuint c = 0;
> 	if (index != 0) {
> 	    while (JS7_ISDEC(*cp)) {
> 		oldIndex = index;
> 		c = JS7_UNDEC(*cp);
> 		index = 10*index + c;
> 		cp++;
> 	    }
> 	}
> 	/* Make sure all characters were consumed and that it couldn't
> 	 * have overflowed.
> 	 */
> 	if (*cp == 0 &&
> 	     (oldIndex < (MAXINDEX / 10) ||
> 	      (oldIndex == (MAXINDEX / 10) && c < (MAXINDEX % 10))))
> 	{
> 	    *indexp = index;
> 	    return JS_TRUE;
> 	}
146c140
< 
---
>     
152,154c146,150
< 
<     *lengthp = js_DoubleToECMAUint32(d);
< 
---
>     if (!js_DoubleToECMAUint32(cx, d, (uint32 *)lengthp)) {
>         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
>                              JSMSG_BAD_ARRAY_LENGTH);
>         return JS_FALSE;
>     }
166d161
<     JSTempValueRooter tvr;
168d162
<     JSBool ok;
169a164
>     jsval v;
171,216c166,168
<     JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_NULL, &tvr);
<     id = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
<     ok = OBJ_GET_PROPERTY(cx, obj, id, &tvr.u.value);
<     if (ok) {
<         /*
<          * Short-circuit, because js_ValueToECMAUint32 fails when called
<          * during init time.
<          */
<         if (JSVAL_IS_INT(tvr.u.value)) {
<             i = JSVAL_TO_INT(tvr.u.value);
<             *lengthp = (jsuint)i;       /* jsuint cast does ToUint32 */
<         } else {
<             ok = js_ValueToECMAUint32(cx, tvr.u.value, (uint32 *)lengthp);
<         }
<     }
<     JS_POP_TEMP_ROOT(cx, &tvr);
<     return ok;
< }
< 
< static JSBool
< IndexToValue(JSContext *cx, jsuint index, jsval *vp)
< {
<     if (index <= JSVAL_INT_MAX) {
<         *vp = INT_TO_JSVAL(index);
<         return JS_TRUE;
<     }
<     return js_NewDoubleValue(cx, (jsdouble)index, vp);
< }
< 
< static JSBool
< BigIndexToId(JSContext *cx, JSObject *obj, jsuint index, JSBool createAtom,
<              jsid *idp)
< {
<     jschar buf[10], *start;
<     JSClass *clasp;
<     JSAtom *atom;
<     JS_STATIC_ASSERT((jsuint)-1 == 4294967295U);
< 
<     JS_ASSERT(index > JSVAL_INT_MAX);
< 
<     start = JS_ARRAY_END(buf);
<     do {
<         --start;
<         *start = (jschar)('0' + index % 10);
<         index /= 10;
<     } while (index != 0);
---
>     id = (jsid) cx->runtime->atomState.lengthAtom;
>     if (!OBJ_GET_PROPERTY(cx, obj, id, &v))
> 	return JS_FALSE;
218,222c170,171
<     /*
<      * Skip the atomization if the class is known to store atoms corresponding
<      * to big indexes together with elements. In such case we know that the
<      * array does not have an element at the given index if its atom does not
<      * exist.
---
>     /* Short-circuit, because js_ValueToECMAUint32 fails when
>      * called during init time.
224,278c173,177
<     if (!createAtom &&
<         ((clasp = OBJ_GET_CLASS(cx, obj)) == &js_ArrayClass ||
<          clasp == &js_ArgumentsClass ||
<          clasp == &js_ObjectClass)) {
<         atom = js_GetExistingStringAtom(cx, start, JS_ARRAY_END(buf) - start);
<         if (!atom) {
<             *idp = JSVAL_VOID;
<             return JS_TRUE;
<         }
<     } else {
<         atom = js_AtomizeChars(cx, start, JS_ARRAY_END(buf) - start, 0);
<         if (!atom)
<             return JS_FALSE;
<     }
< 
<     *idp = ATOM_TO_JSID(atom);
<     return JS_TRUE;
< }
< 
< /*
<  * If the property at the given index exists, get its value into location
<  * pointed by vp and set *hole to false. Otherwise set *hole to true and *vp
<  * to JSVAL_VOID. This function assumes that the location pointed by vp is
<  * properly rooted and can be used as GC-protected storage for temporaries.
<  */
< static JSBool
< GetArrayElement(JSContext *cx, JSObject *obj, jsuint index, JSBool *hole,
<                 jsval *vp)
< {
<     jsid id;
<     JSObject *obj2;
<     JSProperty *prop;
< 
<     if (index <= JSVAL_INT_MAX) {
<         id = INT_TO_JSID(index);
<     } else {
<         if (!BigIndexToId(cx, obj, index, JS_FALSE, &id))
<             return JS_FALSE;
<         if (id == JSVAL_VOID) {
<             *hole = JS_TRUE;
<             *vp = JSVAL_VOID;
<             return JS_TRUE;
<         }
<     }
< 
<     if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop))
<         return JS_FALSE;
<     if (!prop) {
<         *hole = JS_TRUE;
<         *vp = JSVAL_VOID;
<     } else {
<         OBJ_DROP_PROPERTY(cx, obj2, prop);
<         if (!OBJ_GET_PROPERTY(cx, obj, id, vp))
<             return JS_FALSE;
<         *hole = JS_FALSE;
---
>     if (JSVAL_IS_INT(v)) {
> 	i = JSVAL_TO_INT(v);
> 	/* jsuint cast does ToUint32. */
> 	*lengthp = (jsuint)i;
> 	return JS_TRUE;
280c179
<     return JS_TRUE;
---
>     return js_ValueToECMAUint32(cx, v, (uint32 *)lengthp);
283,285d181
< /*
<  * Set the value of the property at the given index to v assuming v is rooted.
<  */
287c183
< SetArrayElement(JSContext *cx, JSObject *obj, jsuint index, jsval v)
---
> IndexToValue(JSContext *cx, jsuint length, jsval *vp)
289,296c185,187
<     jsid id;
< 
<     if (index <= JSVAL_INT_MAX) {
<         id = INT_TO_JSID(index);
<     } else {
<         if (!BigIndexToId(cx, obj, index, JS_TRUE, &id))
<             return JS_FALSE;
<         JS_ASSERT(id != JSVAL_VOID);
---
>     if (length <= JSVAL_INT_MAX) {
> 	*vp = INT_TO_JSVAL(length);
> 	return JS_TRUE;
298c189
<     return OBJ_SET_PROPERTY(cx, obj, id, &v);
---
>     return js_NewDoubleValue(cx, (jsdouble)length, vp);
302c193
< DeleteArrayElement(JSContext *cx, JSObject *obj, jsuint index)
---
> IndexToId(JSContext *cx, jsuint length, jsid *idp)
304,305c195,196
<     jsid id;
<     jsval junk;
---
>     JSString *str;
>     JSAtom *atom;
307,308c198,199
<     if (index <= JSVAL_INT_MAX) {
<         id = INT_TO_JSID(index);
---
>     if (length <= JSVAL_INT_MAX) {
> 	*idp = (jsid) INT_TO_JSVAL(length);
310,316c201,207
<         if (!BigIndexToId(cx, obj, index, JS_FALSE, &id))
<             return JS_FALSE;
<         if (id == JSVAL_VOID)
<             return JS_TRUE;
<     }
<     return OBJ_DELETE_PROPERTY(cx, obj, id, &junk);
< }
---
> 	str = js_NumberToString(cx, (jsdouble)length);
> 	if (!str)
> 	    return JS_FALSE;
> 	atom = js_AtomizeString(cx, str, 0);
> 	if (!atom)
> 	    return JS_FALSE;
> 	*idp = (jsid)atom;
318,330d208
< /*
<  * 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, jsuint index,
<                         JSBool hole, jsval v)
< {
<     if (hole) {
<         JS_ASSERT(v == JSVAL_VOID);
<         return DeleteArrayElement(cx, obj, index);
<     } else {
<         return SetArrayElement(cx, obj, index, v);
331a210
>     return JS_TRUE;
341,342c220,221
<         return JS_FALSE;
<     id = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
---
> 	return JS_FALSE;
>     id = (jsid) cx->runtime->atomState.lengthAtom;
350d228
<     JSTempValueRooter tvr;
352a231
>     jsval v;
355,357c234,235
<     JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_NULL, &tvr);
<     id = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
<     ok = OBJ_GET_PROPERTY(cx, obj, id, &tvr.u.value);
---
>     id = (jsid) cx->runtime->atomState.lengthAtom;
>     ok = OBJ_GET_PROPERTY(cx, obj, id, &v);
359,376c237,239
<     if (ok)
<         ok = ValueIsLength(cx, tvr.u.value, lengthp);
<     JS_POP_TEMP_ROOT(cx, &tvr);
<     return ok;
< }
< 
< JSBool
< js_IsArrayLike(JSContext *cx, JSObject *obj, JSBool *answerp, jsuint *lengthp)
< {
<     JSClass *clasp;
< 
<     clasp = OBJ_GET_CLASS(cx, obj);
<     *answerp = (clasp == &js_ArgumentsClass || clasp == &js_ArrayClass);
<     if (!*answerp) {
<         *lengthp = 0;
<         return JS_TRUE;
<     }
<     return js_GetLengthProperty(cx, obj, lengthp);
---
>     if (!ok)
> 	return JS_FALSE;
>     return ValueIsLength(cx, v, lengthp);
380,389c243,245
<  * The 'length' property of all native Array instances is a shared permanent
<  * property of Array.prototype, so it appears to be a direct property of each
<  * array instance delegating to that Array.prototype. It accesses the private
<  * slot reserved by js_ArrayClass.
<  *
<  * Since SpiderMonkey supports cross-class prototype-based delegation, we have
<  * to be careful about the length getter and setter being called on an object
<  * not of Array class. For the getter, we search obj's prototype chain for the
<  * array that caused this getter to be invoked. In the setter case to overcome
<  * the JSPROP_SHARED attribute, we must define a shadowing length property.
---
>  * This get function is specific to Array.prototype.length and other array
>  * instance length properties.  It calls back through the class get function
>  * in case some magic happens there (see call_getProperty in jsfun.c).
394,400c250
<     do {
<         if (OBJ_GET_CLASS(cx, obj) == &js_ArrayClass) {
<             *vp = STOBJ_GET_SLOT(obj, JSSLOT_ARRAY_LENGTH);
<             break;
<         }
<     } while ((obj = OBJ_GET_PROTO(cx, obj)) != NULL);
<     return JS_TRUE;
---
>     return OBJ_GET_CLASS(cx, obj)->getProperty(cx, obj, id, vp);
406c256,257
<     jsuint newlen, oldlen, gap, index;
---
>     jsuint newlen, oldlen, slot;
>     jsid id2;
408,417d258
<     JSObject *iter;
<     JSTempValueRooter tvr;
<     JSBool ok;
< 
<     if (OBJ_GET_CLASS(cx, obj) != &js_ArrayClass) {
<         jsid lengthId = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
< 
<         return OBJ_DEFINE_PROPERTY(cx, obj, lengthId, *vp, NULL, NULL,
<                                    JSPROP_ENUMERATE, NULL);
<     }
420c261
<         return JS_FALSE;
---
> 	return JS_FALSE;
422,463c263,268
<         return JS_FALSE;
<     if (oldlen > newlen) {
<         if (oldlen - newlen < (1 << 24)) {
<             do {
<                 --oldlen;
<                 if (!JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) ||
<                     !DeleteArrayElement(cx, obj, oldlen)) {
<                     return JS_FALSE;
<                 }
<             } while (oldlen != 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 bug 322135.
<              */
<             iter = JS_NewPropertyIterator(cx, obj);
<             if (!iter)
<                 return JS_FALSE;
< 
<             /* Protect iter against GC in OBJ_DELETE_PROPERTY. */
<             JS_PUSH_TEMP_ROOT_OBJECT(cx, iter, &tvr);
<             gap = oldlen - newlen;
<             for (;;) {
<                 ok = (JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) &&
<                       JS_NextProperty(cx, iter, &id));
<                 if (!ok)
<                     break;
<                 if (id == JSVAL_VOID)
<                     break;
<                 if (js_IdIsIndex(id, &index) && index - newlen < gap) {
<                     ok = OBJ_DELETE_PROPERTY(cx, obj, id, &junk);
<                     if (!ok)
<                         break;
<                 }
<             }
<             JS_POP_TEMP_ROOT(cx, &tvr);
<             if (!ok)
<                 return JS_FALSE;
<         }
---
> 	return JS_FALSE;
>     for (slot = newlen; slot < oldlen; slot++) {
> 	if (!IndexToId(cx, slot, &id2))
> 	    return JS_FALSE;
> 	if (!OBJ_DELETE_PROPERTY(cx, obj, id2, &junk))
> 	    return JS_FALSE;
465,468c270
<     if (!IndexToValue(cx, newlen, vp))
<         return JS_FALSE;
<     STOBJ_SET_SLOT(obj, JSSLOT_ARRAY_LENGTH, *vp);
<     return JS_TRUE;
---
>     return IndexToValue(cx, newlen, vp);
476,477c278,279
<     if (!js_IdIsIndex(id, &index))
<         return JS_TRUE;
---
>     if (!(IdIsIndex(id, &index)))
> 	return JS_TRUE;
479c281
<         return JS_FALSE;
---
> 	return JS_FALSE;
481,482c283,284
<         length = index + 1;
<         return js_SetLengthProperty(cx, obj, length);
---
> 	length = index + 1;
> 	return js_SetLengthProperty(cx, obj, length);
489a292,306
>     jsuint length;
> 
>     if (cx->version == JSVERSION_1_2) {
> 	if (!js_GetLengthProperty(cx, obj, &length))
> 	    return JS_FALSE;
> 	switch (type) {
> 	  case JSTYPE_NUMBER:
> 	    return IndexToValue(cx, length, vp);
> 	  case JSTYPE_BOOLEAN:
> 	    *vp = BOOLEAN_TO_JSVAL(length > 0);
> 	    return JS_TRUE;
> 	  default:
> 	    return JS_TRUE;
> 	}
>     }
495c312
<     JSCLASS_HAS_PRIVATE | JSCLASS_HAS_CACHED_PROTO(JSProto_Array),
---
>     0,
501,511d317
< enum ArrayToStringOp {
<     TO_STRING,
<     TO_LOCALE_STRING,
<     TO_SOURCE
< };
< 
< /*
<  * When op is TO_STRING or TO_LOCALE_STRING sep indicates a separator to use
<  * or "," when sep is NULL.
<  * When op is TO_SOURCE sep must be NULL.
<  */
513,514c319,320
< array_join_sub(JSContext *cx, JSObject *obj, enum ArrayToStringOp op,
<                JSString *sep, jsval *rval)
---
> array_join_sub(JSContext *cx, JSObject *obj, JSString *sep, JSBool literalize,
> 	       jsval *rval, JSBool localeString)
516c322,323
<     JSBool ok, hole;
---
>     JSBool ok;
>     jsval v;
519c326
<     size_t nchars, growth, seplen, tmplen, extratail;
---
>     size_t nchars, growth, seplen, tmplen;
523,525c330
<     JSAtom *atom;
< 
<     JS_CHECK_RECURSION(cx, return JS_FALSE);
---
>     JSObject *obj2;
529c334,335
<         return JS_FALSE;
---
> 	return JS_FALSE;
>     ok = JS_TRUE;
534,539c340,341
< #ifdef DEBUG
<     growth = (size_t) -1;
< #endif
< 
<     if (op == TO_SOURCE) {
<         if (IS_SHARP(he)) {
---
>     if (literalize) {
> 	if (IS_SHARP(he)) {
541c343
<             nchars = js_strlen(chars);
---
> 	    nchars = js_strlen(chars);
543,546c345,348
<             chars[0] = '[';
<             chars[1] = ']';
<             chars[2] = 0;
<             nchars = 2;
---
> 	    chars[0] = '[';
> 	    chars[1] = ']';
> 	    chars[2] = 0;
> 	    nchars = 2;
548,549c350,351
<             goto make_string;
<         }
---
> 	    goto make_string;
> 	}
551,575c353,375
<         /*
<          * Always allocate 2 extra chars for closing ']' and terminating 0
<          * and then preallocate 1 + extratail to include starting '['.
<          */
<         extratail = 2;
<         growth = (1 + extratail) * sizeof(jschar);
<         if (!chars) {
<             nchars = 0;
<             chars = (jschar *) malloc(growth);
<             if (!chars)
<                 goto done;
<         } else {
<             MAKE_SHARP(he);
<             nchars = js_strlen(chars);
<             growth += nchars * sizeof(jschar);
<             chars = (jschar *)realloc((ochars = chars), growth);
<             if (!chars) {
<                 free(ochars);
<                 goto done;
<             }
<         }
<         chars[nchars++] = '[';
<         JS_ASSERT(sep == NULL);
<         sepstr = NULL;  /* indicates to use ", " as separator */
<         seplen = 2;
---
> 	/*
> 	 * Allocate 1 + 3 + 1 for "[", the worst-case closing ", ]", and the
> 	 * terminating 0.
> 	 */
> 	growth = (1 + 3 + 1) * sizeof(jschar);
> 	if (!chars) {
> 	    nchars = 0;
> 	    XMEMTAG("array_join_sub xmalloc");
> 	    chars = (jschar *) xmalloc(growth);
> 	    if (!chars)
> 		goto done;
> 	} else {
> 	    MAKE_SHARP(he);
> 	    nchars = js_strlen(chars);
> 	    XMEMTAG("array_join_sub xrealloc");
> 	    chars = (jschar *)
>                 xrealloc((ochars = chars), nchars * sizeof(jschar) + growth);
> 	    if (!chars) {
> 		xfree(ochars);
> 		goto done;
> 	    }
> 	}
> 	chars[nchars++] = '[';
581c381
<          * case of (op != TO_SOURCE), we don't need chars at all.
---
>          * case of (!literalize), we don't need chars at all.
587d386
<         extratail = 1;  /* allocate extra char for terminating 0 */
592,594c391,393
<             *rval = JS_GetEmptyStringValue(cx);
<             return ok;
<         }
---
> 	    *rval = JS_GetEmptyStringValue(cx);
> 	    return ok;
> 	}
598,604d396
< 
<         if (sep) {
<             JSSTRING_CHARS_AND_LENGTH(sep, sepstr, seplen);
<         } else {
<             sepstr = NULL;      /* indicates to use "," as separator */
<             seplen = 1;
<         }
605a398,399
>     sepstr = NULL;
>     seplen = JSSTRING_LENGTH(sep);
607c401
<     /* Use rval to locally root each element value as we loop and convert. */
---
>     v = JSVAL_NULL;
609,619c403,405
<         ok = (JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) &&
<               GetArrayElement(cx, obj, index, &hole, rval));
<         if (!ok)
<             goto done;
<         if (hole ||
<             (op != TO_SOURCE &&
<              (JSVAL_IS_VOID(*rval) || JSVAL_IS_NULL(*rval)))) {
<             str = cx->runtime->emptyString;
<         } else {
<             if (op == TO_LOCALE_STRING) {
<                 JSObject *robj;
---
> 	ok = JS_GetElement(cx, obj, index, &v);
> 	if (!ok)
> 	    goto done;
621,626c407,417
<                 atom = cx->runtime->atomState.toLocaleStringAtom;
<                 ok = js_ValueToObject(cx, *rval, &robj);
<                 if (ok) {
<                     /* Re-use *rval to protect robj temporarily. */
<                     *rval = OBJECT_TO_JSVAL(robj);
<                     ok = js_TryMethod(cx, robj, atom, 0, NULL, rval);
---
> 	if (JSVAL_IS_VOID(v) || JSVAL_IS_NULL(v)) {
> 	    str = cx->runtime->emptyString;
>         } else {
>             if (localeString) {
>                 if (!js_ValueToObject(cx, v, &obj2) ||
>                     !js_TryMethod(cx, obj2,
>                                   cx->runtime->atomState.toLocaleStringAtom,
>                                   0, NULL, &v)) {
>                     str = NULL;
>                 } else {
>                     str = js_ValueToString(cx, v);
628,632d418
<                 if (!ok)
<                     goto done;
<                 str = js_ValueToString(cx, *rval);
<             } else if (op == TO_STRING) {
<                 str = js_ValueToString(cx, *rval);
634,635c420
<                 JS_ASSERT(op == TO_SOURCE);
<                 str = js_ValueToSource(cx, *rval);
---
>                 str = (literalize ? js_ValueToSource : js_ValueToString)(cx, v);
637,641c422,450
<             if (!str) {
<                 ok = JS_FALSE;
<                 goto done;
<             }
<         }
---
> 	    if (!str) {
> 		ok = JS_FALSE;
> 		goto done;
> 	    }
> 	}
> 
> 	/* Allocate 3 + 1 at end for ", ", closing bracket, and zero. */
> 	growth = (nchars + (sepstr ? seplen : 0) +
> 		  JSSTRING_LENGTH(str) +
> 		  3 + 1) * sizeof(jschar);
> 	if (!chars) {
> 		XMEMTAG("array_join_sub xmalloc 2");
> 	    chars = (jschar *) xmalloc(growth);
> 	    if (!chars)
> 		goto done;
> 	} else {
> 		XMEMTAG("array_join_sub xrealloc 2");
> 	    chars = (jschar *) xrealloc((ochars = chars), growth);
> 	    if (!chars) {
> 		xfree(ochars);
> 		goto done;
> 	    }
> 	}
> 
> 	if (sepstr) {
> 	    js_strncpy(&chars[nchars], sepstr, seplen);
> 	    nchars += seplen;
> 	}
> 	sepstr = JSSTRING_CHARS(sep);
643,650d451
<         /*
<          * Do not append separator after the last element unless it is a hole
<          * and we are in toSource. In that case we append single ",".
<          */
<         if (index + 1 == length)
<             seplen = (hole && op == TO_SOURCE) ? 1 : 0;
< 
<         /* Allocate 1 at end for closing bracket and zero. */
652,674d452
<         growth = nchars + tmplen + seplen + extratail;
<         if (nchars > growth || tmplen > growth ||
<             growth > (size_t)-1 / sizeof(jschar)) {
<             if (chars) {
<                 free(chars);
<                 chars = NULL;
<             }
<             goto done;
<         }
<         growth *= sizeof(jschar);
<         JS_COUNT_OPERATION(cx, JSOW_ALLOCATION);
<         if (!chars) {
<             chars = (jschar *) malloc(growth);
<             if (!chars)
<                 goto done;
<         } else {
<             chars = (jschar *) realloc((ochars = chars), growth);
<             if (!chars) {
<                 free(ochars);
<                 goto done;
<             }
<         }
< 
677,688d454
< 
<         if (seplen) {
<             if (sepstr) {
<                 js_strncpy(&chars[nchars], sepstr, seplen);
<             } else {
<                 JS_ASSERT(seplen == 1 || seplen == 2);
<                 chars[nchars] = ',';
<                 if (seplen == 2)
<                     chars[nchars + 1] = ' ';
<             }
<             nchars += seplen;
<         }
692,694c458,465
<     if (op == TO_SOURCE) {
<         if (chars)
<             chars[nchars++] = ']';
---
>     if (literalize) {
> 	if (chars) {
> 	    if (JSVAL_IS_VOID(v)) {
> 		chars[nchars++] = ',';
> 		chars[nchars++] = ' ';
> 	    }
> 	    chars[nchars++] = ']';
> 	}
700,702c471,473
<         if (chars)
<             free(chars);
<         return ok;
---
> 	if (chars)
> 	    xfree(chars);
> 	return ok;
707,708c478,479
<         JS_ReportOutOfMemory(cx);
<         return JS_FALSE;
---
> 	JS_ReportOutOfMemory(cx);
> 	return JS_FALSE;
711,712c482
<     JS_ASSERT(growth == (size_t)-1 || (nchars + 1) * sizeof(jschar) == growth);
<     str = js_NewString(cx, chars, nchars);
---
>     str = js_NewString(cx, chars, nchars, 0);
714,715c484,485
<         free(chars);
<         return JS_FALSE;
---
> 	xfree(chars);
> 	return JS_FALSE;
720a491,495
> static jschar   comma_space_ucstr[] = {',', ' ', 0};
> static jschar   comma_ucstr[]       = {',', 0};
> static JSString comma_space         = {2, comma_space_ucstr};
> static JSString comma               = {1, comma_ucstr};
> 
723c498,499
< array_toSource(JSContext *cx, uintN argc, jsval *vp)
---
> array_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
> 	       jsval *rval)
725,730c501
<     JSObject *obj;
< 
<     obj = JSVAL_TO_OBJECT(vp[1]);
<     if (!JS_InstanceOf(cx, obj, &js_ArrayClass, vp + 2))
<         return JS_FALSE;
<     return array_join_sub(cx, obj, TO_SOURCE, NULL, vp);
---
>     return array_join_sub(cx, obj, &comma_space, JS_TRUE, rval, JS_FALSE);
735c506,507
< array_toString(JSContext *cx, uintN argc, jsval *vp)
---
> array_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
> 	       jsval *rval)
737c509
<     JSObject *obj;
---
>     JSBool literalize;
739,742c511,517
<     obj = JSVAL_TO_OBJECT(vp[1]);
<     if (!JS_InstanceOf(cx, obj, &js_ArrayClass, vp + 2))
<         return JS_FALSE;
<     return array_join_sub(cx, obj, TO_STRING, NULL, vp);
---
>     /*
>      * JS1.2 arrays convert to array literals, with a comma followed by a space
>      * between each element.
>      */
>     literalize = (cx->version == JSVERSION_1_2);
>     return array_join_sub(cx, obj, literalize ? &comma_space : &comma,
> 			  literalize, rval, JS_FALSE);
746c521,522
< array_toLocaleString(JSContext *cx, uintN argc, jsval *vp)
---
> array_toLocaleString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
> 	       jsval *rval)
748,753d523
<     JSObject *obj;
< 
<     obj = JSVAL_TO_OBJECT(vp[1]);
<     if (!JS_InstanceOf(cx, obj, &js_ArrayClass, vp + 2))
<         return JS_FALSE;
< 
758c528
<     return array_join_sub(cx, obj, TO_LOCALE_STRING, NULL, vp);
---
>     return array_join_sub(cx, obj, &comma, JS_FALSE, rval, JS_TRUE);
762,763c532
< InitArrayElements(JSContext *cx, JSObject *obj, jsuint start, jsuint end,
<                   jsval *vector)
---
> array_join(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
765,771c534,542
<     while (start != end) {
<         if (!JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) ||
<             !SetArrayElement(cx, obj, start++, *vector++)) {
<             return JS_FALSE;
<         }
<     }
<     return JS_TRUE;
---
>     JSString *str;
> 
>     if (JSVAL_IS_VOID(argv[0]))
> 	return array_join_sub(cx, obj, &comma, JS_FALSE, rval, JS_FALSE);
>     str = js_ValueToString(cx, argv[0]);
>     if (!str)
> 	return JS_FALSE;
>     argv[0] = STRING_TO_JSVAL(str);
>     return array_join_sub(cx, obj, str, JS_FALSE, rval, JS_FALSE);
773a545
> #if !JS_HAS_MORE_PERL_FUN
775c547
< InitArrayObject(JSContext *cx, JSObject *obj, jsuint length, jsval *vector)
---
> array_nyi(JSContext *cx, const char *what)
777,783c549,550
<     jsval v;
< 
<     JS_ASSERT(OBJ_GET_CLASS(cx, obj) == &js_ArrayClass);
<     if (!IndexToValue(cx, length, &v))
<         return JS_FALSE;
<     STOBJ_SET_SLOT(obj, JSSLOT_ARRAY_LENGTH, v);
<     return !vector || InitArrayElements(cx, obj, 0, length, vector);
---
>     JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NO_PROTO, what);
>     return JS_FALSE;
784a552
> #endif
786,788d553
< /*
<  * Perl-inspired join, reverse, and sort.
<  */
790c555
< array_join(JSContext *cx, uintN argc, jsval *vp)
---
> InitArrayElements(JSContext *cx, JSObject *obj, jsuint length, jsval *vector)
792c557,558
<     JSString *str;
---
>     jsuint index;
>     jsid id;
794,800c560,564
<     if (JSVAL_IS_VOID(vp[2])) {
<         str = NULL;
<     } else {
<         str = js_ValueToString(cx, vp[2]);
<         if (!str)
<             return JS_FALSE;
<         vp[2] = STRING_TO_JSVAL(str);
---
>     for (index = 0; index < length; index++) {
> 	if (!IndexToId(cx, index, &id))
> 	    return JS_FALSE;
> 	if (!OBJ_SET_PROPERTY(cx, obj, id, &vector[index]))
> 	    return JS_FALSE;
802c566
<     return array_join_sub(cx, JS_THIS_OBJECT(cx, vp), TO_STRING, str, vp);
---
>     return JS_TRUE;
806c570,591
< array_reverse(JSContext *cx, uintN argc, jsval *vp)
---
> InitArrayObject(JSContext *cx, JSObject *obj, jsuint length, jsval *vector)
> {
>     jsval v;
>     jsid id;
> 
>     if (!IndexToValue(cx, length, &v))
> 	return JS_FALSE;
>     id = (jsid) cx->runtime->atomState.lengthAtom;
>     if (!OBJ_DEFINE_PROPERTY(cx, obj, id, v,
>                              array_length_getter, array_length_setter,
>                              JSPROP_PERMANENT,
>                              NULL)) {
> 	  return JS_FALSE;
>     }
>     if (!vector)
> 	return JS_TRUE;
>     return InitArrayElements(cx, obj, length, vector);
> }
> 
> static JSBool
> array_reverse(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
> 	      jsval *rval)
808,809d592
<     JSObject *obj;
<     JSTempValueRooter tvr;
811c594,595
<     JSBool ok, hole, hole2;
---
>     jsid id, id2;
>     jsval v, v2;
813d596
<     obj = JS_THIS_OBJECT(cx, vp);
815c598
<         return JS_FALSE;
---
> 	return JS_FALSE;
817,818d599
<     ok = JS_TRUE;
<     JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_NULL, &tvr);
821,827c602,626
<         ok = JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) &&
<              GetArrayElement(cx, obj, i, &hole, &tvr.u.value) &&
<              GetArrayElement(cx, obj, len - i - 1, &hole2, vp) &&
<              SetOrDeleteArrayElement(cx, obj, len - i - 1, hole, tvr.u.value) &&
<              SetOrDeleteArrayElement(cx, obj, i, hole2, *vp);
<         if (!ok)
<             break;
---
> 	if (!IndexToId(cx, i, &id))
> 	    return JS_FALSE;
> 	if (!IndexToId(cx, len - i - 1, &id2))
> 	    return JS_FALSE;
> 	if (!OBJ_GET_PROPERTY(cx, obj, id, &v))
> 	    return JS_FALSE;
> 	if (!OBJ_GET_PROPERTY(cx, obj, id2, &v2))
> 	    return JS_FALSE;
> 
> #if JS_HAS_SPARSE_ARRAYS
>         /* This part isn't done yet. */
> 
>         if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop))
>             return JS_FALSE;
>         if (!prop) {
>             OBJ_DELETE_PROPERTY(cx, obj, id2, &v); /* v is junk. */
>             continue;
>         }
>         OBJ_DROP_PROPERTY(cx, obj2, prop);
> #endif
> 
> 	if (!OBJ_SET_PROPERTY(cx, obj, id, &v2))
> 	    return JS_FALSE;
> 	if (!OBJ_SET_PROPERTY(cx, obj, id2, &v))
> 	    return JS_FALSE;
829d627
<     JS_POP_TEMP_ROOT(cx, &tvr);
831,832c629,630
<     *vp = OBJECT_TO_JSVAL(obj);
<     return ok;
---
>     *rval = OBJECT_TO_JSVAL(obj);
>     return JS_TRUE;
835c633,634
< typedef struct MSortArgs {
---
> typedef struct HSortArgs {
>     void         *vec;
836a636
>     void         *pivot;
840c640
< } MSortArgs;
---
> } HSortArgs;
842,844c642,649
< /* Helper function for js_MergeSort. */
< static JSBool
< MergeArrays(MSortArgs *msa, void *src, void *dest, size_t run1, size_t run2)
---
> static int
> sort_compare(const void *a, const void *b, void *arg);
> 
> static int
> sort_compare_strings(const void *a, const void *b, void *arg);
> 
> static void
> HeapSortHelper(JSBool building, HSortArgs *hsa, size_t lo, size_t hi)
846,848c651,652
<     void *arg, *a, *b, *c;
<     size_t elsize, runtotal;
<     int cmp_result;
---
>     void *pivot, *vec, *vec2, *arg, *a, *b;
>     size_t elsize;
850a655
>     size_t j, hiDiv2;
852,869c657,662
<     runtotal = run1 + run2;
< 
<     elsize = msa->elsize;
<     cmp = msa->cmp;
<     arg = msa->arg;
<     fastcopy = msa->fastcopy;
< 
< #define CALL_CMP(a, b) \
<     if (!cmp(arg, (a), (b), &cmp_result)) return JS_FALSE;
< 
<     /* Copy runs already in sorted order. */
<     b = (char *)src + run1 * elsize;
<     a = (char *)b - elsize;
<     CALL_CMP(a, b);
<     if (cmp_result <= 0) {
<         memcpy(dest, src, runtotal * elsize);
<         return JS_TRUE;
<     }
---
>     pivot = hsa->pivot;
>     vec = hsa->vec;
>     elsize = hsa->elsize;
>     vec2 =  (char *)vec - 2 * elsize;
>     cmp = hsa->cmp;
>     arg = hsa->arg;
871c664,665
< #define COPY_ONE(p,q,n) \
---
>     fastcopy = hsa->fastcopy;
> #define MEMCPY(p,q,n) \
874,881c668,682
<     a = src;
<     c = dest;
<     for (; runtotal != 0; runtotal--) {
<         JSBool from_a = run2 == 0;
<         if (!from_a && run1 != 0) {
<             CALL_CMP(a,b);
<             from_a = cmp_result <= 0;
<         }
---
>     if (lo == 1) {
>         j = 2;
>         b = (char *)vec + elsize;
>         if (j < hi && cmp(vec, b, arg) < 0)
>             j++;
>         a = (char *)vec + (hi - 1) * elsize;
>         b = (char *)vec2 + j * elsize;
> 
>         /* 
>          * During sorting phase b points to a member of heap that cannot be
>          * bigger then biggest of vec[0] and vec[1], and cmp(a, b, arg) <= 0
>          * always holds.
>          */
>         if ((building || hi == 2) && cmp(a, b, arg) >= 0)
>             return;
883,892c684,689
<         if (from_a) {
<             COPY_ONE(c, a, elsize);
<             run1--;
<             a = (char *)a + elsize;
<         } else {
<             COPY_ONE(c, b, elsize);
<             run2--;
<             b = (char *)b + elsize;
<         }
<         c = (char *)c + elsize;
---
>         MEMCPY(pivot, a, elsize);
>         MEMCPY(a, b, elsize);
>         lo = j;
>     } else {
>         a = (char *)vec2 + lo * elsize;
>         MEMCPY(pivot, a, elsize);
894,895d690
< #undef COPY_ONE
< #undef CALL_CMP
897c692,710
<     return JS_TRUE;
---
>     hiDiv2 = hi/2;
>     while (lo <= hiDiv2) {
>         j = lo + lo;
>         a = (char *)vec2 + j * elsize;
>         b = (char *)vec + (j - 1) * elsize;
>         if (j < hi && cmp(a, b, arg) < 0)
>             j++;
>         b = (char *)vec2 + j * elsize;
>         if (cmp(pivot, b, arg) >= 0)
>             break;
> 
>         a = (char *)vec2 + lo * elsize;
>         MEMCPY(a, b, elsize);
>         lo = j;
>     }
> 
>     a = (char *)vec2 + lo * elsize;
>     MEMCPY(a, pivot, elsize);
> #undef MEMCPY
900,903d712
< /*
<  * This sort is stable, i.e. sequence of equal elements is preserved.
<  * See also bug #224128.
<  */
905,906c714
< js_MergeSort(void *src, size_t nel, size_t elsize,
<              JSComparator cmp, void *arg, void *tmp)
---
> js_HeapSort(void *vec, size_t nel, size_t elsize, JSComparator cmp, void *arg) 
908,912c716,733
<     void *swap, *vec1, *vec2;
<     MSortArgs msa;
<     size_t i, j, lo, hi, run;
<     JSBool fastcopy;
<     int cmp_result;
---
>     void *pivot;
>     HSortArgs hsa;
>     size_t i;
> 
>     pivot = xmalloc(elsize);
>     if (!pivot)
> 	return JS_FALSE;
>     hsa.vec = vec;
>     hsa.elsize = elsize;
>     hsa.pivot = pivot;
>     hsa.cmp = cmp;
>     hsa.arg = arg;
>     hsa.fastcopy = (cmp == sort_compare || cmp == sort_compare_strings);
> 
>     for (i = nel/2; i != 0; i--)
>         HeapSortHelper(JS_TRUE, &hsa, i, nel);
>     while (nel > 2)
>         HeapSortHelper(JS_FALSE, &hsa, 1, --nel);
914,921c735,737
<     /* Avoid memcpy overhead for word-sized and word-aligned elements. */
<     fastcopy = (elsize == sizeof(jsval) &&
<                 (((jsuword) src | (jsuword) tmp) & JSVAL_ALIGN) == 0);
< #define COPY_ONE(p,q,n) \
<     (fastcopy ? (void)(*(jsval*)(p) = *(jsval*)(q)) : (void)memcpy(p, q, n))
< #define CALL_CMP(a, b) \
<     if (!cmp(arg, (a), (b), &cmp_result)) return JS_FALSE;
< #define INS_SORT_INT 4
---
>     xfree(pivot);
>     return JS_TRUE;
> }
923,939c739,743
<     /*
<      * Apply insertion sort to small chunks to reduce the number of merge
<      * passes needed.
<      */
<     for (lo = 0; lo < nel; lo += INS_SORT_INT) {
<         hi = lo + INS_SORT_INT;
<         if (hi >= nel)
<             hi = nel;
<         for (i = lo + 1; i < hi; i++) {
<             vec1 = (char *)src + i * elsize;
<             vec2 = (char *)vec1 - elsize;
<             for (j = i; j > lo; j--) {
<                 CALL_CMP(vec2, vec1);
<                 /* "<=" instead of "<" insures the sort is stable */
<                 if (cmp_result <= 0) {
<                     break;
<                 }
---
> typedef struct CompareArgs {
>     JSContext  *context;
>     jsval      fval;
>     JSBool     status;
> } CompareArgs;
941,991c745,746
<                 /* Swap elements, using "tmp" as tmp storage */
<                 COPY_ONE(tmp, vec2, elsize);
<                 COPY_ONE(vec2, vec1, elsize);
<                 COPY_ONE(vec1, tmp, elsize);
<                 vec1 = vec2;
<                 vec2 = (char *)vec1 - elsize;
<             }
<         }
<     }
< #undef CALL_CMP
< #undef COPY_ONE
< 
<     msa.elsize = elsize;
<     msa.cmp = cmp;
<     msa.arg = arg;
<     msa.fastcopy = fastcopy;
< 
<     vec1 = src;
<     vec2 = tmp;
<     for (run = INS_SORT_INT; run < nel; run *= 2) {
<         for (lo = 0; lo < nel; lo += 2 * run) {
<             hi = lo + run;
<             if (hi >= nel) {
<                 memcpy((char *)vec2 + lo * elsize, (char *)vec1 + lo * elsize,
<                        (nel - lo) * elsize);
<                 break;
<             }
<             if (!MergeArrays(&msa, (char *)vec1 + lo * elsize,
<                              (char *)vec2 + lo * elsize, run,
<                              hi + run > nel ? nel - hi : run)) {
<                 return JS_FALSE;
<             }
<         }
<         swap = vec1;
<         vec1 = vec2;
<         vec2 = swap;
<     }
<     if (src != vec1)
<         memcpy(src, tmp, nel * elsize);
< 
<     return JS_TRUE;
< }
< 
< typedef struct CompareArgs {
<     JSContext   *context;
<     jsval       fval;
<     jsval       *elemroot;      /* stack needed for js_Invoke */
< } CompareArgs;
< 
< static JSBool
< sort_compare(void *arg, const void *a, const void *b, int *result)
---
> static int
> sort_compare(const void *a, const void *b, void *arg)
996,1007c751,753
<     jsval *invokevp, *sp;
<     jsdouble cmp;
< 
<     /**
<      * array_sort deals with holes and undefs on its own and they should not
<      * come here.
<      */
<     JS_ASSERT(av != JSVAL_VOID);
<     JS_ASSERT(bv != JSVAL_VOID);
< 
<     if (!JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP))
<         return JS_FALSE;
---
>     jsdouble cmp = -1;
>     jsval fval, argv[2], rval;
>     JSBool ok;
1009,1014c755,757
<     invokevp = ca->elemroot;
<     sp = invokevp;
<     *sp++ = ca->fval;
<     *sp++ = JSVAL_NULL;
<     *sp++ = av;
<     *sp++ = bv;
---
>     fval = ca->fval;
>     if (fval == JSVAL_NULL) {
> 	JSString *astr, *bstr;
1016,1018c759,791
<     if (!js_Invoke(cx, 2, invokevp, JSINVOKE_INTERNAL) ||
<         !js_ValueToNumber(cx, *invokevp, &cmp)) {
<         return JS_FALSE;
---
> 	if (av == bv) {
> 	    cmp = 0;
> 	} else if (av == JSVAL_VOID || bv == JSVAL_VOID) {
> 	    /* Put undefined properties at the end. */
> 	    cmp = (av == JSVAL_VOID) ? 1 : -1;
> 	} else if ((astr = js_ValueToString(cx, av)) != NULL &&
> 		   (bstr = js_ValueToString(cx, bv)) != NULL) {
> 	    cmp = js_CompareStrings(astr, bstr);
> 	} else {
> 	    ca->status = JS_FALSE;
> 	}
>     } else {
> 	argv[0] = av;
> 	argv[1] = bv;
> 	ok = js_InternalCall(cx,
> 			     OBJ_GET_PARENT(cx, JSVAL_TO_OBJECT(fval)),
> 			     fval, 2, argv, &rval);
> 	if (ok) {
> 	    ok = js_ValueToNumber(cx, rval, &cmp);
> 	    /* Clamp cmp to -1, 0, 1. */
> 	    if (JSDOUBLE_IS_NaN(cmp)) {
> 		/* XXX report some kind of error here?  ECMA talks about
> 		 * 'consistent compare functions' that don't return NaN, but is
> 		 * silent about what the result should be.  So we currently
> 		 * ignore it.
> 		 */
> 		cmp = 0;
> 	    } else if (cmp != 0) {
> 		cmp = cmp > 0 ? 1 : -1;
> 	    }
> 	} else {
> 	    ca->status = ok;
> 	}
1020,1032c793
< 
<     /* Clamp cmp to -1, 0, 1. */
<     *result = 0;
<     if (!JSDOUBLE_IS_NaN(cmp) && cmp != 0)
<         *result = cmp > 0 ? 1 : -1;
< 
<     /*
<      * XXX else report some kind of error here?  ECMA talks about 'consistent
<      * compare functions' that don't return NaN, but is silent about what the
<      * result should be.  So we currently ignore it.
<      */
< 
<     return JS_TRUE;
---
>     return (int)cmp;
1036c797
< sort_compare_strings(void *arg, const void *a, const void *b, int *result)
---
> sort_compare_strings(const void *a, const void *b, void *arg)
1040,1046c801
<     JS_ASSERT(JSVAL_IS_STRING(av));
<     JS_ASSERT(JSVAL_IS_STRING(bv));
<     if (!JS_CHECK_OPERATION_LIMIT((JSContext *)arg, JSOW_JUMP))
<         return JS_FALSE;
< 
<     *result = (int) js_CompareStrings(JSVAL_TO_STRING(av), JSVAL_TO_STRING(bv));
<     return JS_TRUE;
---
>     return (int) js_CompareStrings(JSVAL_TO_STRING(av), JSVAL_TO_STRING(bv));
1049,1052c804,806
< /*
<  * The array_sort function below assumes JSVAL_NULL is zero in order to
<  * perform initialization using memset.  Other parts of SpiderMonkey likewise
<  * "know" that JSVAL_NULL is zero; this static assertion covers all cases.
---
> /* XXXmccabe do the sort helper functions need to take int?  (Or can we claim
>  * that 2^32 * 32 is too large to worry about?)  Something dumps when I change
>  * to unsigned int; is qsort using -1 as a fencepost?
1054,1055d807
< JS_STATIC_ASSERT(JSVAL_NULL == 0);
< 
1057c809
< array_sort(JSContext *cx, uintN argc, jsval *vp)
---
> array_sort(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1059,1060c811
<     jsval *argv, fval, *vec, *mergesort_tmp, v;
<     JSObject *obj;
---
>     jsval fval;
1062,1066c813,816
<     jsuint len, newlen, i, undefs;
<     JSTempValueRooter tvr;
<     JSBool hole, ok;
<     size_t elemsize;
<     JSString *str;
---
>     jsuint len, newlen, i;
>     jsval *vec;
>     jsid id;
>     size_t nbytes;
1074d823
<     argv = JS_ARGV(cx, vp);
1076,1081c825,831
<         if (JSVAL_IS_PRIMITIVE(argv[0])) {
<             JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
<                                  JSMSG_BAD_SORT_ARG);
<             return JS_FALSE;
<         }
<         fval = argv[0];     /* non-default compare function */
---
> 	if (JSVAL_IS_PRIMITIVE(argv[0])) {
> 	    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
> 				 JSMSG_BAD_SORT_ARG);
> 	    return JS_FALSE;
> 	}
> 	fval = argv[0];
>         all_strings = JS_FALSE; /* non-default compare function */
1083c833,834
<         fval = JSVAL_NULL;
---
> 	fval = JSVAL_NULL;
>         all_strings = JS_TRUE;  /* check for all string values */
1086d836
<     obj = JS_THIS_OBJECT(cx, vp);
1088c838
<         return JS_FALSE;
---
> 	return JS_FALSE;
1090c840
<         *vp = OBJECT_TO_JSVAL(obj);
---
>         *rval = OBJECT_TO_JSVAL(obj);
1095,1098c845,846
<      * We need a temporary array of 2 * len jsvals to hold the array elements
<      * and the scratch space for merge sort. Check that its size does not
<      * overflow size_t, which would allow for indexing beyond the end of the
<      * malloc'd vector.
---
>      * Test for size_t overflow, which could lead to indexing beyond the end
>      * of the malloc'd vector.
1100,1101c848,849
< #if JS_BITS_PER_WORD == 32
<     if ((size_t)len > ~(size_t)0 / (2 * sizeof(jsval))) {
---
>     nbytes = len * sizeof(jsval);
>     if (nbytes != (double) len * sizeof(jsval)) {
1105,1106c853,854
< #endif
<     vec = (jsval *) JS_malloc(cx, 2 * (size_t) len * sizeof(jsval));
---
>     XMEMTAG("array_sort");
>     vec = (jsval *) JS_malloc(cx, nbytes);
1108c856
<         return JS_FALSE;
---
> 	return JS_FALSE;
1110,1131c858
<     /*
<      * Initialize vec as a root. We will clear elements of vec one by
<      * one while increasing tvr.count when we know that the property at
<      * the corresponding index exists and its value must be rooted.
<      *
<      * In this way when sorting a huge mostly sparse array we will not
<      * access the tail of vec corresponding to properties that do not
<      * exist, allowing OS to avoiding committing RAM. See bug 330812.
<      *
<      * After this point control must flow through label out: to exit.
<      */
<     JS_PUSH_TEMP_ROOT(cx, 0, vec, &tvr);
< 
<     /*
<      * By ECMA 262, 15.4.4.11, a property that does not exist (which we
<      * call a "hole") is always greater than an existing property with
<      * value undefined and that is always greater than any other property.
<      * Thus to sort holes and undefs we simply count them, sort the rest
<      * of elements, append undefs after them and then make holes after
<      * undefs.
<      */
<     undefs = 0;
---
> #if JS_HAS_SPARSE_ARRAYS
1133,1209c860,861
<     all_strings = JS_TRUE;
<     for (i = 0; i < len; i++) {
<         ok = JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP);
<         if (!ok)
<             goto out;
< 
<         /* Clear vec[newlen] before including it in the rooted set. */
<         vec[newlen] = JSVAL_NULL;
<         tvr.count = newlen + 1;
<         ok = GetArrayElement(cx, obj, i, &hole, &vec[newlen]);
<         if (!ok)
<             goto out;
< 
<         if (hole)
<             continue;
< 
<         if (vec[newlen] == JSVAL_VOID) {
<             ++undefs;
<             continue;
<         }
< 
<         /* We know JSVAL_IS_STRING yields 0 or 1, so avoid a branch via &=. */
<         all_strings &= JSVAL_IS_STRING(vec[newlen]);
< 
<         ++newlen;
<     }
< 
<     if (newlen == 0) {
<         /* The array has only holes and undefs. */
<         ok = JS_TRUE;
<         goto out;
<     }
< 
<     /*
<      * The first newlen elements of vec are copied from the array object
<      * (above). The remaining newlen positions are used as GC-rooted scratch
<      * space for mergesort. We must clear the space before including it to
<      * the root set covered by tvr.count. We assume JSVAL_NULL==0 to optimize
<      * initialization using memset.
<      */
<     mergesort_tmp = vec + newlen;
<     memset(mergesort_tmp, 0, newlen * sizeof(jsval));
<     tvr.count = newlen * 2;
< 
<     /* Here len == 2 * (newlen + undefs + number_of_holes). */
<     if (fval == JSVAL_NULL) {
<         /*
<          * Sort using the default comparator converting all elements to
<          * strings.
<          */
<         if (all_strings) {
<             elemsize = sizeof(jsval);
<         } else {
<             /*
<              * To avoid string conversion on each compare we do it only once
<              * prior to sorting. But we also need the space for the original
<              * values to recover the sorting result. To reuse
<              * sort_compare_strings we move the original values to the odd
<              * indexes in vec, put the string conversion results in the even
<              * indexes and pass 2 * sizeof(jsval) as an element size to the
<              * sorting function. In this way sort_compare_strings will only
<              * see the string values when it casts the compare arguments as
<              * pointers to jsval.
<              *
<              * This requires doubling the temporary storage including the
<              * scratch space for the merge sort. Since vec already contains
<              * the rooted scratch space for newlen elements at the tail, we
<              * can use it to rearrange and convert to strings first and try
<              * realloc only when we know that we successfully converted all
<              * the elements.
<              */
< #if JS_BITS_PER_WORD == 32
<             if ((size_t)newlen > ~(size_t)0 / (4 * sizeof(jsval))) {
<                 JS_ReportOutOfMemory(cx);
<                 ok = JS_FALSE;
<                 goto out;
<             }
---
> #else
>     newlen = len;
1212,1239c864,873
<             /*
<              * Rearrange and string-convert the elements of the vector from
<              * the tail here and, after sorting, move the results back
<              * starting from the start to prevent overwrite the existing
<              * elements.
<              */
<             i = newlen;
<             do {
<                 --i;
<                 ok = JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP);
<                 if (!ok)
<                     goto out;
<                 v = vec[i];
<                 str = js_ValueToString(cx, v);
<                 if (!str) {
<                     ok = JS_FALSE;
<                     goto out;
<                 }
<                 vec[2 * i] = STRING_TO_JSVAL(str);
<                 vec[2 * i + 1] = v;
<             } while (i != 0);
< 
<             JS_ASSERT(tvr.u.array == vec);
<             vec = (jsval *) JS_realloc(cx, vec,
<                                        4 * (size_t) newlen * sizeof(jsval));
<             if (!vec) {
<                 vec = tvr.u.array;
<                 ok = JS_FALSE;
---
>     for (i = 0; i < len; i++) {
> 	ca.status = IndexToId(cx, i, &id);
> 	if (!ca.status)
> 	    goto out;
> #if JS_HAS_SPARSE_ARRAYS
>         {
>             JSObject *obj2;
>             JSProperty *prop;
>             ca.status = OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop);
>             if (!ca.status)
1240a875,877
>             if (!prop) {
>                 vec[i] = JSVAL_VOID;
>                 continue;
1242,1262c879,880
<             tvr.u.array = vec;
<             mergesort_tmp = vec + 2 * newlen;
<             memset(mergesort_tmp, 0, newlen * 2 * sizeof(jsval));
<             tvr.count = newlen * 4;
<             elemsize = 2 * sizeof(jsval);
<         }
<         ok = js_MergeSort(vec, (size_t) newlen, elemsize,
<                           sort_compare_strings, cx, mergesort_tmp);
<         if (!ok)
<             goto out;
<         if (!all_strings) {
<             /*
<              * We want to make the following loop fast and to unroot the
<              * cached results of toString invocations before the operation
<              * callback has a chance to run the GC. For this reason we do
<              * not call JS_CHECK_OPERATION_LIMIT in the loop.
<              */
<             i = 0;
<             do {
<                 vec[i] = vec[2 * i + 1];
<             } while (++i != newlen);
---
>             OBJ_DROP_PROPERTY(cx, obj2, prop);
>             newlen++;
1264,1265c882,885
<     } else {
<         void *mark;
---
> #endif
> 	ca.status = OBJ_GET_PROPERTY(cx, obj, id, &vec[i]);
> 	if (!ca.status)
> 	    goto out;
1267,1278c887,888
<         ca.context = cx;
<         ca.fval = fval;
<         ca.elemroot  = js_AllocStack(cx, 2 + 2, &mark);
<         if (!ca.elemroot) {
<             ok = JS_FALSE;
<             goto out;
<         }
<         ok = js_MergeSort(vec, (size_t) newlen, sizeof(jsval),
<                           sort_compare, &ca, mergesort_tmp);
<         js_FreeStack(cx, mark);
<         if (!ok)
<             goto out;
---
>         /* We know JSVAL_IS_STRING yields 0 or 1, so avoid a branch via &=. */
>         all_strings &= JSVAL_IS_STRING(vec[i]); 
1281,1302c891,917
<     /*
<      * We no longer need to root the scratch space for the merge sort, so
<      * unroot it now to make the job of a potential GC under InitArrayElements
<      * easier.
<      */
<     tvr.count = newlen;
<     ok = InitArrayElements(cx, obj, 0, newlen, vec);
<     if (!ok)
<         goto out;
< 
<   out:
<     JS_POP_TEMP_ROOT(cx, &tvr);
<     JS_free(cx, vec);
<     if (!ok)
<         return JS_FALSE;
< 
<     /* Set undefs that sorted after the rest of elements. */
<     while (undefs != 0) {
<         --undefs;
<         if (!JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) ||
<             !SetArrayElement(cx, obj, newlen++, JSVAL_VOID)) {
<             return JS_FALSE;
---
>     ca.context = cx;
>     ca.fval = fval;
>     ca.status = JS_TRUE;
>     if (!js_HeapSort(vec, (size_t) len, sizeof(jsval),
>                      all_strings ? sort_compare_strings : sort_compare,
>                      &ca)) {
> 	JS_ReportOutOfMemory(cx);
> 	ca.status = JS_FALSE;
>     }
> 
>     if (ca.status) {
> 	ca.status = InitArrayElements(cx, obj, newlen, vec);
> 	if (ca.status)
> 	    *rval = OBJECT_TO_JSVAL(obj);
> #if JS_HAS_SPARSE_ARRAYS
>         /* set length of newly-created array object to old length. */
>         if (ca.status && newlen < len) {
>             ca.status = js_SetLengthProperty(cx, obj, len);
> 
>             /* Delete any leftover properties greater than newlen. */
>             while (ca.status && newlen < len) {
>                 jsval junk;
> 
>                 ca.status = !IndexToId(cx, newlen, &id) ||
>                     !OBJ_DELETE_PROPERTY(cx, obj, id, &junk);
>                 newlen++;
>             }
1303a919
> #endif
1306,1314c922,925
<     /* Re-create any holes that sorted to the end of the array. */
<     while (len > newlen) {
<         if (!JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) ||
<             !DeleteArrayElement(cx, obj, --len)) {
<             return JS_FALSE;
<         }
<     }
<     *vp = OBJECT_TO_JSVAL(obj);
<     return JS_TRUE;
---
> out:
>     if (vec)
> 	JS_free(cx, vec);
>     return ca.status;
1316a928
> #ifdef NOTYET
1318c930,960
<  * Perl-inspired push, pop, shift, unshift, and splice methods.
---
>  * From "Programming perl", Larry Wall and Randall L. Schwartz, Copyright XXX
>  * O'Reilly & Associates, Inc., but with Java primitive type sizes for i, l,
>  * and so on:
>  *
>  *  a   An ASCII string, will be null padded.
>  *  A   An ASCII string, will be space padded.
>  *  b   A bit string, low-to-high order.
>  *  B   A bit string, high-to-low order.
>  *  h   A hexadecimal string, low nybble first.
>  *  H   A hexadecimal string, high nybble first.
>  *  c   A signed char value.
>  *  C   An unsigned char value.
>  *  s   A signed short (16-bit) value.
>  *  S   An unsigned short (16-bit) value.
>  *  i   A signed integer (32-bit) value.
>  *  I   An unsigned integer (32-bit) value.
>  *  l   A signed long (64-bit) value.
>  *  L   An unsigned long (64-bit) value.
>  *  n   A short in "network" byte order.
>  *  N   An integer in "network" byte order.
>  *  f   A single-precision float in IEEE format.
>  *  d   A double-precision float in IEEE format.
>  *  p   A pointer to a string.
>  *  x   A null byte.
>  *  X   Back up one byte.
>  *  @   Null-fill to absolute position.
>  *  u   A uuencoded string.
>  *
>  * Each letter may be followed by a number giving the repeat count.  Together
>  * the letter and repeat count make a field specifier.  Field specifiers may
>  * be separated by whitespace, which will be ignored.
1321c963
< slow_array_push(JSContext *cx, JSObject *obj, uintN argc, jsval *vp)
---
> array_pack(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1323,1334c965,968
<     jsuint length, newlength;
< 
<     if (!js_GetLengthProperty(cx, obj, &length))
<         return JS_FALSE;
<     newlength = length + argc;
<     if (!InitArrayElements(cx, obj, length, newlength, vp + 2))
<         return JS_FALSE;
< 
<     /* Per ECMA-262, return the new array length. */
<     if (!IndexToValue(cx, newlength, vp))
<         return JS_FALSE;
<     return js_SetLengthProperty(cx, obj, newlength);
---
> #if JS_HAS_MORE_PERL_FUN
> #else
>     return array_nyi(cx, "pack");
> #endif
1335a970
> #endif /* NOTYET */
1338c973
< array_push(JSContext *cx, uintN argc, jsval *vp)
---
> array_push(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1340,1341c975,978
<     JSObject *obj;
<     jsval v;
---
> #if JS_HAS_MORE_PERL_FUN
>     jsuint length;
>     uintN i;
>     jsid id;
1343,1351c980,987
<     /* Insist on one argument and obj of the expected class. */
<     obj = JSVAL_TO_OBJECT(vp[1]);
<     if (argc != 1 || OBJ_GET_CLASS(cx, obj) != &js_ArrayClass)
<         return slow_array_push(cx, obj, argc, vp);
< 
<     /* Beware 'length' int to double jsval overflow. */
<     v = STOBJ_GET_SLOT(obj, JSSLOT_ARRAY_LENGTH);
<     if (!(v & JSVAL_INT) || v == INT_TO_JSVAL(JSVAL_INT_MAX))
<         return slow_array_push(cx, obj, argc, vp);
---
>     if (!js_GetLengthProperty(cx, obj, &length))
> 	return JS_FALSE;
>     for (i = 0; i < argc; i++) {
> 	if (!IndexToId(cx, length + i, &id))
> 	    return JS_FALSE;
> 	if (!OBJ_SET_PROPERTY(cx, obj, id, &argv[i]))
> 	    return JS_FALSE;
>     }
1354,1358c990,991
<      * Ok, we can optimize to define a new property identified by the
<      * current value of 'length'.  We know no such property exists,
<      * because if one did, then js_ArrayClass.addProperty would have
<      * increased the value of 'length' to one greater than this index
<      * (proof by contradiction).
---
>      * If JS1.2, follow Perl4 by returning the last thing pushed.  Otherwise,
>      * return the new array length.
1360,1363c993,998
<     if (!js_DefineNativeProperty(cx, obj, INT_JSVAL_TO_JSID(v), vp[2],
<                                  NULL, NULL, JSPROP_ENUMERATE, 0, 0,
<                                  NULL)) {
<         return JS_FALSE;
---
>     length += argc;
>     if (cx->version == JSVERSION_1_2) {
> 	*rval = argc ? argv[argc-1] : JSVAL_VOID;
>     } else {
> 	if (!IndexToValue(cx, length, rval))
> 	    return JS_FALSE;
1365,1368c1000,1003
<     v += 2;
<     JS_ASSERT(STOBJ_GET_SLOT(obj, JSSLOT_ARRAY_LENGTH) == v);
<     *vp = v;
<     return JS_TRUE;
---
>     return js_SetLengthProperty(cx, obj, length);
> #else
>     return array_nyi(cx, "push");
> #endif
1371,1372c1006,1007
< JSBool
< array_pop(JSContext *cx, uintN argc, jsval *vp)
---
> static JSBool
> array_pop(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1374c1009
<     JSObject *obj;
---
> #if JS_HAS_MORE_PERL_FUN
1376c1011,1012
<     JSBool hole;
---
>     jsid id;
>     jsval junk;
1378d1013
<     obj = JS_THIS_OBJECT(cx, vp);
1380,1384c1015,1023
<         return JS_FALSE;
<     if (index == 0) {
<         *vp = JSVAL_VOID;
<     } else {
<         index--;
---
> 	return JS_FALSE;
>     if (index > 0) {
> 	index--;
> 	if (!IndexToId(cx, index, &id))
> 	    return JS_FALSE;
> 
> 	/* Get the to-be-deleted property's value into rval. */
> 	if (!OBJ_GET_PROPERTY(cx, obj, id, rval))
> 	    return JS_FALSE;
1386,1390c1025,1026
<         /* 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))
<             return JS_FALSE;
---
> 	if (!OBJ_DELETE_PROPERTY(cx, obj, id, &junk))
> 	    return JS_FALSE;
1392a1029,1031
> #else
>     return array_nyi(cx, "pop");
> #endif
1396c1035
< array_shift(JSContext *cx, uintN argc, jsval *vp)
---
> array_shift(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1398c1037
<     JSObject *obj;
---
> #if JS_HAS_MORE_PERL_FUN
1400,1401c1039,1040
<     JSBool hole, ok;
<     JSTempValueRooter tvr;
---
>     jsid id, id2;
>     jsval v, junk;
1403d1041
<     obj = JS_THIS_OBJECT(cx, vp);
1405,1431c1043,1070
<         return JS_FALSE;
<     if (length == 0) {
<         *vp = JSVAL_VOID;
<     } else {
<         length--;
< 
<         /* Get the to-be-deleted property's value into vp ASAP. */
<         if (!GetArrayElement(cx, obj, 0, &hole, vp))
<             return JS_FALSE;
< 
<         /* Slide down the array above the first element. */
<         ok = JS_TRUE;
<         JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_NULL, &tvr);
<         for (i = 0; i != length; i++) {
<             ok = JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) &&
<                  GetArrayElement(cx, obj, i + 1, &hole, &tvr.u.value) &&
<                  SetOrDeleteArrayElement(cx, obj, i, hole, tvr.u.value);
<             if (!ok)
<                 break;
<         }
<         JS_POP_TEMP_ROOT(cx, &tvr);
<         if (!ok)
<             return JS_FALSE;
< 
<         /* Delete the only or last element when it exist. */
<         if (!hole && !DeleteArrayElement(cx, obj, length))
<             return JS_FALSE;
---
> 	return JS_FALSE;
>     if (length > 0) {
> 	length--;
> 	id = JSVAL_ZERO;
> 
> 	/* Get the to-be-deleted property's value into rval ASAP. */
> 	if (!OBJ_GET_PROPERTY(cx, obj, id, rval))
> 	    return JS_FALSE;
> 
> 	/*
> 	 * Slide down the array above the first element.
> 	 */
> 	if (length > 0) {
> 	    for (i = 1; i <= length; i++) {
> 		if (!IndexToId(cx, i, &id))
> 		    return JS_FALSE;
> 		if (!IndexToId(cx, i - 1, &id2))
> 		    return JS_FALSE;
> 		if (!OBJ_GET_PROPERTY(cx, obj, id, &v))
> 		    return JS_FALSE;
> 		if (!OBJ_SET_PROPERTY(cx, obj, id2, &v))
> 		    return JS_FALSE;
> 	    }
> 	}
> 
> 	/* Delete the only or last element. */
> 	if (!OBJ_DELETE_PROPERTY(cx, obj, id, &junk))
> 	    return JS_FALSE;
1433a1073,1075
> #else
>     return array_nyi(cx, "shift");
> #endif
1437c1079,1080
< array_unshift(JSContext *cx, uintN argc, jsval *vp)
---
> array_unshift(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
> 	      jsval *rval)
1439,1440c1082
<     JSObject *obj;
<     jsval *argv;
---
> #if JS_HAS_MORE_PERL_FUN
1442,1443c1084,1090
<     JSBool hole, ok;
<     JSTempValueRooter tvr;
---
>     uintN i;
>     jsid id, id2;
>     jsval v;
> #if JS_HAS_SPARSE_ARRAYS
>     JSObject *obj2;
>     JSProperty *prop;
> #endif
1445d1091
<     obj = JS_THIS_OBJECT(cx, vp);
1447c1093
<         return JS_FALSE;
---
> 	return JS_FALSE;
1449,1475c1095,1130
<         /* Slide up the array to make room for argc at the bottom. */
<         argv = JS_ARGV(cx, vp);
<         if (length > 0) {
<             last = length;
<             ok = JS_TRUE;
<             JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_NULL, &tvr);
<             do {
<                 --last;
<                 ok = JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) &&
<                      GetArrayElement(cx, obj, last, &hole, &tvr.u.value) &&
<                      SetOrDeleteArrayElement(cx, obj, last + argc, hole,
<                                              tvr.u.value);
<                 if (!ok)
<                     break;
<             } while (last != 0);
<             JS_POP_TEMP_ROOT(cx, &tvr);
<             if (!ok)
<                 return JS_FALSE;
<         }
< 
<         /* Copy from argv to the bottom of the array. */
<         if (!InitArrayElements(cx, obj, 0, argc, argv))
<             return JS_FALSE;
< 
<         length += argc;
<         if (!js_SetLengthProperty(cx, obj, length))
<             return JS_FALSE;
---
> 	/* Slide up the array to make room for argc at the bottom. */
> 	if (length > 0) {
> 	    last = length;
> 	    while (last--) {
> 		if (!IndexToId(cx, last, &id))
> 		    return JS_FALSE;
> 		if (!IndexToId(cx, last + argc, &id2))
> 		    return JS_FALSE;
> #if JS_HAS_SPARSE_ARRAYS
>                 if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop))
>                     return JS_FALSE;
>                 if (!prop) {
>                     OBJ_DELETE_PROPERTY(cx, obj, id2, &v); /* v is junk. */
>                     continue;
>                 }
>                 OBJ_DROP_PROPERTY(cx, obj2, prop);
> #endif
>                 if (!OBJ_GET_PROPERTY(cx, obj, id, &v))
> 		    return JS_FALSE;
> 		if (!OBJ_SET_PROPERTY(cx, obj, id2, &v))
> 		    return JS_FALSE;
> 	    }
> 	}
> 
> 	/* Copy from argv to the bottom of the array. */
> 	for (i = 0; i < argc; i++) {
> 	    if (!IndexToId(cx, i, &id))
> 		return JS_FALSE;
> 	    if (!OBJ_SET_PROPERTY(cx, obj, id, &argv[i]))
> 		return JS_FALSE;
> 	}
> 
> 	/* Follow Perl by returning the new array length. */
> 	length += argc;
> 	if (!js_SetLengthProperty(cx, obj, length))
> 	    return JS_FALSE;
1477,1479c1132,1135
< 
<     /* Follow Perl by returning the new array length. */
<     return IndexToValue(cx, length, vp);
---
>     return IndexToValue(cx, length, rval);
> #else
>     return array_nyi(cx, "unshift");
> #endif
1483c1139
< array_splice(JSContext *cx, uintN argc, jsval *vp)
---
> array_splice(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1485,1486c1141
<     jsval *argv;
<     JSObject *obj;
---
> #if JS_HAS_MORE_PERL_FUN
1487a1143
>     uintN i;
1489c1145,1146
<     JSBool hole, ok;
---
>     jsid id, id2;
>     jsval v;
1491d1147
<     JSTempValueRooter tvr;
1493c1149
<     /* Nothing to do if no args.  Otherwise get length. */
---
>     /* Nothing to do if no args.  Otherwise lock and load length. */
1495,1497c1151
<         return JS_TRUE;
<     argv = JS_ARGV(cx, vp);
<     obj = JS_THIS_OBJECT(cx, vp);
---
> 	return JS_TRUE;
1499c1153
<         return JS_FALSE;
---
> 	return JS_FALSE;
1503c1157
<         return JS_FALSE;
---
> 	return JS_FALSE;
1506,1508c1160,1162
<         d += length;
<         if (d < 0)
<             d = 0;
---
> 	d += length;
> 	if (d < 0)
> 	    d = 0;
1510c1164
<         d = length;
---
> 	d = length;
1519,1520c1173,1174
<         count = delta;
<         end = length;
---
> 	count = delta;
> 	end = length;
1522,1561c1176,1229
<         if (!js_ValueToNumber(cx, *argv, &d))
<             return JS_FALSE;
<         d = js_DoubleToInteger(d);
<         if (d < 0)
<             d = 0;
<         else if (d > delta)
<             d = delta;
<         count = (jsuint)d;
<         end = begin + count;
<         argc--;
<         argv++;
<     }
< 
<     /*
<      * Create a new array value to return.  Our ECMA v2 proposal specs
<      * that splice always returns an array value, even when given no
<      * arguments.  We think this is best because it eliminates the need
<      * for callers to do an extra test to handle the empty splice case.
<      */
<     obj2 = js_NewArrayObject(cx, 0, NULL);
<     if (!obj2)
<         return JS_FALSE;
<     *vp = OBJECT_TO_JSVAL(obj2);
< 
<     /* After this, control must flow through label out: to exit. */
<     JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_NULL, &tvr);
< 
<     /* If there are elements to remove, put them into the return value. */
<     if (count > 0) {
<         for (last = begin; last < end; last++) {
<             ok = JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) &&
<                  GetArrayElement(cx, obj, last, &hole, &tvr.u.value);
<             if (!ok)
<                 goto out;
< 
<             /* Copy tvr.u.value to new array unless it's a hole. */
<             if (!hole) {
<                 ok = SetArrayElement(cx, obj2, last - begin, tvr.u.value);
<                 if (!ok)
<                     goto out;
---
> 	if (!js_ValueToNumber(cx, *argv, &d))
> 	    return JS_FALSE;
> 	d = js_DoubleToInteger(d);
> 	if (d < 0)
> 	    d = 0;
> 	else if (d > delta)
> 	    d = delta;
> 	count = (jsuint)d;
> 	end = begin + count;
> 	argc--;
> 	argv++;
>     }
> 
>     if (count == 1 && cx->version == JSVERSION_1_2) {
> 	/*
> 	 * JS lacks "list context", whereby in Perl one turns the single
> 	 * scalar that's spliced out into an array just by assigning it to
> 	 * @single instead of $single, or by using it as Perl push's first
> 	 * argument, for instance.
> 	 *
> 	 * JS1.2 emulated Perl too closely and returned a non-Array for
> 	 * the single-splice-out case, requiring callers to test and wrap
> 	 * in [] if necessary.  So JS1.3, default, and other versions all
> 	 * return an array of length 1 for uniformity.
> 	 */
> 	if (!IndexToId(cx, begin, &id))
> 	    return JS_FALSE;
> 	if (!OBJ_GET_PROPERTY(cx, obj, id, rval))
> 	    return JS_FALSE;
>     } else {
> 	if (cx->version != JSVERSION_1_2 || count > 0) {
> 	    /*
> 	     * Create a new array value to return.  Our ECMA v2 proposal specs
> 	     * that splice always returns an array value, even when given no
> 	     * arguments.  We think this is best because it eliminates the need
> 	     * for callers to do an extra test to handle the empty splice case.
> 	     */
> 	    obj2 = js_NewArrayObject(cx, 0, NULL);
> 	    if (!obj2)
> 		return JS_FALSE;
> 	    *rval = OBJECT_TO_JSVAL(obj2);
> 
>             /* If there are elements to remove, put them into the return value. */
>             if (count > 0) {
>                 for (last = begin; last < end; last++) {
>                     if (!IndexToId(cx, last, &id))
>                         return JS_FALSE;
>                     if (!IndexToId(cx, last - begin, &id2))
>                         return JS_FALSE;
>                     if (!OBJ_GET_PROPERTY(cx, obj, id, &v))
>                         return JS_FALSE;
>                     if (!OBJ_SET_PROPERTY(cx, obj2, id2, &v))
>                         return JS_FALSE;
>                 }
1563,1567c1231
<         }
< 
<         ok = js_SetLengthProperty(cx, obj2, end - begin);
<         if (!ok)
<             goto out;
---
> 	}
1572,1583c1236,1249
<         delta = (jsuint)argc - count;
<         last = length;
<         /* (uint) end could be 0, so can't use vanilla >= test */
<         while (last-- > end) {
<             ok = JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) &&
<                  GetArrayElement(cx, obj, last, &hole, &tvr.u.value) &&
<                  SetOrDeleteArrayElement(cx, obj, last + delta, hole,
<                                          tvr.u.value);
<             if (!ok)
<                 goto out;
<         }
<         length += delta;
---
> 	delta = (jsuint)argc - count;
> 	last = length;
> 	/* (uint) end could be 0, so can't use vanilla >= test */
> 	while (last-- > end) {
> 	    if (!IndexToId(cx, last, &id))
> 		return JS_FALSE;
> 	    if (!IndexToId(cx, last + delta, &id2))
> 		return JS_FALSE;
> 	    if (!OBJ_GET_PROPERTY(cx, obj, id, &v))
> 		return JS_FALSE;
> 	    if (!OBJ_SET_PROPERTY(cx, obj, id2, &v))
> 		return JS_FALSE;
> 	}
> 	length += delta;
1585,1594c1251,1262
<         delta = count - (jsuint)argc;
<         for (last = end; last < length; last++) {
<             ok = JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) &&
<                  GetArrayElement(cx, obj, last, &hole, &tvr.u.value) &&
<                  SetOrDeleteArrayElement(cx, obj, last - delta, hole,
<                                          tvr.u.value);
<             if (!ok)
<                 goto out;
<         }
<         length -= delta;
---
> 	delta = count - (jsuint)argc;
> 	for (last = end; last < length; last++) {
> 	    if (!IndexToId(cx, last, &id))
> 		return JS_FALSE;
> 	    if (!IndexToId(cx, last - delta, &id2))
> 		return JS_FALSE;
> 	    if (!OBJ_GET_PROPERTY(cx, obj, id, &v))
> 		return JS_FALSE;
> 	    if (!OBJ_SET_PROPERTY(cx, obj, id2, &v))
> 		return JS_FALSE;
> 	}
> 	length -= delta;
1598,1600c1266,1271
<     ok = InitArrayElements(cx, obj, begin, begin + argc, argv);
<     if (!ok)
<         goto out;
---
>     for (i = 0; i < argc; i++) {
> 	if (!IndexToId(cx, begin + i, &id))
> 	    return JS_FALSE;
> 	if (!OBJ_SET_PROPERTY(cx, obj, id, &argv[i]))
> 	    return JS_FALSE;
>     }
1603,1607c1274,1277
<     ok = js_SetLengthProperty(cx, obj, length);
< 
< out:
<     JS_POP_TEMP_ROOT(cx, &tvr);
<     return ok;
---
>     return js_SetLengthProperty(cx, obj, length);
> #else
>     return array_nyi(cx, "splice");
> #endif
1609a1280
> #if JS_HAS_SEQUENCE_OPS
1614c1285
< array_concat(JSContext *cx, uintN argc, jsval *vp)
---
> array_concat(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1616d1286
<     jsval *argv, v;
1620,1621c1290,1291
<     JSBool hole, ok;
<     JSTempValueRooter tvr;
---
>     jsval v;
>     jsid id, id2;
1623,1625c1293,1295
<     /* Treat our |this| object as the first argument; see ECMA 15.4.4.4. */
<     argv = JS_ARGV(cx, vp) - 1;
<     JS_ASSERT(JS_THIS_OBJECT(cx, vp) == JSVAL_TO_OBJECT(argv[0]));
---
>     /* Treat obj as the first argument; see ECMA 15.4.4.4. */
>     --argv;
>     JS_ASSERT(obj == JSVAL_TO_OBJECT(argv[0]));
1627c1297
<     /* Create a new Array object and root it using *vp. */
---
>     /* Create a new Array object and store it in the rval local root. */
1630,1634c1300,1301
<         return JS_FALSE;
<     *vp = OBJECT_TO_JSVAL(nobj);
< 
<     /* After this, control must flow through label out: to exit. */
<     JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_NULL, &tvr);
---
> 	return JS_FALSE;
>     *rval = OBJECT_TO_JSVAL(nobj);
1639,1671c1306,1313
<         ok = JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP);
<         if (!ok)
<             goto out;
<         v = argv[i];
<         if (JSVAL_IS_OBJECT(v)) {
<             aobj = JSVAL_TO_OBJECT(v);
<             if (aobj && OBJ_GET_CLASS(cx, aobj) == &js_ArrayClass) {
<                 ok = OBJ_GET_PROPERTY(cx, aobj,
<                                       ATOM_TO_JSID(cx->runtime->atomState
<                                                    .lengthAtom),
<                                       &tvr.u.value);
<                 if (!ok)
<                     goto out;
<                 ok = ValueIsLength(cx, tvr.u.value, &alength);
<                 if (!ok)
<                     goto out;
<                 for (slot = 0; slot < alength; slot++) {
<                     ok = JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) &&
<                          GetArrayElement(cx, aobj, slot, &hole,
<                                          &tvr.u.value);
<                     if (!ok)
<                         goto out;
< 
<                     /*
<                      * Per ECMA 262, 15.4.4.4, step 9, ignore non-existent
<                      * properties.
<                      */
<                     if (!hole) {
<                         ok = SetArrayElement(cx, nobj, length + slot,
<                                              tvr.u.value);
<                         if (!ok)
<                             goto out;
<                     }
---
> 	v = argv[i];
> 	if (JSVAL_IS_OBJECT(v)) {
> 	    aobj = JSVAL_TO_OBJECT(v);
> 	    if (aobj && OBJ_GET_CLASS(cx, aobj) == &js_ArrayClass) {
>                 if (!OBJ_GET_PROPERTY(cx, aobj,
>                                       (jsid)cx->runtime->atomState.lengthAtom,
>                                       &v)) {
>                     return JS_FALSE;
1673,1681c1315,1336
<                 length += alength;
<                 continue;
<             }
<         }
< 
<         ok = SetArrayElement(cx, nobj, length, v);
<         if (!ok)
<             goto out;
<         length++;
---
>                 if (!ValueIsLength(cx, v, &alength))
>                     return JS_FALSE;
> 		for (slot = 0; slot < alength; slot++) {
> 		    if (!IndexToId(cx, slot, &id))
> 			return JS_FALSE;
> 		    if (!IndexToId(cx, length + slot, &id2))
> 			return JS_FALSE;
> 		    if (!OBJ_GET_PROPERTY(cx, aobj, id, &v))
> 			return JS_FALSE;
> 		    if (!OBJ_SET_PROPERTY(cx, nobj, id2, &v))
> 			return JS_FALSE;
> 		}
> 		length += alength;
> 		continue;
> 	    }
> 	}
> 
> 	if (!IndexToId(cx, length, &id))
> 	    return JS_FALSE;
> 	if (!OBJ_SET_PROPERTY(cx, nobj, id, &v))
> 	    return JS_FALSE;
> 	length++;
1684,1688c1339
<     ok = js_SetLengthProperty(cx, nobj, length);
< 
< out:
<     JS_POP_TEMP_ROOT(cx, &tvr);
<     return ok;
---
>     return JS_TRUE;
1692c1343
< array_slice(JSContext *cx, uintN argc, jsval *vp)
---
> array_slice(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1694,1695c1345
<     jsval *argv;
<     JSObject *nobj, *obj;
---
>     JSObject *nobj;
1698,1701c1348,1349
<     JSBool hole, ok;
<     JSTempValueRooter tvr;
< 
<     argv = JS_ARGV(cx, vp);
---
>     jsid id, id2;
>     jsval v;
1703d1350
<     /* Create a new Array object and root it using *vp. */
1706,1707c1353
<         return JS_FALSE;
<     *vp = OBJECT_TO_JSVAL(nobj);
---
> 	return JS_FALSE;
1709d1354
<     obj = JS_THIS_OBJECT(cx, vp);
1711c1356
<         return JS_FALSE;
---
> 	return JS_FALSE;
1716,1740c1361,1385
<         if (!js_ValueToNumber(cx, argv[0], &d))
<             return JS_FALSE;
<         d = js_DoubleToInteger(d);
<         if (d < 0) {
<             d += length;
<             if (d < 0)
<                 d = 0;
<         } else if (d > length) {
<             d = length;
<         }
<         begin = (jsuint)d;
< 
<         if (argc > 1) {
<             if (!js_ValueToNumber(cx, argv[1], &d))
<                 return JS_FALSE;
<             d = js_DoubleToInteger(d);
<             if (d < 0) {
<                 d += length;
<                 if (d < 0)
<                     d = 0;
<             } else if (d > length) {
<                 d = length;
<             }
<             end = (jsuint)d;
<         }
---
> 	if (!js_ValueToNumber(cx, argv[0], &d))
> 	    return JS_FALSE;
> 	d = js_DoubleToInteger(d);
> 	if (d < 0) {
> 	    d += length;
> 	    if (d < 0)
> 		d = 0;
> 	} else if (d > length) {
> 	    d = length;
> 	}
> 	begin = (jsuint)d;
> 
> 	if (argc > 1) {
> 	    if (!js_ValueToNumber(cx, argv[1], &d))
> 		return JS_FALSE;
> 	    d = js_DoubleToInteger(d);
> 	    if (d < 0) {
> 		d += length;
> 		if (d < 0)
> 		    d = 0;
> 	    } else if (d > length) {
> 		d = length;
> 	    }
> 	    end = (jsuint)d;
> 	}
1743,1748d1387
<     if (begin > end)
<         begin = end;
< 
<     /* After this, control must flow through label out: to exit. */
<     JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_NULL, &tvr);
< 
1750,1758c1389,1396
<         ok = JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) &&
<              GetArrayElement(cx, obj, slot, &hole, &tvr.u.value);
<         if (!ok)
<             goto out;
<         if (!hole) {
<             ok = SetArrayElement(cx, nobj, slot - begin, tvr.u.value);
<             if (!ok)
<                 goto out;
<         }
---
> 	if (!IndexToId(cx, slot, &id))
> 	    return JS_FALSE;
> 	if (!IndexToId(cx, slot - begin, &id2))
> 	    return JS_FALSE;
> 	if (!OBJ_GET_PROPERTY(cx, obj, id, &v))
> 	    return JS_FALSE;
> 	if (!OBJ_SET_PROPERTY(cx, nobj, id2, &v))
> 	    return JS_FALSE;
1760,1830c1398
<     ok = js_SetLengthProperty(cx, nobj, end - begin);
< 
< out:
<     JS_POP_TEMP_ROOT(cx, &tvr);
<     return ok;
< }
< 
< #if JS_HAS_ARRAY_EXTRAS
< 
< static JSBool
< array_indexOfHelper(JSContext *cx, JSBool isLast, uintN argc, jsval *vp)
< {
<     JSObject *obj;
<     jsuint length, i, stop;
<     jsint direction;
<     JSBool hole;
< 
<     obj = JSVAL_TO_OBJECT(vp[1]);
<     if (!js_GetLengthProperty(cx, obj, &length))
<         return JS_FALSE;
<     if (length == 0)
<         goto not_found;
< 
<     if (argc <= 1) {
<         i = isLast ? length - 1 : 0;
<     } else {
<         jsdouble start;
< 
<         if (!js_ValueToNumber(cx, vp[3], &start))
<             return JS_FALSE;
<         start = js_DoubleToInteger(start);
<         if (start < 0) {
<             start += length;
<             if (start < 0) {
<                 if (isLast)
<                     goto not_found;
<                 i = 0;
<             } else {
<                 i = (jsuint)start;
<             }
<         } else if (start >= length) {
<             if (!isLast)
<                 goto not_found;
<             i = length - 1;
<         } else {
<             i = (jsuint)start;
<         }
<     }
< 
<     if (isLast) {
<         stop = 0;
<         direction = -1;
<     } else {
<         stop = length - 1;
<         direction = 1;
<     }
< 
<     for (;;) {
<         if (!JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) ||
<             !GetArrayElement(cx, obj, (jsuint)i, &hole, vp)) {
<             return JS_FALSE;
<         }
<         if (!hole && js_StrictlyEqual(cx, *vp, vp[2]))
<             return js_NewNumberValue(cx, i, vp);
<         if (i == stop)
<             goto not_found;
<         i += direction;
<     }
< 
<   not_found:
<     *vp = INT_TO_JSVAL(-1);
---
>     *rval = OBJECT_TO_JSVAL(nobj);
1833,2086c1401
< 
< static JSBool
< array_indexOf(JSContext *cx, uintN argc, jsval *vp)
< {
<     return array_indexOfHelper(cx, JS_FALSE, argc, vp);
< }
< 
< static JSBool
< array_lastIndexOf(JSContext *cx, uintN argc, jsval *vp)
< {
<     return array_indexOfHelper(cx, JS_TRUE, argc, vp);
< }
< 
< /* Order is important; extras that take a predicate funarg must follow MAP. */
< typedef enum ArrayExtraMode {
<     FOREACH,
<     REDUCE,
<     REDUCE_RIGHT,
<     MAP,
<     FILTER,
<     SOME,
<     EVERY
< } ArrayExtraMode;
< 
< #define REDUCE_MODE(mode) ((mode) == REDUCE || (mode) == REDUCE_RIGHT)
< 
< static JSBool
< array_extra(JSContext *cx, ArrayExtraMode mode, uintN argc, jsval *vp)
< {
<     JSObject *obj;
<     jsuint length, newlen;
<     jsval *argv, *elemroot, *invokevp, *sp;
<     JSBool ok, cond, hole;
<     JSObject *callable, *thisp, *newarr;
<     jsint start, end, step, i;
<     void *mark;
< 
<     obj = JSVAL_TO_OBJECT(vp[1]);
<     if (!js_GetLengthProperty(cx, obj, &length))
<         return JS_FALSE;
< 
<     /*
<      * First, get or compute our callee, so that we error out consistently
<      * when passed a non-callable object.
<      */
<     argv = vp + 2;
<     callable = js_ValueToCallableObject(cx, &argv[0], JSV2F_SEARCH_STACK);
<     if (!callable)
<         return JS_FALSE;
< 
<     /*
<      * Set our initial return condition, used for zero-length array cases
<      * (and pre-size our map return to match our known length, for all cases).
<      */
< #ifdef __GNUC__ /* quell GCC overwarning */
<     newlen = 0;
<     newarr = NULL;
< #endif
<     start = 0, end = length, step = 1;
< 
<     switch (mode) {
<       case REDUCE_RIGHT:
<         start = length - 1, end = -1, step = -1;
<         /* FALL THROUGH */
<       case REDUCE:
<         if (length == 0 && argc == 1) {
<             JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
<                                  JSMSG_EMPTY_ARRAY_REDUCE);
<             return JS_FALSE;
<         }
<         if (argc >= 2) {
<             *vp = argv[1];
<         } else {
<             do {
<                 if (!GetArrayElement(cx, obj, start, &hole, vp))
<                     return JS_FALSE;
<                 start += step;
<             } while (hole && start != end);
< 
<             if (hole && start == end) {
<                 JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
<                                      JSMSG_EMPTY_ARRAY_REDUCE);
<                 return JS_FALSE;
<             }
<         }
<         break;
<       case MAP:
<       case FILTER:
<         newlen = (mode == MAP) ? length : 0;
<         newarr = js_NewArrayObject(cx, newlen, NULL);
<         if (!newarr)
<             return JS_FALSE;
<         *vp = OBJECT_TO_JSVAL(newarr);
<         break;
<       case SOME:
<         *vp = JSVAL_FALSE;
<         break;
<       case EVERY:
<         *vp = JSVAL_TRUE;
<         break;
<       case FOREACH:
<         *vp = JSVAL_VOID;
<         break;
<     }
< 
<     if (length == 0)
<         return JS_TRUE;
< 
<     if (argc > 1 && !REDUCE_MODE(mode)) {
<         if (!js_ValueToObject(cx, argv[1], &thisp))
<             return JS_FALSE;
<         argv[1] = OBJECT_TO_JSVAL(thisp);
<     } else {
<         thisp = NULL;
<     }
< 
<     /*
<      * For all but REDUCE, we call with 3 args (value, index, array). REDUCE
<      * requires 4 args (accum, value, index, array).
<      */
<     argc = 3 + REDUCE_MODE(mode);
<     elemroot = js_AllocStack(cx, 1 + 2 + argc, &mark);
<     if (!elemroot)
<         return JS_FALSE;
< 
<     /* From this point the control must flow through out:. */
<     ok = JS_TRUE;
<     invokevp = elemroot + 1;
< 
<     for (i = start; i != end; i += step) {
<         ok = JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) &&
<              GetArrayElement(cx, obj, i, &hole, elemroot);
<         if (!ok)
<             goto out;
<         if (hole)
<             continue;
< 
<         /*
<          * Push callable and 'this', then args. We must do this for every
<          * iteration around the loop since js_Invoke uses spbase[0] for return
<          * value storage, while some native functions use spbase[1] for local
<          * rooting.
<          */
<         sp = invokevp;
<         *sp++ = OBJECT_TO_JSVAL(callable);
<         *sp++ = OBJECT_TO_JSVAL(thisp);
<         if (REDUCE_MODE(mode))
<             *sp++ = *vp;
<         *sp++ = *elemroot;
<         *sp++ = INT_TO_JSVAL(i);
<         *sp++ = OBJECT_TO_JSVAL(obj);
< 
<         /* Do the call. */
<         ok = js_Invoke(cx, argc, invokevp, JSINVOKE_INTERNAL);
<         if (!ok)
<             break;
< 
<         if (mode > MAP)
<             cond = js_ValueToBoolean(*invokevp);
< #ifdef __GNUC__ /* quell GCC overwarning */
<         else
<             cond = JS_FALSE;
< #endif
< 
<         switch (mode) {
<           case FOREACH:
<             break;
<           case REDUCE:
<           case REDUCE_RIGHT:
<             *vp = *invokevp;
<             break;
<           case MAP:
<             ok = SetArrayElement(cx, newarr, i, *invokevp);
<             if (!ok)
<                 goto out;
<             break;
<           case FILTER:
<             if (!cond)
<                 break;
<             /* The filter passed *elemroot, so push it onto our result. */
<             ok = SetArrayElement(cx, newarr, newlen++, *elemroot);
<             if (!ok)
<                 goto out;
<             break;
<           case SOME:
<             if (cond) {
<                 *vp = JSVAL_TRUE;
<                 goto out;
<             }
<             break;
<           case EVERY:
<             if (!cond) {
<                 *vp = JSVAL_FALSE;
<                 goto out;
<             }
<             break;
<         }
<     }
< 
<   out:
<     js_FreeStack(cx, mark);
<     if (ok && mode == FILTER)
<         ok = js_SetLengthProperty(cx, newarr, newlen);
<     return ok;
< }
< 
< static JSBool
< array_forEach(JSContext *cx, uintN argc, jsval *vp)
< {
<     return array_extra(cx, FOREACH, argc, vp);
< }
< 
< static JSBool
< array_map(JSContext *cx, uintN argc, jsval *vp)
< {
<     return array_extra(cx, MAP, argc, vp);
< }
< 
< static JSBool
< array_reduce(JSContext *cx, uintN argc, jsval *vp)
< {
<     return array_extra(cx, REDUCE, argc, vp);
< }
< 
< static JSBool
< array_reduceRight(JSContext *cx, uintN argc, jsval *vp)
< {
<     return array_extra(cx, REDUCE_RIGHT, argc, vp);
< }
< 
< static JSBool
< array_filter(JSContext *cx, uintN argc, jsval *vp)
< {
<     return array_extra(cx, FILTER, argc, vp);
< }
< 
< static JSBool
< array_some(JSContext *cx, uintN argc, jsval *vp)
< {
<     return array_extra(cx, SOME, argc, vp);
< }
< 
< static JSBool
< array_every(JSContext *cx, uintN argc, jsval *vp)
< {
<     return array_extra(cx, EVERY, argc, vp);
< }
< #endif
< 
< static JSPropertySpec array_props[] = {
<     {js_length_str,   -1,   JSPROP_SHARED | JSPROP_PERMANENT,
<                             array_length_getter,    array_length_setter},
<     {0,0,0,0,0}
< };
---
> #endif /* JS_HAS_SEQUENCE_OPS */
2090c1405
<     JS_FN(js_toSource_str,      array_toSource,     0,0,0),
---
>     {js_toSource_str,       array_toSource,         0,0,0},
2092,2093c1407,1408
<     JS_FN(js_toString_str,      array_toString,     0,0,0),
<     JS_FN(js_toLocaleString_str,array_toLocaleString,0,0,0),
---
>     {js_toString_str,       array_toString,         0,0,0},
>     {js_toLocaleString_str, array_toLocaleString,   0,0,0},
2096,2103c1411,1421
<     JS_FN("join",               array_join,         1,1,JSFUN_GENERIC_NATIVE),
<     JS_FN("reverse",            array_reverse,      0,0,JSFUN_GENERIC_NATIVE),
<     JS_FN("sort",               array_sort,         0,1,JSFUN_GENERIC_NATIVE),
<     JS_FN("push",               array_push,         1,1,JSFUN_GENERIC_NATIVE),
<     JS_FN("pop",                array_pop,          0,0,JSFUN_GENERIC_NATIVE),
<     JS_FN("shift",              array_shift,        0,0,JSFUN_GENERIC_NATIVE),
<     JS_FN("unshift",            array_unshift,      0,1,JSFUN_GENERIC_NATIVE),
<     JS_FN("splice",             array_splice,       0,2,JSFUN_GENERIC_NATIVE),
---
>     {"join",                array_join,             1,0,0},
>     {"reverse",             array_reverse,          0,0,0},
>     {"sort",                array_sort,             1,0,0},
> #ifdef NOTYET
>     {"pack",                array_pack,             1,0,0},
> #endif
>     {"push",                array_push,             1,0,0},
>     {"pop",                 array_pop,              0,0,0},
>     {"shift",               array_shift,            0,0,0},
>     {"unshift",             array_unshift,          1,0,0},
>     {"splice",              array_splice,           1,0,0},
2106,2118c1424,1426
<     JS_FN("concat",             array_concat,       0,1,JSFUN_GENERIC_NATIVE),
<     JS_FN("slice",              array_slice,        0,2,JSFUN_GENERIC_NATIVE),
< 
< #if JS_HAS_ARRAY_EXTRAS
<     JS_FN("indexOf",            array_indexOf,      1,1,JSFUN_GENERIC_NATIVE),
<     JS_FN("lastIndexOf",        array_lastIndexOf,  1,1,JSFUN_GENERIC_NATIVE),
<     JS_FN("forEach",            array_forEach,      1,1,JSFUN_GENERIC_NATIVE),
<     JS_FN("map",                array_map,          1,1,JSFUN_GENERIC_NATIVE),
<     JS_FN("reduce",             array_reduce,       1,1,JSFUN_GENERIC_NATIVE),
<     JS_FN("reduceRight",        array_reduceRight,  1,1,JSFUN_GENERIC_NATIVE),
<     JS_FN("filter",             array_filter,       1,1,JSFUN_GENERIC_NATIVE),
<     JS_FN("some",               array_some,         1,1,JSFUN_GENERIC_NATIVE),
<     JS_FN("every",              array_every,        1,1,JSFUN_GENERIC_NATIVE),
---
> #if JS_HAS_SEQUENCE_OPS
>     {"concat",              array_concat,           0,0,0},
>     {"slice",               array_slice,            0,0,0},
2121c1429
<     JS_FS_END
---
>     {0,0,0,0,0}
2132,2135c1440,1443
<         obj = js_NewObject(cx, &js_ArrayClass, NULL, NULL);
<         if (!obj)
<             return JS_FALSE;
<         *rval = OBJECT_TO_JSVAL(obj);
---
> 	obj = js_NewObject(cx, &js_ArrayClass, NULL, NULL);
> 	if (!obj)
> 	    return JS_FALSE;
> 	*rval = OBJECT_TO_JSVAL(obj);
2139,2146c1447,1451
<         length = 0;
<         vector = NULL;
<     } else if (argc > 1) {
<         length = (jsuint) argc;
<         vector = argv;
<     } else if (!JSVAL_IS_NUMBER(argv[0])) {
<         length = 1;
<         vector = argv;
---
> 	length = 0;
> 	vector = NULL;
>     } else if (cx->version == JSVERSION_1_2) {
> 	length = (jsuint) argc;
> 	vector = argv;
2148,2150c1453,1463
<         if (!ValueIsLength(cx, argv[0], &length))
<             return JS_FALSE;
<         vector = NULL;
---
>         if (argc > 1) {
> 	    length = (jsuint) argc;
> 	    vector = argv;
>         } else if (!JSVAL_IS_NUMBER(argv[0])) {
> 	    length = 1;
> 	    vector = argv;
>         } else if (ValueIsLength(cx, argv[0], &length)) {
> 	    vector = NULL;
> 	} else {
> 	    return JS_FALSE;
> 	}
2161c1474
<                          array_props, array_methods, NULL, NULL);
---
> 			 NULL, array_methods, NULL, NULL);
2165c1478
<         return NULL;
---
> 	return NULL;
2172d1484
<     JSTempValueRooter tvr;
2177,2185c1489,1493
<         return NULL;
< 
<     JS_PUSH_TEMP_ROOT_OBJECT(cx, obj, &tvr);
<     if (!InitArrayObject(cx, obj, length, vector))
<         obj = NULL;
<     JS_POP_TEMP_ROOT(cx, &tvr);
< 
<     /* Set/clear newborn root, in case we lost it.  */
<     cx->weakRoots.newborn[GCX_OBJECT] = obj;
---
> 	return NULL;
>     if (!InitArrayObject(cx, obj, length, vector)) {
> 	cx->newborn[GCX_OBJECT] = NULL;
> 	return NULL;
>     }
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsarray.h /Volumes/Swap/js_D11/src/jsarray.h
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
50,55d44
< /* Generous sanity-bound on length (in elements) of array initialiser. */
< #define ARRAY_INIT_LIMIT        JS_BIT(24)
< 
< extern JSBool
< js_IdIsIndex(jsval id, jsuint *indexp);
< 
64,65d52
< #define JSSLOT_ARRAY_LENGTH     JSSLOT_PRIVATE
< 
76,80c63
<  * Test whether an object is "array-like".  Currently this means whether obj
<  * is an Array or an arguments object.  We would like an API, and probably a
<  * way in the language, to bless other objects as array-like: having indexed
<  * properties, and a 'length' property of uint32 value equal to one more than
<  * the greatest index.
---
>  * JS-specific heap sort function.
82,83c65
< extern JSBool
< js_IsArrayLike(JSContext *cx, JSObject *obj, JSBool *answerp, jsuint *lengthp);
---
> typedef int (*JSComparator)(const void *a, const void *b, void *arg);
85,97d66
< /*
<  * JS-specific merge sort function.
<  */
< typedef JSBool (*JSComparator)(void *arg, const void *a, const void *b,
<                                int *result);
< /*
<  * NB: vec is the array to be sorted, tmp is temporary space at least as big
<  * as vec. Both should be GC-rooted if appropriate.
<  *
<  * The sorted result is in vec. vec may be in an inconsistent state if the
<  * comparator function cmp returns an error inside a comparison, so remember
<  * to check the return value of this function.
<  */
99,100c68
< js_MergeSort(void *vec, size_t nel, size_t elsize, JSComparator cmp,
<              void *arg, void *tmp);
---
> js_HeapSort(void *vec, size_t nel, size_t elsize, JSComparator cmp, void *arg);
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsatom.c /Volumes/Swap/js_D11/src/jsatom.c
3,4c3,6
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
6,14c8,11
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,24c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
26,36c21
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
---
>  * Contributor(s): 
38c23,33
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
44c39
< #include <stdlib.h>
---
> #include "xstdlib.h"
53d47
< #include "jsconfig.h"
57c51
< #include "jsscan.h"
---
> #include "jsopcode.h"
60,64d53
< const char *
< js_AtomToPrintableString(JSContext *cx, JSAtom *atom)
< {
<     return js_ValueToPrintableString(cx, ATOM_KEY(atom));
< }
66,68c55,57
< #define JS_PROTO(name,code,init) const char js_##name##_str[] = #name;
< #include "jsproto.tbl"
< #undef JS_PROTO
---
> //#include "_optimize.h"
> 
> extern const char js_Error_str[];       /* trivial, from jsexn.h */
71,77c60,61
<  * Names for common atoms defined in JSAtomState starting from
<  * JSAtomState.emptyAtom until JSAtomState.lazy.
<  *
<  * The elements of the array after the first empty string define strings
<  * corresponding to JSType enumerators from jspubtd.h and to two boolean
<  * literals, false and true. The following assert insists that JSType defines
<  * exactly 8 types.
---
>  * Keep this in sync with jspubtd.h -- an assertion below will insist that
>  * its length match the JSType enum's JSTYPE_LIMIT limit value.
79,142c63,70
< JS_STATIC_ASSERT(JSTYPE_LIMIT == 8);
< const char *const js_common_atom_names[] = {
<     "",                         /* emptyAtom                    */
<     js_undefined_str,           /* typeAtoms[JSTYPE_VOID]       */
<     js_object_str,              /* typeAtoms[JSTYPE_OBJECT]     */
<     js_function_str,            /* typeAtoms[JSTYPE_FUNCTION]   */
<     "string",                   /* typeAtoms[JSTYPE_STRING]     */
<     "number",                   /* typeAtoms[JSTYPE_NUMBER]     */
<     "boolean",                  /* typeAtoms[JSTYPE_BOOLEAN]    */
<     js_null_str,                /* typeAtoms[JSTYPE_NULL]       */
<     "xml",                      /* typeAtoms[JSTYPE_XML]        */
<     js_false_str,               /* booleanAtoms[0]              */
<     js_true_str,                /* booleanAtoms[1]              */
<     js_null_str,                /* nullAtom                     */
< 
< #define JS_PROTO(name,code,init) js_##name##_str,
< #include "jsproto.tbl"
< #undef JS_PROTO
< 
<     js_anonymous_str,           /* anonymousAtom                */
<     js_arguments_str,           /* argumentsAtom                */
<     js_arity_str,               /* arityAtom                    */
<     js_callee_str,              /* calleeAtom                   */
<     js_caller_str,              /* callerAtom                   */
<     js_class_prototype_str,     /* classPrototypeAtom           */
<     js_constructor_str,         /* constructorAtom              */
<     js_count_str,               /* countAtom                    */
<     js_each_str,                /* eachAtom                     */
<     js_eval_str,                /* evalAtom                     */
<     js_fileName_str,            /* fileNameAtom                 */
<     js_get_str,                 /* getAtom                      */
<     js_getter_str,              /* getterAtom                   */
<     js_index_str,               /* indexAtom                    */
<     js_input_str,               /* inputAtom                    */
<     js_iterator_str,            /* iteratorAtom                 */
<     js_length_str,              /* lengthAtom                   */
<     js_lineNumber_str,          /* lineNumberAtom               */
<     js_message_str,             /* messageAtom                  */
<     js_name_str,                /* nameAtom                     */
<     js_next_str,                /* nextAtom                     */
<     js_noSuchMethod_str,        /* noSuchMethodAtom             */
<     js_parent_str,              /* parentAtom                   */
<     js_proto_str,               /* protoAtom                    */
<     js_set_str,                 /* setAtom                      */
<     js_setter_str,              /* setterAtom                   */
<     js_stack_str,               /* stackAtom                    */
<     js_toLocaleString_str,      /* toLocaleStringAtom           */
<     js_toSource_str,            /* toSourceAtom                 */
<     js_toString_str,            /* toStringAtom                 */
<     js_valueOf_str,             /* valueOfAtom                  */
<     "(void 0)",                 /* void0Atom                    */
< 
< #if JS_HAS_XML_SUPPORT
<     js_etago_str,               /* etagoAtom                    */
<     js_namespace_str,           /* namespaceAtom                */
<     js_ptagc_str,               /* ptagcAtom                    */
<     js_qualifier_str,           /* qualifierAtom                */
<     js_space_str,               /* spaceAtom                    */
<     js_stago_str,               /* stagoAtom                    */
<     js_star_str,                /* starAtom                     */
<     js_starQualifier_str,       /* starQualifierAtom            */
<     js_tagc_str,                /* tagcAtom                     */
<     js_xml_str,                 /* xmlAtom                      */
< #endif
---
> const char *js_type_str[] = {
>     "undefined",
>     "object",
>     "function",
>     "string",
>     "number",
>     "boolean",
> };
144,150c72,74
< #ifdef NARCISSUS
<     js_call_str,                /* callAtom                     */
<     js_construct_str,           /* constructAtom                */
<     js_hasInstance_str,         /* hasInstanceAtom              */
<     js_ExecutionContext_str,    /* ExecutionContextAtom         */
<     js_current_str,             /* currentAtom                  */
< #endif
---
> const char *js_boolean_str[] = {
>     js_false_str,
>     js_true_str
152,153d75
< JS_STATIC_ASSERT(JS_ARRAY_LENGTH(js_common_atom_names) * sizeof(JSAtom *) ==
<                  LAZY_ATOM_OFFSET_START - ATOM_OFFSET_START);
154a77,88
> const char js_Arguments_str[]       = "Arguments";
> const char js_Array_str[]           = "Array";
> const char js_Boolean_str[]         = "Boolean";
> const char js_Call_str[]            = "Call";
> const char js_Date_str[]            = "Date";
> const char js_Function_str[]        = "Function";
> const char js_Math_str[]            = "Math";
> const char js_Number_str[]          = "Number";
> const char js_Object_str[]          = "Object";
> const char js_RegExp_str[]          = "RegExp";
> const char js_Script_str[]          = "Script";
> const char js_String_str[]          = "String";
163d96
< const char js_each_str[]            = "each";
165,166d97
< const char js_fileName_str[]        = "fileName";
< const char js_get_str[]             = "get";
167a99
> const char js_get_str[]             = "get";
170d101
< const char js_iterator_str[]        = "__iterator__";
172,173d102
< const char js_lineNumber_str[]      = "lineNumber";
< const char js_message_str[]         = "message";
175,177d103
< const char js_next_str[]            = "next";
< const char js_noSuchMethod_str[]    = "__noSuchMethod__";
< const char js_object_str[]          = "object";
182d107
< const char js_stack_str[]           = "stack";
186d110
< const char js_undefined_str[]       = "undefined";
189,200c113,116
< #if JS_HAS_XML_SUPPORT
< const char js_etago_str[]           = "</";
< const char js_namespace_str[]       = "namespace";
< const char js_ptagc_str[]           = "/>";
< const char js_qualifier_str[]       = "::";
< const char js_space_str[]           = " ";
< const char js_stago_str[]           = "<";
< const char js_star_str[]            = "*";
< const char js_starQualifier_str[]   = "*::";
< const char js_tagc_str[]            = ">";
< const char js_xml_str[]             = "xml";
< #endif
---
> #define HASH_OBJECT(o)  ((JSHashNumber)(o) >> JSVAL_TAGBITS)
> #define HASH_INT(i)     ((JSHashNumber)(i))
> #define HASH_DOUBLE(dp) ((JSHashNumber)(((uint32*)(dp))[0] ^ ((uint32*)(dp))[1]))
> #define HASH_BOOLEAN(b) ((JSHashNumber)(b))
202,223c118,122
< #if JS_HAS_GENERATORS
< const char js_close_str[]           = "close";
< const char js_send_str[]            = "send";
< #endif
< 
< #ifdef NARCISSUS
< const char js_call_str[]             = "__call__";
< const char js_construct_str[]        = "__construct__";
< const char js_hasInstance_str[]      = "__hasInstance__";
< const char js_ExecutionContext_str[] = "ExecutionContext";
< const char js_current_str[]          = "current";
< #endif
< 
< /*
<  * JSAtomState.doubleAtoms and JSAtomState.stringAtoms hashtable entry. To
<  * support pinned and interned string atoms, we use the lowest bits of the
<  * keyAndFlags field to store ATOM_PINNED and ATOM_INTERNED flags.
<  */
< typedef struct JSAtomHashEntry {
<     JSDHashEntryHdr hdr;
<     jsuword         keyAndFlags;
< } JSAtomHashEntry;
---
> JS_STATIC_DLL_CALLBACK(JSHashNumber)
> js_hash_atom_key(const void *key)
> {
>     jsval v;
>     jsdouble *dp;
225c124,139
< #define ATOM_ENTRY_FLAG_MASK            (ATOM_PINNED | ATOM_INTERNED)
---
>     /* Order JSVAL_IS_* tests by likelihood of success. */
>     v = (jsval)key;
>     if (JSVAL_IS_STRING(v))
>         return js_HashString(JSVAL_TO_STRING(v));
>     if (JSVAL_IS_INT(v))
>         return HASH_INT(JSVAL_TO_INT(v));
>     if (JSVAL_IS_DOUBLE(v)) {
>         dp = JSVAL_TO_DOUBLE(v);
>         return HASH_DOUBLE(dp);
>     }
>     if (JSVAL_IS_OBJECT(v))
>         return HASH_OBJECT(JSVAL_TO_OBJECT(v));
>     if (JSVAL_IS_BOOLEAN(v))
>         return HASH_BOOLEAN(JSVAL_TO_BOOLEAN(v));
>     return (JSHashNumber)v;
> }
227c141,144
< JS_STATIC_ASSERT(ATOM_ENTRY_FLAG_MASK < JSVAL_ALIGN);
---
> JS_STATIC_DLL_CALLBACK(intN)
> js_compare_atom_keys(const void *k1, const void *k2)
> {
>     jsval v1, v2;
229,265c146,162
< /*
<  * Helper macros to access and modify JSAtomHashEntry.
<  */
< #define TO_ATOM_ENTRY(hdr)              ((JSAtomHashEntry *) hdr)
< #define ATOM_ENTRY_KEY(entry)                                                 \
<     ((void *)((entry)->keyAndFlags & ~ATOM_ENTRY_FLAG_MASK))
< #define ATOM_ENTRY_FLAGS(entry)                                               \
<     ((uintN)((entry)->keyAndFlags & ATOM_ENTRY_FLAG_MASK))
< #define INIT_ATOM_ENTRY(entry, key)                                           \
<     ((void)((entry)->keyAndFlags = (jsuword)(key)))
< #define ADD_ATOM_ENTRY_FLAGS(entry, flags)                                    \
<     ((void)((entry)->keyAndFlags |= (jsuword)(flags)))
< #define CLEAR_ATOM_ENTRY_FLAGS(entry, flags)                                  \
<     ((void)((entry)->keyAndFlags &= ~(jsuword)(flags)))
< 
< JS_STATIC_DLL_CALLBACK(JSDHashNumber)
< HashDouble(JSDHashTable *table, const void *key);
< 
< JS_STATIC_DLL_CALLBACK(JSBool)
< MatchDouble(JSDHashTable *table, const JSDHashEntryHdr *hdr, const void *key);
< 
< JS_STATIC_DLL_CALLBACK(JSDHashNumber)
< HashString(JSDHashTable *table, const void *key);
< 
< JS_STATIC_DLL_CALLBACK(JSBool)
< MatchString(JSDHashTable *table, const JSDHashEntryHdr *hdr, const void *key);
< 
< static const JSDHashTableOps DoubleHashOps = {
<     JS_DHashAllocTable,
<     JS_DHashFreeTable,
<     HashDouble,
<     MatchDouble,
<     JS_DHashMoveEntryStub,
<     JS_DHashClearEntryStub,
<     JS_DHashFinalizeStub,
<     NULL
< };
---
>     v1 = (jsval)k1, v2 = (jsval)k2;
>     if (JSVAL_IS_STRING(v1) && JSVAL_IS_STRING(v2))
>         return !js_CompareStrings(JSVAL_TO_STRING(v1), JSVAL_TO_STRING(v2));
>     if (JSVAL_IS_DOUBLE(v1) && JSVAL_IS_DOUBLE(v2)) {
>         double d1 = *JSVAL_TO_DOUBLE(v1);
>         double d2 = *JSVAL_TO_DOUBLE(v2);
>         if (JSDOUBLE_IS_NaN(d1))
>             return JSDOUBLE_IS_NaN(d2);
> #if defined(XP_WIN) || defined(XP_OS2)
>         /* XXX MSVC miscompiles such that (NaN == 0) */
>         if (JSDOUBLE_IS_NaN(d2))
>             return JS_FALSE;
> #endif
>         return d1 == d2;
>     }
>     return v1 == v2;
> }
267,276c164,168
< static const JSDHashTableOps StringHashOps = {
<     JS_DHashAllocTable,
<     JS_DHashFreeTable,
<     HashString,
<     MatchString,
<     JS_DHashMoveEntryStub,
<     JS_DHashClearEntryStub,
<     JS_DHashFinalizeStub,
<     NULL
< };
---
> JS_STATIC_DLL_CALLBACK(int)
> js_compare_stub(const void *v1, const void *v2)
> {
>     return 1;
> }
278,279c170,175
< #define IS_DOUBLE_TABLE(table)      ((table)->ops == &DoubleHashOps)
< #define IS_STRING_TABLE(table)      ((table)->ops == &StringHashOps)
---
> JS_STATIC_DLL_CALLBACK(void *)
> js_alloc_atom_space(void *priv, size_t size)
> {
> 	XMEMTAG("js_alloc_atom_space");
>     return xmalloc(size);
> }
281c177,181
< #define IS_INITIALIZED_STATE(state) IS_DOUBLE_TABLE(&(state)->doubleAtoms)
---
> JS_STATIC_DLL_CALLBACK(void)
> js_free_atom_space(void *priv, void *item)
> {
>     xfree(item);
> }
283,284c183,184
< JS_STATIC_DLL_CALLBACK(JSDHashNumber)
< HashDouble(JSDHashTable *table, const void *key)
---
> JS_STATIC_DLL_CALLBACK(JSHashEntry *)
> js_alloc_atom(void *priv, const void *key)
286c186,187
<     jsdouble d;
---
>     JSAtomState *state = (JSAtomState *) priv;
>     JSAtom *atom;
288,290c189,200
<     JS_ASSERT(IS_DOUBLE_TABLE(table));
<     d = *(jsdouble *)key;
<     return JSDOUBLE_HI32(d) ^ JSDOUBLE_LO32(d);
---
> 	XMEMTAG("js_alloc_atom");
>     atom = (JSAtom *) xmalloc(sizeof(JSAtom));
>     if (!atom)
>         return NULL;
> #ifdef JS_THREADSAFE
>     state->tablegen++;
> #endif
>     atom->entry.key = key;
>     atom->entry.value = NULL;
>     atom->flags = 0;
>     atom->number = state->number++;
>     return &atom->entry;
293,294c203,204
< JS_STATIC_DLL_CALLBACK(JSDHashNumber)
< HashString(JSDHashTable *table, const void *key)
---
> JS_STATIC_DLL_CALLBACK(void)
> js_free_atom(void *priv, JSHashEntry *he, uintN flag)
296,297c206,211
<     JS_ASSERT(IS_STRING_TABLE(table));
<     return js_HashString((JSString *)key);
---
>     if (flag != HT_FREE_ENTRY)
>         return;
> #ifdef JS_THREADSAFE
>     ((JSAtomState *)priv)->tablegen++;
> #endif
>     xfree(he);
300,304c214,219
< JS_STATIC_DLL_CALLBACK(JSBool)
< MatchDouble(JSDHashTable *table, const JSDHashEntryHdr *hdr, const void *key)
< {
<     JSAtomHashEntry *entry = TO_ATOM_ENTRY(hdr);
<     jsdouble d1, d2;
---
> static JSHashAllocOps atom_alloc_ops = {
>     js_alloc_atom_space,    js_free_atom_space,
>     js_alloc_atom,          js_free_atom
> };
> 
> #define JS_ATOM_HASH_SIZE   1024
306,308c221,228
<     JS_ASSERT(IS_DOUBLE_TABLE(table));
<     if (entry->keyAndFlags == 0) {
<         /* See comments in MatchString. */
---
> JSBool
> js_InitAtomState(JSContext *cx, JSAtomState *state)
> {
>     state->table = JS_NewHashTable(JS_ATOM_HASH_SIZE, js_hash_atom_key,
>                                    js_compare_atom_keys, js_compare_stub,
>                                    &atom_alloc_ops, state);
>     if (!state->table) {
>         JS_ReportOutOfMemory(cx);
312,319c232,235
<     d1 = *(jsdouble *)ATOM_ENTRY_KEY(entry);
<     d2 = *(jsdouble *)key;
<     if (JSDOUBLE_IS_NaN(d1))
<         return JSDOUBLE_IS_NaN(d2);
< #if defined(XP_WIN)
<     /* XXX MSVC miscompiles such that (NaN == 0) */
<     if (JSDOUBLE_IS_NaN(d2))
<         return JS_FALSE;
---
>     state->runtime = cx->runtime;
> #ifdef JS_THREADSAFE
>     js_InitLock(&state->lock);
>     state->tablegen = 0;
321,327d236
<     return d1 == d2;
< }
< 
< JS_STATIC_DLL_CALLBACK(JSBool)
< MatchString(JSDHashTable *table, const JSDHashEntryHdr *hdr, const void *key)
< {
<     JSAtomHashEntry *entry = TO_ATOM_ENTRY(hdr);
329,342c238,239
<     JS_ASSERT(IS_STRING_TABLE(table));
<     if (entry->keyAndFlags == 0) {
<         /*
<          * This happens when js_AtomizeString adds a new hash entry and
<          * releases the lock but before it takes the lock the second time to
<          * initialize keyAndFlags for the entry.
<          *
<          * We always return false for such entries so JS_DHashTableOperate
<          * never finds them. We clean them during GC's sweep phase.
<          *
<          * It means that with a contested lock or when GC is triggered outside
<          * the lock we may end up adding two entries, but this is a price for
<          * simpler code.
<          */
---
>     if (!js_InitPinnedAtoms(cx, state)) {
>         js_FreeAtomState(cx, state);
345c242
<     return js_EqualStrings((JSString *)ATOM_ENTRY_KEY(entry), (JSString *)key);
---
>     return JS_TRUE;
348,356d244
< /*
<  * For a browser build from 2007-08-09 after the browser starts up there are
<  * just 55 double atoms, but over 15000 string atoms. Not to penalize more
<  * economical embeddings allocating too much memory initially we initialize
<  * atomized strings with just 1K entries.
<  */
< #define JS_STRING_HASH_COUNT   1024
< #define JS_DOUBLE_HASH_COUNT   64
< 
358c246
< js_InitAtomState(JSRuntime *rt)
---
> js_InitPinnedAtoms(JSContext *cx, JSAtomState *state)
360c248
<     JSAtomState *state = &rt->atomState;
---
>     uintN i;
362,374c250,299
<    /*
<     * The caller must zero the state before calling this function.
<     */
<     JS_ASSERT(!state->stringAtoms.ops);
<     JS_ASSERT(!state->doubleAtoms.ops);
< 
<     if (!JS_DHashTableInit(&state->stringAtoms, &StringHashOps,
<                            NULL, sizeof(JSAtomHashEntry),
<                            JS_DHASH_DEFAULT_CAPACITY(JS_STRING_HASH_COUNT))) {
<         state->stringAtoms.ops = NULL;
<         return JS_FALSE;
<     }
<     JS_ASSERT(IS_STRING_TABLE(&state->stringAtoms));
---
> #define FROB(lval,str)                                                        \
>     JS_BEGIN_MACRO                                                            \
>         if (!(state->lval = js_Atomize(cx, str, strlen(str), ATOM_PINNED)))   \
>             return JS_FALSE;                                                  \
>     JS_END_MACRO
> 
>     JS_ASSERT(sizeof js_type_str / sizeof js_type_str[0] == JSTYPE_LIMIT);
>     for (i = 0; i < JSTYPE_LIMIT; i++)
>         FROB(typeAtoms[i],        js_type_str[i]);
> 
>     FROB(booleanAtoms[0],         js_false_str);
>     FROB(booleanAtoms[1],         js_true_str);
>     FROB(nullAtom,                js_null_str);
> 
>     FROB(ArgumentsAtom,           js_Arguments_str);
>     FROB(ArrayAtom,               js_Array_str);
>     FROB(BooleanAtom,             js_Boolean_str);
>     FROB(CallAtom,                js_Call_str);
>     FROB(DateAtom,                js_Date_str);
>     FROB(ErrorAtom,               js_Error_str);
>     FROB(FunctionAtom,            js_Function_str);
>     FROB(MathAtom,                js_Math_str);
>     FROB(NumberAtom,              js_Number_str);
>     FROB(ObjectAtom,              js_Object_str);
>     FROB(RegExpAtom,              js_RegExp_str);
>     FROB(ScriptAtom,              js_Script_str);
>     FROB(StringAtom,              js_String_str);
>     FROB(anonymousAtom,           js_anonymous_str);
>     FROB(argumentsAtom,           js_arguments_str);
>     FROB(arityAtom,               js_arity_str);
>     FROB(calleeAtom,              js_callee_str);
>     FROB(callerAtom,              js_caller_str);
>     FROB(classPrototypeAtom,      js_class_prototype_str);
>     FROB(constructorAtom,         js_constructor_str);
>     FROB(countAtom,               js_count_str);
>     FROB(evalAtom,                js_eval_str);
>     FROB(getAtom,                 js_get_str);
>     FROB(getterAtom,              js_getter_str);
>     FROB(indexAtom,               js_index_str);
>     FROB(inputAtom,               js_input_str);
>     FROB(lengthAtom,              js_length_str);
>     FROB(nameAtom,                js_name_str);
>     FROB(parentAtom,              js_parent_str);
>     FROB(protoAtom,               js_proto_str);
>     FROB(setAtom,                 js_set_str);
>     FROB(setterAtom,              js_setter_str);
>     FROB(toSourceAtom,            js_toSource_str);
>     FROB(toStringAtom,            js_toString_str);
>     FROB(toLocaleStringAtom,      js_toLocaleString_str);
>     FROB(valueOfAtom,             js_valueOf_str);
376,384c301
<     if (!JS_DHashTableInit(&state->doubleAtoms, &DoubleHashOps,
<                            NULL, sizeof(JSAtomHashEntry),
<                            JS_DHASH_DEFAULT_CAPACITY(JS_DOUBLE_HASH_COUNT))) {
<         state->doubleAtoms.ops = NULL;
<         JS_DHashTableFinish(&state->stringAtoms);
<         state->stringAtoms.ops = NULL;
<         return JS_FALSE;
<     }
<     JS_ASSERT(IS_DOUBLE_TABLE(&state->doubleAtoms));
---
> #undef FROB
385a303,312
>     memset(&state->lazy, 0, sizeof state->lazy);
>     return JS_TRUE;
> }
> 
> /* NB: cx unused; js_FinishAtomState calls us with null cx. */
> void
> js_FreeAtomState(JSContext *cx, JSAtomState *state)
> {
>     if (state->table)
>         JS_HashTableDestroy(state->table);
387c314
<     js_InitLock(&state->lock);
---
>     js_FinishLock(&state->lock);
389,390c316
<     JS_ASSERT(IS_INITIALIZED_STATE(state));
<     return JS_TRUE;
---
>     memset(state, 0, sizeof *state);
393,395c319,325
< JS_STATIC_DLL_CALLBACK(JSDHashOperator)
< js_string_uninterner(JSDHashTable *table, JSDHashEntryHdr *hdr,
<                      uint32 number, void *arg)
---
> typedef struct UninternArgs {
>     JSRuntime   *rt;
>     jsatomid    leaks;
> } UninternArgs;
> 
> JS_STATIC_DLL_CALLBACK(intN)
> js_atom_uninterner(JSHashEntry *he, intN i, void *arg)
397,399c327,328
<     JSAtomHashEntry *entry = TO_ATOM_ENTRY(hdr);
<     JSRuntime *rt = (JSRuntime *)arg;
<     JSString *str;
---
>     JSAtom *atom;
>     UninternArgs *args;
401,411c330,336
<     /*
<      * Any string entry that remains at this point must be initialized, as the
<      * last GC should clean any uninitialized ones.
<      */
<     JS_ASSERT(IS_STRING_TABLE(table));
<     JS_ASSERT(entry->keyAndFlags != 0);
<     str = (JSString *)ATOM_ENTRY_KEY(entry);
< 
<     /* Pass null as context. */
<     js_FinalizeStringRT(rt, str, js_GetExternalStringGCType(str), NULL);
<     return JS_DHASH_NEXT;
---
>     atom = (JSAtom *)he;
>     args = (UninternArgs *)arg;
>     if (ATOM_IS_STRING(atom))
>         js_FinalizeStringRT(args->rt, ATOM_TO_STRING(atom));
>     else if (ATOM_IS_OBJECT(atom))
>         args->leaks++;
>     return HT_ENUMERATE_NEXT;
415c340
< js_FinishAtomState(JSRuntime *rt)
---
> js_FinishAtomState(JSAtomState *state)
417c342
<     JSAtomState *state = &rt->atomState;
---
>     UninternArgs args;
419,423c344
<     if (!IS_INITIALIZED_STATE(state)) {
<         /*
<          * We are called with uninitialized state when JS_NewRuntime fails and
<          * calls JS_DestroyRuntime on a partially initialized runtime.
<          */
---
>     if (!state->table)
425,433c346,348
<     }
< 
<     JS_DHashTableEnumerate(&state->stringAtoms, js_string_uninterner, rt);
<     JS_DHashTableFinish(&state->stringAtoms);
<     JS_DHashTableFinish(&state->doubleAtoms);
< 
< #ifdef JS_THREADSAFE
<     js_FinishLock(&state->lock);
< #endif
---
>     args.rt = state->runtime;
>     args.leaks = 0;
>     JS_HashTableEnumerateEntries(state->table, js_atom_uninterner, &args);
435,437c350,365
<     memset(state, JS_FREE_PATTERN, sizeof *state);
< #endif
< }
---
>     if (args.leaks != 0) {
>         fprintf(stderr,
> "JS engine warning: %lu atoms remain after destroying the JSRuntime.\n"
> "                   These atoms may point to freed memory. Things reachable\n"
> "                   through them have not been finalized.\n",
>                 (unsigned long) args.leaks);
>     }
> #endif
>     js_FreeAtomState(NULL, state);
> }
> 
> typedef struct MarkArgs {
>     uintN           gcflags;
>     JSGCThingMarker mark;
>     void            *data;
> } MarkArgs;
439,440c367,368
< JSBool
< js_InitCommonAtoms(JSContext *cx)
---
> JS_STATIC_DLL_CALLBACK(intN)
> js_atom_marker(JSHashEntry *he, intN i, void *arg)
442,444c370,372
<     JSAtomState *state = &cx->runtime->atomState;
<     uintN i;
<     JSAtom **atoms;
---
>     JSAtom *atom;
>     MarkArgs *args;
>     jsval key;
446,451c374,381
<     atoms = COMMON_ATOMS_START(state);
<     for (i = 0; i < JS_ARRAY_LENGTH(js_common_atom_names); i++, atoms++) {
<         *atoms = js_Atomize(cx, js_common_atom_names[i],
<                             strlen(js_common_atom_names[i]), ATOM_PINNED);
<         if (!*atoms)
<             return JS_FALSE;
---
>     atom = (JSAtom *)he;
>     args = (MarkArgs *)arg;
>     if ((atom->flags & (ATOM_PINNED | ATOM_INTERNED)) ||
>         (args->gcflags & GC_KEEP_ATOMS)) {
>         atom->flags |= ATOM_MARK;
>         key = ATOM_KEY(atom);
>         if (JSVAL_IS_GCTHING(key))
>             args->mark(JSVAL_TO_GCTHING(key), args->data);
453,454c383,384
<     JS_ASSERT((uint8 *)atoms - (uint8 *)state == LAZY_ATOM_OFFSET_START);
<     memset(atoms, 0, ATOM_OFFSET_LIMIT - LAZY_ATOM_OFFSET_START);
---
>     return HT_ENUMERATE_NEXT;
> }
456c386,397
<     return JS_TRUE;
---
> void
> js_MarkAtomState(JSAtomState *state, uintN gcflags, JSGCThingMarker mark,
>                  void *data)
> {
>     MarkArgs args;
> 
>     if (!state->table)
>         return;
>     args.gcflags = gcflags;
>     args.mark = mark;
>     args.data = data;
>     JS_HashTableEnumerateEntries(state->table, js_atom_marker, &args);
459,465c400,416
< JS_STATIC_DLL_CALLBACK(JSDHashOperator)
< js_atom_unpinner(JSDHashTable *table, JSDHashEntryHdr *hdr,
<                  uint32 number, void *arg)
< {
<     JS_ASSERT(IS_STRING_TABLE(table));
<     CLEAR_ATOM_ENTRY_FLAGS(TO_ATOM_ENTRY(hdr), ATOM_PINNED);
<     return JS_DHASH_NEXT;
---
> JS_STATIC_DLL_CALLBACK(intN)
> js_atom_sweeper(JSHashEntry *he, intN i, void *arg)
> {
>     JSAtom *atom;
>     JSAtomState *state;
> 
>     atom = (JSAtom *)he;
>     if (atom->flags & ATOM_MARK) {
>         atom->flags &= ~ATOM_MARK;
>         state = (JSAtomState *)arg;
>         state->liveAtoms++;
>         return HT_ENUMERATE_NEXT;
>     }
>     JS_ASSERT((atom->flags & (ATOM_PINNED | ATOM_INTERNED)) == 0);
>     atom->entry.key = NULL;
>     atom->flags = 0;
>     return HT_ENUMERATE_REMOVE;
469c420
< js_FinishCommonAtoms(JSContext *cx)
---
> js_SweepAtomState(JSAtomState *state)
471,477c422,424
<     JSAtomState *state = &cx->runtime->atomState;
< 
<     JS_DHashTableEnumerate(&state->stringAtoms, js_atom_unpinner, NULL);
< #ifdef DEBUG
<     memset(COMMON_ATOMS_START(state), JS_FREE_PATTERN,
<            ATOM_OFFSET_LIMIT - ATOM_OFFSET_START);
< #endif
---
>     state->liveAtoms = 0;
>     if (state->table)
>         JS_HashTableEnumerateEntries(state->table, js_atom_sweeper, state);
480,514c427,434
< JS_STATIC_DLL_CALLBACK(JSDHashOperator)
< js_locked_atom_tracer(JSDHashTable *table, JSDHashEntryHdr *hdr,
<                       uint32 number, void *arg)
< {
<     JSAtomHashEntry *entry = TO_ATOM_ENTRY(hdr);
<     JSTracer *trc = (JSTracer *)arg;
< 
<     if (entry->keyAndFlags == 0) {
<         /* Ignore uninitialized entries during tracing. */
<         return JS_DHASH_NEXT;
<     }
<     JS_SET_TRACING_INDEX(trc, "locked_atom", (size_t)number);
<     JS_CallTracer(trc, ATOM_ENTRY_KEY(entry),
<                   IS_STRING_TABLE(table) ? JSTRACE_STRING : JSTRACE_DOUBLE);
<     return JS_DHASH_NEXT;
< }
< 
< JS_STATIC_DLL_CALLBACK(JSDHashOperator)
< js_pinned_atom_tracer(JSDHashTable *table, JSDHashEntryHdr *hdr,
<                         uint32 number, void *arg)
< {
<     JSAtomHashEntry *entry = TO_ATOM_ENTRY(hdr);
<     JSTracer *trc = (JSTracer *)arg;
<     uintN flags = ATOM_ENTRY_FLAGS(entry);
< 
<     JS_ASSERT(IS_STRING_TABLE(table));
<     if (flags & (ATOM_PINNED | ATOM_INTERNED)) {
<         JS_SET_TRACING_INDEX(trc,
<                              flags & ATOM_PINNED
<                              ? "pinned_atom"
<                              : "interned_atom",
<                              (size_t)number);
<         JS_CallTracer(trc, ATOM_ENTRY_KEY(entry), JSTRACE_STRING);
<     }
<     return JS_DHASH_NEXT;
---
> JS_STATIC_DLL_CALLBACK(intN)
> js_atom_unpinner(JSHashEntry *he, intN i, void *arg)
> {
>     JSAtom *atom;
> 
>     atom = (JSAtom *)he;
>     atom->flags &= ~ATOM_PINNED;
>     return HT_ENUMERATE_NEXT;
518c438,445
< js_TraceAtomState(JSTracer *trc, JSBool allAtoms)
---
> js_UnpinPinnedAtoms(JSAtomState *state)
> {
>     if (state->table)
>         JS_HashTableEnumerateEntries(state->table, js_atom_unpinner, NULL);
> }
> 
> static JSAtom *
> js_AtomizeHashedKey(JSContext *cx, jsval key, JSHashNumber keyHash, uintN flags)
520a448,450
>     JSHashTable *table;
>     JSHashEntry *he, **hep;
>     JSAtom *atom;
522,527c452,462
<     state = &trc->context->runtime->atomState;
<     if (allAtoms) {
<         JS_DHashTableEnumerate(&state->doubleAtoms, js_locked_atom_tracer, trc);
<         JS_DHashTableEnumerate(&state->stringAtoms, js_locked_atom_tracer, trc);
<     } else {
<         JS_DHashTableEnumerate(&state->stringAtoms, js_pinned_atom_tracer, trc);
---
>     state = &cx->runtime->atomState;
>     JS_LOCK(&state->lock, cx);
>     table = state->table;
>     hep = JS_HashTableRawLookup(table, keyHash, (void *)key);
>     if ((he = *hep) == NULL) {
>         he = JS_HashTableRawAdd(table, hep, keyHash, (void *)key, NULL);
>         if (!he) {
>             JS_ReportOutOfMemory(cx);
>             atom = NULL;
>             goto out;
>         }
528a464,470
> 
>     atom = (JSAtom *)he;
>     atom->flags |= flags;
>     cx->lastAtom = atom;
> out:
>     JS_UNLOCK(&state->lock,cx);
>     return atom;
531,549c473,482
< JS_STATIC_DLL_CALLBACK(JSDHashOperator)
< js_atom_sweeper(JSDHashTable *table, JSDHashEntryHdr *hdr,
<                 uint32 number, void *arg)
< {
<     JSAtomHashEntry *entry = TO_ATOM_ENTRY(hdr);
<     JSContext *cx = (JSContext *)arg;
< 
<     /* Remove uninitialized entries.  */
<     if (entry->keyAndFlags == 0)
<         return JS_DHASH_REMOVE;
< 
<     if (ATOM_ENTRY_FLAGS(entry) & (ATOM_PINNED | ATOM_INTERNED)) {
<         /* Pinned or interned key cannot be finalized. */
<         JS_ASSERT(!js_IsAboutToBeFinalized(cx, ATOM_ENTRY_KEY(entry)));
<     } else if (js_IsAboutToBeFinalized(cx, ATOM_ENTRY_KEY(entry))) {
<         /* Remove entries with things about to be GC'ed. */
<         return JS_DHASH_REMOVE;
<     }
<     return JS_DHASH_NEXT;
---
> JSAtom *
> js_AtomizeObject(JSContext *cx, JSObject *obj, uintN flags)
> {
>     jsval key;
>     JSHashNumber keyHash;
> 
>     /* XXX must be set in the following order or MSVC1.52 will crash */
>     keyHash = HASH_OBJECT(obj);
>     key = OBJECT_TO_JSVAL(obj);
>     return js_AtomizeHashedKey(cx, key, keyHash, flags);
552,553c485,486
< void
< js_SweepAtomState(JSContext *cx)
---
> JSAtom *
> js_AtomizeBoolean(JSContext *cx, JSBool b, uintN flags)
555c488,489
<     JSAtomState *state = &cx->runtime->atomState;
---
>     jsval key;
>     JSHashNumber keyHash;
557,558c491,494
<     JS_DHashTableEnumerate(&state->doubleAtoms, js_atom_sweeper, cx);
<     JS_DHashTableEnumerate(&state->stringAtoms, js_atom_sweeper, cx);
---
>     key = BOOLEAN_TO_JSVAL(b);
>     keyHash = HASH_BOOLEAN(b);
>     return js_AtomizeHashedKey(cx, key, keyHash, flags);
> }
560,565c496,504
<     /*
<      * Optimize for simplicity and mutate table generation numbers even if the
<      * sweeper has not removed any entries.
<      */
<     state->doubleAtoms.generation++;
<     state->stringAtoms.generation++;
---
> JSAtom *
> js_AtomizeInt(JSContext *cx, jsint i, uintN flags)
> {
>     jsval key;
>     JSHashNumber keyHash;
> 
>     key = INT_TO_JSVAL(i);
>     keyHash = HASH_INT(i);
>     return js_AtomizeHashedKey(cx, key, keyHash, flags);
567a507,510
> /* Worst-case alignment grain and aligning macro for 2x-sized buffer. */
> #define ALIGNMENT(t)    JS_MAX(JSVAL_ALIGN, sizeof(t))
> #define ALIGN(b,t)      ((t*) &(b)[ALIGNMENT(t) - (jsuword)(b) % ALIGNMENT(t)])
> 
569c512
< js_AtomizeDouble(JSContext *cx, jsdouble d)
---
> js_AtomizeDouble(JSContext *cx, jsdouble d, uintN flags)
570a514,516
>     jsdouble *dp;
>     JSHashNumber keyHash;
>     jsval key;
572,576c518,521
<     JSDHashTable *table;
<     JSAtomHashEntry *entry;
<     uint32 gen;
<     jsdouble *key;
<     jsval v;
---
>     JSHashTable *table;
>     JSHashEntry *he, **hep;
>     JSAtom *atom;
>     char buf[2 * ALIGNMENT(double)];
577a523,526
>     dp = ALIGN(buf, double);
>     *dp = d;
>     keyHash = HASH_DOUBLE(dp);
>     key = DOUBLE_TO_JSVAL(dp);
579,580d527
<     table = &state->doubleAtoms;
< 
582,590c529,536
<     entry = TO_ATOM_ENTRY(JS_DHashTableOperate(table, &d, JS_DHASH_ADD));
<     if (!entry)
<         goto failed_hash_add;
<     if (entry->keyAndFlags == 0) {
<         gen = ++table->generation;
<         JS_UNLOCK(&state->lock, cx);
< 
<         key = js_NewDouble(cx, d, 0);
<         if (!key)
---
>     table = state->table;
>     hep = JS_HashTableRawLookup(table, keyHash, (void *)key);
>     if ((he = *hep) == NULL) {
> #ifdef JS_THREADSAFE
>         uint32 gen = state->tablegen;
> #endif
>         JS_UNLOCK(&state->lock,cx);
>         if (!js_NewDoubleValue(cx, d, &key))
592d537
< 
594,603c539,552
<         if (table->generation == gen) {
<             JS_ASSERT(entry->keyAndFlags == 0);
<         } else {
<             entry = TO_ATOM_ENTRY(JS_DHashTableOperate(table, key,
<                                                        JS_DHASH_ADD));
<             if (!entry)
<                 goto failed_hash_add;
<             if (entry->keyAndFlags != 0)
<                 goto finish;
<             ++table->generation;
---
> #ifdef JS_THREADSAFE
>         if (state->tablegen != gen) {
>             hep = JS_HashTableRawLookup(table, keyHash, (void *)key);
>             if ((he = *hep) != NULL) {
>                 atom = (JSAtom *)he;
>                 goto out;
>             }
>         }
> #endif
>         he = JS_HashTableRawAdd(table, hep, keyHash, (void *)key, NULL);
>         if (!he) {
>             JS_ReportOutOfMemory(cx);
>             atom = NULL;
>             goto out;
605d553
<         INIT_ATOM_ENTRY(entry, key);
608,610c556,559
<   finish:
<     v = DOUBLE_TO_JSVAL((jsdouble *)ATOM_ENTRY_KEY(entry));
<     cx->weakRoots.lastAtom = v;
---
>     atom = (JSAtom *)he;
>     atom->flags |= flags;
>     cx->lastAtom = atom;
> out:
612,618c561
< 
<     return (JSAtom *)v;
< 
<   failed_hash_add:
<     JS_UNLOCK(&state->lock,cx);
<     JS_ReportOutOfMemory(cx);
<     return NULL;
---
>     return atom;
624c567,568
<     jsval v;
---
>     JSHashNumber keyHash;
>     jsval key;
626,632c570,572
<     JSDHashTable *table;
<     JSAtomHashEntry *entry;
<     JSString *key;
<     uint32 gen;
< 
<     JS_ASSERT(!(flags & ~(ATOM_PINNED|ATOM_INTERNED|ATOM_TMPSTR|ATOM_NOCOPY)));
<     JS_ASSERT_IF(flags & ATOM_NOCOPY, flags & ATOM_TMPSTR);
---
>     JSHashTable *table;
>     JSHashEntry *he, **hep;
>     JSAtom *atom;
633a574,575
>     keyHash = js_HashString(str);
>     key = STRING_TO_JSVAL(str);
635,636d576
<     table = &state->stringAtoms;
< 
638,653c578,592
<     entry = TO_ATOM_ENTRY(JS_DHashTableOperate(table, str, JS_DHASH_ADD));
<     if (!entry)
<         goto failed_hash_add;
<     if (entry->keyAndFlags != 0) {
<         key = (JSString *)ATOM_ENTRY_KEY(entry);
<     } else {
<         /*
<          * We created a new hashtable entry. Unless str is already allocated
<          * from the GC heap and flat, we have to release state->lock as
<          * string construction is a complex operation. For example, it can
<          * trigger GC which may rehash the table and make the entry invalid.
<          */
<         ++table->generation;
<         if (!(flags & ATOM_TMPSTR) && JSSTRING_IS_FLAT(str)) {
<             JSFLATSTR_CLEAR_MUTABLE(str);
<             key = str;
---
>     table = state->table;
>     hep = JS_HashTableRawLookup(table, keyHash, (void *)key);
>     if ((he = *hep) == NULL) {
> #ifdef JS_THREADSAFE
>         uint32 gen = state->tablegen;
>         JS_UNLOCK(&state->lock, cx);
> #endif
> 
>         if (flags & ATOM_TMPSTR) {
>             str = (flags & ATOM_NOCOPY)
>                   ? js_NewString(cx, str->chars, str->length, 0)
>                   : js_NewStringCopyN(cx, str->chars, str->length, 0);
>             if (!str)
>                 return NULL;
>             key = STRING_TO_JSVAL(str);
655,656c594,596
<             gen = table->generation;
<             JS_UNLOCK(&state->lock, cx);
---
>             if (!JS_MakeStringImmutable(cx, str))
>                 return NULL;
>         }
658,677c598,606
<             if (flags & ATOM_TMPSTR) {
<                 if (flags & ATOM_NOCOPY) {
<                     key = js_NewString(cx, JSFLATSTR_CHARS(str),
<                                        JSFLATSTR_LENGTH(str));
<                     if (!key)
<                         return NULL;
< 
<                     /* Finish handing off chars to the GC'ed key string. */
<                     str->u.chars = NULL;
<                 } else {
<                     key = js_NewStringCopyN(cx, JSFLATSTR_CHARS(str),
<                                             JSFLATSTR_LENGTH(str));
<                     if (!key)
<                         return NULL;
<                 }
<            } else {
<                 JS_ASSERT(JSSTRING_IS_DEPENDENT(str));
<                 if (!js_UndependString(cx, str))
<                     return NULL;
<                 key = str;
---
> #ifdef JS_THREADSAFE
>         JS_LOCK(&state->lock, cx);
>         if (state->tablegen != gen) {
>             hep = JS_HashTableRawLookup(table, keyHash, (void *)key);
>             if ((he = *hep) != NULL) {
>                 atom = (JSAtom *)he;
>                 if (flags & ATOM_NOCOPY)
>                     str->chars = NULL;
>                 goto out;
678a608,609
>         }
> #endif
680,693c611,615
<             JS_LOCK(&state->lock, cx);
<             if (table->generation == gen) {
<                 JS_ASSERT(entry->keyAndFlags == 0);
<             } else {
<                 entry = TO_ATOM_ENTRY(JS_DHashTableOperate(table, key,
<                                                            JS_DHASH_ADD));
<                 if (!entry)
<                     goto failed_hash_add;
<                 if (entry->keyAndFlags != 0) {
<                     key = (JSString *)ATOM_ENTRY_KEY(entry);
<                     goto finish;
<                 }
<                 ++table->generation;
<             }
---
>         he = JS_HashTableRawAdd(table, hep, keyHash, (void *)key, NULL);
>         if (!he) {
>             JS_ReportOutOfMemory(cx);
>             atom = NULL;
>             goto out;
695,696d616
<         INIT_ATOM_ENTRY(entry, key);
<         JSFLATSTR_SET_ATOMIZED(key);
699,707c619,622
<   finish:
<     ADD_ATOM_ENTRY_FLAGS(entry, flags & (ATOM_PINNED | ATOM_INTERNED));
<     JS_ASSERT(JSSTRING_IS_ATOMIZED(key));
<     v = STRING_TO_JSVAL(key);
<     cx->weakRoots.lastAtom = v;
<     JS_UNLOCK(&state->lock, cx);
<     return (JSAtom *)v;
< 
<   failed_hash_add:
---
>     atom = (JSAtom *)he;
>     atom->flags |= flags & (ATOM_PINNED | ATOM_INTERNED);
>     cx->lastAtom = atom;
> out:
709,710c624
<     JS_ReportOutOfMemory(cx);
<     return NULL;
---
>     return atom;
713c627,628
< JSAtom *
---
> #ifdef _UTF8
> JS_FRIEND_API(JSAtom *)
717c632
<     JSString str;
---
>     JSString *str;
718a634,635
>     char buf[2 * ALIGNMENT(JSString)];
> 	int wLength;
729d645
<     size_t inflatedLength = ATOMIZE_BUF_MAX - 1;
731,733c647,652
<     if (length < ATOMIZE_BUF_MAX) {
<         js_InflateStringToBuffer(cx, bytes, length, inflated, &inflatedLength);
<         inflated[inflatedLength] = 0;
---
> 	wLength = js_InflateStringToBuffer(NULL, bytes, length);
>     if (wLength >= 0 && wLength < ATOMIZE_BUF_MAX) {
>         wLength = js_InflateStringToBuffer(inflated, bytes, length);
> 		if (wLength <0 ) {
> 			return NULL;
> 		}
736,737c655
<         inflatedLength = length;
<         chars = js_InflateString(cx, bytes, &inflatedLength);
---
>         chars = js_InflateString(cx, bytes, length, &wLength);
743,745c661,666
<     JSFLATSTR_INIT(&str, (jschar *)chars, inflatedLength);
<     atom = js_AtomizeString(cx, &str, ATOM_TMPSTR | flags);
<     if (chars != inflated && str.u.chars)
---
>     str = ALIGN(buf, JSString);
> 
>     str->chars = chars;
>     str->length = wLength;
>     atom = js_AtomizeString(cx, str, ATOM_TMPSTR | flags);
>     if (chars != inflated && (!atom || ATOM_TO_STRING(atom)->chars != chars))
749,751c670,672
< 
< JSAtom *
< js_AtomizeChars(JSContext *cx, const jschar *chars, size_t length, uintN flags)
---
> #else //#ifdef _UTF8
> JS_FRIEND_API(JSAtom *)
> js_Atomize(JSContext *cx, const char *bytes, size_t length, uintN flags)
753,757c674,677
<     JSString str;
< 
<     JSFLATSTR_INIT(&str, (jschar *)chars, length);
<     return js_AtomizeString(cx, &str, ATOM_TMPSTR | flags);
< }
---
>     jschar *chars;
>     JSString *str;
>     JSAtom *atom;
>     char buf[2 * ALIGNMENT(JSString)];
759,764c679,687
< JSAtom *
< js_GetExistingStringAtom(JSContext *cx, const jschar *chars, size_t length)
< {
<     JSString str, *str2;
<     JSAtomState *state;
<     JSDHashEntryHdr *hdr;
---
>     /*
>      * Avoiding the malloc in js_InflateString on shorter strings saves us
>      * over 20,000 malloc calls on mozilla browser startup. This compares to
>      * only 131 calls where the string is longer than a 31 char (net) buffer.
>      * The vast majority of atomized strings are already in the hashtable. So
>      * js_AtomizeString rarely has to copy the temp string we make.
>      */
> #define ATOMIZE_BUF_MAX 32
>     jschar inflated[ATOMIZE_BUF_MAX];
766,767c689,697
<     JSFLATSTR_INIT(&str, (jschar *)chars, length);
<     state = &cx->runtime->atomState;
---
>     if (length < ATOMIZE_BUF_MAX) {
>         js_InflateStringToBuffer(inflated, bytes, length);
>         chars = inflated;
>     } else {
>         chars = js_InflateString(cx, bytes, length);
>         if (!chars)
>             return NULL;
>         flags |= ATOM_NOCOPY;
>     }
769,774c699
<     JS_LOCK(&state->lock, cx);
<     hdr = JS_DHashTableOperate(&state->stringAtoms, &str, JS_DHASH_LOOKUP);
<     str2 = JS_DHASH_ENTRY_IS_BUSY(hdr)
<            ? (JSString *)ATOM_ENTRY_KEY(TO_ATOM_ENTRY(hdr))
<            : NULL;
<     JS_UNLOCK(&state->lock, cx);
---
>     str = ALIGN(buf, JSString);
776c701,706
<     return str2 ? (JSAtom *)STRING_TO_JSVAL(str2) : NULL;
---
>     str->chars = chars;
>     str->length = length;
>     atom = js_AtomizeString(cx, str, ATOM_TMPSTR | flags);
>     if (chars != inflated && (!atom || ATOM_TO_STRING(atom)->chars != chars))
>         JS_free(cx, chars);
>     return atom;
777a708
> #endif //#ifdef _UTF8
779,782d709
< JSBool
< js_AtomizePrimitiveValue(JSContext *cx, jsval v, JSAtom **atomp)
< {
<     JSAtom *atom;
784,802c711,712
<     if (JSVAL_IS_STRING(v)) {
<         atom = js_AtomizeString(cx, JSVAL_TO_STRING(v), 0);
<         if (!atom)
<             return JS_FALSE;
<     } else if (JSVAL_IS_DOUBLE(v)) {
<         atom = js_AtomizeDouble(cx, *JSVAL_TO_DOUBLE(v));
<         if (!atom)
<             return JS_FALSE;
<     } else {
<         JS_ASSERT(JSVAL_IS_INT(v) || v == JSVAL_TRUE || v == JSVAL_FALSE ||
<                   v == JSVAL_NULL || v == JSVAL_VOID);
<         atom = (JSAtom *)v;
<     }
<     *atomp = atom;
<     return JS_TRUE;
< }
< 
< JSBool
< js_ValueToStringId(JSContext *cx, jsval v, jsid *idp)
---
> JS_FRIEND_API(JSAtom *)
> js_AtomizeChars(JSContext *cx, const jschar *chars, size_t length, uintN flags)
805c715
<     JSAtom *atom;
---
>     char buf[2 * ALIGNMENT(JSString)];
807,830c717,720
<     /*
<      * Optimize for the common case where v is an already-atomized string. The
<      * comment in jsstr.h before the JSSTRING_SET_ATOMIZED macro's definition
<      * explains why this is thread-safe. The extra rooting via lastAtom (which
<      * would otherwise be done in js_js_AtomizeString) ensures the caller that
<      * the resulting id at is least weakly rooted.
<      */
<     if (JSVAL_IS_STRING(v)) {
<         str = JSVAL_TO_STRING(v);
<         if (JSSTRING_IS_ATOMIZED(str)) {
<             cx->weakRoots.lastAtom = v;
<             *idp = ATOM_TO_JSID((JSAtom *) v);
<             return JS_TRUE;
<         }
<     } else {
<         str = js_ValueToString(cx, v);
<         if (!str)
<             return JS_FALSE;
<     }
<     atom = js_AtomizeString(cx, str, 0);
<     if (!atom)
<         return JS_FALSE;
<     *idp = ATOM_TO_JSID(atom);
<     return JS_TRUE;
---
>     str = ALIGN(buf, JSString);
>     str->chars = (jschar *)chars;
>     str->length = length;
>     return js_AtomizeString(cx, str, ATOM_TMPSTR | flags);
833,864c723,736
< #ifdef DEBUG
< 
< JS_STATIC_DLL_CALLBACK(JSDHashOperator)
< atom_dumper(JSDHashTable *table, JSDHashEntryHdr *hdr,
<             uint32 number, void *arg)
< {
<     JSAtomHashEntry *entry = TO_ATOM_ENTRY(hdr);
<     FILE *fp = (FILE *)arg;
<     void *key;
<     uintN flags;
< 
<     fprintf(fp, "%3u %08x ", number, (uintN)entry->hdr.keyHash);
<     if (entry->keyAndFlags == 0) {
<         fputs("<uninitialized>", fp);
<     } else {
<         key = ATOM_ENTRY_KEY(entry);
<         if (IS_DOUBLE_TABLE(table)) {
<             fprintf(fp, "%.16g", *(jsdouble *)key);
<         } else {
<             JS_ASSERT(IS_STRING_TABLE(table));
<             js_FileEscapedString(fp, (JSString *)key, '"');
<         }
<         flags = ATOM_ENTRY_FLAGS(entry);
<         if (flags != 0) {
<             fputs((flags & (ATOM_PINNED | ATOM_INTERNED))
<                   ? " pinned | interned"
<                   : (flags & ATOM_PINNED) ? " pinned" : " interned",
<                   fp);
<         }
<     }
<     putc('\n', fp);
<     return JS_DHASH_NEXT;
---
> JSAtom *
> js_AtomizeValue(JSContext *cx, jsval value, uintN flags)
> {
>     if (JSVAL_IS_STRING(value))
>         return js_AtomizeString(cx, JSVAL_TO_STRING(value), flags);
>     if (JSVAL_IS_INT(value))
>         return js_AtomizeInt(cx, JSVAL_TO_INT(value), flags);
>     if (JSVAL_IS_DOUBLE(value))
>         return js_AtomizeDouble(cx, *JSVAL_TO_DOUBLE(value), flags);
>     if (JSVAL_IS_OBJECT(value))
>         return js_AtomizeObject(cx, JSVAL_TO_OBJECT(value), flags);
>     if (JSVAL_IS_BOOLEAN(value))
>         return js_AtomizeBoolean(cx, JSVAL_TO_BOOLEAN(value), flags);
>     return js_AtomizeHashedKey(cx, value, (JSHashNumber)value, flags);
867,868c739,740
< JS_FRIEND_API(void)
< js_DumpAtoms(JSContext *cx, FILE *fp)
---
> JSAtom *
> js_ValueToStringAtom(JSContext *cx, jsval v)
870,877c742
<     JSAtomState *state = &cx->runtime->atomState;
< 
<     fprintf(fp, "stringAtoms table contents:\n");
<     JS_DHashTableEnumerate(&state->stringAtoms, atom_dumper, fp);
< #ifdef JS_DHASHMETER
<     JS_DHashTableDumpMeter(&state->stringAtoms, atom_dumper, fp);
< #endif
<     putc('\n', fp);
---
>     JSString *str;
879,884c744,747
<     fprintf(fp, "doubleAtoms table contents:\n");
<     JS_DHashTableEnumerate(&state->doubleAtoms, atom_dumper, fp);
< #ifdef JS_DHASHMETER
<     JS_DHashTableDumpMeter(&state->doubleAtoms, atom_dumper, fp);
< #endif
<     putc('\n', fp);
---
>     str = js_ValueToString(cx, v);
>     if (!str)
>         return NULL;
>     return js_AtomizeString(cx, str, 0);
887,888d749
< #endif
< 
892,893c753,754
<     const JSAtom *atom = (const JSAtom *) key;
<     return ATOM_HASH(atom);
---
>     const JSAtom *atom = key;
>     return atom->number;
899c760
<     JSContext *cx = (JSContext *) priv;
---
>     JSContext *cx = priv;
904c765
<         js_ReportOutOfScriptQuota(cx);
---
>         JS_ReportOutOfMemory(cx);
916c777
<     JSContext *cx = (JSContext *) priv;
---
>     JSContext *cx = priv;
921c782
<         js_ReportOutOfScriptQuota(cx);
---
>         JS_ReportOutOfMemory(cx);
945c806
<         if (al->count < 10) {
---
>         if (al->count <= 5) {
952,953c813,814
<             ale->entry.next = al->list;
<             al->list = &ale->entry;
---
>             ALE_SET_NEXT(ale, al->list);
>             al->list = ale;
959c820
<                 al->table = JS_NewHashTable(al->count + 1, js_hash_atom_ptr,
---
>                 al->table = JS_NewHashTable(8, js_hash_atom_ptr,
965,970d825
<                 /*
<                  * Set ht->nentries explicitly, because we are moving entries
<                  * from al to ht, not calling JS_HashTable(Raw|)Add.
<                  */
<                 al->table->nentries = al->count;
< 
972c827
<                 for (ale2 = (JSAtomListElement *)al->list; ale2; ale2 = next) {
---
>                 for (ale2 = al->list; ale2; ale2 = next) {
974c829
<                     ale2->entry.keyHash = ATOM_HASH(ALE_ATOM(ale2));
---
>                     ale2->entry.keyHash = ALE_ATOM(ale2)->number;
977c832
<                     ale2->entry.next = *hep;
---
>                     ALE_SET_NEXT(ale2, *hep);
983c838
<                 hep = JS_HashTableRawLookup(al->table, ATOM_HASH(atom), atom);
---
>                 hep = JS_HashTableRawLookup(al->table, atom->number, atom);
988,989c843
<                   JS_HashTableRawAdd(al->table, hep, ATOM_HASH(atom), atom,
<                                      NULL);
---
>                 JS_HashTableRawAdd(al->table, hep, atom->number, atom, NULL);
998a853,871
> JS_FRIEND_API(JSAtom *)
> js_GetAtom(JSContext *cx, JSAtomMap *map, jsatomid i)
> {
>     JSAtom *atom;
>     static JSAtom dummy;
> 
>     JS_ASSERT(map->vector && i < map->length);
>     if (!map->vector || i >= map->length) {
>         char numBuf[12];
>         JS_snprintf(numBuf, sizeof numBuf, "%lu", (unsigned long)i);
>         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
>                              JSMSG_BAD_ATOMIC_NUMBER, numBuf);
>         return &dummy;
>     }
>     atom = map->vector[i];
>     JS_ASSERT(atom);
>     return atom;
> }
> 
1003c876
<     JSAtom **vector = (JSAtom **) arg;
---
>     JSAtom **vector = arg;
1010,1011c883,884
< static jsrefcount js_atom_map_count;
< static jsrefcount js_atom_map_hash_table_count;
---
> jsrefcount js_atom_map_count;
> jsrefcount js_atom_map_hash_table_count;
1014c887
< void
---
> JS_FRIEND_API(JSBool)
1021,1022d893
<     /* Map length must already be initialized. */
<     JS_ASSERT(al->count == map->length);
1026c897
<     ale = (JSAtomListElement *)al->list;
---
>     ale = al->list;
1028,1029c899,901
<         JS_ASSERT(!map->vector);
<         return;
---
>         map->vector = NULL;
>         map->length = 0;
>         return JS_TRUE;
1033c905,914
<     vector = map->vector;
---
>     if (count >= ATOM_INDEX_LIMIT) {
>         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
>                              JSMSG_TOO_MANY_LITERALS);
>         return JS_FALSE;
>     }
> 	XMEMTAG("js_InitAtomMap");
>     vector = (JSAtom **) JS_malloc(cx, (size_t) count * sizeof *vector);
>     if (!vector)
>         return JS_FALSE;
> 
1044a926,939
> 
>     map->vector = vector;
>     map->length = (jsatomid)count;
>     return JS_TRUE;
> }
> 
> JS_FRIEND_API(void)
> js_FreeAtomMap(JSContext *cx, JSAtomMap *map)
> {
>     if (map->vector) {
>         JS_free(cx, map->vector);
>         map->vector = NULL;
>     }
>     map->length = 0;
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsatom.h /Volumes/Swap/js_D11/src/jsatom.h
3,4c3,6
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
6,14c8,11
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,24c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
26,36c21
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
---
>  * Contributor(s): 
38c23,33
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
46d40
< #include "jsconfig.h"
49d42
< #include "jsdhash.h"
60,63c53,63
< #define ATOM_PINNED     0x1       /* atom is pinned against GC */
< #define ATOM_INTERNED   0x2       /* pinned variant for JS_Intern* API */
< #define ATOM_NOCOPY     0x4       /* don't copy atom string bytes */
< #define ATOM_TMPSTR     0x8       /* internal, to avoid extra string */
---
> #define ATOM_PINNED     0x01            /* atom is pinned against GC */
> #define ATOM_INTERNED   0x02            /* pinned variant for JS_Intern* API */
> #define ATOM_MARK       0x04            /* atom is reachable via GC */
> #define ATOM_NOCOPY     0x40            /* don't copy atom string bytes */
> #define ATOM_TMPSTR     0x80            /* internal, to avoid extra string */
> 
> struct JSAtom {
>     JSHashEntry         entry;          /* key is jsval, value keyword info */
>     uint32              flags;          /* pinned, interned, and mark flags */
>     jsatomid            number;         /* atom serial number and hash code */
> };
65c65,69
< #define ATOM_KEY(atom)            ((jsval)(atom))
---
> #define ATOM_KEY(atom)            ((jsval)(atom)->entry.key)
> #define ATOM_IS_OBJECT(atom)      JSVAL_IS_OBJECT(ATOM_KEY(atom))
> #define ATOM_TO_OBJECT(atom)      JSVAL_TO_OBJECT(ATOM_KEY(atom))
> #define ATOM_IS_INT(atom)         JSVAL_IS_INT(ATOM_KEY(atom))
> #define ATOM_TO_INT(atom)         JSVAL_TO_INT(ATOM_KEY(atom))
69a74,76
> #define ATOM_IS_BOOLEAN(atom)     JSVAL_IS_BOOLEAN(ATOM_KEY(atom))
> #define ATOM_TO_BOOLEAN(atom)     JSVAL_TO_BOOLEAN(ATOM_KEY(atom))
> #define ATOM_BYTES(atom)          JS_GetStringBytes(ATOM_TO_STRING(atom))
71,89c78,79
< JS_STATIC_ASSERT(sizeof(JSHashNumber) == 4);
< JS_STATIC_ASSERT(sizeof(JSAtom *) == JS_BYTES_PER_WORD);
< 
< #if JS_BYTES_PER_WORD == 4
< # define ATOM_HASH(atom)          ((JSHashNumber)(atom) >> 2)
< #elif JS_BYTES_PER_WORD == 8
< # define ATOM_HASH(atom)          (((JSHashNumber)(jsuword)(atom) >> 3) ^     \
<                                    (JSHashNumber)((jsuword)(atom) >> 32))
< #else
< # error "Unsupported configuration"
< #endif
< 
< /*
<  * Return a printable, lossless char[] representation of a string-type atom.
<  * The lifetime of the result extends at least until the next GC activation,
<  * longer if cx's string newborn root is not overwritten.
<  */
< extern const char *
< js_AtomToPrintableString(JSContext *cx, JSAtom *atom);
---
> #define ATOM_KEYWORD(atom)        ((struct keyword *)(atom)->entry.value)
> #define ATOM_SET_KEYWORD(atom,kw) ((atom)->entry.value = (kw))
96,98c86,87
< #define ALE_INDEX(ale)  ((jsatomid) JS_PTR_TO_UINT32((ale)->entry.value))
< #define ALE_JSOP(ale)   ((JSOp) JS_PTR_TO_UINT32((ale)->entry.value))
< #define ALE_VALUE(ale)  ((jsval) (ale)->entry.value)
---
> #define ALE_INDEX(ale)  ((jsatomid) (ale)->entry.value)
> #define ALE_JSOP(ale)   ((JSOp) (ale)->entry.value)
102,103c91,93
< #define ALE_SET_INDEX(ale,index)((ale)->entry.value = JS_UINT32_TO_PTR(index))
< #define ALE_SET_JSOP(ale,op)    ((ale)->entry.value = JS_UINT32_TO_PTR(op))
---
> #define ALE_SET_INDEX(ale,index)((ale)->entry.value = (void *)(index))
> #define ALE_SET_JSOP(ale,op)    ((ale)->entry.value = (void *)(op))
> #define ALE_SET_NEXT(ale,link)  ((ale)->entry.next = (JSHashEntry *)(link))
106c96
<     JSHashEntry         *list;          /* literals indexed for mapping */
---
>     JSAtomListElement   *list;          /* literals indexed for mapping */
123,124c113
<             _hep = JS_HashTableRawLookup((_al)->table, ATOM_HASH(_atom),      \
<                                          _atom);                              \
---
>             _hep = JS_HashTableRawLookup((_al)->table, _atom->number, _atom); \
127c116
<             JSHashEntry **_alep = &(_al)->list;                               \
---
>             JSAtomListElement **_alep = &(_al)->list;                         \
129c118
<             while ((_ale = (JSAtomListElement *)*_alep) != NULL) {            \
---
>             while ((_ale = *_alep) != NULL) {                                 \
132,134c121,123
<                     *_alep = (_ale)->entry.next;                              \
<                     (_ale)->entry.next = (_al)->list;                         \
<                     (_al)->list = &_ale->entry;                               \
---
>                     *_alep = ALE_NEXT(_ale);                                  \
>                     ALE_SET_NEXT(_ale, (_al)->list);                          \
>                     (_al)->list = _ale;                                       \
137c126
<                 _alep = &_ale->entry.next;                                    \
---
>                 _alep = (JSAtomListElement **)&_ale->entry.next;              \
148,165c137,140
<     JSDHashTable        stringAtoms;    /* hash table with shared strings */
<     JSDHashTable        doubleAtoms;    /* hash table with shared doubles */
< #ifdef JS_THREADSAFE
<     JSThinLock          lock;
< #endif
< 
<     /*
<      * From this point until the end of struct definition the struct must
<      * contain only JSAtom fields. We use this to access the storage occupied
<      * by the common atoms in js_FinishCommonAtoms.
<      *
<      * js_common_atom_names defined in jsatom.c contains C strings for atoms
<      * in the order of atom fields here. Therefore you must update that array
<      * if you change member order here.
<      */
< 
<     /* The rt->emptyString atom, see jsstr.c's js_InitRuntimeStringState. */
<     JSAtom              *emptyAtom;
---
>     JSRuntime           *runtime;       /* runtime that owns us */
>     JSHashTable         *table;         /* hash table containing all atoms */
>     jsatomid            number;         /* one beyond greatest atom number */
>     jsatomid            liveAtoms;      /* number of live atoms after last GC */
172,174d146
<     /* Standard class constructor or prototype names. */
<     JSAtom              *classAtoms[JSProto_LIMIT];
< 
175a148,160
>     JSAtom              *ArgumentsAtom;
>     JSAtom              *ArrayAtom;
>     JSAtom              *BooleanAtom;
>     JSAtom              *CallAtom;
>     JSAtom              *DateAtom;
>     JSAtom              *ErrorAtom;
>     JSAtom              *FunctionAtom;
>     JSAtom              *MathAtom;
>     JSAtom              *NumberAtom;
>     JSAtom              *ObjectAtom;
>     JSAtom              *RegExpAtom;
>     JSAtom              *ScriptAtom;
>     JSAtom              *StringAtom;
184d168
<     JSAtom              *eachAtom;
186d169
<     JSAtom              *fileNameAtom;
191d173
<     JSAtom              *iteratorAtom;
193,194d174
<     JSAtom              *lineNumberAtom;
<     JSAtom              *messageAtom;
196,197d175
<     JSAtom              *nextAtom;
<     JSAtom              *noSuchMethodAtom;
202d179
<     JSAtom              *stackAtom;
207,228d183
<     JSAtom              *void0Atom;
< 
< #if JS_HAS_XML_SUPPORT
<     JSAtom              *etagoAtom;
<     JSAtom              *namespaceAtom;
<     JSAtom              *ptagcAtom;
<     JSAtom              *qualifierAtom;
<     JSAtom              *spaceAtom;
<     JSAtom              *stagoAtom;
<     JSAtom              *starAtom;
<     JSAtom              *starQualifierAtom;
<     JSAtom              *tagcAtom;
<     JSAtom              *xmlAtom;
< #endif
< 
< #ifdef NARCISSUS
<     JSAtom              *callAtom;
<     JSAtom              *constructAtom;
<     JSAtom              *hasInstanceAtom;
<     JSAtom              *ExecutionContextAtom;
<     JSAtom              *currentAtom;
< #endif
231a187
>         JSAtom          *EvalErrorAtom;
232a189
>         JSAtom          *InternalErrorAtom;
234c191,195
<         JSAtom          *XMLListAtom;
---
>         JSAtom          *RangeErrorAtom;
>         JSAtom          *ReferenceErrorAtom;
>         JSAtom          *SyntaxErrorAtom;
>         JSAtom          *TypeErrorAtom;
>         JSAtom          *URIErrorAtom;
242d202
<         JSAtom          *functionNamespaceURIAtom;
247d206
<         JSAtom          *isXMLNameAtom;
258,291d216
< };
< 
< #define ATOM_OFFSET_START       offsetof(JSAtomState, emptyAtom)
< #define LAZY_ATOM_OFFSET_START  offsetof(JSAtomState, lazy)
< #define ATOM_OFFSET_LIMIT       (sizeof(JSAtomState))
< 
< #define COMMON_ATOMS_START(state)                                             \
<     (JSAtom **)((uint8 *)(state) + ATOM_OFFSET_START)
< 
< /* Start and limit offsets should correspond to atoms. */
< JS_STATIC_ASSERT(ATOM_OFFSET_START % sizeof(JSAtom *) == 0);
< JS_STATIC_ASSERT(ATOM_OFFSET_LIMIT % sizeof(JSAtom *) == 0);
< 
< #define ATOM_OFFSET(name)       offsetof(JSAtomState, name##Atom)
< #define OFFSET_TO_ATOM(rt,off)  (*(JSAtom **)((char*)&(rt)->atomState + (off)))
< #define CLASS_ATOM_OFFSET(name) offsetof(JSAtomState,classAtoms[JSProto_##name])
< 
< #define CLASS_ATOM(cx,name) \
<     ((cx)->runtime->atomState.classAtoms[JSProto_##name])
< 
< extern const char *const js_common_atom_names[];
< 
< /*
<  * Macros to access C strings for JSType and boolean literals together with
<  * checks that type names and booleans starts from index 1 and 1+JSTYPE_LIMIT
<  * correspondingly.
<  */
< #define JS_TYPE_STR(type)    (js_common_atom_names[1 + (type)])
< #define JS_BOOLEAN_STR(type) (js_common_atom_names[1 + JSTYPE_LIMIT + (type)])
< 
< JS_STATIC_ASSERT(1 * sizeof(JSAtom *) ==
<                  offsetof(JSAtomState, typeAtoms) - ATOM_OFFSET_START);
< JS_STATIC_ASSERT((1 + JSTYPE_LIMIT) * sizeof(JSAtom *) ==
<                  offsetof(JSAtomState, booleanAtoms) - ATOM_OFFSET_START);
293,296c218,222
< /* Well-known predefined C strings. */
< #define JS_PROTO(name,code,init) extern const char js_##name##_str[];
< #include "jsproto.tbl"
< #undef JS_PROTO
---
> #ifdef JS_THREADSAFE
>     JSThinLock          lock;
>     volatile uint32     tablegen;
> #endif
> };
297a224,239
> /* Well-known predefined strings and their atoms. */
> extern const char   *js_type_str[];
> extern const char   *js_boolean_str[];
> 
> extern const char   js_Arguments_str[];
> extern const char   js_Array_str[];
> extern const char   js_Boolean_str[];
> extern const char   js_Call_str[];
> extern const char   js_Date_str[];
> extern const char   js_Function_str[];
> extern const char   js_Math_str[];
> extern const char   js_Number_str[];
> extern const char   js_Object_str[];
> extern const char   js_RegExp_str[];
> extern const char   js_Script_str[];
> extern const char   js_String_str[];
304d245
< extern const char   js_close_str[];
307,308d247
< extern const char   js_etago_str[];
< extern const char   js_each_str[];
310,311d248
< extern const char   js_fileName_str[];
< extern const char   js_get_str[];
312a250
> extern const char   js_get_str[];
315d252
< extern const char   js_iterator_str[];
317,318d253
< extern const char   js_lineNumber_str[];
< extern const char   js_message_str[];
320,323d254
< extern const char   js_namespace_str[];
< extern const char   js_next_str[];
< extern const char   js_noSuchMethod_str[];
< extern const char   js_object_str[];
326,328d256
< extern const char   js_ptagc_str[];
< extern const char   js_qualifier_str[];
< extern const char   js_send_str[];
331,336d258
< extern const char   js_space_str[];
< extern const char   js_stack_str[];
< extern const char   js_stago_str[];
< extern const char   js_star_str[];
< extern const char   js_starQualifier_str[];
< extern const char   js_tagc_str[];
340d261
< extern const char   js_undefined_str[];
342,350d262
< extern const char   js_xml_str[];
< 
< #ifdef NARCISSUS
< extern const char   js_call_str[];
< extern const char   js_construct_str[];
< extern const char   js_hasInstance_str[];
< extern const char   js_ExecutionContext_str[];
< extern const char   js_current_str[];
< #endif
353,355c265,266
<  * Initialize atom state. Return true on success, false on failure to allocate
<  * memory. The caller must zero rt->atomState before calling this function and
<  * only call it after js_InitGC successfully returns.
---
>  * Initialize atom state.  Return true on success, false with an out of
>  * memory error report on failure.
358c269
< js_InitAtomState(JSRuntime *rt);
---
> js_InitAtomState(JSContext *cx, JSAtomState *state);
361,362c272
<  * Free and clear atom state including any interned string atoms. This
<  * function must be called before js_FinishGC.
---
>  * Free and clear atom state (except for any interned string atoms).
365c275
< js_FinishAtomState(JSRuntime *rt);
---
> js_FreeAtomState(JSContext *cx, JSAtomState *state);
368c278,288
<  * Atom tracing and garbage collection hooks.
---
>  * Interned strings are atoms that live until state's runtime is destroyed.
>  * This function frees all interned string atoms, and then frees and clears
>  * state's members (just as js_FreeAtomState does), unless there aren't any
>  * interned strings in state -- in which case state must be "free" already.
>  *
>  * NB: js_FreeAtomState is called for each "last" context being destroyed in
>  * a runtime, where there may yet be another context created in the runtime;
>  * whereas js_FinishAtomState is called from JS_DestroyRuntime, when we know
>  * that no more contexts will be created.  Thus we minimize garbage during
>  * context-free episodes on a runtime, while preserving atoms created by the
>  * JS_Intern*String APIs for the life of the runtime.
369a290,297
> extern void
> js_FinishAtomState(JSAtomState *state);
> 
> /*
>  * Atom garbage collection hooks.
>  */
> typedef void
> (*JSGCThingMarker)(void *thing, void *data);
372c300,301
< js_TraceAtomState(JSTracer *trc, JSBool allAtoms);
---
> js_MarkAtomState(JSAtomState *state, uintN gcflags, JSGCThingMarker mark,
>                  void *data);
375c304
< js_SweepAtomState(JSContext *cx);
---
> js_SweepAtomState(JSAtomState *state);
378c307
< js_InitCommonAtoms(JSContext *cx);
---
> js_InitPinnedAtoms(JSContext *cx, JSAtomState *state);
381c310
< js_FinishCommonAtoms(JSContext *cx);
---
> js_UnpinPinnedAtoms(JSAtomState *state);
384,385c313,314
<  * Find or create the atom for a double value. Return null on failure to
<  * allocate memory.
---
>  * Find or create the atom for an object.  If we create a new atom, give it the
>  * type indicated in flags.  Return 0 on failure to allocate memory.
388c317
< js_AtomizeDouble(JSContext *cx, jsdouble d);
---
> js_AtomizeObject(JSContext *cx, JSObject *obj, uintN flags);
391,392c320,321
<  * Find or create the atom for a string. Return null on failure to allocate
<  * memory.
---
>  * Find or create the atom for a Boolean value.  If we create a new atom, give
>  * it the type indicated in flags.  Return 0 on failure to allocate memory.
395c324
< js_AtomizeString(JSContext *cx, JSString *str, uintN flags);
---
> js_AtomizeBoolean(JSContext *cx, JSBool b, uintN flags);
396a326,329
> /*
>  * Find or create the atom for an integer value.  If we create a new atom, give
>  * it the type indicated in flags.  Return 0 on failure to allocate memory.
>  */
398c331
< js_Atomize(JSContext *cx, const char *bytes, size_t length, uintN flags);
---
> js_AtomizeInt(JSContext *cx, jsint i, uintN flags);
399a333,336
> /*
>  * Find or create the atom for a double value.  If we create a new atom, give
>  * it the type indicated in flags.  Return 0 on failure to allocate memory.
>  */
401c338
< js_AtomizeChars(JSContext *cx, const jschar *chars, size_t length, uintN flags);
---
> js_AtomizeDouble(JSContext *cx, jsdouble d, uintN flags);
404,405c341,342
<  * Return an existing atom for the given char array or null if the char
<  * sequence is currently not atomized.
---
>  * Find or create the atom for a string.  If we create a new atom, give it the
>  * type indicated in flags.  Return 0 on failure to allocate memory.
408c345,351
< js_GetExistingStringAtom(JSContext *cx, const jschar *chars, size_t length);
---
> js_AtomizeString(JSContext *cx, JSString *str, uintN flags);
> 
> extern JS_FRIEND_API(JSAtom *)
> js_Atomize(JSContext *cx, const char *bytes, size_t length, uintN flags);
> 
> extern JS_FRIEND_API(JSAtom *)
> js_AtomizeChars(JSContext *cx, const jschar *chars, size_t length, uintN flags);
411c354
<  * This variant handles all primitive values.
---
>  * This variant handles all value tag types.
413,414c356,357
< JSBool
< js_AtomizePrimitiveValue(JSContext *cx, jsval v, JSAtom **atomp);
---
> extern JSAtom *
> js_AtomizeValue(JSContext *cx, jsval value, uintN flags);
417c360
<  * Convert v to an atomized string and wrap it as an id.
---
>  * Convert v to an atomized string.
419,427c362,363
< extern JSBool
< js_ValueToStringId(JSContext *cx, jsval v, jsid *idp);
< 
< #ifdef DEBUG
< 
< extern JS_FRIEND_API(void)
< js_DumpAtoms(JSContext *cx, FILE *fp);
< 
< #endif
---
> extern JSAtom *
> js_ValueToStringAtom(JSContext *cx, jsval v);
435a372,377
>  * Get the atom with index i from map.
>  */
> extern JS_FRIEND_API(JSAtom *)
> js_GetAtom(JSContext *cx, JSAtomMap *map, jsatomid i);
> 
> /*
437,438c379,382
<  * to its address. map->length must already be set to the number of atoms in
<  * the list and map->vector must point to pre-allocated memory.
---
>  * to its address.  The GC must not run until all indexed atoms in atomLists
>  * have been mapped by scripts connected to live objects (Function and Script
>  * class objects have scripts as/in their private data -- the GC knows about
>  * these two classes).
440c384
< extern void
---
> extern JS_FRIEND_API(JSBool)
442a387,392
> /*
>  * Free map->vector and clear map.
>  */
> extern JS_FRIEND_API(void)
> js_FreeAtomMap(JSContext *cx, JSAtomMap *map);
> 
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsbit.h /Volumes/Swap/js_D11/src/jsbit.h
2,13c2,11
< /* ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
> /*
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
18,21c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
25,37c23,33
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
43,44d38
< #include "jsutil.h"
< 
71,117d64
<  * Replace bit-scanning code sequences with CPU-specific instructions to
<  * speedup calculations of ceiling/floor log2.
<  *
<  * With GCC 3.4 or later we can use __builtin_clz for that, see bug 327129.
<  *
<  * SWS: Added MSVC intrinsic bitscan support.  See bugs 349364 and 356856.
<  */
< #if defined(_WIN32) && (_MSC_VER >= 1300) && defined(_M_IX86)
< 
< unsigned char _BitScanForward(unsigned long * Index, unsigned long Mask);
< unsigned char _BitScanReverse(unsigned long * Index, unsigned long Mask);
< # pragma intrinsic(_BitScanForward,_BitScanReverse)
< 
< __forceinline static int
< __BitScanForward32(unsigned int val)
< {
<    unsigned long idx;
< 
<    _BitScanForward(&idx, (unsigned long)val);
<    return (int)idx;
< }
< __forceinline static int
< __BitScanReverse32(unsigned int val)
< {
<    unsigned long idx;
< 
<    _BitScanReverse(&idx, (unsigned long)val);
<    return (int)(31-idx);
< }
< # define js_bitscan_ctz32(val)  __BitScanForward32(val)
< # define js_bitscan_clz32(val)  __BitScanReverse32(val)
< # define JS_HAS_BUILTIN_BITSCAN32
< 
< #elif (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
< 
< # define js_bitscan_ctz32(val)  __builtin_ctz(val)
< # define js_bitscan_clz32(val)  __builtin_clz(val)
< # define JS_HAS_BUILTIN_BITSCAN32
< # if (JS_BYTES_PER_WORD == 8)
< #  define js_bitscan_ctz64(val)  __builtin_ctzll(val)
< #  define js_bitscan_clz64(val)  __builtin_clzll(val)
< #  define JS_HAS_BUILTIN_BITSCAN64
< # endif
< 
< #endif
< 
< /*
121,134c68
< #ifdef JS_HAS_BUILTIN_BITSCAN32
< /*
<  * Use intrinsic function or count-leading-zeros to calculate ceil(log2(_n)).
<  * The macro checks for "n <= 1" and not "n != 0" as js_bitscan_clz32(0) is
<  * undefined.
<  */
< # define JS_CEILING_LOG2(_log2,_n)                                            \
<     JS_BEGIN_MACRO                                                            \
<         JS_STATIC_ASSERT(sizeof(unsigned int) == sizeof(JSUint32));           \
<         unsigned int j_ = (unsigned int)(_n);                                 \
<         (_log2) = (j_ <= 1 ? 0 : 32 - js_bitscan_clz32(j_ - 1));              \
<     JS_END_MACRO
< #else
< # define JS_CEILING_LOG2(_log2,_n)                                            \
---
> #define JS_CEILING_LOG2(_log2,_n)                                             \
151d84
< #endif
159,171c92
< #ifdef JS_HAS_BUILTIN_BITSCAN32
< /*
<  * Use js_bitscan_clz32 or count-leading-zeros to calculate floor(log2(_n)).
<  * Since js_bitscan_clz32(0) is undefined, the macro set the loweset bit to 1
<  * to ensure 0 result when _n == 0.
<  */
< # define JS_FLOOR_LOG2(_log2,_n)                                              \
<     JS_BEGIN_MACRO                                                            \
<         JS_STATIC_ASSERT(sizeof(unsigned int) == sizeof(JSUint32));           \
<         (_log2) = 31 - js_bitscan_clz32(((unsigned int)(_n)) | 1);            \
<     JS_END_MACRO
< #else
< # define JS_FLOOR_LOG2(_log2,_n)                                              \
---
> #define JS_FLOOR_LOG2(_log2,_n)                                               \
186,247d106
< #endif
< 
< /*
<  * Internal function.
<  * Compute the log of the least power of 2 greater than or equal to n.
<  * This is a version of JS_CeilingLog2 that operates on jsuword with
<  * CPU-dependant size.
<  */
< #define JS_CEILING_LOG2W(n) ((n) <= 1 ? 0 : 1 + JS_FLOOR_LOG2W((n) - 1))
< 
< /*
<  * Internal function.
<  * Compute the log of the greatest power of 2 less than or equal to n.
<  * This is a version of JS_FloorLog2 that operates on jsuword with
<  * CPU-dependant size and requires that n != 0.
<  */
< #define JS_FLOOR_LOG2W(n) (JS_ASSERT((n) != 0), js_FloorLog2wImpl(n))
< 
< #if JS_BYTES_PER_WORD == 4
< 
< # ifdef JS_HAS_BUILTIN_BITSCAN32
< JS_STATIC_ASSERT(sizeof(unsigned) == sizeof(JSUword));
< #  define js_FloorLog2wImpl(n)                                                \
<    ((JSUword)(JS_BITS_PER_WORD - 1 - js_bitscan_clz32(n)))
< # else
< #  define js_FloorLog2wImpl(n) ((JSUword)JS_FloorLog2(n))
< #endif
< 
< #elif JS_BYTES_PER_WORD == 8
< 
< # ifdef JS_HAS_BUILTIN_BITSCAN64
< JS_STATIC_ASSERT(sizeof(unsigned long long) == sizeof(JSUword));
< #  define js_FloorLog2wImpl(n)                                                \
<    ((JSUword)(JS_BITS_PER_WORD - 1 - js_bitscan_clz64(n)))
< # else
< extern JSUword js_FloorLog2wImpl(JSUword n);
< # endif
< 
< #else
< 
< # error "NOT SUPPORTED"
< 
< #endif
< 
< /*
<  * Macros for rotate left. There is no rotate operation in the C Language so
<  * the construct (a << 4) | (a >> 28) is used instead. Most compilers convert
<  * this to a rotate instruction but some versions of MSVC don't without a
<  * little help.  To get MSVC to generate a rotate instruction, we have to use
<  * the _rotl intrinsic and use a pragma to make _rotl inline.
<  *
<  * MSVC in VS2005 will do an inline rotate instruction on the above construct.
<  */
< 
< #if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || \
<     defined(_M_X64))
< #include <stdlib.h>
< #pragma intrinsic(_rotl)
< #define JS_ROTATE_LEFT32(a, bits) _rotl(a, bits)
< #else
< #define JS_ROTATE_LEFT32(a, bits) (((a) << (bits)) | ((a) >> (32 - (bits))))
< #endif
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsbool.c /Volumes/Swap/js_D11/src/jsbool.c
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
57c52,54
< JSClass js_BooleanClass = {
---
> //#include "_optimize.h"
> 
> static JSClass boolean_class = {
59c56
<     JSCLASS_HAS_PRIVATE | JSCLASS_HAS_CACHED_PROTO(JSProto_Boolean),
---
>     JSCLASS_HAS_PRIVATE,
69c66,67
< bool_toSource(JSContext *cx, uintN argc, jsval *vp)
---
> bool_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
> 	      jsval *rval)
75,77c73,77
<     if (!js_GetPrimitiveThis(cx, vp, &js_BooleanClass, &v))
<         return JS_FALSE;
<     JS_ASSERT(JSVAL_IS_BOOLEAN(v));
---
>     if (!JS_InstanceOf(cx, obj, &boolean_class, argv))
> 	return JS_FALSE;
>     v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
>     if (!JSVAL_IS_BOOLEAN(v))
> 	return js_obj_toSource(cx, obj, argc, argv, rval);
79,80c79,80
<                 js_BooleanClass.name,
<                 JS_BOOLEAN_STR(JSVAL_TO_BOOLEAN(v)));
---
> 		boolean_class.name,
> 		js_boolean_str[JSVAL_TO_BOOLEAN(v) ? 1 : 0]);
83,84c83,84
<         return JS_FALSE;
<     *vp = STRING_TO_JSVAL(str);
---
> 	return JS_FALSE;
>     *rval = STRING_TO_JSVAL(str);
90c90,91
< bool_toString(JSContext *cx, uintN argc, jsval *vp)
---
> bool_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
> 	      jsval *rval)
96,98c97,101
<     if (!js_GetPrimitiveThis(cx, vp, &js_BooleanClass, &v))
<         return JS_FALSE;
<     JS_ASSERT(JSVAL_IS_BOOLEAN(v));
---
>     if (!JS_InstanceOf(cx, obj, &boolean_class, argv))
> 	return JS_FALSE;
>     v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
>     if (!JSVAL_IS_BOOLEAN(v))
> 	return js_obj_toString(cx, obj, argc, argv, rval);
102,103c105,106
<         return JS_FALSE;
<     *vp = STRING_TO_JSVAL(str);
---
> 	return JS_FALSE;
>     *rval = STRING_TO_JSVAL(str);
108c111
< bool_valueOf(JSContext *cx, uintN argc, jsval *vp)
---
> bool_valueOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
110c113,116
<     return js_GetPrimitiveThis(cx, vp, &js_BooleanClass, vp);
---
>     if (!JS_InstanceOf(cx, obj, &boolean_class, argv))
> 	return JS_FALSE;
>     *rval = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
>     return JS_TRUE;
115c121
<     JS_FN(js_toSource_str,  bool_toSource,  0, 0, JSFUN_THISP_BOOLEAN),
---
>     {js_toSource_str,   bool_toSource,          0,0,0},
117,119c123,125
<     JS_FN(js_toString_str,  bool_toString,  0, 0, JSFUN_THISP_BOOLEAN),
<     JS_FN(js_valueOf_str,   bool_valueOf,   0, 0, JSFUN_THISP_BOOLEAN),
<     JS_FS_END
---
>     {js_toString_str,	bool_toString,		0,0,0},
>     {js_valueOf_str,	bool_valueOf,		0,0,0},
>     {0,0,0,0,0}
121a128,132
> #ifdef XP_MAC
> #undef Boolean
> #define Boolean js_Boolean
> #endif
> 
124a136
>     JSBool b;
127,129c139,145
<     bval = (argc != 0)
<            ? BOOLEAN_TO_JSVAL(js_ValueToBoolean(argv[0]))
<            : JSVAL_FALSE;
---
>     if (argc != 0) {
> 	if (!js_ValueToBoolean(cx, argv[0], &b))
> 	    return JS_FALSE;
> 	bval = BOOLEAN_TO_JSVAL(b);
>     } else {
> 	bval = JSVAL_FALSE;
>     }
131,132c147,148
<         *rval = bval;
<         return JS_TRUE;
---
> 	*rval = bval;
> 	return JS_TRUE;
134c150
<     STOBJ_SET_SLOT(obj, JSSLOT_PRIVATE, bval);
---
>     OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, bval);
143,144c159,160
<     proto = JS_InitClass(cx, obj, NULL, &js_BooleanClass, Boolean, 1,
<                         NULL, boolean_methods, NULL, NULL);
---
>     proto = JS_InitClass(cx, obj, NULL, &boolean_class, Boolean, 1,
> 			NULL, boolean_methods, NULL, NULL);
146,147c162,163
<         return NULL;
<     STOBJ_SET_SLOT(proto, JSSLOT_PRIVATE, JSVAL_FALSE);
---
> 	return NULL;
>     OBJ_SET_SLOT(cx, proto, JSSLOT_PRIVATE, JSVAL_FALSE);
150a167,178
> JSObject *
> js_BooleanToObject(JSContext *cx, JSBool b)
> {
>     JSObject *obj;
> 
>     obj = js_NewObject(cx, &boolean_class, NULL, NULL);
>     if (!obj)
> 	return NULL;
>     OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, BOOLEAN_TO_JSVAL(b));
>     return obj;
> }
> 
158c186
< js_ValueToBoolean(jsval v)
---
> js_ValueToBoolean(JSContext *cx, jsval v, JSBool *bp)
160,169c188,199
<     if (JSVAL_IS_NULL(v) || JSVAL_IS_VOID(v))
<         return JS_FALSE;
<     if (JSVAL_IS_OBJECT(v))
<         return JS_TRUE;
<     if (JSVAL_IS_STRING(v))
<         return JSSTRING_LENGTH(JSVAL_TO_STRING(v)) != 0;
<     if (JSVAL_IS_INT(v))
<         return JSVAL_TO_INT(v) != 0;
<     if (JSVAL_IS_DOUBLE(v)) {
<         jsdouble d;
---
>     JSBool b;
>     jsdouble d;
> 
> #if defined _MSC_VER && _MSC_VER <= 800
>     /* MSVC1.5 coredumps */
>     if (!bp)
> 	return JS_TRUE;
>     /* This should be an if-else chain, but MSVC1.5 crashes if it is. */
> #define ELSE
> #else
> #define ELSE else
> #endif
171,172c201,204
<         d = *JSVAL_TO_DOUBLE(v);
<         return !JSDOUBLE_IS_NaN(d) && d != 0;
---
>     if (JSVAL_IS_NULL(v) || JSVAL_IS_VOID(v)) {
> 	/* Must return early to avoid falling thru to JSVAL_IS_OBJECT case. */
> 	*bp = JS_FALSE;
> 	return JS_TRUE;
174,175c206,240
<     JS_ASSERT(JSVAL_IS_BOOLEAN(v));
<     return JSVAL_TO_BOOLEAN(v);
---
>     if (JSVAL_IS_OBJECT(v)) {
> 	if (!JSVERSION_IS_ECMA(cx->version)) {
> 	    if (!OBJ_DEFAULT_VALUE(cx, JSVAL_TO_OBJECT(v), JSTYPE_BOOLEAN, &v))
> 		return JS_FALSE;
> 	    if (!JSVAL_IS_BOOLEAN(v))
> 		v = JSVAL_TRUE;		/* non-null object is true */
> 	    b = JSVAL_TO_BOOLEAN(v);
> 	} else {
> 	    b = JS_TRUE;
> 	}
>     } ELSE
>     if (JSVAL_IS_STRING(v)) {
> 	b = JSSTRING_LENGTH(JSVAL_TO_STRING(v)) ? JS_TRUE : JS_FALSE;
>     } ELSE
>     if (JSVAL_IS_INT(v)) {
> 	b = JSVAL_TO_INT(v) ? JS_TRUE : JS_FALSE;
>     } ELSE
>     if (JSVAL_IS_DOUBLE(v)) {
> 	d = *JSVAL_TO_DOUBLE(v);
> 	b = (!JSDOUBLE_IS_NaN(d) && d != 0) ? JS_TRUE : JS_FALSE;
>     } ELSE
> #if defined _MSC_VER && _MSC_VER <= 800
>     if (JSVAL_IS_BOOLEAN(v)) {
> 	b = JSVAL_TO_BOOLEAN(v);
>     }
> #else
>     {
>         JS_ASSERT(JSVAL_IS_BOOLEAN(v));
> 	b = JSVAL_TO_BOOLEAN(v);
>     }
> #endif
> 
> #undef ELSE
>     *bp = b;
>     return JS_TRUE;
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsbool.h /Volumes/Swap/js_D11/src/jsbool.h
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
48,61d42
< /*
<  * Crypto-booleans, not visible to script but used internally by the engine.
<  *
<  * JSVAL_HOLE is a useful value for identifying a hole in an array.  It's also
<  * used in the interpreter to represent "no exception pending".  In general it
<  * can be used to represent "no value".
<  *
<  * JSVAL_ARETURN is used to throw asynchronous return for generator.close().
<  */
< #define JSVAL_HOLE      BOOLEAN_TO_JSVAL(2)
< #define JSVAL_ARETURN   BOOLEAN_TO_JSVAL(3)
< 
< extern JSClass js_BooleanClass;
< 
64a46,48
> extern JSObject *
> js_BooleanToObject(JSContext *cx, JSBool b);
> 
69c53
< js_ValueToBoolean(jsval v);
---
> js_ValueToBoolean(JSContext *cx, jsval v, JSBool *bp);
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsclist.h /Volumes/Swap/js_D11/src/jsclist.h
2,13c2,11
< /* ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
> /*
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
18,37c16,33
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
55,60c51,56
< #define JS_INSERT_BEFORE(_e,_l)  \
<     JS_BEGIN_MACRO               \
<         (_e)->next = (_l);       \
<         (_e)->prev = (_l)->prev; \
<         (_l)->prev->next = (_e); \
<         (_l)->prev = (_e);       \
---
> #define JS_INSERT_BEFORE(_e,_l)	 \
>     JS_BEGIN_MACRO		 \
> 	(_e)->next = (_l);	 \
> 	(_e)->prev = (_l)->prev; \
> 	(_l)->prev->next = (_e); \
> 	(_l)->prev = (_e);	 \
66,71c62,67
< #define JS_INSERT_AFTER(_e,_l)   \
<     JS_BEGIN_MACRO               \
<         (_e)->next = (_l)->next; \
<         (_e)->prev = (_l);       \
<         (_l)->next->prev = (_e); \
<         (_l)->next = (_e);       \
---
> #define JS_INSERT_AFTER(_e,_l)	 \
>     JS_BEGIN_MACRO		 \
> 	(_e)->next = (_l)->next; \
> 	(_e)->prev = (_l);	 \
> 	(_l)->next->prev = (_e); \
> 	(_l)->next = (_e);	 \
77,78c73,74
< #define JS_NEXT_LINK(_e)         \
<         ((_e)->next)
---
> #define JS_NEXT_LINK(_e)	 \
>     	((_e)->next)
82,83c78,79
< #define JS_PREV_LINK(_e)         \
<         ((_e)->prev)
---
> #define JS_PREV_LINK(_e)	 \
>     	((_e)->prev)
102,105c98,101
< #define JS_REMOVE_LINK(_e)             \
<     JS_BEGIN_MACRO                     \
<         (_e)->prev->next = (_e)->next; \
<         (_e)->next->prev = (_e)->prev; \
---
> #define JS_REMOVE_LINK(_e)	       \
>     JS_BEGIN_MACRO		       \
> 	(_e)->prev->next = (_e)->next; \
> 	(_e)->next->prev = (_e)->prev; \
113,117c109,113
<     JS_BEGIN_MACRO                     \
<         (_e)->prev->next = (_e)->next; \
<         (_e)->next->prev = (_e)->prev; \
<         (_e)->next = (_e);             \
<         (_e)->prev = (_e);             \
---
>     JS_BEGIN_MACRO		       \
> 	(_e)->prev->next = (_e)->next; \
> 	(_e)->next->prev = (_e)->prev; \
> 	(_e)->next = (_e);	       \
> 	(_e)->prev = (_e);	       \
131,133c127,129
<     JS_BEGIN_MACRO         \
<         (_l)->next = (_l); \
<         (_l)->prev = (_l); \
---
>     JS_BEGIN_MACRO	   \
> 	(_l)->next = (_l); \
> 	(_l)->prev = (_l); \
diff -r /Volumes/Swap/js-14-2-2008/js/src/jscntxt.c /Volumes/Swap/js_D11/src/jscntxt.c
2d1
<  * vim: set ts=8 sw=4 et tw=80:
4,15c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
20,23c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
27,39c23,33
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
46c40
< #include <stdlib.h>
---
> #include "xstdlib.h"
64d57
< #include "jsscope.h"
68,182d60
< #ifdef JS_THREADSAFE
< #include "prtypes.h"
< 
< /*
<  * The index for JSThread info, returned by PR_NewThreadPrivateIndex.  The
<  * index value is visible and shared by all threads, but the data associated
<  * with it is private to each thread.
<  */
< static PRUintn threadTPIndex;
< static JSBool  tpIndexInited = JS_FALSE;
< 
< JSBool
< js_InitThreadPrivateIndex(void (JS_DLL_CALLBACK *ptr)(void *))
< {
<     PRStatus status;
< 
<     if (tpIndexInited)
<         return JS_TRUE;
< 
<     status = PR_NewThreadPrivateIndex(&threadTPIndex, ptr);
< 
<     if (status == PR_SUCCESS)
<         tpIndexInited = JS_TRUE;
<     return status == PR_SUCCESS;
< }
< 
< /*
<  * Callback function to delete a JSThread info when the thread that owns it
<  * is destroyed.
<  */
< void JS_DLL_CALLBACK
< js_ThreadDestructorCB(void *ptr)
< {
<     JSThread *thread = (JSThread *)ptr;
< 
<     if (!thread)
<         return;
< 
<     /*
<      * Check that this thread properly called either JS_DestroyContext or
<      * JS_ClearContextThread on each JSContext it created or used.
<      */
<     JS_ASSERT(JS_CLIST_IS_EMPTY(&thread->contextList));
<     GSN_CACHE_CLEAR(&thread->gsnCache);
<     free(thread);
< }
< 
< /*
<  * Get current thread-local JSThread info, creating one if it doesn't exist.
<  * Each thread has a unique JSThread pointer.
<  *
<  * Since we are dealing with thread-local data, no lock is needed.
<  *
<  * Return a pointer to the thread local info, NULL if the system runs out
<  * of memory, or it failed to set thread private data (neither case is very
<  * likely; both are probably due to out-of-memory).  It is up to the caller
<  * to report an error, if possible.
<  */
< JSThread *
< js_GetCurrentThread(JSRuntime *rt)
< {
<     JSThread *thread;
< 
<     thread = (JSThread *)PR_GetThreadPrivate(threadTPIndex);
<     if (!thread) {
<         thread = (JSThread *) calloc(1, sizeof(JSThread));
<         if (!thread)
<             return NULL;
< 
<         if (PR_FAILURE == PR_SetThreadPrivate(threadTPIndex, thread)) {
<             free(thread);
<             return NULL;
<         }
< 
<         JS_INIT_CLIST(&thread->contextList);
<         thread->id = js_CurrentThreadId();
< 
<         /* js_SetContextThread initialize gcFreeLists as necessary. */
< #ifdef DEBUG
<         memset(thread->gcFreeLists, JS_FREE_PATTERN,
<                sizeof(thread->gcFreeLists));
< #endif
<     }
<     return thread;
< }
< 
< /*
<  * Sets current thread as owning thread of a context by assigning the
<  * thread-private info to the context. If the current thread doesn't have
<  * private JSThread info, create one.
<  */
< JSBool
< js_SetContextThread(JSContext *cx)
< {
<     JSThread *thread = js_GetCurrentThread(cx->runtime);
< 
<     if (!thread) {
<         JS_ReportOutOfMemory(cx);
<         return JS_FALSE;
<     }
< 
<     /*
<      * Clear gcFreeLists on each transition from 0 to 1 context active on the
<      * current thread. See bug 351602.
<      */
<     if (JS_CLIST_IS_EMPTY(&thread->contextList))
<         memset(thread->gcFreeLists, 0, sizeof(thread->gcFreeLists));
< 
<     /* Assert that the previous cx->thread called JS_ClearContextThread(). */
<     JS_ASSERT(!cx->thread || cx->thread == thread);
<     if (!cx->thread)
<         JS_APPEND_LINK(&cx->threadLinks, &thread->contextList);
<     cx->thread = thread;
<     return JS_TRUE;
< }
184,220c62
< /* Remove the owning thread info of a context. */
< void
< js_ClearContextThread(JSContext *cx)
< {
<     /*
<      * If cx is associated with a thread, this must be called only from that
<      * thread.  If not, this is a harmless no-op.
<      */
<     JS_ASSERT(cx->thread == js_GetCurrentThread(cx->runtime) || !cx->thread);
<     JS_REMOVE_AND_INIT_LINK(&cx->threadLinks);
< #ifdef DEBUG
<     if (JS_CLIST_IS_EMPTY(&cx->thread->contextList)) {
<         memset(cx->thread->gcFreeLists, JS_FREE_PATTERN,
<                sizeof(cx->thread->gcFreeLists));
<     }
< #endif
<     cx->thread = NULL;
< }
< 
< #endif /* JS_THREADSAFE */
< 
< void
< js_OnVersionChange(JSContext *cx)
< {
< #ifdef DEBUG
<     JSVersion version = JSVERSION_NUMBER(cx);
< 
<     JS_ASSERT(version == JSVERSION_DEFAULT || version >= JSVERSION_ECMA_3);
< #endif
< }
< 
< void
< js_SetVersion(JSContext *cx, JSVersion version)
< {
<     cx->version = version;
<     js_OnVersionChange(cx);
< }
---
> //#include "_optimize.h"
227d68
<     JSContextCallback cxCallback;
229c70,71
<     cx = (JSContext *) malloc(sizeof *cx);
---
> 	XMEMTAG("js_NewContext ");
>     cx = (JSContext *) xmalloc(sizeof *cx);
235,240d76
<     JS_ClearOperationCallback(cx);
<     cx->debugHooks = &rt->globalDebugHooks;
< #if JS_STACK_GROWTH_DIRECTION > 0
<     cx->stackLimit = (jsuword)-1;
< #endif
<     cx->scriptStackQuota = JS_DEFAULT_SCRIPT_STACK_QUOTA;
242,243c78
<     JS_INIT_CLIST(&cx->threadLinks);
<     js_SetContextThread(cx);
---
>     js_InitContextForLocking(cx);
271,274c106,111
<     JS_INIT_ARENA_POOL(&cx->stackPool, "stack", stackChunkSize, sizeof(jsval),
<                        &cx->scriptStackQuota);
<     JS_INIT_ARENA_POOL(&cx->tempPool, "temp", 1024, sizeof(jsdouble),
<                        &cx->scriptStackQuota);
---
>     cx->jsop_eq = JSOP_EQ;
>     cx->jsop_ne = JSOP_NE;
>     JS_InitArenaPool(&cx->stackPool, "stack", stackChunkSize, sizeof(jsval));
>     JS_InitArenaPool(&cx->codePool, "code", 1024, sizeof(jsbytecode));
>     JS_InitArenaPool(&cx->notePool, "note", 1024, sizeof(jssrcnote));
>     JS_InitArenaPool(&cx->tempPool, "temp", 1024, sizeof(jsdouble));
275a113
> #if JS_HAS_REGEXPS
277c115
<         js_DestroyContext(cx, JSDCM_NEW_FAILED);
---
>         js_DestroyContext(cx, JS_NO_GC);
279a118,121
> #endif
> #if JS_HAS_EXCEPTIONS
>     cx->throwing = JS_FALSE;
> #endif
290,301c132,136
< #ifdef JS_THREADSAFE
<         JS_BeginRequest(cx);
< #endif
<         ok = js_InitCommonAtoms(cx);
< 
<         /*
<          * scriptFilenameTable may be left over from a previous episode of
<          * non-zero contexts alive in rt, so don't re-init the table if it's
<          * not necessary.
<          */
<         if (ok && !rt->scriptFilenameTable)
<             ok = js_InitRuntimeScriptState(rt);
---
>         ok = (rt->atomState.liveAtoms == 0)
>              ? js_InitAtomState(cx, &rt->atomState)
>              : js_InitPinnedAtoms(cx, &rt->atomState);
>         if (ok)
>             ok = js_InitScanner(cx);
306,308d140
< #ifdef JS_THREADSAFE
<         JS_EndRequest(cx);
< #endif
310c142
<             js_DestroyContext(cx, JSDCM_NEW_FAILED);
---
>             js_DestroyContext(cx, JS_NO_GC);
320,324d151
<     cxCallback = rt->cxCallback;
<     if (cxCallback && !cxCallback(cx, JSCONTEXT_NEW)) {
<         js_DestroyContext(cx, JSDCM_NEW_FAILED);
<         return NULL;
<     }
329c156
< js_DestroyContext(JSContext *cx, JSDestroyContextMode mode)
---
> js_DestroyContext(JSContext *cx, JSGCMode gcmode)
332d158
<     JSContextCallback cxCallback;
335,336d160
<     JSLocalRootStack *lrs;
<     JSLocalRootChunk *lrc;
340,354d163
<     if (mode != JSDCM_NEW_FAILED) {
<         cxCallback = rt->cxCallback;
<         if (cxCallback) {
<             /*
<              * JSCONTEXT_DESTROY callback is not allowed to fail and must
<              * return true.
<              */
< #ifdef DEBUG
<             JSBool callbackStatus =
< #endif
<             cxCallback(cx, JSCONTEXT_DESTROY);
<             JS_ASSERT(callbackStatus);
<         }
<     }
< 
379a189,191
>         /* Unpin all pinned atoms before final GC. */
>         js_UnpinPinnedAtoms(&rt->atomState);
> 
384,386d195
<         /* Unpin all common atoms before final GC. */
<         js_FinishCommonAtoms(cx);
< 
391a201
> #if JS_HAS_REGEXPS
398a209
> #endif
417c228,229
<         js_GC(cx, GC_LAST_CONTEXT);
---
>         /* Always force, so we wait for any racing GC to finish. */
>         js_ForceGC(cx, GC_LAST_CONTEXT);
419,424c231,237
<         /*
<          * Free the script filename table if it exists and is empty. Do this
<          * after the last GC to avoid finalizers tripping on free memory.
<          */
<         if (rt->scriptFilenameTable && rt->scriptFilenameTable->nentries == 0)
<             js_FinishRuntimeScriptState(rt);
---
>         /* Iterate until no finalizer removes a GC root or lock. */
>         while (rt->gcPoke)
>             js_GC(cx, GC_LAST_CONTEXT);
> 
>         /* Try to free atom state, now that no unrooted scripts survive. */
>         if (rt->atomState.liveAtoms == 0)
>             js_FreeAtomState(cx, &rt->atomState);
432,434c245,247
<         if (mode == JSDCM_FORCE_GC)
<             js_GC(cx, GC_NORMAL);
<         else if (mode == JSDCM_MAYBE_GC)
---
>         if (gcmode == JS_FORCE_GC)
>             js_ForceGC(cx, 0);
>         else if (gcmode == JS_MAYBE_GC)
439a253,254
>     JS_FinishArenaPool(&cx->codePool);
>     JS_FinishArenaPool(&cx->notePool);
441d255
< 
443c257
<         free(cx->lastMessage);
---
>         xfree(cx->lastMessage);
459,471d272
<     lrs = cx->localRootStack;
<     if (lrs) {
<         while ((lrc = lrs->topChunk) != &lrs->firstChunk) {
<             lrs->topChunk = lrc->down;
<             JS_free(cx, lrc);
<         }
<         JS_free(cx, lrs);
<     }
< 
< #ifdef JS_THREADSAFE
<     js_ClearContextThread(cx);
< #endif
< 
473c274
<     free(cx);
---
>     xfree(cx);
507,832d307
< JS_STATIC_DLL_CALLBACK(JSDHashNumber)
< resolving_HashKey(JSDHashTable *table, const void *ptr)
< {
<     const JSResolvingKey *key = (const JSResolvingKey *)ptr;
< 
<     return ((JSDHashNumber)JS_PTR_TO_UINT32(key->obj) >> JSVAL_TAGBITS) ^ key->id;
< }
< 
< JS_PUBLIC_API(JSBool)
< resolving_MatchEntry(JSDHashTable *table,
<                      const JSDHashEntryHdr *hdr,
<                      const void *ptr)
< {
<     const JSResolvingEntry *entry = (const JSResolvingEntry *)hdr;
<     const JSResolvingKey *key = (const JSResolvingKey *)ptr;
< 
<     return entry->key.obj == key->obj && entry->key.id == key->id;
< }
< 
< static const JSDHashTableOps resolving_dhash_ops = {
<     JS_DHashAllocTable,
<     JS_DHashFreeTable,
<     resolving_HashKey,
<     resolving_MatchEntry,
<     JS_DHashMoveEntryStub,
<     JS_DHashClearEntryStub,
<     JS_DHashFinalizeStub,
<     NULL
< };
< 
< JSBool
< js_StartResolving(JSContext *cx, JSResolvingKey *key, uint32 flag,
<                   JSResolvingEntry **entryp)
< {
<     JSDHashTable *table;
<     JSResolvingEntry *entry;
< 
<     table = cx->resolvingTable;
<     if (!table) {
<         table = JS_NewDHashTable(&resolving_dhash_ops, NULL,
<                                  sizeof(JSResolvingEntry),
<                                  JS_DHASH_MIN_SIZE);
<         if (!table)
<             goto outofmem;
<         cx->resolvingTable = table;
<     }
< 
<     entry = (JSResolvingEntry *)
<             JS_DHashTableOperate(table, key, JS_DHASH_ADD);
<     if (!entry)
<         goto outofmem;
< 
<     if (entry->flags & flag) {
<         /* An entry for (key, flag) exists already -- dampen recursion. */
<         entry = NULL;
<     } else {
<         /* Fill in key if we were the first to add entry, then set flag. */
<         if (!entry->key.obj)
<             entry->key = *key;
<         entry->flags |= flag;
<     }
<     *entryp = entry;
<     return JS_TRUE;
< 
< outofmem:
<     JS_ReportOutOfMemory(cx);
<     return JS_FALSE;
< }
< 
< void
< js_StopResolving(JSContext *cx, JSResolvingKey *key, uint32 flag,
<                  JSResolvingEntry *entry, uint32 generation)
< {
<     JSDHashTable *table;
< 
<     /*
<      * Clear flag from entry->flags and return early if other flags remain.
<      * We must take care to re-lookup entry if the table has changed since
<      * it was found by js_StartResolving.
<      */
<     table = cx->resolvingTable;
<     if (!entry || table->generation != generation) {
<         entry = (JSResolvingEntry *)
<                 JS_DHashTableOperate(table, key, JS_DHASH_LOOKUP);
<     }
<     JS_ASSERT(JS_DHASH_ENTRY_IS_BUSY(&entry->hdr));
<     entry->flags &= ~flag;
<     if (entry->flags)
<         return;
< 
<     /*
<      * Do a raw remove only if fewer entries were removed than would cause
<      * alpha to be less than .5 (alpha is at most .75).  Otherwise, we just
<      * call JS_DHashTableOperate to re-lookup the key and remove its entry,
<      * compressing or shrinking the table as needed.
<      */
<     if (table->removedCount < JS_DHASH_TABLE_SIZE(table) >> 2)
<         JS_DHashTableRawRemove(table, &entry->hdr);
<     else
<         JS_DHashTableOperate(table, key, JS_DHASH_REMOVE);
< }
< 
< JSBool
< js_EnterLocalRootScope(JSContext *cx)
< {
<     JSLocalRootStack *lrs;
<     int mark;
< 
<     lrs = cx->localRootStack;
<     if (!lrs) {
<         lrs = (JSLocalRootStack *) JS_malloc(cx, sizeof *lrs);
<         if (!lrs)
<             return JS_FALSE;
<         lrs->scopeMark = JSLRS_NULL_MARK;
<         lrs->rootCount = 0;
<         lrs->topChunk = &lrs->firstChunk;
<         lrs->firstChunk.down = NULL;
<         cx->localRootStack = lrs;
<     }
< 
<     /* Push lrs->scopeMark to save it for restore when leaving. */
<     mark = js_PushLocalRoot(cx, lrs, INT_TO_JSVAL(lrs->scopeMark));
<     if (mark < 0)
<         return JS_FALSE;
<     lrs->scopeMark = (uint32) mark;
<     return JS_TRUE;
< }
< 
< void
< js_LeaveLocalRootScopeWithResult(JSContext *cx, jsval rval)
< {
<     JSLocalRootStack *lrs;
<     uint32 mark, m, n;
<     JSLocalRootChunk *lrc;
< 
<     /* Defend against buggy native callers. */
<     lrs = cx->localRootStack;
<     JS_ASSERT(lrs && lrs->rootCount != 0);
<     if (!lrs || lrs->rootCount == 0)
<         return;
< 
<     mark = lrs->scopeMark;
<     JS_ASSERT(mark != JSLRS_NULL_MARK);
<     if (mark == JSLRS_NULL_MARK)
<         return;
< 
<     /* Free any chunks being popped by this leave operation. */
<     m = mark >> JSLRS_CHUNK_SHIFT;
<     n = (lrs->rootCount - 1) >> JSLRS_CHUNK_SHIFT;
<     while (n > m) {
<         lrc = lrs->topChunk;
<         JS_ASSERT(lrc != &lrs->firstChunk);
<         lrs->topChunk = lrc->down;
<         JS_free(cx, lrc);
<         --n;
<     }
< 
<     /*
<      * Pop the scope, restoring lrs->scopeMark.  If rval is a GC-thing, push
<      * it on the caller's scope, or store it in lastInternalResult if we are
<      * leaving the outermost scope.  We don't need to allocate a new lrc
<      * because we can overwrite the old mark's slot with rval.
<      */
<     lrc = lrs->topChunk;
<     m = mark & JSLRS_CHUNK_MASK;
<     lrs->scopeMark = (uint32) JSVAL_TO_INT(lrc->roots[m]);
<     if (JSVAL_IS_GCTHING(rval) && !JSVAL_IS_NULL(rval)) {
<         if (mark == 0) {
<             cx->weakRoots.lastInternalResult = rval;
<         } else {
<             /*
<              * Increment m to avoid the "else if (m == 0)" case below.  If
<              * rval is not a GC-thing, that case would take care of freeing
<              * any chunk that contained only the old mark.  Since rval *is*
<              * a GC-thing here, we want to reuse that old mark's slot.
<              */
<             lrc->roots[m++] = rval;
<             ++mark;
<         }
<     }
<     lrs->rootCount = (uint32) mark;
< 
<     /*
<      * Free the stack eagerly, risking malloc churn.  The alternative would
<      * require an lrs->entryCount member, maintained by Enter and Leave, and
<      * tested by the GC in addition to the cx->localRootStack non-null test.
<      *
<      * That approach would risk hoarding 264 bytes (net) per context.  Right
<      * now it seems better to give fresh (dirty in CPU write-back cache, and
<      * the data is no longer needed) memory back to the malloc heap.
<      */
<     if (mark == 0) {
<         cx->localRootStack = NULL;
<         JS_free(cx, lrs);
<     } else if (m == 0) {
<         lrs->topChunk = lrc->down;
<         JS_free(cx, lrc);
<     }
< }
< 
< void
< js_ForgetLocalRoot(JSContext *cx, jsval v)
< {
<     JSLocalRootStack *lrs;
<     uint32 i, j, m, n, mark;
<     JSLocalRootChunk *lrc, *lrc2;
<     jsval top;
< 
<     lrs = cx->localRootStack;
<     JS_ASSERT(lrs && lrs->rootCount);
<     if (!lrs || lrs->rootCount == 0)
<         return;
< 
<     /* Prepare to pop the top-most value from the stack. */
<     n = lrs->rootCount - 1;
<     m = n & JSLRS_CHUNK_MASK;
<     lrc = lrs->topChunk;
<     top = lrc->roots[m];
< 
<     /* Be paranoid about calls on an empty scope. */
<     mark = lrs->scopeMark;
<     JS_ASSERT(mark < n);
<     if (mark >= n)
<         return;
< 
<     /* If v was not the last root pushed in the top scope, find it. */
<     if (top != v) {
<         /* Search downward in case v was recently pushed. */
<         i = n;
<         j = m;
<         lrc2 = lrc;
<         while (--i > mark) {
<             if (j == 0)
<                 lrc2 = lrc2->down;
<             j = i & JSLRS_CHUNK_MASK;
<             if (lrc2->roots[j] == v)
<                 break;
<         }
< 
<         /* If we didn't find v in this scope, assert and bail out. */
<         JS_ASSERT(i != mark);
<         if (i == mark)
<             return;
< 
<         /* Swap top and v so common tail code can pop v. */
<         lrc2->roots[j] = top;
<     }
< 
<     /* Pop the last value from the stack. */
<     lrc->roots[m] = JSVAL_NULL;
<     lrs->rootCount = n;
<     if (m == 0) {
<         JS_ASSERT(n != 0);
<         JS_ASSERT(lrc != &lrs->firstChunk);
<         lrs->topChunk = lrc->down;
<         JS_free(cx, lrc);
<     }
< }
< 
< int
< js_PushLocalRoot(JSContext *cx, JSLocalRootStack *lrs, jsval v)
< {
<     uint32 n, m;
<     JSLocalRootChunk *lrc;
< 
<     n = lrs->rootCount;
<     m = n & JSLRS_CHUNK_MASK;
<     if (n == 0 || m != 0) {
<         /*
<          * At start of first chunk, or not at start of a non-first top chunk.
<          * Check for lrs->rootCount overflow.
<          */
<         if ((uint32)(n + 1) == 0) {
<             JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
<                                  JSMSG_TOO_MANY_LOCAL_ROOTS);
<             return -1;
<         }
<         lrc = lrs->topChunk;
<         JS_ASSERT(n != 0 || lrc == &lrs->firstChunk);
<     } else {
<         /*
<          * After lrs->firstChunk, trying to index at a power-of-two chunk
<          * boundary: need a new chunk.
<          */
<         lrc = (JSLocalRootChunk *) JS_malloc(cx, sizeof *lrc);
<         if (!lrc)
<             return -1;
<         lrc->down = lrs->topChunk;
<         lrs->topChunk = lrc;
<     }
<     lrs->rootCount = n + 1;
<     lrc->roots[m] = v;
<     return (int) n;
< }
< 
< void
< js_TraceLocalRoots(JSTracer *trc, JSLocalRootStack *lrs)
< {
<     uint32 n, m, mark;
<     JSLocalRootChunk *lrc;
<     jsval v;
< 
<     n = lrs->rootCount;
<     if (n == 0)
<         return;
< 
<     mark = lrs->scopeMark;
<     lrc = lrs->topChunk;
<     do {
<         while (--n > mark) {
<             m = n & JSLRS_CHUNK_MASK;
<             v = lrc->roots[m];
<             JS_ASSERT(JSVAL_IS_GCTHING(v) && v != JSVAL_NULL);
<             JS_SET_TRACING_INDEX(trc, "local_root", n);
<             js_CallValueTracerIfGCThing(trc, v);
<             if (m == 0)
<                 lrc = lrc->down;
<         }
<         m = n & JSLRS_CHUNK_MASK;
<         mark = JSVAL_TO_INT(lrc->roots[m]);
<         if (m == 0)
<             lrc = lrc->down;
<     } while (n != 0);
<     JS_ASSERT(!lrc);
< }
< 
842,843c317
<     JS_ASSERT(reportp);
<     if (reportp->errorNumber == JSMSG_UNCAUGHT_EXCEPTION)
---
>     if (reportp && reportp->errorNumber == JSMSG_UNCAUGHT_EXCEPTION)
845a320
> #if JS_HAS_ERROR_EXCEPTIONS
856,857c331,332
<     } else if (cx->debugHooks->debugErrorHook && cx->errorReporter) {
<         JSDebugErrorHook hook = cx->debugHooks->debugErrorHook;
---
>     } else if (cx->runtime->debugErrorHook && cx->errorReporter) {
>         JSDebugErrorHook hook = cx->runtime->debugErrorHook;
860c335
<             hook(cx, message, reportp, cx->debugHooks->debugErrorHookData);
---
>             hook(cx, message, reportp, cx->runtime->debugErrorHookData);
861a337,339
> #else
>     js_ReportErrorAgain(cx, message, reportp);
> #endif
872c350
< js_ReportOutOfMemory(JSContext *cx)
---
> js_ReportOutOfMemory(JSContext *cx, JSErrorCallback callback)
874c352
<     JSStackFrame *fp;
---
>     JSStackFrame *fp = cx->fp;
879,880c357
<     const JSErrorFormatString *efs =
<         js_GetLocalizedErrorMessage(cx, NULL, NULL, JSMSG_OUT_OF_MEMORY);
---
>     const JSErrorFormatString *efs = callback(NULL, NULL, JSMSG_OUT_OF_MEMORY);
883d359
<     /* Fill out the report, but don't do anything that requires allocation. */
885c361,362
<     report.flags = JSREPORT_ERROR;
---
> 
>     /* Fill out the report, but don't do anything that requires allocation. */
886a364
>     report.flags = JSREPORT_ERROR;
892,897c370,376
<     for (fp = cx->fp; fp; fp = fp->down) {
<         if (fp->script && fp->pc) {
<             report.filename = fp->script->filename;
<             report.lineno = js_PCToLineNumber(cx, fp->script, fp->pc);
<             break;
<         }
---
>     while (fp && (!fp->script || !fp->pc))
>         fp = fp->down;
> 
>     if (fp) {
>         report.filename = fp->script->filename;
>         report.lineno = js_PCToLineNumber(fp->script, fp->pc);
>         report.lscript = fp->script->lscript;	// !!dp
905c384
<         JSDebugErrorHook hook = cx->debugHooks->debugErrorHook;
---
>         JSDebugErrorHook hook = cx->runtime->debugErrorHook;
907c386
<             !hook(cx, msg, &report, cx->debugHooks->debugErrorHookData)) {
---
>             !hook(cx, msg, &report, cx->runtime->debugErrorHookData)) {
916,928d394
< void
< js_ReportOutOfScriptQuota(JSContext *cx)
< {
<     JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
<                          JSMSG_SCRIPT_STACK_QUOTA);
< }
< 
< void
< js_ReportOverRecursed(JSContext *cx)
< {
<     JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_OVER_RECURSED);
< }
< 
932,934d397
<     char *message;
<     jschar *ucmessage;
<     size_t messagelen;
936c399,400
<     JSErrorReport report;
---
>     JSErrorReport report, *reportp;
>     char *last;
942,945c406,408
<     message = JS_vsmprintf(format, ap);
<     if (!message)
<         return JS_FALSE;
<     messagelen = strlen(message);
---
>     /* Find the top-most active script frame, for best line number blame. */
>     for (fp = cx->fp; fp && (!fp->script || !fp->pc); fp = fp->down)
>         continue;
947c410,411
<     memset(&report, 0, sizeof (struct JSErrorReport));
---
>     reportp = &report;
>     memset(reportp, 0, sizeof (struct JSErrorReport));
949,958c413,417
<     report.errorNumber = JSMSG_USER_DEFINED_ERROR;
<     report.ucmessage = ucmessage = js_InflateString(cx, message, &messagelen);
< 
<     /* Find the top-most active script frame, for best line number blame. */
<     for (fp = cx->fp; fp; fp = fp->down) {
<         if (fp->script && fp->pc) {
<             report.filename = fp->script->filename;
<             report.lineno = js_PCToLineNumber(cx, fp->script, fp->pc);
<             break;
<         }
---
>     if (fp) {
>         report.filename = fp->script->filename;
>         report.lineno = js_PCToLineNumber(fp->script, fp->pc);
>         report.lscript =  fp->script->lscript;	// !!dp
>         /* XXX should fetch line somehow */
959a419,421
>     last = JS_vsmprintf(format, ap);
>     if (!last)
>         return JS_FALSE;
961c423,426
<     warning = JSREPORT_IS_WARNING(report.flags);
---
>     ReportError(cx, last, reportp);
>     xfree(last);
> 
>     warning = JSREPORT_IS_WARNING(reportp->flags);
963c428
<         report.flags &= ~JSREPORT_WARNING;
---
>         reportp->flags &= ~JSREPORT_WARNING;
966,969d430
< 
<     ReportError(cx, message, &report);
<     free(message);
<     JS_free(cx, ucmessage);
983a445,446
> 
> #ifdef _UTF8
992a456
> 	size_t mbLength;
1001,1005c465
< 
<     /* Most calls supply js_GetErrorMessage; if this is so, assume NULL. */
<     if (!callback || callback == js_GetErrorMessage)
<         efs = js_GetLocalizedErrorMessage(cx, userRef, NULL, errorNumber);
<     else
---
>     if (callback) {
1007,1012c467,501
<     if (efs) {
<         size_t totalArgsLength = 0;
<         size_t argLengths[10]; /* only {0} thru {9} supported */
<         argCount = efs->argCount;
<         JS_ASSERT(argCount <= 10);
<         if (argCount > 0) {
---
>         if (efs) {
>             size_t totalArgsLength = 0;
>             size_t argLengths[10]; /* only {0} thru {9} supported */
>             argCount = efs->argCount;
>             JS_ASSERT(argCount <= 10);
>             if (argCount > 0) {
>                 /*
>                  * Gather the arguments into an array, and accumulate
>                  * their sizes. We allocate 1 more than necessary and
>                  * null it out to act as the caboose when we free the
>                  * pointers later.
>                  */
>                 XMEMTAG("js_ExpandErrorArguments messageArgs ");
>                 reportp->messageArgs = (const jschar **)
>                     JS_malloc(cx, sizeof(jschar *) * (argCount + 1));
>                 if (!reportp->messageArgs)
>                     return JS_FALSE;
>                 reportp->messageArgs[argCount] = NULL;
>                 for (i = 0; i < argCount; i++) {
>                     if (charArgs) {
> 						size_t wLength;
>                         char *charArg = va_arg(ap, char *);
>                         reportp->messageArgs[i]
>                             = js_InflateString(cx, charArg, strlen(charArg),&wLength);
>                         if (!reportp->messageArgs[i])
>                             goto error;
>                     }
>                     else
>                         reportp->messageArgs[i] = va_arg(ap, jschar *);
>                     argLengths[i] = js_strlen(reportp->messageArgs[i]);
>                     totalArgsLength += argLengths[i];
>                 }
>                 /* NULL-terminate for easy copying. */
>                 reportp->messageArgs[i] = NULL;
>             }
1014,1017c503,504
<              * Gather the arguments into an array, and accumulate
<              * their sizes. We allocate 1 more than necessary and
<              * null it out to act as the caboose when we free the
<              * pointers later.
---
>              * Parse the error format, substituting the argument X
>              * for {X} in the format.
1019,1030c506,564
<             reportp->messageArgs = (const jschar **)
<                 JS_malloc(cx, sizeof(jschar *) * (argCount + 1));
<             if (!reportp->messageArgs)
<                 return JS_FALSE;
<             reportp->messageArgs[argCount] = NULL;
<             for (i = 0; i < argCount; i++) {
<                 if (charArgs) {
<                     char *charArg = va_arg(ap, char *);
<                     size_t charArgLength = strlen(charArg);
<                     reportp->messageArgs[i]
<                         = js_InflateString(cx, charArg, &charArgLength);
<                     if (!reportp->messageArgs[i])
---
>             if (argCount > 0) {
>                 if (efs->format) {
>                     const char *fmt;
>                     const jschar *arg;
>                     jschar *out;
>                     int expandedArgs = 0;
>                     size_t expandedLength
>                         = strlen(efs->format)
>                             - (3 * argCount) /* exclude the {n} */
>                             + totalArgsLength;
>                     /*
>                      * Note - the above calculation assumes that each argument
>                      * is used once and only once in the expansion !!!
>                      */
>                    	XMEMTAG("js_ExpandErrorArguments ucmessage ");
>                     reportp->ucmessage = out = (jschar *)
>                         JS_malloc(cx, (expandedLength + 1) * sizeof(jschar));
>                     if (!out)
>                         goto error;
>                     fmt = efs->format;
>                     while (*fmt) {
>                         if (*fmt == '{') {
>                             if (isdigit(fmt[1])) {
>                                 int d = JS7_UNDEC(fmt[1]);
>                                 JS_ASSERT(expandedArgs < argCount);
>                                 arg = reportp->messageArgs[d];
>                                 js_strncpy(out, arg, argLengths[d]);
>                                 out += argLengths[d];
>                                 fmt += 3;
>                                 expandedArgs++;
>                                 continue;
>                             }
>                         }
>                         /*
>                          * is this kosher?
>                          */
>                         *out++ = (unsigned char)(*fmt++);
>                     }
>                     JS_ASSERT(expandedArgs == argCount);
>                     *out = 0;
>                     *messagep =
>                         js_DeflateString(cx, reportp->ucmessage,
>                                          (size_t)(out - reportp->ucmessage),&mbLength);
>                     if (!*messagep)
>                         goto error;
>                 }
>             } else {
>                 /*
>                  * Zero arguments: the format string (if it exists) is the
>                  * entire message.
>                  */
>                 if (efs->format) {
> 					size_t wLength;
>                     *messagep = JS_strdup(cx, efs->format);
>                     if (!*messagep)
>                         goto error;
>                     reportp->ucmessage
>                         = js_InflateString(cx, *messagep, strlen(*messagep),&wLength);
>                     if (!reportp->ucmessage)
1032,1033d565
<                 } else {
<                     reportp->messageArgs[i] = va_arg(ap, jschar *);
1035,1036d566
<                 argLengths[i] = js_strlen(reportp->messageArgs[i]);
<                 totalArgsLength += argLengths[i];
1038,1039d567
<             /* NULL-terminate for easy copying. */
<             reportp->messageArgs[i] = NULL;
1041,1057c569,610
<         /*
<          * Parse the error format, substituting the argument X
<          * for {X} in the format.
<          */
<         if (argCount > 0) {
<             if (efs->format) {
<                 jschar *buffer, *fmt, *out;
<                 int expandedArgs = 0;
<                 size_t expandedLength;
<                 size_t len = strlen(efs->format);
< 
<                 buffer = fmt = js_InflateString (cx, efs->format, &len);
<                 if (!buffer)
<                     goto error;
<                 expandedLength = len
<                                  - (3 * argCount)       /* exclude the {n} */
<                                  + totalArgsLength;
---
>     }
>     if (*messagep == NULL) {
>         /* where's the right place for this ??? */
>         const char *defaultErrorMessage
>             = "No error message available for error number %d";
>         size_t nbytes = strlen(defaultErrorMessage) + 16;
>         XMEMTAG("js_ExpandErrorArguments messagep ");
>         *messagep = (char *)JS_malloc(cx, nbytes);
>         if (!*messagep)
>             goto error;
>         JS_snprintf(*messagep, nbytes, defaultErrorMessage, errorNumber);
>     }
>     return JS_TRUE;
> 
> error:
>     if (reportp->messageArgs) {
>         i = 0;
>         while (reportp->messageArgs[i])
>             JS_free(cx, (void *)reportp->messageArgs[i++]);
>         JS_free(cx, (void *)reportp->messageArgs);
>         reportp->messageArgs = NULL;
>     }
>     if (reportp->ucmessage) {
>         JS_free(cx, (void *)reportp->ucmessage);
>         reportp->ucmessage = NULL;
>     }
>     if (*messagep) {
>         JS_free(cx, (void *)*messagep);
>         *messagep = NULL;
>     }
>     return JS_FALSE;
> }
> #else //#ifdef _UTF8
> JSBool
> js_ExpandErrorArguments(JSContext *cx, JSErrorCallback callback,
>                         void *userRef, const uintN errorNumber,
>                         char **messagep, JSErrorReport *reportp,
>                         JSBool *warningp, JSBool charArgs, va_list ap)
> {
>     const JSErrorFormatString *efs;
>     int i;
>     int argCount;
1058a612,626
>     *warningp = JSREPORT_IS_WARNING(reportp->flags);
>     if (*warningp && JS_HAS_WERROR_OPTION(cx)) {
>         reportp->flags &= ~JSREPORT_WARNING;
>         *warningp = JS_FALSE;
>     }
> 
>     *messagep = NULL;
>     if (callback) {
>         efs = callback(userRef, NULL, errorNumber);
>         if (efs) {
>             size_t totalArgsLength = 0;
>             size_t argLengths[10]; /* only {0} thru {9} supported */
>             argCount = efs->argCount;
>             JS_ASSERT(argCount <= 10);
>             if (argCount > 0) {
1060,1080c628,645
<                 * Note - the above calculation assumes that each argument
<                 * is used once and only once in the expansion !!!
<                 */
<                 reportp->ucmessage = out = (jschar *)
<                     JS_malloc(cx, (expandedLength + 1) * sizeof(jschar));
<                 if (!out) {
<                     JS_free (cx, buffer);
<                     goto error;
<                 }
<                 while (*fmt) {
<                     if (*fmt == '{') {
<                         if (isdigit(fmt[1])) {
<                             int d = JS7_UNDEC(fmt[1]);
<                             JS_ASSERT(d < argCount);
<                             js_strncpy(out, reportp->messageArgs[d],
<                                        argLengths[d]);
<                             out += argLengths[d];
<                             fmt += 3;
<                             expandedArgs++;
<                             continue;
<                         }
---
>                  * Gather the arguments into an array, and accumulate
>                  * their sizes. We allocate 1 more than necessary and
>                  * null it out to act as the caboose when we free the
>                  * pointers later.
>                  */
>                 XMEMTAG("js_ExpandErrorArguments messageArgs ");
>                 reportp->messageArgs = (const jschar **)
>                     JS_malloc(cx, sizeof(jschar *) * (argCount + 1));
>                 if (!reportp->messageArgs)
>                     return JS_FALSE;
>                 reportp->messageArgs[argCount] = NULL;
>                 for (i = 0; i < argCount; i++) {
>                     if (charArgs) {
>                         char *charArg = va_arg(ap, char *);
>                         reportp->messageArgs[i]
>                             = js_InflateString(cx, charArg, strlen(charArg));
>                         if (!reportp->messageArgs[i])
>                             goto error;
1082c647,650
<                     *out++ = *fmt++;
---
>                     else
>                         reportp->messageArgs[i] = va_arg(ap, jschar *);
>                     argLengths[i] = js_strlen(reportp->messageArgs[i]);
>                     totalArgsLength += argLengths[i];
1084,1091c652,653
<                 JS_ASSERT(expandedArgs == argCount);
<                 *out = 0;
<                 JS_free (cx, buffer);
<                 *messagep =
<                     js_DeflateString(cx, reportp->ucmessage,
<                                      (size_t)(out - reportp->ucmessage));
<                 if (!*messagep)
<                     goto error;
---
>                 /* NULL-terminate for easy copying. */
>                 reportp->messageArgs[i] = NULL;
1093d654
<         } else {
1095,1096c656,657
<              * Zero arguments: the format string (if it exists) is the
<              * entire message.
---
>              * Parse the error format, substituting the argument X
>              * for {X} in the format.
1098,1106c659,718
<             if (efs->format) {
<                 size_t len;
<                 *messagep = JS_strdup(cx, efs->format);
<                 if (!*messagep)
<                     goto error;
<                 len = strlen(*messagep);
<                 reportp->ucmessage = js_InflateString(cx, *messagep, &len);
<                 if (!reportp->ucmessage)
<                     goto error;
---
>             if (argCount > 0) {
>                 if (efs->format) {
>                     const char *fmt;
>                     const jschar *arg;
>                     jschar *out;
>                     int expandedArgs = 0;
>                     size_t expandedLength
>                         = strlen(efs->format)
>                             - (3 * argCount) /* exclude the {n} */
>                             + totalArgsLength;
>                     /*
>                      * Note - the above calculation assumes that each argument
>                      * is used once and only once in the expansion !!!
>                      */
>                    	XMEMTAG("js_ExpandErrorArguments ucmessage ");
>                     reportp->ucmessage = out = (jschar *)
>                         JS_malloc(cx, (expandedLength + 1) * sizeof(jschar));
>                     if (!out)
>                         goto error;
>                     fmt = efs->format;
>                     while (*fmt) {
>                         if (*fmt == '{') {
>                             if (isdigit(fmt[1])) {
>                                 int d = JS7_UNDEC(fmt[1]);
>                                 JS_ASSERT(expandedArgs < argCount);
>                                 arg = reportp->messageArgs[d];
>                                 js_strncpy(out, arg, argLengths[d]);
>                                 out += argLengths[d];
>                                 fmt += 3;
>                                 expandedArgs++;
>                                 continue;
>                             }
>                         }
>                         /*
>                          * is this kosher?
>                          */
>                         *out++ = (unsigned char)(*fmt++);
>                     }
>                     JS_ASSERT(expandedArgs == argCount);
>                     *out = 0;
>                     *messagep =
>                         js_DeflateString(cx, reportp->ucmessage,
>                                          (size_t)(out - reportp->ucmessage));
>                     if (!*messagep)
>                         goto error;
>                 }
>             } else {
>                 /*
>                  * Zero arguments: the format string (if it exists) is the
>                  * entire message.
>                  */
>                 if (efs->format) {
>                     *messagep = JS_strdup(cx, efs->format);
>                     if (!*messagep)
>                         goto error;
>                     reportp->ucmessage
>                         = js_InflateString(cx, *messagep, strlen(*messagep));
>                     if (!reportp->ucmessage)
>                         goto error;
>                 }
1114a727
>         XMEMTAG("js_ExpandErrorArguments messagep ");
1124,1129c737,739
<         /* free the arguments only if we allocated them */
<         if (charArgs) {
<             i = 0;
<             while (reportp->messageArgs[i])
<                 JS_free(cx, (void *)reportp->messageArgs[i++]);
<         }
---
>         i = 0;
>         while (reportp->messageArgs[i])
>             JS_free(cx, (void *)reportp->messageArgs[i++]);
1142a753,754
> #endif //#ifdef _UTF8
> 
1157c769,796
<     memset(&report, 0, sizeof (struct JSErrorReport));
---
>     memset(&report, 0, sizeof (struct JSErrorReport));	// !!dp
>     //report.messageArgs = NULL;
>     //report.ucmessage = NULL;
> 	//message = NULL;
> 
>     fp = cx->fp;
>     if (fp && fp->script && fp->pc) {
>         report.filename = fp->script->filename;
>         report.lineno = js_PCToLineNumber(fp->script, fp->pc);
>         report.lscript = fp->script->lscript;	// !!dp
>     } else {
>         /*  We can't find out where the error was from the current
>             frame so see if the next frame has a script/pc combo we
>             could use */
>         if (fp && fp->down && fp->down->script && fp->down->pc) {
>             report.filename = fp->down->script->filename;
>             report.lineno = js_PCToLineNumber(fp->down->script, fp->down->pc);
>           	report.lscript = fp->down->script->lscript;	// !!dp
>       }
>         else {
>             report.filename = NULL;
>             report.lineno = 0;
>         }
>     }
> 
>     /* XXX should fetch line somehow */
>     report.linebuf = NULL;
>     report.tokenptr = NULL;
1162,1163c801,802
<      * If we can't find out where the error was based on the current frame,
<      * see if the next frame has a script/pc combo we can use.
---
>      * XXX js_ExpandErrorArguments only sometimes fills these in, so we
>      * initialize them to clear garbage.
1165,1171c804,807
<     for (fp = cx->fp; fp; fp = fp->down) {
<         if (fp->script && fp->pc) {
<             report.filename = fp->script->filename;
<             report.lineno = js_PCToLineNumber(cx, fp->script, fp->pc);
<             break;
<         }
<     }
---
>     report.uclinebuf = NULL;
>     report.uctokenptr = NULL;
>     report.ucmessage = NULL;
>     report.messageArgs = NULL;
1183,1191c819,821
<         /*
<          * js_ExpandErrorArguments owns its messageArgs only if it had to
<          * inflate the arguments (from regular |char *|s).
<          */
<         if (charArgs) {
<             int i = 0;
<             while (report.messageArgs[i])
<                 JS_free(cx, (void *)report.messageArgs[i++]);
<         }
---
>         int i = 0;
>         while (report.messageArgs[i])
>             JS_free(cx, (void *)report.messageArgs[i++]);
1209c839
<         free(cx->lastMessage);
---
>         xfree(cx->lastMessage);
1220c850
<         JSDebugErrorHook hook = cx->debugHooks->debugErrorHook;
---
>         JSDebugErrorHook hook = cx->runtime->debugErrorHook;
1223c853
<                   cx->debugHooks->debugErrorHookData)) {
---
>                   cx->runtime->debugErrorHookData)) {
1237,1290d866
< JSBool
< js_ReportIsNullOrUndefined(JSContext *cx, intN spindex, jsval v,
<                            JSString *fallback)
< {
<     char *bytes;
<     JSBool ok;
< 
<     bytes = js_DecompileValueGenerator(cx, spindex, v, fallback);
<     if (!bytes)
<         return JS_FALSE;
< 
<     if (strcmp(bytes, js_undefined_str) == 0 ||
<         strcmp(bytes, js_null_str) == 0) {
<         ok = JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR,
<                                           js_GetErrorMessage, NULL,
<                                           JSMSG_NO_PROPERTIES, bytes,
<                                           NULL, NULL);
<     } else if (JSVAL_IS_VOID(v)) {
<         ok = JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR,
<                                           js_GetErrorMessage, NULL,
<                                           JSMSG_NULL_OR_UNDEFINED, bytes,
<                                           js_undefined_str, NULL);
<     } else {
<         JS_ASSERT(JSVAL_IS_NULL(v));
<         ok = JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR,
<                                           js_GetErrorMessage, NULL,
<                                           JSMSG_NULL_OR_UNDEFINED, bytes,
<                                           js_null_str, NULL);
<     }
< 
<     JS_free(cx, bytes);
<     return ok;
< }
< 
< JSBool
< js_ReportValueErrorFlags(JSContext *cx, uintN flags, const uintN errorNumber,
<                          intN spindex, jsval v, JSString *fallback,
<                          const char *arg1, const char *arg2)
< {
<     char *bytes;
<     JSBool ok;
< 
<     JS_ASSERT(js_ErrorFormatString[errorNumber].argCount >= 1);
<     JS_ASSERT(js_ErrorFormatString[errorNumber].argCount <= 3);
<     bytes = js_DecompileValueGenerator(cx, spindex, v, fallback);
<     if (!bytes)
<         return JS_FALSE;
< 
<     ok = JS_ReportErrorFlagsAndNumber(cx, flags, js_GetErrorMessage,
<                                       NULL, errorNumber, bytes, arg1, arg2);
<     JS_free(cx, bytes);
<     return ok;
< }
< 
1297a874,877
> #if JS_HAS_DFLT_MSG_STRINGS
> #define MSG_DEF(name, number, count, exception, format) \
>     { format, count } ,
> #else
1299c879,880
<     { format, count, exception } ,
---
>     { NULL, count } ,
> #endif
1311,1335d891
< 
< JSBool
< js_ResetOperationCount(JSContext *cx)
< {
<     JSScript *script;
< 
<     JS_ASSERT(cx->operationCount <= 0);
<     JS_ASSERT(cx->operationLimit > 0);
< 
<     cx->operationCount = (int32) cx->operationLimit;
<     if (cx->operationCallbackIsSet)
<         return cx->operationCallback(cx);
< 
<     if (cx->operationCallback) {
<         /*
<          * Invoke the deprecated branch callback. It may be called only when
<          * the top-most frame is scripted or JSOPTION_NATIVE_BRANCH_CALLBACK
<          * is set.
<          */
<         script = cx->fp ? cx->fp->script : NULL;
<         if (script || JS_HAS_OPTION(cx, JSOPTION_NATIVE_BRANCH_CALLBACK))
<             return ((JSBranchCallback) cx->operationCallback)(cx, script);
<     }
<     return JS_TRUE;
< }
diff -r /Volumes/Swap/js-14-2-2008/js/src/jscntxt.h /Volumes/Swap/js_D11/src/jscntxt.h
2d1
<  * vim: set ts=8 sw=4 et tw=78:
4,15c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
20,23c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
27,39c23,33
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
58d51
< #include "jsutil.h"
62,151c55
< /*
<  * js_GetSrcNote cache to avoid O(n^2) growth in finding a source note for a
<  * given pc in a script.
<  */
< typedef struct JSGSNCache {
<     JSScript        *script;
<     JSDHashTable    table;
< #ifdef JS_GSNMETER
<     uint32          hits;
<     uint32          misses;
<     uint32          fills;
<     uint32          clears;
< # define GSN_CACHE_METER(cache,cnt) (++(cache)->cnt)
< #else
< # define GSN_CACHE_METER(cache,cnt) /* nothing */
< #endif
< } JSGSNCache;
< 
< #define GSN_CACHE_CLEAR(cache)                                                \
<     JS_BEGIN_MACRO                                                            \
<         (cache)->script = NULL;                                               \
<         if ((cache)->table.ops) {                                             \
<             JS_DHashTableFinish(&(cache)->table);                             \
<             (cache)->table.ops = NULL;                                        \
<         }                                                                     \
<         GSN_CACHE_METER(cache, clears);                                       \
<     JS_END_MACRO
< 
< /* These helper macros take a cx as parameter and operate on its GSN cache. */
< #define JS_CLEAR_GSN_CACHE(cx)      GSN_CACHE_CLEAR(&JS_GSN_CACHE(cx))
< #define JS_METER_GSN_CACHE(cx,cnt)  GSN_CACHE_METER(&JS_GSN_CACHE(cx), cnt)
< 
< #ifdef JS_THREADSAFE
< 
< /*
<  * Structure uniquely representing a thread.  It holds thread-private data
<  * that can be accessed without a global lock.
<  */
< struct JSThread {
<     /* Linked list of all contexts active on this thread. */
<     JSCList             contextList;
< 
<     /* Opaque thread-id, from NSPR's PR_GetCurrentThread(). */
<     jsword              id;
< 
<     /* Thread-local gc free lists array. */
<     JSGCThing           *gcFreeLists[GC_NUM_FREELISTS];
< 
<     /*
<      * Thread-local version of JSRuntime.gcMallocBytes to avoid taking
<      * locks on each JS_malloc.
<      */
<     uint32              gcMallocBytes;
< 
<     /*
<      * Store the GSN cache in struct JSThread, not struct JSContext, both to
<      * save space and to simplify cleanup in js_GC.  Any embedding (Firefox
<      * or another Gecko application) that uses many contexts per thread is
<      * unlikely to interleave js_GetSrcNote-intensive loops in the decompiler
<      * among two or more contexts running script in one thread.
<      */
<     JSGSNCache          gsnCache;
< 
<     /* Property cache for faster call/get/set invocation. */
<     JSPropertyCache     propertyCache;
< };
< 
< #define JS_GSN_CACHE(cx)        ((cx)->thread->gsnCache)
< #define JS_PROPERTY_CACHE(cx)   ((cx)->thread->propertyCache)
< 
< extern void JS_DLL_CALLBACK
< js_ThreadDestructorCB(void *ptr);
< 
< extern JSBool
< js_SetContextThread(JSContext *cx);
< 
< extern void
< js_ClearContextThread(JSContext *cx);
< 
< extern JSThread *
< js_GetCurrentThread(JSRuntime *rt);
< 
< #endif /* JS_THREADSAFE */
< 
< typedef enum JSDestroyContextMode {
<     JSDCM_NO_GC,
<     JSDCM_MAYBE_GC,
<     JSDCM_FORCE_GC,
<     JSDCM_NEW_FAILED
< } JSDestroyContextMode;
---
> typedef enum JSGCMode { JS_NO_GC, JS_MAYBE_GC, JS_FORCE_GC } JSGCMode;
165,179d68
< /*
<  * Forward declaration for opaque JSRuntime.nativeIteratorStates.
<  */
< typedef struct JSNativeIteratorState JSNativeIteratorState;
< 
< typedef struct JSSetSlotRequest JSSetSlotRequest;
< 
< struct JSSetSlotRequest {
<     JSObject            *obj;           /* object containing slot to set */
<     JSObject            *pobj;          /* new proto or parent reference */
<     uint16              slot;           /* which to set, proto or parent */
<     uint16              errnum;         /* JSMSG_NO_ERROR or error result */
<     JSSetSlotRequest    *next;          /* next request in GC worklist */
< };
< 
184,186d72
<     /* Context create/destroy callback. */
<     JSContextCallback   cxCallback;
< 
188,189c74
<     JSGCChunkInfo       *gcChunkList;
<     JSGCArenaList       gcArenaList[GC_NUM_FREELISTS];
---
>     JSArenaPool         gcArenaPool;
192c77,78
<     jsrefcount          gcKeepAtoms;
---
>     JSGCThing           *gcFreeList;
>     jsrefcount          gcDisabled;
196,197d81
<     uint32              gcMaxMallocBytes;
<     uint32              gcStackPoolLifespan;
200,207d83
<     JSTracer            *gcMarkingTracer;
< 
<     /*
<      * NB: do not pack another flag here by claiming gcPadding unless the new
<      * flag is written only by the GC thread.  Atomic updates to packed bytes
<      * are not guaranteed, so stores issued by one thread may be lost due to
<      * unsynchronized read-modify-write cycles on other threads.
<      */
210,214d85
<     uint16              gcPadding;
< #ifdef JS_GC_ZEAL
<     jsrefcount          gcZeal;
< #endif
< 
217,219c88,89
<     JSGCArenaInfo       *gcUntracedArenaStackTop;
< #ifdef DEBUG
<     size_t              gcTraceLaterCount;
---
> #ifdef JS_GCMETER
>     JSGCStats           gcStats;
222,241c92,93
<     /*
<      * Table for tracking iterators to ensure that we close iterator's state
<      * before finalizing the iterable object.
<      */
<     JSPtrTable          gcIteratorTable;
< 
<     /*
<      * The trace operation and its data argument to trace embedding-specific
<      * GC roots.
<      */
<     JSTraceDataOp       gcExtraRootsTraceOp;
<     void                *gcExtraRootsData;
< 
<     /*
<      * Used to serialize cycle checks when setting __proto__ or __parent__ by
<      * requesting the GC handle the required cycle detection. If the GC hasn't
<      * been poked, it won't scan for garbage. This member is protected by
<      * rt->gcLock.
<      */
<     JSSetSlotRequest    *setSlotRequests;
---
>     /* Literal table maintained by jsatom.c functions. */
>     JSAtomState         atomState;
256,267c108
< #ifdef JS_THREADSAFE
<     JSLock              *deflatedStringCacheLock;
< #endif
<     JSHashTable         *deflatedStringCache;
< #ifdef DEBUG
<     uint32              deflatedStringCacheBytes;
< #endif
< 
<     /*
<      * Empty and unit-length strings held for use by this runtime's contexts.
<      * The unitStrings array and its elements are created on demand.
<      */
---
>     /* Empty string held for use by this runtime's contexts. */
269d109
<     JSString            **unitStrings;
274,275c114,134
<     /* Per runtime debug hooks -- see jsprvtd.h and jsdbgapi.h. */
<     JSDebugHooks        globalDebugHooks;
---
>     /* These are used for debugging -- see jsprvtd.h and jsdbgapi.h. */
>     JSTrapHandler       interruptHandler;
>     void                *interruptHandlerData;
>     JSNewScriptHook     newScriptHook;
>     void                *newScriptHookData;
>     JSDestroyScriptHook destroyScriptHook;
>     void                *destroyScriptHookData;
>     JSTrapHandler       debuggerHandler;
>     void                *debuggerHandlerData;
>     JSSourceHandler     sourceHandler;
>     void                *sourceHandlerData;
>     JSInterpreterHook   executeHook;
>     void                *executeHookData;
>     JSInterpreterHook   callHook;
>     void                *callHookData;
>     JSObjectHook        objectHook;
>     void                *objectHookData;
>     JSTrapHandler       throwHook;
>     void                *throwHookData;
>     JSDebugErrorHook    debugErrorHook;
>     void                *debugErrorHookData;
280a140,143
>     /* Weak links to properties, indexed by quickened get/set opcodes. */
>     /* XXX must come after JSCLists or MSVC alignment bug bites empty lists */
>     JSPropertyCache     propertyCache;
> 
290c153
<     JSThread            *gcThread;
---
>     jsword              gcThread;
300a164,169
>     /* Used to serialize cycle checks when setting __proto__ or __parent__. */
>     PRLock              *setSlotLock;
>     PRCondVar           *setSlotDone;
>     JSBool              setSlotBusy;
>     JSScope             *setSlotScope;  /* deadlock avoidance, see jslock.c */
> 
322,329d190
< 
<     /*
<      * Lock serializing trapList and watchPointList accesses, and count of all
<      * mutations to trapList and watchPointList made by debugger threads.  To
<      * keep the code simple, we define debuggerMutations for the thread-unsafe
<      * case too.
<      */
<     PRLock              *debuggerLock;
331d191
<     uint32              debuggerMutations;
342,350c202
<     /* Optional hook to find principals for an object in this runtime. */
<     JSObjectPrincipalsFinder findObjectPrincipals;
< 
<     /*
<      * Shared scope property tree, and arena-pool for allocating its nodes.
<      * The propertyRemovals counter is incremented for every js_ClearScope,
<      * and for each js_RemoveScopeProperty that frees a slot in an object.
<      * See js_NativeGet and js_NativeSet in jsobj.c.
<      */
---
>     /* Shared scope property tree, and allocator for its nodes. */
354,366d205
<     int32               propertyRemovals;
< 
<     /* Script filename table. */
<     struct JSHashTable  *scriptFilenameTable;
<     JSCList             scriptFilenamePrefixes;
< #ifdef JS_THREADSAFE
<     PRLock              *scriptFilenameTableLock;
< #endif
< 
<     /* Number localization, used by jsnum.c */
<     const char          *thousandsSeparator;
<     const char          *decimalSeparator;
<     const char          *numGrouping;
368,423c207
<     /*
<      * Weak references to lazily-created, well-known XML singletons.
<      *
<      * NB: Singleton objects must be carefully disconnected from the rest of
<      * the object graph usually associated with a JSContext's global object,
<      * including the set of standard class objects.  See jsxml.c for details.
<      */
<     JSObject            *anynameObject;
<     JSObject            *functionNamespaceObject;
< 
<     /*
<      * A helper list for the GC, so it can mark native iterator states. See
<      * js_TraceNativeIteratorStates for details.
<      */
<     JSNativeIteratorState *nativeIteratorStates;
< 
< #ifndef JS_THREADSAFE
<     /*
<      * For thread-unsafe embeddings, the GSN cache lives in the runtime and
<      * not each context, since we expect it to be filled once when decompiling
<      * a longer script, then hit repeatedly as js_GetSrcNote is called during
<      * the decompiler activation that filled it.
<      */
<     JSGSNCache          gsnCache;
< 
<     /* Property cache for faster call/get/set invocation. */
<     JSPropertyCache     propertyCache;
< 
< #define JS_GSN_CACHE(cx)        ((cx)->runtime->gsnCache)
< #define JS_PROPERTY_CACHE(cx)   ((cx)->runtime->propertyCache)
< #endif
< 
<     /*
<      * Object shape (property cache structural type) identifier generator.
<      *
<      * Type 0 stands for the empty scope, and must not be regenerated due to
<      * uint32 wrap-around. Since we use atomic pre-increment, the initial
<      * value for the first typed non-empty scope will be 1.
<      *
<      * The GC compresses live types, minimizing rt->shapeGen in the process.
<      * If this counter overflows into SHAPE_OVERFLOW_BIT (in jsinterp.h), the
<      * GC will disable property caches for all threads, to avoid aliasing two
<      * different types. Updated by js_GenerateShape (in jsinterp.c).
<      */
<     uint32              shapeGen;
< 
<     /* Literal table maintained by jsatom.c functions. */
<     JSAtomState         atomState;
< 
<     /*
<      * Various metering fields are defined at the end of JSRuntime. In this
<      * way there is no need to recompile all the code that refers to other
<      * fields of JSRuntime after enabling the corresponding metering macro.
<      */
< 
< #if defined DEBUG || defined JS_DUMP_PROPTREE_STATS
---
> #ifdef DEBUG
437a222
>     jsrefcount          badUndependStrings;
439d223
<     jsrefcount          liveScopePropsPreSweep;
452d235
<     jsrefcount          badUndependStrings;
457,476d239
< #endif /* DEBUG || JS_DUMP_PROPTREE_STATS */
< 
< #ifdef JS_SCOPE_DEPTH_METER
<     /*
<      * Stats on runtime prototype chain lookups and scope chain depths, i.e.,
<      * counts of objects traversed on a chain until the wanted id is found.
<      */
<     JSBasicStats        protoLookupDepthStats;
<     JSBasicStats        scopeSearchDepthStats;
< 
<     /*
<      * Stats on compile-time host environment and lexical scope chain lengths
<      * (maximum depths).
<      */
<     JSBasicStats        hostenvScopeDepthStats;
<     JSBasicStats        lexicalScopeDepthStats;
< #endif
< 
< #ifdef JS_GCMETER
<     JSGCStats           gcStats;
488,489c251,252
< #define JS_KEEP_ATOMS(rt)   JS_ATOMIC_INCREMENT(&(rt)->gcKeepAtoms);
< #define JS_UNKEEP_ATOMS(rt) JS_ATOMIC_DECREMENT(&(rt)->gcKeepAtoms);
---
> #define JS_ENABLE_GC(rt)    JS_ATOMIC_DECREMENT(&(rt)->gcDisabled);
> #define JS_DISABLE_GC(rt)   JS_ATOMIC_INCREMENT(&(rt)->gcDisabled);
511a275
> 
526d289
<     uint32              flags;
529,644d291
< #define JSRESFLAG_LOOKUP        0x1     /* resolving id from lookup */
< #define JSRESFLAG_WATCH         0x2     /* resolving id from watch */
< 
< typedef struct JSLocalRootChunk JSLocalRootChunk;
< 
< #define JSLRS_CHUNK_SHIFT       8
< #define JSLRS_CHUNK_SIZE        JS_BIT(JSLRS_CHUNK_SHIFT)
< #define JSLRS_CHUNK_MASK        JS_BITMASK(JSLRS_CHUNK_SHIFT)
< 
< struct JSLocalRootChunk {
<     jsval               roots[JSLRS_CHUNK_SIZE];
<     JSLocalRootChunk    *down;
< };
< 
< typedef struct JSLocalRootStack {
<     uint32              scopeMark;
<     uint32              rootCount;
<     JSLocalRootChunk    *topChunk;
<     JSLocalRootChunk    firstChunk;
< } JSLocalRootStack;
< 
< #define JSLRS_NULL_MARK ((uint32) -1)
< 
< /*
<  * Macros to push/pop JSTempValueRooter instances to context-linked stack of
<  * temporary GC roots. If you need to protect a result value that flows out of
<  * a C function across several layers of other functions, use the
<  * js_LeaveLocalRootScopeWithResult internal API (see further below) instead.
<  *
<  * The macros also provide a simple way to get a single rooted pointer via
<  * JS_PUSH_TEMP_ROOT_<KIND>(cx, NULL, &tvr). Then &tvr.u.<kind> gives the
<  * necessary pointer.
<  *
<  * JSTempValueRooter.count defines the type of the rooted value referenced by
<  * JSTempValueRooter.u union of type JSTempValueUnion. When count is positive
<  * or zero, u.array points to a vector of jsvals. Otherwise it must be one of
<  * the following constants:
<  */
< #define JSTVU_SINGLE        (-1)    /* u.value or u.<gcthing> is single jsval
<                                        or GC-thing */
< #define JSTVU_TRACE         (-2)    /* u.trace is a hook to trace a custom
<                                      * structure */
< #define JSTVU_SPROP         (-3)    /* u.sprop roots property tree node */
< #define JSTVU_WEAK_ROOTS    (-4)    /* u.weakRoots points to saved weak roots */
< #define JSTVU_PARSE_CONTEXT (-5)    /* u.parseContext roots JSParseContext* */
< #define JSTVU_SCRIPT        (-6)    /* u.script roots JSScript* */
< 
< /*
<  * Here single JSTVU_SINGLE covers both jsval and pointers to any GC-thing via
<  * reinterpreting the thing as JSVAL_OBJECT. It works because the GC-thing is
<  * aligned on a 0 mod 8 boundary, and object has the 0 jsval tag. So any
<  * GC-thing may be tagged as if it were an object and untagged, if it's then
<  * used only as an opaque pointer until discriminated by other means than tag
<  * bits. This is how, for example, js_GetGCThingTraceKind uses its |thing|
<  * parameter -- it consults GC-thing flags stored separately from the thing to
<  * decide the kind of thing.
<  *
<  * The following checks that this type-punning is possible.
<  */
< JS_STATIC_ASSERT(sizeof(JSTempValueUnion) == sizeof(jsval));
< JS_STATIC_ASSERT(sizeof(JSTempValueUnion) == sizeof(void *));
< 
< #define JS_PUSH_TEMP_ROOT_COMMON(cx,x,tvr,cnt,kind)                           \
<     JS_BEGIN_MACRO                                                            \
<         JS_ASSERT((cx)->tempValueRooters != (tvr));                           \
<         (tvr)->count = (cnt);                                                 \
<         (tvr)->u.kind = (x);                                                  \
<         (tvr)->down = (cx)->tempValueRooters;                                 \
<         (cx)->tempValueRooters = (tvr);                                       \
<     JS_END_MACRO
< 
< #define JS_POP_TEMP_ROOT(cx,tvr)                                              \
<     JS_BEGIN_MACRO                                                            \
<         JS_ASSERT((cx)->tempValueRooters == (tvr));                           \
<         (cx)->tempValueRooters = (tvr)->down;                                 \
<     JS_END_MACRO
< 
< #define JS_PUSH_TEMP_ROOT(cx,cnt,arr,tvr)                                     \
<     JS_BEGIN_MACRO                                                            \
<         JS_ASSERT((int)(cnt) >= 0);                                           \
<         JS_PUSH_TEMP_ROOT_COMMON(cx, arr, tvr, (ptrdiff_t) (cnt), array);     \
<     JS_END_MACRO
< 
< #define JS_PUSH_SINGLE_TEMP_ROOT(cx,val,tvr)                                  \
<     JS_PUSH_TEMP_ROOT_COMMON(cx, val, tvr, JSTVU_SINGLE, value)
< 
< #define JS_PUSH_TEMP_ROOT_OBJECT(cx,obj,tvr)                                  \
<     JS_PUSH_TEMP_ROOT_COMMON(cx, obj, tvr, JSTVU_SINGLE, object)
< 
< #define JS_PUSH_TEMP_ROOT_STRING(cx,str,tvr)                                  \
<     JS_PUSH_TEMP_ROOT_COMMON(cx, str, tvr, JSTVU_SINGLE, string)
< 
< #define JS_PUSH_TEMP_ROOT_FUNCTION(cx,fun,tvr)                                \
<     JS_PUSH_TEMP_ROOT_COMMON(cx, fun, tvr, JSTVU_SINGLE, function)
< 
< #define JS_PUSH_TEMP_ROOT_QNAME(cx,qn,tvr)                                    \
<     JS_PUSH_TEMP_ROOT_COMMON(cx, qn, tvr, JSTVU_SINGLE, qname)
< 
< #define JS_PUSH_TEMP_ROOT_XML(cx,xml_,tvr)                                    \
<     JS_PUSH_TEMP_ROOT_COMMON(cx, xml_, tvr, JSTVU_SINGLE, xml)
< 
< #define JS_PUSH_TEMP_ROOT_TRACE(cx,trace_,tvr)                                \
<     JS_PUSH_TEMP_ROOT_COMMON(cx, trace_, tvr, JSTVU_TRACE, trace)
< 
< #define JS_PUSH_TEMP_ROOT_SPROP(cx,sprop_,tvr)                                \
<     JS_PUSH_TEMP_ROOT_COMMON(cx, sprop_, tvr, JSTVU_SPROP, sprop)
< 
< #define JS_PUSH_TEMP_ROOT_WEAK_COPY(cx,weakRoots_,tvr)                        \
<     JS_PUSH_TEMP_ROOT_COMMON(cx, weakRoots_, tvr, JSTVU_WEAK_ROOTS, weakRoots)
< 
< #define JS_PUSH_TEMP_ROOT_PARSE_CONTEXT(cx,pc,tvr)                            \
<     JS_PUSH_TEMP_ROOT_COMMON(cx, pc, tvr, JSTVU_PARSE_CONTEXT, parseContext)
< 
< #define JS_PUSH_TEMP_ROOT_SCRIPT(cx,script_,tvr)                              \
<     JS_PUSH_TEMP_ROOT_COMMON(cx, script_, tvr, JSTVU_SCRIPT, script)
< 
646d292
<     /* JSRuntime contextList linkage. */
649,711c295,296
<     /*
<      * Operation count. It is declared early in the structure as a frequently
<      * accessed field.
<      */
<     int32               operationCount;
< 
< #if JS_HAS_XML_SUPPORT
<     /*
<      * Bit-set formed from binary exponentials of the XML_* tiny-ids defined
<      * for boolean settings in jsxml.c, plus an XSF_CACHE_VALID bit.  Together
<      * these act as a cache of the boolean XML.ignore* and XML.prettyPrinting
<      * property values associated with this context's global object.
<      */
<     uint8               xmlSettingFlags;
<     uint8               padding;
< #else
<     uint16              padding;
< #endif
< 
<     /* Runtime version control identifier. */
<     uint16              version;
< 
<     /* Per-context options. */
<     uint32              options;            /* see jsapi.h for JSOPTION_* */
< 
<     /* Locale specific callbacks for string conversion. */
<     JSLocaleCallbacks   *localeCallbacks;
< 
<     /*
<      * cx->resolvingTable is non-null and non-empty if we are initializing
<      * standard classes lazily, or if we are otherwise recursing indirectly
<      * from js_LookupProperty through a JSClass.resolve hook.  It is used to
<      * limit runaway recursion (see jsapi.c and jsobj.c).
<      */
<     JSDHashTable        *resolvingTable;
< 
< #if JS_HAS_LVALUE_RETURN
<     /*
<      * Secondary return value from native method called on the left-hand side
<      * of an assignment operator.  The native should store the object in which
<      * to set a property in *rval, and return the property's id expressed as a
<      * jsval by calling JS_SetCallReturnValue2(cx, idval).
<      */
<     jsval               rval2;
<     JSPackedBool        rval2set;
< #endif
< 
<     /*
<      * True if generating an error, to prevent runaway recursion.
<      * NB: generatingError packs with rval2set, #if JS_HAS_LVALUE_RETURN;
<      * with insideGCMarkCallback and with throwing below.
<      */
<     JSPackedBool        generatingError;
< 
<     /* Flag to indicate that we run inside gcCallback(cx, JSGC_MARK_END). */
<     JSPackedBool        insideGCMarkCallback;
< 
<     /* Exception state -- the exception member is a GC root by definition. */
<     JSPackedBool        throwing;           /* is there a pending exception? */
<     jsval               exception;          /* most-recently-thrown exception */
< 
<     /* Limit pointer for checking native stack consumption during recursion. */
<     jsuword             stackLimit;
---
>     /* Interpreter activation count. */
>     uintN               interpLevel;
713,714c298,301
<     /* Quota on the size of arenas used to compile and execute scripts. */
<     size_t              scriptStackQuota;
---
>     /* Runtime version control identifier and equality operators. */
>     JSVersion           version;
>     jsbytecode          jsop_eq;
>     jsbytecode          jsop_ne;
723c310,312
<     /* Temporary arena pool used while compiling and decompiling. */
---
>     /* Temporary arena pools used while compiling and decompiling. */
>     JSArenaPool         codePool;
>     JSArenaPool         notePool;
729,730c318,322
<     /* Storage to root recently allocated GC things and script result. */
<     JSWeakRoots         weakRoots;
---
>     /* Most recently created things by type, members of the GC's root set. */
>     JSGCThing           *newborn[GCX_NTYPES];
> 
>     /* Atom root for the last-looked-up atom on this context. */
>     JSAtom              *lastAtom;
744a337,342
> #if 1 // !!dp
> 	LGenericOutProc		traceOutProc;		
> 	void				*outParam;
> 	JSBool				traceDetails;
> 	//LTraceProc			traceProc;
> #endif
747c345,346
<     /* Per-context optional error reporter. */
---
>     /* Per-context optional user callbacks. */
>     JSBranchCallback    branchCallback;
750,761d348
<     /*
<      * Flag indicating that the operation callback is set. When the flag is 0
<      * but operationCallback is not null, operationCallback stores the branch
<      * callback.
<      */
<     uint32              operationCallbackIsSet :    1;
<     uint32              operationLimit         :    31;
<     JSOperationCallback operationCallback;
< 
<     /* Interpreter activation count. */
<     uintN               interpLevel;
< 
768c355
<     JSThread            *thread;
---
>     jsword              thread;
770,771d356
<     /* Same as requestDepth but ignoring JS_SuspendRequest/JS_ResumeRequest */
<     jsrefcount          outstandingRequests;
773,778d357
<     JSScope             *lockedSealedScope; /* weak ref, for low-cost sealed
<                                                scope locking */
<     JSCList             threadLinks;        /* JSThread contextList linkage */
< 
< #define CX_FROM_THREAD_LINKS(tl) \
<     ((JSContext *)((char *)(tl) - offsetof(JSContext, threadLinks)))
781,795c360,368
<     /* PDL of stack headers describing stack slots not rooted by argv, etc. */
<     JSStackHeader       *stackHeaders;
< 
<     /* Optional stack of heap-allocated scoped local GC roots. */
<     JSLocalRootStack    *localRootStack;
< 
<     /* Stack of thread-stack-allocated temporary GC roots. */
<     JSTempValueRooter   *tempValueRooters;
< 
<     /* Debug hooks associated with the current context. */
<     JSDebugHooks        *debugHooks;
< };
< 
< #ifdef JS_THREADSAFE
< # define JS_THREAD_ID(cx)       ((cx)->thread ? (cx)->thread->id : 0)
---
> #if JS_HAS_LVALUE_RETURN
>     /*
>      * Secondary return value from native method called on the left-hand side
>      * of an assignment operator.  The native should store the object in which
>      * to set a property in *rval, and return the property's id expressed as a
>      * jsval by calling JS_SetCallReturnValue2(cx, idval).
>      */
>     jsval               rval2;
>     JSPackedBool        rval2set;
798,818c371,376
< #ifdef __cplusplus
< /* FIXME(bug 332648): Move this into a public header. */
< class JSAutoTempValueRooter
< {
<   public:
<     JSAutoTempValueRooter(JSContext *cx, size_t len, jsval *vec)
<         : mContext(cx) {
<         JS_PUSH_TEMP_ROOT(mContext, len, vec, &mTvr);
<     }
<     JSAutoTempValueRooter(JSContext *cx, jsval v)
<         : mContext(cx) {
<         JS_PUSH_SINGLE_TEMP_ROOT(mContext, v, &mTvr);
<     }
< 
<     ~JSAutoTempValueRooter() {
<         JS_POP_TEMP_ROOT(mContext, &mTvr);
<     }
< 
<   private:
<     static void *operator new(size_t);
<     static void operator delete(void *, size_t);
---
>     /*
>      * True if creating an exception object, to prevent runaway recursion.
>      * NB: creatingException packs with rval2set, #if JS_HAS_LVALUE_RETURN,
>      * and with throwing, below.
>      */
>     JSPackedBool        creatingException;
820,823c378,389
<     JSContext *mContext;
<     JSTempValueRooter mTvr;
< };
< #endif
---
>     /*
>      * Exception state -- the exception member is a GC root by definition.
>      * NB: throwing packs with creatingException and rval2set, above.
>      */
>     JSPackedBool        throwing;           /* is there a pending exception? */
>     jsval               exception;          /* most-recently-thrown exception */
>     #if 1 // !!dp
> 	JSPackedBool		trySeen;			// JSOP_TRY seend
> 	#endif
> 	
>     /* Per-context options. */
>     uint32              options;            /* see jsapi.h for JSOPTION_* */
825,864c391,392
< /*
<  * Slightly more readable macros for testing per-context option settings (also
<  * to hide bitset implementation detail).
<  *
<  * JSOPTION_XML must be handled specially in order to propagate from compile-
<  * to run-time (from cx->options to script->version/cx->version).  To do that,
<  * we copy JSOPTION_XML from cx->options into cx->version as JSVERSION_HAS_XML
<  * whenever options are set, and preserve this XML flag across version number
<  * changes done via the JS_SetVersion API.
<  *
<  * But when executing a script or scripted function, the interpreter changes
<  * cx->version, including the XML flag, to script->version.  Thus JSOPTION_XML
<  * is a compile-time option that causes a run-time version change during each
<  * activation of the compiled script.  That version change has the effect of
<  * changing JS_HAS_XML_OPTION, so that any compiling done via eval enables XML
<  * support.  If an XML-enabled script or function calls a non-XML function,
<  * the flag bit will be cleared during the callee's activation.
<  *
<  * Note that JS_SetVersion API calls never pass JSVERSION_HAS_XML or'd into
<  * that API's version parameter.
<  *
<  * Note also that script->version must contain this XML option flag in order
<  * for XDR'ed scripts to serialize and deserialize with that option preserved
<  * for detection at run-time.  We can't copy other compile-time options into
<  * script->version because that would break backward compatibility (certain
<  * other options, e.g. JSOPTION_VAROBJFIX, are analogous to JSOPTION_XML).
<  */
< #define JS_HAS_OPTION(cx,option)        (((cx)->options & (option)) != 0)
< #define JS_HAS_STRICT_OPTION(cx)        JS_HAS_OPTION(cx, JSOPTION_STRICT)
< #define JS_HAS_WERROR_OPTION(cx)        JS_HAS_OPTION(cx, JSOPTION_WERROR)
< #define JS_HAS_COMPILE_N_GO_OPTION(cx)  JS_HAS_OPTION(cx, JSOPTION_COMPILE_N_GO)
< #define JS_HAS_ATLINE_OPTION(cx)        JS_HAS_OPTION(cx, JSOPTION_ATLINE)
< 
< #define JSVERSION_MASK                  0x0FFF  /* see JSVersion in jspubtd.h */
< #define JSVERSION_HAS_XML               0x1000  /* flag induced by XML option */
< 
< #define JSVERSION_NUMBER(cx)            ((JSVersion)((cx)->version &          \
<                                                      JSVERSION_MASK))
< #define JS_HAS_XML_OPTION(cx)           ((cx)->version & JSVERSION_HAS_XML || \
<                                          JSVERSION_NUMBER(cx) >= JSVERSION_1_6)
---
>     /* Locale specific callbacks for string conversion. */
>     JSLocaleCallbacks   *localeCallbacks;
866,872c394,401
< /*
<  * Initialize a library-wide thread private data index, and remember that it
<  * has already been done, so that it happens only once ever.  Returns true on
<  * success.
<  */
< extern JSBool
< js_InitThreadPrivateIndex(void (JS_DLL_CALLBACK *ptr)(void *));
---
>     /*
>      * cx->resolving is non-zero if we are init'ing standard classes lazily, or
>      * if we are otherwise recursing indirectly from js_LookupProperty through
>      * a JSClass.resolve hook.  It is used together with cx->resolvingTable to
>      * limit runaway recursion (see jsapi.c and jsobj.c).
>      */
>     uint32              resolving;
>     JSDHashTable        *resolvingTable;
874,879c403,405
< /*
<  * Common subroutine of JS_SetVersion and js_SetVersion, to update per-context
<  * data that depends on version.
<  */
< extern void
< js_OnVersionChange(JSContext *cx);
---
>     /* PDL of stack headers describing stack slots not rooted by argv, etc. */
>     JSStackHeader       *stackHeaders;
> };
881,886c407,409
< /*
<  * Unlike the JS_SetVersion API, this function stores JSVERSION_HAS_XML and
<  * any future non-version-number flags induced by compiler options.
<  */
< extern void
< js_SetVersion(JSContext *cx, JSVersion version);
---
> /* Slightly more readable macros, also to hide bitset implementation detail. */
> #define JS_HAS_STRICT_OPTION(cx)    ((cx)->options & JSOPTION_STRICT)
> #define JS_HAS_WERROR_OPTION(cx)    ((cx)->options & JSOPTION_WERROR)
888,891d410
< /*
<  * Create and destroy functions for JSContext, which is manually allocated
<  * and exclusively owned.
<  */
896c415
< js_DestroyContext(JSContext *cx, JSDestroyContextMode mode);
---
> js_DestroyContext(JSContext *cx, JSGCMode gcmode);
913,949d431
<  * JSClass.resolve and watchpoint recursion damping machinery.
<  */
< extern JSBool
< js_StartResolving(JSContext *cx, JSResolvingKey *key, uint32 flag,
<                   JSResolvingEntry **entryp);
< 
< extern void
< js_StopResolving(JSContext *cx, JSResolvingKey *key, uint32 flag,
<                  JSResolvingEntry *entry, uint32 generation);
< 
< /*
<  * Local root set management.
<  *
<  * NB: the jsval parameters below may be properly tagged jsvals, or GC-thing
<  * pointers cast to (jsval).  This relies on JSObject's tag being zero, but
<  * on the up side it lets us push int-jsval-encoded scopeMark values on the
<  * local root stack.
<  */
< extern JSBool
< js_EnterLocalRootScope(JSContext *cx);
< 
< #define js_LeaveLocalRootScope(cx) \
<     js_LeaveLocalRootScopeWithResult(cx, JSVAL_NULL)
< 
< extern void
< js_LeaveLocalRootScopeWithResult(JSContext *cx, jsval rval);
< 
< extern void
< js_ForgetLocalRoot(JSContext *cx, jsval v);
< 
< extern int
< js_PushLocalRoot(JSContext *cx, JSLocalRootStack *lrs, jsval v);
< 
< extern void
< js_TraceLocalRoots(JSTracer *trc, JSLocalRootStack *lrs);
< 
< /*
981,1000c463
< js_ReportOutOfMemory(JSContext *cx);
< 
< /*
<  * Report that cx->scriptStackQuota is exhausted.
<  */
< extern void
< js_ReportOutOfScriptQuota(JSContext *cx);
< 
< extern void
< js_ReportOverRecursed(JSContext *cx);
< 
< #define JS_CHECK_RECURSION(cx, onerror)                                       \
<     JS_BEGIN_MACRO                                                            \
<         int stackDummy_;                                                      \
<                                                                               \
<         if (!JS_CHECK_STACK_SIZE(cx, stackDummy_)) {                          \
<             js_ReportOverRecursed(cx);                                        \
<             onerror;                                                          \
<         }                                                                     \
<     JS_END_MACRO
---
> js_ReportOutOfMemory(JSContext *cx, JSErrorCallback errorCallback);
1012,1040d474
< /*
<  * Report an attempt to access the property of a null or undefined value (v).
<  */
< extern JSBool
< js_ReportIsNullOrUndefined(JSContext *cx, intN spindex, jsval v,
<                            JSString *fallback);
< 
< /*
<  * Report error using js_DecompileValueGenerator(cx, spindex, v, fallback) as
<  * the first argument for the error message. If the error message has less
<  * then 3 arguments, use null for arg1 or arg2.
<  */
< extern JSBool
< js_ReportValueErrorFlags(JSContext *cx, uintN flags, const uintN errorNumber,
<                          intN spindex, jsval v, JSString *fallback,
<                          const char *arg1, const char *arg2);
< 
< #define js_ReportValueError(cx,errorNumber,spindex,v,fallback)                \
<     ((void)js_ReportValueErrorFlags(cx, JSREPORT_ERROR, errorNumber,          \
<                                     spindex, v, fallback, NULL, NULL))
< 
< #define js_ReportValueError2(cx,errorNumber,spindex,v,fallback,arg1)          \
<     ((void)js_ReportValueErrorFlags(cx, JSREPORT_ERROR, errorNumber,          \
<                                     spindex, v, fallback, arg1, NULL))
< 
< #define js_ReportValueError3(cx,errorNumber,spindex,v,fallback,arg1,arg2)     \
<     ((void)js_ReportValueErrorFlags(cx, JSREPORT_ERROR, errorNumber,          \
<                                     spindex, v, fallback, arg1, arg2))
< 
1043,1106d476
< /*
<  * See JS_SetThreadStackLimit in jsapi.c, where we check that the stack grows
<  * in the expected direction.  On Unix-y systems, JS_STACK_GROWTH_DIRECTION is
<  * computed on the build host by jscpucfg.c and written into jsautocfg.h.  The
<  * macro is hardcoded in jscpucfg.h on Windows and Mac systems (for historical
<  * reasons pre-dating autoconf usage).
<  */
< #if JS_STACK_GROWTH_DIRECTION > 0
< # define JS_CHECK_STACK_SIZE(cx, lval)  ((jsuword)&(lval) < (cx)->stackLimit)
< #else
< # define JS_CHECK_STACK_SIZE(cx, lval)  ((jsuword)&(lval) > (cx)->stackLimit)
< #endif
< 
< /*
<  * Update the operation counter according to the given weight and call the
<  * operation callback when we reach the operation limit. To make this
<  * frequently executed macro faster we decrease the counter from
<  * JSContext.operationLimit and compare against zero to check the limit.
<  *
<  * This macro can run the full GC. Return true if it is OK to continue and
<  * false otherwise.
<  */
< #define JS_CHECK_OPERATION_LIMIT(cx, weight)                                  \
<     (JS_CHECK_OPERATION_WEIGHT(weight),                                       \
<      (((cx)->operationCount -= (weight)) > 0 || js_ResetOperationCount(cx)))
< 
< /*
<  * A version of JS_CHECK_OPERATION_LIMIT that just updates the operation count
<  * without calling the operation callback or any other API. This macro resets
<  * the count to 0 when it becomes negative to prevent a wrap-around when the
<  * macro is called repeatably.
<  */
< #define JS_COUNT_OPERATION(cx, weight)                                        \
<     ((void)(JS_CHECK_OPERATION_WEIGHT(weight),                                \
<             (cx)->operationCount = ((cx)->operationCount > 0)                 \
<                                    ? (cx)->operationCount - (weight)          \
<                                    : 0))
< 
< /*
<  * The implementation of the above macros assumes that subtracting weights
<  * twice from a positive number does not wrap-around INT32_MIN.
<  */
< #define JS_CHECK_OPERATION_WEIGHT(weight)                                     \
<     (JS_ASSERT((uint32) (weight) > 0),                                        \
<      JS_ASSERT((uint32) (weight) < JS_BIT(30)))
< 
< /* Relative operations weights. */
< #define JSOW_JUMP                   1
< #define JSOW_ALLOCATION             100
< #define JSOW_LOOKUP_PROPERTY        5
< #define JSOW_GET_PROPERTY           10
< #define JSOW_SET_PROPERTY           20
< #define JSOW_NEW_PROPERTY           200
< #define JSOW_DELETE_PROPERTY        30
< #define JSOW_ENTER_SHARP            JS_OPERATION_WEIGHT_BASE
< #define JSOW_SCRIPT_JUMP            JS_OPERATION_WEIGHT_BASE
< 
< /*
<  * Reset the operation count and call the operation callback assuming that the
<  * operation limit is reached.
<  */
< extern JSBool
< js_ResetOperationCount(JSContext *cx);
< 
diff -r /Volumes/Swap/js-14-2-2008/js/src/jscompat.h /Volumes/Swap/js_D11/src/jscompat.h
1,12c1,10
< /* ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
> /*
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
17,20c15,18
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998-1999
<  * the Initial Developer. All Rights Reserved.
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation. Portions created by Netscape are
>  * Copyright (C) 1998-1999 Netscape Communications Corporation. All
>  * Rights Reserved.
24,36c22,32
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
39c35
<  * Copyright (C) 1996-1999 Netscape Communications Corporation, All Rights Reserved.
---
>  * Copyright © 1996-1999 Netscape Communications Corporation, All Rights Reserved.
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsconfig.h /Volumes/Swap/js_D11/src/jsconfig.h
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
44c39
< #define JS_VERSION 180
---
> #define JS_VERSION 150
47,79c42
< /*
<  * Compile-time JS version configuration.  The JS version numbers lie on the
<  * number line like so:
<  *
<  * 1.0     1.1     1.2     1.3     1.4     ECMAv3  1.5     1.6     1.7     1.8
<  *         ^                       ^
<  *         |                       |
<  *         basis for ECMAv1        close to ECMAv2
<  *
<  * where ECMAv3 stands for ECMA-262 Edition 3.  See the runtime version enum
<  * JSVersion in jspubtd.h.  Code in the engine can therefore count on version
<  * <= JSVERSION_1_4 to mean "before the Third Edition of ECMA-262" and version
<  * > JSVERSION_1_4 to mean "at or after the Third Edition".
<  *
<  * In the (likely?) event that SpiderMonkey grows to implement JavaScript 2.0,
<  * or ECMA-262 Edition 4 (JS2 without certain extensions), the version number
<  * to use would be near 200, or greater.
<  *
<  * The JS_VERSION_ECMA_3 version is the minimal configuration conforming to
<  * the ECMA-262 Edition 3 specification.  Use it for minimal embeddings, where
<  * you're sure you don't need any of the extensions disabled in this version.
<  * In order to facilitate testing, JS_HAS_OBJ_PROTO_PROP is defined as part of
<  * the JS_VERSION_ECMA_3_TEST version.
<  *
<  * To keep things sane in the modern age, where we need exceptions in order to
<  * implement, e.g., iterators and generators, we are dropping support for all
<  * versions <= 1.4.
<  */
< #define JS_VERSION_ECMA_3       148
< #define JS_VERSION_ECMA_3_TEST  149
< 
< #if JS_VERSION == JS_VERSION_ECMA_3 ||                                        \
<     JS_VERSION == JS_VERSION_ECMA_3_TEST
---
> #if JS_VERSION == 100
81,85c44,64
< #define JS_HAS_STR_HTML_HELPERS 0       /* has str.anchor, str.bold, etc. */
< #define JS_HAS_PERL_SUBSTR      0       /* has str.substr */
< #if JS_VERSION == JS_VERSION_ECMA_3_TEST
< #define JS_HAS_OBJ_PROTO_PROP   1       /* has o.__proto__ etc. */
< #else
---
> #define JS_BUG_NULL_INDEX_PROPS 1       /* o[0] defaults to null, not void */
> #define JS_BUG_EMPTY_INDEX_ZERO 1       /* o[""] is equivalent to o[0] */
> #define JS_BUG_EAGER_TOSTRING   1       /* o.toString() trumps o.valueOf() */
> #define JS_BUG_VOID_TOSTRING    0       /* void 0 + 0 == "undefined0" */
> #define JS_BUG_EVAL_THIS_FUN    0       /* eval('this') in function f is f */
> #define JS_BUG_EVAL_THIS_SCOPE  0       /* Math.eval('sin(x)') vs. local x */
> #define JS_BUG_FALLIBLE_EQOPS   1       /* fallible/intransitive equality ops */
> #define JS_BUG_FALLIBLE_TONUM   1       /* fallible ValueToNumber primitive */
> #define JS_BUG_WITH_CLOSURE     0       /* with(o)function f(){} sets o.f */
> 
> #define JS_HAS_PROP_DELETE      0       /* delete o.p removes p from o */
> #define JS_HAS_CALL_OBJECT      0       /* fun.caller is stack frame obj */
> #define JS_HAS_LABEL_STATEMENT  0       /* has break/continue to label: */
> #define JS_HAS_DO_WHILE_LOOP    0       /* has do {...} while (b) */
> #define JS_HAS_SWITCH_STATEMENT 0       /* has switch (v) {case c: ...} */
> #define JS_HAS_SOME_PERL_FUN    0       /* has array.join/reverse/sort */
> #define JS_HAS_MORE_PERL_FUN    0       /* has array.push, str.substr, etc */
> #define JS_HAS_VALUEOF_HINT     0       /* valueOf(hint) where hint is typeof */
> #define JS_HAS_LEXICAL_CLOSURE  0       /* nested functions, lexically closed */
> #define JS_HAS_APPLY_FUNCTION   0       /* has fun.apply(obj, argArray) */
> #define JS_HAS_CALL_FUNCTION    0       /* has fun.call(obj, arg1, ... argN) */
87c66,68
< #endif
---
> #define JS_HAS_REGEXPS          0       /* has perl r.e.s via RegExp, /pat/ */
> #define JS_HAS_SEQUENCE_OPS     0       /* has array.slice, string.concat */
> #define JS_HAS_INITIALIZERS     0       /* has var o = {'foo': 42, 'bar':3} */
90a72
> #define JS_HAS_TRIPLE_EQOPS     0       /* has === and !== identity eqops */
91a74
> #define JS_HAS_REPLACE_LAMBDA   0       /* has string.replace(re, lambda) */
93,94c76,78
< #define JS_HAS_XDR              0       /* has XDR API and internal support */
< #define JS_HAS_XDR_FREEZE_THAW  0       /* has XDR freeze/thaw script methods */
---
> #define JS_HAS_XDR              0       /* has XDR API and object methods */
> #define JS_HAS_EXCEPTIONS       0       /* has exception handling */
> #define JS_HAS_UNDEFINED        0       /* has global "undefined" property */
95a80,82
> #define JS_HAS_IN_OPERATOR      0       /* has in operator ('p' in {p:1}) */
> #define JS_HAS_INSTANCEOF       0       /* has {p:1} instanceof Object */
> #define JS_HAS_ARGS_OBJECT      0       /* has minimal ECMA arguments object */
96a84
> #define JS_HAS_ERROR_EXCEPTIONS 0       /* has error object hierarchy */
97a86
> #define JS_HAS_NEW_OBJ_METHODS  0       /* has Object.prototype query methods */
98a88,89
> #define JS_HAS_DFLT_MSG_STRINGS 1       /* provides English error messages */
> #define JS_HAS_NUMBER_FORMATS   0       /* numbers have formatting methods */
103,111c94
< #define JS_HAS_LVALUE_RETURN    1       /* has o.item(i) = j; for native item */
< #define JS_HAS_NO_SUCH_METHOD   0       /* has o.__noSuchMethod__ handler */
< #define JS_HAS_XML_SUPPORT      0       /* has ECMAScript for XML support */
< #define JS_HAS_ARRAY_EXTRAS     0       /* has indexOf and Lispy extras */
< #define JS_HAS_GENERATORS       0       /* has yield in generator function */
< #define JS_HAS_BLOCK_SCOPE      0       /* has block scope via let/arraycomp */
< #define JS_HAS_DESTRUCTURING    0       /* has [a,b] = ... or {p:a,q:b} = ... */
< #define JS_HAS_GENERATOR_EXPRS  0       /* has (expr for (lhs in iterable)) */
< #define JS_HAS_EXPR_CLOSURES    0       /* has function (formals) listexpr */
---
> #define JS_HAS_LVALUE_RETURN    0       /* has o.item(i) = j; for native item */
113c96
< #elif JS_VERSION < 150
---
> #elif JS_VERSION == 110
115c98,148
< #error "unsupported JS_VERSION"
---
> #define JS_BUG_NULL_INDEX_PROPS 1       /* o[0] defaults to null, not void */
> #define JS_BUG_EMPTY_INDEX_ZERO 1       /* o[""] is equivalent to o[0] */
> #define JS_BUG_EAGER_TOSTRING   1       /* o.toString() trumps o.valueOf() */
> #define JS_BUG_VOID_TOSTRING    0       /* void 0 + 0 == "undefined0" */
> #define JS_BUG_EVAL_THIS_FUN    1       /* eval('this') in function f is f */
> #define JS_BUG_EVAL_THIS_SCOPE  1       /* Math.eval('sin(x)') vs. local x */
> #define JS_BUG_FALLIBLE_EQOPS   1       /* fallible/intransitive equality ops */
> #define JS_BUG_FALLIBLE_TONUM   1       /* fallible ValueToNumber primitive */
> #define JS_BUG_WITH_CLOSURE     0       /* with(o)function f(){} sets o.f */
> 
> #define JS_HAS_PROP_DELETE      0       /* delete o.p removes p from o */
> #define JS_HAS_CALL_OBJECT      0       /* fun.caller is stack frame obj */
> #define JS_HAS_LABEL_STATEMENT  0       /* has break/continue to label: */
> #define JS_HAS_DO_WHILE_LOOP    0       /* has do {...} while (b) */
> #define JS_HAS_SWITCH_STATEMENT 0       /* has switch (v) {case c: ...} */
> #define JS_HAS_SOME_PERL_FUN    1       /* has array.join/reverse/sort */
> #define JS_HAS_MORE_PERL_FUN    0       /* has array.push, str.substr, etc */
> #define JS_HAS_VALUEOF_HINT     0       /* valueOf(hint) where hint is typeof */
> #define JS_HAS_LEXICAL_CLOSURE  0       /* nested functions, lexically closed */
> #define JS_HAS_APPLY_FUNCTION   0       /* has apply(fun, arg1, ... argN) */
> #define JS_HAS_CALL_FUNCTION    0       /* has fun.call(obj, arg1, ... argN) */
> #define JS_HAS_OBJ_PROTO_PROP   0       /* has o.__proto__ etc. */
> #define JS_HAS_REGEXPS          0       /* has perl r.e.s via RegExp, /pat/ */
> #define JS_HAS_SEQUENCE_OPS     0       /* has array.slice, string.concat */
> #define JS_HAS_INITIALIZERS     0       /* has var o = {'foo': 42, 'bar':3} */
> #define JS_HAS_OBJ_WATCHPOINT   0       /* has o.watch and o.unwatch */
> #define JS_HAS_EXPORT_IMPORT    0       /* has export fun; import obj.fun */
> #define JS_HAS_EVAL_THIS_SCOPE  0       /* Math.eval is same as with (Math) */
> #define JS_HAS_TRIPLE_EQOPS     0       /* has === and !== identity eqops */
> #define JS_HAS_SHARP_VARS       0       /* has #n=, #n# for object literals */
> #define JS_HAS_REPLACE_LAMBDA   0       /* has string.replace(re, lambda) */
> #define JS_HAS_SCRIPT_OBJECT    0       /* has (new Script("x++")).exec() */
> #define JS_HAS_XDR              0       /* has XDR API and object methods */
> #define JS_HAS_EXCEPTIONS       0       /* has exception handling */
> #define JS_HAS_UNDEFINED        0       /* has global "undefined" property */
> #define JS_HAS_TOSOURCE         0       /* has Object/Array toSource method */
> #define JS_HAS_IN_OPERATOR      0       /* has in operator ('p' in {p:1}) */
> #define JS_HAS_INSTANCEOF       0       /* has {p:1} instanceof Object */
> #define JS_HAS_ARGS_OBJECT      0       /* has minimal ECMA arguments object */
> #define JS_HAS_DEBUGGER_KEYWORD 0       /* has hook for debugger keyword */
> #define JS_HAS_ERROR_EXCEPTIONS 0       /* has error object hierarchy */
> #define JS_HAS_CATCH_GUARD      0       /* has exception handling catch guard */
> #define JS_HAS_NEW_OBJ_METHODS  0       /* has Object.prototype query methods */
> #define JS_HAS_SPARSE_ARRAYS    0       /* array methods preserve empty elems */
> #define JS_HAS_DFLT_MSG_STRINGS 1       /* provides English error messages */
> #define JS_HAS_NUMBER_FORMATS   0       /* numbers have formatting methods */
> #define JS_HAS_GETTER_SETTER    0       /* has JS2 getter/setter functions */
> #define JS_HAS_UNEVAL           0       /* has uneval() top-level function */
> #define JS_HAS_CONST            0       /* has JS2 const as alternative var */
> #define JS_HAS_FUN_EXPR_STMT    0       /* has function expression statement */
> #define JS_HAS_LVALUE_RETURN    0       /* has o.item(i) = j; for native item */
117c150
< #elif JS_VERSION == 150
---
> #elif JS_VERSION == 120
119,120c152,172
< #define JS_HAS_STR_HTML_HELPERS 1       /* has str.anchor, str.bold, etc. */
< #define JS_HAS_PERL_SUBSTR      1       /* has str.substr */
---
> #define JS_BUG_NULL_INDEX_PROPS 0       /* o[0] defaults to null, not void */
> #define JS_BUG_EMPTY_INDEX_ZERO 0       /* o[""] is equivalent to o[0] */
> #define JS_BUG_EAGER_TOSTRING   0       /* o.toString() trumps o.valueOf() */
> #define JS_BUG_VOID_TOSTRING    1       /* void 0 + 0 == "undefined0" */
> #define JS_BUG_EVAL_THIS_FUN    0       /* eval('this') in function f is f */
> #define JS_BUG_EVAL_THIS_SCOPE  0       /* Math.eval('sin(x)') vs. local x */
> #define JS_BUG_FALLIBLE_EQOPS   0       /* fallible/intransitive equality ops */
> #define JS_BUG_FALLIBLE_TONUM   0       /* fallible ValueToNumber primitive */
> #define JS_BUG_WITH_CLOSURE     1       /* with(o)function f(){} sets o.f */
> 
> #define JS_HAS_PROP_DELETE      1       /* delete o.p removes p from o */
> #define JS_HAS_CALL_OBJECT      1       /* fun.caller is stack frame obj */
> #define JS_HAS_LABEL_STATEMENT  1       /* has break/continue to label: */
> #define JS_HAS_DO_WHILE_LOOP    1       /* has do {...} while (b) */
> #define JS_HAS_SWITCH_STATEMENT 1       /* has switch (v) {case c: ...} */
> #define JS_HAS_SOME_PERL_FUN    1       /* has array.join/reverse/sort */
> #define JS_HAS_MORE_PERL_FUN    1       /* has array.push, str.substr, etc */
> #define JS_HAS_VALUEOF_HINT     1       /* valueOf(hint) where hint is typeof */
> #define JS_HAS_LEXICAL_CLOSURE  1       /* nested functions, lexically closed */
> #define JS_HAS_APPLY_FUNCTION   1       /* has apply(fun, arg1, ... argN) */
> #define JS_HAS_CALL_FUNCTION    0       /* has fun.call(obj, arg1, ... argN) */
121a174,176
> #define JS_HAS_REGEXPS          1       /* has perl r.e.s via RegExp, /pat/ */
> #define JS_HAS_SEQUENCE_OPS     1       /* has array.slice, string.concat */
> #define JS_HAS_INITIALIZERS     1       /* has var o = {'foo': 42, 'bar':3} */
125,131c180,194
< #define JS_HAS_SHARP_VARS       1       /* has #n=, #n# for object literals */
< #define JS_HAS_SCRIPT_OBJECT    1       /* has (new Script("x++")).exec() */
< #define JS_HAS_XDR              1       /* has XDR API and internal support */
< #define JS_HAS_XDR_FREEZE_THAW  0       /* has XDR freeze/thaw script methods */
< #define JS_HAS_TOSOURCE         1       /* has Object/Array toSource method */
< #define JS_HAS_DEBUGGER_KEYWORD 1       /* has hook for debugger keyword */
< #define JS_HAS_CATCH_GUARD      1       /* has exception handling catch guard */
---
> #define JS_HAS_TRIPLE_EQOPS     0       /* has === and !== identity eqops */
> #define JS_HAS_SHARP_VARS       0       /* has #n=, #n# for object literals */
> #define JS_HAS_REPLACE_LAMBDA   0       /* has string.replace(re, lambda) */
> #define JS_HAS_SCRIPT_OBJECT    0       /* has (new Script("x++")).exec() */
> #define JS_HAS_XDR              0       /* has XDR API and object methods */
> #define JS_HAS_EXCEPTIONS       0       /* has exception handling */
> #define JS_HAS_UNDEFINED        0       /* has global "undefined" property */
> #define JS_HAS_TOSOURCE         0       /* has Object/Array toSource method */
> #define JS_HAS_IN_OPERATOR      0       /* has in operator ('p' in {p:1}) */
> #define JS_HAS_INSTANCEOF       0       /* has {p:1} instanceof Object */
> #define JS_HAS_ARGS_OBJECT      0       /* has minimal ECMA arguments object */
> #define JS_HAS_DEBUGGER_KEYWORD 0       /* has hook for debugger keyword */
> #define JS_HAS_ERROR_EXCEPTIONS 0       /* has error object hierarchy */
> #define JS_HAS_CATCH_GUARD      0       /* has exception handling catch guard */
> #define JS_HAS_NEW_OBJ_METHODS  0       /* has Object.prototype query methods */
133,145c196,202
< #define JS_HAS_GETTER_SETTER    1       /* has JS2 getter/setter functions */
< #define JS_HAS_UNEVAL           1       /* has uneval() top-level function */
< #define JS_HAS_CONST            1       /* has JS2 const as alternative var */
< #define JS_HAS_FUN_EXPR_STMT    1       /* has function expression statement */
< #define JS_HAS_LVALUE_RETURN    1       /* has o.item(i) = j; for native item */
< #define JS_HAS_NO_SUCH_METHOD   1       /* has o.__noSuchMethod__ handler */
< #define JS_HAS_XML_SUPPORT      0       /* has ECMAScript for XML support */
< #define JS_HAS_ARRAY_EXTRAS     0       /* has indexOf and Lispy extras */
< #define JS_HAS_GENERATORS       0       /* has yield in generator function */
< #define JS_HAS_BLOCK_SCOPE      0       /* has block scope via let/arraycomp */
< #define JS_HAS_DESTRUCTURING    0       /* has [a,b] = ... or {p:a,q:b} = ... */
< #define JS_HAS_GENERATOR_EXPRS  0       /* has (expr for (lhs in iterable)) */
< #define JS_HAS_EXPR_CLOSURES    0       /* has function (formals) listexpr */
---
> #define JS_HAS_DFLT_MSG_STRINGS 1       /* provides English error messages */
> #define JS_HAS_NUMBER_FORMATS   0       /* numbers have formatting methods */
> #define JS_HAS_GETTER_SETTER    0       /* has JS2 getter/setter functions */
> #define JS_HAS_UNEVAL           0       /* has uneval() top-level function */
> #define JS_HAS_CONST            0       /* has JS2 const as alternative var */
> #define JS_HAS_FUN_EXPR_STMT    0       /* has function expression statement */
> #define JS_HAS_LVALUE_RETURN    0       /* has o.item(i) = j; for native item */
147c204
< #elif JS_VERSION == 160
---
> #elif JS_VERSION == 130
149,150c206,226
< #define JS_HAS_STR_HTML_HELPERS 1       /* has str.anchor, str.bold, etc. */
< #define JS_HAS_PERL_SUBSTR      1       /* has str.substr */
---
> #define JS_BUG_NULL_INDEX_PROPS 0       /* o[0] defaults to null, not void */
> #define JS_BUG_EMPTY_INDEX_ZERO 0       /* o[""] is equivalent to o[0] */
> #define JS_BUG_EAGER_TOSTRING   0       /* o.toString() trumps o.valueOf() */
> #define JS_BUG_VOID_TOSTRING    0       /* void 0 + 0 == "undefined0" */
> #define JS_BUG_EVAL_THIS_FUN    0       /* eval('this') in function f is f */
> #define JS_BUG_EVAL_THIS_SCOPE  0       /* Math.eval('sin(x)') vs. local x */
> #define JS_BUG_FALLIBLE_EQOPS   0       /* fallible/intransitive equality ops */
> #define JS_BUG_FALLIBLE_TONUM   0       /* fallible ValueToNumber primitive */
> #define JS_BUG_WITH_CLOSURE     1       /* with(o)function f(){} sets o.f */
> 
> #define JS_HAS_PROP_DELETE      1       /* delete o.p removes p from o */
> #define JS_HAS_CALL_OBJECT      1       /* fun.caller is stack frame obj */
> #define JS_HAS_LABEL_STATEMENT  1       /* has break/continue to label: */
> #define JS_HAS_DO_WHILE_LOOP    1       /* has do {...} while (b) */
> #define JS_HAS_SWITCH_STATEMENT 1       /* has switch (v) {case c: ...} */
> #define JS_HAS_SOME_PERL_FUN    1       /* has array.join/reverse/sort */
> #define JS_HAS_MORE_PERL_FUN    1       /* has array.push, str.substr, etc */
> #define JS_HAS_VALUEOF_HINT     1       /* valueOf(hint) where hint is typeof */
> #define JS_HAS_LEXICAL_CLOSURE  1       /* nested functions, lexically closed */
> #define JS_HAS_APPLY_FUNCTION   1       /* has apply(fun, arg1, ... argN) */
> #define JS_HAS_CALL_FUNCTION    1       /* has fun.call(obj, arg1, ... argN) */
151a228,230
> #define JS_HAS_REGEXPS          1       /* has perl r.e.s via RegExp, /pat/ */
> #define JS_HAS_SEQUENCE_OPS     1       /* has array.slice, string.concat */
> #define JS_HAS_INITIALIZERS     1       /* has var o = {'foo': 42, 'bar':3} */
154a234
> #define JS_HAS_TRIPLE_EQOPS     1       /* has === and !== identity eqops */
155a236
> #define JS_HAS_REPLACE_LAMBDA   1       /* has string.replace(re, lambda) */
157,158c238,240
< #define JS_HAS_XDR              1       /* has XDR API and internal support */
< #define JS_HAS_XDR_FREEZE_THAW  0       /* has XDR freeze/thaw script methods */
---
> #define JS_HAS_XDR              1       /* has XDR API and object methods */
> #define JS_HAS_EXCEPTIONS       0       /* has exception handling */
> #define JS_HAS_UNDEFINED        1       /* has global "undefined" property */
159a242,244
> #define JS_HAS_IN_OPERATOR      0       /* has in operator ('p' in {p:1}) */
> #define JS_HAS_INSTANCEOF       0       /* has {p:1} instanceof Object */
> #define JS_HAS_ARGS_OBJECT      1       /* has minimal ECMA arguments object */
161c246,248
< #define JS_HAS_CATCH_GUARD      1       /* has exception handling catch guard */
---
> #define JS_HAS_ERROR_EXCEPTIONS 0       /* has error object hierarchy */
> #define JS_HAS_CATCH_GUARD      0       /* has exception handling catch guard */
> #define JS_HAS_NEW_OBJ_METHODS  0       /* has Object.prototype query methods */
163,175c250,256
< #define JS_HAS_GETTER_SETTER    1       /* has JS2 getter/setter functions */
< #define JS_HAS_UNEVAL           1       /* has uneval() top-level function */
< #define JS_HAS_CONST            1       /* has JS2 const as alternative var */
< #define JS_HAS_FUN_EXPR_STMT    1       /* has function expression statement */
< #define JS_HAS_LVALUE_RETURN    1       /* has o.item(i) = j; for native item */
< #define JS_HAS_NO_SUCH_METHOD   1       /* has o.__noSuchMethod__ handler */
< #define JS_HAS_XML_SUPPORT      1       /* has ECMAScript for XML support */
< #define JS_HAS_ARRAY_EXTRAS     1       /* has indexOf and Lispy extras */
< #define JS_HAS_GENERATORS       0       /* has yield in generator function */
< #define JS_HAS_BLOCK_SCOPE      0       /* has block scope via let/arraycomp */
< #define JS_HAS_DESTRUCTURING    0       /* has [a,b] = ... or {p:a,q:b} = ... */
< #define JS_HAS_GENERATOR_EXPRS  0       /* has (expr for (lhs in iterable)) */
< #define JS_HAS_EXPR_CLOSURES    0       /* has function (formals) listexpr */
---
> #define JS_HAS_DFLT_MSG_STRINGS 1       /* provides English error messages */
> #define JS_HAS_NUMBER_FORMATS   0       /* numbers have formatting methods */
> #define JS_HAS_GETTER_SETTER    0       /* has JS2 getter/setter functions */
> #define JS_HAS_UNEVAL           0       /* has uneval() top-level function */
> #define JS_HAS_CONST            0       /* has JS2 const as alternative var */
> #define JS_HAS_FUN_EXPR_STMT    0       /* has function expression statement */
> #define JS_HAS_LVALUE_RETURN    0       /* has o.item(i) = j; for native item */
177c258
< #elif JS_VERSION == 170
---
> #elif JS_VERSION == 140
179,180c260,280
< #define JS_HAS_STR_HTML_HELPERS 1       /* has str.anchor, str.bold, etc. */
< #define JS_HAS_PERL_SUBSTR      1       /* has str.substr */
---
> #define JS_BUG_NULL_INDEX_PROPS 0       /* o[0] defaults to null, not void */
> #define JS_BUG_EMPTY_INDEX_ZERO 0       /* o[""] is equivalent to o[0] */
> #define JS_BUG_EAGER_TOSTRING   0       /* o.toString() trumps o.valueOf() */
> #define JS_BUG_VOID_TOSTRING    0       /* void 0 + 0 == "undefined0" */
> #define JS_BUG_EVAL_THIS_FUN    0       /* eval('this') in function f is f */
> #define JS_BUG_EVAL_THIS_SCOPE  0       /* Math.eval('sin(x)') vs. local x */
> #define JS_BUG_FALLIBLE_EQOPS   0       /* fallible/intransitive equality ops */
> #define JS_BUG_FALLIBLE_TONUM   0       /* fallible ValueToNumber primitive */
> #define JS_BUG_WITH_CLOSURE     1       /* with(o)function f(){} sets o.f */
> 
> #define JS_HAS_PROP_DELETE      1       /* delete o.p removes p from o */
> #define JS_HAS_CALL_OBJECT      1       /* fun.caller is stack frame obj */
> #define JS_HAS_LABEL_STATEMENT  1       /* has break/continue to label: */
> #define JS_HAS_DO_WHILE_LOOP    1       /* has do {...} while (b) */
> #define JS_HAS_SWITCH_STATEMENT 1       /* has switch (v) {case c: ...} */
> #define JS_HAS_SOME_PERL_FUN    1       /* has array.join/reverse/sort */
> #define JS_HAS_MORE_PERL_FUN    1       /* has array.push, str.substr, etc */
> #define JS_HAS_VALUEOF_HINT     1       /* valueOf(hint) where hint is typeof */
> #define JS_HAS_LEXICAL_CLOSURE  1       /* nested functions, lexically closed */
> #define JS_HAS_APPLY_FUNCTION   1       /* has apply(fun, arg1, ... argN) */
> #define JS_HAS_CALL_FUNCTION    1       /* has fun.call(obj, arg1, ... argN) */
181a282,284
> #define JS_HAS_REGEXPS          1       /* has perl r.e.s via RegExp, /pat/ */
> #define JS_HAS_SEQUENCE_OPS     1       /* has array.slice, string.concat */
> #define JS_HAS_INITIALIZERS     1       /* has var o = {'foo': 42, 'bar':3} */
184a288
> #define JS_HAS_TRIPLE_EQOPS     1       /* has === and !== identity eqops */
186,188c290,294
< #define JS_HAS_SCRIPT_OBJECT    0       /* has (new Script("x++")).exec() */
< #define JS_HAS_XDR              1       /* has XDR API and internal support */
< #define JS_HAS_XDR_FREEZE_THAW  0       /* has XDR freeze/thaw script methods */
---
> #define JS_HAS_REPLACE_LAMBDA   1       /* has string.replace(re, lambda) */
> #define JS_HAS_SCRIPT_OBJECT    1       /* has (new Script("x++")).exec() */
> #define JS_HAS_XDR		1	/* has XDR API and object methods */
> #define JS_HAS_EXCEPTIONS	1	/* has exception handling */
> #define JS_HAS_UNDEFINED        1       /* has global "undefined" property */
189a296,298
> #define JS_HAS_IN_OPERATOR      1       /* has in operator ('p' in {p:1}) */
> #define JS_HAS_INSTANCEOF       1       /* has {p:1} instanceof Object */
> #define JS_HAS_ARGS_OBJECT      1       /* has minimal ECMA arguments object */
191c300,302
< #define JS_HAS_CATCH_GUARD      1       /* has exception handling catch guard */
---
> #define JS_HAS_ERROR_EXCEPTIONS 0       /* rt errors reflected as exceptions */
> #define JS_HAS_CATCH_GUARD      0       /* has exception handling catch guard */
> #define JS_HAS_NEW_OBJ_METHODS  0       /* has Object.prototype query methods */
193,205c304,310
< #define JS_HAS_GETTER_SETTER    1       /* has JS2 getter/setter functions */
< #define JS_HAS_UNEVAL           1       /* has uneval() top-level function */
< #define JS_HAS_CONST            1       /* has JS2 const as alternative var */
< #define JS_HAS_FUN_EXPR_STMT    1       /* has function expression statement */
< #define JS_HAS_LVALUE_RETURN    1       /* has o.item(i) = j; for native item */
< #define JS_HAS_NO_SUCH_METHOD   1       /* has o.__noSuchMethod__ handler */
< #define JS_HAS_XML_SUPPORT      1       /* has ECMAScript for XML support */
< #define JS_HAS_ARRAY_EXTRAS     1       /* has indexOf and Lispy extras */
< #define JS_HAS_GENERATORS       1       /* has yield in generator function */
< #define JS_HAS_BLOCK_SCOPE      1       /* has block scope via let/arraycomp */
< #define JS_HAS_DESTRUCTURING    1       /* has [a,b] = ... or {p:a,q:b} = ... */
< #define JS_HAS_GENERATOR_EXPRS  0       /* has (expr for (lhs in iterable)) */
< #define JS_HAS_EXPR_CLOSURES    0       /* has function (formals) listexpr */
---
> #define JS_HAS_DFLT_MSG_STRINGS 1       /* provides English error messages */
> #define JS_HAS_NUMBER_FORMATS   0       /* numbers have formatting methods */
> #define JS_HAS_GETTER_SETTER    0       /* has JS2 getter/setter functions */
> #define JS_HAS_UNEVAL           0       /* has uneval() top-level function */
> #define JS_HAS_CONST            0       /* has JS2 const as alternative var */
> #define JS_HAS_FUN_EXPR_STMT    0       /* has function expression statement */
> #define JS_HAS_LVALUE_RETURN    0       /* has o.item(i) = j; for native item */
207c312
< #elif JS_VERSION == 180
---
> #elif JS_VERSION == 150
209,210c314,334
< #define JS_HAS_STR_HTML_HELPERS 1       /* has str.anchor, str.bold, etc. */
< #define JS_HAS_PERL_SUBSTR      1       /* has str.substr */
---
> #define JS_BUG_NULL_INDEX_PROPS 0       /* o[0] defaults to null, not void */
> #define JS_BUG_EMPTY_INDEX_ZERO 0       /* o[""] is equivalent to o[0] */
> #define JS_BUG_EAGER_TOSTRING   0       /* o.toString() trumps o.valueOf() */
> #define JS_BUG_VOID_TOSTRING    0       /* void 0 + 0 == "undefined0" */
> #define JS_BUG_EVAL_THIS_FUN    0       /* eval('this') in function f is f */
> #define JS_BUG_EVAL_THIS_SCOPE  0       /* Math.eval('sin(x)') vs. local x */
> #define JS_BUG_FALLIBLE_EQOPS   0       /* fallible/intransitive equality ops */
> #define JS_BUG_FALLIBLE_TONUM   0       /* fallible ValueToNumber primitive */
> #define JS_BUG_WITH_CLOSURE     0       /* with(o)function f(){} sets o.f */
> 
> #define JS_HAS_PROP_DELETE      1       /* delete o.p removes p from o */
> #define JS_HAS_CALL_OBJECT      1       /* fun.caller is stack frame obj */
> #define JS_HAS_LABEL_STATEMENT  1       /* has break/continue to label: */
> #define JS_HAS_DO_WHILE_LOOP    1       /* has do {...} while (b) */
> #define JS_HAS_SWITCH_STATEMENT 1       /* has switch (v) {case c: ...} */
> #define JS_HAS_SOME_PERL_FUN    1       /* has array.join/reverse/sort */
> #define JS_HAS_MORE_PERL_FUN    1       /* has array.push, str.substr, etc */
> #define JS_HAS_VALUEOF_HINT     1       /* valueOf(hint) where hint is typeof */
> #define JS_HAS_LEXICAL_CLOSURE  1       /* nested functions, lexically closed */
> #define JS_HAS_APPLY_FUNCTION   1       /* has apply(fun, arg1, ... argN) */
> #define JS_HAS_CALL_FUNCTION    1       /* has fun.call(obj, arg1, ... argN) */
211a336,338
> #define JS_HAS_REGEXPS          1       /* has perl r.e.s via RegExp, /pat/ */
> #define JS_HAS_SEQUENCE_OPS     1       /* has array.slice, string.concat */
> #define JS_HAS_INITIALIZERS     1       /* has var o = {'foo': 42, 'bar':3} */
214a342
> #define JS_HAS_TRIPLE_EQOPS     1       /* has === and !== identity eqops */
216,218c344,348
< #define JS_HAS_SCRIPT_OBJECT    0       /* has (new Script("x++")).exec() */
< #define JS_HAS_XDR              1       /* has XDR API and internal support */
< #define JS_HAS_XDR_FREEZE_THAW  0       /* has XDR freeze/thaw script methods */
---
> #define JS_HAS_REPLACE_LAMBDA   1       /* has string.replace(re, lambda) */
> #define JS_HAS_SCRIPT_OBJECT    1       /* has (new Script("x++")).exec() */
> #define JS_HAS_XDR              1       /* has XDR API and object methods */
> #define JS_HAS_EXCEPTIONS       1       /* has exception handling */
> #define JS_HAS_UNDEFINED        1       /* has global "undefined" property */
219a350,352
> #define JS_HAS_IN_OPERATOR      1       /* has in operator ('p' in {p:1}) */
> #define JS_HAS_INSTANCEOF       1       /* has {p:1} instanceof Object */
> #define JS_HAS_ARGS_OBJECT      1       /* has minimal ECMA arguments object */
220a354
> #define JS_HAS_ERROR_EXCEPTIONS 1       /* rt errors reflected as exceptions */
221a356
> #define JS_HAS_NEW_OBJ_METHODS  1       /* has Object.prototype query methods */
222a358,359
> #define JS_HAS_DFLT_MSG_STRINGS 1       /* provides English error messages */
> #define JS_HAS_NUMBER_FORMATS   1       /* numbers have formatting methods */
228,235d364
< #define JS_HAS_NO_SUCH_METHOD   1       /* has o.__noSuchMethod__ handler */
< #define JS_HAS_XML_SUPPORT      1       /* has ECMAScript for XML support */
< #define JS_HAS_ARRAY_EXTRAS     1       /* has indexOf and Lispy extras */
< #define JS_HAS_GENERATORS       1       /* has yield in generator function */
< #define JS_HAS_BLOCK_SCOPE      1       /* has block scope via let/arraycomp */
< #define JS_HAS_DESTRUCTURING    2       /* has [a,b] = ... or {p:a,q:b} = ... */
< #define JS_HAS_GENERATOR_EXPRS  1       /* has (expr for (lhs in iterable)) */
< #define JS_HAS_EXPR_CLOSURES    1       /* has function (formals) listexpr */
242,248d370
< 
< /* Features that are present in all versions. */
< #define JS_HAS_RESERVED_JAVA_KEYWORDS   1
< #define JS_HAS_RESERVED_ECMA_KEYWORDS   1
< 
< /* Feature-test macro for evolving destructuring support. */
< #define JS_HAS_DESTRUCTURING_SHORTHAND  (JS_HAS_DESTRUCTURING == 2)
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsconfig.mk /Volumes/Swap/js_D11/src/jsconfig.mk
3,14c3,11
< # ***** BEGIN LICENSE BLOCK *****
< # Version: MPL 1.1/GPL 2.0/LGPL 2.1
< #
< # The contents of this file are subject to the Mozilla Public License Version
< # 1.1 (the "License"); you may not use this file except in compliance with
< # the License. You may obtain a copy of the License at
< # http://www.mozilla.org/MPL/
< #
< # Software distributed under the License is distributed on an "AS IS" basis,
< # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
< # for the specific language governing rights and limitations under the
< # License.
---
> # The contents of this file are subject to the Netscape Public
> # License Version 1.1 (the "License"); you may not use this file
> # except in compliance with the License. You may obtain a copy of
> # the License at http://www.mozilla.org/NPL/
> # 
> # Software distributed under the License is distributed on an "AS
> # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
> # implied. See the License for the specific language governing
> # rights and limitations under the License.
19,22c16,19
< # The Initial Developer of the Original Code is
< # Netscape Communications Corporation.
< # Portions created by the Initial Developer are Copyright (C) 1998-1999
< # the Initial Developer. All Rights Reserved.
---
> # The Initial Developer of the Original Code is Netscape
> # Communications Corporation. Portions created by Netscape are
> # Copyright (C) 1998-1999 Netscape Communications Corporation. All
> # Rights Reserved.
26,36c23,32
< # Alternatively, the contents of this file may be used under the terms of
< # either of the GNU General Public License Version 2 or later (the "GPL"),
< # or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
< # in which case the provisions of the GPL or the LGPL are applicable instead
< # of those above. If you wish to allow use of your version of this file only
< # under the terms of either the GPL or the LGPL, and not to allow others to
< # use your version of this file under the terms of the MPL, indicate your
< # decision by deleting the provisions above and replace them with the notice
< # and other provisions required by the GPL or the LGPL. If you do not delete
< # the provisions above, a recipient may use your version of this file under
< # the terms of any one of the MPL, the GPL or the LGPL.
---
> # Alternatively, the contents of this file may be used under the
> # terms of the GNU Public License (the "GPL"), in which case the
> # provisions of the GPL are applicable instead of those above.
> # If you wish to allow use of your version of this file only
> # under the terms of the GPL and not to allow others to use your
> # version of this file under the NPL, indicate your decision by
> # deleting the provisions above and replace them with the notice
> # and other provisions required by the GPL.  If you do not delete
> # the provisions above, a recipient may use your version of this
> # file under either the NPL or the GPL.
38d33
< # ***** END LICENSE BLOCK *****
Only in /Volumes/Swap/js-14-2-2008/js/src: jscpucfg.c
diff -r /Volumes/Swap/js-14-2-2008/js/src/jscpucfg.h /Volumes/Swap/js_D11/src/jscpucfg.h
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
45,49c40,41
< #if defined(XP_WIN) || defined(XP_OS2) || defined(WINCE)
< 
< #if defined(_WIN64)
< 
< #if defined(_M_X64) || defined(_M_AMD64) || defined(_AMD64_)
---
> #ifdef XP_MAC
> #if (defined(__APPLE__) && defined(__MACH__)) && defined(__LITTLE_ENDIAN__)
51a44,47
> #else
> #undef  IS_LITTLE_ENDIAN
> #define IS_BIG_ENDIAN 1
> #endif // (defined(__APPLE__) && defined(__MACH__))
60c56
< #define JS_BYTES_PER_WORD   8L
---
> #define JS_BYTES_PER_WORD   4L
70c66
< #define JS_BITS_PER_WORD    64L
---
> #define JS_BITS_PER_WORD    32L
79c75
< #define JS_BITS_PER_WORD_LOG2   6L
---
> #define JS_BITS_PER_WORD_LOG2   5L
84c80
< #define JS_ALIGN_OF_INT64   8L
---
> #define JS_ALIGN_OF_INT64   2L
86,88c82,84
< #define JS_ALIGN_OF_DOUBLE  8L
< #define JS_ALIGN_OF_POINTER 8L
< #define JS_ALIGN_OF_WORD    8L
---
> #define JS_ALIGN_OF_DOUBLE  4L
> #define JS_ALIGN_OF_POINTER 4L
> #define JS_ALIGN_OF_WORD    4L
90c86
< #define JS_BYTES_PER_WORD_LOG2   3L
---
> #define JS_BYTES_PER_WORD_LOG2   2L
92,97c88
< #define PR_WORDS_PER_DWORD_LOG2  0L
< #else  /* !(defined(_M_X64) || defined(_M_AMD64) || defined(_AMD64_)) */
< #error "CPU type is unknown"
< #endif /* !(defined(_M_X64) || defined(_M_AMD64) || defined(_AMD64_)) */
< 
< #elif defined(_WIN32) || defined(XP_OS2) || defined(WINCE)
---
> #define PR_WORDS_PER_DWORD_LOG2  1L
99,101c90
< #ifdef __WATCOMC__
< #define HAVE_VA_LIST_AS_ARRAY
< #endif
---
> #elif defined(XP_WIN) || defined(XP_OS2)
102a92
> #if defined( _WIN32) || defined(XP_OS2)
146c136
< #endif /* _WIN32 || XP_OS2 || WINCE*/
---
> #endif /* _WIN32 || XP_OS2 */
149d138
< 
193d181
< 
204,206c192
< #error "Must define one of XP_BEOS, XP_OS2, XP_WIN, or XP_UNIX"
< 
< #endif
---
> #error "Must define one of XP_BEOS, XP_MAC, XP_OS2, XP_WIN, or XP_UNIX"
208,209d193
< #ifndef JS_STACK_GROWTH_DIRECTION
< #define JS_STACK_GROWTH_DIRECTION (-1)
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsdate.c /Volumes/Swap/js_D11/src/jsdate.c
2d1
<  * vim: set ts=8 sw=4 et tw=78:
4,15c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
20,23c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
27,39c23,33
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
56d49
< #include <locale.h>
58c51
< #include <stdlib.h>
---
> #include "xstdlib.h"
71a65,68
> #include "jsapi.h"
> 
> 
> //#include "_optimize.h"
183c180
<         result += msPerDay;
---
> 	result += msPerDay;
188c185
<                          ? 366 : 365)
---
> 			 ? 366 : 365)
194c191
<                          - floor(((y)-1901)/100.0) + floor(((y)-1601)/400.0))
---
> 			 - floor(((y)-1901)/100.0) + floor(((y)-1601)/400.0))
235c232
<         return 0;
---
> 	return 0;
238c235
<         return 1;
---
> 	return 1;
240c237
<         return 2;
---
> 	return 2;
242c239
<         return 3;
---
> 	return 3;
244c241
<         return 4;
---
> 	return 4;
246c243
<         return 5;
---
> 	return 5;
248c245
<         return 6;
---
> 	return 6;
250c247
<         return 7;
---
> 	return 7;
252c249
<         return 8;
---
> 	return 8;
254c251
<         return 9;
---
> 	return 9;
256c253
<         return 10;
---
> 	return 10;
268c265
<         return d + 1;
---
> 	return d + 1;
272c269
<         return d - step;
---
> 	return d - step;
275c272
<         return d - step;
---
> 	return d - step;
278c275
<         return d - step;
---
> 	return d - step;
281c278
<         return d - step;
---
> 	return d - step;
284c281
<         return d - step;
---
> 	return d - step;
287c284
<         return d - step;
---
> 	return d - step;
290c287
<         return d - step;
---
> 	return d - step;
293c290
<         return d - step;
---
> 	return d - step;
296c293
<         return d - step;
---
> 	return d - step;
299c296
<         return d - step;
---
> 	return d - step;
311c308
<         result += 7;
---
> 	result += 7;
315,377d311
< #define MakeTime(hour, min, sec, ms) \
< ((((hour) * MinutesPerHour + (min)) * SecondsPerMinute + (sec)) * msPerSecond + (ms))
< 
< static jsdouble
< MakeDay(jsdouble year, jsdouble month, jsdouble date)
< {
<     JSBool leap;
<     jsdouble yearday;
<     jsdouble monthday;
< 
<     year += floor(month / 12);
< 
<     month = fmod(month, 12.0);
<     if (month < 0)
<         month += 12;
< 
<     leap = (DaysInYear((jsint) year) == 366);
< 
<     yearday = floor(TimeFromYear(year) / msPerDay);
<     monthday = DayFromMonth(month, leap);
< 
<     return yearday + monthday + date - 1;
< }
< 
< #define MakeDate(day, time) ((day) * msPerDay + (time))
< 
< /*
<  * Years and leap years on which Jan 1 is a Sunday, Monday, etc.
<  *
<  * yearStartingWith[0][i] is an example non-leap year where
<  * Jan 1 appears on Sunday (i == 0), Monday (i == 1), etc.
<  *
<  * yearStartingWith[1][i] is an example leap year where
<  * Jan 1 appears on Sunday (i == 0), Monday (i == 1), etc.
<  */
< static jsint yearStartingWith[2][7] = {
<     {1978, 1973, 1974, 1975, 1981, 1971, 1977},
<     {1984, 1996, 1980, 1992, 1976, 1988, 1972}
< };
< 
< /*
<  * Find a year for which any given date will fall on the same weekday.
<  *
<  * This function should be used with caution when used other than
<  * for determining DST; it hasn't been proven not to produce an
<  * incorrect year for times near year boundaries.
<  */
< static jsint
< EquivalentYearForDST(jsint year)
< {
<     jsint day;
<     JSBool isLeapYear;
< 
<     day = (jsint) DayFromYear(year) + 4;
<     day = day % 7;
<     if (day < 0)
<         day += 7;
< 
<     isLeapYear = (DaysInYear(year) == 366);
< 
<     return yearStartingWith[isLeapYear][day];
< }
< 
391,404c325
<         return t;
< 
<     /*
<      * If earlier than 1970 or after 2038, potentially beyond the ken of
<      * many OSes, map it to an equivalent year before asking.
<      */
<     if (t < 0.0 || t > 2145916800000.0) {
<         jsint year;
<         jsdouble day;
< 
<         year = EquivalentYearForDST(YearFromTime(t));
<         day = MakeDay(year, MonthFromTime(t), DateFromTime(t));
<         t = MakeDate(day, TimeWithinDay(t));
<     }
---
> 	return t;
434c355
<         result += (intN)HoursPerDay;
---
> 	result += (intN)HoursPerDay;
443c364
<         result += (intN)MinutesPerHour;
---
> 	result += (intN)MinutesPerHour;
452c373
<         result += (intN)SecondsPerMinute;
---
> 	result += (intN)SecondsPerMinute;
461c382,410
<         result += (intN)msPerSecond;
---
> 	result += (intN)msPerSecond;
>     return result;
> }
> 
> #define MakeTime(hour, min, sec, ms) \
> (((hour * MinutesPerHour + min) * SecondsPerMinute + sec) * msPerSecond + ms)
> 
> static jsdouble
> MakeDay(jsdouble year, jsdouble month, jsdouble date)
> {
>     jsdouble result;
>     JSBool leap;
>     jsdouble yearday;
>     jsdouble monthday;
> 
>     year += floor(month / 12);
> 
>     month = fmod(month, 12.0);
>     if (month < 0)
> 	month += 12;
> 
>     leap = (DaysInYear((jsint) year) == 366);
> 
>     yearday = floor(TimeFromYear(year) / msPerDay);
>     monthday = DayFromMonth(month, leap);
> 
>     result = yearday
> 	     + monthday
> 	     + date - 1;
464a414,415
> #define MakeDate(day, time) (day * msPerDay + time)
> 
466,467c417,418
<                       && !((d < 0 ? -d : d) > HalfTimeDomain)) \
<                      ? js_DoubleToInteger(d + (+0.)) : *cx->runtime->jsNaN)
---
> 		      && !((d < 0 ? -d : d) > HalfTimeDomain)) \
> 		     ? js_DoubleToInteger(d + (+0.)) : *cx->runtime->jsNaN)
477,484c428
< /*
<  * We use the first reseved slot to store UTC time, and the second for caching
<  * the local time. The initial value of the cache entry is NaN.
<  */
< #define UTC_TIME_SLOT           0
< #define LOCAL_TIME_SLOT         1
< 
< JSClass js_DateClass = {
---
> static JSClass date_class = {
486c430
<     JSCLASS_HAS_RESERVED_SLOTS(2) |  JSCLASS_HAS_CACHED_PROTO(JSProto_Date),
---
>     JSCLASS_HAS_PRIVATE,
494c438
< static const char* wtb[] = {
---
> static char* wtb[] = {
521c465
<                    int count, int ignoreCase)
---
> 		   int count, int ignoreCase)
527,538c471,482
<         if (ignoreCase) {
<             if (JS_TOLOWER((jschar)s1[s1off]) != JS_TOLOWER(s2[s2off])) {
<                 break;
<             }
<         } else {
<             if ((jschar)s1[s1off] != s2[s2off]) {
<                 break;
<             }
<         }
<         s1off++;
<         s2off++;
<         count--;
---
> 	if (ignoreCase) {
> 	    if (JS_TOLOWER((jschar)s1[s1off]) != JS_TOLOWER(s2[s2off])) {
> 		break;
> 	    }
> 	} else {
> 	    if ((jschar)s1[s1off] != s2[s2off]) {
> 		break;
> 	    }
> 	}
> 	s1off++;
> 	s2off++;
> 	count--;
542c486
<         result = JS_TRUE;
---
> 	result = JS_TRUE;
551c495
<                   jsdouble min, jsdouble sec, jsdouble msec)
---
> 		  jsdouble min, jsdouble sec, jsdouble msec)
562,563c506,511
< 
< /* compute the time in msec (unclipped) from the given args */
---
> 
> /*
>  * See ECMA 15.9.4.[3-10];
>  */
> /* XXX this function must be above date_parseString to avoid a
>    horrid bug in the Win16 1.52 compiler */
565d512
< 
567c514
< date_msecFromArgs(JSContext *cx, uintN argc, jsval *argv, jsdouble *rval)
---
> date_UTC(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
569d515
<     uintN loop;
570a517
>     uintN loop;
572d518
<     jsdouble msec_time;
575,590c521,531
<         if (loop < argc) {
<             if (!js_ValueToNumber(cx, argv[loop], &d))
<                 return JS_FALSE;
<             /* return NaN if any arg is not finite */
<             if (!JSDOUBLE_IS_FINITE(d)) {
<                 *rval = *cx->runtime->jsNaN;
<                 return JS_TRUE;
<             }
<             array[loop] = js_DoubleToInteger(d);
<         } else {
<             if (loop == 2) {
<                 array[loop] = 1; /* Default the date argument to 1. */
<             } else {
<                 array[loop] = 0;
<             }
<         }
---
> 	if (loop < argc) {
> 	    if (!js_ValueToNumber(cx, argv[loop], &d))
> 		return JS_FALSE;
> 	    /* return NaN if any arg is NaN */
> 	    if (!JSDOUBLE_IS_FINITE(d)) {
> 		return js_NewNumberValue(cx, d, rval);
> 	    }
> 	    array[loop] = floor(d);
> 	} else {
> 	    array[loop] = 0;
> 	}
595c536
<         array[0] += 1900;
---
> 	array[0] += 1900;
597,601c538,545
<     msec_time = date_msecFromDate(array[0], array[1], array[2],
<                                   array[3], array[4], array[5], array[6]);
<     *rval = msec_time;
<     return JS_TRUE;
< }
---
>     /* if we got a 0 for 'date' (which is out of range)
>      * pretend it's a 1.  (So Date.UTC(1972, 5) works) */
>     if (array[2] < 1)
> 	array[2] = 1;
> 
>     d = date_msecFromDate(array[0], array[1], array[2],
> 			      array[3], array[4], array[5], array[6]);
>     d = TIMECLIP(d);
603,617c547
< 
< /*
<  * See ECMA 15.9.4.[3-10];
<  */
< static JSBool
< date_UTC(JSContext *cx, uintN argc, jsval *vp)
< {
<     jsdouble msec_time;
< 
<     if (!date_msecFromArgs(cx, argc, vp + 2, &msec_time))
<         return JS_FALSE;
< 
<     msec_time = TIMECLIP(msec_time);
< 
<     return js_NewNumberValue(cx, msec_time, vp);
---
>     return js_NewNumberValue(cx, d, rval);
625,626c555,556
<     const jschar *s;
<     size_t limit;
---
>     const jschar *s = JSSTRING_CHARS(str);
>     size_t limit = JSSTRING_LENGTH(str);
636c566
<     int tzoffset = -1;
---
>     jsdouble tzoffset = -1;  /* was an int, overflowed on win16!!! */
639,640d568
<     int temp;
<     JSBool seenmonthname = JS_FALSE;
642d569
<     JSSTRING_CHARS_AND_LENGTH(str, s, limit);
644c571
<         goto syntax;
---
> 	goto syntax;
646,753c573,677
<         c = s[i];
<         i++;
<         if (c <= ' ' || c == ',' || c == '-') {
<             if (c == '-' && '0' <= s[i] && s[i] <= '9') {
<               prevc = c;
<             }
<             continue;
<         }
<         if (c == '(') { /* comments) */
<             int depth = 1;
<             while (i < limit) {
<                 c = s[i];
<                 i++;
<                 if (c == '(') depth++;
<                 else if (c == ')')
<                     if (--depth <= 0)
<                         break;
<             }
<             continue;
<         }
<         if ('0' <= c && c <= '9') {
<             n = c - '0';
<             while (i < limit && '0' <= (c = s[i]) && c <= '9') {
<                 n = n * 10 + c - '0';
<                 i++;
<             }
< 
<             /* allow TZA before the year, so
<              * 'Wed Nov 05 21:49:11 GMT-0800 1997'
<              * works */
< 
<             /* uses of seenplusminus allow : in TZA, so Java
<              * no-timezone style of GMT+4:30 works
<              */
< 
<             if ((prevc == '+' || prevc == '-')/*  && year>=0 */) {
<                 /* make ':' case below change tzoffset */
<                 seenplusminus = JS_TRUE;
< 
<                 /* offset */
<                 if (n < 24)
<                     n = n * 60; /* EG. "GMT-3" */
<                 else
<                     n = n % 100 + n / 100 * 60; /* eg "GMT-0430" */
<                 if (prevc == '+')       /* plus means east of GMT */
<                     n = -n;
<                 if (tzoffset != 0 && tzoffset != -1)
<                     goto syntax;
<                 tzoffset = n;
<             } else if (prevc == '/' && mon >= 0 && mday >= 0 && year < 0) {
<                 if (c <= ' ' || c == ',' || c == '/' || i >= limit)
<                     year = n;
<                 else
<                     goto syntax;
<             } else if (c == ':') {
<                 if (hour < 0)
<                     hour = /*byte*/ n;
<                 else if (min < 0)
<                     min = /*byte*/ n;
<                 else
<                     goto syntax;
<             } else if (c == '/') {
<                 /* until it is determined that mon is the actual
<                    month, keep it as 1-based rather than 0-based */
<                 if (mon < 0)
<                     mon = /*byte*/ n;
<                 else if (mday < 0)
<                     mday = /*byte*/ n;
<                 else
<                     goto syntax;
<             } else if (i < limit && c != ',' && c > ' ' && c != '-' && c != '(') {
<                 goto syntax;
<             } else if (seenplusminus && n < 60) {  /* handle GMT-3:30 */
<                 if (tzoffset < 0)
<                     tzoffset -= n;
<                 else
<                     tzoffset += n;
<             } else if (hour >= 0 && min < 0) {
<                 min = /*byte*/ n;
<             } else if (prevc == ':' && min >= 0 && sec < 0) {
<                 sec = /*byte*/ n;
<             } else if (mon < 0) {
<                 mon = /*byte*/n;
<             } else if (mon >= 0 && mday < 0) {
<                 mday = /*byte*/ n;
<             } else if (mon >= 0 && mday >= 0 && year < 0) {
<                 year = n;
<             } else {
<                 goto syntax;
<             }
<             prevc = 0;
<         } else if (c == '/' || c == ':' || c == '+' || c == '-') {
<             prevc = c;
<         } else {
<             size_t st = i - 1;
<             int k;
<             while (i < limit) {
<                 c = s[i];
<                 if (!(('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')))
<                     break;
<                 i++;
<             }
<             if (i <= st + 1)
<                 goto syntax;
<             for (k = JS_ARRAY_LENGTH(wtb); --k >= 0;)
<                 if (date_regionMatches(wtb[k], 0, s, st, i-st, 1)) {
<                     int action = ttb[k];
<                     if (action != 0) {
---
> 	c = s[i];
> 	i++;
> 	if (c <= ' ' || c == ',' || c == '-') {
> 	    if (c == '-' && '0' <= s[i] && s[i] <= '9') {
> 	      prevc = c;
> 	    }
> 	    continue;
> 	}
> 	if (c == '(') { /* comments) */
> 	    int depth = 1;
> 	    while (i < limit) {
> 		c = s[i];
> 		i++;
> 		if (c == '(') depth++;
> 		else if (c == ')')
> 		    if (--depth <= 0)
> 			break;
> 	    }
> 	    continue;
> 	}
> 	if ('0' <= c && c <= '9') {
> 	    n = c - '0';
> 	    while (i < limit && '0' <= (c = s[i]) && c <= '9') {
> 		n = n * 10 + c - '0';
> 		i++;
> 	    }
> 
> 	    /* allow TZA before the year, so
> 	     * 'Wed Nov 05 21:49:11 GMT-0800 1997'
> 	     * works */
> 
> 	    /* uses of seenplusminus allow : in TZA, so Java
> 	     * no-timezone style of GMT+4:30 works
> 	     */
> 
> 	    if ((prevc == '+' || prevc == '-')/*  && year>=0 */) {
> 		/* make ':' case below change tzoffset */
> 		seenplusminus = JS_TRUE;
> 
> 		/* offset */
> 		if (n < 24)
> 		    n = n * 60; /* EG. "GMT-3" */
> 		else
> 		    n = n % 100 + n / 100 * 60; /* eg "GMT-0430" */
> 		if (prevc == '+')       /* plus means east of GMT */
> 		    n = -n;
> 		if (tzoffset != 0 && tzoffset != -1)
> 		    goto syntax;
> 		tzoffset = n;
> 	    } else if (n >= 70 ||
> 		       (prevc == '/' && mon >= 0 && mday >= 0 && year < 0)) {
> 		if (year >= 0)
> 		    goto syntax;
> 		else if (c <= ' ' || c == ',' || c == '/' || i >= limit)
> 		    year = n < 100 ? n + 1900 : n;
> 		else
> 		    goto syntax;
> 	    } else if (c == ':') {
> 		if (hour < 0)
> 		    hour = /*byte*/ n;
> 		else if (min < 0)
> 		    min = /*byte*/ n;
> 		else
> 		    goto syntax;
> 	    } else if (c == '/') {
> 		if (mon < 0)
> 		    mon = /*byte*/ n-1;
> 		else if (mday < 0)
> 		    mday = /*byte*/ n;
> 		else
> 		    goto syntax;
> 	    } else if (i < limit && c != ',' && c > ' ' && c != '-') {
> 		goto syntax;
> 	    } else if (seenplusminus && n < 60) {  /* handle GMT-3:30 */
> 		if (tzoffset < 0)
> 		    tzoffset -= n;
> 		else
> 		    tzoffset += n;
> 	    } else if (hour >= 0 && min < 0) {
> 		min = /*byte*/ n;
> 	    } else if (min >= 0 && sec < 0) {
> 		sec = /*byte*/ n;
> 	    } else if (mday < 0) {
> 		mday = /*byte*/ n;
> 	    } else {
> 		goto syntax;
> 	    }
> 	    prevc = 0;
> 	} else if (c == '/' || c == ':' || c == '+' || c == '-') {
> 	    prevc = c;
> 	} else {
> 	    size_t st = i - 1;
> 	    int k;
> 	    while (i < limit) {
> 		c = s[i];
> 		if (!(('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')))
> 		    break;
> 		i++;
> 	    }
> 	    if (i <= st + 1)
> 		goto syntax;
> 	    for (k = (sizeof(wtb)/sizeof(char*)); --k >= 0;)
> 		if (date_regionMatches(wtb[k], 0, s, st, i-st, 1)) {
> 		    int action = ttb[k];
> 		    if (action != 0) {
769,798c693,708
<                         } else if (action <= 13) { /* month! */
<                             /* Adjust mon to be 1-based until the final values
<                                for mon, mday and year are adjusted below */
<                             if (seenmonthname) {
<                                 goto syntax;
<                             }
<                             seenmonthname = JS_TRUE;
<                             temp = /*byte*/ (action - 2) + 1;
< 
<                             if (mon < 0) {
<                                 mon = temp;
<                             } else if (mday < 0) {
<                                 mday = mon;
<                                 mon = temp;
<                             } else if (year < 0) {
<                                 year = mon;
<                                 mon = temp;
<                             } else {
<                                 goto syntax;
<                             }
<                         } else {
<                             tzoffset = action - 10000;
<                         }
<                     }
<                     break;
<                 }
<             if (k < 0)
<                 goto syntax;
<             prevc = 0;
<         }
---
> 			} else if (action <= 13) { /* month! */
> 			    if (mon < 0) {
> 				mon = /*byte*/ (action - 2);
> 			    } else {
> 				goto syntax;
> 			    }
> 			} else {
> 			    tzoffset = action - 10000;
> 			}
> 		    }
> 		    break;
> 		}
> 	    if (k < 0)
> 		goto syntax;
> 	    prevc = 0;
> 	}
801,863c711
<         goto syntax;
<     /*
<       Case 1. The input string contains an English month name.
<               The form of the string can be month f l, or f month l, or
<               f l month which each evaluate to the same date.
<               If f and l are both greater than or equal to 70, or
<               both less than 70, the date is invalid.
<               The year is taken to be the greater of the values f, l.
<               If the year is greater than or equal to 70 and less than 100,
<               it is considered to be the number of years after 1900.
<       Case 2. The input string is of the form "f/m/l" where f, m and l are
<               integers, e.g. 7/16/45.
<               Adjust the mon, mday and year values to achieve 100% MSIE
<               compatibility.
<               a. If 0 <= f < 70, f/m/l is interpreted as month/day/year.
<                  i.  If year < 100, it is the number of years after 1900
<                  ii. If year >= 100, it is the number of years after 0.
<               b. If 70 <= f < 100
<                  i.  If m < 70, f/m/l is interpreted as
<                      year/month/day where year is the number of years after
<                      1900.
<                  ii. If m >= 70, the date is invalid.
<               c. If f >= 100
<                  i.  If m < 70, f/m/l is interpreted as
<                      year/month/day where year is the number of years after 0.
<                  ii. If m >= 70, the date is invalid.
<     */
<     if (seenmonthname) {
<         if ((mday >= 70 && year >= 70) || (mday < 70 && year < 70)) {
<             goto syntax;
<         }
<         if (mday > year) {
<             temp = year;
<             year = mday;
<             mday = temp;
<         }
<         if (year >= 70 && year < 100) {
<             year += 1900;
<         }
<     } else if (mon < 70) { /* (a) month/day/year */
<         if (year < 100) {
<             year += 1900;
<         }
<     } else if (mon < 100) { /* (b) year/month/day */
<         if (mday < 70) {
<             temp = year;
<             year = mon + 1900;
<             mon = mday;
<             mday = temp;
<         } else {
<             goto syntax;
<         }
<     } else { /* (c) year/month/day */
<         if (mday < 70) {
<             temp = year;
<             year = mon;
<             mon = mday;
<             mday = temp;
<         } else {
<             goto syntax;
<         }
<     }
<     mon -= 1; /* convert month to 0-based */
---
> 	goto syntax;
865c713
<         sec = 0;
---
> 	sec = 0;
867c715
<         min = 0;
---
> 	min = 0;
869c717
<         hour = 0;
---
> 	hour = 0;
871,872c719,720
<         jsdouble msec_time;
<         msec_time = date_msecFromDate(year, mon, mday, hour, min, sec, 0);
---
> 	jsdouble msec_time;
> 	msec_time = date_msecFromDate(year, mon, mday, hour, min, sec, 0);
874,875c722,723
<         *result = UTC(msec_time);
<         return JS_TRUE;
---
> 	*result = UTC(msec_time);
> 	return JS_TRUE;
890c738
< date_parse(JSContext *cx, uintN argc, jsval *vp)
---
> date_parse(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
895c743
<     str = js_ValueToString(cx, vp[2]);
---
>     str = js_ValueToString(cx, argv[0]);
897c745
<         return JS_FALSE;
---
> 	return JS_FALSE;
899,900c747,748
<         *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
<         return JS_TRUE;
---
> 	*rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
> 	return JS_TRUE;
904c752
<     return js_NewNumberValue(cx, result, vp);
---
>     return js_NewNumberValue(cx, result, rval);
908c756
< date_now(JSContext *cx, uintN argc, jsval *vp)
---
> date_now(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
918c766
<     return js_NewDoubleValue(cx, msec_time, vp);
---
>     return js_NewDoubleValue(cx, msec_time, rval);
922,923c770,771
<  * Get UTC time from the date object. Returns false if the object is not
<  * Date type.
---
>  * Check that obj is an object of class Date, and get the date value.
>  * Return NULL on failure.
925,977c773,774
< static JSBool
< GetUTCTime(JSContext *cx, JSObject *obj, jsval *vp, jsdouble *dp)
< {
<     jsval v;
< 
<     if (vp && !JS_InstanceOf(cx, obj, &js_DateClass, vp + 2))
<         return JS_FALSE;
<     if (!JS_GetReservedSlot(cx, obj, UTC_TIME_SLOT, &v))
<         return JS_FALSE;
< 
<     *dp = *JSVAL_TO_DOUBLE(v);
<     return JS_TRUE;
< }
< 
< /*
<  * Set UTC time slot with a pointer pointing to a jsdouble. This function is
<  * used only for setting UTC time to some predefined values, such as NaN.
<  *
<  * It also invalidates cached local time.
<  */
< static JSBool
< SetUTCTimePtr(JSContext *cx, JSObject *obj, jsval *vp, jsdouble *dp)
< {
<     if (vp && !JS_InstanceOf(cx, obj, &js_DateClass, vp + 2))
<         return JS_FALSE;
< 
<     /* Invalidate local time cache. */
<     if (!JS_SetReservedSlot(cx, obj, LOCAL_TIME_SLOT,
<                             DOUBLE_TO_JSVAL(cx->runtime->jsNaN))) {
<         return JS_FALSE;
<     }
< 
<     return JS_SetReservedSlot(cx, obj, UTC_TIME_SLOT, DOUBLE_TO_JSVAL(dp));
< }
< 
< /*
<  * Set UTC time to a given time.
<  */
< static JSBool
< SetUTCTime(JSContext *cx, JSObject *obj, jsval *vp, jsdouble t)
< {
<     jsdouble *dp = js_NewDouble(cx, t, 0);
<     if (!dp)
<         return JS_FALSE;
<     return SetUTCTimePtr(cx, obj, vp, dp);
< }
< 
< /*
<  * Get the local time, cache it if necessary. If UTC time is not finite
<  * (e.g., NaN), the local time slot is set to the UTC time without conversion.
<  */
< static JSBool
< GetLocalTime(JSContext *cx, JSObject *obj, jsval *vp, jsdouble *dp)
---
> static jsdouble *
> date_getProlog(JSContext *cx, JSObject *obj, jsval *argv)
979,1007c776,778
<     jsval v;
<     jsdouble result;
<     jsdouble *cached;
< 
<     if (!JS_GetReservedSlot(cx, obj, LOCAL_TIME_SLOT, &v))
<         return JS_FALSE;
< 
<     result = *JSVAL_TO_DOUBLE(v);
< 
<     if (JSDOUBLE_IS_NaN(result)) {
<         if (!GetUTCTime(cx, obj, vp, &result))
<             return JS_FALSE;
< 
<         /* if result is NaN, it couldn't be finite. */
<         if (JSDOUBLE_IS_FINITE(result))
<             result = LocalTime(result);
< 
<         cached = js_NewDouble(cx, result, 0);
<         if (!cached)
<             return JS_FALSE;
< 
<         if (!JS_SetReservedSlot(cx, obj, LOCAL_TIME_SLOT,
<                                 DOUBLE_TO_JSVAL(cached))) {
<             return JS_FALSE;
<         }
<     }
< 
<     *dp = result;
<     return JS_TRUE;
---
>     if (!JS_InstanceOf(cx, obj, &date_class, argv))
> 	return NULL;
>     return JSVAL_TO_DOUBLE(OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE));
1014c785
< date_getTime(JSContext *cx, uintN argc, jsval *vp)
---
> date_getTime(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1016c787,789
<     jsdouble result;
---
>     jsdouble *date = date_getProlog(cx, obj, argv);
>     if (!date)
> 	return JS_FALSE;
1018,1019c791
<     return GetUTCTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &result) &&
<            js_NewNumberValue(cx, result, vp);
---
>     return js_NewNumberValue(cx, *date, rval);
1023c795
< GetYear(JSContext *cx, JSBool fullyear, jsval *vp)
---
> date_getYear(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1025a798,801
>     jsdouble *date = date_getProlog(cx, obj, argv);
>     if (!date)
> 	return JS_FALSE;
>     result = *date;
1027,1028c803,804
<     if (!GetLocalTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &result))
<         return JS_FALSE;
---
>     if (!JSDOUBLE_IS_FINITE(result))
> 	return js_NewNumberValue(cx, result, rval);
1030,1031c806
<     if (JSDOUBLE_IS_FINITE(result)) {
<         result = YearFromTime(result);
---
>     result = YearFromTime(LocalTime(result));
1033,1034c808,821
<         /* Follow ECMA-262 to the letter, contrary to IE JScript. */
<         if (!fullyear)
---
>     /*
>      * During the great date rewrite of 1.3, we tried to track the evolving ECMA
>      * standard, which then had a definition of getYear which always subtracted
>      * 1900.  Which we implemented, not realizing that it was incompatible with
>      * the old behavior...  now, rather than thrash the behavior yet again,
>      * we've decided to leave it with the - 1900 behavior and point people to
>      * the getFullYear method.  But we try to protect existing scripts that
>      * have specified a version...
>      */
>     if (cx->version == JSVERSION_1_0 ||
>         cx->version == JSVERSION_1_1 ||
>         cx->version == JSVERSION_1_2)
>     {
>         if (result >= 1900 && result < 2000)
1035a823,824
>     } else {
>         result -= 1900;
1037,1038c826
< 
<     return js_NewNumberValue(cx, result, vp);
---
>     return js_NewNumberValue(cx, result, rval);
1042c830,831
< date_getYear(JSContext *cx, uintN argc, jsval *vp)
---
> date_getFullYear(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
> 		 jsval *rval)
1044,1045c833,837
<     return GetYear(cx, JS_FALSE, vp);
< }
---
>     jsdouble result;
>     jsdouble *date = date_getProlog(cx, obj, argv);
>     if (!date)
> 	return JS_FALSE;
>     result = *date;
1047,1050c839,843
< static JSBool
< date_getFullYear(JSContext *cx, uintN argc, jsval *vp)
< {
<     return GetYear(cx, JS_TRUE, vp);
---
>     if (!JSDOUBLE_IS_FINITE(result))
> 	return js_NewNumberValue(cx, result, rval);
> 
>     result = YearFromTime(LocalTime(result));
>     return js_NewNumberValue(cx, result, rval);
1054c847,848
< date_getUTCFullYear(JSContext *cx, uintN argc, jsval *vp)
---
> date_getUTCFullYear(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
> 		    jsval *rval)
1056a851,854
>     jsdouble *date = date_getProlog(cx, obj, argv);
>     if (!date)
> 	return JS_FALSE;
>     result = *date;
1058,1062c856,857
<     if (!GetUTCTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &result))
<         return JS_FALSE;
< 
<     if (JSDOUBLE_IS_FINITE(result))
<         result = YearFromTime(result);
---
>     if (!JSDOUBLE_IS_FINITE(result))
> 	return js_NewNumberValue(cx, result, rval);
1064c859,860
<     return js_NewNumberValue(cx, result, vp);
---
>     result = YearFromTime(result);
>     return js_NewNumberValue(cx, result, rval);
1068c864,865
< date_getMonth(JSContext *cx, uintN argc, jsval *vp)
---
> date_getMonth(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
> 	      jsval *rval)
1070a868,871
>     jsdouble *date = date_getProlog(cx, obj, argv);
>     if (!date)
> 	return JS_FALSE;
>     result = *date;
1072,1076c873,874
<     if (!GetLocalTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &result))
<         return JS_FALSE;
< 
<     if (JSDOUBLE_IS_FINITE(result))
<         result = MonthFromTime(result);
---
>     if (!JSDOUBLE_IS_FINITE(result))
> 	return js_NewNumberValue(cx, result, rval);
1078c876,877
<     return js_NewNumberValue(cx, result, vp);
---
>     result = MonthFromTime(LocalTime(result));
>     return js_NewNumberValue(cx, result, rval);
1082c881,882
< date_getUTCMonth(JSContext *cx, uintN argc, jsval *vp)
---
> date_getUTCMonth(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
> 		 jsval *rval)
1084a885,888
>     jsdouble *date = date_getProlog(cx, obj, argv);
>     if (!date)
> 	return JS_FALSE;
>     result = *date;
1086,1090c890,891
<     if (!GetUTCTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &result))
<         return JS_FALSE;
< 
<     if (JSDOUBLE_IS_FINITE(result))
<         result = MonthFromTime(result);
---
>     if (!JSDOUBLE_IS_FINITE(result))
> 	return js_NewNumberValue(cx, result, rval);
1092c893,894
<     return js_NewNumberValue(cx, result, vp);
---
>     result = MonthFromTime(result);
>     return js_NewNumberValue(cx, result, rval);
1096c898
< date_getDate(JSContext *cx, uintN argc, jsval *vp)
---
> date_getDate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1098a901,904
>     jsdouble *date = date_getProlog(cx, obj, argv);
>     if (!date)
> 	return JS_FALSE;
>     result = *date;
1100,1104c906,907
<     if (!GetLocalTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &result))
<         return JS_FALSE;
< 
<     if (JSDOUBLE_IS_FINITE(result))
<         result = DateFromTime(result);
---
>     if (!JSDOUBLE_IS_FINITE(result))
> 	return js_NewNumberValue(cx, result, rval);
1106c909,911
<     return js_NewNumberValue(cx, result, vp);
---
>     result = LocalTime(result);
>     result = DateFromTime(result);
>     return js_NewNumberValue(cx, result, rval);
1110c915,916
< date_getUTCDate(JSContext *cx, uintN argc, jsval *vp)
---
> date_getUTCDate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
> 		jsval *rval)
1112a919,922
>     jsdouble *date = date_getProlog(cx, obj, argv);
>     if (!date)
> 	return JS_FALSE;
>     result = *date;
1114,1118c924,925
<     if (!GetUTCTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &result))
<         return JS_FALSE;
< 
<     if (JSDOUBLE_IS_FINITE(result))
<         result = DateFromTime(result);
---
>     if (!JSDOUBLE_IS_FINITE(result))
> 	return js_NewNumberValue(cx, result, rval);
1120c927,928
<     return js_NewNumberValue(cx, result, vp);
---
>     result = DateFromTime(result);
>     return js_NewNumberValue(cx, result, rval);
1124c932
< date_getDay(JSContext *cx, uintN argc, jsval *vp)
---
> date_getDay(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1126a935,938
>     jsdouble *date = date_getProlog(cx, obj, argv);
>     if (!date)
> 	return JS_FALSE;
>     result = *date;
1128,1132c940,941
<     if (!GetLocalTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &result))
<         return JS_FALSE;
< 
<     if (JSDOUBLE_IS_FINITE(result))
<         result = WeekDay(result);
---
>     if (!JSDOUBLE_IS_FINITE(result))
> 	return js_NewNumberValue(cx, result, rval);
1134c943,945
<     return js_NewNumberValue(cx, result, vp);
---
>     result = LocalTime(result);
>     result = WeekDay(result);
>     return js_NewNumberValue(cx, result, rval);
1138c949,950
< date_getUTCDay(JSContext *cx, uintN argc, jsval *vp)
---
> date_getUTCDay(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
> 	       jsval *rval)
1140a953,956
>     jsdouble *date = date_getProlog(cx, obj, argv);
>     if (!date)
> 	return JS_FALSE;
>     result = *date;
1142,1146c958,959
<     if (!GetUTCTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &result))
<         return JS_FALSE;
< 
<     if (JSDOUBLE_IS_FINITE(result))
<         result = WeekDay(result);
---
>     if (!JSDOUBLE_IS_FINITE(result))
> 	return js_NewNumberValue(cx, result, rval);
1148c961,962
<     return js_NewNumberValue(cx, result, vp);
---
>     result = WeekDay(result);
>     return js_NewNumberValue(cx, result, rval);
1152c966,967
< date_getHours(JSContext *cx, uintN argc, jsval *vp)
---
> date_getHours(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
> 	      jsval *rval)
1154a970,973
>     jsdouble *date = date_getProlog(cx, obj, argv);
>     if (!date)
> 	return JS_FALSE;
>     result = *date;
1156,1160c975,976
<     if (!GetLocalTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &result))
<         return JS_FALSE;
< 
<     if (JSDOUBLE_IS_FINITE(result))
<         result = HourFromTime(result);
---
>     if (!JSDOUBLE_IS_FINITE(result))
> 	return js_NewNumberValue(cx, result, rval);
1162c978,979
<     return js_NewNumberValue(cx, result, vp);
---
>     result = HourFromTime(LocalTime(result));
>     return js_NewNumberValue(cx, result, rval);
1166c983,984
< date_getUTCHours(JSContext *cx, uintN argc, jsval *vp)
---
> date_getUTCHours(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
> 		 jsval *rval)
1168a987,990
>     jsdouble *date = date_getProlog(cx, obj, argv);
>     if (!date)
> 	return JS_FALSE;
>     result = *date;
1170,1174c992,993
<     if (!GetUTCTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &result))
<         return JS_FALSE;
< 
<     if (JSDOUBLE_IS_FINITE(result))
<         result = HourFromTime(result);
---
>     if (!JSDOUBLE_IS_FINITE(result))
> 	return js_NewNumberValue(cx, result, rval);
1176c995,996
<     return js_NewNumberValue(cx, result, vp);
---
>     result = HourFromTime(result);
>     return js_NewNumberValue(cx, result, rval);
1180c1000,1001
< date_getMinutes(JSContext *cx, uintN argc, jsval *vp)
---
> date_getMinutes(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
> 		jsval *rval)
1182a1004,1007
>     jsdouble *date = date_getProlog(cx, obj, argv);
>     if (!date)
> 	return JS_FALSE;
>     result = *date;
1184,1188c1009,1010
<     if (!GetLocalTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &result))
<         return JS_FALSE;
< 
<     if (JSDOUBLE_IS_FINITE(result))
<         result = MinFromTime(result);
---
>     if (!JSDOUBLE_IS_FINITE(result))
> 	return js_NewNumberValue(cx, result, rval);
1190c1012,1013
<     return js_NewNumberValue(cx, result, vp);
---
>     result = MinFromTime(LocalTime(result));
>     return js_NewNumberValue(cx, result, rval);
1194c1017,1018
< date_getUTCMinutes(JSContext *cx, uintN argc, jsval *vp)
---
> date_getUTCMinutes(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
> 		   jsval *rval)
1196a1021,1024
>     jsdouble *date = date_getProlog(cx, obj, argv);
>     if (!date)
> 	return JS_FALSE;
>     result = *date;
1198,1202c1026,1027
<     if (!GetUTCTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &result))
<         return JS_FALSE;
< 
<     if (JSDOUBLE_IS_FINITE(result))
<         result = MinFromTime(result);
---
>     if (!JSDOUBLE_IS_FINITE(result))
> 	return js_NewNumberValue(cx, result, rval);
1204c1029,1030
<     return js_NewNumberValue(cx, result, vp);
---
>     result = MinFromTime(result);
>     return js_NewNumberValue(cx, result, rval);
1210c1036,1037
< date_getUTCSeconds(JSContext *cx, uintN argc, jsval *vp)
---
> date_getUTCSeconds(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
> 		jsval *rval)
1212a1040,1043
>     jsdouble *date = date_getProlog(cx, obj, argv);
>     if (!date)
> 	return JS_FALSE;
>     result = *date;
1214,1218c1045,1046
<     if (!GetUTCTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &result))
<         return JS_FALSE;
< 
<     if (JSDOUBLE_IS_FINITE(result))
<         result = SecFromTime(result);
---
>     if (!JSDOUBLE_IS_FINITE(result))
> 	return js_NewNumberValue(cx, result, rval);
1220c1048,1049
<     return js_NewNumberValue(cx, result, vp);
---
>     result = SecFromTime(result);
>     return js_NewNumberValue(cx, result, rval);
1226c1055,1056
< date_getUTCMilliseconds(JSContext *cx, uintN argc, jsval *vp)
---
> date_getUTCMilliseconds(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
> 		     jsval *rval)
1228a1059,1062
>     jsdouble *date = date_getProlog(cx, obj, argv);
>     if (!date)
> 	return JS_FALSE;
>     result = *date;
1230,1234c1064,1065
<     if (!GetUTCTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &result))
<         return JS_FALSE;
< 
<     if (JSDOUBLE_IS_FINITE(result))
<         result = msFromTime(result);
---
>     if (!JSDOUBLE_IS_FINITE(result))
> 	return js_NewNumberValue(cx, result, rval);
1236c1067,1068
<     return js_NewNumberValue(cx, result, vp);
---
>     result = msFromTime(result);
>     return js_NewNumberValue(cx, result, rval);
1240c1072,1073
< date_getTimezoneOffset(JSContext *cx, uintN argc, jsval *vp)
---
> date_getTimezoneOffset(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
> 		       jsval *rval)
1242,1249c1075,1079
<     JSObject *obj;
<     jsdouble utctime, localtime, result;
< 
<     obj = JSVAL_TO_OBJECT(vp[1]);
<     if (!GetUTCTime(cx, obj, vp, &utctime))
<         return JS_FALSE;
<     if (!GetLocalTime(cx, obj, NULL, &localtime))
<         return JS_FALSE;
---
>     jsdouble result;
>     jsdouble *date = date_getProlog(cx, obj, argv);
>     if (!date)
> 	return JS_FALSE;
>     result = *date;
1252,1254c1082,1084
<      * Return the time zone offset in minutes for the current locale that is
<      * appropriate for this time. This value would be a constant except for
<      * daylight savings time.
---
>      * Return the time zone offset in minutes for the current locale
>      * that is appropriate for this time. This value would be a
>      * constant except for daylight savings time.
1256,1257c1086,1087
<     result = (utctime - localtime) / msPerMinute;
<     return js_NewNumberValue(cx, result, vp);
---
>     result = (result - LocalTime(result)) / msPerMinute;
>     return js_NewNumberValue(cx, result, rval);
1261c1091
< date_setTime(JSContext *cx, uintN argc, jsval *vp)
---
> date_setTime(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1263a1094,1096
>     jsdouble *date = date_getProlog(cx, obj, argv);
>     if (!date)
> 	return JS_FALSE;
1265,1266c1098,1099
<     if (!js_ValueToNumber(cx, vp[2], &result))
<         return JS_FALSE;
---
>     if (!js_ValueToNumber(cx, argv[0], &result))
> 	return JS_FALSE;
1270,1273c1103,1104
<     if (!SetUTCTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, result))
<         return JS_FALSE;
< 
<     return js_NewNumberValue(cx, result, vp);
---
>     *date = result;
>     return js_NewNumberValue(cx, result, rval);
1277c1108,1109
< date_makeTime(JSContext *cx, uintN maxargs, JSBool local, uintN argc, jsval *vp)
---
> date_makeTime(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
> 	      uintN maxargs, JSBool local, jsval *rval)
1279,1280d1110
<     JSObject *obj;
<     jsval *argv;
1289,1291c1119,1123
<     obj = JSVAL_TO_OBJECT(vp[1]);
<     if (!GetUTCTime(cx, obj, vp, &result))
<         return JS_FALSE;
---
>     jsdouble *date = date_getProlog(cx, obj, argv);
>     if (!date)
> 	return JS_FALSE;
> 
>     result = *date;
1295c1127
<         return js_NewNumberValue(cx, result, vp);
---
> 	return js_NewNumberValue(cx, result, rval);
1297,1298c1129
<     /*
<      * Satisfy the ECMA rule that if a function is called with
---
>     /* Satisfy the ECMA rule that if a function is called with
1307c1138
<         argc = 1;   /* should be safe, because length of all setters is 1 */
---
> 	argc = 1;   /* should be safe, because length of all settors is 1 */
1309,1310c1140
<         argc = maxargs;  /* clamp argc */
<     JS_ASSERT(1 <= argc && argc <= 4);
---
> 	argc = maxargs;  /* clamp argc */
1312d1141
<     argv = vp + 2;
1314,1322c1143,1149
<         if (!js_ValueToNumber(cx, argv[i], &args[i]))
<             return JS_FALSE;
<         if (!JSDOUBLE_IS_FINITE(args[i])) {
<             if (!SetUTCTimePtr(cx, obj, NULL, cx->runtime->jsNaN))
<                 return JS_FALSE;
<             *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
<             return JS_TRUE;
<         }
<         args[i] = js_DoubleToInteger(args[i]);
---
> 	if (!js_ValueToNumber(cx, argv[i], &args[i]))
> 	    return JS_FALSE;
> 	if (!JSDOUBLE_IS_FINITE(args[i])) {
> 	    *date = *cx->runtime->jsNaN;
> 	    return js_NewNumberValue(cx, *date, rval);
> 	}
> 	args[i] = js_DoubleToInteger(args[i]);
1326c1153
<         lorutime = LocalTime(result);
---
> 	lorutime = LocalTime(result);
1328c1155
<         lorutime = result;
---
> 	lorutime = result;
1333c1160
<         hour = *argp++;
---
> 	hour = *argp++;
1335c1162
<         hour = HourFromTime(lorutime);
---
> 	hour = HourFromTime(lorutime);
1338c1165
<         min = *argp++;
---
> 	min = *argp++;
1340c1167
<         min = MinFromTime(lorutime);
---
> 	min = MinFromTime(lorutime);
1343c1170
<         sec = *argp++;
---
> 	sec = *argp++;
1345c1172
<         sec = SecFromTime(lorutime);
---
> 	sec = SecFromTime(lorutime);
1348c1175
<         msec = *argp;
---
> 	msec = *argp;
1350c1177
<         msec = msFromTime(lorutime);
---
> 	msec = msFromTime(lorutime);
1358c1185
<         result = UTC(result);
---
> 	result = UTC(result);
1362,1366c1189,1190
<     result = TIMECLIP(result);
<     if (!SetUTCTime(cx, obj, NULL, result))
<         return JS_FALSE;
< 
<     return js_NewNumberValue(cx, result, vp);
---
>     *date = TIMECLIP(result);
>     return js_NewNumberValue(cx, *date, rval);
1370c1194,1195
< date_setMilliseconds(JSContext *cx, uintN argc, jsval *vp)
---
> date_setMilliseconds(JSContext *cx, JSObject *obj, uintN argc,
> 		     jsval *argv, jsval *rval)
1372c1197
<     return date_makeTime(cx, 1, JS_TRUE, argc, vp);
---
>     return date_makeTime(cx, obj, argc, argv, 1, JS_TRUE, rval);
1376c1201,1202
< date_setUTCMilliseconds(JSContext *cx, uintN argc, jsval *vp)
---
> date_setUTCMilliseconds(JSContext *cx, JSObject *obj, uintN argc,
> 			jsval *argv, jsval *rval)
1378c1204
<     return date_makeTime(cx, 1, JS_FALSE, argc, vp);
---
>     return date_makeTime(cx, obj, argc, argv, 1, JS_FALSE, rval);
1382c1208,1209
< date_setSeconds(JSContext *cx, uintN argc, jsval *vp)
---
> date_setSeconds(JSContext *cx, JSObject *obj, uintN argc,
> 		jsval *argv, jsval *rval)
1384c1211
<     return date_makeTime(cx, 2, JS_TRUE, argc, vp);
---
>     return date_makeTime(cx, obj, argc, argv, 2, JS_TRUE, rval);
1388c1215,1216
< date_setUTCSeconds(JSContext *cx, uintN argc, jsval *vp)
---
> date_setUTCSeconds(JSContext *cx, JSObject *obj, uintN argc,
> 		   jsval *argv, jsval *rval)
1390c1218
<     return date_makeTime(cx, 2, JS_FALSE, argc, vp);
---
>     return date_makeTime(cx, obj, argc, argv, 2, JS_FALSE, rval);
1394c1222,1223
< date_setMinutes(JSContext *cx, uintN argc, jsval *vp)
---
> date_setMinutes(JSContext *cx, JSObject *obj, uintN argc,
> 		jsval *argv, jsval *rval)
1396c1225
<     return date_makeTime(cx, 3, JS_TRUE, argc, vp);
---
>     return date_makeTime(cx, obj, argc, argv, 3, JS_TRUE, rval);
1400c1229,1230
< date_setUTCMinutes(JSContext *cx, uintN argc, jsval *vp)
---
> date_setUTCMinutes(JSContext *cx, JSObject *obj, uintN argc,
> 		   jsval *argv, jsval *rval)
1402c1232
<     return date_makeTime(cx, 3, JS_FALSE, argc, vp);
---
>     return date_makeTime(cx, obj, argc, argv, 3, JS_FALSE, rval);
1406c1236,1237
< date_setHours(JSContext *cx, uintN argc, jsval *vp)
---
> date_setHours(JSContext *cx, JSObject *obj, uintN argc,
> 	      jsval *argv, jsval *rval)
1408c1239
<     return date_makeTime(cx, 4, JS_TRUE, argc, vp);
---
>     return date_makeTime(cx, obj, argc, argv, 4, JS_TRUE, rval);
1412c1243,1244
< date_setUTCHours(JSContext *cx, uintN argc, jsval *vp)
---
> date_setUTCHours(JSContext *cx, JSObject *obj, uintN argc,
> 		 jsval *argv, jsval *rval)
1414c1246
<     return date_makeTime(cx, 4, JS_FALSE, argc, vp);
---
>     return date_makeTime(cx, obj, argc, argv, 4, JS_FALSE, rval);
1418c1250,1251
< date_makeDate(JSContext *cx, uintN maxargs, JSBool local, uintN argc, jsval *vp)
---
> date_makeDate(JSContext *cx, JSObject *obj, uintN argc,
> 	      jsval *argv, uintN maxargs, JSBool local, jsval *rval)
1420,1421d1252
<     JSObject *obj;
<     jsval *argv;
1428,1430c1259,1263
<     obj = JSVAL_TO_OBJECT(vp[1]);
<     if (!GetUTCTime(cx, obj, vp, &result))
<         return JS_FALSE;
---
>     jsdouble *date = date_getProlog(cx, obj, argv);
>     if (!date)
> 	return JS_FALSE;
> 
>     result = *date;
1434c1267
<         argc = 1;   /* should be safe, because length of all setters is 1 */
---
> 	argc = 1;   /* should be safe, because length of all settors is 1 */
1436,1437c1269
<         argc = maxargs;   /* clamp argc */
<     JS_ASSERT(1 <= argc && argc <= 3);
---
> 	argc = maxargs;   /* clamp argc */
1439d1270
<     argv = vp + 2;
1441,1449c1272,1278
<         if (!js_ValueToNumber(cx, argv[i], &args[i]))
<             return JS_FALSE;
<         if (!JSDOUBLE_IS_FINITE(args[i])) {
<             if (!SetUTCTimePtr(cx, obj, NULL, cx->runtime->jsNaN))
<                 return JS_FALSE;
<             *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
<             return JS_TRUE;
<         }
<         args[i] = js_DoubleToInteger(args[i]);
---
> 	if (!js_ValueToNumber(cx, argv[i], &args[i]))
> 	    return JS_FALSE;
> 	if (!JSDOUBLE_IS_FINITE(args[i])) {
> 	    *date = *cx->runtime->jsNaN;
> 	    return js_NewNumberValue(cx, *date, rval);
> 	}
> 	args[i] = js_DoubleToInteger(args[i]);
1455,1457c1284,1287
<         if (maxargs < 3)
<             return js_NewNumberValue(cx, result, vp);
<         lorutime = +0.;
---
> 	if (argc < 3)
> 	    return js_NewNumberValue(cx, result, rval);
> 	else
> 	    lorutime = +0.;
1459c1289,1292
<         lorutime = local ? LocalTime(result) : result;
---
> 	if (local)
> 	    lorutime = LocalTime(result);
> 	else
> 	    lorutime = result;
1465c1298
<         year = *argp++;
---
> 	year = *argp++;
1467c1300
<         year = YearFromTime(lorutime);
---
> 	year = YearFromTime(lorutime);
1470c1303
<         month = *argp++;
---
> 	month = *argp++;
1472c1305
<         month = MonthFromTime(lorutime);
---
> 	month = MonthFromTime(lorutime);
1475c1308
<         day = *argp++;
---
> 	day = *argp++;
1477c1310
<         day = DateFromTime(lorutime);
---
> 	day = DateFromTime(lorutime);
1483,1487c1316
<         result = UTC(result);
< 
<     result = TIMECLIP(result);
<     if (!SetUTCTime(cx, obj, NULL, result))
<         return JS_FALSE;
---
> 	result = UTC(result);
1489c1318,1319
<     return js_NewNumberValue(cx, result, vp);
---
>     *date = TIMECLIP(result);
>     return js_NewNumberValue(cx, *date, rval);
1493c1323,1324
< date_setDate(JSContext *cx, uintN argc, jsval *vp)
---
> date_setDate(JSContext *cx, JSObject *obj, uintN argc,
> 	     jsval *argv, jsval *rval)
1495c1326
<     return date_makeDate(cx, 1, JS_TRUE, argc, vp);
---
>     return date_makeDate(cx, obj, argc, argv, 1, JS_TRUE, rval);
1499c1330,1331
< date_setUTCDate(JSContext *cx, uintN argc, jsval *vp)
---
> date_setUTCDate(JSContext *cx, JSObject *obj, uintN argc,
> 		jsval *argv, jsval *rval)
1501c1333
<     return date_makeDate(cx, 1, JS_FALSE, argc, vp);
---
>     return date_makeDate(cx, obj, argc, argv, 1, JS_FALSE, rval);
1505c1337,1338
< date_setMonth(JSContext *cx, uintN argc, jsval *vp)
---
> date_setMonth(JSContext *cx, JSObject *obj, uintN argc,
> 	      jsval *argv, jsval *rval)
1507c1340
<     return date_makeDate(cx, 2, JS_TRUE, argc, vp);
---
>     return date_makeDate(cx, obj, argc, argv, 2, JS_TRUE, rval);
1511c1344,1345
< date_setUTCMonth(JSContext *cx, uintN argc, jsval *vp)
---
> date_setUTCMonth(JSContext *cx, JSObject *obj, uintN argc,
> 		 jsval *argv, jsval *rval)
1513c1347
<     return date_makeDate(cx, 2, JS_FALSE, argc, vp);
---
>     return date_makeDate(cx, obj, argc, argv, 2, JS_FALSE, rval);
1517c1351,1352
< date_setFullYear(JSContext *cx, uintN argc, jsval *vp)
---
> date_setFullYear(JSContext *cx, JSObject *obj, uintN argc,
> 		 jsval *argv, jsval *rval)
1519c1354
<     return date_makeDate(cx, 3, JS_TRUE, argc, vp);
---
>     return date_makeDate(cx, obj, argc, argv, 3, JS_TRUE, rval);
1523c1358,1359
< date_setUTCFullYear(JSContext *cx, uintN argc, jsval *vp)
---
> date_setUTCFullYear(JSContext *cx, JSObject *obj, uintN argc,
> 		    jsval *argv, jsval *rval)
1525c1361
<     return date_makeDate(cx, 3, JS_FALSE, argc, vp);
---
>     return date_makeDate(cx, obj, argc, argv, 3, JS_FALSE, rval);
1529c1365,1366
< date_setYear(JSContext *cx, uintN argc, jsval *vp)
---
> date_setYear(JSContext *cx, JSObject *obj, uintN argc,
> 	     jsval *argv, jsval *rval)
1531d1367
<     JSObject *obj;
1537,1539c1373,1375
<     obj = JSVAL_TO_OBJECT(vp[1]);
<     if (!GetUTCTime(cx, obj, vp, &result))
<         return JS_FALSE;
---
>     jsdouble *date = date_getProlog(cx, obj, argv);
>     if (!date)
> 	return JS_FALSE;
1541,1542c1377,1380
<     if (!js_ValueToNumber(cx, vp[2], &year))
<         return JS_FALSE;
---
>     result = *date;
> 
>     if (!js_ValueToNumber(cx, argv[0], &year))
> 	return JS_FALSE;
1544,1546c1382,1383
<         if (!SetUTCTimePtr(cx, obj, NULL, cx->runtime->jsNaN))
<             return JS_FALSE;
<         return js_NewNumberValue(cx, *cx->runtime->jsNaN, vp);
---
> 	*date = *cx->runtime->jsNaN;
> 	return js_NewNumberValue(cx, *date, rval);
1552c1389
<         t = +0.0;
---
> 	t = +0.0;
1554c1391
<         t = LocalTime(result);
---
> 	t = LocalTime(result);
1558c1395
<         year += 1900;
---
> 	year += 1900;
1564,1568c1401,1402
<     result = TIMECLIP(result);
<     if (!SetUTCTime(cx, obj, NULL, result))
<         return JS_FALSE;
< 
<     return js_NewNumberValue(cx, result, vp);
---
>     *date = TIMECLIP(result);
>     return js_NewNumberValue(cx, *date, rval);
1583c1417,1418
< date_toGMTString(JSContext *cx, uintN argc, jsval *vp)
---
> date_toGMTString(JSContext *cx, JSObject *obj, uintN argc,
> 		 jsval *argv, jsval *rval)
1587,1590c1422,1424
<     jsdouble utctime;
< 
<     if (!GetUTCTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &utctime))
<         return JS_FALSE;
---
>     jsdouble *date = date_getProlog(cx, obj, argv);
>     if (!date)
> 	return JS_FALSE;
1592,1593c1426,1427
<     if (!JSDOUBLE_IS_FINITE(utctime)) {
<         JS_snprintf(buf, sizeof buf, js_NaN_date_str);
---
>     if (!JSDOUBLE_IS_FINITE(*date)) {
> 	JS_snprintf(buf, sizeof buf, js_NaN_date_str);
1595,1605c1429,1441
<         /* Avoid dependence on PRMJ_FormatTimeUSEnglish, because it
<          * requires a PRMJTime... which only has 16-bit years.  Sub-ECMA.
<          */
<         JS_snprintf(buf, sizeof buf, "%s, %.2d %s %.4d %.2d:%.2d:%.2d GMT",
<                     days[WeekDay(utctime)],
<                     DateFromTime(utctime),
<                     months[MonthFromTime(utctime)],
<                     YearFromTime(utctime),
<                     HourFromTime(utctime),
<                     MinFromTime(utctime),
<                     SecFromTime(utctime));
---
> 	jsdouble temp = *date;
> 
> 	/* Avoid dependence on PRMJ_FormatTimeUSEnglish, because it
> 	 * requires a PRMJTime... which only has 16-bit years.  Sub-ECMA.
> 	 */
> 	JS_snprintf(buf, sizeof buf, "%s, %.2d %s %.4d %.2d:%.2d:%.2d GMT",
> 		    days[WeekDay(temp)],
> 		    DateFromTime(temp),
> 		    months[MonthFromTime(temp)],
> 		    YearFromTime(temp),
> 		    HourFromTime(temp),
> 		    MinFromTime(temp),
> 		    SecFromTime(temp));
1609,1610c1445,1446
<         return JS_FALSE;
<     *vp = STRING_TO_JSVAL(str);
---
> 	return JS_FALSE;
>     *rval = STRING_TO_JSVAL(str);
1614a1451,1452
>  * If findEquivalent is true, then try to map the year to an equivalent year
>  * that's in range.
1617c1455
< new_explode(jsdouble timeval, PRMJTime *split)
---
> new_explode(jsdouble timeval, PRMJTime *split, JSBool findEquivalent)
1619a1458,1478
>     int16 adjustedYear;
> 
>     /* If the year doesn't fit in a PRMJTime, find something to do about it. */
>     if (year > 32767 || year < -32768) {
> 	if (findEquivalent) {
> 	    /* We're really just trying to get a timezone string; map the year
> 	     * to some equivalent year in the range 0 to 2800.  Borrowed from
> 	     * A. D. Olsen.
> 	     */
> 	    jsint cycles;
> #define CYCLE_YEARS 2800L
> 	    cycles = (year >= 0) ? year / CYCLE_YEARS
> 				 : -1 - (-1 - year) / CYCLE_YEARS;
> 	    adjustedYear = (int16)(year - cycles * CYCLE_YEARS);
> 	} else {
> 	    /* Clamp it to the nearest representable year. */
> 	    adjustedYear = (int16)((year > 0) ? 32767 : - 32768);
> 	}
>     } else {
> 	adjustedYear = (int16)year;
>     }
1628c1487
<     split->tm_year = year;
---
>     split->tm_year = (int16) adjustedYear;
1652c1511
<         JS_snprintf(buf, sizeof buf, js_NaN_date_str);
---
> 	JS_snprintf(buf, sizeof buf, js_NaN_date_str);
1654c1513
<         jsdouble local = LocalTime(date);
---
> 	jsdouble local = LocalTime(date);
1656,1674c1515,1533
<         /* offset from GMT in minutes.  The offset includes daylight savings,
<            if it applies. */
<         jsint minutes = (jsint) floor(AdjustTime(date) / msPerMinute);
< 
<         /* map 510 minutes to 0830 hours */
<         intN offset = (minutes / 60) * 100 + minutes % 60;
< 
<         /* print as "Wed Nov 05 19:38:03 GMT-0800 (PST) 1997" The TZA is
<          * printed as 'GMT-0800' rather than as 'PST' to avoid
<          * operating-system dependence on strftime (which
<          * PRMJ_FormatTimeUSEnglish calls, for %Z only.)  win32 prints
<          * PST as 'Pacific Standard Time.'  This way we always know
<          * what we're getting, and can parse it if we produce it.
<          * The OS TZA string is included as a comment.
<          */
< 
<         /* get a timezone string from the OS to include as a
<            comment. */
<         new_explode(date, &split);
---
> 	/* offset from GMT in minutes.  The offset includes daylight savings,
> 	   if it applies. */
> 	jsint minutes = (jsint) floor(AdjustTime(date) / msPerMinute);
> 
> 	/* map 510 minutes to 0830 hours */
> 	intN offset = (minutes / 60) * 100 + minutes % 60;
> 
> 	/* print as "Wed Nov 05 19:38:03 GMT-0800 (PST) 1997" The TZA is
> 	 * printed as 'GMT-0800' rather than as 'PST' to avoid
> 	 * operating-system dependence on strftime (which
> 	 * PRMJ_FormatTimeUSEnglish calls, for %Z only.)  win32 prints
> 	 * PST as 'Pacific Standard Time.'  This way we always know
> 	 * what we're getting, and can parse it if we produce it.
> 	 * The OS TZA string is included as a comment.
> 	 */
> 
> 	/* get a timezone string from the OS to include as a
> 	   comment. */
> 	new_explode(date, &split, JS_TRUE);
1749c1608
<         return JS_FALSE;
---
> 	return JS_FALSE;
1755c1614,1615
< date_toLocaleHelper(JSContext *cx, const char *format, jsval *vp)
---
> date_toLocaleHelper(JSContext *cx, JSObject *obj, uintN argc,
> 		    jsval *argv, jsval *rval, char *format)
1757d1616
<     JSObject *obj;
1761,1765c1620,1622
<     jsdouble utctime;
< 
<     obj = JSVAL_TO_OBJECT(vp[1]);
<     if (!GetUTCTime(cx, obj, vp, &utctime))
<         return JS_FALSE;
---
>     jsdouble *date = date_getProlog(cx, obj, argv);
>     if (!date)
> 	return JS_FALSE;
1767,1768c1624,1625
<     if (!JSDOUBLE_IS_FINITE(utctime)) {
<         JS_snprintf(buf, sizeof buf, js_NaN_date_str);
---
>     if (!JSDOUBLE_IS_FINITE(*date)) {
> 	JS_snprintf(buf, sizeof buf, js_NaN_date_str);
1770,1779c1627,1636
<         intN result_len;
<         jsdouble local = LocalTime(utctime);
<         new_explode(local, &split);
< 
<         /* let PRMJTime format it.       */
<         result_len = PRMJ_FormatTime(buf, sizeof buf, format, &split);
< 
<         /* If it failed, default to toString. */
<         if (result_len == 0)
<             return date_format(cx, utctime, FORMATSPEC_FULL, vp);
---
> 	intN result_len;
> 	jsdouble local = LocalTime(*date);
> 	new_explode(local, &split, JS_FALSE);
> 
> 	/* let PRMJTime format it.	 */
> 	result_len = PRMJ_FormatTime(buf, sizeof buf, format, &split);
> 
> 	/* If it failed, default to toString. */
> 	if (result_len == 0)
> 	    return date_format(cx, *date, FORMATSPEC_FULL, rval);
1782,1789c1639,1640
<         if (strcmp(format, "%x") == 0 && result_len >= 6 &&
<             /* Format %x means use OS settings, which may have 2-digit yr, so
<                hack end of 3/11/22 or 11.03.22 or 11Mar22 to use 4-digit yr...*/
<             !isdigit(buf[result_len - 3]) &&
<             isdigit(buf[result_len - 2]) && isdigit(buf[result_len - 1]) &&
<             /* ...but not if starts with 4-digit year, like 2022/3/11. */
<             !(isdigit(buf[0]) && isdigit(buf[1]) &&
<               isdigit(buf[2]) && isdigit(buf[3]))) {
---
>         if (buf[result_len - 3] == '/' &&
>             isdigit(buf[result_len - 2]) && isdigit(buf[result_len - 1])) {
1796,1798d1646
<     if (cx->localeCallbacks && cx->localeCallbacks->localeToUnicode)
<         return cx->localeCallbacks->localeToUnicode(cx, buf, vp);
< 
1801,1802c1649,1650
<         return JS_FALSE;
<     *vp = STRING_TO_JSVAL(str);
---
> 	return JS_FALSE;
>     *rval = STRING_TO_JSVAL(str);
1807c1655,1656
< date_toLocaleString(JSContext *cx, uintN argc, jsval *vp)
---
> date_toLocaleString(JSContext *cx, JSObject *obj, uintN argc,
> 		    jsval *argv, jsval *rval)
1813c1662
<     return date_toLocaleHelper(cx,
---
>     return date_toLocaleHelper(cx, obj, argc, argv, rval,
1815c1664
<                                    "%#c"
---
> 				   "%#c"
1817c1666
<                                    "%c"
---
> 				   "%c"
1819c1668
<                                , vp);
---
> 				   );
1823c1672,1673
< date_toLocaleDateString(JSContext *cx, uintN argc, jsval *vp)
---
> date_toLocaleDateString(JSContext *cx, JSObject *obj, uintN argc,
> 		    jsval *argv, jsval *rval)
1829c1679
<     return date_toLocaleHelper(cx,
---
>     return date_toLocaleHelper(cx, obj, argc, argv, rval,
1831c1681
<                                    "%#x"
---
> 				   "%#x"
1833c1683
<                                    "%x"
---
> 				   "%x"
1835,1841c1685
<                                , vp);
< }
< 
< static JSBool
< date_toLocaleTimeString(JSContext *cx, uintN argc, jsval *vp)
< {
<     return date_toLocaleHelper(cx, "%X", vp);
---
> 				   );
1845c1689,1690
< date_toLocaleFormat(JSContext *cx, uintN argc, jsval *vp)
---
> date_toLocaleTimeString(JSContext *cx, JSObject *obj, uintN argc,
> 		    jsval *argv, jsval *rval)
1847,1861c1692
<     JSString *fmt;
<     const char *fmtbytes;
< 
<     if (argc == 0)
<         return date_toLocaleString(cx, argc, vp);
< 
<     fmt = js_ValueToString(cx, vp[2]);
<     if (!fmt)
<         return JS_FALSE;
<     vp[2] = STRING_TO_JSVAL(fmt);
<     fmtbytes = js_GetStringBytes(cx, fmt);
<     if (!fmtbytes)
<         return JS_FALSE;
< 
<     return date_toLocaleHelper(cx, fmtbytes, vp);
---
>     return date_toLocaleHelper(cx, obj, argc, argv, rval, "%X");
1865c1696,1697
< date_toTimeString(JSContext *cx, uintN argc, jsval *vp)
---
> date_toTimeString(JSContext *cx, JSObject *obj, uintN argc,
> 		    jsval *argv, jsval *rval)
1867,1871c1699,1702
<     jsdouble utctime;
< 
<     if (!GetUTCTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &utctime))
<         return JS_FALSE;
<     return date_format(cx, utctime, FORMATSPEC_TIME, vp);
---
>     jsdouble *date = date_getProlog(cx, obj, argv);
>     if (!date)
> 	return JS_FALSE;
>     return date_format(cx, *date, FORMATSPEC_TIME, rval);
1875c1706,1707
< date_toDateString(JSContext *cx, uintN argc, jsval *vp)
---
> date_toDateString(JSContext *cx, JSObject *obj, uintN argc,
> 		    jsval *argv, jsval *rval)
1877,1881c1709,1712
<     jsdouble utctime;
< 
<     if (!GetUTCTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &utctime))
<         return JS_FALSE;
<     return date_format(cx, utctime, FORMATSPEC_DATE, vp);
---
>     jsdouble *date = date_getProlog(cx, obj, argv);
>     if (!date)
> 	return JS_FALSE;
>     return date_format(cx, *date, FORMATSPEC_DATE, rval);
1889c1720,1721
< date_toSource(JSContext *cx, uintN argc, jsval *vp)
---
> date_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
> 	      jsval *rval)
1891c1723
<     jsdouble utctime;
---
>     jsdouble *date;
1895,1896c1727,1729
<     if (!GetUTCTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &utctime))
<         return JS_FALSE;
---
>     date = date_getProlog(cx, obj, argv);
>     if (!date)
> 	return JS_FALSE;
1898c1731
<     numStr = JS_dtostr(buf, sizeof buf, DTOSTR_STANDARD, 0, utctime);
---
>     numStr = JS_dtostr(buf, sizeof buf, DTOSTR_STANDARD, 0, *date);
1900,1901c1733,1734
<         JS_ReportOutOfMemory(cx);
<         return JS_FALSE;
---
> 	JS_ReportOutOfMemory(cx);
> 	return JS_FALSE;
1904c1737
<     bytes = JS_smprintf("(new %s(%s))", js_Date_str, numStr);
---
>     bytes = JS_smprintf("(new %s(%s))", date_class.name, numStr);
1906,1907c1739,1740
<         JS_ReportOutOfMemory(cx);
<         return JS_FALSE;
---
> 	JS_ReportOutOfMemory(cx);
> 	return JS_FALSE;
1912,1913c1745,1746
<         free(bytes);
<         return JS_FALSE;
---
> 	xfree(bytes);
> 	return JS_FALSE;
1915c1748
<     *vp = STRING_TO_JSVAL(str);
---
>     *rval = STRING_TO_JSVAL(str);
1921c1754,1755
< date_toString(JSContext *cx, uintN argc, jsval *vp)
---
> date_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
> 	      jsval *rval)
1923,1927c1757,1760
<     jsdouble utctime;
< 
<     if (!GetUTCTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &utctime))
<         return JS_FALSE;
<     return date_format(cx, utctime, FORMATSPEC_FULL, vp);
---
>     jsdouble *date = date_getProlog(cx, obj, argv);
>     if (!date)
> 	return JS_FALSE;
>     return date_format(cx, *date, FORMATSPEC_FULL, rval);
1929a1763
> #if JS_HAS_VALUEOF_HINT
1931c1765,1766
< date_valueOf(JSContext *cx, uintN argc, jsval *vp)
---
> date_valueOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
> 	     jsval *rval)
1933,1934d1767
<     JSString *str, *str2;
< 
1937c1770
<      * GetUTCTime, which does the check.
---
>      * date_getProlog, which does the check.
1942c1775
<         return date_getTime(cx, argc, vp);
---
> 	return date_getTime(cx, obj, argc, argv, rval);
1945,1951c1778,1788
<     str = js_ValueToString(cx, vp[2]);
<     if (!str)
<         return JS_FALSE;
<     str2 = ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[JSTYPE_NUMBER]);
<     if (js_EqualStrings(str, str2))
<         return date_getTime(cx, argc, vp);
<     return date_toString(cx, argc, vp);
---
>     if (argc == 1) {
> 	JSString *str, *str2;
> 
> 	str = js_ValueToString(cx, argv[0]);
> 	if (!str)
> 	    return JS_FALSE;
> 	str2 = ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[JSTYPE_NUMBER]);
> 	if (!js_CompareStrings(str, str2))
> 	    return date_getTime(cx, obj, argc, argv, rval);
>     }
>     return date_toString(cx, obj, argc, argv, rval);
1952a1790,1792
> #else
> #define date_valueOf date_getTime
> #endif
1960,1963c1800,1803
<     JS_FN("UTC",                 date_UTC,                2,MAXARGS,0),
<     JS_FN("parse",               date_parse,              1,1,0),
<     JS_FN("now",                 date_now,                0,0,0),
<     JS_FS_END
---
>     {"UTC",               date_UTC,               MAXARGS,0,0 },
>     {"parse",             date_parse,             1,0,0 },
>     {"now",               date_now,               0,0,0 },
>     {0,0,0,0,0}
1967,2008c1807,1847
<     JS_FN("getTime",             date_getTime,            0,0,0),
<     JS_FN("getTimezoneOffset",   date_getTimezoneOffset,  0,0,0),
<     JS_FN("getYear",             date_getYear,            0,0,0),
<     JS_FN("getFullYear",         date_getFullYear,        0,0,0),
<     JS_FN("getUTCFullYear",      date_getUTCFullYear,     0,0,0),
<     JS_FN("getMonth",            date_getMonth,           0,0,0),
<     JS_FN("getUTCMonth",         date_getUTCMonth,        0,0,0),
<     JS_FN("getDate",             date_getDate,            0,0,0),
<     JS_FN("getUTCDate",          date_getUTCDate,         0,0,0),
<     JS_FN("getDay",              date_getDay,             0,0,0),
<     JS_FN("getUTCDay",           date_getUTCDay,          0,0,0),
<     JS_FN("getHours",            date_getHours,           0,0,0),
<     JS_FN("getUTCHours",         date_getUTCHours,        0,0,0),
<     JS_FN("getMinutes",          date_getMinutes,         0,0,0),
<     JS_FN("getUTCMinutes",       date_getUTCMinutes,      0,0,0),
<     JS_FN("getSeconds",          date_getUTCSeconds,      0,0,0),
<     JS_FN("getUTCSeconds",       date_getUTCSeconds,      0,0,0),
<     JS_FN("getMilliseconds",     date_getUTCMilliseconds, 0,0,0),
<     JS_FN("getUTCMilliseconds",  date_getUTCMilliseconds, 0,0,0),
<     JS_FN("setTime",             date_setTime,            1,1,0),
<     JS_FN("setYear",             date_setYear,            1,1,0),
<     JS_FN("setFullYear",         date_setFullYear,        1,3,0),
<     JS_FN("setUTCFullYear",      date_setUTCFullYear,     1,3,0),
<     JS_FN("setMonth",            date_setMonth,           1,2,0),
<     JS_FN("setUTCMonth",         date_setUTCMonth,        1,2,0),
<     JS_FN("setDate",             date_setDate,            1,1,0),
<     JS_FN("setUTCDate",          date_setUTCDate,         1,1,0),
<     JS_FN("setHours",            date_setHours,           1,4,0),
<     JS_FN("setUTCHours",         date_setUTCHours,        1,4,0),
<     JS_FN("setMinutes",          date_setMinutes,         1,3,0),
<     JS_FN("setUTCMinutes",       date_setUTCMinutes,      1,3,0),
<     JS_FN("setSeconds",          date_setSeconds,         1,2,0),
<     JS_FN("setUTCSeconds",       date_setUTCSeconds,      1,2,0),
<     JS_FN("setMilliseconds",     date_setMilliseconds,    1,1,0),
<     JS_FN("setUTCMilliseconds",  date_setUTCMilliseconds, 1,1,0),
<     JS_FN("toUTCString",         date_toGMTString,        0,0,0),
<     JS_FN(js_toLocaleString_str, date_toLocaleString,     0,0,0),
<     JS_FN("toLocaleDateString",  date_toLocaleDateString, 0,0,0),
<     JS_FN("toLocaleTimeString",  date_toLocaleTimeString, 0,0,0),
<     JS_FN("toLocaleFormat",      date_toLocaleFormat,     0,0,0),
<     JS_FN("toDateString",        date_toDateString,       0,0,0),
<     JS_FN("toTimeString",        date_toTimeString,       0,0,0),
---
>     {"getTime",             date_getTime,           0,0,0 },
>     {"getTimezoneOffset",   date_getTimezoneOffset, 0,0,0 },
>     {"getYear",             date_getYear,           0,0,0 },
>     {"getFullYear",         date_getFullYear,       0,0,0 },
>     {"getUTCFullYear",      date_getUTCFullYear,    0,0,0 },
>     {"getMonth",            date_getMonth,          0,0,0 },
>     {"getUTCMonth",         date_getUTCMonth,       0,0,0 },
>     {"getDate",             date_getDate,           0,0,0 },
>     {"getUTCDate",          date_getUTCDate,        0,0,0 },
>     {"getDay",              date_getDay,            0,0,0 },
>     {"getUTCDay",           date_getUTCDay,         0,0,0 },
>     {"getHours",            date_getHours,          0,0,0 },
>     {"getUTCHours",         date_getUTCHours,       0,0,0 },
>     {"getMinutes",          date_getMinutes,        0,0,0 },
>     {"getUTCMinutes",       date_getUTCMinutes,     0,0,0 },
>     {"getSeconds",          date_getUTCSeconds,     0,0,0 },
>     {"getUTCSeconds",       date_getUTCSeconds,     0,0,0 },
>     {"getMilliseconds",     date_getUTCMilliseconds,0,0,0 },
>     {"getUTCMilliseconds",  date_getUTCMilliseconds,0,0,0 },
>     {"setTime",             date_setTime,           1,0,0 },
>     {"setYear",             date_setYear,           1,0,0 },
>     {"setFullYear",         date_setFullYear,       3,0,0 },
>     {"setUTCFullYear",      date_setUTCFullYear,    3,0,0 },
>     {"setMonth",            date_setMonth,          2,0,0 },
>     {"setUTCMonth",         date_setUTCMonth,       2,0,0 },
>     {"setDate",             date_setDate,           1,0,0 },
>     {"setUTCDate",          date_setUTCDate,        1,0,0 },
>     {"setHours",            date_setHours,          4,0,0 },
>     {"setUTCHours",         date_setUTCHours,       4,0,0 },
>     {"setMinutes",          date_setMinutes,        3,0,0 },
>     {"setUTCMinutes",       date_setUTCMinutes,     3,0,0 },
>     {"setSeconds",          date_setSeconds,        2,0,0 },
>     {"setUTCSeconds",       date_setUTCSeconds,     2,0,0 },
>     {"setMilliseconds",     date_setMilliseconds,   1,0,0 },
>     {"setUTCMilliseconds",  date_setUTCMilliseconds,1,0,0 },
>     {"toUTCString",         date_toGMTString,       0,0,0 },
>     {js_toLocaleString_str, date_toLocaleString,    0,0,0 },
>     {"toLocaleDateString",  date_toLocaleDateString,0,0,0 },
>     {"toLocaleTimeString",  date_toLocaleTimeString,0,0,0 },
>     {"toDateString",        date_toDateString,      0,0,0 },
>     {"toTimeString",        date_toTimeString,      0,0,0 },
2010c1849
<     JS_FN(js_toSource_str,       date_toSource,           0,0,0),
---
>     {js_toSource_str,       date_toSource,          0,0,0 },
2012,2014c1851,1853
<     JS_FN(js_toString_str,       date_toString,           0,0,0),
<     JS_FN(js_valueOf_str,        date_valueOf,            0,0,0),
<     JS_FS_END
---
>     {js_toString_str,       date_toString,          0,0,0 },
>     {js_valueOf_str,        date_valueOf,           0,0,0 },
>     {0,0,0,0,0}
2022c1861
<     date = js_NewDouble(cx, 0.0, 0);
---
>     date = js_NewDouble(cx, 0.0);
2024,2029c1863,1864
<         return NULL;
< 
<     JS_SetReservedSlot(cx, obj, UTC_TIME_SLOT,
<                        DOUBLE_TO_JSVAL(date));
<     JS_SetReservedSlot(cx, obj, LOCAL_TIME_SLOT,
<                        DOUBLE_TO_JSVAL(cx->runtime->jsNaN));
---
> 	return NULL;
>     OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, DOUBLE_TO_JSVAL(date));
2040c1875
<     /* Date called as function. */
---
>     /* Date called as function */
2042,2043c1877,1878
<         int64 us, ms, us2ms;
<         jsdouble msec_time;
---
> 	int64 us, ms, us2ms;
> 	jsdouble msec_time;
2045,2051c1880,1886
<         /* NSPR 2.0 docs say 'We do not support PRMJ_NowMS and PRMJ_NowS',
<          * so compute ms from PRMJ_Now.
<          */
<         us = PRMJ_Now();
<         JSLL_UI2L(us2ms, PRMJ_USEC_PER_MSEC);
<         JSLL_DIV(ms, us, us2ms);
<         JSLL_L2D(msec_time, ms);
---
> 	/* NSPR 2.0 docs say 'We do not support PRMJ_NowMS and PRMJ_NowS',
> 	 * so compute ms from PRMJ_Now.
> 	 */
> 	us = PRMJ_Now();
> 	JSLL_UI2L(us2ms, PRMJ_USEC_PER_MSEC);
> 	JSLL_DIV(ms, us, us2ms);
> 	JSLL_L2D(msec_time, ms);
2053c1888
<         return date_format(cx, msec_time, FORMATSPEC_FULL, rval);
---
> 	return date_format(cx, msec_time, FORMATSPEC_FULL, rval);
2056c1891
<     /* Date called as constructor. */
---
>     /* Date called as constructor */
2058,2059c1893,1894
<         int64 us, ms, us2ms;
<         jsdouble msec_time;
---
> 	int64 us, ms, us2ms;
> 	jsdouble msec_time;
2061,2068c1896,1903
<         date = date_constructor(cx, obj);
<         if (!date)
<             return JS_FALSE;
< 
<         us = PRMJ_Now();
<         JSLL_UI2L(us2ms, PRMJ_USEC_PER_MSEC);
<         JSLL_DIV(ms, us, us2ms);
<         JSLL_L2D(msec_time, ms);
---
> 	date = date_constructor(cx, obj);
> 	if (!date)
> 	    return JS_FALSE;
> 
> 	us = PRMJ_Now();
> 	JSLL_UI2L(us2ms, PRMJ_USEC_PER_MSEC);
> 	JSLL_DIV(ms, us, us2ms);
> 	JSLL_L2D(msec_time, ms);
2070c1905
<         *date = msec_time;
---
> 	*date = msec_time;
2072,2093c1907,1928
<         if (!JSVAL_IS_STRING(argv[0])) {
<             /* the argument is a millisecond number */
<             if (!js_ValueToNumber(cx, argv[0], &d))
<                 return JS_FALSE;
<             date = date_constructor(cx, obj);
<             if (!date)
<                 return JS_FALSE;
<             *date = TIMECLIP(d);
<         } else {
<             /* the argument is a string; parse it. */
<             date = date_constructor(cx, obj);
<             if (!date)
<                 return JS_FALSE;
< 
<             str = js_ValueToString(cx, argv[0]);
<             if (!str)
<                 return JS_FALSE;
< 
<             if (!date_parseString(str, date))
<                 *date = *cx->runtime->jsNaN;
<             *date = TIMECLIP(*date);
<         }
---
> 	if (!JSVAL_IS_STRING(argv[0])) {
> 	    /* the argument is a millisecond number */
> 	    if (!js_ValueToNumber(cx, argv[0], &d))
> 		    return JS_FALSE;
> 	    date = date_constructor(cx, obj);
> 	    if (!date)
> 		return JS_FALSE;
> 	    *date = TIMECLIP(d);
> 	} else {
> 	    /* the argument is a string; parse it. */
> 	    date = date_constructor(cx, obj);
> 	    if (!date)
> 		return JS_FALSE;
> 
> 	    str = js_ValueToString(cx, argv[0]);
> 	    if (!str)
> 		return JS_FALSE;
> 
> 	    if (!date_parseString(str, date))
> 		*date = *cx->runtime->jsNaN;
> 	    *date = TIMECLIP(*date);
> 	}
2095,2108c1930,1957
<         jsdouble *date;
<         jsdouble msec_time;
< 
<         if (!date_msecFromArgs(cx, argc, argv, &msec_time))
<             return JS_FALSE;
< 
<         date = date_constructor(cx, obj);
<         if (!date)
<             return JS_FALSE;
< 
<         if (JSDOUBLE_IS_FINITE(msec_time)) {
<             msec_time = UTC(msec_time);
<             msec_time = TIMECLIP(msec_time);
<         }
---
> 	jsdouble array[MAXARGS];
> 	uintN loop;
> 	jsdouble double_arg;
> 	jsdouble day;
> 	jsdouble msec_time;
> 
> 	for (loop = 0; loop < MAXARGS; loop++) {
> 	    if (loop < argc) {
> 		if (!js_ValueToNumber(cx, argv[loop], &double_arg))
> 		    return JS_FALSE;
> 		/* if any arg is NaN, make a NaN date object
> 		   and return */
> 		if (!JSDOUBLE_IS_FINITE(double_arg)) {
> 		    date = date_constructor(cx, obj);
> 		    if (!date)
> 			return JS_FALSE;
> 		    *date = *cx->runtime->jsNaN;
> 		    return JS_TRUE;
> 		}
> 		array[loop] = js_DoubleToInteger(double_arg);
> 	    } else {
>                 if (loop == 2) {
>                     array[loop] = 1; /* Default the date argument to 1. */
>                 } else {
>                     array[loop] = 0;
>                 }
> 	    }
> 	}
2110c1959,1971
<         *date = msec_time;
---
> 	date = date_constructor(cx, obj);
> 	if (!date)
> 	    return JS_FALSE;
> 
> 	/* adjust 2-digit years into the 20th century */
> 	if (array[0] >= 0 && array[0] <= 99)
> 	    array[0] += 1900;
> 
> 	day = MakeDay(array[0], array[1], array[2]);
> 	msec_time = MakeTime(array[3], array[4], array[5], array[6]);
> 	msec_time = MakeDate(day, msec_time);
> 	msec_time = UTC(msec_time);
> 	*date = TIMECLIP(msec_time);
2123,2124c1984,1985
<     proto = JS_InitClass(cx, obj, NULL, &js_DateClass, Date, MAXARGS,
<                          NULL, date_methods, NULL, date_static_methods);
---
>     proto = JS_InitClass(cx, obj, NULL, &date_class, Date, MAXARGS,
> 			 NULL, date_methods, NULL, date_static_methods);
2126c1987
<         return NULL;
---
> 	return NULL;
2135c1996
<         return NULL;
---
> 	return NULL;
2147c2008
<     obj = js_NewObject(cx, &js_DateClass, NULL, NULL);
---
>     obj = js_NewObject(cx, &date_class, NULL, NULL);
2149c2010
<         return NULL;
---
> 	return NULL;
2153c2014
<         return NULL;
---
> 	return NULL;
2166d2026
<     JS_ASSERT(mon < 12);
2175,2176c2035,2040
<     jsdouble utctime;
<     return GetUTCTime(cx, obj, NULL, &utctime) && !JSDOUBLE_IS_NaN(utctime);
---
>     jsdouble *date = date_getProlog(cx, obj, NULL);
> 
>     if (!date || JSDOUBLE_IS_NaN(*date))
>         return JS_FALSE;
>     else
>         return JS_TRUE;
2182c2046
<     jsdouble localtime;
---
>     jsdouble *date = date_getProlog(cx, obj, NULL);
2185,2188c2049,2051
<     if (!GetLocalTime(cx, obj, NULL, &localtime) || JSDOUBLE_IS_NaN(localtime))
<         return 0;
< 
<     return (int) YearFromTime(localtime);
---
>     if (!date || JSDOUBLE_IS_NaN(*date))
> 	return 0;
>     return (int) YearFromTime(LocalTime(*date));
2194c2057
<     jsdouble localtime;
---
>     jsdouble *date = date_getProlog(cx, obj, NULL);
2196,2199c2059,2061
<     if (!GetLocalTime(cx, obj, NULL, &localtime) || JSDOUBLE_IS_NaN(localtime))
<         return 0;
< 
<     return (int) MonthFromTime(localtime);
---
>     if (!date || JSDOUBLE_IS_NaN(*date))
> 	return 0;
>     return (int) MonthFromTime(LocalTime(*date));
2205,2208c2067
<     jsdouble localtime;
< 
<     if (!GetLocalTime(cx, obj, NULL, &localtime) || JSDOUBLE_IS_NaN(localtime))
<         return 0;
---
>     jsdouble *date = date_getProlog(cx, obj, NULL);
2210c2069,2071
<     return (int) DateFromTime(localtime);
---
>     if (!date || JSDOUBLE_IS_NaN(*date))
> 	return 0;
>     return (int) DateFromTime(LocalTime(*date));
2216,2219c2077
<     jsdouble localtime;
< 
<     if (!GetLocalTime(cx, obj, NULL, &localtime) || JSDOUBLE_IS_NaN(localtime))
<         return 0;
---
>     jsdouble *date = date_getProlog(cx, obj, NULL);
2221c2079,2081
<     return (int) HourFromTime(localtime);
---
>     if (!date || JSDOUBLE_IS_NaN(*date))
> 	return 0;
>     return (int) HourFromTime(LocalTime(*date));
2227c2087
<     jsdouble localtime;
---
>     jsdouble *date = date_getProlog(cx, obj, NULL);
2229,2232c2089,2091
<     if (!GetLocalTime(cx, obj, NULL, &localtime) || JSDOUBLE_IS_NaN(localtime))
<         return 0;
< 
<     return (int) MinFromTime(localtime);
---
>     if (!date || JSDOUBLE_IS_NaN(*date))
> 	return 0;
>     return (int) MinFromTime(LocalTime(*date));
2238c2097
<     jsdouble utctime;
---
>     jsdouble *date = date_getProlog(cx, obj, NULL);
2240,2243c2099,2101
<     if (!GetUTCTime(cx, obj, NULL, &utctime) || JSDOUBLE_IS_NaN(utctime))
<         return 0;
< 
<     return (int) SecFromTime(utctime);
---
>     if (!date || JSDOUBLE_IS_NaN(*date))
> 	return 0;
>     return (int) SecFromTime(*date);
2250,2253c2108,2111
< 
<     if (!GetLocalTime(cx, obj, NULL, &local))
<         return;
< 
---
>     jsdouble *date = date_getProlog(cx, obj, NULL);
>     if (!date)
> 	return;
>     local = LocalTime(*date);
2256,2257c2114
<         local = 0;
< 
---
> 	local = 0;
2259,2267c2116,2122
<                               MonthFromTime(local),
<                               DateFromTime(local),
<                               HourFromTime(local),
<                               MinFromTime(local),
<                               SecFromTime(local),
<                               msFromTime(local));
< 
<     /* SetUTCTime also invalidates local time cache. */
<     SetUTCTime(cx, obj, NULL, UTC(local));
---
> 			      MonthFromTime(local),
> 			      DateFromTime(local),
> 			      HourFromTime(local),
> 			      MinFromTime(local),
> 			      SecFromTime(local),
> 			      msFromTime(local));
>     *date = UTC(local);
2274,2279c2129,2132
< 
<     JS_ASSERT(month < 12);
< 
<     if (!GetLocalTime(cx, obj, NULL, &local))
<         return;
< 
---
>     jsdouble *date = date_getProlog(cx, obj, NULL);
>     if (!date)
> 	return;
>     local = LocalTime(*date);
2282,2283c2135
<         return;
< 
---
> 	return;
2285,2291c2137,2143
<                               month,
<                               DateFromTime(local),
<                               HourFromTime(local),
<                               MinFromTime(local),
<                               SecFromTime(local),
<                               msFromTime(local));
<     SetUTCTime(cx, obj, NULL, UTC(local));
---
> 			      month,
> 			      DateFromTime(local),
> 			      HourFromTime(local),
> 			      MinFromTime(local),
> 			      SecFromTime(local),
> 			      msFromTime(local));
>     *date = UTC(local);
2298,2301c2150,2153
< 
<     if (!GetLocalTime(cx, obj, NULL, &local))
<         return;
< 
---
>     jsdouble *datep = date_getProlog(cx, obj, NULL);
>     if (!datep)
> 	return;
>     local = LocalTime(*datep);
2303,2304c2155
<         return;
< 
---
> 	return;
2306,2312c2157,2163
<                               MonthFromTime(local),
<                               date,
<                               HourFromTime(local),
<                               MinFromTime(local),
<                               SecFromTime(local),
<                               msFromTime(local));
<     SetUTCTime(cx, obj, NULL, UTC(local));
---
> 			      MonthFromTime(local),
> 			      date,
> 			      HourFromTime(local),
> 			      MinFromTime(local),
> 			      SecFromTime(local),
> 			      msFromTime(local));
>     *datep = UTC(local);
2319,2322c2170,2173
< 
<     if (!GetLocalTime(cx, obj, NULL, &local))
<         return;
< 
---
>     jsdouble *date = date_getProlog(cx, obj, NULL);
>     if (!date)
> 	return;
>     local = LocalTime(*date);
2324c2175
<         return;
---
> 	return;
2326,2332c2177,2183
<                               MonthFromTime(local),
<                               DateFromTime(local),
<                               hours,
<                               MinFromTime(local),
<                               SecFromTime(local),
<                               msFromTime(local));
<     SetUTCTime(cx, obj, NULL, UTC(local));
---
> 			      MonthFromTime(local),
> 			      DateFromTime(local),
> 			      hours,
> 			      MinFromTime(local),
> 			      SecFromTime(local),
> 			      msFromTime(local));
>     *date = UTC(local);
2339,2342c2190,2193
< 
<     if (!GetLocalTime(cx, obj, NULL, &local))
<         return;
< 
---
>     jsdouble *date = date_getProlog(cx, obj, NULL);
>     if (!date)
> 	return;
>     local = LocalTime(*date);
2344c2195
<         return;
---
> 	return;
2346,2352c2197,2203
<                               MonthFromTime(local),
<                               DateFromTime(local),
<                               HourFromTime(local),
<                               minutes,
<                               SecFromTime(local),
<                               msFromTime(local));
<     SetUTCTime(cx, obj, NULL, UTC(local));
---
> 			      MonthFromTime(local),
> 			      DateFromTime(local),
> 			      HourFromTime(local),
> 			      minutes,
> 			      SecFromTime(local),
> 			      msFromTime(local));
>     *date = UTC(local);
2359,2362c2210,2213
< 
<     if (!GetLocalTime(cx, obj, NULL, &local))
<         return;
< 
---
>     jsdouble *date = date_getProlog(cx, obj, NULL);
>     if (!date)
> 	return;
>     local = LocalTime(*date);
2364c2215
<         return;
---
> 	return;
2366,2372c2217,2223
<                               MonthFromTime(local),
<                               DateFromTime(local),
<                               HourFromTime(local),
<                               MinFromTime(local),
<                               seconds,
<                               msFromTime(local));
<     SetUTCTime(cx, obj, NULL, UTC(local));
---
> 			      MonthFromTime(local),
> 			      DateFromTime(local),
> 			      HourFromTime(local),
> 			      MinFromTime(local),
> 			      seconds,
> 			      msFromTime(local));
>     *date = UTC(local);
2378,2379c2229,2230
<     jsdouble utctime;
<     if (!GetUTCTime(cx, obj, NULL, &utctime))
---
>     jsdouble *date = date_getProlog(cx, obj, NULL);
>     if (!date || JSDOUBLE_IS_NaN(*date))
2381c2232
<     return utctime;
---
>     return (*date);
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsdate.h /Volumes/Swap/js_D11/src/jsdate.h
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
49,50d43
< extern JSClass js_DateClass;
< 
67,70d59
<  *
<  * Assert that mon < 12 to help catch off-by-one user errors, which are common
<  * due to the 0-based month numbering copied into JS from Java (java.util.Date
<  * in 1995). js_DateSetMonth (below) likewise asserts month < 12.
74c63
<                  int hour, int min, int sec);
---
> 				int hour, int min, int sec);
105c94
< js_DateSetMonth(JSContext *cx, JSObject *obj, int month);
---
> js_DateSetMonth(JSContext *cx, JSObject *obj, int year);
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsdbgapi.c /Volumes/Swap/js_D11/src/jsdbgapi.c
2d1
<  * vim: set ts=8 sw=4 et tw=78:
4,5c3,6
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
7,15c8,11
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
20,25c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
27,37c21
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
---
>  * Contributor(s): 
39c23,33
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
53d46
< #include "jsemit.h"
60d52
< #include "jsparse.h"
65,67c57,58
< #ifdef MOZ_SHARK
< #include <CHUD/CHUD.h>
< #endif
---
> 
> //#include "_optimize.h"
78,84d68
< #define DBG_LOCK(rt)            JS_ACQUIRE_LOCK((rt)->debuggerLock)
< #define DBG_UNLOCK(rt)          JS_RELEASE_LOCK((rt)->debuggerLock)
< #define DBG_LOCK_EVAL(rt,expr)  (DBG_LOCK(rt), (expr), DBG_UNLOCK(rt))
< 
< /*
<  * NB: FindTrap must be called with rt->debuggerLock acquired.
<  */
104d87
<     DBG_LOCK(cx->runtime);
110d92
<     DBG_UNLOCK(cx->runtime);
117d98
<     JSTrap *junk, *trap, *twin;
119c100
<     uint32 sample;
---
>     JSTrap *trap;
121d101
<     junk = NULL;
123d102
<     DBG_LOCK(rt);
126,127c105,106
<         JS_ASSERT(trap->script == script && trap->pc == pc);
<         JS_ASSERT(*pc == JSOP_TRAP);
---
>         /* Restore opcode at pc so it can be saved again. */
>         *pc = (jsbytecode)trap->op;
129,130d107
<         sample = rt->debuggerMutations;
<         DBG_UNLOCK(rt);
137,151d113
<         DBG_LOCK(rt);
<         twin = (rt->debuggerMutations != sample)
<                ? FindTrap(rt, script, pc)
<                : NULL;
<         if (twin) {
<             junk = trap;
<             trap = twin;
<         } else {
<             JS_APPEND_LINK(&trap->links, &rt->trapList);
<             ++rt->debuggerMutations;
<             trap->script = script;
<             trap->pc = pc;
<             trap->op = (JSOp)*pc;
<             *pc = JSOP_TRAP;
<         }
152a115,118
>     JS_APPEND_LINK(&trap->links, &rt->trapList);
>     trap->script = script;
>     trap->pc = pc;
>     trap->op = (JSOp)*pc;
155,157c121
<     DBG_UNLOCK(rt);
<     if (junk)
<         JS_free(cx, junk);
---
>     *pc = JSOP_TRAP;
166c130
<     DBG_LOCK_EVAL(cx->runtime, trap = FindTrap(cx->runtime, script, pc));
---
>     trap = FindTrap(cx->runtime, script, pc);
168,173d131
< #ifdef JS_THREADSAFE
<         /*
<          * If we lost a race with another thread, return JSOP_LIMIT so our
<          * caller can detect this case and do something sane.
<          */
< #else
175d132
< #endif
182c139
< DestroyTrapAndUnlock(JSContext *cx, JSTrap *trap)
---
> DestroyTrap(JSContext *cx, JSTrap *trap)
184d140
<     ++cx->runtime->debuggerMutations;
187,188d142
<     DBG_UNLOCK(cx->runtime);
< 
199d152
<     DBG_LOCK(cx->runtime);
206,208c159
<         DestroyTrapAndUnlock(cx, trap);
<     else
<         DBG_UNLOCK(cx->runtime);
---
>         DestroyTrap(cx, trap);
216d166
<     uint32 sample;
219d168
<     DBG_LOCK(rt);
224,230c173,174
<         if (trap->script == script) {
<             sample = rt->debuggerMutations;
<             DestroyTrapAndUnlock(cx, trap);
<             DBG_LOCK(rt);
<             if (rt->debuggerMutations != sample + 1)
<                 next = (JSTrap *)rt->trapList.next;
<         }
---
>         if (trap->script == script)
>             DestroyTrap(cx, trap);
232d175
<     DBG_UNLOCK(rt);
240d182
<     uint32 sample;
243d184
<     DBG_LOCK(rt);
248,252c189
<         sample = rt->debuggerMutations;
<         DestroyTrapAndUnlock(cx, trap);
<         DBG_LOCK(rt);
<         if (rt->debuggerMutations != sample + 1)
<             next = (JSTrap *)rt->trapList.next;
---
>         DestroyTrap(cx, trap);
254d190
<     DBG_UNLOCK(rt);
261d196
<     jsint op;
262a198
>     jsint op;
264d199
<     DBG_LOCK(cx->runtime);
266d200
<     JS_ASSERT(!trap || trap->handler);
268,283c202
<         op = (JSOp) *pc;
<         DBG_UNLOCK(cx->runtime);
< 
<         /* Defend against "pc for wrong script" API usage error. */
<         JS_ASSERT(op != JSOP_TRAP);
< 
< #ifdef JS_THREADSAFE
<         /* If the API was abused, we must fail for want of the real op. */
<         if (op == JSOP_TRAP)
<             return JSTRAP_ERROR;
< 
<         /* Assume a race with a debugger thread and try to carry on. */
<         *rval = INT_TO_JSVAL(op);
<         return JSTRAP_CONTINUE;
< #else
<         /* Always fail if single-threaded (must be an API usage error). */
---
>         JS_ASSERT(0);   /* XXX can't happen */
285d203
< #endif
287,288d204
<     DBG_UNLOCK(cx->runtime);
< 
305,306c221,222
<     rt->globalDebugHooks.interruptHandler = handler;
<     rt->globalDebugHooks.interruptHandlerData = closure;
---
>     rt->interruptHandler = handler;
>     rt->interruptHandlerData = closure;
314c230
<         *handlerp = (JSTrapHandler)rt->globalDebugHooks.interruptHandler;
---
>         *handlerp = (JSTrapHandler)rt->interruptHandler;
316,318c232,234
<         *closurep = rt->globalDebugHooks.interruptHandlerData;
<     rt->globalDebugHooks.interruptHandler = 0;
<     rt->globalDebugHooks.interruptHandlerData = 0;
---
>         *closurep = rt->interruptHandlerData;
>     rt->interruptHandler = 0;
>     rt->interruptHandlerData = 0;
331c247
<     uintN               flags;
---
>     jsrefcount          nrefs;
334,335c250
< #define JSWP_LIVE       0x1             /* live because set and not cleared */
< #define JSWP_HELD       0x2             /* held while running handler/setter */
---
> #define HoldWatchPoint(wp) ((wp)->nrefs++)
337,339d251
< /*
<  * NB: DropWatchPointAndUnlock releases cx->runtime->debuggerLock in all cases.
<  */
341c253
< DropWatchPointAndUnlock(JSContext *cx, JSWatchPoint *wp, uintN flag)
---
> DropWatchPoint(JSContext *cx, JSWatchPoint *wp)
343d254
<     JSBool ok, found;
345,346d255
<     JSScope *scope;
<     JSPropertyOp setter;
348,353c257,258
<     ok = JS_TRUE;
<     wp->flags &= ~flag;
<     if (wp->flags != 0) {
<         DBG_UNLOCK(cx->runtime);
<         return ok;
<     }
---
>     if (--wp->nrefs != 0)
>         return JS_TRUE;
359d263
<     ++cx->runtime->debuggerMutations;
362,390c266,271
< 
<     /*
<      * Passing null for the scope parameter tells js_GetWatchedSetter to find
<      * any watch point for sprop, and not to lock or unlock rt->debuggerLock.
<      * If js_ChangeNativePropertyAttrs fails, propagate failure after removing
<      * wp->closure's root and freeing wp.
<      */
<     setter = js_GetWatchedSetter(cx->runtime, NULL, sprop);
<     DBG_UNLOCK(cx->runtime);
<     if (!setter) {
<         JS_LOCK_OBJ(cx, wp->object);
<         scope = OBJ_SCOPE(wp->object);
<         found = (scope->object == wp->object &&
<                  SCOPE_GET_PROPERTY(scope, sprop->id));
<         JS_UNLOCK_SCOPE(cx, scope);
< 
<         /*
<          * If the property wasn't found on wp->object or didn't exist, then
<          * someone else has dealt with this sprop, and we don't need to change
<          * the property attributes.
<          */
<         if (found) {
<             sprop = js_ChangeScopePropertyAttrs(cx, scope, sprop,
<                                                 0, sprop->attrs,
<                                                 sprop->getter,
<                                                 wp->setter);
<             if (!sprop)
<                 ok = JS_FALSE;
<         }
---
>     if (!js_GetWatchedSetter(cx->runtime, NULL, sprop)) {
>         sprop = js_ChangeNativePropertyAttrs(cx, wp->object, sprop,
>                                              0, sprop->attrs,
>                                              sprop->getter, wp->setter);
>         if (!sprop)
>             return JS_FALSE;
392c273
< 
---
>     js_RemoveRoot(cx->runtime, &wp->closure);
394c275
<     return ok;
---
>     return JS_TRUE;
397,401d277
< /*
<  * NB: js_TraceWatchPoints does not acquire cx->runtime->debuggerLock, since
<  * the debugger should never be racing with the GC (i.e., the debugger must
<  * respect the request model).
<  */
403c279
< js_TraceWatchPoints(JSTracer *trc, JSObject *obj)
---
> js_MarkWatchPoints(JSRuntime *rt)
405d280
<     JSRuntime *rt;
408,409d282
<     rt = trc->context->runtime;
< 
413,446c286
<         if (wp->object == obj) {
<             TRACE_SCOPE_PROPERTY(trc, wp->sprop);
<             if ((wp->sprop->attrs & JSPROP_SETTER) && wp->setter) {
<                 JS_CALL_OBJECT_TRACER(trc, (JSObject *)wp->setter,
<                                       "wp->setter");
<             }
<             JS_SET_TRACING_NAME(trc, "wp->closure");
<             js_CallValueTracerIfGCThing(trc, (jsval) wp->closure);
<         }
<     }
< }
< 
< void
< js_SweepWatchPoints(JSContext *cx)
< {
<     JSRuntime *rt;
<     JSWatchPoint *wp, *next;
<     uint32 sample;
< 
<     rt = cx->runtime;
<     DBG_LOCK(rt);
<     for (wp = (JSWatchPoint *)rt->watchPointList.next;
<          wp != (JSWatchPoint *)&rt->watchPointList;
<          wp = next) {
<         next = (JSWatchPoint *)wp->links.next;
<         if (js_IsAboutToBeFinalized(cx, wp->object)) {
<             sample = rt->debuggerMutations;
< 
<             /* Ignore failures. */
<             DropWatchPointAndUnlock(cx, wp, JSWP_LIVE);
<             DBG_LOCK(rt);
<             if (rt->debuggerMutations != sample + 1)
<                 next = (JSWatchPoint *)rt->watchPointList.next;
<         }
---
>         MARK_SCOPE_PROPERTY(wp->sprop);
448d287
<     DBG_UNLOCK(rt);
451,455d289
< 
< 
< /*
<  * NB: FindWatchPoint must be called with rt->debuggerLock acquired.
<  */
474d307
<     JSScopeProperty *sprop;
476d308
<     DBG_LOCK(rt);
478,480c310,312
<     sprop = wp ? wp->sprop : NULL;
<     DBG_UNLOCK(rt);
<     return sprop;
---
>     if (!wp)
>         return NULL;
>     return wp->sprop;
483,486d314
< /*
<  * Secret handshake with DropWatchPointAndUnlock: if (!scope), we know our
<  * caller has acquired rt->debuggerLock, so we don't have to.
<  */
491d318
<     JSPropertyOp setter;
494,496d320
<     setter = NULL;
<     if (scope)
<         DBG_LOCK(rt);
500,503c324,325
<         if ((!scope || wp->object == scope->object) && wp->sprop == sprop) {
<             setter = wp->setter;
<             break;
<         }
---
>         if ((!scope || wp->object == scope->object) && wp->sprop == sprop)
>             return wp->setter;
505,507c327
<     if (scope)
<         DBG_UNLOCK(rt);
<     return setter;
---
>     return NULL;
516c336
<     jsval propid, userid;
---
>     jsval userid;
521d340
<     DBG_LOCK(rt);
526,530c345
<         if (wp->object == obj && SPROP_USERID(sprop) == id &&
<             !(wp->flags & JSWP_HELD)) {
<             wp->flags |= JSWP_HELD;
<             DBG_UNLOCK(rt);
< 
---
>         if (wp->object == obj && SPROP_USERID(sprop) == id) {
532,535c347
<             propid = ID_TO_VALUE(sprop->id);
<             userid = (sprop->flags & SPROP_HAS_SHORTID)
<                      ? INT_TO_JSVAL(sprop->shortid)
<                      : propid;
---
>             userid = SPROP_USERID(sprop);
538,540c350,351
< 
<             /* NB: wp is held, so we can safely dereference it still. */
<             ok = wp->handler(cx, obj, propid,
---
>             HoldWatchPoint(wp);
>             ok = wp->handler(cx, obj, userid,
542c353
<                              ? OBJ_GET_SLOT(cx, obj, sprop->slot)
---
>                              ? OBJ_GET_SLOT(cx, obj, wp->sprop->slot)
547,555c358,360
<                  * Create a pseudo-frame for the setter invocation so that any
<                  * stack-walking security code under the setter will correctly
<                  * identify the guilty party.  So that the watcher appears to
<                  * be active to obj_eval and other such code, point frame.pc
<                  * at the JSOP_STOP at the end of the script.
<                  *
<                  * The pseudo-frame is not created for fast natives as they
<                  * are treated as interpreter frame extensions and always
<                  * trusted.
---
>                  * Create pseudo-frame for call to setter so that any 
>                  * stack-walking security code in the setter will correctly
>                  * identify the guilty party.
557,564c362,363
<                 JSObject *closure;
<                 JSClass *clasp;
<                 JSFunction *fun;
<                 JSScript *script;
<                 JSBool injectFrame;
<                 uintN nslots;
<                 jsval smallv[5];
<                 jsval *argv;
---
>                 JSObject *funobj = (JSObject *) wp->closure;
>                 JSFunction *fun = (JSFunction *) JS_GetPrivate(cx, funobj);
567,624c366,370
<                 closure = (JSObject *) wp->closure;
<                 clasp = OBJ_GET_CLASS(cx, closure);
<                 if (clasp == &js_FunctionClass) {
<                     fun = GET_FUNCTION_PRIVATE(cx, closure);
<                     script = FUN_SCRIPT(fun);
<                 } else if (clasp == &js_ScriptClass) {
<                     fun = NULL;
<                     script = (JSScript *) JS_GetPrivate(cx, closure);
<                 } else {
<                     fun = NULL;
<                     script = NULL;
<                 }
< 
<                 nslots = 2;
<                 injectFrame = JS_TRUE;
<                 if (fun) {
<                     nslots += FUN_MINARGS(fun);
<                     if (!FUN_INTERPRETED(fun)) {
<                         nslots += fun->u.n.extra;
<                         injectFrame = !(fun->flags & JSFUN_FAST_NATIVE);
<                     }
<                 }
< 
<                 if (injectFrame) {
<                     if (nslots <= JS_ARRAY_LENGTH(smallv)) {
<                         argv = smallv;
<                     } else {
<                         argv = (jsval *) JS_malloc(cx, nslots * sizeof(jsval));
<                         if (!argv) {
<                             DBG_LOCK(rt);
<                             DropWatchPointAndUnlock(cx, wp, JSWP_HELD);
<                             return JS_FALSE;
<                         }
<                     }
< 
<                     argv[0] = OBJECT_TO_JSVAL(closure);
<                     argv[1] = JSVAL_NULL;
<                     memset(argv + 2, 0, (nslots - 2) * sizeof(jsval));
< 
<                     memset(&frame, 0, sizeof(frame));
<                     frame.script = script;
<                     if (script) {
<                         JS_ASSERT(script->length >= JSOP_STOP_LENGTH);
<                         frame.pc = script->code + script->length
<                                    - JSOP_STOP_LENGTH;
<                     }
<                     frame.callee = closure;
<                     frame.fun = fun;
<                     frame.argv = argv + 2;
<                     frame.down = cx->fp;
<                     frame.scopeChain = OBJ_GET_PARENT(cx, closure);
< 
<                     cx->fp = &frame;
<                 }
< #ifdef __GNUC__
<                 else
<                     argv = NULL;    /* suppress bogus gcc warnings */
< #endif
---
>                 memset(&frame, 0, sizeof(frame));
>                 frame.script = fun->script;
>                 frame.fun = fun;
>                 frame.down = cx->fp;
>                 cx->fp = &frame;
630,640c376
<                 if (injectFrame) {
<                     /* Evil code can cause us to have an arguments object. */
<                     if (frame.callobj)
<                         ok &= js_PutCallObject(cx, &frame);
<                     if (frame.argsobj)
<                         ok &= js_PutArgsObject(cx, &frame);
< 
<                     cx->fp = frame.down;
<                     if (argv != smallv)
<                         JS_free(cx, argv);
<                 }
---
>                 cx->fp = frame.down;
642,643c378
<             DBG_LOCK(rt);
<             return DropWatchPointAndUnlock(cx, wp, JSWP_HELD) && ok;
---
>             return DropWatchPoint(cx, wp);
646,647c381,382
<     DBG_UNLOCK(rt);
<     return JS_TRUE;
---
>     JS_ASSERT(0);       /* XXX can't happen */
>     return JS_FALSE;
659,660c394
<     JS_ASSERT(OBJ_GET_CLASS(cx, funobj) == &js_FunctionClass);
<     wrapper = GET_FUNCTION_PRIVATE(cx, funobj);
---
>     wrapper = (JSFunction *) JS_GetPrivate(cx, funobj);
675,680c409,410
<     if (JSID_IS_ATOM(id)) {
<         atom = JSID_TO_ATOM(id);
<     } else if (JSID_IS_INT(id)) {
<         if (!js_ValueToStringId(cx, INT_JSID_TO_JSVAL(id), &id))
<             return NULL;
<         atom = JSID_TO_ATOM(id);
---
>     if (!JSVAL_IS_INT(id)) {
>         atom = (JSAtom *)id;
682c412,414
<         atom = NULL;
---
>         atom = js_AtomizeInt(cx, JSVAL_TO_INT(id), 0);
>         if (!atom)
>             return NULL;
693c425
< JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsval idval,
---
> JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsval id,
695a428
>     JSAtom *atom;
698d430
<     JSProperty *prop;
701d432
<     JSBool ok;
711,714c442,450
<     if (JSVAL_IS_INT(idval))
<         propid = INT_JSVAL_TO_JSID(idval);
<     else if (!js_ValueToStringId(cx, idval, &propid))
<         return JS_FALSE;
---
>     if (JSVAL_IS_INT(id)) {
>         propid = (jsid)id;
>         atom = NULL;
>     } else {
>         atom = js_ValueToStringAtom(cx, id);
>         if (!atom)
>             return JS_FALSE;
>         propid = (jsid)atom;
>     }
716c452
<     if (!js_LookupProperty(cx, obj, propid, &pobj, &prop))
---
>     if (!js_LookupProperty(cx, obj, propid, &pobj, (JSProperty **)&sprop))
718d453
<     sprop = (JSScopeProperty *) prop;
727,728c462,463
<                                    &prop)) {
<                 return JS_FALSE;
---
>                                    (JSProperty **)&sprop)) {
>                 sprop = NULL;
730d464
<             sprop = (JSScopeProperty *) prop;
736,737c470
<         uintN attrs, flags;
<         intN shortid;
---
>         uintN attrs;
746,747d478
<             flags = sprop->flags;
<             shortid = sprop->shortid;
749,751c480,481
<             if (!OBJ_GET_PROPERTY(cx, pobj, propid, &value) ||
<                 !OBJ_GET_ATTRIBUTES(cx, pobj, propid, prop, &attrs)) {
<                 OBJ_DROP_PROPERTY(cx, pobj, prop);
---
>             if (!OBJ_GET_PROPERTY(cx, pobj, id, &value)) {
>                 OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop);
754,756c484,485
<             getter = setter = NULL;
<             flags = 0;
<             shortid = 0;
---
>             getter = setter = JS_PropertyStub;
>             attrs = JSPROP_ENUMERATE;
758c487
<         OBJ_DROP_PROPERTY(cx, pobj, prop);
---
>         OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop);
760,763c489,491
<         /* Recall that obj is native, whether or not pobj is native. */
<         if (!js_DefineNativeProperty(cx, obj, propid, value, getter, setter,
<                                      attrs, flags, shortid, &prop)) {
<             return JS_FALSE;
---
>         if (!js_DefineProperty(cx, obj, propid, value, getter, setter, attrs,
>                                (JSProperty **)&sprop)) {
>             sprop = NULL;
765d492
<         sprop = (JSScopeProperty *) prop;
766a494,495
>     if (!sprop)
>         return JS_FALSE;
768,773d496
<     /*
<      * At this point, prop/sprop exists in obj, obj is locked, and we must
<      * OBJ_DROP_PROPERTY(cx, obj, prop) before returning.
<      */
<     ok = JS_TRUE;
<     DBG_LOCK(rt);
776d498
<         DBG_UNLOCK(rt);
778,781c500,501
<         if (!watcher) {
<             ok = JS_FALSE;
<             goto out;
<         }
---
>         if (!watcher)
>             return JS_FALSE;
784,787c504,505
<         if (!wp) {
<             ok = JS_FALSE;
<             goto out;
<         }
---
>         if (!wp)
>             return JS_FALSE;
789a508,512
>         if (!js_AddRoot(cx, &wp->closure, "wp->closure")) {
>             JS_free(cx, wp);
>             return JS_FALSE;
>         }
>         JS_APPEND_LINK(&wp->links, &rt->watchPointList);
791c514,515
<         JS_ASSERT(sprop->setter != js_watch_set || pobj != obj);
---
>         wp->sprop = sprop;
>         JS_ASSERT(sprop->setter != js_watch_set);
793,795c517
<         wp->flags = JSWP_LIVE;
< 
<         /* XXXbe nest in obj lock here */
---
>         wp->nrefs = 1;
798,816c520,521
<         if (!sprop) {
<             /* Self-link so DropWatchPointAndUnlock can JS_REMOVE_LINK it. */
<             JS_INIT_CLIST(&wp->links);
<             DBG_LOCK(rt);
<             DropWatchPointAndUnlock(cx, wp, JSWP_LIVE);
<             ok = JS_FALSE;
<             goto out;
<         }
<         wp->sprop = sprop;
< 
<         /*
<          * Now that wp is fully initialized, append it to rt's wp list.
<          * Because obj is locked we know that no other thread could have added
<          * a watchpoint for (obj, propid).
<          */
<         DBG_LOCK(rt);
<         JS_ASSERT(!FindWatchPoint(rt, OBJ_SCOPE(obj), propid));
<         JS_APPEND_LINK(&wp->links, &rt->watchPointList);
<         ++rt->debuggerMutations;
---
>         if (!sprop)
>             return DropWatchPoint(cx, wp);
820,824c525,526
<     DBG_UNLOCK(rt);
< 
< out:
<     OBJ_DROP_PROPERTY(cx, obj, prop);
<     return ok;
---
>     OBJ_DROP_PROPERTY(cx, obj, (JSProperty *)sprop);
>     return JS_TRUE;
835d536
<     DBG_LOCK(rt);
844c545
<             return DropWatchPointAndUnlock(cx, wp, JSWP_LIVE);
---
>             return DropWatchPoint(cx, wp);
847d547
<     DBG_UNLOCK(rt);
860d559
<     uint32 sample;
863d561
<     DBG_LOCK(rt);
868,875c566,567
<         if (wp->object == obj) {
<             sample = rt->debuggerMutations;
<             if (!DropWatchPointAndUnlock(cx, wp, JSWP_LIVE))
<                 return JS_FALSE;
<             DBG_LOCK(rt);
<             if (rt->debuggerMutations != sample + 1)
<                 next = (JSWatchPoint *)rt->watchPointList.next;
<         }
---
>         if (wp->object == obj && !DropWatchPoint(cx, wp))
>             return JS_FALSE;
877d568
<     DBG_UNLOCK(rt);
886d576
<     uint32 sample;
889d578
<     DBG_LOCK(rt);
894,895c583
<         sample = rt->debuggerMutations;
<         if (!DropWatchPointAndUnlock(cx, wp, JSWP_LIVE))
---
>         if (!DropWatchPoint(cx, wp))
897,899d584
<         DBG_LOCK(rt);
<         if (rt->debuggerMutations != sample + 1)
<             next = (JSWatchPoint *)rt->watchPointList.next;
901d585
<     DBG_UNLOCK(rt);
910c594
<     return js_PCToLineNumber(cx, script, pc);
---
>     return js_PCToLineNumber(script, pc);
922,934c606
<     return FUN_SCRIPT(fun);
< }
< 
< JS_PUBLIC_API(JSNative)
< JS_GetFunctionNative(JSContext *cx, JSFunction *fun)
< {
<     return FUN_NATIVE(fun);
< }
< 
< JS_PUBLIC_API(JSFastNative)
< JS_GetFunctionFastNative(JSContext *cx, JSFunction *fun)
< {
<     return FUN_FAST_NATIVE(fun);
---
>     return fun->script;
967,1017d638
< JS_PUBLIC_API(JSStackFrame *)
< JS_GetScriptedCaller(JSContext *cx, JSStackFrame *fp)
< {
<     if (!fp)
<         fp = cx->fp;
<     while (fp) {
<         if (fp->script)
<             return fp;
<         fp = fp->down;
<     }
<     return NULL;
< }
< 
< JS_PUBLIC_API(JSPrincipals *)
< JS_StackFramePrincipals(JSContext *cx, JSStackFrame *fp)
< {
<     if (fp->fun) {
<         JSRuntime *rt = cx->runtime;
< 
<         if (rt->findObjectPrincipals) {
<             if (fp->fun->object != fp->callee)
<                 return rt->findObjectPrincipals(cx, fp->callee);
<             /* FALL THROUGH */
<         }
<     }
<     if (fp->script)
<         return fp->script->principals;
<     return NULL;
< }
< 
< JS_PUBLIC_API(JSPrincipals *)
< JS_EvalFramePrincipals(JSContext *cx, JSStackFrame *fp, JSStackFrame *caller)
< {
<     JSRuntime *rt;
<     JSPrincipals *principals, *callerPrincipals;
< 
<     rt = cx->runtime;
<     if (rt->findObjectPrincipals) {
<         principals = rt->findObjectPrincipals(cx, fp->callee);
<     } else {
<         principals = NULL;
<     }
<     if (!caller)
<         return principals;
<     callerPrincipals = JS_StackFramePrincipals(cx, caller);
<     return (callerPrincipals && principals &&
<             callerPrincipals->subsume(callerPrincipals, principals))
<            ? principals
<            : callerPrincipals;
< }
< 
1021,1022c642,648
<     if (fp->annotation && fp->script) {
<         JSPrincipals *principals = JS_StackFramePrincipals(cx, fp);
---
>     if (fp->annotation) {
>         JSPrincipals *principals = fp->script
>             ? fp->script->principals
>             : NULL;
> 
>         if (principals == NULL)
>             return NULL;
1024c650
<         if (principals && principals->globalPrivilegesEnabled(cx, principals)) {
---
>         if (principals->globalPrivilegesEnabled(cx, principals)) {
1026,1027c652,653
<              * Give out an annotation only if privileges have not been revoked
<              * or disabled globally.
---
>              * Only give out an annotation if privileges have not
>              * been revoked globally.
1045,1050c671,677
<     JSPrincipals *principals;
< 
<     principals = JS_StackFramePrincipals(cx, fp);
<     if (!principals)
<         return NULL;
<     return principals->getPrincipalArray(cx, principals);
---
>     JSPrincipals *principals = fp->script
>         ? fp->script->principals
>         : NULL;
> 
>     return principals
>         ? principals->getPrincipalArray(cx, principals)
>         : NULL;
1071c698
<     return js_GetScopeChain(cx, fp);
---
>     return fp->scopeChain;
1079c706
< 
---
> #if JS_HAS_ARGS_OBJECT
1082c709,710
< 
---
> #endif
> #if JS_HAS_CALL_OBJECT
1087a716,718
> #else
>     return NULL;
> #endif /* JS_HAS_CALL_OBJECT */
1106,1118c737
<     /*
<      * Test both fp->fun and fp->argv to defend against any control flow from
<      * the compiler reaching this API entry point, where fp is a frame pushed
<      * by the compiler that has non-null fun but null argv.
<      */
<     if (fp->fun && fp->argv) {
<         JSObject *obj = fp->callee;
< 
<         JS_ASSERT(OBJ_GET_CLASS(cx, obj) == &js_FunctionClass);
<         JS_ASSERT(OBJ_GET_PRIVATE(cx, obj) == fp->fun);
<         return obj;
<     }
<     return NULL;
---
>     return fp->argv && fp->fun ? JSVAL_TO_OBJECT(fp->argv[-2]) : NULL;
1127,1132d745
< JS_PUBLIC_API(JSObject *)
< JS_GetFrameCalleeObject(JSContext *cx, JSStackFrame *fp)
< {
<     return fp->callee;
< }
< 
1174c787
<     return (JSVersion) (script->version & JSVERSION_MASK);
---
>     return script->version;
1182,1183c795,796
<     rt->globalDebugHooks.newScriptHook = hook;
<     rt->globalDebugHooks.newScriptHookData = callerdata;
---
>     rt->newScriptHook = hook;
>     rt->newScriptHookData = callerdata;
1190,1191c803,804
<     rt->globalDebugHooks.destroyScriptHook = hook;
<     rt->globalDebugHooks.destroyScriptHookData = callerdata;
---
>     rt->destroyScriptHook = hook;
>     rt->destroyScriptHookData = callerdata;
1198c811
<                           const jschar *chars, uintN length,
---
>                           const jschar *bytes, uintN length,
1202d814
<     JSObject *scobj;
1207,1210d818
<     scobj = JS_GetFrameScopeChain(cx, fp);
<     if (!scobj)
<         return JS_FALSE;
< 
1213c821
<      * flags to the code generator.
---
>      * flags to the code generator (see js_EmitTree's TOK_SEMI case).
1217,1219c825,829
<     script = js_CompileScript(cx, scobj, JS_StackFramePrincipals(cx, fp),
<                               TCF_COMPILE_N_GO, chars, length, NULL,
<                               filename, lineno);
---
>     script = JS_CompileUCScriptForPrincipals(cx, fp->scopeChain,
>                                              fp->script
>                                              ? fp->script->principals
>                                              : NULL,
>                                              bytes, length, filename, lineno);
1224,1225c834,835
<     ok = js_Execute(cx, scobj, script, fp, JSFRAME_DEBUGGER | JSFRAME_EVAL,
<                     rval);
---
>     ok = js_Execute(cx, fp->scopeChain, script, fp,
>                     JSFRAME_DEBUGGER | JSFRAME_EVAL, rval);
1229a840,841
> 
> #ifdef _UTF8
1238c850
<     size_t len = length;
---
> 	size_t wLength;
1240c852,871
<     chars = js_InflateString(cx, bytes, &len);
---
>     chars = js_InflateString(cx, bytes, length,&wLength);
>     if (!chars)
>         return JS_FALSE;
>     ok = JS_EvaluateUCInStackFrame(cx, fp, chars, wLength, filename, lineno,
>                                    rval);
>     JS_free(cx, chars);
> 
>     return ok;
> }
> #else //#ifdef _UTF8
> JS_PUBLIC_API(JSBool)
> JS_EvaluateInStackFrame(JSContext *cx, JSStackFrame *fp,
>                         const char *bytes, uintN length,
>                         const char *filename, uintN lineno,
>                         jsval *rval)
> {
>     jschar *chars;
>     JSBool ok;
> 
>     chars = js_InflateString(cx, bytes, length);
1243d873
<     length = (uintN) len;
1249a880
> #endif //#ifdef _UTF8
1282a914
>     JSPropertyOp getter;
1299c931
< 
---
>     
1311c943
< 
---
>     
1318c950,951
< 
---
>     
>     getter = sprop->getter;
1322,1323c955,960
<               | ((sprop->getter == js_GetCallVariable) ? JSPD_VARIABLE  : 0);
< 
---
> #if JS_HAS_CALL_OBJECT
>               | ((getter == js_GetCallVariable)    ? JSPD_VARIABLE  : 0)
> #endif /* JS_HAS_CALL_OBJECT */
>               | ((getter == js_GetArgument)        ? JSPD_ARGUMENT  : 0)
>               | ((getter == js_GetLocalVariable)   ? JSPD_VARIABLE  : 0);
> #if JS_HAS_CALL_OBJECT
1326c963
<         sprop->getter == js_CallClass.getProperty) {
---
>         getter == js_CallClass.getProperty) {
1338c975
< 
---
> #endif /* JS_HAS_CALL_OBJECT */
1382,1384c1019,1021
<     n = STOBJ_NSLOTS(obj);
<     if (n > scope->entryCount)
<         n = scope->entryCount;
---
>     n = scope->entryCount;
>     if (n > scope->map.nslots)
>         n = scope->map.nslots;
1435,1436c1072,1073
<     rt->globalDebugHooks.debuggerHandler = handler;
<     rt->globalDebugHooks.debuggerHandlerData = closure;
---
>     rt->debuggerHandler = handler;
>     rt->debuggerHandlerData = closure;
1443,1444c1080,1081
<     rt->globalDebugHooks.sourceHandler = handler;
<     rt->globalDebugHooks.sourceHandlerData = closure;
---
>     rt->sourceHandler = handler;
>     rt->sourceHandlerData = closure;
1451,1452c1088,1089
<     rt->globalDebugHooks.executeHook = hook;
<     rt->globalDebugHooks.executeHookData = closure;
---
>     rt->executeHook = hook;
>     rt->executeHookData = closure;
1459,1460c1096,1097
<     rt->globalDebugHooks.callHook = hook;
<     rt->globalDebugHooks.callHookData = closure;
---
>     rt->callHook = hook;
>     rt->callHookData = closure;
1467,1468c1104,1105
<     rt->globalDebugHooks.objectHook = hook;
<     rt->globalDebugHooks.objectHookData = closure;
---
>     rt->objectHook = hook;
>     rt->objectHookData = closure;
1475,1476c1112,1113
<     rt->globalDebugHooks.throwHook = hook;
<     rt->globalDebugHooks.throwHookData = closure;
---
>     rt->throwHook = hook;
>     rt->throwHookData = closure;
1483,1484c1120,1121
<     rt->globalDebugHooks.debugErrorHook = hook;
<     rt->globalDebugHooks.debugErrorHookData = closure;
---
>     rt->debugErrorHook = hook;
>     rt->debugErrorHookData = closure;
1496,1500c1133
<     nbytes = sizeof *obj;
<     if (obj->dslots) {
<         nbytes += ((uint32)obj->dslots[-1] - JS_INITIAL_NSLOTS + 1)
<                   * sizeof obj->dslots[0];
<     }
---
>     nbytes = sizeof *obj + obj->map->nslots * sizeof obj->slots[0];
1516c1149
<     nbytes = sizeof(JSAtom *) + sizeof(JSDHashEntryStub);
---
>     nbytes = sizeof *atom;
1519c1152
<         nbytes += (JSFLATSTR_LENGTH(ATOM_TO_STRING(atom)) + 1) * sizeof(jschar);
---
>         nbytes += (ATOM_TO_STRING(atom)->length + 1) * sizeof(jschar);
1521a1155,1156
>     } else if (ATOM_IS_OBJECT(atom)) {
>         nbytes += JS_GetObjectTotalSize(cx, ATOM_TO_OBJECT(atom));
1529c1164,1166
<     size_t nbytes;
---
>     size_t nbytes, obytes;
>     JSObject *obj;
>     JSAtom *atom;
1532,1537c1169,1181
<     if (fun->object)
<         nbytes += JS_GetObjectTotalSize(cx, fun->object);
<     if (FUN_INTERPRETED(fun))
<         nbytes += JS_GetScriptTotalSize(cx, fun->u.i.script);
<     if (fun->atom)
<         nbytes += GetAtomTotalSize(cx, fun->atom);
---
>     JS_ASSERT(fun->nrefs);
>     obj = fun->object;
>     if (obj) {
>         obytes = JS_GetObjectTotalSize(cx, obj);
>         if (fun->nrefs > 1)
>             obytes = (obytes + fun->nrefs - 1) / fun->nrefs;
>         nbytes += obytes;
>     }
>     if (fun->script)
>         nbytes += JS_GetScriptTotalSize(cx, fun->script);
>     atom = fun->atom;
>     if (atom)
>         nbytes += GetAtomTotalSize(cx, atom);
1546a1191
>     JSObject *obj;
1549c1194
<     JSObjectArray *objarray;
---
>     JSTryNote *tn, *tnotes;
1553,1554c1198,1200
<     if (script->object)
<         nbytes += JS_GetObjectTotalSize(cx, script->object);
---
>     obj = script->object;
>     if (obj)
>         nbytes += JS_GetObjectTotalSize(cx, obj);
1564,1589c1210,1221
<     notes = SCRIPT_NOTES(script);
<     for (sn = notes; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn))
<         continue;
<     nbytes += (sn - notes + 1) * sizeof *sn;
< 
<     if (script->objectsOffset != 0) {
<         objarray = JS_SCRIPT_OBJECTS(script);
<         i = objarray->length;
<         nbytes += sizeof *objarray + i * sizeof objarray->vector[0];
<         do {
<             nbytes += JS_GetObjectTotalSize(cx, objarray->vector[--i]);
<         } while (i != 0);
<     }
< 
<     if (script->regexpsOffset != 0) {
<         objarray = JS_SCRIPT_REGEXPS(script);
<         i = objarray->length;
<         nbytes += sizeof *objarray + i * sizeof objarray->vector[0];
<         do {
<             nbytes += JS_GetObjectTotalSize(cx, objarray->vector[--i]);
<         } while (i != 0);
<     }
< 
<     if (script->trynotesOffset != 0) {
<         nbytes += sizeof(JSTryNoteArray) +
<             JS_SCRIPT_TRYNOTES(script)->length * sizeof(JSTryNote);
---
>     notes = script->notes;
>     if (notes) {
>         for (sn = notes; !SN_IS_TERMINATOR(sn); sn += SN_LENGTH(sn))
>             continue;
>         nbytes += (sn - notes + 1) * sizeof *sn;
>     }
> 
>     tnotes = script->trynotes;
>     if (tnotes) {
>         for (tn = tnotes; tn->catchStart; tn++)
>             continue;
>         nbytes += (tn - tnotes + 1) * sizeof *tn;
1597c1229
<             pbytes = JS_HOWMANY(pbytes, principals->refcount);
---
>             pbytes = (pbytes + principals->refcount - 1) / principals->refcount;
1603,1760d1234
< 
< JS_PUBLIC_API(uint32)
< JS_GetTopScriptFilenameFlags(JSContext *cx, JSStackFrame *fp)
< {
<     if (!fp)
<         fp = cx->fp;
<     while (fp) {
<         if (fp->script)
<             return JS_GetScriptFilenameFlags(fp->script);
<         fp = fp->down;
<     }
<     return 0;
<  }
< 
< JS_PUBLIC_API(uint32)
< JS_GetScriptFilenameFlags(JSScript *script)
< {
<     JS_ASSERT(script);
<     if (!script->filename)
<         return JSFILENAME_NULL;
<     return js_GetScriptFilenameFlags(script->filename);
< }
< 
< JS_PUBLIC_API(JSBool)
< JS_FlagScriptFilenamePrefix(JSRuntime *rt, const char *prefix, uint32 flags)
< {
<     if (!js_SaveScriptFilenameRT(rt, prefix, flags))
<         return JS_FALSE;
<     return JS_TRUE;
< }
< 
< JS_PUBLIC_API(JSBool)
< JS_IsSystemObject(JSContext *cx, JSObject *obj)
< {
<     return STOBJ_IS_SYSTEM(obj);
< }
< 
< JS_PUBLIC_API(JSObject *)
< JS_NewSystemObject(JSContext *cx, JSClass *clasp, JSObject *proto,
<                    JSObject *parent, JSBool system)
< {
<     JSObject *obj;
< 
<     obj = js_NewObject(cx, clasp, proto, parent);
<     if (obj && system)
<         STOBJ_SET_SYSTEM(obj);
<     return obj;
< }
< 
< /************************************************************************/
< 
< JS_PUBLIC_API(JSDebugHooks *)
< JS_GetGlobalDebugHooks(JSRuntime *rt)
< {
<     return &rt->globalDebugHooks;
< }
< 
< JS_PUBLIC_API(JSDebugHooks *)
< JS_SetContextDebugHooks(JSContext *cx, JSDebugHooks *hooks)
< {
<     JSDebugHooks *old;
< 
<     JS_ASSERT(hooks);
<     old = cx->debugHooks;
<     cx->debugHooks = hooks;
<     return old;
< }
< 
< #ifdef MOZ_SHARK
< 
< JS_PUBLIC_API(JSBool)
< JS_StartChudRemote() 
< {
<     if (chudIsRemoteAccessAcquired() && 
<         (chudStartRemotePerfMonitor("Mozilla") == chudSuccess)) {
<         return JS_TRUE;
<     }
< 
<     return JS_FALSE;
< }
< 
< JS_PUBLIC_API(JSBool)
< JS_StopChudRemote()
< {
<     if (chudIsRemoteAccessAcquired() &&
<         (chudStopRemotePerfMonitor() == chudSuccess)) {
<         return JS_TRUE;
<     }
< 
<     return JS_FALSE;
< }
< 
< JS_PUBLIC_API(JSBool)
< JS_ConnectShark()
< {
<     if (!chudIsInitialized() && (chudInitialize() != chudSuccess))
<         return JS_FALSE;
< 
<     if (chudAcquireRemoteAccess() != chudSuccess)
<         return JS_FALSE;
< 
<     return JS_TRUE;
< }
< 
< JS_PUBLIC_API(JSBool)
< JS_DisconnectShark()
< {
<     if (chudIsRemoteAccessAcquired() && (chudReleaseRemoteAccess() != chudSuccess))
<         return JS_FALSE;
< 
<     return JS_TRUE;
< }
< 
< JS_FRIEND_API(JSBool)
< js_StartShark(JSContext *cx, JSObject *obj,
<               uintN argc, jsval *argv, jsval *rval)
< {
<     if (!JS_StartChudRemote()) {
<         JS_ReportError(cx, "Error starting CHUD.");
<     }
< 
<     return JS_TRUE;
< }
< 
< JS_FRIEND_API(JSBool)
< js_StopShark(JSContext *cx, JSObject *obj,
<              uintN argc, jsval *argv, jsval *rval)
< {
<     if (!JS_StopChudRemote()) {
<         JS_ReportError(cx, "Error stopping CHUD.");
<     }
<         
<     return JS_TRUE;
< }
< 
< JS_FRIEND_API(JSBool)
< js_ConnectShark(JSContext *cx, JSObject *obj,
<                 uintN argc, jsval *argv, jsval *rval)
< {
<     if (!JS_ConnectShark()) {
<         JS_ReportError(cx, "Error connecting to Shark.");
<     }
<         
<     return JS_TRUE;
< }
< 
< JS_FRIEND_API(JSBool)
< js_DisconnectShark(JSContext *cx, JSObject *obj,
<                    uintN argc, jsval *argv, jsval *rval)
< {
<     if (!JS_DisconnectShark()) {
<         JS_ReportError(cx, "Error disconnecting from Shark.");
<     }
<         
<     return JS_TRUE;
< }
< 
< #endif /* MOZ_SHARK */
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsdbgapi.h /Volumes/Swap/js_D11/src/jsdbgapi.h
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
56c51
<            JSTrapHandler handler, void *closure);
---
> 	   JSTrapHandler handler, void *closure);
63c58
<              JSTrapHandler *handlerp, void **closurep);
---
> 	     JSTrapHandler *handlerp, void **closurep);
84c79
<                  JSWatchPointHandler handler, void *closure);
---
> 		 JSWatchPointHandler handler, void *closure);
88c83
<                    JSWatchPointHandler *handlerp, void **closurep);
---
> 		   JSWatchPointHandler *handlerp, void **closurep);
102,105c97
< js_TraceWatchPoints(JSTracer *trc, JSObject *obj);
< 
< extern void
< js_SweepWatchPoints(JSContext *cx);
---
> js_MarkWatchPoints(JSRuntime *rt);
110,112d101
< /*
<  * NB: callers outside of jsdbgapi.c must pass non-null scope.
<  */
140,145d128
< extern JS_PUBLIC_API(JSNative)
< JS_GetFunctionNative(JSContext *cx, JSFunction *fun);
< 
< extern JS_PUBLIC_API(JSFastNative)
< JS_GetFunctionFastNative(JSContext *cx, JSFunction *fun);
< 
165,190c148,149
< /*
<  * Get the closest scripted frame below fp.  If fp is null, start from cx->fp.
<  */
< extern JS_PUBLIC_API(JSStackFrame *)
< JS_GetScriptedCaller(JSContext *cx, JSStackFrame *fp);
< 
< /*
<  * Return a weak reference to fp's principals.  A null return does not denote
<  * an error, it means there are no principals.
<  */
< extern JS_PUBLIC_API(JSPrincipals *)
< JS_StackFramePrincipals(JSContext *cx, JSStackFrame *fp);
< 
< /*
<  * This API is like JS_StackFramePrincipals(cx, caller), except that if
<  * cx->runtime->findObjectPrincipals is non-null, it returns the weaker of
<  * the caller's principals and the object principals of fp's callee function
<  * object (fp->argv[-2]), which is eval, Function, or a similar eval-like
<  * method.  The caller parameter should be JS_GetScriptedCaller(cx, fp).
<  *
<  * All eval-like methods must use JS_EvalFramePrincipals to acquire a weak
<  * reference to the correct principals for the eval call to be secure, given
<  * an embedding that calls JS_SetObjectPrincipalsFinder (see jsapi.h).
<  */
< extern JS_PUBLIC_API(JSPrincipals *)
< JS_EvalFramePrincipals(JSContext *cx, JSStackFrame *fp, JSStackFrame *caller);
---
> extern JS_PUBLIC_API(JSBool)
> JS_IsNativeFrame(JSContext *cx, JSStackFrame *fp);
201,203d159
< extern JS_PUBLIC_API(JSBool)
< JS_IsNativeFrame(JSContext *cx, JSStackFrame *fp);
< 
237,242d192
< /**
<  * Return fp's callee function object (fp->callee) if it has one.
<  */
< extern JS_PUBLIC_API(JSObject *)
< JS_GetFrameCalleeObject(JSContext *cx, JSStackFrame *fp);
< 
256c206
< 
---
>      
272c222
<                         void *callerdata);
---
> 			void *callerdata);
278c228
<                           const jschar *chars, uintN length,
---
>                           const jschar *bytes, uintN length,
284,286c234,236
<                         const char *bytes, uintN length,
<                         const char *filename, uintN lineno,
<                         jsval *rval);
---
> 			const char *bytes, uintN length,
> 			const char *filename, uintN lineno,
> 			jsval *rval);
320c270
<                    JSPropertyDesc *pd);
---
> 		   JSPropertyDesc *pd);
362,444d311
< /*
<  * Get the top-most running script on cx starting from fp, or from the top of
<  * cx's frame stack if fp is null, and return its script filename flags.  If
<  * the script has a null filename member, return JSFILENAME_NULL.
<  */
< extern JS_PUBLIC_API(uint32)
< JS_GetTopScriptFilenameFlags(JSContext *cx, JSStackFrame *fp);
< 
< /*
<  * Get the script filename flags for the script.  If the script doesn't have a
<  * filename, return JSFILENAME_NULL.
<  */
< extern JS_PUBLIC_API(uint32)
< JS_GetScriptFilenameFlags(JSScript *script);
< 
< /*
<  * Associate flags with a script filename prefix in rt, so that any subsequent
<  * script compilation will inherit those flags if the script's filename is the
<  * same as prefix, or if prefix is a substring of the script's filename.
<  *
<  * The API defines only one flag bit, JSFILENAME_SYSTEM, leaving the remaining
<  * 31 bits up to the API client to define.  The union of all 32 bits must not
<  * be a legal combination, however, in order to preserve JSFILENAME_NULL as a
<  * unique value.  API clients may depend on JSFILENAME_SYSTEM being a set bit
<  * in JSFILENAME_NULL -- a script with a null filename member is presumed to
<  * be a "system" script.
<  */
< extern JS_PUBLIC_API(JSBool)
< JS_FlagScriptFilenamePrefix(JSRuntime *rt, const char *prefix, uint32 flags);
< 
< #define JSFILENAME_NULL         0xffffffff      /* null script filename */
< #define JSFILENAME_SYSTEM       0x00000001      /* "system" script, see below */
< #define JSFILENAME_PROTECTED    0x00000002      /* scripts need protection */
< 
< /*
<  * Return true if obj is a "system" object, that is, one created by
<  * JS_NewSystemObject with the system flag set and not JS_NewObject.
<  *
<  * What "system" means is up to the API client, but it can be used to implement
<  * access control policies based on script filenames and their prefixes, using
<  * JS_FlagScriptFilenamePrefix and JS_GetTopScriptFilenameFlags.
<  */
< extern JS_PUBLIC_API(JSBool)
< JS_IsSystemObject(JSContext *cx, JSObject *obj);
< 
< /*
<  * Call JS_NewObject(cx, clasp, proto, parent) and, if system is true, mark the
<  * result as a system object, that is an object for which JS_IsSystemObject
<  * returns true.
<  */
< extern JS_PUBLIC_API(JSObject *)
< JS_NewSystemObject(JSContext *cx, JSClass *clasp, JSObject *proto,
<                    JSObject *parent, JSBool system);
< 
< /************************************************************************/
< 
< extern JS_PUBLIC_API(JSDebugHooks *)
< JS_GetGlobalDebugHooks(JSRuntime *rt);
< 
< extern JS_PUBLIC_API(JSDebugHooks *)
< JS_SetContextDebugHooks(JSContext *cx, JSDebugHooks *hooks);
< 
< #ifdef MOZ_SHARK
< extern JS_PUBLIC_API(JSBool) JS_StartChudRemote();
< extern JS_PUBLIC_API(JSBool) JS_StopChudRemote();
< extern JS_PUBLIC_API(JSBool) JS_ConnectShark();
< extern JS_PUBLIC_API(JSBool) JS_DisconnectShark();
< 
< extern JS_FRIEND_API(JSBool) js_StopShark(JSContext *cx, JSObject *obj,
<                                           uintN argc, jsval *argv, jsval *rval);
< 
< extern JS_FRIEND_API(JSBool) js_StartShark(JSContext *cx, JSObject *obj,
<                                            uintN argc, jsval *argv, jsval *rval);
< 
< extern JS_FRIEND_API(JSBool) js_ConnectShark(JSContext *cx, JSObject *obj,
<                                              uintN argc, jsval *argv,
<                                              jsval *rval);
< 
< extern JS_FRIEND_API(JSBool) js_DisconnectShark(JSContext *cx, JSObject *obj,
<                                                 uintN argc, jsval *argv,
<                                                 jsval *rval);
< #endif /* MOZ_SHARK */
< 
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsdhash.c /Volumes/Swap/js_D11/src/jsdhash.c
3c3
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
---
>  * Version: NPL 1.1/GPL 2.0/LGPL 2.1
5,8c5,8
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
---
>  * The contents of this file are subject to the Netscape Public License
>  * Version 1.1 (the "License"); you may not use this file except in
>  * compliance with the License. You may obtain a copy of the License at
>  * http://www.mozilla.org/NPL/
17c17
<  * The Initial Developer of the Original Code is
---
>  * The Initial Developer of the Original Code is 
25d24
<  *   L. David Baron <dbaron@dbaron.org>, Mozilla Corporation
28,29c27,28
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
---
>  * either the GNU General Public License Version 2 or later (the "GPL"), or 
>  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
33c32
<  * use your version of this file under the terms of the MPL, indicate your
---
>  * use your version of this file under the terms of the NPL, indicate your
37c36
<  * the terms of any one of the MPL, the GPL or the LGPL.
---
>  * the terms of any one of the NPL, the GPL or the LGPL.
45c44
< #include <stdlib.h>
---
> #include "xstdlib.h"
52c51
< # if defined MOZILLA_CLIENT && defined DEBUG_XXXbrendan
---
> # if defined MOZILLA_CLIENT && defined DEBUG_brendan
60,82d58
< /*
<  * The following DEBUG-only code is used to assert that calls to one of
<  * table->ops or to an enumerator do not cause re-entry into a call that
<  * can mutate the table.  The recursion level is stored in additional
<  * space allocated at the end of the entry store to avoid changing
<  * JSDHashTable, which could cause issues when mixing DEBUG and
<  * non-DEBUG components.
<  */
< #ifdef DEBUG
< 
< #define RECURSION_LEVEL(table_) (*(uint32*)(table_->entryStore + \
<                                             JS_DHASH_TABLE_SIZE(table_) * \
<                                             table_->entrySize))
< 
< #define ENTRY_STORE_EXTRA                   sizeof(uint32)
< #define INCREMENT_RECURSION_LEVEL(table_)   (++RECURSION_LEVEL(table_))
< #define DECREMENT_RECURSION_LEVEL(table_)   (--RECURSION_LEVEL(table_))
< 
< #else
< 
< #define ENTRY_STORE_EXTRA 0
< #define INCREMENT_RECURSION_LEVEL(table_)   ((void)1)
< #define DECREMENT_RECURSION_LEVEL(table_)   ((void)0)
84c60
< #endif /* defined(DEBUG) */
---
> //#include "_optimize.h"
89c65,66
<     return malloc(nbytes);
---
> 	XMEMTAG("JS_DHashAllocTable");
>     return xmalloc(nbytes);
95c72
<     free(ptr);
---
>     xfree(ptr);
105,106c82,83
<     for (s = (const unsigned char *) key; *s != '\0'; s++)
<         h = JS_ROTATE_LEFT32(h, 4) ^ *s;
---
>     for (s = key; *s != '\0'; s++)
>         h = (h >> (JS_DHASH_BITS - 4)) ^ (h << 4) ^ *s;
109a87,94
> JS_PUBLIC_API(const void *)
> JS_DHashGetKeyStub(JSDHashTable *table, JSDHashEntryHdr *entry)
> {
>     JSDHashEntryStub *stub = (JSDHashEntryStub *)entry;
> 
>     return stub->key;
> }
> 
113c98
<     return (JSDHashNumber)(unsigned long)key >> 2;
---
>     return (JSDHashNumber)key >> 2;
126,138d110
< JS_PUBLIC_API(JSBool)
< JS_DHashMatchStringKey(JSDHashTable *table,
<                        const JSDHashEntryHdr *entry,
<                        const void *key)
< {
<     const JSDHashEntryStub *stub = (const JSDHashEntryStub *)entry;
< 
<     /* XXX tolerate null keys on account of sloppy Mozilla callers. */
<     return stub->key == key ||
<            (stub->key && key &&
<             strcmp((const char *) stub->key, (const char *) key) == 0);
< }
< 
154,162d125
< JS_DHashFreeStringKey(JSDHashTable *table, JSDHashEntryHdr *entry)
< {
<     const JSDHashEntryStub *stub = (const JSDHashEntryStub *)entry;
< 
<     free((void *) stub->key);
<     memset(entry, 0, table->entrySize);
< }
< 
< JS_PUBLIC_API(void)
169a133
>     JS_DHashGetKeyStub,
190c154,155
<     table = (JSDHashTable *) malloc(sizeof *table);
---
> 	XMEMTAG("JS_NewDHashTable ");
>     table = (JSDHashTable *) xmalloc(sizeof *table);
194c159
<         free(table);
---
>         xfree(table);
204c169
<     free(table);
---
>     xfree(table);
219c184
<                 (void *) table,
---
>                 (void *)table,
229,231c194
< 
<     JS_CEILING_LOG2(log2, capacity);
< 
---
>     log2 = JS_CeilingLog2(capacity);
236,237c199,200
<     table->maxAlphaFrac = (uint8)(0x100 * JS_DHASH_DEFAULT_MAX_ALPHA);
<     table->minAlphaFrac = (uint8)(0x100 * JS_DHASH_DEFAULT_MIN_ALPHA);
---
>     table->maxAlphaFrac = 0xC0;                 /* 12/16 or .75 */
>     table->minAlphaFrac = 0x40;                 /* 1/4   or .25 */
243,244c206
<     table->entryStore = (char *) ops->allocTable(table,
<                                                  nbytes + ENTRY_STORE_EXTRA);
---
>     table->entryStore = ops->allocTable(table, nbytes);
249,253d210
< 
< #ifdef DEBUG
<     RECURSION_LEVEL(table) = 0;
< #endif
< 
346c303
< #ifdef DEBUG_XXXbrendan
---
> #ifdef DEBUG_brendan
358,359d314
<     INCREMENT_RECURSION_LEVEL(table);
< 
376,378d330
<     DECREMENT_RECURSION_LEVEL(table);
<     JS_ASSERT(RECURSION_LEVEL(table) == 0);
< 
383c335
< static JSDHashEntryHdr * JS_DHASH_FASTCALL
---
> static JSDHashEntryHdr *
420c372,378
<     firstRemoved = NULL;
---
>     if (ENTRY_IS_REMOVED(entry)) {
>         firstRemoved = entry;
>     } else {
>         firstRemoved = NULL;
>         if (op == JS_DHASH_ADD)
>             entry->keyHash |= COLLISION_FLAG;
>     }
423,430d380
<         if (JS_UNLIKELY(ENTRY_IS_REMOVED(entry))) {
<             if (!firstRemoved)
<                 firstRemoved = entry;
<         } else {
<             if (op == JS_DHASH_ADD)
<                 entry->keyHash |= COLLISION_FLAG;
<         }
< 
446,450d395
<     }
< 
<     /* NOTREACHED */
<     return NULL;
< }
452,500c397,402
< /*
<  * This is a copy of SearchTable, used by ChangeTable, hardcoded to
<  *   1. assume |op == PL_DHASH_ADD|,
<  *   2. assume that |key| will never match an existing entry, and
<  *   3. assume that no entries have been removed from the current table
<  *      structure.
<  * Avoiding the need for |key| means we can avoid needing a way to map
<  * entries to keys, which means callers can use complex key types more
<  * easily.
<  */
< static JSDHashEntryHdr * JS_DHASH_FASTCALL
< FindFreeEntry(JSDHashTable *table, JSDHashNumber keyHash)
< {
<     JSDHashNumber hash1, hash2;
<     int hashShift, sizeLog2;
<     JSDHashEntryHdr *entry;
<     uint32 sizeMask;
< 
<     METER(table->stats.searches++);
<     JS_ASSERT(!(keyHash & COLLISION_FLAG));
< 
<     /* Compute the primary hash address. */
<     hashShift = table->hashShift;
<     hash1 = HASH1(keyHash, hashShift);
<     entry = ADDRESS_ENTRY(table, hash1);
< 
<     /* Miss: return space for a new entry. */
<     if (JS_DHASH_ENTRY_IS_FREE(entry)) {
<         METER(table->stats.misses++);
<         return entry;
<     }
< 
<     /* Collision: double hash. */
<     sizeLog2 = JS_DHASH_BITS - table->hashShift;
<     hash2 = HASH2(keyHash, sizeLog2, hashShift);
<     sizeMask = JS_BITMASK(sizeLog2);
< 
<     for (;;) {
<         JS_ASSERT(!ENTRY_IS_REMOVED(entry));
<         entry->keyHash |= COLLISION_FLAG;
< 
<         METER(table->stats.steps++);
<         hash1 -= hash2;
<         hash1 &= sizeMask;
< 
<         entry = ADDRESS_ENTRY(table, hash1);
<         if (JS_DHASH_ENTRY_IS_FREE(entry)) {
<             METER(table->stats.misses++);
<             return entry;
---
>         if (ENTRY_IS_REMOVED(entry)) {
>             if (!firstRemoved)
>                 firstRemoved = entry;
>         } else {
>             if (op == JS_DHASH_ADD)
>                 entry->keyHash |= COLLISION_FLAG;
515a418
>     JSDHashGetKey getKey;
517,519d419
< #ifdef DEBUG
<     uint32 recursionLevel;
< #endif
531,532c431
<     newEntryStore = (char *) table->ops->allocTable(table,
<                                                     nbytes + ENTRY_STORE_EXTRA);
---
>     newEntryStore = table->ops->allocTable(table, nbytes);
537,539d435
< #ifdef DEBUG
<     recursionLevel = RECURSION_LEVEL(table);
< #endif
547a444
>     getKey = table->ops->getKey;
549,551d445
< #ifdef DEBUG
<     RECURSION_LEVEL(table) = recursionLevel;
< #endif
558c452,453
<             newEntry = FindFreeEntry(table, oldEntry->keyHash);
---
>             newEntry = SearchTable(table, getKey(table, oldEntry),
>                                    oldEntry->keyHash, JS_DHASH_ADD);
570c465
< JS_PUBLIC_API(JSDHashEntryHdr *) JS_DHASH_FASTCALL
---
> JS_PUBLIC_API(JSDHashEntryHdr *)
578,580d472
<     JS_ASSERT(op == JS_DHASH_LOOKUP || RECURSION_LEVEL(table) == 0);
<     INCREMENT_RECURSION_LEVEL(table);
< 
618,619c510
<                 entry = NULL;
<                 break;
---
>                 return NULL;
636,642c527,528
<             if (table->ops->initEntry &&
<                 !table->ops->initEntry(table, entry, key)) {
<                 /* We haven't claimed entry yet; fail with null return. */
<                 memset(entry + 1, 0, table->entrySize - sizeof *entry);
<                 entry = NULL;
<                 break;
<             }
---
>             if (table->ops->initEntry)
>                 table->ops->initEntry(table, entry, key);
673,674d558
<     DECREMENT_RECURSION_LEVEL(table);
< 
700c584
<     uint32 i, capacity, entrySize, ceiling;
---
>     uint32 i, capacity, entrySize;
705,706d588
<     INCREMENT_RECURSION_LEVEL(table);
< 
728,729d609
<     JS_ASSERT(!didRemove || RECURSION_LEVEL(table) == 1);
< 
746,750c626,628
< 
<         JS_CEILING_LOG2(ceiling, capacity);
<         ceiling -= JS_DHASH_BITS - table->hashShift;
< 
<         (void) ChangeTable(table, ceiling);
---
>         (void) ChangeTable(table,
>                            JS_CeilingLog2(capacity)
>                            - (JS_DHASH_BITS - table->hashShift));
752,754d629
< 
<     DECREMENT_RECURSION_LEVEL(table);
< 
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsdhash.h /Volumes/Swap/js_D11/src/jsdhash.h
3c3
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
---
>  * Version: NPL 1.1/GPL 2.0/LGPL 2.1
5,8c5,8
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
---
>  * The contents of this file are subject to the Netscape Public License
>  * Version 1.1 (the "License"); you may not use this file except in
>  * compliance with the License. You may obtain a copy of the License at
>  * http://www.mozilla.org/NPL/
17c17
<  * The Initial Developer of the Original Code is
---
>  * The Initial Developer of the Original Code is 
26,27c26,27
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
---
>  * either the GNU General Public License Version 2 or later (the "GPL"), or 
>  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
31c31
<  * use your version of this file under the terms of the MPL, indicate your
---
>  * use your version of this file under the terms of the NPL, indicate your
35c35
<  * the terms of any one of the MPL, the GPL or the LGPL.
---
>  * the terms of any one of the NPL, the GPL or the LGPL.
48,56c48
< #if defined(__GNUC__) && defined(__i386__) && (__GNUC__ >= 3) && !defined(XP_OS2)
< #define JS_DHASH_FASTCALL __attribute__ ((regparm (3),stdcall))
< #elif defined(XP_WIN)
< #define JS_DHASH_FASTCALL __fastcall
< #else
< #define JS_DHASH_FASTCALL
< #endif
< 
< #ifdef DEBUG_XXXbrendan
---
> #ifdef DEBUG_brendan
89,94c81,85
<  * either here.  Instead, the API uses const void *key as a formal parameter.
<  * The key need not be stored in the entry; it may be part of the value, but
<  * need not be stored at all.
<  *
<  * Callback types are defined below and grouped into the JSDHashTableOps
<  * structure, for single static initialization per hash table sub-type.
---
>  * either here.  Instead, the API uses const void *key as a formal parameter,
>  * and asks each entry for its key when necessary via a getKey callback, used
>  * when growing or shrinking the table.  Other callback types are defined
>  * below and grouped into the JSDHashTableOps structure, for single static
>  * initialization per hash table sub-type.
246a238,247
>  * When a table grows or shrinks, each entry is queried for its key using this
>  * callback.  NB: in that event, entry is not in table any longer; it's in the
>  * old entryStore vector, which is due to be freed once all entries have been
>  * moved via moveEntry callbacks.
>  */
> typedef const void *
> (* JS_DLL_CALLBACK JSDHashGetKey)    (JSDHashTable *table,
>                                       JSDHashEntryHdr *entry);
> 
> /*
297c298
< typedef JSBool
---
> typedef void
311d311
<  *                      Return JS_TRUE on success, JS_FALSE on error.
332a333
>     JSDHashGetKey       getKey;
360a362,364
> extern JS_PUBLIC_API(const void *)
> JS_DHashGetKeyStub(JSDHashTable *table, JSDHashEntryHdr *entry);
> 
369,373d372
< extern JS_PUBLIC_API(JSBool)
< JS_DHashMatchStringKey(JSDHashTable *table,
<                        const JSDHashEntryHdr *entry,
<                        const void *key);
< 
383,385d381
< JS_DHashFreeStringKey(JSDHashTable *table, JSDHashEntryHdr *entry);
< 
< extern JS_PUBLIC_API(void)
431c427
< extern JS_PUBLIC_API(void)
---
> JS_PUBLIC_API(void)
446,469d441
<  * Default max/min alpha, and macros to compute the value for the |capacity|
<  * parameter to JS_NewDHashTable and JS_DHashTableInit, given default or any
<  * max alpha, such that adding entryCount entries right after initializing the
<  * table will not require a reallocation (so JS_DHASH_ADD can't fail for those
<  * JS_DHashTableOperate calls).
<  *
<  * NB: JS_DHASH_CAP is a helper macro meant for use only in JS_DHASH_CAPACITY.
<  * Don't use it directly!
<  */
< #define JS_DHASH_DEFAULT_MAX_ALPHA 0.75
< #define JS_DHASH_DEFAULT_MIN_ALPHA 0.25
< 
< #define JS_DHASH_CAP(entryCount, maxAlpha)                                    \
<     ((uint32)((double)(entryCount) / (maxAlpha)))
< 
< #define JS_DHASH_CAPACITY(entryCount, maxAlpha)                               \
<     (JS_DHASH_CAP(entryCount, maxAlpha) +                                     \
<      (((JS_DHASH_CAP(entryCount, maxAlpha) * (uint8)(0x100 * (maxAlpha)))     \
<        >> 8) < (entryCount)))
< 
< #define JS_DHASH_DEFAULT_CAPACITY(entryCount)                                 \
<     JS_DHASH_CAPACITY(entryCount, JS_DHASH_DEFAULT_MAX_ALPHA)
< 
< /*
504,508c476,477
<  * If entry is null upon return, then either the table is severely overloaded,
<  * and memory can't be allocated for entry storage via table->ops->allocTable;
<  * Or if table->ops->initEntry is non-null, the table->ops->initEntry op may
<  * have returned false.
<  *
---
>  * If entry is null upon return, the table is severely overloaded, and new
>  * memory can't be allocated for new entry storage via table->ops->allocTable.
522c491
< extern JS_PUBLIC_API(JSDHashEntryHdr *) JS_DHASH_FASTCALL
---
> extern JS_PUBLIC_API(JSDHashEntryHdr *)
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsdtoa.c /Volumes/Swap/js_D11/src/jsdtoa.c
3,4c3,6
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
6,14c8,11
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,24c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
26,36c21
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
---
>  * Contributor(s): 
38c23,33
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
51c46
< #include "jsbit.h"
---
> #include "jsapi.h"
56a52,54
> 
> //#include "_optimize.h"
> 
195c193
< #include "stdlib.h"
---
> #include "xstdlib.h"
201c199
< #define MALLOC malloc
---
> #define MALLOC xmalloc
231a230,239
> /*
>  * MacOS 10.2 defines the macro FLT_ROUNDS to an internal function
>  * which does not exist on 10.1.  We can safely #define it to 1 here
>  * to allow 10.2 builds to run on 10.1, since we can't use fesetround()
>  * (which does not exist on 10.1 either).
>  */
> #if defined(MACOS_DEPLOYMENT_TARGET) && (MACOS_DEPLOYMENT_TARGET < 100200)
> #undef FLT_ROUNDS   
> #define FLT_ROUNDS 1
> #endif
544,546d551
< #ifdef JS_HAS_BUILTIN_BITSCAN32
<     return( (!x) ? 32 : js_bitscan_clz32(x) );
< #else
571d575
< #endif /* JS_HAS_BUILTIN_BITSCAN32 */
580,588d583
< #ifdef JS_HAS_BUILTIN_BITSCAN32
<     int32 k;
<     ULong x = *y;
< 
<    if (x>1)
<       *y = ( x >> (k = js_bitscan_ctz32(x)) );
<    else
<       k = ((x ^ 1) << 5);
< #else
626d620
< #endif /* JS_HAS_BUILTIN_BITSCAN32 */
997c991
<     double a = 0;
---
>     double a;
1028c1022
<     double d = 0;
---
>     double d;
1227c1221
<             free(temp);
---
>             xfree(temp);
1236c1230
<         free(temp);
---
>         xfree(temp);
1256c1250
<     bb = bd = bs = delta = NULL;
---
> 	bb = bd = bs = delta = NULL;
1378,1379c1372,1373
<                     set_word0(rv, 0x7ff00000);
<                     set_word1(rv, 0);
---
>                     word0(rv) = 0x7ff00000;
>                     word1(rv) = 0;
1386,1387c1380,1381
<                     set_word0(rv, NAN_WORD0);
<                     set_word1(rv, NAN_WORD1);
---
>                     word0(rv) = NAN_WORD0;
>                     word1(rv) = NAN_WORD1;
1457,1458c1451,1452
<                 set_word0(rv, Exp_mask);
<                 set_word1(rv, 0);
---
>                 word0(rv) = Exp_mask;
>                 word1(rv) = 0;
1844d1837
<         rv0 = 0.;
1883d1875
<     RELEASE_DTOA_LOCK();
2049c2041
<  * when the number is exactly halfway between two representable values.  For example,
---
>  * when the number is exactly halfway between two representable values.  For example, 
2103d2094
<     const char *cs;
2116,2117c2107,2108
<         cs = !word1(d) && !(word0(d) & Frac_mask) ? "Infinity" : "NaN";
<         if ((cs[0] == 'I' && bufsize < 9) || (cs[0] == 'N' && bufsize < 4)) {
---
>         s = !word1(d) && !(word0(d) & Frac_mask) ? "Infinity" : "NaN";
>         if ((s[0] == 'I' && bufsize < 9) || (s[0] == 'N' && bufsize < 4)) {
2122c2113
<         strcpy(buf, cs);
---
>         strcpy(buf, s);
2129c2120
< 
---
>     
2133c2124
< 
---
>     
2353,2357c2344
<                 if (1. - d < eps) {
< #ifdef DEBUG
<                     /* Clear d to avoid precision warning. */
<                     d = 0;
< #endif
---
>                 if (1. - d < eps)
2359d2345
<                 }
2375,2379c2361
<                     if (d > 0.5 + eps) {
< #ifdef DEBUG
<                         /* Clear d to avoid precision warning. */
<                         d = 0;
< #endif
---
>                     if (d > 0.5 + eps)
2381d2362
<                     }
2411,2413c2392
< 
<         /* Use true number of digits to limit looping. */
<         for(i = 1; i<=k+1; i++) {
---
>         for(i = 1;; i++) {
2438,2446c2417,2418
<             d *= 10.;
<         }
< #ifdef DEBUG
<         if (d != 0.0) {
<             fprintf(stderr,
< "WARNING: A loss of precision for double floating point is detected.\n"
< "         The result of any operation on doubles can be meaningless.\n"
< "         A possible cause is missing code to restore FPU state, see\n"
< "         bug 360282 for details.\n");
---
>             if (!(d *= 10.))
>                 break;
2448d2419
< #endif
2696c2667
<                 *s++ = (char)dig + 1;
---
>                 *s++ = (char)(dig + 1);
2860c2831
< 
---
>         
2930c2901
< 
---
>         
2965c2936,2937
<     buffer = (char*) malloc(DTOBASESTR_BUFFER_SIZE);
---
> 	XMEMTAG("JS_dtobasestr");
>     buffer = (char*) xmalloc(DTOBASESTR_BUFFER_SIZE);
2985c2957
< 
---
>         
3010,3011d2981
<                 RELEASE_DTOA_LOCK();
<                 free(buffer);
3028c2998
< 
---
>         
3036c3006
< 
---
>             
3046,3047d3015
<                 RELEASE_DTOA_LOCK();
<                 free(buffer);
3052c3020
< 
---
>             
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsdtoa.h /Volumes/Swap/js_D11/src/jsdtoa.h
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
Only in /Volumes/Swap/js-14-2-2008/js/src: jsdtracef.c
Only in /Volumes/Swap/js-14-2-2008/js/src: jsdtracef.h
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsemit.c /Volumes/Swap/js_D11/src/jsemit.c
2d1
<  * vim: set ts=8 sw=4 et tw=78:
4,5c3,6
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
7,15c8,11
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
20,23c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
27,39c23,33
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
56d49
< #include "jsbool.h"
64d56
< #include "jsregexp.h"
69,72c61,64
< /* Allocation chunk counts, must be powers of two in general. */
< #define BYTECODE_CHUNK  256     /* code allocation increment */
< #define SRCNOTE_CHUNK   64      /* initial srcnote allocation increment */
< #define TRYNOTE_CHUNK   64      /* trynote allocation increment */
---
> /* Allocation grain counts, must be powers of two in general. */
> #define BYTECODE_GRAIN  256     /* code allocation increment */
> #define SRCNOTE_GRAIN   64      /* initial srcnote allocation increment */
> #define TRYNOTE_GRAIN   64      /* trynote allocation increment */
79,83c71
< #define CG_TS(cg) TS((cg)->treeContext.parseContext)
< 
< static JSBool
< NewTryNote(JSContext *cx, JSCodeGenerator *cg, JSTryNoteKind kind,
<            uintN stackDepth, size_t start, size_t end);
---
> //#include "_optimize.h"
85,88c73,76
< JS_FRIEND_API(void)
< js_InitCodeGenerator(JSContext *cx, JSCodeGenerator *cg, JSParseContext *pc,
<                      JSArenaPool *codePool, JSArenaPool *notePool,
<                      uintN lineno)
---
> JS_FRIEND_API(JSBool)
> js_InitCodeGenerator(JSContext *cx, JSCodeGenerator *cg,
>                      const char *filename, uintN lineno,
>                      JSPrincipals *principals)
91,95c79,83
<     TREE_CONTEXT_INIT(&cg->treeContext, pc);
<     cg->codePool = codePool;
<     cg->notePool = notePool;
<     cg->codeMark = JS_ARENA_MARK(codePool);
<     cg->noteMark = JS_ARENA_MARK(notePool);
---
>     TREE_CONTEXT_INIT(&cg->treeContext);
>     cg->treeContext.flags |= TCF_COMPILING;
>     cg->codeMark = JS_ARENA_MARK(&cx->codePool);
>     cg->noteMark = JS_ARENA_MARK(&cx->notePool);
>     cg->tempMark = JS_ARENA_MARK(&cx->tempPool);
97c85,87
<     cg->firstLine = cg->prolog.currentLine = cg->main.currentLine = lineno;
---
>     cg->filename = filename;
>     cg->firstLine = cg->currentLine = lineno;
>     cg->principals = principals;
99,100c89,90
<     cg->prolog.noteMask = cg->main.noteMask = SRCNOTE_CHUNK - 1;
<     ATOM_LIST_INIT(&cg->constList);
---
>     cg->noteMask = SRCNOTE_GRAIN - 1;
>     return JS_TRUE;
107,108c97,99
<     JS_ARENA_RELEASE(cg->codePool, cg->codeMark);
<     JS_ARENA_RELEASE(cg->notePool, cg->noteMark);
---
>     JS_ARENA_RELEASE(&cx->codePool, cg->codeMark);
>     JS_ARENA_RELEASE(&cx->notePool, cg->noteMark);
>     JS_ARENA_RELEASE(&cx->tempPool, cg->tempMark);
124,125c115,116
<         length = (length <= BYTECODE_CHUNK)
<                  ? BYTECODE_CHUNK
---
>         length = (length <= BYTECODE_GRAIN)
>                  ? BYTECODE_GRAIN
129c120
<             JS_ARENA_ALLOCATE_CAST(base, jsbytecode *, cg->codePool, incr);
---
>             JS_ARENA_ALLOCATE_CAST(base, jsbytecode *, &cx->codePool, incr);
133c124
<             JS_ARENA_GROW_CAST(base, jsbytecode *, cg->codePool, size, incr);
---
>             JS_ARENA_GROW_CAST(base, jsbytecode *, &cx->codePool, size, incr);
136c127
<             js_ReportOutOfScriptQuota(cx);
---
>             JS_ReportOutOfMemory(cx);
150,151c141
<     JSOp op;
<     const JSCodeSpec *cs;
---
>     JSCodeSpec *cs;
155,160c145
<     op = (JSOp) *pc;
<     cs = &js_CodeSpec[op];
<     if ((cs->format & JOF_TMPSLOT) &&
<         (uintN)cg->stackDepth >= cg->maxStackDepth) {
<         cg->maxStackDepth = cg->stackDepth + 1;
<     }
---
>     cs = &js_CodeSpec[pc[0]];
162,176c147,148
<     if (nuses < 0) {
<         switch (op) {
<           case JSOP_POPN:
<             nuses = GET_UINT16(pc);
<             break;
<           case JSOP_NEW:
<           case JSOP_CALL:
<           case JSOP_SETCALL:
<           case JSOP_EVAL:
<             nuses = 2 + GET_ARGC(pc);   /* stack: fun, this, [argc arguments] */
<             break;
<           default:
<             JS_ASSERT(0);
<         }
<     }
---
>     if (nuses < 0)
>         nuses = 2 + GET_ARGC(pc);       /* stack: fun, this, [argc arguments] */
178d149
<     JS_ASSERT(cg->stackDepth >= 0);
181,182d151
<         JSTokenStream *ts;
< 
184,189c153,155
<         ts = &cg->treeContext.parseContext->tokenStream;
<         JS_ReportErrorFlagsAndNumber(cx, JSREPORT_WARNING,
<                                      js_GetErrorMessage, NULL,
<                                      JSMSG_STACK_UNDERFLOW,
<                                      ts->filename ? ts->filename : "stdin",
<                                      numBuf);
---
>         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
>                              JSMSG_STACK_UNDERFLOW,
>                              cg->filename ? cg->filename : "stdin", numBuf);
258,259d223
< const char js_finally_block_str[]  = "finally block";
< const char js_script_str[]         = "script";
261a226
>     "block",                 /* BLOCK */
265d229
<     "destructuring body",    /* BODY */
267d230
<     "block",                 /* BLOCK */
268a232
>     "try statement",         /* TRY */
270,272c234
<     "try block",             /* TRY */
<     js_finally_block_str,    /* FINALLY */
<     js_finally_block_str,    /* SUBROUTINE */
---
>     "finally statement",     /* FINALLY */
279,280d240
< JS_STATIC_ASSERT(JS_ARRAY_LENGTH(statementName) == STMT_LIMIT);
< 
285c245
<         return js_script_str;
---
>         return "script";
344c304
<   (see http://www.cmcrossroads.com/bradapp/ftp/src/libs/C++/AvlTrees.html).
---
>   (see http://www.enteract.com/~bradapp/ftp/src/libs/C++/AvlTrees.html).
357,360c317,321
<   proxy bytecode (JSOP_BACKPATCH; JSOP_BACKPATCH_POP for branch ops) whose
<   nuses/ndefs counts help keep the stack balanced, but whose opcode format
<   distinguishes its backpatch delta immediate operand from a normal jump
<   offset.
---
>   proxy bytecode (JSOP_BACKPATCH; JSOP_BACKPATCH_PUSH for jumps that push a
>   result on the interpreter's stack, namely JSOP_GOSUB; or JSOP_BACKPATCH_POP
>   for branch ops) whose nuses/ndefs counts help keep the stack balanced, but
>   whose opcode format distinguishes its backpatch delta immediate operand from
>   a normal jump offset.
433c394
<                 js_ReportOutOfScriptQuota(args->cx);
---
>                 JS_ReportOutOfMemory(args->cx);
532,533c493
<         if (!sdbase) {
<             js_ReportOutOfScriptQuota(cx);
---
>         if (!sdbase)
535d494
<         }
569,607d527
< static jsbytecode *
< AddSwitchSpanDeps(JSContext *cx, JSCodeGenerator *cg, jsbytecode *pc)
< {
<     JSOp op;
<     jsbytecode *pc2;
<     ptrdiff_t off;
<     jsint low, high;
<     uintN njumps, indexlen;
< 
<     op = (JSOp) *pc;
<     JS_ASSERT(op == JSOP_TABLESWITCH || op == JSOP_LOOKUPSWITCH);
<     pc2 = pc;
<     off = GET_JUMP_OFFSET(pc2);
<     if (!AddSpanDep(cx, cg, pc, pc2, off))
<         return NULL;
<     pc2 += JUMP_OFFSET_LEN;
<     if (op == JSOP_TABLESWITCH) {
<         low = GET_JUMP_OFFSET(pc2);
<         pc2 += JUMP_OFFSET_LEN;
<         high = GET_JUMP_OFFSET(pc2);
<         pc2 += JUMP_OFFSET_LEN;
<         njumps = (uintN) (high - low + 1);
<         indexlen = 0;
<     } else {
<         njumps = GET_UINT16(pc2);
<         pc2 += UINT16_LEN;
<         indexlen = INDEX_LEN;
<     }
<     while (njumps) {
<         --njumps;
<         pc2 += indexlen;
<         off = GET_JUMP_OFFSET(pc2);
<         if (!AddSpanDep(cx, cg, pc, pc2, off))
<             return NULL;
<         pc2 += JUMP_OFFSET_LEN;
<     }
<     return 1 + pc2;
< }
< 
613,614c533,534
<     const JSCodeSpec *cs;
<     ptrdiff_t off;
---
>     JSCodeSpec *cs;
>     ptrdiff_t len, off;
616c536
<     pc = CG_BASE(cg) + cg->spanDepTodo;
---
>     pc = CG_BASE(cg);
618,619c538
<     while (pc != end) {
<         JS_ASSERT(pc < end);
---
>     while (pc < end) {
621a541
>         len = (ptrdiff_t)cs->length;
623,630c543
<         switch (JOF_TYPE(cs->format)) {
<           case JOF_TABLESWITCH:
<           case JOF_LOOKUPSWITCH:
<             pc = AddSwitchSpanDeps(cx, cg, pc);
<             if (!pc)
<                 return JS_FALSE;
<             break;
< 
---
>         switch (cs->format & JOF_TYPEMASK) {
635,637d547
<             /* FALL THROUGH */
<           default:
<             pc += cs->length;
638a549,598
> 
> #if JS_HAS_SWITCH_STATEMENT
>           case JOF_TABLESWITCH:
>           {
>             jsbytecode *pc2;
>             jsint i, low, high;
> 
>             pc2 = pc;
>             off = GET_JUMP_OFFSET(pc2);
>             if (!AddSpanDep(cx, cg, pc, pc2, off))
>                 return JS_FALSE;
>             pc2 += JUMP_OFFSET_LEN;
>             low = GET_JUMP_OFFSET(pc2);
>             pc2 += JUMP_OFFSET_LEN;
>             high = GET_JUMP_OFFSET(pc2);
>             pc2 += JUMP_OFFSET_LEN;
>             for (i = low; i <= high; i++) {
>                 off = GET_JUMP_OFFSET(pc2);
>                 if (!AddSpanDep(cx, cg, pc, pc2, off))
>                     return JS_FALSE;
>                 pc2 += JUMP_OFFSET_LEN;
>             }
>             len = 1 + pc2 - pc;
>             break;
>           }
> 
>           case JOF_LOOKUPSWITCH:
>           {
>             jsbytecode *pc2;
>             jsint npairs;
> 
>             pc2 = pc;
>             off = GET_JUMP_OFFSET(pc2);
>             if (!AddSpanDep(cx, cg, pc, pc2, off))
>                 return JS_FALSE;
>             pc2 += JUMP_OFFSET_LEN;
>             npairs = (jsint) GET_ATOM_INDEX(pc2);
>             pc2 += ATOM_INDEX_LEN;
>             while (npairs) {
>                 pc2 += ATOM_INDEX_LEN;
>                 off = GET_JUMP_OFFSET(pc2);
>                 if (!AddSpanDep(cx, cg, pc, pc2, off))
>                     return JS_FALSE;
>                 pc2 += JUMP_OFFSET_LEN;
>                 npairs--;
>             }
>             len = 1 + pc2 - pc;
>             break;
>           }
> #endif /* JS_HAS_SWITCH_STATEMENT */
639a600,601
> 
>         pc += len;
765c727
<     JSTryNode *tryNode;
---
>     JSTryNote *tn, *tnlimit;
799c761
<                 type = JOF_OPTYPE(op);
---
>                 type = (js_CodeSpec[op].format & JOF_TYPEMASK);
816c778
<                 span = SD_SPAN(sd, pivot);
---
>                 span = SD_TARGET_OFFSET(sd) - pivot;
833,835c795
<                       default:
<                         ReportStatementTooLarge(cx, cg);
<                         return JS_FALSE;
---
>                       default:                JS_ASSERT(0);
877,878d836
<         JSTokenStream *ts = &cg->treeContext.parseContext->tokenStream;
< 
880c838
<                ts->filename ? ts->filename : "stdin", cg->firstLine,
---
>                cg->filename ? cg->filename : "stdin", cg->firstLine,
893c851
<             JS_ASSERT(length > BYTECODE_CHUNK);
---
>             JS_ASSERT(length > BYTECODE_GRAIN);
896c854
<             JS_ARENA_GROW_CAST(base, jsbytecode *, cg->codePool, size, incr);
---
>             JS_ARENA_GROW_CAST(base, jsbytecode *, &cx->codePool, size, incr);
898c856
<                 js_ReportOutOfScriptQuota(cx);
---
>                 JS_ReportOutOfMemory(cx);
932c890
<             type = JOF_OPTYPE(op);
---
>             type = (js_CodeSpec[op].format & JOF_TYPEMASK);
942c900
<         span = SD_SPAN(sd, pivot);
---
>         span = SD_TARGET_OFFSET(sd) - pivot;
993,995c951
<          * for span-dependent instruction operands.  However, we fix only main
<          * notes here, not prolog notes -- we know that prolog opcodes are not
<          * span-dependent, and aren't likely ever to be.
---
>          * for span-dependent instruction operands.
999c955
<         for (sn = cg->main.notes, snlimit = sn + cg->main.noteCount;
---
>         for (sn = cg->notes, snlimit = sn + cg->noteCount;
1023c979
<                     snlimit = cg->main.notes + cg->main.noteCount;
---
>                     snlimit = cg->notes + cg->noteCount;
1061c1017
<                     noteIndex = sn - cg->main.notes;
---
>                     noteIndex = sn - cg->notes;
1064,1065c1020,1021
<                     sn = cg->main.notes + noteIndex;
<                     snlimit = cg->main.notes + cg->main.noteCount;
---
>                     sn = cg->notes + noteIndex;
>                     snlimit = cg->notes + cg->noteCount;
1069d1024
<         cg->main.lastNoteOffset += growth;
1075c1030
<         for (tryNode = cg->lastTryNode; tryNode; tryNode = tryNode->prev) {
---
>         for (tn = cg->tryBase, tnlimit = cg->tryNext; tn < tnlimit; tn++) {
1081c1036
<             offset = tryNode->note.start;
---
>             offset = tn->start;
1084c1039
<             tryNode->note.start = offset + delta;
---
>             tn->start = offset + delta;
1090c1045
<             length = tryNode->note.length;
---
>             length = tn->length;
1092,1094c1047,1057
<             if (sd2 != sd) {
<                 tryNode->note.length =
<                     length + sd2->offset - sd2->before - delta;
---
>             if (sd2 != sd)
>                 tn->length = length + sd2->offset - sd2->before - delta;
> 
>             /*
>              * Finally, adjust tn->catchStart upward only if it is non-zero,
>              * and provided there are spandeps below it that grew.
>              */
>             offset = tn->catchStart;
>             if (offset != 0) {
>                 sd = FindNearestSpanDep(cg, offset, sd2 - sdbase, &guard);
>                 tn->catchStart = offset + sd->offset - sd->before;
1115c1078
<             type = JOF_OPTYPE(op);
---
>             type = (js_CodeSpec[op].format & JOF_TYPEMASK);
1137c1100
<         JS_ASSERT(SD_SPAN(sd, pivot) == span);
---
>         JS_ASSERT(SD_TARGET_OFFSET(sd) == pivot + span);
1155d1117
<     cg->spanDepTodo = CG_OFFSET(cg);
1162d1123
<     JSBool extend;
1166,1168c1127,1130
<     extend = off < JUMP_OFFSET_MIN || JUMP_OFFSET_MAX < off;
<     if (extend && !cg->spanDeps && !BuildSpanDepTable(cx, cg))
<         return JS_FALSE;
---
>     if (off < JUMP_OFFSET_MIN || JUMP_OFFSET_MAX < off) {
>         if (!cg->spanDeps && !BuildSpanDepTable(cx, cg))
>             return JS_FALSE;
>     }
1171c1133
<     if (jmp >= 0 && (extend || cg->spanDeps)) {
---
>     if (jmp >= 0 && cg->spanDeps) {
1219c1181
< js_InStatement(JSTreeContext *tc, JSStmtType type)
---
> js_InWithStatement(JSTreeContext *tc)
1224c1186
<         if (stmt->type == type)
---
>         if (stmt->type == STMT_WITH)
1231c1193
< js_IsGlobalReference(JSTreeContext *tc, JSAtom *atom, JSBool *loopyp)
---
> js_InCatchBlock(JSTreeContext *tc, JSAtom *atom)
1234d1195
<     JSScope *scope;
1236d1196
<     *loopyp = JS_FALSE;
1238,1249c1198,1199
<         if (stmt->type == STMT_WITH)
<             return JS_FALSE;
<         if (STMT_IS_LOOP(stmt)) {
<             *loopyp = JS_TRUE;
<             continue;
<         }
<         if (stmt->flags & SIF_SCOPE) {
<             JS_ASSERT(STOBJ_GET_CLASS(stmt->u.blockObj) == &js_BlockClass);
<             scope = OBJ_SCOPE(stmt->u.blockObj);
<             if (SCOPE_GET_PROPERTY(scope, ATOM_TO_JSID(atom)))
<                 return JS_FALSE;
<         }
---
>         if (stmt->type == STMT_CATCH && stmt->label == atom)
>             return JS_TRUE;
1251c1201
<     return JS_TRUE;
---
>     return JS_FALSE;
1259d1208
<     stmt->flags = 0;
1261,1262c1210
<     stmt->u.label = NULL;
<     JS_ASSERT(!stmt->u.blockObj);
---
>     stmt->label = NULL;
1265,1284d1212
<     if (STMT_LINKS_SCOPE(stmt)) {
<         stmt->downScope = tc->topScopeStmt;
<         tc->topScopeStmt = stmt;
<     } else {
<         stmt->downScope = NULL;
<     }
< }
< 
< void
< js_PushBlockScope(JSTreeContext *tc, JSStmtInfo *stmt, JSObject *blockObj,
<                   ptrdiff_t top)
< {
< 
<     js_PushStatement(tc, stmt, STMT_BLOCK, top);
<     stmt->flags |= SIF_SCOPE;
<     STOBJ_SET_PARENT(blockObj, tc->blockChain);
<     stmt->downScope = tc->topScopeStmt;
<     tc->topScopeStmt = stmt;
<     tc->blockChain = blockObj;
<     stmt->u.blockObj = blockObj;
1291,1309c1219
< static ptrdiff_t
< EmitBackPatchOp(JSContext *cx, JSCodeGenerator *cg, JSOp op, ptrdiff_t *lastp)
< {
<     ptrdiff_t offset, delta;
< 
<     offset = CG_OFFSET(cg);
<     delta = offset - *lastp;
<     *lastp = offset;
<     JS_ASSERT(delta > 0);
<     return EmitJump(cx, cg, op, delta);
< }
< 
< /*
<  * Macro to emit a bytecode followed by a uint16 immediate operand stored in
<  * big-endian order, used for arg and var numbers as well as for atomIndexes.
<  * NB: We use cx and cg from our caller's lexical environment, and return
<  * false on error.
<  */
< #define EMIT_UINT16_IMM_OP(op, i)                                             \
---
> #define EMIT_BACKPATCH_OP(cx, cg, last, op, jmp)                              \
1311,1312c1221,1226
<         if (js_Emit3(cx, cg, op, UINT16_HI(i), UINT16_LO(i)) < 0)             \
<             return JS_FALSE;                                                  \
---
>         ptrdiff_t offset, delta;                                              \
>         offset = CG_OFFSET(cg);                                               \
>         delta = offset - (last);                                              \
>         last = offset;                                                        \
>         JS_ASSERT(delta > 0);                                                 \
>         jmp = EmitJump((cx), (cg), (op), (delta));                            \
1315,1330c1229
< static JSBool
< FlushPops(JSContext *cx, JSCodeGenerator *cg, intN *npops)
< {
<     JS_ASSERT(*npops != 0);
<     if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0)
<         return JS_FALSE;
<     EMIT_UINT16_IMM_OP(JSOP_POPN, *npops);
<     *npops = 0;
<     return JS_TRUE;
< }
< 
< /*
<  * Emit additional bytecode(s) for non-local jumps.
<  *
<  * FIXME: https://bugzilla.mozilla.org/show_bug.cgi?id=379758
<  */
---
> /* Emit additional bytecode(s) for non-local jumps. */
1335c1234
<     intN depth, npops;
---
>     intN depth;
1340,1344c1239,1243
<      * Return from a try block that has a finally clause or from a for-in loop
<      * must be split into two ops: JSOP_SETRVAL, to pop the r.v. and store it
<      * in fp->rval; and JSOP_RETRVAL, which makes control flow go back to the
<      * caller, who picks up fp->rval as usual.  Otherwise, the stack will be
<      * unbalanced when executing the finally clause.
---
>      * Return from within a try block that has a finally clause must be split
>      * into two ops: JSOP_SETRVAL, to pop the r.v. and store it in fp->rval;
>      * and JSOP_RETRVAL, which makes control flow go back to the caller, who
>      * picks up fp->rval as usual.  Otherwise, the stack will be unbalanced
>      * when executing the finally clause.
1347,1350c1246,1247
<      * STMT_FINALLY) or a for-in loop to ensure that we emit just one
<      * JSOP_SETRVAL before one or more JSOP_GOSUBs/JSOP_ENDITERs and other
<      * fixup opcodes emitted by this function.
<      *
---
>      * STMT_FINALLY) to ensure that we emit just one JSOP_SETRVAL before one
>      * or more JSOP_GOSUBs and other fixup opcodes emitted by this function.
1352,1354c1249,1251
<      * The fixup opcodes and gosubs/enditers must interleave in the proper
<      * order, from inner statement to outer, so that finally clauses run at
<      * the correct stack depth.
---
>      * The fixup opcodes and gosubs must interleave in the proper order, from
>      * inner statement to outer, so that finally clauses run at the correct
>      * stack depth.
1360,1363c1257
<             if (stmt->type == STMT_FINALLY ||
<                 ((cg->treeContext.flags & TCF_FUN_HEAVYWEIGHT) &&
<                  STMT_MAYBE_SCOPE(stmt)) ||
<                 stmt->type == STMT_FOR_IN_LOOP) {
---
>             if (stmt->type == STMT_FINALLY) {
1387,1390d1280
<     npops = 0;
< 
< #define FLUSH_POPS() if (npops && !FlushPops(cx, cg, &npops)) return JS_FALSE
< 
1394d1283
<             FLUSH_POPS();
1397c1286
<             jmp = EmitBackPatchOp(cx, cg, JSOP_BACKPATCH, &GOSUBS(*stmt));
---
>             EMIT_BACKPATCH_OP(cx, cg, stmt->gosub, JSOP_BACKPATCH_PUSH, jmp);
1402a1292
>           case STMT_CATCH:
1404d1293
<             FLUSH_POPS();
1413a1303
>              * JSOP_POP2 isn't decompiled, so it doesn't need to be HIDDEN.
1415,1418c1305
<             FLUSH_POPS();
<             if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0)
<                 return JS_FALSE;
<             if (js_Emit1(cx, cg, JSOP_ENDITER) < 0)
---
>             if (js_Emit1(cx, cg, JSOP_POP2) < 0)
1423,1427c1310,1314
<             /*
<              * There's a [exception or hole, retsub pc-index] pair on the
<              * stack that we need to pop.
<              */
<             npops += 2;
---
>             /* There's a retsub pc-offset on the stack that we need to pop. */
>             if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0)
>                 return JS_FALSE;
>             if (js_Emit1(cx, cg, JSOP_POP) < 0)
>                 return JS_FALSE;
1432,1442d1318
< 
<         if (stmt->flags & SIF_SCOPE) {
<             uintN i;
< 
<             /* There is a Block object with locals on the stack to pop. */
<             FLUSH_POPS();
<             if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0)
<                 return JS_FALSE;
<             i = OBJ_BLOCK_COUNT(cx, stmt->u.blockObj);
<             EMIT_UINT16_IMM_OP(JSOP_LEAVEBLOCK, i);
<         }
1445d1320
<     FLUSH_POPS();
1448,1449d1322
< 
< #undef FLUSH_POPS
1454c1327
<          ptrdiff_t *lastp, JSAtomListElement *label, JSSrcNoteType noteType)
---
>          ptrdiff_t *last, JSAtomListElement *label, JSSrcNoteType noteType)
1456a1330
>     ptrdiff_t jmp;
1461,1463c1335
<     if (label)
<         index = js_NewSrcNote2(cx, cg, noteType, (ptrdiff_t) ALE_INDEX(label));
<     else if (noteType != SRC_NULL)
---
>     if (label) {
1465,1468c1337,1346
<     else
<         index = 0;
<     if (index < 0)
<         return -1;
---
>         if (index < 0)
>             return -1;
>         if (!js_SetSrcNoteOffset(cx, cg, (uintN)index, 0,
>                                  (ptrdiff_t) ALE_INDEX(label))) {
>             return -1;
>         }
>     } else if (noteType != SRC_NULL) {
>         if (js_NewSrcNote(cx, cg, noteType) < 0)
>             return -1;
>     }
1470c1348,1349
<     return EmitBackPatchOp(cx, cg, JSOP_BACKPATCH, lastp);
---
>     EMIT_BACKPATCH_OP(cx, cg, *last, JSOP_BACKPATCH, jmp);
>     return jmp;
1477c1356
<     jsbytecode *pc, *stop;
---
>     jsbytecode *pc;
1481,1482c1360
<     stop = CG_CODE(cg, -1);
<     while (pc != stop) {
---
>     while (pc != CG_CODE(cg, -1)) {
1501,1511c1379
<     JSStmtInfo *stmt;
< 
<     stmt = tc->topStmt;
<     tc->topStmt = stmt->down;
<     if (STMT_LINKS_SCOPE(stmt)) {
<         tc->topScopeStmt = stmt->downScope;
<         if (stmt->flags & SIF_SCOPE) {
<             tc->blockChain = STOBJ_GET_PARENT(stmt->u.blockObj);
<             --tc->scopeDepth;
<         }
<     }
---
>     tc->topStmt = tc->topStmt->down;
1520,1523c1388,1390
<     if (!STMT_IS_TRYING(stmt) &&
<         (!BackPatch(cx, cg, stmt->breaks, CG_NEXT(cg), JSOP_GOTO) ||
<          !BackPatch(cx, cg, stmt->continues, CG_CODE(cg, stmt->update),
<                     JSOP_GOTO))) {
---
>     if (!BackPatch(cx, cg, stmt->breaks, CG_NEXT(cg), JSOP_GOTO) ||
>         !BackPatch(cx, cg, stmt->continues, CG_CODE(cg, stmt->update),
>                    JSOP_GOTO)) {
1530,1762d1396
< JSBool
< js_DefineCompileTimeConstant(JSContext *cx, JSCodeGenerator *cg, JSAtom *atom,
<                              JSParseNode *pn)
< {
<     jsdouble dval;
<     jsint ival;
<     JSAtom *valueAtom;
<     jsval v;
<     JSAtomListElement *ale;
< 
<     /* XXX just do numbers for now */
<     if (pn->pn_type == TOK_NUMBER) {
<         dval = pn->pn_dval;
<         if (JSDOUBLE_IS_INT(dval, ival) && INT_FITS_IN_JSVAL(ival)) {
<             v = INT_TO_JSVAL(ival);
<         } else {
<             /*
<              * We atomize double to root a jsdouble instance that we wrap as
<              * jsval and store in cg->constList. This works because atoms are
<              * protected from GC during compilation.
<              */
<             valueAtom = js_AtomizeDouble(cx, dval);
<             if (!valueAtom)
<                 return JS_FALSE;
<             v = ATOM_KEY(valueAtom);
<         }
<         ale = js_IndexAtom(cx, atom, &cg->constList);
<         if (!ale)
<             return JS_FALSE;
<         ale->entry.value = (void *)v;
<     }
<     return JS_TRUE;
< }
< 
< #define LET_DECL 1
< #define VAR_DECL 2
< 
< JSStmtInfo *
< js_LexicalLookup(JSTreeContext *tc, JSAtom *atom, jsint *slotp, uintN decltype)
< {
<     JSStmtInfo *stmt;
<     JSObject *obj;
<     JSScope *scope;
<     JSScopeProperty *sprop;
<     jsval v;
< 
<     for (stmt = tc->topScopeStmt; stmt; stmt = stmt->downScope) {
<         if (stmt->type == STMT_WITH) {
<             /* Ignore with statements enclosing a single let declaration. */
<             if (decltype == LET_DECL)
<                 continue;
<             break;
<         }
< 
<         /* Skip "maybe scope" statements that don't contain let bindings. */
<         if (!(stmt->flags & SIF_SCOPE))
<             continue;
< 
<         obj = stmt->u.blockObj;
<         JS_ASSERT(LOCKED_OBJ_GET_CLASS(obj) == &js_BlockClass);
<         scope = OBJ_SCOPE(obj);
<         sprop = SCOPE_GET_PROPERTY(scope, ATOM_TO_JSID(atom));
<         if (sprop) {
<             JS_ASSERT(sprop->flags & SPROP_HAS_SHORTID);
< 
<             if (slotp) {
<                 /*
<                  * Use LOCKED_OBJ_GET_SLOT since we know obj is single-
<                  * threaded and owned by this compiler activation.
<                  */
<                 v = LOCKED_OBJ_GET_SLOT(obj, JSSLOT_BLOCK_DEPTH);
<                 JS_ASSERT(JSVAL_IS_INT(v) && JSVAL_TO_INT(v) >= 0);
<                 *slotp = JSVAL_TO_INT(v) + sprop->shortid;
<             }
<             return stmt;
<         }
<     }
< 
<     if (slotp)
<         *slotp = -1;
<     return stmt;
< }
< 
< /*
<  * Check if the attributes describe a property holding a compile-time constant
<  * or a permanent, read-only property without a getter.
<  */
< #define IS_CONSTANT_PROPERTY(attrs)                                           \
<     (((attrs) & (JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_GETTER)) ==      \
<      (JSPROP_READONLY | JSPROP_PERMANENT))
< 
< /*
<  * The function sets vp to JSVAL_HOLE when the atom does not corresponds to a
<  * name defining a constant.
<  */
< static JSBool
< LookupCompileTimeConstant(JSContext *cx, JSCodeGenerator *cg, JSAtom *atom,
<                           jsval *vp)
< {
<     JSBool ok;
<     JSStmtInfo *stmt;
<     jsint slot;
<     JSAtomListElement *ale;
<     JSObject *obj, *pobj;
<     JSProperty *prop;
<     uintN attrs;
< 
<     /*
<      * Chase down the cg stack, but only until we reach the outermost cg.
<      * This enables propagating consts from top-level into switch cases in a
<      * function compiled along with the top-level script.
<      */
<     *vp = JSVAL_HOLE;
<     do {
<         if ((cg->treeContext.flags & TCF_IN_FUNCTION) ||
<             cx->fp->varobj == cx->fp->scopeChain) {
<             /* XXX this will need revising when 'let const' is added. */
<             stmt = js_LexicalLookup(&cg->treeContext, atom, &slot, 0);
<             if (stmt)
<                 return JS_TRUE;
< 
<             ATOM_LIST_SEARCH(ale, &cg->constList, atom);
<             if (ale) {
<                 JS_ASSERT(ALE_VALUE(ale) != JSVAL_HOLE);
<                 *vp = ALE_VALUE(ale);
<                 return JS_TRUE;
<             }
< 
<             /*
<              * Try looking in the variable object for a direct property that
<              * is readonly and permanent.  We know such a property can't be
<              * shadowed by another property on obj's prototype chain, or a
<              * with object or catch variable; nor can prop's value be changed,
<              * nor can prop be deleted.
<              */
<             if (cg->treeContext.flags & TCF_IN_FUNCTION) {
<                 if (js_LookupLocal(cx, cg->treeContext.fun, atom, NULL) !=
<                     JSLOCAL_NONE) {
<                     break;
<                 }
<             } else if (cg->treeContext.flags & TCF_COMPILE_N_GO) {
<                 obj = cx->fp->varobj;
<                 ok = OBJ_LOOKUP_PROPERTY(cx, obj, ATOM_TO_JSID(atom), &pobj,
<                                          &prop);
<                 if (!ok)
<                     return JS_FALSE;
<                 if (pobj == obj) {
<                     /*
<                      * We're compiling code that will be executed immediately,
<                      * not re-executed against a different scope chain and/or
<                      * variable object.  Therefore we can get constant values
<                      * from our variable object here.
<                      */
<                     ok = OBJ_GET_ATTRIBUTES(cx, obj, ATOM_TO_JSID(atom), prop,
<                                             &attrs);
<                     if (ok && IS_CONSTANT_PROPERTY(attrs)) {
<                         ok = OBJ_GET_PROPERTY(cx, obj, ATOM_TO_JSID(atom), vp);
<                         JS_ASSERT_IF(ok, *vp != JSVAL_HOLE);
<                     }
<                 }
<                 if (prop)
<                     OBJ_DROP_PROPERTY(cx, pobj, prop);
<                 if (!ok)
<                     return JS_FALSE;
<                 if (prop)
<                     break;
<             }
<         }
<     } while ((cg = cg->parent) != NULL);
<     return JS_TRUE;
< }
< 
< /*
<  * Return JSOP_NOP to indicate that index fits 2 bytes and no index segment
<  * reset instruction is necessary, JSOP_FALSE to indicate an error or either
<  * JSOP_RESETBASE0 or JSOP_RESETBASE1 to indicate the reset bytecode to issue
<  * after the main bytecode sequence.
<  */
< static JSOp
< EmitBigIndexPrefix(JSContext *cx, JSCodeGenerator *cg, uintN index)
< {
<     uintN indexBase;
< 
<     /*
<      * We have max 3 bytes for indexes and check for INDEX_LIMIT overflow only
<      * for big indexes.
<      */
<     JS_STATIC_ASSERT(INDEX_LIMIT <= JS_BIT(24));
<     JS_STATIC_ASSERT(INDEX_LIMIT >=
<                      (JSOP_INDEXBASE3 - JSOP_INDEXBASE1 + 2) << 16);
< 
<     if (index < JS_BIT(16))
<         return JSOP_NOP;
<     indexBase = index >> 16;
<     if (indexBase <= JSOP_INDEXBASE3 - JSOP_INDEXBASE1 + 1) {
<         if (js_Emit1(cx, cg, (JSOp)(JSOP_INDEXBASE1 + indexBase - 1)) < 0)
<             return JSOP_FALSE;
<         return JSOP_RESETBASE0;
<     }
< 
<     if (index >= INDEX_LIMIT) {
<         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
<                              JSMSG_TOO_MANY_LITERALS);
<         return JSOP_FALSE;
<     }
< 
<     if (js_Emit2(cx, cg, JSOP_INDEXBASE, (JSOp)indexBase) < 0)
<         return JSOP_FALSE;
<     return JSOP_RESETBASE;
< }
< 
< /*
<  * Emit a bytecode and its 2-byte constant index immediate operand. If the
<  * index requires more than 2 bytes, emit a prefix op whose 8-bit immediate
<  * operand effectively extends the 16-bit immediate of the prefixed opcode,
<  * by changing index "segment" (see jsinterp.c). We optimize segments 1-3
<  * with single-byte JSOP_INDEXBASE[123] codes.
<  *
<  * Such prefixing currently requires a suffix to restore the "zero segment"
<  * register setting, but this could be optimized further.
<  */
< static JSBool
< EmitIndexOp(JSContext *cx, JSOp op, uintN index, JSCodeGenerator *cg)
< {
<     JSOp bigSuffix;
< 
<     bigSuffix = EmitBigIndexPrefix(cx, cg, index);
<     if (bigSuffix == JSOP_FALSE)
<         return JS_FALSE;
<     EMIT_UINT16_IMM_OP(op, index);
<     return bigSuffix == JSOP_NOP || js_Emit1(cx, cg, bigSuffix) >= 0;
< }
< 
1764,1765c1398,1400
<  * Slight sugar for EmitIndexOp, again accessing cx and cg from the macro
<  * caller's lexical environment, and embedding a false return on error.
---
>  * Emit a bytecode and its 2-byte constant (atom) index immediate operand.
>  * NB: We use cx and cg from our caller's lexical environment, and return
>  * false on error.
1767c1402
< #define EMIT_INDEX_OP(op, index)                                              \
---
> #define EMIT_ATOM_INDEX_OP(op, atomIndex)                                     \
1769c1404,1405
<         if (!EmitIndexOp(cx, op, index, cg))                                  \
---
>         if (js_Emit3(cx, cg, op, ATOM_INDEX_HI(atomIndex),                    \
>                                  ATOM_INDEX_LO(atomIndex)) < 0) {             \
1770a1407
>         }                                                                     \
1773d1409
< 
1779,1783d1414
<     JS_ASSERT(JOF_OPTYPE(op) == JOF_ATOM);
<     if (op == JSOP_GETPROP &&
<         pn->pn_atom == cx->runtime->atomState.lengthAtom) {
<         return js_Emit1(cx, cg, JSOP_LENGTH) >= 0;
<     }
1787,1833c1418,1419
<     return EmitIndexOp(cx, op, ALE_INDEX(ale), cg);
< }
< 
< static uintN
< IndexParsedObject(JSParsedObjectBox *pob, JSEmittedObjectList *list);
< 
< static JSBool
< EmitObjectOp(JSContext *cx, JSParsedObjectBox *pob, JSOp op,
<              JSCodeGenerator *cg)
< {
<     JS_ASSERT(JOF_OPTYPE(op) == JOF_OBJECT);
<     return EmitIndexOp(cx, op, IndexParsedObject(pob, &cg->objectList), cg);
< }
< 
< /*
<  * What good are ARGNO_LEN and VARNO_LEN, you ask?  The answer is that, apart
<  * from EmitSlotIndexOp, they abstract out the detail that both are 2, and in
<  * other parts of the code there's no necessary relationship between the two.
<  * The abstraction cracks here in order to share EmitSlotIndexOp code among
<  * the JSOP_DEFLOCALFUN and JSOP_GET{ARG,VAR,LOCAL}PROP cases.
<  */
< JS_STATIC_ASSERT(ARGNO_LEN == 2);
< JS_STATIC_ASSERT(VARNO_LEN == 2);
< 
< static JSBool
< EmitSlotIndexOp(JSContext *cx, JSOp op, uintN slot, uintN index,
<                  JSCodeGenerator *cg)
< {
<     JSOp bigSuffix;
<     ptrdiff_t off;
<     jsbytecode *pc;
< 
<     JS_ASSERT(JOF_OPTYPE(op) == JOF_SLOTATOM ||
<               JOF_OPTYPE(op) == JOF_SLOTOBJECT);
<     bigSuffix = EmitBigIndexPrefix(cx, cg, index);
<     if (bigSuffix == JSOP_FALSE)
<         return JS_FALSE;
< 
<     /* Emit [op, slot, index]. */
<     off = js_EmitN(cx, cg, op, 2 + INDEX_LEN);
<     if (off < 0)
<         return JS_FALSE;
<     pc = CG_CODE(cg, off);
<     SET_UINT16(pc, slot);
<     pc += 2;
<     SET_INDEX(pc, index);
<     return bigSuffix == JSOP_NOP || js_Emit1(cx, cg, bigSuffix) >= 0;
---
>     EMIT_ATOM_INDEX_OP(op, ALE_INDEX(ale));
>     return JS_TRUE;
1843c1429
<  * whether optimization occurred, in which case BindNameToSlot also updated
---
>  * whether optimization occurred, in which case LookupArgOrVar also updated
1847c1433
<  * variable name, pn->pn_const will be true for const properties after a
---
>  * variable name, pn->pn_attrs will contain the property's attributes after a
1849,1852d1434
<  *
<  * NB: if you add more opcodes specialized from JSOP_NAME, etc., don't forget
<  * to update the TOK_FOR (for-in) and TOK_ASSIGN (op=, e.g. +=) special cases
<  * in js_EmitTree.
1855,1856c1437
< BindNameToSlot(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn,
<                uintN decltype)
---
> LookupArgOrVar(JSContext *cx, JSTreeContext *tc, JSParseNode *pn)
1858c1439,1440
<     JSTreeContext *tc;
---
>     JSObject *obj, *pobj;
>     JSClass *clasp;
1860,1861c1442
<     JSStmtInfo *stmt;
<     jsint slot;
---
>     JSScopeProperty *sprop;
1863,1867d1443
<     JSStackFrame *fp;
<     JSLocalKind localKind;
<     uintN index;
<     JSAtomListElement *ale;
<     JSBool constOp;
1873,1910d1448
<     /* QNAME references can never be optimized to use arg/var storage. */
<     if (pn->pn_op == JSOP_QNAMEPART)
<         return JS_TRUE;
< 
<     /*
<      * We can't optimize if we are compiling a with statement and its body,
<      * or we're in a catch block whose exception variable has the same name
<      * as this node.  FIXME: we should be able to optimize catch vars to be
<      * block-locals.
<      */
<     tc = &cg->treeContext;
<     atom = pn->pn_atom;
<     if (decltype != VAR_DECL &&
<         (stmt = js_LexicalLookup(tc, atom, &slot, decltype))) {
<         if (stmt->type == STMT_WITH)
<             return JS_TRUE;
< 
<         JS_ASSERT(stmt->flags & SIF_SCOPE);
<         JS_ASSERT(slot >= 0);
<         op = PN_OP(pn);
<         switch (op) {
<           case JSOP_NAME:     op = JSOP_GETLOCAL; break;
<           case JSOP_SETNAME:  op = JSOP_SETLOCAL; break;
<           case JSOP_INCNAME:  op = JSOP_INCLOCAL; break;
<           case JSOP_NAMEINC:  op = JSOP_LOCALINC; break;
<           case JSOP_DECNAME:  op = JSOP_DECLOCAL; break;
<           case JSOP_NAMEDEC:  op = JSOP_LOCALDEC; break;
<           case JSOP_FORNAME:  op = JSOP_FORLOCAL; break;
<           case JSOP_DELNAME:  op = JSOP_FALSE; break;
<           default: JS_ASSERT(0);
<         }
<         if (op != pn->pn_op) {
<             pn->pn_op = op;
<             pn->pn_slot = slot;
<         }
<         return JS_TRUE;
<     }
< 
1919,1985c1457,1464
<     if (!(tc->flags & TCF_IN_FUNCTION) &&
<         !((cx->fp->flags & JSFRAME_SPECIAL) && cx->fp->fun)) {
<         /*
<          * We are compiling a script or eval and eval is not inside a function
<          * frame.
<          *
<          * We can't optimize if we are in an eval called inside a with
<          * statement.
<          */
<         fp = cx->fp;
<         if (fp->scopeChain != fp->varobj)
<             return JS_TRUE;
< 
<         /*
<          * A Script object can be used to split an eval into a compile step
<          * done at construction time, and an execute step done separately,
<          * possibly in a different scope altogether.  We therefore cannot do
<          * any name-to-slot optimizations, but must lookup names at runtime.
<          * Note that script_exec ensures that its caller's frame has a Call
<          * object, so arg and var name lookups will succeed.
<          */
<         if (fp->flags & JSFRAME_SCRIPT_OBJECT)
<             return JS_TRUE;
< 
<         /*
<          * We cannot optimize the name access when compiling with an eval or
<          * debugger frame.
<          */
<         if (fp->flags & JSFRAME_SPECIAL)
<             return JS_TRUE;
< 
<         /*
<          * We are compiling a top-level script. Optimize global variable
<          * accesses if there are at least 100 uses in unambiguous contexts,
<          * or failing that, if least half of all the uses of global
<          * vars/consts/functions are in loops.
<          */
<         if (!(tc->globalUses >= 100 ||
<               (tc->loopyGlobalUses &&
<                tc->loopyGlobalUses >= tc->globalUses / 2))) {
<             return JS_TRUE;
<         }
< 
<         /*
<          * We are optimizing global variables and there may be no pre-existing
<          * global property named atom.  If atom was declared via const or var,
<          * optimize pn to access fp->vars using the appropriate JSOP_*GVAR op.
<          */
<         ATOM_LIST_SEARCH(ale, &tc->decls, atom);
<         if (!ale) {
<             /* Use precedes declaration, or name is never declared. */
<             return JS_TRUE;
<         }
<         constOp = (ALE_JSOP(ale) == JSOP_DEFCONST);
< 
<         /* Index atom so we can map fast global number to name. */
<         ale = js_IndexAtom(cx, atom, &cg->atomList);
<         if (!ale)
<             return JS_FALSE;
< 
<         /* Defend against tc->ngvars 16-bit overflow. */
<         slot = ALE_INDEX(ale);
<         if ((slot + 1) >> 16)
<             return JS_TRUE;
< 
<         if ((uint16)(slot + 1) > tc->ngvars)
<             tc->ngvars = (uint16)(slot + 1);
---
>     /*
>      * We can't optimize if we're not compiling a function body, whether via
>      * eval, or directly when compiling a function statement or expression.
>      */
>     obj = cx->fp->varobj;
>     clasp = OBJ_GET_CLASS(cx, obj);
>     if (clasp != &js_FunctionClass && clasp != &js_CallClass)
>         return JS_TRUE;
1987,2004c1466,1474
<         op = PN_OP(pn);
<         switch (op) {
<           case JSOP_NAME:     op = JSOP_GETGVAR; break;
<           case JSOP_SETNAME:  op = JSOP_SETGVAR; break;
<           case JSOP_SETCONST: /* NB: no change */ break;
<           case JSOP_INCNAME:  op = JSOP_INCGVAR; break;
<           case JSOP_NAMEINC:  op = JSOP_GVARINC; break;
<           case JSOP_DECNAME:  op = JSOP_DECGVAR; break;
<           case JSOP_NAMEDEC:  op = JSOP_GVARDEC; break;
<           case JSOP_FORNAME:  /* NB: no change */ break;
<           case JSOP_DELNAME:  /* NB: no change */ break;
<           default: JS_ASSERT(0);
<         }
<         pn->pn_const = constOp;
<         if (op != pn->pn_op) {
<             pn->pn_op = op;
<             pn->pn_slot = slot;
<         }
---
>     /*
>      * We can't optimize if we're in an eval called inside a with statement,
>      * or we're compiling a with statement and its body, or we're in a catch
>      * block whose exception variable has the same name as pn.
>      */
>     atom = pn->pn_atom;
>     if (cx->fp->scopeChain != obj ||
>         js_InWithStatement(tc) ||
>         js_InCatchBlock(tc, atom)) {
2008,2017c1478,1492
<     if (tc->flags & TCF_IN_FUNCTION) {
<         /*
<          * We are compiling a function body and may be able to optimize name
<          * to stack slot. Look for an argument or variable in the function and
<          * rewrite pn_op and update pn accordingly.
<          */
<         localKind = js_LookupLocal(cx, tc->fun, atom, &index);
<         if (localKind != JSLOCAL_NONE) {
<             op = PN_OP(pn);
<             if (localKind == JSLOCAL_ARG) {
---
>     /*
>      * Ok, we may be able to optimize name to stack slot. Look for an argument
>      * or variable property in the function, or its call object, not found in
>      * any prototype object.  Rewrite pn_op and update pn accordingly.  NB: We
>      * know that JSOP_DELNAME on an argument or variable must evaluate to
>      * false, due to JSPROP_PERMANENT.
>      */
>     if (!js_LookupProperty(cx, obj, (jsid)atom, &pobj, (JSProperty **)&sprop))
>         return JS_FALSE;
>     op = pn->pn_op;
>     if (sprop) {
>         if (pobj == obj) {
>             JSPropertyOp getter = sprop->getter;
> 
>             if (getter == js_GetArgument) {
2029,2032c1504,1506
<                 pn->pn_const = JS_FALSE;
<             } else {
<                 JS_ASSERT(localKind == JSLOCAL_VAR ||
<                           localKind == JSLOCAL_CONST);
---
>             } else if (getter == js_GetLocalVariable ||
>                        getter == js_GetCallVariable)
>             {
2045d1518
<                 pn->pn_const = (localKind == JSLOCAL_CONST);
2047,2049c1520,1524
<             pn->pn_op = op;
<             pn->pn_slot = index;
<             return JS_TRUE;
---
>             if (op != pn->pn_op) {
>                 pn->pn_op = op;
>                 pn->pn_slot = sprop->shortid;
>             }
>             pn->pn_attrs = sprop->attrs;
2051c1526
<         tc->flags |= TCF_FUN_USES_NONLOCALS;
---
>         OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop);
2054,2067c1529,1543
<     /*
<      * Here we either compiling a function body or an eval script inside a
<      * function and couldn't optimize pn, so it's not a global or local slot
<      * name.
<      *
<      * Now we must check for the predefined arguments variable.  It may be
<      * overridden by assignment, in which case the function is heavyweight
<      * and the interpreter will look up 'arguments' in the function's call
<      * object.
<      */
<     if (pn->pn_op == JSOP_NAME &&
<         atom == cx->runtime->atomState.argumentsAtom) {
<         pn->pn_op = JSOP_ARGUMENTS;
<         return JS_TRUE;
---
>     if (pn->pn_slot < 0) {
>         /*
>          * We couldn't optimize it, so it's not an arg or local var name.  Now
>          * we must check for the predefined arguments variable.  It may be
>          * overridden by assignment, in which case the function is heavyweight
>          * and the interpreter will look up 'arguments' in the function's call
>          * object.
>          */
>         if (pn->pn_op == JSOP_NAME &&
>             atom == cx->runtime->atomState.argumentsAtom) {
>             pn->pn_op = JSOP_ARGUMENTS;
>             return JS_TRUE;
>         }
> 
>         tc->flags |= TCF_FUN_USES_NONLOCALS;
2085c1561
< CheckSideEffects(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn,
---
> CheckSideEffects(JSContext *cx, JSTreeContext *tc, JSParseNode *pn,
2089d1564
<     JSFunction *fun;
2105,2106c1580
<         fun = GET_FUNCTION_PRIVATE(cx, pn->pn_funpob->object);
<         if (fun->atom)
---
>         if (pn->pn_fun->atom)
2113,2115c1587
<             pn->pn_type == TOK_LB ||
<             pn->pn_type == TOK_RB ||
<             pn->pn_type == TOK_RC) {
---
>             pn->pn_type == TOK_LB) {
2126,2129d1597
<              *
<              * Array and object initializers (TOK_RB and TOK_RC lists) must be
<              * considered useful, because they are sugar for constructor calls
<              * (to Array and Object, respectively).
2134c1602
<                 ok &= CheckSideEffects(cx, cg, pn2, answer);
---
>                 ok &= CheckSideEffects(cx, tc, pn2, answer);
2139,2141c1607,1609
<         ok = CheckSideEffects(cx, cg, pn->pn_kid1, answer) &&
<              CheckSideEffects(cx, cg, pn->pn_kid2, answer) &&
<              CheckSideEffects(cx, cg, pn->pn_kid3, answer);
---
>         ok = CheckSideEffects(cx, tc, pn->pn_kid1, answer) &&
>              CheckSideEffects(cx, tc, pn->pn_kid2, answer) &&
>              CheckSideEffects(cx, tc, pn->pn_kid3, answer);
2151,2153d1618
<              *
<              * The only exception is assignment of a useless value to a const
<              * declared in the function currently being compiled.
2155,2161c1620,1624
<             pn2 = pn->pn_left;
<             if (pn2->pn_type != TOK_NAME) {
<                 *answer = JS_TRUE;
<             } else {
<                 if (!BindNameToSlot(cx, cg, pn2, 0))
<                     return JS_FALSE;
<                 if (!CheckSideEffects(cx, cg, pn->pn_right, answer))
---
>             *answer = JS_TRUE;
>         } else {
>             if (pn->pn_type == TOK_LB) {
>                 pn2 = pn->pn_left;
>                 if (pn2->pn_type == TOK_NAME && !LookupArgOrVar(cx, tc, pn2))
2163,2166c1626,1631
<                 if (!*answer &&
<                     (pn->pn_op != JSOP_NOP ||
<                      pn2->pn_slot < 0 ||
<                      !pn2->pn_const)) {
---
>                 if (pn2->pn_op != JSOP_ARGUMENTS) {
>                     /*
>                      * Any indexed property reference could call a getter with
>                      * side effects, except for arguments[i] where arguments is
>                      * unambiguous.
>                      */
2170,2175c1635,1636
<         } else {
<             /*
<              * We can't easily prove that neither operand ever denotes an
<              * object with a toString or valueOf method.
<              */
<             *answer = JS_TRUE;
---
>             ok = CheckSideEffects(cx, tc, pn->pn_left, answer) &&
>                  CheckSideEffects(cx, tc, pn->pn_right, answer);
2180,2212c1641,1645
<         switch (pn->pn_type) {
<           case TOK_RP:
<             ok = CheckSideEffects(cx, cg, pn->pn_kid, answer);
<             break;
< 
<           case TOK_DELETE:
<             pn2 = pn->pn_kid;
<             switch (pn2->pn_type) {
<               case TOK_NAME:
<               case TOK_DOT:
< #if JS_HAS_XML_SUPPORT
<               case TOK_DBLDOT:
< #endif
< #if JS_HAS_LVALUE_RETURN
<               case TOK_LP:
< #endif
<               case TOK_LB:
<                 /* All these delete addressing modes have effects too. */
<                 *answer = JS_TRUE;
<                 break;
<               default:
<                 ok = CheckSideEffects(cx, cg, pn2, answer);
<                 break;
<             }
<             break;
< 
<           default:
<             /*
<              * All of TOK_INC, TOK_DEC, TOK_THROW, TOK_YIELD, and TOK_DEFSHARP
<              * have direct effects. Of the remaining unary-arity node types,
<              * we can't easily prove that the operand never denotes an object
<              * with a toString or valueOf method.
<              */
---
>         if (pn->pn_type == TOK_INC || pn->pn_type == TOK_DEC ||
>             pn->pn_type == TOK_DELETE ||
>             pn->pn_type == TOK_THROW ||
>             pn->pn_type == TOK_DEFSHARP) {
>             /* All these operations have effects that we must commit. */
2214c1647,1648
<             break;
---
>         } else {
>             ok = CheckSideEffects(cx, tc, pn->pn_kid, answer);
2219,2225c1653,1654
<         /*
<          * Take care to avoid trying to bind a label name (labels, both for
<          * statements and property values in object initialisers, have pn_op
<          * defaulted to JSOP_NOP).
<          */
<         if (pn->pn_type == TOK_NAME && pn->pn_op != JSOP_NOP) {
<             if (!BindNameToSlot(cx, cg, pn, 0))
---
>         if (pn->pn_type == TOK_NAME) {
>             if (!LookupArgOrVar(cx, tc, pn))
2236,2237c1665,1666
<         if (pn->pn_type == TOK_DOT) {
<             if (pn2->pn_type == TOK_NAME && !BindNameToSlot(cx, cg, pn2, 0))
---
>         if (pn->pn_type == TOK_DOT && pn2->pn_type == TOK_NAME) {
>             if (!LookupArgOrVar(cx, tc, pn2))
2248c1677
<         ok = CheckSideEffects(cx, cg, pn2, answer);
---
>         ok = CheckSideEffects(cx, tc, pn2, answer);
2260,2337c1689
< EmitNameOp(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn,
<            JSBool callContext)
< {
<     JSOp op;
< 
<     if (!BindNameToSlot(cx, cg, pn, 0))
<         return JS_FALSE;
<     op = PN_OP(pn);
< 
<     if (callContext) {
<         switch (op) {
<           case JSOP_NAME:
<             op = JSOP_CALLNAME;
<             break;
<           case JSOP_GETVAR:
<             op = JSOP_CALLVAR;
<             break;
<           case JSOP_GETGVAR:
<             op = JSOP_CALLGVAR;
<             break;
<           case JSOP_GETARG:
<             op = JSOP_CALLARG;
<             break;
<           case JSOP_GETLOCAL:
<             op = JSOP_CALLLOCAL;
<             break;
<           default:
<             JS_ASSERT(op == JSOP_ARGUMENTS);
<             break;
<         }
<     }
< 
<     if (op == JSOP_ARGUMENTS) {
<         if (js_Emit1(cx, cg, op) < 0)
<             return JS_FALSE;
<         if (callContext && js_Emit1(cx, cg, JSOP_GLOBALTHIS) < 0)
<             return JS_FALSE;
<     } else {
<         if (pn->pn_slot >= 0) {
<             EMIT_UINT16_IMM_OP(op, pn->pn_slot);
<         } else {
<             if (!EmitAtomOp(cx, pn, op, cg))
<                 return JS_FALSE;
<         }
<     }
< 
<     return JS_TRUE;
< }
< 
< #if JS_HAS_XML_SUPPORT
< static JSBool
< EmitXMLName(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg)
< {
<     JSParseNode *pn2;
<     uintN oldflags;
< 
<     JS_ASSERT(pn->pn_type == TOK_UNARYOP);
<     JS_ASSERT(pn->pn_op == JSOP_XMLNAME);
<     JS_ASSERT(op == JSOP_XMLNAME || op == JSOP_CALLXMLNAME);
< 
<     pn2 = pn->pn_kid;
<     oldflags = cg->treeContext.flags;
<     cg->treeContext.flags &= ~TCF_IN_FOR_INIT;
<     if (!js_EmitTree(cx, cg, pn2))
<         return JS_FALSE;
<     cg->treeContext.flags |= oldflags & TCF_IN_FOR_INIT;
<     if (js_NewSrcNote2(cx, cg, SRC_PCBASE,
<                        CG_OFFSET(cg) - pn2->pn_offset) < 0) {
<         return JS_FALSE;
<     }
< 
<     return js_Emit1(cx, cg, op) >= 0;
< }
< #endif
< 
< static JSBool
< EmitPropOp(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg,
<            JSBool callContext)
---
> EmitPropOp(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg)
2340a1693
>     JSAtomListElement *ale;
2343,2389c1696,1704
<     if (callContext) {
<         JS_ASSERT(pn->pn_type == TOK_DOT);
<         JS_ASSERT(op == JSOP_GETPROP);
<         op = JSOP_CALLPROP;
<     } else if (op == JSOP_GETPROP && pn->pn_type == TOK_DOT) {
<         if (pn2->pn_op == JSOP_THIS) {
<             /* Fast path for gets of |this.foo|. */
<             return EmitAtomOp(cx, pn, JSOP_GETTHISPROP, cg);
<         }
< 
<         if (pn2->pn_type == TOK_NAME) {
<             /*
<              * Try to optimize:
<              *  - arguments.length into JSOP_ARGCNT
<              *  - argname.prop into JSOP_GETARGPROP
<              *  - varname.prop into JSOP_GETVARPROP
<              *  - localname.prop into JSOP_GETLOCALPROP
<              */
<             if (!BindNameToSlot(cx, cg, pn2, 0))
<                 return JS_FALSE;
<             switch (pn2->pn_op) {
<               case JSOP_ARGUMENTS:
<                 if (pn->pn_atom == cx->runtime->atomState.lengthAtom)
<                     return js_Emit1(cx, cg, JSOP_ARGCNT) >= 0;
<                 break;
< 
<               case JSOP_GETARG:
<                 op = JSOP_GETARGPROP;
<                 goto do_indexconst;
<               case JSOP_GETVAR:
<                 op = JSOP_GETVARPROP;
<                 goto do_indexconst;
<               case JSOP_GETLOCAL:
<                 op = JSOP_GETLOCALPROP;
<               do_indexconst: {
<                 JSAtomListElement *ale;
<                 jsatomid atomIndex;
< 
<                 ale = js_IndexAtom(cx, pn->pn_atom, &cg->atomList);
<                 if (!ale)
<                     return JS_FALSE;
<                 atomIndex = ALE_INDEX(ale);
<                 return EmitSlotIndexOp(cx, op, pn2->pn_slot, atomIndex, cg);
<               }
< 
<               default:;
<             }
---
>     if (op == JSOP_GETPROP &&
>         pn->pn_type == TOK_DOT &&
>         pn2->pn_type == TOK_NAME) {
>         /* Try to optimize arguments.length into JSOP_ARGCNT. */
>         if (!LookupArgOrVar(cx, &cg->treeContext, pn2))
>             return JS_FALSE;
>         if (pn2->pn_op == JSOP_ARGUMENTS &&
>             pn->pn_atom == cx->runtime->atomState.lengthAtom) {
>             return js_Emit1(cx, cg, JSOP_ARGCNT) >= 0;
2423c1738,1739
<             if (!EmitAtomOp(cx, pndot, PN_OP(pndot), cg))
---
>             ale = js_IndexAtom(cx, pndot->pn_atom, &cg->atomList);
>             if (!ale)
2424a1741
>             EMIT_ATOM_INDEX_OP(pndot->pn_op, ALE_INDEX(ale));
2436,2437c1753
<     if (js_NewSrcNote2(cx, cg, SRC_PCBASE,
<                        CG_OFFSET(cg) - pn2->pn_offset) < 0) {
---
>     if (js_NewSrcNote2(cx, cg, SRC_PCBASE, CG_OFFSET(cg) - pn2->pn_offset) < 0)
2439d1754
<     }
2445c1760,1761
<         if (!EmitAtomOp(cx, pn, op, cg))
---
>         ale = js_IndexAtom(cx, pn->pn_atom, &cg->atomList);
>         if (!ale)
2446a1763
>         EMIT_ATOM_INDEX_OP(op, ALE_INDEX(ale));
2455c1772
<     JSParseNode *left, *right, *next, ltmp, rtmp;
---
>     JSParseNode *left, *right, *next;
2461c1778
<         JS_ASSERT(pn->pn_op == JSOP_GETELEM || pn->pn_op == JSOP_IMPORTELEM);
---
>         JS_ASSERT(pn->pn_op == JSOP_GETELEM);
2473c1790
<             if (!BindNameToSlot(cx, cg, left, 0))
---
>             if (!LookupArgOrVar(cx, &cg->treeContext, left))
2477,2482c1794
<                 (jsuint)slot < JS_BIT(16)) {
<                 /*
<                  * arguments[i]() requires arguments object as "this".
<                  * Check that we never generates list for that usage.
<                  */
<                 JS_ASSERT(op != JSOP_CALLELEM || next->pn_next);
---
>                 (jsuint)slot < ATOM_INDEX_LIMIT) {
2484c1796
<                 EMIT_UINT16_IMM_OP(JSOP_ARGSUB, (jsatomid)slot);
---
>                 EMIT_ATOM_INDEX_OP(JSOP_ARGSUB, (jsatomid)slot);
2512,2542c1824,1826
<         if (pn->pn_arity == PN_NAME) {
<             /*
<              * Set left and right so pn appears to be a TOK_LB node, instead
<              * of a TOK_DOT node.  See the TOK_FOR/IN case in js_EmitTree, and
<              * EmitDestructuringOps nearer below.  In the destructuring case,
<              * the base expression (pn_expr) of the name may be null, which
<              * means we have to emit a JSOP_BINDNAME.
<              */
<             left = pn->pn_expr;
<             if (!left) {
<                 left = &ltmp;
<                 left->pn_type = TOK_STRING;
<                 left->pn_op = JSOP_BINDNAME;
<                 left->pn_arity = PN_NULLARY;
<                 left->pn_pos = pn->pn_pos;
<                 left->pn_atom = pn->pn_atom;
<             }
<             right = &rtmp;
<             right->pn_type = TOK_STRING;
<             JS_ASSERT(ATOM_IS_STRING(pn->pn_atom));
<             right->pn_op = js_IsIdentifier(ATOM_TO_STRING(pn->pn_atom))
<                            ? JSOP_QNAMEPART
<                            : JSOP_STRING;
<             right->pn_arity = PN_NULLARY;
<             right->pn_pos = pn->pn_pos;
<             right->pn_atom = pn->pn_atom;
<         } else {
<             JS_ASSERT(pn->pn_arity == PN_BINARY);
<             left = pn->pn_left;
<             right = pn->pn_right;
<         }
---
>         JS_ASSERT(pn->pn_arity == PN_BINARY);
>         left = pn->pn_left;
>         right = pn->pn_right;
2548c1832
<             if (!BindNameToSlot(cx, cg, left, 0))
---
>             if (!LookupArgOrVar(cx, &cg->treeContext, left))
2552c1836
<                 (jsuint)slot < JS_BIT(16)) {
---
>                 (jsuint)slot < ATOM_INDEX_LIMIT) {
2554c1838
<                 EMIT_UINT16_IMM_OP(JSOP_ARGSUB, (jsatomid)slot);
---
>                 EMIT_ATOM_INDEX_OP(JSOP_ARGSUB, (jsatomid)slot);
2562,2565d1845
< 
<     /* The right side of the descendant operator is implicitly quoted. */
<     JS_ASSERT(op != JSOP_DESCENDANTS || right->pn_type != TOK_STRING ||
<               right->pn_op == JSOP_QNAMEPART);
2577,2579c1857
<     uint32 u;
<     ptrdiff_t off;
<     jsbytecode *pc;
---
>     jsatomid atomIndex;
2588,2605c1866,1869
<         if ((jsint)(int8)ival == ival)
<             return js_Emit2(cx, cg, JSOP_INT8, (jsbytecode)(int8)ival) >= 0;
< 
<         u = (uint32)ival;
<         if (u < JS_BIT(16)) {
<             EMIT_UINT16_IMM_OP(JSOP_UINT16, u);
<         } else if (u < JS_BIT(24)) {
<             off = js_EmitN(cx, cg, JSOP_UINT24, 3);
<             if (off < 0)
<                 return JS_FALSE;
<             pc = CG_CODE(cg, off);
<             SET_UINT24(pc, u);
<         } else {
<             off = js_EmitN(cx, cg, JSOP_INT32, 4);
<             if (off < 0)
<                 return JS_FALSE;
<             pc = CG_CODE(cg, off);
<             SET_INT32(pc, ival);
---
>         if ((jsuint)ival < (jsuint)ATOM_INDEX_LIMIT) {
>             atomIndex = (jsatomid)ival;
>             EMIT_ATOM_INDEX_OP(JSOP_UINT16, atomIndex);
>             return JS_TRUE;
2607c1871,1873
<         return JS_TRUE;
---
>         atom = js_AtomizeInt(cx, ival, 0);
>     } else {
>         atom = js_AtomizeDouble(cx, dval, 0);
2609,2610d1874
< 
<     atom = js_AtomizeDouble(cx, dval);
2613d1876
< 
2617c1880,1915
<     return EmitIndexOp(cx, JSOP_DOUBLE, ALE_INDEX(ale), cg);
---
>     EMIT_ATOM_INDEX_OP(JSOP_NUMBER, ALE_INDEX(ale));
>     return JS_TRUE;
> }
> 
> JSBool
> js_EmitFunctionBody(JSContext *cx, JSCodeGenerator *cg, JSParseNode *body,
>                     JSFunction *fun)
> {
>     JSStackFrame *fp, frame;
>     JSObject *funobj;
>     JSBool ok;
> 
>     if (!js_AllocTryNotes(cx, cg))
>         return JS_FALSE;
> 
>     fp = cx->fp;
>     funobj = fun->object;
>     if (!fp || fp->fun != fun || fp->varobj != funobj ||
>         fp->scopeChain != funobj) {
>         memset(&frame, 0, sizeof frame);
>         frame.fun = fun;
>         frame.varobj = frame.scopeChain = funobj;
>         frame.down = fp;
>         cx->fp = &frame;
>     }
>     ok = js_EmitTree(cx, cg, body);
>     cx->fp = fp;
>     if (!ok)
>         return JS_FALSE;
> 
>     fun->script = js_NewScriptFromCG(cx, cg, fun);
>     if (!fun->script)
>         return JS_FALSE;
>     if (cg->treeContext.flags & TCF_FUN_HEAVYWEIGHT)
>         fun->flags |= JSFUN_HEAVYWEIGHT;
>     return JS_TRUE;
2619a1918,1948
> /* A macro for inlining at the top of js_EmitTree (whence it came). */
> #define UPDATE_LINENO_NOTES(cx, cg, pn)                                       \
>     JS_BEGIN_MACRO                                                            \
>         uintN line_ = (pn)->pn_pos.begin.lineno;                              \
>         uintN delta_ = line_ - (cg)->currentLine;                             \
>         if (delta_ != 0) {                                                    \
>             /*                                                                \
>              * Encode any change in the current source line number by using   \
>              * either several SRC_NEWLINE notes or just one SRC_SETLINE note, \
>              * whichever consumes less space.                                 \
>              *                                                                \
>              * NB: We handle backward line number deltas (possible with for   \
>              * loops where the update part is emitted after the body, but its \
>              * line number is <= any line number in the body) here by letting \
>              * unsigned delta_ wrap to a very large number, which triggers a  \
>              * SRC_SETLINE.                                                   \
>              */                                                               \
>             (cg)->currentLine = line_;                                        \
>             if (delta_ >= (uintN)(2 + ((line_ > SN_3BYTE_OFFSET_MASK)<<1))) { \
>                 if (js_NewSrcNote2(cx, cg, SRC_SETLINE, (ptrdiff_t)line_) < 0)\
>                     return JS_FALSE;                                          \
>             } else {                                                          \
>                 do {                                                          \
>                     if (js_NewSrcNote(cx, cg, SRC_NEWLINE) < 0)               \
>                         return JS_FALSE;                                      \
>                 } while (--delta_ != 0);                                      \
>             }                                                                 \
>         }                                                                     \
>     JS_END_MACRO
> 
> /* A function, so that we avoid macro-bloating all the other callsites. */
2621,2622c1950,1957
< EmitSwitch(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn,
<            JSStmtInfo *stmtInfo)
---
> UpdateLinenoNotes(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
> {
>     UPDATE_LINENO_NOTES(cx, cg, pn);
>     return JS_TRUE;
> }
> 
> JSBool
> js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
2624,2626c1959,1961
<     JSOp switchOp;
<     JSBool ok, hasDefault, constPropagated;
<     ptrdiff_t top, off, defaultOffset;
---
>     JSBool ok, useful, wantval;
>     JSStmtInfo *stmt, stmtInfo;
>     ptrdiff_t top, off, tmp, beq, jmp;
2628,2632d1962
<     uint32 caseCount, tableLength;
<     JSParseNode **table;
<     jsdouble d;
<     jsint i, low, high;
<     jsval v;
2635c1965
<     JSParsedObjectBox *pob;
---
>     jsatomid atomIndex;
2637,2642c1967,1969
<     size_t switchSize, tableSize;
<     jsbytecode *pc, *savepc;
< #if JS_HAS_BLOCK_SCOPE
<     JSObject *obj;
<     jsint count;
< #endif
---
>     JSSrcNoteType noteType;
>     JSOp op;
>     uint32 argc;
2644,2645d1970
<     /* Try for most optimal, fall back if not dense ints, and per ECMAv2. */
<     switchOp = JSOP_TABLESWITCH;
2647,2671c1972,1973
<     hasDefault = constPropagated = JS_FALSE;
<     defaultOffset = -1;
< 
<     /*
<      * If the switch contains let variables scoped by its body, model the
<      * resulting block on the stack first, before emitting the discriminant's
<      * bytecode (in case the discriminant contains a stack-model dependency
<      * such as a let expression).
<      */
<     pn2 = pn->pn_right;
< #if JS_HAS_BLOCK_SCOPE
<     if (pn2->pn_type == TOK_LEXICALSCOPE) {
<         pob = pn2->pn_pob;
<         obj = pob->object;
<         OBJ_SET_BLOCK_DEPTH(cx, obj, cg->stackDepth);
< 
<         /*
<          * Push the body's block scope before discriminant code-gen for proper
<          * static block scope linkage in case the discriminant contains a let
<          * expression.  The block's locals must lie under the discriminant on
<          * the stack so that case-dispatch bytecodes can find the discriminant
<          * on top of stack.
<          */
<         js_PushBlockScope(&cg->treeContext, stmtInfo, obj, -1);
<         stmtInfo->type = STMT_SWITCH;
---
>     cg->emitLevel++;
>     pn->pn_offset = top = CG_OFFSET(cg);
2673,3971c1975,1976
<         count = OBJ_BLOCK_COUNT(cx, obj);
<         cg->stackDepth += count;
<         if ((uintN)cg->stackDepth > cg->maxStackDepth)
<             cg->maxStackDepth = cg->stackDepth;
< 
<         /* Emit JSOP_ENTERBLOCK before code to evaluate the discriminant. */
<         if (!EmitObjectOp(cx, pob, JSOP_ENTERBLOCK, cg))
<             return JS_FALSE;
< 
<         /*
<          * Pop the switch's statement info around discriminant code-gen.  Note
<          * how this leaves cg->treeContext.blockChain referencing the switch's
<          * block scope object, which is necessary for correct block parenting
<          * in the case where the discriminant contains a let expression.
<          */
<         cg->treeContext.topStmt = stmtInfo->down;
<         cg->treeContext.topScopeStmt = stmtInfo->downScope;
<     }
< #ifdef __GNUC__
<     else {
<         count = -1;
<     }
< #endif
< #endif
< 
<     /*
<      * Emit code for the discriminant first (or nearly first, in the case of a
<      * switch whose body is a block scope).
<      */
<     if (!js_EmitTree(cx, cg, pn->pn_left))
<         return JS_FALSE;
< 
<     /* Switch bytecodes run from here till end of final case. */
<     top = CG_OFFSET(cg);
< #if !JS_HAS_BLOCK_SCOPE
<     js_PushStatement(&cg->treeContext, stmtInfo, STMT_SWITCH, top);
< #else
<     if (pn2->pn_type == TOK_LC) {
<         js_PushStatement(&cg->treeContext, stmtInfo, STMT_SWITCH, top);
<     } else {
<         /* Re-push the switch's statement info record. */
<         cg->treeContext.topStmt = cg->treeContext.topScopeStmt = stmtInfo;
< 
<         /* Set the statement info record's idea of top. */
<         stmtInfo->update = top;
< 
<         /* Advance pn2 to refer to the switch case list. */
<         pn2 = pn2->pn_expr;
<     }
< #endif
< 
<     caseCount = pn2->pn_count;
<     tableLength = 0;
<     table = NULL;
< 
<     if (caseCount == 0 ||
<         (caseCount == 1 &&
<          (hasDefault = (pn2->pn_head->pn_type == TOK_DEFAULT)))) {
<         caseCount = 0;
<         low = 0;
<         high = -1;
<     } else {
< #define INTMAP_LENGTH   256
<         jsbitmap intmap_space[INTMAP_LENGTH];
<         jsbitmap *intmap = NULL;
<         int32 intmap_bitlen = 0;
< 
<         low  = JSVAL_INT_MAX;
<         high = JSVAL_INT_MIN;
< 
<         for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {
<             if (pn3->pn_type == TOK_DEFAULT) {
<                 hasDefault = JS_TRUE;
<                 caseCount--;    /* one of the "cases" was the default */
<                 continue;
<             }
< 
<             JS_ASSERT(pn3->pn_type == TOK_CASE);
<             if (switchOp == JSOP_CONDSWITCH)
<                 continue;
< 
<             pn4 = pn3->pn_left;
<             switch (pn4->pn_type) {
<               case TOK_NUMBER:
<                 d = pn4->pn_dval;
<                 if (JSDOUBLE_IS_INT(d, i) && INT_FITS_IN_JSVAL(i)) {
<                     pn3->pn_val = INT_TO_JSVAL(i);
<                 } else {
<                     atom = js_AtomizeDouble(cx, d);
<                     if (!atom) {
<                         ok = JS_FALSE;
<                         goto release;
<                     }
<                     pn3->pn_val = ATOM_KEY(atom);
<                 }
<                 break;
<               case TOK_STRING:
<                 pn3->pn_val = ATOM_KEY(pn4->pn_atom);
<                 break;
<               case TOK_NAME:
<                 if (!pn4->pn_expr) {
<                     ok = LookupCompileTimeConstant(cx, cg, pn4->pn_atom, &v);
<                     if (!ok)
<                         goto release;
<                     if (v != JSVAL_HOLE) {
<                         if (!JSVAL_IS_PRIMITIVE(v)) {
<                             /*
<                              * XXX JSOP_LOOKUPSWITCH does not support const-
<                              * propagated object values, see bug 407186.
<                              */
<                             switchOp = JSOP_CONDSWITCH;
<                             continue;
<                         }
<                         pn3->pn_val = v;
<                         constPropagated = JS_TRUE;
<                         break;
<                     }
<                 }
<                 /* FALL THROUGH */
<               case TOK_PRIMARY:
<                 if (pn4->pn_op == JSOP_TRUE) {
<                     pn3->pn_val = JSVAL_TRUE;
<                     break;
<                 }
<                 if (pn4->pn_op == JSOP_FALSE) {
<                     pn3->pn_val = JSVAL_FALSE;
<                     break;
<                 }
<                 /* FALL THROUGH */
<               default:
<                 switchOp = JSOP_CONDSWITCH;
<                 continue;
<             }
< 
<             JS_ASSERT(JSVAL_IS_PRIMITIVE(pn3->pn_val));
< 
<             if (switchOp != JSOP_TABLESWITCH)
<                 continue;
<             if (!JSVAL_IS_INT(pn3->pn_val)) {
<                 switchOp = JSOP_LOOKUPSWITCH;
<                 continue;
<             }
<             i = JSVAL_TO_INT(pn3->pn_val);
<             if ((jsuint)(i + (jsint)JS_BIT(15)) >= (jsuint)JS_BIT(16)) {
<                 switchOp = JSOP_LOOKUPSWITCH;
<                 continue;
<             }
<             if (i < low)
<                 low = i;
<             if (high < i)
<                 high = i;
< 
<             /*
<              * Check for duplicates, which require a JSOP_LOOKUPSWITCH.
<              * We bias i by 65536 if it's negative, and hope that's a rare
<              * case (because it requires a malloc'd bitmap).
<              */
<             if (i < 0)
<                 i += JS_BIT(16);
<             if (i >= intmap_bitlen) {
<                 if (!intmap &&
<                     i < (INTMAP_LENGTH << JS_BITS_PER_WORD_LOG2)) {
<                     intmap = intmap_space;
<                     intmap_bitlen = INTMAP_LENGTH << JS_BITS_PER_WORD_LOG2;
<                 } else {
<                     /* Just grab 8K for the worst-case bitmap. */
<                     intmap_bitlen = JS_BIT(16);
<                     intmap = (jsbitmap *)
<                         JS_malloc(cx,
<                                   (JS_BIT(16) >> JS_BITS_PER_WORD_LOG2)
<                                   * sizeof(jsbitmap));
<                     if (!intmap) {
<                         JS_ReportOutOfMemory(cx);
<                         return JS_FALSE;
<                     }
<                 }
<                 memset(intmap, 0, intmap_bitlen >> JS_BITS_PER_BYTE_LOG2);
<             }
<             if (JS_TEST_BIT(intmap, i)) {
<                 switchOp = JSOP_LOOKUPSWITCH;
<                 continue;
<             }
<             JS_SET_BIT(intmap, i);
<         }
< 
<       release:
<         if (intmap && intmap != intmap_space)
<             JS_free(cx, intmap);
<         if (!ok)
<             return JS_FALSE;
< 
<         /*
<          * Compute table length and select lookup instead if overlarge or
<          * more than half-sparse.
<          */
<         if (switchOp == JSOP_TABLESWITCH) {
<             tableLength = (uint32)(high - low + 1);
<             if (tableLength >= JS_BIT(16) || tableLength > 2 * caseCount)
<                 switchOp = JSOP_LOOKUPSWITCH;
<         } else if (switchOp == JSOP_LOOKUPSWITCH) {
<             /*
<              * Lookup switch supports only atom indexes below 64K limit.
<              * Conservatively estimate the maximum possible index during
<              * switch generation and use conditional switch if it exceeds
<              * the limit.
<              */
<             if (caseCount + cg->atomList.count > JS_BIT(16))
<                 switchOp = JSOP_CONDSWITCH;
<         }
<     }
< 
<     /*
<      * Emit a note with two offsets: first tells total switch code length,
<      * second tells offset to first JSOP_CASE if condswitch.
<      */
<     noteIndex = js_NewSrcNote3(cx, cg, SRC_SWITCH, 0, 0);
<     if (noteIndex < 0)
<         return JS_FALSE;
< 
<     if (switchOp == JSOP_CONDSWITCH) {
<         /*
<          * 0 bytes of immediate for unoptimized ECMAv2 switch.
<          */
<         switchSize = 0;
<     } else if (switchOp == JSOP_TABLESWITCH) {
<         /*
<          * 3 offsets (len, low, high) before the table, 1 per entry.
<          */
<         switchSize = (size_t)(JUMP_OFFSET_LEN * (3 + tableLength));
<     } else {
<         /*
<          * JSOP_LOOKUPSWITCH:
<          * 1 offset (len) and 1 atom index (npairs) before the table,
<          * 1 atom index and 1 jump offset per entry.
<          */
<         switchSize = (size_t)(JUMP_OFFSET_LEN + INDEX_LEN +
<                               (INDEX_LEN + JUMP_OFFSET_LEN) * caseCount);
<     }
< 
<     /*
<      * Emit switchOp followed by switchSize bytes of jump or lookup table.
<      *
<      * If switchOp is JSOP_LOOKUPSWITCH or JSOP_TABLESWITCH, it is crucial
<      * to emit the immediate operand(s) by which bytecode readers such as
<      * BuildSpanDepTable discover the length of the switch opcode *before*
<      * calling js_SetJumpOffset (which may call BuildSpanDepTable).  It's
<      * also important to zero all unknown jump offset immediate operands,
<      * so they can be converted to span dependencies with null targets to
<      * be computed later (js_EmitN zeros switchSize bytes after switchOp).
<      */
<     if (js_EmitN(cx, cg, switchOp, switchSize) < 0)
<         return JS_FALSE;
< 
<     off = -1;
<     if (switchOp == JSOP_CONDSWITCH) {
<         intN caseNoteIndex = -1;
<         JSBool beforeCases = JS_TRUE;
< 
<         /* Emit code for evaluating cases and jumping to case statements. */
<         for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {
<             pn4 = pn3->pn_left;
<             if (pn4 && !js_EmitTree(cx, cg, pn4))
<                 return JS_FALSE;
<             if (caseNoteIndex >= 0) {
<                 /* off is the previous JSOP_CASE's bytecode offset. */
<                 if (!js_SetSrcNoteOffset(cx, cg, (uintN)caseNoteIndex, 0,
<                                          CG_OFFSET(cg) - off)) {
<                     return JS_FALSE;
<                 }
<             }
<             if (!pn4) {
<                 JS_ASSERT(pn3->pn_type == TOK_DEFAULT);
<                 continue;
<             }
<             caseNoteIndex = js_NewSrcNote2(cx, cg, SRC_PCDELTA, 0);
<             if (caseNoteIndex < 0)
<                 return JS_FALSE;
<             off = EmitJump(cx, cg, JSOP_CASE, 0);
<             if (off < 0)
<                 return JS_FALSE;
<             pn3->pn_offset = off;
<             if (beforeCases) {
<                 uintN noteCount, noteCountDelta;
< 
<                 /* Switch note's second offset is to first JSOP_CASE. */
<                 noteCount = CG_NOTE_COUNT(cg);
<                 if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 1,
<                                          off - top)) {
<                     return JS_FALSE;
<                 }
<                 noteCountDelta = CG_NOTE_COUNT(cg) - noteCount;
<                 if (noteCountDelta != 0)
<                     caseNoteIndex += noteCountDelta;
<                 beforeCases = JS_FALSE;
<             }
<         }
< 
<         /*
<          * If we didn't have an explicit default (which could fall in between
<          * cases, preventing us from fusing this js_SetSrcNoteOffset with the
<          * call in the loop above), link the last case to the implicit default
<          * for the decompiler.
<          */
<         if (!hasDefault &&
<             caseNoteIndex >= 0 &&
<             !js_SetSrcNoteOffset(cx, cg, (uintN)caseNoteIndex, 0,
<                                  CG_OFFSET(cg) - off)) {
<             return JS_FALSE;
<         }
< 
<         /* Emit default even if no explicit default statement. */
<         defaultOffset = EmitJump(cx, cg, JSOP_DEFAULT, 0);
<         if (defaultOffset < 0)
<             return JS_FALSE;
<     } else {
<         pc = CG_CODE(cg, top + JUMP_OFFSET_LEN);
< 
<         if (switchOp == JSOP_TABLESWITCH) {
<             /* Fill in switch bounds, which we know fit in 16-bit offsets. */
<             SET_JUMP_OFFSET(pc, low);
<             pc += JUMP_OFFSET_LEN;
<             SET_JUMP_OFFSET(pc, high);
<             pc += JUMP_OFFSET_LEN;
< 
<             /*
<              * Use malloc to avoid arena bloat for programs with many switches.
<              * We free table if non-null at label out, so all control flow must
<              * exit this function through goto out or goto bad.
<              */
<             if (tableLength != 0) {
<                 tableSize = (size_t)tableLength * sizeof *table;
<                 table = (JSParseNode **) JS_malloc(cx, tableSize);
<                 if (!table)
<                     return JS_FALSE;
<                 memset(table, 0, tableSize);
<                 for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {
<                     if (pn3->pn_type == TOK_DEFAULT)
<                         continue;
<                     i = JSVAL_TO_INT(pn3->pn_val);
<                     i -= low;
<                     JS_ASSERT((uint32)i < tableLength);
<                     table[i] = pn3;
<                 }
<             }
<         } else {
<             JS_ASSERT(switchOp == JSOP_LOOKUPSWITCH);
< 
<             /* Fill in the number of cases. */
<             SET_INDEX(pc, caseCount);
<             pc += INDEX_LEN;
<         }
< 
<         /*
<          * After this point, all control flow involving JSOP_TABLESWITCH
<          * must set ok and goto out to exit this function.  To keep things
<          * simple, all switchOp cases exit that way.
<          */
<         if (cg->spanDeps) {
<             /*
<              * We have already generated at least one big jump so we must
<              * explicitly add span dependencies for the switch jumps. When
<              * called below, js_SetJumpOffset can only do it when patching
<              * the first big jump or when cg->spanDeps is null.
<              */
<             if (!AddSwitchSpanDeps(cx, cg, CG_CODE(cg, top)))
<                 goto bad;
<         }
< 
<         if (constPropagated) {
<             /*
<              * Skip switchOp, as we are not setting jump offsets in the two
<              * for loops below.  We'll restore CG_NEXT(cg) from savepc after,
<              * unless there was an error.
<              */
<             savepc = CG_NEXT(cg);
<             CG_NEXT(cg) = pc + 1;
<             if (switchOp == JSOP_TABLESWITCH) {
<                 for (i = 0; i < (jsint)tableLength; i++) {
<                     pn3 = table[i];
<                     if (pn3 &&
<                         (pn4 = pn3->pn_left) != NULL &&
<                         pn4->pn_type == TOK_NAME) {
<                         /* Note a propagated constant with the const's name. */
<                         JS_ASSERT(!pn4->pn_expr);
<                         ale = js_IndexAtom(cx, pn4->pn_atom, &cg->atomList);
<                         if (!ale)
<                             goto bad;
<                         CG_NEXT(cg) = pc;
<                         if (js_NewSrcNote2(cx, cg, SRC_LABEL, (ptrdiff_t)
<                                            ALE_INDEX(ale)) < 0) {
<                             goto bad;
<                         }
<                     }
<                     pc += JUMP_OFFSET_LEN;
<                 }
<             } else {
<                 for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {
<                     pn4 = pn3->pn_left;
<                     if (pn4 && pn4->pn_type == TOK_NAME) {
<                         /* Note a propagated constant with the const's name. */
<                         JS_ASSERT(!pn4->pn_expr);
<                         ale = js_IndexAtom(cx, pn4->pn_atom, &cg->atomList);
<                         if (!ale)
<                             goto bad;
<                         CG_NEXT(cg) = pc;
<                         if (js_NewSrcNote2(cx, cg, SRC_LABEL, (ptrdiff_t)
<                                            ALE_INDEX(ale)) < 0) {
<                             goto bad;
<                         }
<                     }
<                     pc += INDEX_LEN + JUMP_OFFSET_LEN;
<                 }
<             }
<             CG_NEXT(cg) = savepc;
<         }
<     }
< 
<     /* Emit code for each case's statements, copying pn_offset up to pn3. */
<     for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {
<         if (switchOp == JSOP_CONDSWITCH && pn3->pn_type != TOK_DEFAULT)
<             CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, pn3->pn_offset);
<         pn4 = pn3->pn_right;
<         ok = js_EmitTree(cx, cg, pn4);
<         if (!ok)
<             goto out;
<         pn3->pn_offset = pn4->pn_offset;
<         if (pn3->pn_type == TOK_DEFAULT)
<             off = pn3->pn_offset - top;
<     }
< 
<     if (!hasDefault) {
<         /* If no default case, offset for default is to end of switch. */
<         off = CG_OFFSET(cg) - top;
<     }
< 
<     /* We better have set "off" by now. */
<     JS_ASSERT(off != -1);
< 
<     /* Set the default offset (to end of switch if no default). */
<     if (switchOp == JSOP_CONDSWITCH) {
<         pc = NULL;
<         JS_ASSERT(defaultOffset != -1);
<         ok = js_SetJumpOffset(cx, cg, CG_CODE(cg, defaultOffset),
<                               off - (defaultOffset - top));
<         if (!ok)
<             goto out;
<     } else {
<         pc = CG_CODE(cg, top);
<         ok = js_SetJumpOffset(cx, cg, pc, off);
<         if (!ok)
<             goto out;
<         pc += JUMP_OFFSET_LEN;
<     }
< 
<     /* Set the SRC_SWITCH note's offset operand to tell end of switch. */
<     off = CG_OFFSET(cg) - top;
<     ok = js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 0, off);
<     if (!ok)
<         goto out;
< 
<     if (switchOp == JSOP_TABLESWITCH) {
<         /* Skip over the already-initialized switch bounds. */
<         pc += 2 * JUMP_OFFSET_LEN;
< 
<         /* Fill in the jump table, if there is one. */
<         for (i = 0; i < (jsint)tableLength; i++) {
<             pn3 = table[i];
<             off = pn3 ? pn3->pn_offset - top : 0;
<             ok = js_SetJumpOffset(cx, cg, pc, off);
<             if (!ok)
<                 goto out;
<             pc += JUMP_OFFSET_LEN;
<         }
<     } else if (switchOp == JSOP_LOOKUPSWITCH) {
<         /* Skip over the already-initialized number of cases. */
<         pc += INDEX_LEN;
< 
<         for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {
<             if (pn3->pn_type == TOK_DEFAULT)
<                 continue;
<             if (!js_AtomizePrimitiveValue(cx, pn3->pn_val, &atom))
<                 goto bad;
<             ale = js_IndexAtom(cx, atom, &cg->atomList);
<             if (!ale)
<                 goto bad;
<             SET_INDEX(pc, ALE_INDEX(ale));
<             pc += INDEX_LEN;
< 
<             off = pn3->pn_offset - top;
<             ok = js_SetJumpOffset(cx, cg, pc, off);
<             if (!ok)
<                 goto out;
<             pc += JUMP_OFFSET_LEN;
<         }
<     }
< 
< out:
<     if (table)
<         JS_free(cx, table);
<     if (ok) {
<         ok = js_PopStatementCG(cx, cg);
< 
< #if JS_HAS_BLOCK_SCOPE
<         if (ok && pn->pn_right->pn_type == TOK_LEXICALSCOPE) {
<             EMIT_UINT16_IMM_OP(JSOP_LEAVEBLOCK, count);
<             cg->stackDepth -= count;
<         }
< #endif
<     }
<     return ok;
< 
< bad:
<     ok = JS_FALSE;
<     goto out;
< }
< 
< JSBool
< js_EmitFunctionScript(JSContext *cx, JSCodeGenerator *cg, JSParseNode *body)
< {
<     if (cg->treeContext.flags & TCF_FUN_IS_GENERATOR) {
<         /* JSOP_GENERATOR must be the first instruction. */
<         CG_SWITCH_TO_PROLOG(cg);
<         JS_ASSERT(CG_NEXT(cg) == CG_BASE(cg));
<         if (js_Emit1(cx, cg, JSOP_GENERATOR) < 0)
<             return JS_FALSE;
<         CG_SWITCH_TO_MAIN(cg);
<     }
< 
<     return js_EmitTree(cx, cg, body) &&
<            js_Emit1(cx, cg, JSOP_STOP) >= 0 &&
<            js_NewScriptFromCG(cx, cg);
< }
< 
< /* A macro for inlining at the top of js_EmitTree (whence it came). */
< #define UPDATE_LINE_NUMBER_NOTES(cx, cg, pn)                                  \
<     JS_BEGIN_MACRO                                                            \
<         uintN line_ = (pn)->pn_pos.begin.lineno;                              \
<         uintN delta_ = line_ - CG_CURRENT_LINE(cg);                           \
<         if (delta_ != 0) {                                                    \
<             /*                                                                \
<              * Encode any change in the current source line number by using   \
<              * either several SRC_NEWLINE notes or just one SRC_SETLINE note, \
<              * whichever consumes less space.                                 \
<              *                                                                \
<              * NB: We handle backward line number deltas (possible with for   \
<              * loops where the update part is emitted after the body, but its \
<              * line number is <= any line number in the body) here by letting \
<              * unsigned delta_ wrap to a very large number, which triggers a  \
<              * SRC_SETLINE.                                                   \
<              */                                                               \
<             CG_CURRENT_LINE(cg) = line_;                                      \
<             if (delta_ >= (uintN)(2 + ((line_ > SN_3BYTE_OFFSET_MASK)<<1))) { \
<                 if (js_NewSrcNote2(cx, cg, SRC_SETLINE, (ptrdiff_t)line_) < 0)\
<                     return JS_FALSE;                                          \
<             } else {                                                          \
<                 do {                                                          \
<                     if (js_NewSrcNote(cx, cg, SRC_NEWLINE) < 0)               \
<                         return JS_FALSE;                                      \
<                 } while (--delta_ != 0);                                      \
<             }                                                                 \
<         }                                                                     \
<     JS_END_MACRO
< 
< /* A function, so that we avoid macro-bloating all the other callsites. */
< static JSBool
< UpdateLineNumberNotes(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
< {
<     UPDATE_LINE_NUMBER_NOTES(cx, cg, pn);
<     return JS_TRUE;
< }
< 
< static JSBool
< MaybeEmitVarDecl(JSContext *cx, JSCodeGenerator *cg, JSOp prologOp,
<                  JSParseNode *pn, jsatomid *result)
< {
<     jsatomid atomIndex;
<     JSAtomListElement *ale;
< 
<     if (pn->pn_slot >= 0) {
<         atomIndex = (jsatomid) pn->pn_slot;
<     } else {
<         ale = js_IndexAtom(cx, pn->pn_atom, &cg->atomList);
<         if (!ale)
<             return JS_FALSE;
<         atomIndex = ALE_INDEX(ale);
<     }
< 
<     if (JOF_OPTYPE(pn->pn_op) == JOF_ATOM &&
<         (!(cg->treeContext.flags & TCF_IN_FUNCTION) ||
<          (cg->treeContext.flags & TCF_FUN_HEAVYWEIGHT))) {
<         /* Emit a prolog bytecode to predefine the variable. */
<         CG_SWITCH_TO_PROLOG(cg);
<         if (!UpdateLineNumberNotes(cx, cg, pn))
<             return JS_FALSE;
<         EMIT_INDEX_OP(prologOp, atomIndex);
<         CG_SWITCH_TO_MAIN(cg);
<     }
< 
<     if (result)
<         *result = atomIndex;
<     return JS_TRUE;
< }
< 
< #if JS_HAS_DESTRUCTURING
< 
< typedef JSBool
< (*DestructuringDeclEmitter)(JSContext *cx, JSCodeGenerator *cg, JSOp prologOp,
<                             JSParseNode *pn);
< 
< static JSBool
< EmitDestructuringDecl(JSContext *cx, JSCodeGenerator *cg, JSOp prologOp,
<                       JSParseNode *pn)
< {
<     JSOp decltype;
< 
<     JS_ASSERT(pn->pn_type == TOK_NAME);
<     decltype = (JSOp) ((prologOp == JSOP_NOP) ? LET_DECL : VAR_DECL);
<     if (!BindNameToSlot(cx, cg, pn, decltype))
<         return JS_FALSE;
< 
<     JS_ASSERT(pn->pn_op != JSOP_ARGUMENTS);
<     return MaybeEmitVarDecl(cx, cg, prologOp, pn, NULL);
< }
< 
< static JSBool
< EmitDestructuringDecls(JSContext *cx, JSCodeGenerator *cg, JSOp prologOp,
<                        JSParseNode *pn)
< {
<     JSParseNode *pn2, *pn3;
<     DestructuringDeclEmitter emitter;
< 
<     if (pn->pn_type == TOK_RB) {
<         for (pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) {
<             if (pn2->pn_type == TOK_COMMA)
<                 continue;
<             emitter = (pn2->pn_type == TOK_NAME)
<                       ? EmitDestructuringDecl
<                       : EmitDestructuringDecls;
<             if (!emitter(cx, cg, prologOp, pn2))
<                 return JS_FALSE;
<         }
<     } else {
<         JS_ASSERT(pn->pn_type == TOK_RC);
<         for (pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) {
<             pn3 = pn2->pn_right;
<             emitter = (pn3->pn_type == TOK_NAME)
<                       ? EmitDestructuringDecl
<                       : EmitDestructuringDecls;
<             if (!emitter(cx, cg, prologOp, pn3))
<                 return JS_FALSE;
<         }
<     }
<     return JS_TRUE;
< }
< 
< static JSBool
< EmitDestructuringOpsHelper(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn);
< 
< static JSBool
< EmitDestructuringLHS(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
< {
<     jsuint slot;
< 
<     /* Skip any parenthesization. */
<     while (pn->pn_type == TOK_RP)
<         pn = pn->pn_kid;
< 
<     /*
<      * Now emit the lvalue opcode sequence.  If the lvalue is a nested
<      * destructuring initialiser-form, call ourselves to handle it, then
<      * pop the matched value.  Otherwise emit an lvalue bytecode sequence
<      * ending with a JSOP_ENUMELEM or equivalent op.
<      */
<     if (pn->pn_type == TOK_RB || pn->pn_type == TOK_RC) {
<         if (!EmitDestructuringOpsHelper(cx, cg, pn))
<             return JS_FALSE;
<         if (js_Emit1(cx, cg, JSOP_POP) < 0)
<             return JS_FALSE;
<     } else {
<         if (pn->pn_type == TOK_NAME && !BindNameToSlot(cx, cg, pn, 0))
<             return JS_FALSE;
< 
<         switch (pn->pn_op) {
<           case JSOP_SETNAME:
<             /*
<              * NB: pn is a PN_NAME node, not a PN_BINARY.  Nevertheless,
<              * we want to emit JSOP_ENUMELEM, which has format JOF_ELEM.
<              * So here and for JSOP_ENUMCONSTELEM, we use EmitElemOp.
<              */
<             if (!EmitElemOp(cx, pn, JSOP_ENUMELEM, cg))
<                 return JS_FALSE;
<             break;
< 
<           case JSOP_SETCONST:
<             if (!EmitElemOp(cx, pn, JSOP_ENUMCONSTELEM, cg))
<                 return JS_FALSE;
<             break;
< 
<           case JSOP_SETLOCAL:
<             slot = (jsuint) pn->pn_slot;
<             EMIT_UINT16_IMM_OP(JSOP_SETLOCALPOP, slot);
<             break;
< 
<           case JSOP_SETARG:
<           case JSOP_SETVAR:
<           case JSOP_SETGVAR:
<             slot = (jsuint) pn->pn_slot;
<             EMIT_UINT16_IMM_OP(PN_OP(pn), slot);
<             if (js_Emit1(cx, cg, JSOP_POP) < 0)
<                 return JS_FALSE;
<             break;
< 
<           default:
< #if JS_HAS_LVALUE_RETURN || JS_HAS_XML_SUPPORT
<           {
<             ptrdiff_t top;
< 
<             top = CG_OFFSET(cg);
<             if (!js_EmitTree(cx, cg, pn))
<                 return JS_FALSE;
<             if (js_NewSrcNote2(cx, cg, SRC_PCBASE, CG_OFFSET(cg) - top) < 0)
<                 return JS_FALSE;
<             if (js_Emit1(cx, cg, JSOP_ENUMELEM) < 0)
<                 return JS_FALSE;
<             break;
<           }
< #endif
<           case JSOP_ENUMELEM:
<             JS_ASSERT(0);
<         }
<     }
< 
<     return JS_TRUE;
< }
< 
< /*
<  * Recursive helper for EmitDestructuringOps.
<  *
<  * Given a value to destructure on the stack, walk over an object or array
<  * initialiser at pn, emitting bytecodes to match property values and store
<  * them in the lvalues identified by the matched property names.
<  */
< static JSBool
< EmitDestructuringOpsHelper(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
< {
<     jsuint index;
<     JSParseNode *pn2, *pn3;
<     JSBool doElemOp;
< 
< #ifdef DEBUG
<     intN stackDepth = cg->stackDepth;
<     JS_ASSERT(stackDepth != 0);
<     JS_ASSERT(pn->pn_arity == PN_LIST);
<     JS_ASSERT(pn->pn_type == TOK_RB || pn->pn_type == TOK_RC);
< #endif
< 
<     if (pn->pn_count == 0) {
<         /* Emit a DUP;POP sequence for the decompiler. */
<         return js_Emit1(cx, cg, JSOP_DUP) >= 0 &&
<                js_Emit1(cx, cg, JSOP_POP) >= 0;
<     }
< 
<     index = 0;
<     for (pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) {
<         /*
<          * Duplicate the value being destructured to use as a reference base.
<          */
<         if (js_Emit1(cx, cg, JSOP_DUP) < 0)
<             return JS_FALSE;
< 
<         /*
<          * Now push the property name currently being matched, which is either
<          * the array initialiser's current index, or the current property name
<          * "label" on the left of a colon in the object initialiser.  Set pn3
<          * to the lvalue node, which is in the value-initializing position.
<          */
<         doElemOp = JS_TRUE;
<         if (pn->pn_type == TOK_RB) {
<             if (!EmitNumberOp(cx, index, cg))
<                 return JS_FALSE;
<             pn3 = pn2;
<         } else {
<             JS_ASSERT(pn->pn_type == TOK_RC);
<             JS_ASSERT(pn2->pn_type == TOK_COLON);
<             pn3 = pn2->pn_left;
<             if (pn3->pn_type == TOK_NUMBER) {
<                 /*
<                  * If we are emitting an object destructuring initialiser,
<                  * annotate the index op with SRC_INITPROP so we know we are
<                  * not decompiling an array initialiser.
<                  */
<                 if (js_NewSrcNote(cx, cg, SRC_INITPROP) < 0)
<                     return JS_FALSE;
<                 if (!EmitNumberOp(cx, pn3->pn_dval, cg))
<                     return JS_FALSE;
<             } else {
<                 JS_ASSERT(pn3->pn_type == TOK_STRING ||
<                           pn3->pn_type == TOK_NAME);
<                 if (!EmitAtomOp(cx, pn3, JSOP_GETPROP, cg))
<                     return JS_FALSE;
<                 doElemOp = JS_FALSE;
<             }
<             pn3 = pn2->pn_right;
<         }
< 
<         if (doElemOp) {
<             /*
<              * Ok, get the value of the matching property name.  This leaves
<              * that value on top of the value being destructured, so the stack
<              * is one deeper than when we started.
<              */
<             if (js_Emit1(cx, cg, JSOP_GETELEM) < 0)
<                 return JS_FALSE;
<             JS_ASSERT(cg->stackDepth == stackDepth + 1);
<         }
< 
<         /* Nullary comma node makes a hole in the array destructurer. */
<         if (pn3->pn_type == TOK_COMMA && pn3->pn_arity == PN_NULLARY) {
<             JS_ASSERT(pn->pn_type == TOK_RB);
<             JS_ASSERT(pn2 == pn3);
<             if (js_Emit1(cx, cg, JSOP_POP) < 0)
<                 return JS_FALSE;
<         } else {
<             if (!EmitDestructuringLHS(cx, cg, pn3))
<                 return JS_FALSE;
<         }
< 
<         JS_ASSERT(cg->stackDepth == stackDepth);
<         ++index;
<     }
< 
<     return JS_TRUE;
< }
< 
< static ptrdiff_t
< OpToDeclType(JSOp op)
< {
<     switch (op) {
<       case JSOP_NOP:
<         return SRC_DECL_LET;
<       case JSOP_DEFCONST:
<         return SRC_DECL_CONST;
<       case JSOP_DEFVAR:
<         return SRC_DECL_VAR;
<       default:
<         return SRC_DECL_NONE;
<     }
< }
< 
< static JSBool
< EmitDestructuringOps(JSContext *cx, JSCodeGenerator *cg, JSOp declOp,
<                      JSParseNode *pn)
< {
<     /*
<      * If we're called from a variable declaration, help the decompiler by
<      * annotating the first JSOP_DUP that EmitDestructuringOpsHelper emits.
<      * If the destructuring initialiser is empty, our helper will emit a
<      * JSOP_DUP followed by a JSOP_POP for the decompiler.
<      */
<     if (js_NewSrcNote2(cx, cg, SRC_DESTRUCT, OpToDeclType(declOp)) < 0)
<         return JS_FALSE;
< 
<     /*
<      * Call our recursive helper to emit the destructuring assignments and
<      * related stack manipulations.
<      */
<     return EmitDestructuringOpsHelper(cx, cg, pn);
< }
< 
< static JSBool
< EmitGroupAssignment(JSContext *cx, JSCodeGenerator *cg, JSOp declOp,
<                     JSParseNode *lhs, JSParseNode *rhs)
< {
<     jsuint depth, limit, slot, nslots;
<     JSParseNode *pn;
< 
<     depth = limit = (uintN) cg->stackDepth;
<     for (pn = rhs->pn_head; pn; pn = pn->pn_next) {
<         if (limit == JS_BIT(16)) {
<             js_ReportCompileErrorNumber(cx, CG_TS(cg), rhs, JSREPORT_ERROR,
<                                         JSMSG_ARRAY_INIT_TOO_BIG);
<             return JS_FALSE;
<         }
< 
<         if (pn->pn_type == TOK_COMMA) {
<             if (js_Emit1(cx, cg, JSOP_PUSH) < 0)
<                 return JS_FALSE;
<         } else {
<             JS_ASSERT(pn->pn_type != TOK_DEFSHARP);
<             if (!js_EmitTree(cx, cg, pn))
<                 return JS_FALSE;
<         }
<         ++limit;
<     }
< 
<     if (js_NewSrcNote2(cx, cg, SRC_GROUPASSIGN, OpToDeclType(declOp)) < 0)
<         return JS_FALSE;
< 
<     slot = depth;
<     for (pn = lhs->pn_head; pn; pn = pn->pn_next) {
<         if (slot < limit) {
<             EMIT_UINT16_IMM_OP(JSOP_GETLOCAL, slot);
<         } else {
<             if (js_Emit1(cx, cg, JSOP_PUSH) < 0)
<                 return JS_FALSE;
<         }
<         if (pn->pn_type == TOK_COMMA && pn->pn_arity == PN_NULLARY) {
<             if (js_Emit1(cx, cg, JSOP_POP) < 0)
<                 return JS_FALSE;
<         } else {
<             if (!EmitDestructuringLHS(cx, cg, pn))
<                 return JS_FALSE;
<         }
<         ++slot;
<     }
< 
<     nslots = limit - depth;
<     EMIT_UINT16_IMM_OP(JSOP_POPN, nslots);
<     cg->stackDepth = (uintN) depth;
<     return JS_TRUE;
< }
< 
< /*
<  * Helper called with pop out param initialized to a JSOP_POP* opcode.  If we
<  * can emit a group assignment sequence, which results in 0 stack depth delta,
<  * we set *pop to JSOP_NOP so callers can veto emitting pn followed by a pop.
<  */
< static JSBool
< MaybeEmitGroupAssignment(JSContext *cx, JSCodeGenerator *cg, JSOp declOp,
<                          JSParseNode *pn, JSOp *pop)
< {
<     JSParseNode *lhs, *rhs;
< 
<     JS_ASSERT(pn->pn_type == TOK_ASSIGN);
<     JS_ASSERT(*pop == JSOP_POP || *pop == JSOP_POPV);
<     lhs = pn->pn_left;
<     rhs = pn->pn_right;
<     if (lhs->pn_type == TOK_RB && rhs->pn_type == TOK_RB &&
<         lhs->pn_count <= rhs->pn_count &&
<         (rhs->pn_count == 0 ||
<          rhs->pn_head->pn_type != TOK_DEFSHARP)) {
<         if (!EmitGroupAssignment(cx, cg, declOp, lhs, rhs))
<             return JS_FALSE;
<         *pop = JSOP_NOP;
<     }
<     return JS_TRUE;
< }
< 
< #endif /* JS_HAS_DESTRUCTURING */
< 
< static JSBool
< EmitVariables(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn,
<               JSBool inLetHead, ptrdiff_t *headNoteIndex)
< {
<     JSTreeContext *tc;
<     JSBool let, forInVar;
< #if JS_HAS_BLOCK_SCOPE
<     JSBool forInLet, popScope;
<     JSStmtInfo *stmt, *scopeStmt;
< #endif
<     ptrdiff_t off, noteIndex, tmp;
<     JSParseNode *pn2, *pn3;
<     JSOp op;
<     jsatomid atomIndex;
<     uintN oldflags;
< 
<     /* Default in case of JS_HAS_BLOCK_SCOPE early return, below. */
<     *headNoteIndex = -1;
< 
<     /*
<      * Let blocks and expressions have a parenthesized head in which the new
<      * scope is not yet open. Initializer evaluation uses the parent node's
<      * lexical scope. If popScope is true below, then we hide the top lexical
<      * block from any calls to BindNameToSlot hiding in pn2->pn_expr so that
<      * it won't find any names in the new let block.
<      *
<      * The same goes for let declarations in the head of any kind of for loop.
<      * Unlike a let declaration 'let x = i' within a block, where x is hoisted
<      * to the start of the block, a 'for (let x = i...) ...' loop evaluates i
<      * in the containing scope, and puts x in the loop body's scope.
<      */
<     tc = &cg->treeContext;
<     let = (pn->pn_op == JSOP_NOP);
<     forInVar = (pn->pn_extra & PNX_FORINVAR) != 0;
< #if JS_HAS_BLOCK_SCOPE
<     forInLet = let && forInVar;
<     popScope = (inLetHead || (let && (tc->flags & TCF_IN_FOR_INIT)));
<     JS_ASSERT(!popScope || let);
< #endif
< 
<     off = noteIndex = -1;
<     for (pn2 = pn->pn_head; ; pn2 = pn2->pn_next) {
< #if JS_HAS_DESTRUCTURING
<         if (pn2->pn_type != TOK_NAME) {
<             if (pn2->pn_type == TOK_RB || pn2->pn_type == TOK_RC) {
<                 /*
<                  * Emit variable binding ops, but not destructuring ops.
<                  * The parser (see Variables, jsparse.c) has ensured that
<                  * our caller will be the TOK_FOR/TOK_IN case in js_EmitTree,
<                  * and that case will emit the destructuring code only after
<                  * emitting an enumerating opcode and a branch that tests
<                  * whether the enumeration ended.
<                  */
<                 JS_ASSERT(forInVar);
<                 JS_ASSERT(pn->pn_count == 1);
<                 if (!EmitDestructuringDecls(cx, cg, PN_OP(pn), pn2))
<                     return JS_FALSE;
<                 break;
<             }
< 
<             /*
<              * A destructuring initialiser assignment preceded by var is
<              * always evaluated promptly, even if it is to the left of 'in'
<              * in a for-in loop.  As with 'for (var x = i in o)...', this
<              * will cause the entire 'var [a, b] = i' to be hoisted out of
<              * the head of the loop.
<              */
<             JS_ASSERT(pn2->pn_type == TOK_ASSIGN);
<             if (pn->pn_count == 1 && !forInLet) {
<                 /*
<                  * If this is the only destructuring assignment in the list,
<                  * try to optimize to a group assignment.  If we're in a let
<                  * head, pass JSOP_POP rather than the pseudo-prolog JSOP_NOP
<                  * in pn->pn_op, to suppress a second (and misplaced) 'let'.
<                  */
<                 JS_ASSERT(noteIndex < 0 && !pn2->pn_next);
<                 op = JSOP_POP;
<                 if (!MaybeEmitGroupAssignment(cx, cg,
<                                               inLetHead ? JSOP_POP :
<                                               PN_OP(pn),
<                                               pn2, &op)) {
<                     return JS_FALSE;
<                 }
<                 if (op == JSOP_NOP) {
<                     pn->pn_extra = (pn->pn_extra & ~PNX_POPVAR) | PNX_GROUPINIT;
<                     break;
<                 }
<             }
< 
<             pn3 = pn2->pn_left;
<             if (!EmitDestructuringDecls(cx, cg, PN_OP(pn), pn3))
<                 return JS_FALSE;
< 
< #if JS_HAS_BLOCK_SCOPE
<             /*
<              * If this is a 'for (let [x, y] = i in o) ...' let declaration,
<              * throw away i if it is a useless expression.
<              */
<             if (forInLet) {
<                 JSBool useful = JS_FALSE;
< 
<                 JS_ASSERT(pn->pn_count == 1);
<                 if (!CheckSideEffects(cx, cg, pn2->pn_right, &useful))
<                     return JS_FALSE;
<                 if (!useful)
<                     return JS_TRUE;
<             }
< #endif
< 
<             if (!js_EmitTree(cx, cg, pn2->pn_right))
<                 return JS_FALSE;
< 
< #if JS_HAS_BLOCK_SCOPE
<             /*
<              * The expression i in 'for (let [x, y] = i in o) ...', which is
<              * pn2->pn_right above, appears to have side effects.  We've just
<              * emitted code to evaluate i, but we must not destructure i yet.
<              * Let the TOK_FOR: code in js_EmitTree do the destructuring to
<              * emit the right combination of source notes and bytecode for the
<              * decompiler.
<              *
<              * This has the effect of hoisting the evaluation of i out of the
<              * for-in loop, without hoisting the let variables, which must of
<              * course be scoped by the loop.  Set PNX_POPVAR to cause JSOP_POP
<              * to be emitted, just before returning from this function.
<              */
<             if (forInVar) {
<                 pn->pn_extra |= PNX_POPVAR;
<                 if (forInLet)
<                     break;
<             }
< #endif
< 
<             /*
<              * Veto pn->pn_op if inLetHead to avoid emitting a SRC_DESTRUCT
<              * that's redundant with respect to the SRC_DECL/SRC_DECL_LET that
<              * we will emit at the bottom of this function.
<              */
<             if (!EmitDestructuringOps(cx, cg,
<                                       inLetHead ? JSOP_POP : PN_OP(pn),
<                                       pn3)) {
<                 return JS_FALSE;
<             }
<             goto emit_note_pop;
<         }
< #else
<         JS_ASSERT(pn2->pn_type == TOK_NAME);
< #endif
< 
<         if (!BindNameToSlot(cx, cg, pn2, let ? LET_DECL : VAR_DECL))
<             return JS_FALSE;
<         JS_ASSERT(pn2->pn_slot >= 0 || !let);
< 
<         op = PN_OP(pn2);
<         if (op == JSOP_ARGUMENTS) {
<             /* JSOP_ARGUMENTS => no initializer */
<             JS_ASSERT(!pn2->pn_expr && !let);
<             pn3 = NULL;
< #ifdef __GNUC__
<             atomIndex = 0;            /* quell GCC overwarning */
< #endif
<         } else {
<             if (!MaybeEmitVarDecl(cx, cg, PN_OP(pn), pn2, &atomIndex))
<                 return JS_FALSE;
< 
<             pn3 = pn2->pn_expr;
<             if (pn3) {
< #if JS_HAS_BLOCK_SCOPE
<                 /*
<                  * If this is a 'for (let x = i in o) ...' let declaration,
<                  * throw away i if it is a useless expression.
<                  */
<                 if (forInLet) {
<                     JSBool useful = JS_FALSE;
< 
<                     JS_ASSERT(pn->pn_count == 1);
<                     if (!CheckSideEffects(cx, cg, pn3, &useful))
<                         return JS_FALSE;
<                     if (!useful)
<                         return JS_TRUE;
<                 }
< #endif
< 
<                 if (op == JSOP_SETNAME) {
<                     JS_ASSERT(!let);
<                     EMIT_INDEX_OP(JSOP_BINDNAME, atomIndex);
<                 }
<                 if (pn->pn_op == JSOP_DEFCONST &&
<                     !js_DefineCompileTimeConstant(cx, cg, pn2->pn_atom,
<                                                   pn3)) {
<                     return JS_FALSE;
<                 }
< 
< #if JS_HAS_BLOCK_SCOPE
<                 /* Evaluate expr in the outer lexical scope if requested. */
<                 if (popScope) {
<                     stmt = tc->topStmt;
<                     scopeStmt = tc->topScopeStmt;
< 
<                     tc->topStmt = stmt->down;
<                     tc->topScopeStmt = scopeStmt->downScope;
<                 }
< #ifdef __GNUC__
<                 else {
<                     stmt = scopeStmt = NULL;    /* quell GCC overwarning */
<                 }
< #endif
< #endif
< 
<                 oldflags = cg->treeContext.flags;
<                 cg->treeContext.flags &= ~TCF_IN_FOR_INIT;
<                 if (!js_EmitTree(cx, cg, pn3))
<                     return JS_FALSE;
<                 cg->treeContext.flags |= oldflags & TCF_IN_FOR_INIT;
< 
< #if JS_HAS_BLOCK_SCOPE
<                 if (popScope) {
<                     tc->topStmt = stmt;
<                     tc->topScopeStmt = scopeStmt;
<                 }
< #endif
<             }
<         }
< 
<         /*
<          * 'for (var x in o) ...' and 'for (var x = i in o) ...' call the
<          * TOK_VAR case, but only the initialized case (a strange one that
<          * falls out of ECMA-262's grammar) wants to run past this point.
<          * Both cases must conditionally emit a JSOP_DEFVAR, above.  Note
<          * that the parser error-checks to ensure that pn->pn_count is 1.
<          *
<          * 'for (let x = i in o) ...' must evaluate i before the loop, and
<          * subject it to useless expression elimination.  The variable list
<          * in pn is a single let declaration if pn_op == JSOP_NOP.  We test
<          * the let local in order to break early in this case, as well as in
<          * the 'for (var x in o)' case.
<          *
<          * XXX Narcissus keeps track of variable declarations in the node
<          * for the script being compiled, so there's no need to share any
<          * conditional prolog code generation there.  We could do likewise,
<          * but it's a big change, requiring extra allocation, so probably
<          * not worth the trouble for SpiderMonkey.
<          */
<         JS_ASSERT(pn3 == pn2->pn_expr);
<         if (forInVar && (!pn3 || let)) {
<             JS_ASSERT(pn->pn_count == 1);
<             break;
<         }
< 
<         if (pn2 == pn->pn_head &&
<             !inLetHead &&
<             js_NewSrcNote2(cx, cg, SRC_DECL,
<                            (pn->pn_op == JSOP_DEFCONST)
<                            ? SRC_DECL_CONST
<                            : (pn->pn_op == JSOP_DEFVAR)
<                            ? SRC_DECL_VAR
<                            : SRC_DECL_LET) < 0) {
<             return JS_FALSE;
<         }
<         if (op == JSOP_ARGUMENTS) {
<             if (js_Emit1(cx, cg, op) < 0)
<                 return JS_FALSE;
<         } else if (pn2->pn_slot >= 0) {
<             EMIT_UINT16_IMM_OP(op, atomIndex);
<         } else {
<             EMIT_INDEX_OP(op, atomIndex);
<         }
< 
< #if JS_HAS_DESTRUCTURING
<     emit_note_pop:
< #endif
<         tmp = CG_OFFSET(cg);
<         if (noteIndex >= 0) {
<             if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 0, tmp-off))
<                 return JS_FALSE;
<         }
<         if (!pn2->pn_next)
<             break;
<         off = tmp;
<         noteIndex = js_NewSrcNote2(cx, cg, SRC_PCDELTA, 0);
<         if (noteIndex < 0 || js_Emit1(cx, cg, JSOP_POP) < 0)
<             return JS_FALSE;
<     }
< 
<     /* If this is a let head, emit and return a srcnote on the pop. */
<     if (inLetHead) {
<         *headNoteIndex = js_NewSrcNote(cx, cg, SRC_DECL);
<         if (*headNoteIndex < 0)
<             return JS_FALSE;
<         if (!(pn->pn_extra & PNX_POPVAR))
<             return js_Emit1(cx, cg, JSOP_NOP) >= 0;
<     }
< 
<     return !(pn->pn_extra & PNX_POPVAR) || js_Emit1(cx, cg, JSOP_POP) >= 0;
< }
< 
< #if defined DEBUG_brendanXXX || defined DEBUG_mrbkap
< static JSBool
< GettableNoteForNextOp(JSCodeGenerator *cg)
< {
<     ptrdiff_t offset, target;
<     jssrcnote *sn, *end;
< 
<     offset = 0;
<     target = CG_OFFSET(cg);
<     for (sn = CG_NOTES(cg), end = sn + CG_NOTE_COUNT(cg); sn < end;
<          sn = SN_NEXT(sn)) {
<         if (offset == target && SN_IS_GETTABLE(sn))
<             return JS_TRUE;
<         offset += SN_DELTA(sn);
<     }
<     return JS_FALSE;
< }
< #endif
< 
< /* Top-level named functions need a nop for decompilation. */
< static JSBool
< EmitFunctionDefNop(JSContext *cx, JSCodeGenerator *cg, uintN index)
< {
<     return js_NewSrcNote2(cx, cg, SRC_FUNCDEF, (ptrdiff_t)index) >= 0 &&
<            js_Emit1(cx, cg, JSOP_NOP) >= 0;
< }
< 
< JSBool
< js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
< {
<     JSBool ok, useful, wantval;
<     JSStmtInfo *stmt, stmtInfo;
<     ptrdiff_t top, off, tmp, beq, jmp;
<     JSParseNode *pn2, *pn3;
<     JSAtom *atom;
<     JSAtomListElement *ale;
<     jsatomid atomIndex;
<     uintN index;
<     ptrdiff_t noteIndex;
<     JSSrcNoteType noteType;
<     jsbytecode *pc;
<     JSOp op;
<     JSTokenType type;
<     uint32 argc;
< 
<     JS_CHECK_RECURSION(cx, return JS_FALSE);
< 
<     ok = JS_TRUE;
<     cg->emitLevel++;
<     pn->pn_offset = top = CG_OFFSET(cg);
< 
<     /* Emit notes to tell the current bytecode's source line number. */
<     UPDATE_LINE_NUMBER_NOTES(cx, cg, pn);
---
>     /* Emit notes to tell the current bytecode's source line number. */
>     UPDATE_LINENO_NOTES(cx, cg, pn);
3976d1980
<         JSFunction *fun;
3979,4002c1983
<         uintN slot;
< 
< #if JS_HAS_XML_SUPPORT
<         if (pn->pn_arity == PN_NULLARY) {
<             if (js_Emit1(cx, cg, JSOP_GETFUNNS) < 0)
<                 return JS_FALSE;
<             break;
<         }
< #endif
< 
<         fun = GET_FUNCTION_PRIVATE(cx, pn->pn_funpob->object);
<         if (fun->u.i.script) {
<             /*
<              * This second pass is needed to emit JSOP_NOP with a source note
<              * for the already-emitted function. See comments in the TOK_LC
<              * case.
<              */
<             JS_ASSERT(pn->pn_op == JSOP_NOP);
<             JS_ASSERT(cg->treeContext.flags & TCF_IN_FUNCTION);
<             JS_ASSERT(pn->pn_index != (uint32) -1);
<             if (!EmitFunctionDefNop(cx, cg, pn->pn_index))
<                 return JS_FALSE;
<             break;
<         }
---
>         JSFunction *fun;
4005,4006c1986,1987
<         cg2mark = JS_ARENA_MARK(cg->codePool);
<         JS_ARENA_ALLOCATE_TYPE(cg2, JSCodeGenerator, cg->codePool);
---
>         cg2mark = JS_ARENA_MARK(&cx->tempPool);
>         JS_ARENA_ALLOCATE_TYPE(cg2, JSCodeGenerator, &cx->tempPool);
4008c1989
<             js_ReportOutOfScriptQuota(cx);
---
>             JS_ReportOutOfMemory(cx);
4011,4028c1992,1995
<         js_InitCodeGenerator(cx, cg2, cg->treeContext.parseContext,
<                              cg->codePool, cg->notePool,
<                              pn->pn_pos.begin.lineno);
<         cg2->treeContext.flags = (uint16) (pn->pn_flags | TCF_IN_FUNCTION);
<         cg2->treeContext.maxScopeDepth = pn->pn_sclen;
<         cg2->treeContext.fun = fun;
<         cg2->parent = cg;
<         if (!js_EmitFunctionScript(cx, cg2, pn->pn_body)) {
<             pn = NULL;
<         } else {
<             /*
<              * We need an activation object if an inner peeks out, or if such
<              * inner-peeking caused one of our inners to become heavyweight.
<              */
<             if (cg2->treeContext.flags &
<                 (TCF_FUN_USES_NONLOCALS | TCF_FUN_HEAVYWEIGHT)) {
<                 cg->treeContext.flags |= TCF_FUN_HEAVYWEIGHT;
<             }
---
>         if (!js_InitCodeGenerator(cx, cg2, cg->filename,
>                                   pn->pn_pos.begin.lineno,
>                                   cg->principals)) {
>             return JS_FALSE;
4030,4033c1997,2000
<         js_FinishCodeGenerator(cx, cg2);
<         JS_ARENA_RELEASE(cg->codePool, cg2mark);
<         cg2 = NULL;
<         if (!pn)
---
>         cg2->treeContext.flags = pn->pn_flags | TCF_IN_FUNCTION;
>         cg2->treeContext.tryCount = pn->pn_tryCount;
>         fun = pn->pn_fun;
>         if (!js_EmitFunctionBody(cx, cg2, pn->pn_body, fun))
4035a2003,2013
>         /*
>          * We need an activation object if an inner peeks out, or if such
>          * inner-peeking caused one of our inners to become heavyweight.
>          */
>         if (cg2->treeContext.flags &
>             (TCF_FUN_USES_NONLOCALS | TCF_FUN_HEAVYWEIGHT)) {
>             cg->treeContext.flags |= TCF_FUN_HEAVYWEIGHT;
>         }
>         js_FinishCodeGenerator(cx, cg2);
>         JS_ARENA_RELEASE(&cx->tempPool, cg2mark);
> 
4037c2015,2021
<         index = IndexParsedObject(pn->pn_funpob, &cg->objectList);
---
>         atom = js_AtomizeObject(cx, fun->object, 0);
>         if (!atom)
>             return JS_FALSE;
>         ale = js_IndexAtom(cx, atom, &cg->atomList);
>         if (!ale)
>             return JS_FALSE;
>         atomIndex = ALE_INDEX(ale);
4038a2023
> #if JS_HAS_LEXICAL_CLOSURE
4041,4045c2026
<             if ((pn->pn_flags & TCF_GENEXP_LAMBDA) &&
<                 js_NewSrcNote(cx, cg, SRC_GENEXP) < 0) {
<                 return JS_FALSE;
<             }
<             EMIT_INDEX_OP(PN_OP(pn), index);
---
>             EMIT_ATOM_INDEX_OP(pn->pn_op, atomIndex);
4047a2029,2036
> #endif
> 
>         /* Top-level named functions need a nop for decompilation. */
>         noteIndex = js_NewSrcNote2(cx, cg, SRC_FUNCDEF, (ptrdiff_t)atomIndex);
>         if (noteIndex < 0 ||
>             js_Emit1(cx, cg, JSOP_NOP) < 0) {
>             return JS_FALSE;
>         }
4050,4056c2039,2040
<          * For a script we emit the code as we parse. Thus the bytecode for
<          * top-level functions should go in the prolog to predefine their
<          * names in the variable object before the already-generated main code
<          * is executed. This extra work for top-level scripts is not necessary
<          * when we emit the code for a function. It is fully parsed prior to
<          * invocation of the emitter and calls to js_EmitTree for function
<          * definitions can be scheduled before generating the rest of code.
---
>          * Top-levels also need a prolog op to predefine their names in the
>          * variable object, or if local, to fill their stack slots.
4058,4068c2042,2057
<         if (!(cg->treeContext.flags & TCF_IN_FUNCTION)) {
<             CG_SWITCH_TO_PROLOG(cg);
< 
<             /*
<              * Emit JSOP_CLOSURE for eval code to do fewer checks when
<              * instantiating top-level functions in the non-eval case.
<              */
<             JS_ASSERT(!cg->treeContext.topStmt);
<             op = (cx->fp->flags & JSFRAME_EVAL) ? JSOP_CLOSURE : JSOP_DEFFUN;
<             EMIT_INDEX_OP(op, index);
<             CG_SWITCH_TO_MAIN(cg);
---
>         CG_SWITCH_TO_PROLOG(cg);
> #if JS_HAS_LEXICAL_CLOSURE
>         if (cg->treeContext.flags & TCF_IN_FUNCTION) {
>             JSObject *obj, *pobj;
>             JSScopeProperty *sprop;
>             uintN slot;
>             jsbytecode *pc;
> 
>             obj = OBJ_GET_PARENT(cx, fun->object);
>             if (!js_LookupProperty(cx, obj, (jsid)fun->atom, &pobj,
>                                    (JSProperty **)&sprop)) {
>                 return JS_FALSE;
>             }
>             JS_ASSERT(sprop && pobj == obj);
>             slot = sprop->shortid;
>             OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop);
4070,4071c2059,2061
<             /* Emit NOP for the decompiler. */
<             if (!EmitFunctionDefNop(cx, cg, index))
---
>             /* Emit [JSOP_DEFLOCALFUN, local variable slot, atomIndex]. */
>             off = js_EmitN(cx, cg, JSOP_DEFLOCALFUN, VARNO_LEN+ATOM_INDEX_LEN);
>             if (off < 0)
4073,4075c2063,2067
<         } else {
< #ifdef DEBUG
<             JSLocalKind localKind =
---
>             pc = CG_CODE(cg, off);
>             SET_VARNO(pc, slot);
>             pc += VARNO_LEN;
>             SET_ATOM_INDEX(pc, atomIndex);
>         } else
4077,4083c2069,2071
<                 js_LookupLocal(cx, cg->treeContext.fun, fun->atom, &slot);
<             JS_ASSERT(localKind == JSLOCAL_VAR || localKind == JSLOCAL_CONST);
<             JS_ASSERT(pn->pn_index == (uint32) -1);
<             pn->pn_index = index;
<             if (!EmitSlotIndexOp(cx, JSOP_DEFLOCALFUN, slot, index, cg))
<                 return JS_FALSE;
<         }
---
>             EMIT_ATOM_INDEX_OP(JSOP_DEFFUN, atomIndex);
>         CG_SWITCH_TO_MAIN(cg);
> 
4106c2094
<                 EMIT_INDEX_OP(JSOP_EXPORTNAME, ALE_INDEX(ale));
---
>                 EMIT_ATOM_INDEX_OP(JSOP_EXPORTNAME, ALE_INDEX(ale));
4134d2121
<         top = CG_OFFSET(cg);
4136c2123,2124
<             js_PushStatement(&cg->treeContext, &stmtInfo, STMT_IF, top);
---
>             js_PushStatement(&cg->treeContext, &stmtInfo, STMT_IF,
>                              CG_OFFSET(cg));
4142,4145c2130
<              * to help the decompiler.  Actually, we need two offsets, one for
<              * decompiling any else clause and the second for decompiling an
<              * else-if chain without bracing, overindenting, or incorrectly
<              * scoping let declarations.
---
>              * to help the decompiler.
4149d2133
<             stmtInfo.update = top;
4152,4153d2135
<             if (!js_SetSrcNoteOffset(cx, cg, noteIndex, 1, top - jmp))
<                 return JS_FALSE;
4207a2190
> #if JS_HAS_SWITCH_STATEMENT
4209,4211c2192,2343
<         /* Out of line to avoid bloating js_EmitTree's stack frame size. */
<         ok = EmitSwitch(cx, cg, pn, &stmtInfo);
<         break;
---
>       {
>         JSOp switchop;
>         uint32 ncases, tablen = 0;
>         jsint i, low, high;
>         jsdouble d;
>         size_t switchsize, tablesize;
>         JSParseNode **table;
>         jsbytecode *pc;
>         JSBool hasDefault = JS_FALSE;
>         ptrdiff_t defaultOffset = -1;
> 
>         /* Try for most optimal, fall back if not dense ints, and per ECMAv2. */
>         switchop = JSOP_TABLESWITCH;
> 
>         /* Emit code for the discriminant first. */
>         if (!js_EmitTree(cx, cg, pn->pn_kid1))
>             return JS_FALSE;
> 
>         /* Switch bytecodes run from here till end of final case. */
>         top = CG_OFFSET(cg);
>         js_PushStatement(&cg->treeContext, &stmtInfo, STMT_SWITCH, top);
> 
>         pn2 = pn->pn_kid2;
>         ncases = pn2->pn_count;
> 
>         if (ncases == 0 ||
>             (ncases == 1 &&
>              (hasDefault = (pn2->pn_head->pn_type == TOK_DEFAULT)))) {
>             ncases = 0;
>             low = 0;
>             high = -1;
>         } else {
> #define INTMAP_LENGTH   256
>             jsbitmap intmap_space[INTMAP_LENGTH];
>             jsbitmap *intmap = NULL;
>             int32 intmap_bitlen = 0;
> 
>             low  = JSVAL_INT_MAX;
>             high = JSVAL_INT_MIN;
> 
>             for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {
>                 if (pn3->pn_type == TOK_DEFAULT) {
>                     hasDefault = JS_TRUE;
>                     ncases--;   /* one of the "cases" was the default */
>                     continue;
>                 }
> 
>                 JS_ASSERT(pn3->pn_type == TOK_CASE);
>                 if (switchop == JSOP_CONDSWITCH)
>                     continue;
> 
>                 pn4 = pn3->pn_left;
>                 switch (pn4->pn_type) {
>                   case TOK_NUMBER:
>                     d = pn4->pn_dval;
>                     if (JSDOUBLE_IS_INT(d, i) && INT_FITS_IN_JSVAL(i)) {
>                         pn3->pn_val = INT_TO_JSVAL(i);
>                     } else {
>                         atom = js_AtomizeDouble(cx, d, 0);
>                         if (!atom) {
>                             ok = JS_FALSE;
>                             goto release;
>                         }
>                         pn3->pn_val = ATOM_KEY(atom);
>                     }
>                     break;
>                   case TOK_STRING:
>                     pn3->pn_val = ATOM_KEY(pn4->pn_atom);
>                     break;
>                   case TOK_PRIMARY:
>                     if (pn4->pn_op == JSOP_TRUE) {
>                         pn3->pn_val = JSVAL_TRUE;
>                         break;
>                     }
>                     if (pn4->pn_op == JSOP_FALSE) {
>                         pn3->pn_val = JSVAL_FALSE;
>                         break;
>                     }
>                     /* FALL THROUGH */
>                   default:
>                     switchop = JSOP_CONDSWITCH;
>                     continue;
>                 }
> 
>                 JS_ASSERT(JSVAL_IS_NUMBER(pn3->pn_val) ||
>                           JSVAL_IS_STRING(pn3->pn_val) ||
>                           JSVAL_IS_BOOLEAN(pn3->pn_val));
> 
>                 if (switchop != JSOP_TABLESWITCH)
>                     continue;
>                 if (!JSVAL_IS_INT(pn3->pn_val)) {
>                     switchop = JSOP_LOOKUPSWITCH;
>                     continue;
>                 }
>                 i = JSVAL_TO_INT(pn3->pn_val);
>                 if ((jsuint)(i + (jsint)JS_BIT(15)) >= (jsuint)JS_BIT(16)) {
>                     switchop = JSOP_LOOKUPSWITCH;
>                     continue;
>                 }
>                 if (i < low)
>                     low = i;
>                 if (high < i)
>                     high = i;
> 
>                 /*
>                  * Check for duplicates, which require a JSOP_LOOKUPSWITCH.
>                  * We bias i by 65536 if it's negative, and hope that's a rare
>                  * case (because it requires a malloc'd bitmap).
>                  */
>                 if (i < 0)
>                     i += JS_BIT(16);
>                 if (i >= intmap_bitlen) {
>                     if (!intmap &&
>                         i < (INTMAP_LENGTH << JS_BITS_PER_WORD_LOG2)) {
>                         intmap = intmap_space;
>                         intmap_bitlen = INTMAP_LENGTH << JS_BITS_PER_WORD_LOG2;
>                     } else {
>                         /* Just grab 8K for the worst-case bitmap. */
>                         intmap_bitlen = JS_BIT(16);
>                         XMEMTAG("jsemit jsbitmap");
>                         intmap = (jsbitmap *)
>                             JS_malloc(cx,
>                                       (JS_BIT(16) >> JS_BITS_PER_WORD_LOG2)
>                                       * sizeof(jsbitmap));
>                         if (!intmap) {
>                             JS_ReportOutOfMemory(cx);
>                             return JS_FALSE;
>                         }
>                     }
>                     memset(intmap, 0, intmap_bitlen >> JS_BITS_PER_BYTE_LOG2);
>                 }
>                 if (JS_TEST_BIT(intmap, i)) {
>                     switchop = JSOP_LOOKUPSWITCH;
>                     continue;
>                 }
>                 JS_SET_BIT(intmap, i);
>             }
> 
>           release:
>             if (intmap && intmap != intmap_space)
>                 JS_free(cx, intmap);
>             if (!ok)
>                 return JS_FALSE;
> 
>             if (switchop != JSOP_CONDSWITCH) {
>                 if (switchop == JSOP_TABLESWITCH) {
>                     tablen = (uint32)(high - low + 1);
>                     if (tablen >= JS_BIT(16) || tablen > 2 * ncases)
>                         switchop = JSOP_LOOKUPSWITCH;
>                 }
>             }
>         }
4213d2344
<       case TOK_WHILE:
4215,4232c2346,2347
<          * Minimize bytecodes issued for one or more iterations by jumping to
<          * the condition below the body and closing the loop if the condition
<          * is true with a backward branch. For iteration count i:
<          *
<          *  i    test at the top                 test at the bottom
<          *  =    ===============                 ==================
<          *  0    ifeq-pass                       goto; ifne-fail
<          *  1    ifeq-fail; goto; ifne-pass      goto; ifne-pass; ifne-fail
<          *  2    2*(ifeq-fail; goto); ifeq-pass  goto; 2*ifne-pass; ifne-fail
<          *  . . .
<          *  N    N*(ifeq-fail; goto); ifeq-pass  goto; N*ifne-pass; ifne-fail
<          *
<          * SpiderMonkey, pre-mozilla.org, emitted while parsing and so used
<          * test at the top. When JSParseNode trees were added during the ES3
<          * work (1998-9), the code generation scheme was not optimized, and
<          * the decompiler continued to take advantage of the branch and jump
<          * that bracketed the body. But given the SRC_WHILE note, it is easy
<          * to support the more efficient scheme.
---
>          * Emit a note with two offsets: first tells total switch code length,
>          * second tells offset to first JSOP_CASE if condswitch.
4233a2349,2545
>         noteIndex = js_NewSrcNote3(cx, cg, SRC_SWITCH, 0, 0);
>         if (noteIndex < 0)
>             return JS_FALSE;
> 
>         if (switchop == JSOP_CONDSWITCH) {
>             /*
>              * 0 bytes of immediate for unoptimized ECMAv2 switch.
>              */
>             switchsize = 0;
>         } else if (switchop == JSOP_TABLESWITCH) {
>             /*
>              * 3 offsets (len, low, high) before the table, 1 per entry.
>              */
>             switchsize = (size_t)(JUMP_OFFSET_LEN * (3 + tablen));
>         } else {
>             /*
>              * JSOP_LOOKUPSWITCH:
>              * 1 offset (len) and 1 atom index (npairs) before the table,
>              * 1 atom index and 1 jump offset per entry.
>              */
>             switchsize = (size_t)(JUMP_OFFSET_LEN + ATOM_INDEX_LEN +
>                                   (ATOM_INDEX_LEN + JUMP_OFFSET_LEN) * ncases);
>         }
> 
>         /*
>          * Emit switchop followed by switchsize bytes of jump or lookup table.
>          *
>          * If switchop is JSOP_LOOKUPSWITCH or JSOP_TABLESWITCH, it is crucial
>          * to emit the immediate operand(s) by which bytecode readers such as
>          * BuildSpanDepTable discover the length of the switch opcode *before*
>          * calling js_SetJumpOffset (which may call BuildSpanDepTable).  It's
>          * also important to zero all unknown jump offset immediate operands,
>          * so they can be converted to span dependencies with null targets to
>          * be computed later (js_EmitN zeros switchsize bytes after switchop).
>          */
>         if (js_EmitN(cx, cg, switchop, switchsize) < 0)
>             return JS_FALSE;
> 
>         off = -1;
>         if (switchop == JSOP_CONDSWITCH) {
>             intN caseNoteIndex = -1;
> 
>             /* Emit code for evaluating cases and jumping to case statements. */
>             for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {
>                 pn4 = pn3->pn_left;
>                 if (pn4 && !js_EmitTree(cx, cg, pn4))
>                     return JS_FALSE;
>                 if (caseNoteIndex >= 0) {
>                     /* off is the previous JSOP_CASE's bytecode offset. */
>                     if (!js_SetSrcNoteOffset(cx, cg, (uintN)caseNoteIndex, 0,
>                                              CG_OFFSET(cg) - off)) {
>                         return JS_FALSE;
>                     }
>                 }
>                 if (pn3->pn_type == TOK_DEFAULT)
>                     continue;
>                 caseNoteIndex = js_NewSrcNote2(cx, cg, SRC_PCDELTA, 0);
>                 if (caseNoteIndex < 0)
>                     return JS_FALSE;
>                 off = EmitJump(cx, cg, JSOP_CASE, 0);
>                 if (off < 0)
>                     return JS_FALSE;
>                 pn3->pn_offset = off;
>                 if (pn3 == pn2->pn_head) {
>                     /* Switch note's second offset is to first JSOP_CASE. */
>                     if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 1,
>                                              off - top)) {
>                         return JS_FALSE;
>                     }
>                 }
>             }
> 
>             /* Emit default even if no explicit default statement. */
>             defaultOffset = EmitJump(cx, cg, JSOP_DEFAULT, 0);
>             if (defaultOffset < 0)
>                 return JS_FALSE;
>         } else if (switchop == JSOP_TABLESWITCH) {
>             /* Fill in switch bounds, which we know fit in 16-bit offsets. */
>             pc = CG_CODE(cg, top + JUMP_OFFSET_LEN);
>             SET_JUMP_OFFSET(pc, low);
>             pc += JUMP_OFFSET_LEN;
>             SET_JUMP_OFFSET(pc, high);
>             pc += JUMP_OFFSET_LEN;
>         } else {
>             JS_ASSERT(switchop == JSOP_LOOKUPSWITCH);
> 
>             /* Fill in the number of cases. */
>             pc = CG_CODE(cg, top + JUMP_OFFSET_LEN);
>             SET_ATOM_INDEX(pc, ncases);
>         }
> 
>         /* Emit code for each case's statements, copying pn_offset up to pn3. */
>         for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {
>             if (switchop == JSOP_CONDSWITCH && pn3->pn_type != TOK_DEFAULT) {
>                 pn3->pn_val = INT_TO_JSVAL(pn3->pn_offset - top);
>                 CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, pn3->pn_offset);
>             }
>             pn4 = pn3->pn_right;
>             if (!js_EmitTree(cx, cg, pn4))
>                 return JS_FALSE;
>             pn3->pn_offset = pn4->pn_offset;
>             if (pn3->pn_type == TOK_DEFAULT)
>                 off = pn3->pn_offset - top;
>         }
> 
>         if (!hasDefault) {
>             /* If no default case, offset for default is to end of switch. */
>             off = CG_OFFSET(cg) - top;
>         }
> 
>         /* We better have set "off" by now. */
>         JS_ASSERT(off != -1);
> 
>         /* Set the default offset (to end of switch if no default). */
>         pc = NULL;
>         if (switchop == JSOP_CONDSWITCH) {
>             JS_ASSERT(defaultOffset != -1);
>             if (!js_SetJumpOffset(cx, cg, CG_CODE(cg, defaultOffset),
>                                   off - (defaultOffset - top))) {
>                 return JS_FALSE;
>             }
>         } else {
>             pc = CG_CODE(cg, top);
>             if (!js_SetJumpOffset(cx, cg, pc, off))
>                 return JS_FALSE;
>             pc += JUMP_OFFSET_LEN;
>         }
> 
>         /* Set the SRC_SWITCH note's offset operand to tell end of switch. */
>         off = CG_OFFSET(cg) - top;
>         if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 0, off))
>             return JS_FALSE;
> 
>         if (switchop == JSOP_TABLESWITCH) {
>             /* Skip over the already-initialized switch bounds. */
>             pc += 2 * JUMP_OFFSET_LEN;
> 
>             /* Fill in the jump table, if there is one. */
>             if (tablen) {
>                 /* Avoid bloat for a compilation unit with many switches. */
>                 tablesize = (size_t)tablen * sizeof *table;
> 				XMEMTAG("jsemit JSParseNode");
>                 table = (JSParseNode **) JS_malloc(cx, tablesize);
>                 if (!table) {
>                     JS_ReportOutOfMemory(cx);
>                     return JS_FALSE;
>                 }
>                 memset(table, 0, tablesize);
>                 for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {
>                     if (pn3->pn_type == TOK_DEFAULT)
>                         continue;
>                     i = JSVAL_TO_INT(pn3->pn_val);
>                     i -= low;
>                     JS_ASSERT((uint32)i < tablen);
>                     table[i] = pn3;
>                 }
>                 for (i = 0; i < (jsint)tablen; i++) {
>                     pn3 = table[i];
>                     off = pn3 ? pn3->pn_offset - top : 0;
>                     ok = js_SetJumpOffset(cx, cg, pc, off);
>                     if (!ok)
>                         break;
>                     pc += JUMP_OFFSET_LEN;
>                 }
>                 JS_free(cx, table);
>                 if (!ok)
>                     return JS_FALSE;
>             }
>         } else if (switchop == JSOP_LOOKUPSWITCH) {
>             /* Skip over the already-initialized number of cases. */
>             pc += ATOM_INDEX_LEN;
> 
>             for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {
>                 if (pn3->pn_type == TOK_DEFAULT)
>                     continue;
>                 atom = js_AtomizeValue(cx, pn3->pn_val, 0);
>                 if (!atom)
>                     return JS_FALSE;
>                 ale = js_IndexAtom(cx, atom, &cg->atomList);
>                 if (!ale)
>                     return JS_FALSE;
>                 SET_ATOM_INDEX(pc, ALE_INDEX(ale));
>                 pc += ATOM_INDEX_LEN;
> 
>                 off = pn3->pn_offset - top;
>                 if (!js_SetJumpOffset(cx, cg, pc, off))
>                     return JS_FALSE;
>                 pc += JUMP_OFFSET_LEN;
>             }
>         }
> 
>         ok = js_PopStatementCG(cx, cg);
>         break;
>       }
> #endif /* JS_HAS_SWITCH_STATEMENT */
> 
>       case TOK_WHILE:
4234a2547,2548
>         if (!js_EmitTree(cx, cg, pn->pn_left))
>             return JS_FALSE;
4238,4239c2552,2553
<         jmp = EmitJump(cx, cg, JSOP_GOTO, 0);
<         if (jmp < 0)
---
>         beq = EmitJump(cx, cg, JSOP_IFEQ, 0);
>         if (beq < 0)
4241d2554
<         top = CG_OFFSET(cg);
4244,4248c2557,2558
<         CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, jmp);
<         if (!js_EmitTree(cx, cg, pn->pn_left))
<             return JS_FALSE;
<         beq = EmitJump(cx, cg, JSOP_IFNE, top - CG_OFFSET(cg));
<         if (beq < 0)
---
>         jmp = EmitJump(cx, cg, JSOP_GOTO, top - CG_OFFSET(cg));
>         if (jmp < 0)
4250c2560,2561
<         if (!js_SetSrcNoteOffset(cx, cg, noteIndex, 0, beq - jmp))
---
>         CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, beq);
>         if (!js_SetSrcNoteOffset(cx, cg, noteIndex, 0, jmp - beq))
4254a2566
> #if JS_HAS_DO_WHILE_LOOP
4257,4258c2569,2570
<         noteIndex = js_NewSrcNote(cx, cg, SRC_WHILE);
<         if (noteIndex < 0 || js_Emit1(cx, cg, JSOP_NOP) < 0)
---
>         if (js_NewSrcNote(cx, cg, SRC_WHILE) < 0 ||
>             js_Emit1(cx, cg, JSOP_NOP) < 0) {
4259a2572
>         }
4278,4280c2591,2594
<          * Since we use JSOP_IFNE for other purposes as well as for do-while
<          * loops, we must store 1 + (beq - top) in the SRC_WHILE note offset,
<          * and the decompiler must get that delta and decompile recursively.
---
>          * No source note needed, because JSOP_IFNE is used only for do-while.
>          * If we ever use JSOP_IFNE for other purposes, we can still avoid yet
>          * another note here, by storing (jmp - top) in the SRC_WHILE note's
>          * offset, and fetching that delta in order to decompile recursively.
4282,4285c2596
<         beq = EmitJump(cx, cg, JSOP_IFNE, top - CG_OFFSET(cg));
<         if (beq < 0)
<             return JS_FALSE;
<         if (!js_SetSrcNoteOffset(cx, cg, noteIndex, 0, 1 + (beq - top)))
---
>         if (EmitJump(cx, cg, JSOP_IFNE, top - CG_OFFSET(cg)) < 0)
4288a2600
> #endif /* JS_HAS_DO_WHILE_LOOP */
4296c2608,2616
<             JSBool emitIFEQ;
---
>             /* If the left part is var x = i, bind x, evaluate i, and pop. */
>             pn3 = pn2->pn_left;
>             if (pn3->pn_type == TOK_VAR && pn3->pn_head->pn_expr) {
>                 if (!js_EmitTree(cx, cg, pn3))
>                     return JS_FALSE;
>                 /* Set pn3 to the variable name, to avoid another var note. */
>                 pn3 = pn3->pn_head;
>                 JS_ASSERT(pn3->pn_type == TOK_NAME);
>             }
4298c2618
<             /* Set stmtInfo type for later testing. */
---
>             /* Fix stmtInfo and emit a push to allocate the iterator. */
4301,4330c2621
< 
<             /*
<              * If the left part is 'var x', emit code to define x if necessary
<              * using a prolog opcode, but do not emit a pop.  If the left part
<              * is 'var x = i', emit prolog code to define x if necessary; then
<              * emit code to evaluate i, assign the result to x, and pop the
<              * result off the stack.
<              *
<              * All the logic to do this is implemented in the outer switch's
<              * TOK_VAR case, conditioned on pn_extra flags set by the parser.
<              *
<              * In the 'for (var x = i in o) ...' case, the js_EmitTree(...pn3)
<              * called here will generate the proper note for the assignment
<              * op that sets x = i, hoisting the initialized var declaration
<              * out of the loop: 'var x = i; for (x in o) ...'.
<              *
<              * In the 'for (var x in o) ...' case, nothing but the prolog op
<              * (if needed) should be generated here, we must emit the note
<              * just before the JSOP_FOR* opcode in the switch on pn3->pn_type
<              * a bit below, so nothing is hoisted: 'for (var x in o) ...'.
<              *
<              * A 'for (let x = i in o)' loop must not be hoisted, since in
<              * this form the let variable is scoped by the loop body (but not
<              * the head).  The initializer expression i must be evaluated for
<              * any side effects.  So we hoist only i in the let case.
<              */
<             pn3 = pn2->pn_left;
<             type = PN_TYPE(pn3);
<             cg->treeContext.flags |= TCF_IN_FOR_INIT;
<             if (TOKEN_TYPE_IS_DECL(type) && !js_EmitTree(cx, cg, pn3))
---
>             if (js_Emit1(cx, cg, JSOP_PUSH) < 0)
4332d2622
<             cg->treeContext.flags &= ~TCF_IN_FOR_INIT;
4337,4350c2627
< 
<             /*
<              * Emit a bytecode to convert top of stack value to the iterator
<              * object depending on the loop variant (for-in, for-each-in, or
<              * destructuring for-in).
<              */
< #if JS_HAS_DESTRUCTURING
<             JS_ASSERT(pn->pn_op == JSOP_FORIN ||
<                       pn->pn_op == JSOP_FOREACHKEYVAL ||
<                       pn->pn_op == JSOP_FOREACH);
< #else
<             JS_ASSERT(pn->pn_op == JSOP_FORIN || pn->pn_op == JSOP_FOREACH);
< #endif
<             if (js_Emit1(cx, cg, PN_OP(pn)) < 0)
---
>             if (js_Emit1(cx, cg, JSOP_TOOBJECT) < 0)
4356,4371c2633,2634
<             /*
<              * Compile a JSOP_FOR* bytecode based on the left hand side.
<              *
<              * Initialize op to JSOP_SETNAME in case of |for ([a, b] in o)...|
<              * or similar, to signify assignment, rather than declaration, to
<              * the decompiler.  EmitDestructuringOps takes a prolog bytecode
<              * parameter and emits the appropriate source note, defaulting to
<              * assignment, so JSOP_SETNAME is not critical here; many similar
<              * ops could be used -- just not JSOP_NOP (which means 'let').
<              */
<             emitIFEQ = JS_TRUE;
<             op = JSOP_SETNAME;
<             switch (type) {
< #if JS_HAS_BLOCK_SCOPE
<               case TOK_LET:
< #endif
---
>             /* Compile a JSOP_FOR* bytecode based on the left hand side. */
>             switch (pn3->pn_type) {
4373d2635
<                 JS_ASSERT(pn3->pn_arity == PN_LIST && pn3->pn_count == 1);
4375,4405c2637
< #if JS_HAS_DESTRUCTURING
<                 if (pn3->pn_type == TOK_ASSIGN) {
<                     pn3 = pn3->pn_left;
<                     JS_ASSERT(pn3->pn_type == TOK_RB || pn3->pn_type == TOK_RC);
<                 }
<                 if (pn3->pn_type == TOK_RB || pn3->pn_type == TOK_RC) {
<                     op = PN_OP(pn2->pn_left);
<                     goto destructuring_for;
<                 }
< #else
<                 JS_ASSERT(pn3->pn_type == TOK_NAME);
< #endif
<                 /*
<                  * Always annotate JSOP_FORLOCAL if given input of the form
<                  * 'for (let x in * o)' -- the decompiler must not hoist the
<                  * 'let x' out of the loop head, or x will be bound in the
<                  * wrong scope.  Likewise, but in this case only for the sake
<                  * of higher decompilation fidelity only, do not hoist 'var x'
<                  * when given 'for (var x in o)'.  But 'for (var x = i in o)'
<                  * requires hoisting in order to preserve the initializer i.
<                  * The decompiler can only handle so much!
<                  */
<                 if ((
< #if JS_HAS_BLOCK_SCOPE
<                      type == TOK_LET ||
< #endif
<                      !pn3->pn_expr) &&
<                     js_NewSrcNote2(cx, cg, SRC_DECL,
<                                    type == TOK_VAR
<                                    ? SRC_DECL_VAR
<                                    : SRC_DECL_LET) < 0) {
---
>                 if (js_NewSrcNote(cx, cg, SRC_VAR) < 0)
4407d2638
<                 }
4409a2641,2644
>                 pn3->pn_op = JSOP_FORNAME;
>                 if (!LookupArgOrVar(cx, &cg->treeContext, pn3))
>                     return JS_FALSE;
>                 op = pn3->pn_op;
4411,4433c2646,2647
<                     op = PN_OP(pn3);
<                     switch (op) {
<                       case JSOP_GETARG:   /* FALL THROUGH */
<                       case JSOP_SETARG:   op = JSOP_FORARG; break;
<                       case JSOP_GETVAR:   /* FALL THROUGH */
<                       case JSOP_SETVAR:   op = JSOP_FORVAR; break;
<                       case JSOP_GETGVAR:  /* FALL THROUGH */
<                       case JSOP_SETGVAR:  op = JSOP_FORNAME; break;
<                       case JSOP_GETLOCAL: /* FALL THROUGH */
<                       case JSOP_SETLOCAL: op = JSOP_FORLOCAL; break;
<                       default:            JS_ASSERT(0);
<                     }
<                 } else {
<                     pn3->pn_op = JSOP_FORNAME;
<                     if (!BindNameToSlot(cx, cg, pn3, 0))
<                         return JS_FALSE;
<                     op = PN_OP(pn3);
<                 }
<                 if (pn3->pn_slot >= 0) {
<                     if (pn3->pn_const) {
<                         JS_ASSERT(op == JSOP_FORVAR);
<                         op = JSOP_FORCONST;
<                     }
---
>                     if (pn3->pn_attrs & JSPROP_READONLY)
>                         op = JSOP_GETVAR;
4435c2649
<                     EMIT_UINT16_IMM_OP(op, atomIndex);
---
>                     EMIT_ATOM_INDEX_OP(op, atomIndex);
4443,4444c2657
<                 useful = JS_FALSE;
<                 if (!CheckSideEffects(cx, cg, pn3->pn_expr, &useful))
---
>                 if (!EmitPropOp(cx, pn3, JSOP_FORPROP, cg))
4446,4451c2659
<                 if (!useful) {
<                     if (!EmitPropOp(cx, pn3, JSOP_FORPROP, cg, JS_FALSE))
<                         return JS_FALSE;
<                     break;
<                 }
<                 /* FALL THROUGH */
---
>                 break;
4453,4463d2660
< #if JS_HAS_DESTRUCTURING
<               case TOK_RB:
<               case TOK_RC:
<               destructuring_for:
< #endif
< #if JS_HAS_XML_SUPPORT
<               case TOK_UNARYOP:
< #endif
< #if JS_HAS_LVALUE_RETURN
<               case TOK_LP:
< #endif
4471d2667
<                 emitIFEQ = JS_FALSE;
4478c2674
<                  * the top of the loop, because the loop-closing jump might
---
>                  * the top of the loop, because the loop-closing jump might be
4489,4518d2684
< #if JS_HAS_DESTRUCTURING
<                 if (pn3->pn_type == TOK_RB || pn3->pn_type == TOK_RC) {
<                     if (!EmitDestructuringOps(cx, cg, op, pn3))
<                         return JS_FALSE;
<                     if (js_Emit1(cx, cg, JSOP_POP) < 0)
<                         return JS_FALSE;
<                     break;
<                 }
< #endif
< #if JS_HAS_LVALUE_RETURN
<                 if (pn3->pn_type == TOK_LP) {
<                     JS_ASSERT(pn3->pn_op == JSOP_SETCALL);
<                     if (!js_EmitTree(cx, cg, pn3))
<                         return JS_FALSE;
<                     if (!js_Emit1(cx, cg, JSOP_ENUMELEM))
<                         return JS_FALSE;
<                     break;
<                 }
< #endif
< #if JS_HAS_XML_SUPPORT
<                 if (pn3->pn_type == TOK_UNARYOP) {
<                     JS_ASSERT(pn3->pn_op == JSOP_BINDXMLNAME);
<                     if (!js_EmitTree(cx, cg, pn3))
<                         return JS_FALSE;
<                     if (!js_Emit1(cx, cg, JSOP_ENUMELEM))
<                         return JS_FALSE;
<                     break;
<                 }
< #endif
< 
4527,4528c2693
< 
<             if (emitIFEQ) {
---
>             if (pn3->pn_type != TOK_LB) {
4540,4542c2705
<             op = JSOP_POP;
<             pn3 = pn2->pn_kid1;
<             if (!pn3) {
---
>             if (!pn2->pn_kid1) {
4546,4549c2709
<                 cg->treeContext.flags |= TCF_IN_FOR_INIT;
< #if JS_HAS_DESTRUCTURING
<                 if (pn3->pn_type == TOK_ASSIGN &&
<                     !MaybeEmitGroupAssignment(cx, cg, op, pn3, &op)) {
---
>                 if (!js_EmitTree(cx, cg, pn2->pn_kid1))
4551,4568c2711
<                 }
< #endif
<                 if (op == JSOP_POP) {
<                     if (!js_EmitTree(cx, cg, pn3))
<                         return JS_FALSE;
<                     if (TOKEN_TYPE_IS_DECL(pn3->pn_type)) {
<                         /*
<                          * Check whether a destructuring-initialized var decl
<                          * was optimized to a group assignment.  If so, we do
<                          * not need to emit a pop below, so switch to a nop,
<                          * just for the decompiler.
<                          */
<                         JS_ASSERT(pn3->pn_arity == PN_LIST);
<                         if (pn3->pn_extra & PNX_GROUPINIT)
<                             op = JSOP_NOP;
<                     }
<                 }
<                 cg->treeContext.flags &= ~TCF_IN_FOR_INIT;
---
>                 op = JSOP_POP;
4618,4621c2761,2763
<                 op = JSOP_POP;
< #if JS_HAS_DESTRUCTURING
<                 if (pn3->pn_type == TOK_ASSIGN &&
<                     !MaybeEmitGroupAssignment(cx, cg, op, pn3, &op)) {
---
>                 if (!js_EmitTree(cx, cg, pn3))
>                     return JS_FALSE;
>                 if (js_Emit1(cx, cg, JSOP_POP) < 0)
4623,4630d2764
<                 }
< #endif
<                 if (op == JSOP_POP) {
<                     if (!js_EmitTree(cx, cg, pn3))
<                         return JS_FALSE;
<                     if (js_Emit1(cx, cg, op) < 0)
<                         return JS_FALSE;
<                 }
4634c2768
<                 if (CG_CURRENT_LINE(cg) != (uintN) off) {
---
>                 if (cg->currentLine != (uintN) off) {
4637c2771
<                     CG_CURRENT_LINE(cg) = (uintN) off;
---
>                     cg->currentLine = (uintN) off;
4661c2795
<         /* Now fixup all breaks and continues (before for/in's JSOP_ENDITER). */
---
>         /* Now fixup all breaks and continues (before for/in's final POP2). */
4667,4668c2801,2802
<              * JSOP_ENDITER needs a slot to save an exception thrown from the
<              * body of for-in loop when closing the iterator object.
---
>              * Generate the object and iterator pop opcodes after popping the
>              * stmtInfo stack, so breaks will go to this pop bytecode.
4670,4674c2804,2815
<             JS_ASSERT(js_CodeSpec[JSOP_ENDITER].format & JOF_TMPSLOT);
<             if (!NewTryNote(cx, cg, JSTN_ITER, cg->stackDepth, top,
<                             CG_OFFSET(cg)) ||
<                 js_Emit1(cx, cg, JSOP_ENDITER) < 0) {
<                 return JS_FALSE;
---
>             if (pn3->pn_type != TOK_LB) {
>                 if (js_Emit1(cx, cg, JSOP_POP2) < 0)
>                     return JS_FALSE;
>             } else {
>                 /*
>                  * With 'for(x[i]...)', there's only the object on the stack,
>                  * so we need to hide the pop.
>                  */
>                 if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0)
>                     return JS_FALSE;
>                 if (js_Emit1(cx, cg, JSOP_POP) < 0)
>                     return JS_FALSE;
4686c2827
<             while (stmt->type != STMT_LABEL || stmt->u.label != atom)
---
>             while (stmt->type != STMT_LABEL || stmt->label != atom)
4709c2850
<             while (stmt->type != STMT_LABEL || stmt->u.label != atom) {
---
>             while (stmt->type != STMT_LABEL || stmt->label != atom) {
4740,4742c2881,2885
<       case TOK_TRY:
<       {
<         ptrdiff_t tryStart, tryEnd, catchJump, finallyStart;
---
> #if JS_HAS_EXCEPTIONS
> 
>       case TOK_TRY: {
>         ptrdiff_t start, end, catchStart, finallyCatch, catchJump;
>         JSParseNode *iter;
4744d2886
<         JSParseNode *lastCatch;
4746c2888,2897
<         catchJump = -1;
---
>         /* Quell GCC overwarnings. */
>         end = catchStart = finallyCatch = catchJump = -1;
> 
> /* Emit JSOP_GOTO that points to the first op after the catch/finally blocks */
> #define EMIT_CATCH_GOTO(cx, cg, jmp)                                          \
>     EMIT_BACKPATCH_OP(cx, cg, stmtInfo.catchJump, JSOP_BACKPATCH, jmp)
> 
> /* Emit JSOP_GOSUB that points to the finally block. */
> #define EMIT_FINALLY_GOSUB(cx, cg, jmp)                                       \
>     EMIT_BACKPATCH_OP(cx, cg, stmtInfo.gosub, JSOP_BACKPATCH_PUSH, jmp)
4752c2903
<          * When a finally block is 'active' (STMT_FINALLY on the treeContext),
---
>          * When a finally block is `active' (STMT_FINALLY on the treeContext),
4755c2906
<          * EmitBackPatchOp and BackPatch).
---
>          * EMIT_BACKPATCH_OP and BackPatch).
4758c2909
<                          pn->pn_kid3 ? STMT_FINALLY : STMT_TRY,
---
>                          pn->pn_kid3 ? STMT_FINALLY : STMT_BLOCK,
4762,4764c2913,2915
<          * Since an exception can be thrown at any place inside the try block,
<          * we need to restore the stack and the scope chain before we transfer
<          * the control to the exception handler.
---
>          * About JSOP_SETSP: an exception can be thrown while the stack is in
>          * an unbalanced state, and this imbalance causes problems with things
>          * like function invocation later on.
4766,4768c2917,2921
<          * For that we store in a try note associated with the catch or
<          * finally block the stack depth upon the try entry. The interpreter
<          * uses this depth to properly unwind the stack and the scope chain.
---
>          * To fix this, we compute the `balanced' stack depth upon try entry,
>          * and then restore the stack to this depth when we hit the first catch
>          * or finally block.  We can't just zero the stack, because things like
>          * for/in and with that are active upon entry to the block keep state
>          * variables on the stack.
4775c2928
<         tryStart = CG_OFFSET(cg);
---
>         start = CG_OFFSET(cg);
4783c2936
<             jmp = EmitBackPatchOp(cx, cg, JSOP_BACKPATCH, &GOSUBS(stmtInfo));
---
>             EMIT_FINALLY_GOSUB(cx, cg, jmp);
4786,4788d2938
< 
<             /* JSOP_RETSUB pops the return pc-index, balancing the stack. */
<             cg->stackDepth = depth;
4794c2944
<         jmp = EmitBackPatchOp(cx, cg, JSOP_BACKPATCH, &catchJump);
---
>         EMIT_CATCH_GOTO(cx, cg, jmp);
4798c2948
<         tryEnd = CG_OFFSET(cg);
---
>         end = CG_OFFSET(cg);
4801,4804c2951,2953
<         pn2 = pn->pn_kid2;
<         lastCatch = NULL;
<         if (pn2) {
<             jsint count = 0;    /* previous catch block's population */
---
>         iter = pn->pn_kid2;
>         if (iter) {
>             catchStart = end;
4809,4811c2958,2961
<              * [throwing]                          only if 2nd+ catch block
<              * [leaveblock]                        only if 2nd+ catch block
<              * enterblock                          with SRC_CATCH
---
>              * [ popscope ]                        only if 2nd+ catch block
>              * name Object
>              * pushobj
>              * newinit
4813,4814c2963,2964
<              * [dup]                               only if catchguard
<              * setlocalpop <slot>                  or destructuring code
---
>              * initcatchvar <atom>
>              * enterwith
4817d2966
<              * [pop]                               only if catchguard
4819c2968
<              * leaveblock
---
>              * leavewith
4824c2973
<              * code will [gosub] to the finally code if appropriate, and is
---
>              * code will GOSUB to the finally code if appropriate, and is
4828,4829c2977,2983
<             for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {
<                 ptrdiff_t guardJump, catchNote;
---
>             for (;;) {
>                 JSStmtInfo stmtInfo2;
>                 JSParseNode *disc;
>                 ptrdiff_t guardnote;
> 
>                 if (!UpdateLinenoNotes(cx, cg, iter))
>                     return JS_FALSE;
4831,4833c2985
<                 JS_ASSERT(cg->stackDepth == depth);
<                 guardJump = GUARDJUMP(stmtInfo);
<                 if (guardJump != -1) {
---
>                 if (catchJump != -1) {
4835c2987
<                     CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, guardJump);
---
>                     CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, catchJump);
4837,4841c2989,2991
<                     /*
<                      * Account for the pushed exception object that we still
<                      * have after the jumping from the previous guard.
<                      */
<                     cg->stackDepth = depth + 1;
---
>                     /* Compensate for the [leavewith]. */
>                     cg->stackDepth++;
>                     JS_ASSERT((uintN) cg->stackDepth <= cg->maxStackDepth);
4843,4848d2992
<                     /*
<                      * Move exception back to cx->exception to prepare for
<                      * the next catch. We hide [throwing] from the decompiler
<                      * since it compensates for the hidden JSOP_DUP at the
<                      * start of the previous guarded catch.
<                      */
4850c2994
<                         js_Emit1(cx, cg, JSOP_THROWING) < 0) {
---
>                         js_Emit1(cx, cg, JSOP_LEAVEWITH) < 0) {
4852a2997,3001
>                 } else {
>                     /* Set stack to original depth (see SETSP comment above). */
>                     EMIT_ATOM_INDEX_OP(JSOP_SETSP, (jsatomid)depth);
>                     cg->stackDepth = depth;
>                 }
4854,4858c3003,3046
<                     /*
<                      * Emit an unbalanced [leaveblock] for the previous catch,
<                      * whose block object count is saved below.
<                      */
<                     if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0)
---
>                 /* Non-negative guardnote offset is length of catchguard. */
>                 guardnote = js_NewSrcNote2(cx, cg, SRC_CATCH, 0);
>                 if (guardnote < 0 ||
>                     js_Emit1(cx, cg, JSOP_NOP) < 0) {
>                     return JS_FALSE;
>                 }
> 
>                 /* Construct the scope holder and push it on. */
>                 ale = js_IndexAtom(cx, cx->runtime->atomState.ObjectAtom,
>                                    &cg->atomList);
>                 if (!ale)
>                     return JS_FALSE;
>                 EMIT_ATOM_INDEX_OP(JSOP_NAME, ALE_INDEX(ale));
> 
>                 if (js_Emit1(cx, cg, JSOP_PUSHOBJ) < 0 ||
>                     js_Emit1(cx, cg, JSOP_NEWINIT) < 0 ||
>                     js_Emit1(cx, cg, JSOP_EXCEPTION) < 0) {
>                     return JS_FALSE;
>                 }
> 
>                 /* initcatchvar <atomIndex> */
>                 disc = iter->pn_kid1;
>                 ale = js_IndexAtom(cx, disc->pn_atom, &cg->atomList);
>                 if (!ale)
>                     return JS_FALSE;
> 
>                 EMIT_ATOM_INDEX_OP(JSOP_INITCATCHVAR, ALE_INDEX(ale));
>                 if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0 ||
>                     js_Emit1(cx, cg, JSOP_ENTERWITH) < 0) {
>                     return JS_FALSE;
>                 }
> 
>                 /* boolean_expr */
>                 if (disc->pn_expr) {
>                     ptrdiff_t guardstart = CG_OFFSET(cg);
>                     if (!js_EmitTree(cx, cg, disc->pn_expr))
>                         return JS_FALSE;
>                     if (!js_SetSrcNoteOffset(cx, cg, guardnote, 0,
>                                              CG_OFFSET(cg) - guardstart)) {
>                         return JS_FALSE;
>                     }
>                     /* ifeq <next block> */
>                     catchJump = EmitJump(cx, cg, JSOP_IFEQ, 0);
>                     if (catchJump < 0)
4860,4861d3047
<                     JS_ASSERT(count >= 0);
<                     EMIT_UINT16_IMM_OP(JSOP_LEAVEBLOCK, count);
4864,4872c3050,3054
<                 /*
<                  * Annotate the JSOP_ENTERBLOCK that's about to be generated
<                  * by the call to js_EmitTree immediately below.  Save this
<                  * source note's index in stmtInfo for use by the TOK_CATCH:
<                  * case, where the length of the catch guard is set as the
<                  * note's offset.
<                  */
<                 catchNote = js_NewSrcNote2(cx, cg, SRC_CATCH, 0);
<                 if (catchNote < 0)
---
>                 /* Emit catch block. */
>                 js_PushStatement(&cg->treeContext, &stmtInfo2, STMT_CATCH,
>                                  CG_OFFSET(cg));
>                 stmtInfo2.label = disc->pn_atom;
>                 if (!js_EmitTree(cx, cg, iter->pn_kid3))
4874c3056
<                 CATCHNOTE(stmtInfo) = catchNote;
---
>                 js_PopStatementCG(cx, cg);
4877,4879c3059,3060
<                  * Emit the lexical scope and catch body.  Save the catch's
<                  * block object population via count, for use when targeting
<                  * guardJump at the next catch (the guard mismatch case).
---
>                  * Jump over the remaining catch blocks.
>                  * This counts as a non-local jump, so do the finally thing.
4881,4883c3062,3065
<                 JS_ASSERT(pn3->pn_type == TOK_LEXICALSCOPE);
<                 count = OBJ_BLOCK_COUNT(cx, pn3->pn_pob->object);
<                 if (!js_EmitTree(cx, cg, pn3))
---
> 
>                 /* popscope */
>                 if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0 ||
>                     js_Emit1(cx, cg, JSOP_LEAVEWITH) < 0) {
4884a3067
>                 }
4888,4889c3071
<                     jmp = EmitBackPatchOp(cx, cg, JSOP_BACKPATCH,
<                                           &GOSUBS(stmtInfo));
---
>                     EMIT_FINALLY_GOSUB(cx, cg, jmp);
4892d3073
<                     JS_ASSERT(cg->stackDepth == depth);
4895,4898c3076
<                 /*
<                  * Jump over the remaining catch blocks.  This will get fixed
<                  * up to jump to after catch/finally.
<                  */
---
>                 /* This will get fixed up to jump to after catch/finally. */
4901c3079
<                 jmp = EmitBackPatchOp(cx, cg, JSOP_BACKPATCH, &catchJump);
---
>                 EMIT_CATCH_GOTO(cx, cg, jmp);
4904,4909c3082,3084
< 
<                 /*
<                  * Save a pointer to the last catch node to handle try-finally
<                  * and try-catch(guard)-finally special cases.
<                  */
<                 lastCatch = pn3->pn_expr;
---
>                 if (!iter->pn_kid2)     /* leave iter at last catch */
>                     break;
>                 iter = iter->pn_kid2;
4914,4917c3089,3091
<          * Last catch guard jumps to the rethrow code sequence if none of the
<          * guards match. Target guardJump at the beginning of the rethrow
<          * sequence, just in case a guard expression throws and leaves the
<          * stack unbalanced.
---
>          * We use a [leavewith],[gosub],rethrow block for rethrowing
>          * when there's no unguarded catch, and also for running finally
>          * code while letting an uncaught exception pass through.
4919,4925c3093,3094
<         if (lastCatch && lastCatch->pn_kid2) {
<             CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, GUARDJUMP(stmtInfo));
< 
<             /* Sync the stack to take into account pushed exception. */
<             JS_ASSERT(cg->stackDepth == depth);
<             cg->stackDepth = depth + 1;
< 
---
>         if (pn->pn_kid3 ||
>             (catchJump != -1 && iter->pn_kid1->pn_expr)) {
4927,4928c3096,3100
<              * Rethrow the exception, delegating executing of finally if any
<              * to the exception handler.
---
>              * Emit another stack fixup, because the catch could itself
>              * throw an exception in an unbalanced state, and the finally
>              * may need to call functions.  If there is no finally, only
>              * guarded catches, the rethrow code below nevertheless needs
>              * stack fixup.
4929a3102,3126
>             finallyCatch = CG_OFFSET(cg);
>             EMIT_ATOM_INDEX_OP(JSOP_SETSP, (jsatomid)depth);
>             cg->stackDepth = depth;
> 
>             /* Last discriminant jumps to rethrow if none match. */
>             if (catchJump != -1 && iter->pn_kid1->pn_expr) {
>                 CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, catchJump);
> 
>                 /* Compensate for the [leavewith]. */
>                 cg->stackDepth++;
>                 JS_ASSERT((uintN) cg->stackDepth <= cg->maxStackDepth);
> 
>                 if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0 ||
>                     js_Emit1(cx, cg, JSOP_LEAVEWITH) < 0) {
>                     return JS_FALSE;
>                 }
>             }
> 
>             if (pn->pn_kid3) {
>                 EMIT_FINALLY_GOSUB(cx, cg, jmp);
>                 if (jmp < 0)
>                     return JS_FALSE;
>                 cg->stackDepth = depth;
>             }
> 
4930a3128,3129
>                 js_Emit1(cx, cg, JSOP_EXCEPTION) < 0 ||
>                 js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0 ||
4933a3133
>             JS_ASSERT(cg->stackDepth == depth);
4936,4939c3136,3139
<         JS_ASSERT(cg->stackDepth == depth);
< 
<         /* Emit finally handler if any. */
<         finallyStart = 0;   /* to quell GCC uninitialized warnings */
---
>         /*
>          * If we have a finally, it belongs here, and we have to fix up the
>          * gosubs that might have been emitted before non-local jumps.
>          */
4941,4945c3141
<             /*
<              * Fix up the gosubs that might have been emitted before non-local
<              * jumps to the finally code.
<              */
<             if (!BackPatch(cx, cg, GOSUBS(stmtInfo), CG_NEXT(cg), JSOP_GOSUB))
---
>             if (!BackPatch(cx, cg, stmtInfo.gosub, CG_NEXT(cg), JSOP_GOSUB))
4948,4949d3143
<             finallyStart = CG_OFFSET(cg);
< 
4951,4958c3145,3147
<              * The stack depth at the begining of finally must match the try
<              * depth plus 2 slots. The interpreter uses these two slots to
<              * either push (true, exception) pair when it transfers control
<              * flow to the finally after capturing an exception, or to push
<              * (false, pc-index) when it calls finally from [gosub]. The first
<              * element of the pair indicates for [retsub] that it should
<              * either rethrow the pending exception or transfer the control
<              * back to the caller of finally.
---
>              * The stack budget must be balanced at this point, and we need
>              * one more slot for the JSOP_RETSUB return address pushed by a
>              * JSOP_GOSUB opcode that calls this finally clause.
4961,4963c3150
<             JS_ASSERT((uintN)depth <= cg->maxStackDepth);
<             cg->stackDepth += 2;
<             if ((uintN)cg->stackDepth > cg->maxStackDepth)
---
>             if ((uintN)++cg->stackDepth > cg->maxStackDepth)
4968c3155
<             if (!UpdateLineNumberNotes(cx, cg, pn->pn_kid3))
---
>             if (!UpdateLinenoNotes(cx, cg, pn->pn_kid3))
4975,4978d3161
< 
<             /* Restore stack depth budget to its balanced state. */
<             JS_ASSERT(cg->stackDepth == depth + 2);
<             cg->stackDepth = depth;
4980,4981c3163
<         if (!js_PopStatementCG(cx, cg))
<             return JS_FALSE;
---
>         js_PopStatementCG(cx, cg);
4989c3171
<         if (!BackPatch(cx, cg, catchJump, CG_NEXT(cg), JSOP_GOTO))
---
>         if (!BackPatch(cx, cg, stmtInfo.catchJump, CG_NEXT(cg), JSOP_GOTO))
4996,4998c3178,3181
<         if (pn->pn_kid2 &&
<             !NewTryNote(cx, cg, JSTN_CATCH, depth, tryStart, tryEnd)) {
<             return JS_FALSE;
---
>         if (pn->pn_kid2) {
>             JS_ASSERT(end != -1 && catchStart != -1);
>             if (!js_NewTryNote(cx, cg, start, end, catchStart))
>                 return JS_FALSE;
5006,5008c3189,3192
<         if (pn->pn_kid3 &&
<             !NewTryNote(cx, cg, JSTN_FINALLY, depth, tryStart, finallyStart)) {
<             return JS_FALSE;
---
>         if (pn->pn_kid3) {
>             JS_ASSERT(finallyCatch != -1);
>             if (!js_NewTryNote(cx, cg, start, finallyCatch, finallyCatch))
>                 return JS_FALSE;
5013,5041c3197
<       case TOK_CATCH:
<       {
<         ptrdiff_t catchStart, guardJump;
<         JSObject *blockObj;
< 
<         /*
<          * Morph STMT_BLOCK to STMT_CATCH, note the block entry code offset,
<          * and save the block object atom.
<          */
<         stmt = cg->treeContext.topStmt;
<         JS_ASSERT(stmt->type == STMT_BLOCK && (stmt->flags & SIF_SCOPE));
<         stmt->type = STMT_CATCH;
<         catchStart = stmt->update;
<         blockObj = stmt->u.blockObj;
< 
<         /* Go up one statement info record to the TRY or FINALLY record. */
<         stmt = stmt->down;
<         JS_ASSERT(stmt->type == STMT_TRY || stmt->type == STMT_FINALLY);
< 
<         /* Pick up the pending exception and bind it to the catch variable. */
<         if (js_Emit1(cx, cg, JSOP_EXCEPTION) < 0)
<             return JS_FALSE;
< 
<         /*
<          * Dup the exception object if there is a guard for rethrowing to use
<          * it later when rethrowing or in other catches.
<          */
<         if (pn->pn_kid2 && js_Emit1(cx, cg, JSOP_DUP) < 0)
<             return JS_FALSE;
---
> #endif /* JS_HAS_EXCEPTIONS */
5043,5050c3199,3203
<         pn2 = pn->pn_kid1;
<         switch (pn2->pn_type) {
< #if JS_HAS_DESTRUCTURING
<           case TOK_RB:
<           case TOK_RC:
<             if (!EmitDestructuringOps(cx, cg, JSOP_NOP, pn2))
<                 return JS_FALSE;
<             if (js_Emit1(cx, cg, JSOP_POP) < 0)
---
>       case TOK_VAR:
>         off = noteIndex = -1;
>         for (pn2 = pn->pn_head; ; pn2 = pn2->pn_next) {
>             JS_ASSERT(pn2->pn_type == TOK_NAME);
>             if (!LookupArgOrVar(cx, &cg->treeContext, pn2))
5052c3205,3209
<             break;
---
>             op = pn2->pn_op;
>             if (op == JSOP_ARGUMENTS) {
>                 JS_ASSERT(!pn2->pn_expr); /* JSOP_ARGUMENTS => no initializer */
> #ifdef __GNUC__
>                 atomIndex = 0;            /* quell GCC overwarning */
5053a3211,3218
>             } else {
>                 if (pn2->pn_slot >= 0) {
>                     atomIndex = (jsatomid) pn2->pn_slot;
>                 } else {
>                     ale = js_IndexAtom(cx, pn2->pn_atom, &cg->atomList);
>                     if (!ale)
>                         return JS_FALSE;
>                     atomIndex = ALE_INDEX(ale);
5055,5070c3220,3239
<           case TOK_NAME:
<             /* Inline BindNameToSlot, adding block depth to pn2->pn_slot. */
<             pn2->pn_slot += OBJ_BLOCK_DEPTH(cx, blockObj);
<             EMIT_UINT16_IMM_OP(JSOP_SETLOCALPOP, pn2->pn_slot);
<             break;
< 
<           default:
<             JS_ASSERT(0);
<         }
< 
<         /* Emit the guard expression, if there is one. */
<         if (pn->pn_kid2) {
<             if (!js_EmitTree(cx, cg, pn->pn_kid2))
<                 return JS_FALSE;
<             if (!js_SetSrcNoteOffset(cx, cg, CATCHNOTE(*stmt), 0,
<                                      CG_OFFSET(cg) - catchStart)) {
---
>                     if (!(cg->treeContext.flags & TCF_IN_FUNCTION) ||
>                         (cg->treeContext.flags & TCF_FUN_HEAVYWEIGHT)) {
>                         /* Emit a prolog bytecode to predefine the variable. */
>                         CG_SWITCH_TO_PROLOG(cg);
>                         EMIT_ATOM_INDEX_OP(pn->pn_op, atomIndex);
>                         CG_SWITCH_TO_MAIN(cg);
>                     }
>                 }
>                 if (pn2->pn_expr) {
>                     if (op == JSOP_SETNAME)
>                         EMIT_ATOM_INDEX_OP(JSOP_BINDNAME, atomIndex);
>                     if (!js_EmitTree(cx, cg, pn2->pn_expr))
>                         return JS_FALSE;
>                 }
>             }
>             if (pn2 == pn->pn_head &&
>                 js_NewSrcNote(cx, cg,
>                               (pn->pn_op == JSOP_DEFCONST)
>                               ? SRC_CONST
>                               : SRC_VAR) < 0) {
5073,5075c3242,3258
<             /* ifeq <next block> */
<             guardJump = EmitJump(cx, cg, JSOP_IFEQ, 0);
<             if (guardJump < 0)
---
>             if (op == JSOP_ARGUMENTS) {
>                 if (js_Emit1(cx, cg, op) < 0)
>                     return JS_FALSE;
>             } else {
>                 EMIT_ATOM_INDEX_OP(op, atomIndex);
>             }
>             tmp = CG_OFFSET(cg);
>             if (noteIndex >= 0) {
>                 if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 0, tmp-off))
>                     return JS_FALSE;
>             }
>             if (!pn2->pn_next)
>                 break;
>             off = tmp;
>             noteIndex = js_NewSrcNote2(cx, cg, SRC_PCDELTA, 0);
>             if (noteIndex < 0 ||
>                 js_Emit1(cx, cg, JSOP_POP) < 0) {
5077,5079c3260,3262
<             GUARDJUMP(*stmt) = guardJump;
< 
<             /* Pop duplicated exception object as we no longer need it. */
---
>             }
>         }
>         if (pn->pn_extra) {
5083,5100d3265
< 
<         /* Emit the catch body. */
<         if (!js_EmitTree(cx, cg, pn->pn_kid3))
<             return JS_FALSE;
< 
<         /*
<          * Annotate the JSOP_LEAVEBLOCK that will be emitted as we unwind via
<          * our TOK_LEXICALSCOPE parent, so the decompiler knows to pop.
<          */
<         off = cg->stackDepth;
<         if (js_NewSrcNote2(cx, cg, SRC_CATCH, off) < 0)
<             return JS_FALSE;
<         break;
<       }
< 
<       case TOK_VAR:
<         if (!EmitVariables(cx, cg, pn, JS_FALSE, &noteIndex))
<             return JS_FALSE;
5129,5150d3293
< #if JS_HAS_GENERATORS
<       case TOK_YIELD:
<         if (!(cg->treeContext.flags & TCF_IN_FUNCTION)) {
<             js_ReportCompileErrorNumber(cx, CG_TS(cg), pn, JSREPORT_ERROR,
<                                         JSMSG_BAD_RETURN_OR_YIELD,
<                                         js_yield_str);
<             return JS_FALSE;
<         }
<         if (pn->pn_kid) {
<             if (!js_EmitTree(cx, cg, pn->pn_kid))
<                 return JS_FALSE;
<         } else {
<             if (js_Emit1(cx, cg, JSOP_PUSH) < 0)
<                 return JS_FALSE;
<         }
<         if (pn->pn_hidden && js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0)
<             return JS_FALSE;
<         if (js_Emit1(cx, cg, JSOP_YIELD) < 0)
<             return JS_FALSE;
<         break;
< #endif
< 
5152,5171d3294
< #if JS_HAS_XML_SUPPORT
<         if (pn->pn_arity == PN_UNARY) {
<             if (!js_EmitTree(cx, cg, pn->pn_kid))
<                 return JS_FALSE;
<             if (js_Emit1(cx, cg, PN_OP(pn)) < 0)
<                 return JS_FALSE;
<             break;
<         }
< #endif
< 
<         JS_ASSERT(pn->pn_arity == PN_LIST);
< 
<         noteIndex = -1;
<         tmp = CG_OFFSET(cg);
<         if (pn->pn_extra & PNX_NEEDBRACES) {
<             noteIndex = js_NewSrcNote2(cx, cg, SRC_BRACE, 0);
<             if (noteIndex < 0 || js_Emit1(cx, cg, JSOP_NOP) < 0)
<                 return JS_FALSE;
<         }
< 
5173,5210d3295
<         if (pn->pn_extra & PNX_FUNCDEFS) {
<             /*
<              * This block contains top-level function definitions. To ensure
<              * that we emit the bytecode defining them prior the rest of code
<              * in the block we use a separate pass over functions. During the
<              * main pass later the emitter will add JSOP_NOP with source notes
<              * for the function to preserve the original functions position
<              * when decompiling.
<              *
<              * Currently this is used only for functions, as compile-as-we go
<              * mode for scripts does not allow separate emitter passes.
<              */
<             JS_ASSERT(cg->treeContext.flags & TCF_IN_FUNCTION);
<             for (pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) {
<                 if (pn2->pn_type == TOK_FUNCTION) {
<                     JS_ASSERT(pn2->pn_op == JSOP_NOP);
<                     if (!js_EmitTree(cx, cg, pn2))
<                         return JS_FALSE;
<                 }
<             }
<         }
<         for (pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) {
<             if (!js_EmitTree(cx, cg, pn2))
<                 return JS_FALSE;
<         }
< 
<         if (noteIndex >= 0 &&
<             !js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 0,
<                                  CG_OFFSET(cg) - tmp)) {
<             return JS_FALSE;
<         }
< 
<         ok = js_PopStatementCG(cx, cg);
<         break;
< 
<       case TOK_BODY:
<         JS_ASSERT(pn->pn_arity == PN_LIST);
<         js_PushStatement(&cg->treeContext, &stmtInfo, STMT_BODY, top);
5227c3312,3314
<             useful = wantval = !(cg->treeContext.flags & TCF_IN_FUNCTION);
---
>             useful = wantval = !cx->fp->fun ||
>                                cx->fp->fun->native ||
>                                (cx->fp->flags & JSFRAME_SPECIAL);
5229c3316
<                 if (!CheckSideEffects(cx, cg, pn2, &useful))
---
>                 if (!CheckSideEffects(cx, &cg->treeContext, pn2, &useful))
5232,5244c3319,3321
< 
<             /*
<              * Don't eliminate apparently useless expressions if they are
<              * labeled expression statements.  The tc->topStmt->update test
<              * catches the case where we are nesting in js_EmitTree for a
<              * labeled compound statement.
<              */
<             if (!useful &&
<                 (!cg->treeContext.topStmt ||
<                  cg->treeContext.topStmt->type != STMT_LABEL ||
<                  cg->treeContext.topStmt->update < CG_OFFSET(cg))) {
<                 CG_CURRENT_LINE(cg) = pn2->pn_pos.begin.lineno;
<                 if (!js_ReportCompileErrorNumber(cx, CG_TS(cg), pn2,
---
>             if (!useful) {
>                 cg->currentLine = pn2->pn_pos.begin.lineno;
>                 if (!js_ReportCompileErrorNumber(cx, NULL, cg,
5251,5264c3328,3331
<                 op = wantval ? JSOP_POPV : JSOP_POP;
< #if JS_HAS_DESTRUCTURING
<                 if (!wantval &&
<                     pn2->pn_type == TOK_ASSIGN &&
<                     !MaybeEmitGroupAssignment(cx, cg, op, pn2, &op)) {
<                     return JS_FALSE;
<                 }
< #endif
<                 if (op != JSOP_NOP) {
<                     if (!js_EmitTree(cx, cg, pn2))
<                         return JS_FALSE;
<                     if (js_Emit1(cx, cg, op) < 0)
<                         return JS_FALSE;
<                 }
---
>                 if (!js_EmitTree(cx, cg, pn2))
>                     return JS_FALSE;
>                 if (js_Emit1(cx, cg, wantval ? JSOP_POPV : JSOP_POP) < 0)
>                     return JS_FALSE;
5276,5281c3343,3346
<         noteType = (pn2->pn_type == TOK_LC ||
<                     (pn2->pn_type == TOK_LEXICALSCOPE &&
<                      pn2->pn_expr->pn_type == TOK_LC))
<                    ? SRC_LABELBRACE
<                    : SRC_LABEL;
<         noteIndex = js_NewSrcNote2(cx, cg, noteType,
---
>         noteIndex = js_NewSrcNote2(cx, cg,
>                                    (pn2->pn_type == TOK_LC)
>                                    ? SRC_LABELBRACE
>                                    : SRC_LABEL,
5291c3356
<         stmtInfo.u.label = atom;
---
>         stmtInfo.label = atom;
5298c3363
<         if (noteType == SRC_LABELBRACE) {
---
>         if (pn2->pn_type == TOK_LC) {
5340c3405
<         atomIndex = (jsatomid) -1;              /* quell GCC overwarning */
---
>         atomIndex = (jsatomid) -1; /* Suppress warning. */
5343c3408
<             if (!BindNameToSlot(cx, cg, pn2, 0))
---
>             if (!LookupArgOrVar(cx, &cg->treeContext, pn2))
5352c3417
<                 EMIT_INDEX_OP(JSOP_BINDNAME, atomIndex);
---
>                 EMIT_ATOM_INDEX_OP(JSOP_BINDNAME, atomIndex);
5364c3429
<             JS_ASSERT(pn2->pn_arity == PN_BINARY);
---
>             JS_ASSERT(pn->pn_arity == PN_BINARY);
5370,5374d3434
< #if JS_HAS_DESTRUCTURING
<           case TOK_RB:
<           case TOK_RC:
<             break;
< #endif
5381,5389d3440
< #if JS_HAS_XML_SUPPORT
<           case TOK_UNARYOP:
<             JS_ASSERT(pn2->pn_op == JSOP_SETXMLNAME);
<             if (!js_EmitTree(cx, cg, pn2->pn_kid))
<                 return JS_FALSE;
<             if (js_Emit1(cx, cg, JSOP_BINDXMLNAME) < 0)
<                 return JS_FALSE;
<             break;
< #endif
5394c3445
<         op = PN_OP(pn);
---
>         op = pn->pn_op;
5405,5407c3456
<                     EMIT_UINT16_IMM_OP((pn2->pn_op == JSOP_SETGVAR)
<                                        ? JSOP_GETGVAR
<                                        : (pn2->pn_op == JSOP_SETARG)
---
>                     EMIT_ATOM_INDEX_OP((pn2->pn_op == JSOP_SETARG)
5409,5410d3457
<                                        : (pn2->pn_op == JSOP_SETLOCAL)
<                                        ? JSOP_GETLOCAL
5415,5418c3462
<                 if (js_Emit1(cx, cg, JSOP_DUP) < 0)
<                     return JS_FALSE;
<                 EMIT_INDEX_OP(JSOP_GETXPROP, atomIndex);
<                 break;
---
>                 /* FALL THROUGH */
5422,5427c3466
<                 if (pn2->pn_atom == cx->runtime->atomState.lengthAtom) {
<                     if (js_Emit1(cx, cg, JSOP_LENGTH) < 0)
<                         return JS_FALSE;
<                 } else {
<                     EMIT_INDEX_OP(JSOP_GETPROP, atomIndex);
<                 }
---
>                 EMIT_ATOM_INDEX_OP(JSOP_GETPROP, atomIndex);
5433,5435d3471
< #if JS_HAS_XML_SUPPORT
<               case TOK_UNARYOP:
< #endif
5451,5463c3487,3488
<             /*
<              * Take care to avoid SRC_ASSIGNOP if the left-hand side is a
<              * const declared in a function (i.e., with non-negative pn_slot
<              * and when pn_const is true), as in this case (just a bit further
<              * below) we will avoid emitting the assignment op.
<              */
<             if (pn2->pn_type != TOK_NAME ||
<                 pn2->pn_slot < 0 ||
<                 !pn2->pn_const) {
<                 if (js_NewSrcNote(cx, cg, SRC_ASSIGNOP) < 0)
<                     return JS_FALSE;
<             }
<             if (js_Emit1(cx, cg, op) < 0)
---
>             if (js_NewSrcNote(cx, cg, SRC_ASSIGNOP) < 0 ||
>                 js_Emit1(cx, cg, op) < 0) {
5464a3490
>             }
5468,5474c3494,3496
<         if (pn2->pn_type != TOK_NAME &&
< #if JS_HAS_DESTRUCTURING
<             pn2->pn_type != TOK_RB &&
<             pn2->pn_type != TOK_RC &&
< #endif
<             js_NewSrcNote2(cx, cg, SRC_PCBASE, CG_OFFSET(cg) - top) < 0) {
<             return JS_FALSE;
---
>         if (pn2->pn_type != TOK_NAME) {
>             if (js_NewSrcNote2(cx, cg, SRC_PCBASE, CG_OFFSET(cg) - top) < 0)
>                 return JS_FALSE;
5480,5483c3502
<             if (pn2->pn_slot < 0 || !pn2->pn_const) {
<                 if (pn2->pn_slot >= 0) {
<                     EMIT_UINT16_IMM_OP(PN_OP(pn2), atomIndex);
<                 } else {
---
>             if (pn2->pn_slot < 0 || !(pn2->pn_attrs & JSPROP_READONLY)) {
5485,5486c3504
<                     EMIT_INDEX_OP(PN_OP(pn2), atomIndex);
<                 }
---
>                 EMIT_ATOM_INDEX_OP(pn2->pn_op, atomIndex);
5496,5510c3514
< #if JS_HAS_DESTRUCTURING
<           case TOK_RB:
<           case TOK_RC:
<             if (!EmitDestructuringOps(cx, cg, JSOP_SETNAME, pn2))
<                 return JS_FALSE;
<             break;
< #endif
< #if JS_HAS_XML_SUPPORT
<           case TOK_UNARYOP:
<             if (js_Emit1(cx, cg, JSOP_SETXMLNAME) < 0)
<                 return JS_FALSE;
<             break;
< #endif
<           default:
<             JS_ASSERT(0);
---
>           default:;
5530,5544d3533
< 
<         /*
<          * Because each branch pushes a single value, but our stack budgeting
<          * analysis ignores branches, we now have to adjust cg->stackDepth to
<          * ignore the value pushed by the first branch.  Execution will follow
<          * only one path, so we must decrement cg->stackDepth.
<          *
<          * Failing to do this will foil code, such as the try/catch/finally
<          * exception handling code generator, that samples cg->stackDepth for
<          * use at runtime (JSOP_SETSP), or in let expression and block code
<          * generation, which must use the stack depth to compute local stack
<          * indexes correctly.
<          */
<         JS_ASSERT(cg->stackDepth > 0);
<         cg->stackDepth--;
5549a3539,3549
> 
>         /*
>          * Because each branch pushes a single value, but our stack budgeting
>          * analysis ignores branches, we now have two values accounted for in
>          * cg->stackDepth.  Execution will follow only one path, so we must
>          * decrement cg->stackDepth here.  Failing to do this will foil code,
>          * such as the try/catch/finally exception handling code generator,
>          * that samples cg->stackDepth for use at runtime (JSOP_SETSP).
>          */
>         JS_ASSERT(cg->stackDepth > 1);
>         cg->stackDepth--;
5562a3563,3567
>          *
>          * Avoid tail recursion for long ||...|| expressions and long &&...&&
>          * expressions or long mixtures of ||'s and &&'s that can easily blow
>          * the stack, by forward-linking and then backpatching all the JSOP_OR
>          * and JSOP_AND bytecodes' immediate jump-offset operands.
5564c3569,3578
<         if (pn->pn_arity == PN_BINARY) {
---
>         pn3 = pn;
>         if (!js_EmitTree(cx, cg, pn->pn_left))
>             return JS_FALSE;
>         top = EmitJump(cx, cg, JSOP_BACKPATCH_POP, 0);
>         if (top < 0)
>             return JS_FALSE;
>         jmp = top;
>         pn2 = pn->pn_right;
>         while (pn2->pn_type == TOK_OR || pn2->pn_type == TOK_AND) {
>             pn = pn2;
5567,5585c3581,3582
<             top = EmitJump(cx, cg, JSOP_BACKPATCH_POP, 0);
<             if (top < 0)
<                 return JS_FALSE;
<             if (!js_EmitTree(cx, cg, pn->pn_right))
<                 return JS_FALSE;
<             off = CG_OFFSET(cg);
<             pc = CG_CODE(cg, top);
<             CHECK_AND_SET_JUMP_OFFSET(cx, cg, pc, off - top);
<             *pc = pn->pn_op;
<         } else {
<             JS_ASSERT(pn->pn_arity == PN_LIST);
<             JS_ASSERT(pn->pn_head->pn_next->pn_next);
< 
<             /* Left-associative operator chain: avoid too much recursion. */
<             pn2 = pn->pn_head;
<             if (!js_EmitTree(cx, cg, pn2))
<                 return JS_FALSE;
<             top = EmitJump(cx, cg, JSOP_BACKPATCH_POP, 0);
<             if (top < 0)
---
>             off = EmitJump(cx, cg, JSOP_BACKPATCH_POP, 0);
>             if (off < 0)
5587,5601c3584
< 
<             /* Emit nodes between the head and the tail. */
<             jmp = top;
<             while ((pn2 = pn2->pn_next)->pn_next) {
<                 if (!js_EmitTree(cx, cg, pn2))
<                     return JS_FALSE;
<                 off = EmitJump(cx, cg, JSOP_BACKPATCH_POP, 0);
<                 if (off < 0)
<                     return JS_FALSE;
<                 if (!SetBackPatchDelta(cx, cg, CG_CODE(cg, jmp), off - jmp))
<                     return JS_FALSE;
<                 jmp = off;
< 
<             }
<             if (!js_EmitTree(cx, cg, pn2))
---
>             if (!SetBackPatchDelta(cx, cg, CG_CODE(cg, jmp), off - jmp))
5603,5612c3586,3587
< 
<             pn2 = pn->pn_head;
<             off = CG_OFFSET(cg);
<             do {
<                 pc = CG_CODE(cg, top);
<                 tmp = GetJumpOffset(cg, pc);
<                 CHECK_AND_SET_JUMP_OFFSET(cx, cg, pc, off - top);
<                 *pc = pn->pn_op;
<                 top += tmp;
<             } while ((pn2 = pn2->pn_next)->pn_next);
---
>             jmp = off;
>             pn2 = pn->pn_right;
5613a3589,3598
>         if (!js_EmitTree(cx, cg, pn2))
>             return JS_FALSE;
>         off = CG_OFFSET(cg);
>         do {
>             jsbytecode *pc = CG_CODE(cg, top);
>             tmp = GetJumpOffset(cg, pc);
>             CHECK_AND_SET_JUMP_OFFSET(cx, cg, pc, off - top);
>             *pc = pn3->pn_op;
>             top += tmp;
>         } while ((pn3 = pn3->pn_right) != pn2);
5620a3606
> #if JS_HAS_IN_OPERATOR
5621a3608,3609
> #endif
> #if JS_HAS_INSTANCEOF
5622a3611
> #endif
5633c3622
<             op = PN_OP(pn);
---
>             op = pn->pn_op;
5641,5661d3629
< #if JS_HAS_XML_SUPPORT
<             uintN oldflags;
< 
<       case TOK_DBLCOLON:
<             if (pn->pn_arity == PN_NAME) {
<                 if (!js_EmitTree(cx, cg, pn->pn_expr))
<                     return JS_FALSE;
<                 if (!EmitAtomOp(cx, pn, PN_OP(pn), cg))
<                     return JS_FALSE;
<                 break;
<             }
< 
<             /*
<              * Binary :: has a right operand that brackets arbitrary code,
<              * possibly including a let (a = b) ... expression.  We must clear
<              * TCF_IN_FOR_INIT to avoid mis-compiling such beasts.
<              */
<             oldflags = cg->treeContext.flags;
<             cg->treeContext.flags &= ~TCF_IN_FOR_INIT;
< #endif
< 
5667,5670c3635
< #if JS_HAS_XML_SUPPORT
<             cg->treeContext.flags |= oldflags & TCF_IN_FOR_INIT;
< #endif
<             if (js_Emit1(cx, cg, PN_OP(pn)) < 0)
---
>             if (js_Emit1(cx, cg, pn->pn_op) < 0)
5674a3640
> #if JS_HAS_EXCEPTIONS
5676,5680d3641
< #if JS_HAS_XML_SUPPORT
<       case TOK_AT:
<       case TOK_DEFAULT:
<         JS_ASSERT(pn->pn_arity == PN_UNARY);
<         /* FALL THROUGH */
5683,5685d3643
<       {
<         uintN oldflags;
< 
5687,5704c3645
<         op = PN_OP(pn);
< #if JS_HAS_XML_SUPPORT
<         if (op == JSOP_XMLNAME) {
<             if (!EmitXMLName(cx, pn, op, cg))
<                 return JS_FALSE;
<             break;
<         }
< #endif
<         pn2 = pn->pn_kid;
<         if (op == JSOP_TYPEOF) {
<             for (pn3 = pn2; pn3->pn_type == TOK_RP; pn3 = pn3->pn_kid)
<                 continue;
<             if (pn3->pn_type != TOK_NAME)
<                 op = JSOP_TYPEOFEXPR;
<         }
<         oldflags = cg->treeContext.flags;
<         cg->treeContext.flags &= ~TCF_IN_FOR_INIT;
<         if (!js_EmitTree(cx, cg, pn2))
---
>         if (!js_EmitTree(cx, cg, pn->pn_kid))
5706,5707c3647
<         cg->treeContext.flags |= oldflags & TCF_IN_FOR_INIT;
<         if (js_Emit1(cx, cg, op) < 0)
---
>         if (js_Emit1(cx, cg, pn->pn_op) < 0)
5710d3649
<       }
5717c3656
<         op = PN_OP(pn);
---
>         op = pn->pn_op;
5721c3660
<             if (!BindNameToSlot(cx, cg, pn2, 0))
---
>             if (!LookupArgOrVar(cx, &cg->treeContext, pn2))
5723c3662
<             op = PN_OP(pn2);
---
>             op = pn2->pn_op;
5725,5730c3664,3665
<                 if (pn2->pn_const) {
<                     /* Incrementing a declared const: just get its value. */
<                     op = (JOF_OPTYPE(op) == JOF_ATOM)
<                          ? JSOP_GETGVAR
<                          : JSOP_GETVAR;
<                 }
---
>                 if (pn2->pn_attrs & JSPROP_READONLY)
>                     op = JSOP_GETVAR;
5732c3667
<                 EMIT_UINT16_IMM_OP(op, atomIndex);
---
>                 EMIT_ATOM_INDEX_OP(op, atomIndex);
5739c3674
<             if (!EmitPropOp(cx, pn2, op, cg, JS_FALSE))
---
>             if (!EmitPropOp(cx, pn2, op, cg))
5758,5768d3692
< #if JS_HAS_XML_SUPPORT
<           case TOK_UNARYOP:
<             JS_ASSERT(pn2->pn_op == JSOP_SETXMLNAME);
<             if (!js_EmitTree(cx, cg, pn2->pn_kid))
<                 return JS_FALSE;
<             if (js_Emit1(cx, cg, JSOP_BINDXMLNAME) < 0)
<                 return JS_FALSE;
<             if (js_Emit1(cx, cg, op) < 0)
<                 return JS_FALSE;
<             break;
< #endif
5772,5782d3695
< 
<         /*
<          * Post-increments require an extra slot for GC protection in case
<          * the initial value being post-incremented or -decremented is not a
<          * number, but converts to a jsdouble.  In the TOK_NAME cases, op has
<          * 0 operand uses and 1 definition, so we don't need an extra stack
<          * slot -- we can use the one allocated for the def.
<          */
<         JS_ASSERT(((js_CodeSpec[op].format >> JOF_TMPSLOT_SHIFT) & 1) ==
<                   ((js_CodeSpec[op].format & JOF_POST) &&
<                    pn2->pn_type != TOK_NAME));
5786,5789c3699
<         /*
<          * Under ECMA 3, deleting a non-reference returns true -- but alas we
<          * must evaluate the operand if it appears it might have side effects.
<          */
---
>         /* Under ECMA 3, deleting a non-reference returns true. */
5794c3704
<             if (!BindNameToSlot(cx, cg, pn2, 0))
---
>             if (!LookupArgOrVar(cx, &cg->treeContext, pn2))
5796c3706
<             op = PN_OP(pn2);
---
>             op = pn2->pn_op;
5806,5822c3716
<             if (!EmitPropOp(cx, pn2, JSOP_DELPROP, cg, JS_FALSE))
<                 return JS_FALSE;
<             break;
< #if JS_HAS_XML_SUPPORT
<           case TOK_DBLDOT:
<             if (!EmitElemOp(cx, pn2, JSOP_DELDESC, cg))
<                 return JS_FALSE;
<             break;
< #endif
< #if JS_HAS_LVALUE_RETURN
<           case TOK_LP:
<             top = CG_OFFSET(cg);
<             if (!js_EmitTree(cx, cg, pn2))
<                 return JS_FALSE;
<             if (js_NewSrcNote2(cx, cg, SRC_PCBASE, CG_OFFSET(cg) - top) < 0)
<                 return JS_FALSE;
<             if (js_Emit1(cx, cg, JSOP_DELELEM) < 0)
---
>             if (!EmitPropOp(cx, pn2, JSOP_DELPROP, cg))
5825d3718
< #endif
5829,6024c3722,3724
<             break;
<           default:
<             /*
<              * If useless, just emit JSOP_TRUE; otherwise convert delete foo()
<              * to foo(), true (a comma expression, requiring SRC_PCDELTA, and
<              * also JSOP_GROUP for correctly parenthesized decompilation).
<              */
<             useful = JS_FALSE;
<             if (!CheckSideEffects(cx, cg, pn2, &useful))
<                 return JS_FALSE;
<             if (!useful) {
<                 off = noteIndex = -1;
<             } else {
<                 if (!js_EmitTree(cx, cg, pn2))
<                     return JS_FALSE;
<                 off = CG_OFFSET(cg);
<                 noteIndex = js_NewSrcNote2(cx, cg, SRC_PCDELTA, 0);
<                 if (noteIndex < 0 || js_Emit1(cx, cg, JSOP_POP) < 0)
<                     return JS_FALSE;
<             }
<             if (js_Emit1(cx, cg, JSOP_TRUE) < 0)
<                 return JS_FALSE;
<             if (noteIndex >= 0) {
<                 tmp = CG_OFFSET(cg);
<                 if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 0, tmp-off))
<                     return JS_FALSE;
<             }
<             if (js_Emit1(cx, cg, JSOP_GROUP) < 0)
<                 return JS_FALSE;
<         }
<         break;
< 
< #if JS_HAS_XML_SUPPORT
<       case TOK_FILTER:
<         if (!js_EmitTree(cx, cg, pn->pn_left))
<             return JS_FALSE;
<         jmp = js_Emit3(cx, cg, JSOP_FILTER, 0, 0);
<         if (jmp < 0)
<             return JS_FALSE;
<         top = CG_OFFSET(cg);
<         if (!js_EmitTree(cx, cg, pn->pn_right))
<             return JS_FALSE;
<         CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, jmp);
<         if (EmitJump(cx, cg, JSOP_ENDFILTER, top - CG_OFFSET(cg)) < 0)
<             return JS_FALSE;
<         break;
< #endif
< 
<       case TOK_DOT:
<         /*
<          * Pop a stack operand, convert it to object, get a property named by
<          * this bytecode's immediate-indexed atom operand, and push its value
<          * (not a reference to it).
<          */
<         ok = EmitPropOp(cx, pn, PN_OP(pn), cg, JS_FALSE);
<         break;
< 
<       case TOK_LB:
< #if JS_HAS_XML_SUPPORT
<       case TOK_DBLDOT:
< #endif
<         /*
<          * Pop two operands, convert the left one to object and the right one
<          * to property name (atom or tagged int), get the named property, and
<          * push its value.  Set the "obj" register to the result of ToObject
<          * on the left operand.
<          */
<         ok = EmitElemOp(cx, pn, PN_OP(pn), cg);
<         break;
< 
<       case TOK_NEW:
<       case TOK_LP:
<       {
<         uintN oldflags;
< 
<         /*
<          * Emit function call or operator new (constructor call) code.
<          * First, emit code for the left operand to evaluate the callable or
<          * constructable object expression.
<          */
<         pn2 = pn->pn_head;
<         switch (pn2->pn_type) {
<           case TOK_NAME:
<             if (!EmitNameOp(cx, cg, pn2, JS_TRUE))
<                 return JS_FALSE;
<             break;
<           case TOK_DOT:
<             if (!EmitPropOp(cx, pn2, PN_OP(pn2), cg, JS_TRUE))
<                 return JS_FALSE;
<             break;
<           case TOK_LB:
<             JS_ASSERT(pn2->pn_op == JSOP_GETELEM);
<             if (!EmitElemOp(cx, pn2, JSOP_CALLELEM, cg))
<                 return JS_FALSE;
<             break;
<           case TOK_UNARYOP:
< #if JS_HAS_XML_SUPPORT
<             if (pn2->pn_op == JSOP_XMLNAME) {
<                 if (!EmitXMLName(cx, pn2, JSOP_CALLXMLNAME, cg))
<                     return JS_FALSE;
<                 break;
<             }
< #endif
<             /* FALL THROUGH */
<           default:
<             /*
<              * Push the appropriate global object after the expression as the
<              * |this| parameter for the function call. ECMA-262 specifies that
<              * this happens after actual argument evaluation, but the result
<              * can't be affected by argument evaluation so we do it early and
<              * avoid null testing in js_ComputeThis.
<              */
<             if (!js_EmitTree(cx, cg, pn2) ||
<                 !js_Emit1(cx, cg, JSOP_GLOBALTHIS) < 0) {
<                 return JS_FALSE;
<             }
<         }
< 
<         /* Remember start of callable-object bytecode for decompilation hint. */
<         off = top;
< 
<         /*
<          * Emit code for each argument in order, then emit the JSOP_*CALL or
<          * JSOP_NEW bytecode with a two-byte immediate telling how many args
<          * were pushed on the operand stack.
<          */
<         oldflags = cg->treeContext.flags;
<         cg->treeContext.flags &= ~TCF_IN_FOR_INIT;
<         for (pn3 = pn2->pn_next; pn3; pn3 = pn3->pn_next) {
<             if (!js_EmitTree(cx, cg, pn3))
<                 return JS_FALSE;
<         }
<         cg->treeContext.flags |= oldflags & TCF_IN_FOR_INIT;
<         if (js_NewSrcNote2(cx, cg, SRC_PCBASE, CG_OFFSET(cg) - off) < 0)
<             return JS_FALSE;
< 
<         argc = pn->pn_count - 1;
<         if (js_Emit3(cx, cg, PN_OP(pn), ARGC_HI(argc), ARGC_LO(argc)) < 0)
<             return JS_FALSE;
<         break;
<       }
< 
<       case TOK_LEXICALSCOPE:
<       {
<         JSObject *obj;
<         jsint count;
< 
<         obj = pn->pn_pob->object;
<         js_PushBlockScope(&cg->treeContext, &stmtInfo, obj, CG_OFFSET(cg));
< 
<         OBJ_SET_BLOCK_DEPTH(cx, obj, cg->stackDepth);
<         count = OBJ_BLOCK_COUNT(cx, obj);
<         cg->stackDepth += count;
<         if ((uintN)cg->stackDepth > cg->maxStackDepth)
<             cg->maxStackDepth = cg->stackDepth;
< 
<         /*
<          * If this lexical scope is not for a catch block, let block or let
<          * expression, or any kind of for loop (where the scope starts in the
<          * head after the first part if for (;;), else in the body if for-in);
<          * and if our container is top-level but not a function body, or else
<          * a block statement; then emit a SRC_BRACE note.  All other container
<          * statements get braces by default from the decompiler.
<          */
<         noteIndex = -1;
<         type = PN_TYPE(pn->pn_expr);
<         if (type != TOK_CATCH && type != TOK_LET && type != TOK_FOR &&
<             (!(stmt = stmtInfo.down)
<              ? !(cg->treeContext.flags & TCF_IN_FUNCTION)
<              : stmt->type == STMT_BLOCK)) {
< #if defined DEBUG_brendanXXX || defined DEBUG_mrbkap
<             /* There must be no source note already output for the next op. */
<             JS_ASSERT(CG_NOTE_COUNT(cg) == 0 ||
<                       CG_LAST_NOTE_OFFSET(cg) != CG_OFFSET(cg) ||
<                       !GettableNoteForNextOp(cg));
< #endif
<             noteIndex = js_NewSrcNote2(cx, cg, SRC_BRACE, 0);
<             if (noteIndex < 0)
<                 return JS_FALSE;
<         }
< 
<         JS_ASSERT(CG_OFFSET(cg) == top);
<         if (!EmitObjectOp(cx, pn->pn_pob, JSOP_ENTERBLOCK, cg))
<             return JS_FALSE;
< 
<         if (!js_EmitTree(cx, cg, pn->pn_expr))
<             return JS_FALSE;
< 
<         op = PN_OP(pn);
<         if (op == JSOP_LEAVEBLOCKEXPR) {
<             if (js_NewSrcNote2(cx, cg, SRC_PCBASE, CG_OFFSET(cg) - top) < 0)
<                 return JS_FALSE;
<         } else {
<             if (noteIndex >= 0 &&
<                 !js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 0,
<                                      CG_OFFSET(cg) - top)) {
---
>             break;
>           default:
>             if (js_Emit1(cx, cg, JSOP_TRUE) < 0)
6026d3725
<             }
6027a3727
>         break;
6029,6033c3729,3737
<         /* Emit the JSOP_LEAVEBLOCK or JSOP_LEAVEBLOCKEXPR opcode. */
<         EMIT_UINT16_IMM_OP(op, count);
<         cg->stackDepth -= count;
< 
<         ok = js_PopStatementCG(cx, cg);
---
>       case TOK_DOT:
>         /*
>          * Pop a stack operand, convert it to object, get a property named by
>          * this bytecode's immediate-indexed atom operand, and push its value
>          * (not a reference to it).  This bytecode sets the virtual machine's
>          * "obj" register to the left operand's ToObject conversion result,
>          * for use by JSOP_PUSHOBJ.
>          */
>         ok = EmitPropOp(cx, pn, pn->pn_op, cg);
6035d3738
<       }
6037,6045c3740,3748
< #if JS_HAS_BLOCK_SCOPE
<       case TOK_LET:
<         /* Let statements have their variable declarations on the left. */
<         if (pn->pn_arity == PN_BINARY) {
<             pn2 = pn->pn_right;
<             pn = pn->pn_left;
<         } else {
<             pn2 = NULL;
<         }
---
>       case TOK_LB:
>         /*
>          * Pop two operands, convert the left one to object and the right one
>          * to property name (atom or tagged int), get the named property, and
>          * push its value.  Set the "obj" register to the result of ToObject
>          * on the left operand.
>          */
>         ok = EmitElemOp(cx, pn, pn->pn_op, cg);
>         break;
6047,6049c3750,3758
<         /* Non-null pn2 means that pn is the variable list from a let head. */
<         JS_ASSERT(pn->pn_arity == PN_LIST);
<         if (!EmitVariables(cx, cg, pn, pn2 != NULL, &noteIndex))
---
>       case TOK_NEW:
>       case TOK_LP:
>         /*
>          * Emit function call or operator new (constructor call) code.
>          * First, emit code for the left operand to evaluate the callable or
>          * constructable object expression.
>          */
>         pn2 = pn->pn_head;
>         if (!js_EmitTree(cx, cg, pn2))
6052,6055c3761,3762
<         /* Thus non-null pn2 is the body of the let block or expression. */
<         tmp = CG_OFFSET(cg);
<         if (pn2 && !js_EmitTree(cx, cg, pn2))
<             return JS_FALSE;
---
>         /* Remember start of callable-object bytecode for decompilation hint. */
>         off = pn2->pn_offset;
6057,6059c3764,3768
<         if (noteIndex >= 0 &&
<             !js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 0,
<                                  CG_OFFSET(cg) - tmp)) {
---
>         /*
>          * Push the virtual machine's "obj" register, which was set by a name,
>          * property, or element get (or set) bytecode.
>          */
>         if (js_Emit1(cx, cg, JSOP_PUSHOBJ) < 0)
6061,6063d3769
<         }
<         break;
< #endif /* JS_HAS_BLOCK_SCOPE */
6065,6066d3770
< #if JS_HAS_GENERATORS
<        case TOK_ARRAYPUSH:
6068,6070c3772,3774
<          * The array object's stack index is in cg->arrayCompSlot.  See below
<          * under the array initialiser code generator for array comprehension
<          * special casing.
---
>          * Emit code for each argument in order, then emit the JSOP_*CALL or
>          * JSOP_NEW bytecode with a two-byte immediate telling how many args
>          * were pushed on the operand stack.
6072c3776,3783
<         if (!js_EmitTree(cx, cg, pn->pn_kid))
---
>         for (pn2 = pn2->pn_next; pn2; pn2 = pn2->pn_next) {
>             if (!js_EmitTree(cx, cg, pn2))
>                 return JS_FALSE;
>         }
>         if (js_NewSrcNote2(cx, cg, SRC_PCBASE, CG_OFFSET(cg) - off) < 0)
>             return JS_FALSE;
>         argc = pn->pn_count - 1;
>         if (js_Emit3(cx, cg, pn->pn_op, ARGC_HI(argc), ARGC_LO(argc)) < 0)
6074d3784
<         EMIT_UINT16_IMM_OP(PN_OP(pn), cg->arrayCompSlot);
6076d3785
< #endif
6077a3787
> #if JS_HAS_INITIALIZERS
6079,6081d3788
< #if JS_HAS_GENERATORS
<       case TOK_ARRAYCOMP:
< #endif
6088c3795,3802
<         if (js_Emit2(cx, cg, JSOP_NEWINIT, (jsbytecode) JSProto_Array) < 0)
---
>         ale = js_IndexAtom(cx, cx->runtime->atomState.ArrayAtom,
>                            &cg->atomList);
>         if (!ale)
>             return JS_FALSE;
>         EMIT_ATOM_INDEX_OP(JSOP_NAME, ALE_INDEX(ale));
>         if (js_Emit1(cx, cg, JSOP_PUSHOBJ) < 0)
>             return JS_FALSE;
>         if (js_Emit1(cx, cg, JSOP_NEWINIT) < 0)
6094c3808
<             EMIT_UINT16_IMM_OP(JSOP_DEFSHARP, (jsatomid)pn2->pn_num);
---
>             EMIT_ATOM_INDEX_OP(JSOP_DEFSHARP, (jsatomid)pn2->pn_num);
6099,6124c3813,3824
< #if JS_HAS_GENERATORS
<         if (pn->pn_type == TOK_ARRAYCOMP) {
<             uintN saveSlot;
< 
<             /*
<              * Pass the new array's stack index to the TOK_ARRAYPUSH case by
<              * storing it in pn->pn_extra, then simply traverse the TOK_FOR
<              * node and its kids under pn2 to generate this comprehension.
<              */
<             JS_ASSERT(cg->stackDepth > 0);
<             saveSlot = cg->arrayCompSlot;
<             cg->arrayCompSlot = (uint32) (cg->stackDepth - 1);
<             if (!js_EmitTree(cx, cg, pn2))
<                 return JS_FALSE;
<             cg->arrayCompSlot = saveSlot;
< 
<             /* Emit the usual op needed for decompilation. */
<             if (js_Emit1(cx, cg, JSOP_ENDINIT) < 0)
<                 return JS_FALSE;
<             break;
<         }
< #endif /* JS_HAS_GENERATORS */
< 
<         for (atomIndex = 0; pn2; atomIndex++, pn2 = pn2->pn_next) {
<             if (!EmitNumberOp(cx, atomIndex, cg))
<                 return JS_FALSE;
---
>         for (atomIndex = 0; pn2; pn2 = pn2->pn_next) {
>             /* PrimaryExpr enforced ATOM_INDEX_LIMIT, so in-line optimize. */
>             JS_ASSERT(atomIndex < ATOM_INDEX_LIMIT);
>             if (atomIndex == 0) {
>                 if (js_Emit1(cx, cg, JSOP_ZERO) < 0)
>                     return JS_FALSE;
>             } else if (atomIndex == 1) {
>                 if (js_Emit1(cx, cg, JSOP_ONE) < 0)
>                     return JS_FALSE;
>             } else {
>                 EMIT_ATOM_INDEX_OP(JSOP_UINT16, (jsatomid)atomIndex);
>             }
6126c3826
<             /* FIXME 260106: holes in a sparse initializer are void-filled. */
---
>             /* Sub-optimal: holes in a sparse initializer are void-filled. */
6134d3833
< 
6136a3836,3837
> 
>             atomIndex++;
6139c3840
<         if (pn->pn_extra & PNX_ENDCOMMA) {
---
>         if (pn->pn_extra) {
6151,6157d3851
< #if JS_HAS_DESTRUCTURING_SHORTHAND
<         if (pn->pn_extra & PNX_SHORTHAND) {
<             js_ReportCompileErrorNumber(cx, CG_TS(cg), pn, JSREPORT_ERROR,
<                                         JSMSG_BAD_OBJECT_INIT);
<             return JS_FALSE;
<         }
< #endif
6164c3858,3866
<         if (js_Emit2(cx, cg, JSOP_NEWINIT, (jsbytecode) JSProto_Object) < 0)
---
>         ale = js_IndexAtom(cx, cx->runtime->atomState.ObjectAtom,
>                            &cg->atomList);
>         if (!ale)
>             return JS_FALSE;
>         EMIT_ATOM_INDEX_OP(JSOP_NAME, ALE_INDEX(ale));
> 
>         if (js_Emit1(cx, cg, JSOP_PUSHOBJ) < 0)
>             return JS_FALSE;
>         if (js_Emit1(cx, cg, JSOP_NEWINIT) < 0)
6170c3872
<             EMIT_UINT16_IMM_OP(JSOP_DEFSHARP, (jsatomid)pn2->pn_num);
---
>             EMIT_ATOM_INDEX_OP(JSOP_DEFSHARP, (jsatomid)pn2->pn_num);
6178,6181c3880,3881
<             if (pn3->pn_type == TOK_NUMBER) {
< #ifdef __GNUC__
<                 ale = NULL;     /* quell GCC overwarning */
< #endif
---
>             switch (pn3->pn_type) {
>               case TOK_NUMBER:
6184,6186c3884,3886
<             } else {
<                 JS_ASSERT(pn3->pn_type == TOK_NAME ||
<                           pn3->pn_type == TOK_STRING);
---
>                 break;
>               case TOK_NAME:
>               case TOK_STRING:
6189a3890,3892
>                 break;
>               default:
>                 JS_ASSERT(0);
6197c3900
<             op = PN_OP(pn2);
---
>             op = pn2->pn_op;
6205c3908
<                 if (js_NewSrcNote(cx, cg, SRC_INITPROP) < 0)
---
>                 if (js_NewSrcNote(cx, cg, SRC_LABEL) < 0)
6210c3913
<                 EMIT_INDEX_OP(JSOP_INITPROP, ALE_INDEX(ale));
---
>                 EMIT_ATOM_INDEX_OP(JSOP_INITPROP, ALE_INDEX(ale));
6223c3926
<         EMIT_UINT16_IMM_OP(JSOP_DEFSHARP, (jsatomid) pn->pn_num);
---
>         EMIT_ATOM_INDEX_OP(JSOP_DEFSHARP, (jsatomid) pn->pn_num);
6227c3930
<         EMIT_UINT16_IMM_OP(JSOP_USESHARP, (jsatomid) pn->pn_num);
---
>         EMIT_ATOM_INDEX_OP(JSOP_USESHARP, (jsatomid) pn->pn_num);
6229a3933
> #endif /* JS_HAS_INITIALIZERS */
6232,6234d3935
<       {
<         uintN oldflags;
< 
6240,6241d3940
<         oldflags = cg->treeContext.flags;
<         cg->treeContext.flags &= ~TCF_IN_FOR_INIT;
6244d3942
<         cg->treeContext.flags |= oldflags & TCF_IN_FOR_INIT;
6248d3945
<       }
6251c3948
<         if (!EmitNameOp(cx, cg, pn, JS_FALSE))
---
>         if (!LookupArgOrVar(cx, &cg->treeContext, pn))
6253,6261c3950,3961
<         break;
< 
< #if JS_HAS_XML_SUPPORT
<       case TOK_XMLATTR:
<       case TOK_XMLSPACE:
<       case TOK_XMLTEXT:
<       case TOK_XMLCDATA:
<       case TOK_XMLCOMMENT:
< #endif
---
>         op = pn->pn_op;
>         if (op == JSOP_ARGUMENTS) {
>             if (js_Emit1(cx, cg, op) < 0)
>                 return JS_FALSE;
>             break;
>         }
>         if (pn->pn_slot >= 0) {
>             atomIndex = (jsatomid) pn->pn_slot;
>             EMIT_ATOM_INDEX_OP(op, atomIndex);
>             break;
>         }
>         /* FALL THROUGH */
6263c3963,3975
<         ok = EmitAtomOp(cx, pn, PN_OP(pn), cg);
---
>       case TOK_OBJECT:
>         /*
>          * The scanner and parser associate JSOP_NAME with TOK_NAME, although
>          * other bytecodes may result instead (JSOP_BINDNAME/JSOP_SETNAME,
>          * JSOP_FORNAME, etc.).  Among JSOP_*NAME* variants, only JSOP_NAME
>          * may generate the first operand of a call or new expression, so only
>          * it sets the "obj" virtual machine register to the object along the
>          * scope chain in which the name was found.
>          *
>          * Token types for STRING and OBJECT have corresponding bytecode ops
>          * in pn_op and emit the same format as NAME, so they share this code.
>          */
>         ok = EmitAtomOp(cx, pn, pn->pn_op, cg);
6270,6290d3981
<       case TOK_REGEXP:
<         /*
<          * If the regexp's script is one-shot, we can avoid the extra
<          * fork-on-exec costs of JSOP_REGEXP by selecting JSOP_OBJECT.
<          * Otherwise, to avoid incorrect proto, parent, and lastIndex
<          * sharing among threads and sequentially across re-execution,
<          * select JSOP_REGEXP.
<          */
<         JS_ASSERT(pn->pn_op == JSOP_REGEXP);
<         if (cg->treeContext.flags & TCF_COMPILE_N_GO) {
<             ok = EmitObjectOp(cx, pn->pn_pob, JSOP_OBJECT, cg);
<         } else {
<             ok = EmitIndexOp(cx, JSOP_REGEXP,
<                              IndexParsedObject(pn->pn_pob, &cg->regexpList),
<                              cg);
<         }
<         break;
< 
< #if JS_HAS_XML_SUPPORT
<       case TOK_ANYNAME:
< #endif
6292c3983
<         if (js_Emit1(cx, cg, PN_OP(pn)) < 0)
---
>         if (js_Emit1(cx, cg, pn->pn_op) < 0)
6303,6446d3993
< #if JS_HAS_XML_SUPPORT
<       case TOK_XMLELEM:
<       case TOK_XMLLIST:
<         if (pn->pn_op == JSOP_XMLOBJECT) {
<             ok = EmitObjectOp(cx, pn->pn_pob, PN_OP(pn), cg);
<             break;
<         }
< 
<         JS_ASSERT(pn->pn_type == TOK_XMLLIST || pn->pn_count != 0);
<         switch (pn->pn_head ? pn->pn_head->pn_type : TOK_XMLLIST) {
<           case TOK_XMLETAGO:
<             JS_ASSERT(0);
<             /* FALL THROUGH */
<           case TOK_XMLPTAGC:
<           case TOK_XMLSTAGO:
<             break;
<           default:
<             if (js_Emit1(cx, cg, JSOP_STARTXML) < 0)
<                 return JS_FALSE;
<         }
< 
<         for (pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) {
<             if (pn2->pn_type == TOK_LC &&
<                 js_Emit1(cx, cg, JSOP_STARTXMLEXPR) < 0) {
<                 return JS_FALSE;
<             }
<             if (!js_EmitTree(cx, cg, pn2))
<                 return JS_FALSE;
<             if (pn2 != pn->pn_head && js_Emit1(cx, cg, JSOP_ADD) < 0)
<                 return JS_FALSE;
<         }
< 
<         if (pn->pn_extra & PNX_XMLROOT) {
<             if (pn->pn_count == 0) {
<                 JS_ASSERT(pn->pn_type == TOK_XMLLIST);
<                 atom = cx->runtime->atomState.emptyAtom;
<                 ale = js_IndexAtom(cx, atom, &cg->atomList);
<                 if (!ale)
<                     return JS_FALSE;
<                 EMIT_INDEX_OP(JSOP_STRING, ALE_INDEX(ale));
<             }
<             if (js_Emit1(cx, cg, PN_OP(pn)) < 0)
<                 return JS_FALSE;
<         }
< #ifdef DEBUG
<         else
<             JS_ASSERT(pn->pn_count != 0);
< #endif
<         break;
< 
<       case TOK_XMLPTAGC:
<         if (pn->pn_op == JSOP_XMLOBJECT) {
<             ok = EmitObjectOp(cx, pn->pn_pob, PN_OP(pn), cg);
<             break;
<         }
<         /* FALL THROUGH */
< 
<       case TOK_XMLSTAGO:
<       case TOK_XMLETAGO:
<       {
<         uint32 i;
< 
<         if (js_Emit1(cx, cg, JSOP_STARTXML) < 0)
<             return JS_FALSE;
< 
<         ale = js_IndexAtom(cx,
<                            (pn->pn_type == TOK_XMLETAGO)
<                            ? cx->runtime->atomState.etagoAtom
<                            : cx->runtime->atomState.stagoAtom,
<                            &cg->atomList);
<         if (!ale)
<             return JS_FALSE;
<         EMIT_INDEX_OP(JSOP_STRING, ALE_INDEX(ale));
< 
<         JS_ASSERT(pn->pn_count != 0);
<         pn2 = pn->pn_head;
<         if (pn2->pn_type == TOK_LC && js_Emit1(cx, cg, JSOP_STARTXMLEXPR) < 0)
<             return JS_FALSE;
<         if (!js_EmitTree(cx, cg, pn2))
<             return JS_FALSE;
<         if (js_Emit1(cx, cg, JSOP_ADD) < 0)
<             return JS_FALSE;
< 
<         for (pn2 = pn2->pn_next, i = 0; pn2; pn2 = pn2->pn_next, i++) {
<             if (pn2->pn_type == TOK_LC &&
<                 js_Emit1(cx, cg, JSOP_STARTXMLEXPR) < 0) {
<                 return JS_FALSE;
<             }
<             if (!js_EmitTree(cx, cg, pn2))
<                 return JS_FALSE;
<             if ((i & 1) && pn2->pn_type == TOK_LC) {
<                 if (js_Emit1(cx, cg, JSOP_TOATTRVAL) < 0)
<                     return JS_FALSE;
<             }
<             if (js_Emit1(cx, cg,
<                          (i & 1) ? JSOP_ADDATTRVAL : JSOP_ADDATTRNAME) < 0) {
<                 return JS_FALSE;
<             }
<         }
< 
<         ale = js_IndexAtom(cx,
<                            (pn->pn_type == TOK_XMLPTAGC)
<                            ? cx->runtime->atomState.ptagcAtom
<                            : cx->runtime->atomState.tagcAtom,
<                            &cg->atomList);
<         if (!ale)
<             return JS_FALSE;
<         EMIT_INDEX_OP(JSOP_STRING, ALE_INDEX(ale));
<         if (js_Emit1(cx, cg, JSOP_ADD) < 0)
<             return JS_FALSE;
< 
<         if ((pn->pn_extra & PNX_XMLROOT) && js_Emit1(cx, cg, PN_OP(pn)) < 0)
<             return JS_FALSE;
<         break;
<       }
< 
<       case TOK_XMLNAME:
<         if (pn->pn_arity == PN_LIST) {
<             JS_ASSERT(pn->pn_count != 0);
<             for (pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) {
<                 if (!js_EmitTree(cx, cg, pn2))
<                     return JS_FALSE;
<                 if (pn2 != pn->pn_head && js_Emit1(cx, cg, JSOP_ADD) < 0)
<                     return JS_FALSE;
<             }
<         } else {
<             JS_ASSERT(pn->pn_arity == PN_NULLARY);
<             ok = (pn->pn_op == JSOP_OBJECT)
<                  ? EmitObjectOp(cx, pn->pn_pob, PN_OP(pn), cg)
<                  : EmitAtomOp(cx, pn, PN_OP(pn), cg);
<         }
<         break;
< 
<       case TOK_XMLPI:
<         ale = js_IndexAtom(cx, pn->pn_atom2, &cg->atomList);
<         if (!ale)
<             return JS_FALSE;
<         if (!EmitIndexOp(cx, JSOP_QNAMEPART, ALE_INDEX(ale), cg))
<             return JS_FALSE;
<         if (!EmitAtomOp(cx, pn, JSOP_XMLPI, cg))
<             return JS_FALSE;
<         break;
< #endif /* JS_HAS_XML_SUPPORT */
< 
6457d4003
< /* XXX get rid of offsetBias, it's used only by SRC_FOR and SRC_DECL */
6461c4007
<     {"if-else",         2,      0,      1},
---
>     {"if-else",         1,      0,      1},
6465c4011
<     {"decl",            1,      1,      1},
---
>     {"var",             0,      0,      0},
6469c4015
<     {"brace",           1,      0,      1},
---
>     {"reserved0",       0,      0,      0},
6479,6480c4025,4026
<     {"catch",           1,      0,      1},
<     {"extended",       -1,      0,      0},
---
>     {"catch",           1,     11,      1},
>     {"const",           0,      0,      0},
6493,6497c4039,4043
<     index = CG_NOTE_COUNT(cg);
<     if (((uintN)index & CG_NOTE_MASK(cg)) == 0) {
<         pool = cg->notePool;
<         size = SRCNOTE_SIZE(CG_NOTE_MASK(cg) + 1);
<         if (!CG_NOTES(cg)) {
---
>     index = cg->noteCount;
>     if (((uintN)index & cg->noteMask) == 0) {
>         pool = &cx->notePool;
>         size = SRCNOTE_SIZE(cg->noteMask + 1);
>         if (!cg->notes) {
6499c4045
<             JS_ARENA_ALLOCATE_CAST(CG_NOTES(cg), jssrcnote *, pool, size);
---
>             JS_ARENA_ALLOCATE_CAST(cg->notes, jssrcnote *, pool, size);
6502,6504c4048,4050
<             JS_ARENA_GROW_CAST(CG_NOTES(cg), jssrcnote *, pool, size, size);
<             if (CG_NOTES(cg))
<                 CG_NOTE_MASK(cg) = (CG_NOTE_MASK(cg) << 1) | 1;
---
>             JS_ARENA_GROW_CAST(cg->notes, jssrcnote *, pool, size, size);
>             if (cg->notes)
>                 cg->noteMask = (cg->noteMask << 1) | 1;
6506,6507c4052,4053
<         if (!CG_NOTES(cg)) {
<             js_ReportOutOfScriptQuota(cx);
---
>         if (!cg->notes) {
>             JS_ReportOutOfMemory(cx);
6512c4058
<     CG_NOTE_COUNT(cg) = index + 1;
---
>     cg->noteCount = index + 1;
6524,6525c4070,4071
<      * Claim a note slot in CG_NOTES(cg) by growing it if necessary and then
<      * incrementing CG_NOTE_COUNT(cg).
---
>      * Claim a note slot in cg->notes by growing it if necessary and then
>      * incrementing cg->noteCount.
6530c4076
<     sn = &CG_NOTES(cg)[index];
---
>     sn = &cg->notes[index];
6537,6538c4083,4084
<     delta = offset - CG_LAST_NOTE_OFFSET(cg);
<     CG_LAST_NOTE_OFFSET(cg) = offset;
---
>     delta = offset - cg->lastNoteOffset;
>     cg->lastNoteOffset = offset;
6547c4093
<             sn = &CG_NOTES(cg)[index];
---
>             sn = &cg->notes[index];
6554c4100
<      * does take two bytes, js_SetSrcNoteOffset will grow CG_NOTES(cg).
---
>      * does take two bytes, js_SetSrcNoteOffset will grow cg->notes.
6601,6605c4147,4151
<     pool = cg->notePool;
<     size = SRCNOTE_SIZE(CG_NOTE_MASK(cg) + 1);
<     JS_ARENA_GROW_CAST(CG_NOTES(cg), jssrcnote *, pool, size, size);
<     if (!CG_NOTES(cg)) {
<         js_ReportOutOfScriptQuota(cx);
---
>     pool = &cx->notePool;
>     size = SRCNOTE_SIZE(cg->noteMask + 1);
>     JS_ARENA_GROW_CAST(cg->notes, jssrcnote *, pool, size, size);
>     if (!cg->notes) {
>         JS_ReportOutOfMemory(cx);
6608c4154
<     CG_NOTE_MASK(cg) = (CG_NOTE_MASK(cg) << 1) | 1;
---
>     cg->noteMask = (cg->noteMask << 1) | 1;
6619,6625c4165
<     /*
<      * Called only from OptimizeSpanDeps and js_FinishTakingSrcNotes to add to
<      * main script note deltas, and only by a small positive amount.
<      */
<     JS_ASSERT(cg->current == &cg->main);
<     JS_ASSERT((unsigned) delta < (unsigned) SN_XDELTA_LIMIT);
< 
---
>     JS_ASSERT(delta < SN_XDELTA_LIMIT);
6632,6633c4172,4173
<         index = sn - cg->main.notes;
<         if ((cg->main.noteCount & cg->main.noteMask) == 0) {
---
>         index = sn - cg->notes;
>         if ((cg->noteCount & cg->noteMask) == 0) {
6636c4176
<             sn = cg->main.notes + index;
---
>             sn = cg->notes + index;
6638,6639c4178,4179
<         diff = cg->main.noteCount - index;
<         cg->main.noteCount++;
---
>         diff = cg->noteCount - index;
>         cg->noteCount++;
6647c4187
< JS_FRIEND_API(uintN)
---
> uintN
6654c4194
<     for (base = sn++; arity; sn++, arity--) {
---
>     for (base = sn++; arity--; sn++) {
6672,6674c4212,4213
<         return (ptrdiff_t)(((uint32)(sn[0] & SN_3BYTE_OFFSET_MASK) << 16)
<                            | (sn[1] << 8)
<                            | sn[2]);
---
>         return (ptrdiff_t)((((uint32)(sn[0] & SN_3BYTE_OFFSET_MASK)) << 16)
>                            | (sn[1] << 8) | sn[2]);
6686c4225
<     if ((jsuword)offset >= (jsuword)((ptrdiff_t)SN_3BYTE_OFFSET_FLAG << 16)) {
---
>     if ((jsuword)offset >= (jsuword)(((ptrdiff_t)SN_3BYTE_OFFSET_FLAG) << 16)) {
6692c4231
<     sn = &CG_NOTES(cg)[index];
---
>     sn = &cg->notes[index];
6705c4244
<             index = PTRDIFF(sn, CG_NOTES(cg), jssrcnote);
---
>             index = PTRDIFF(sn, cg->notes, jssrcnote);
6712c4251
<             if (((CG_NOTE_COUNT(cg) + 1) & CG_NOTE_MASK(cg)) <= 1) {
---
>             if (((cg->noteCount + 1) & cg->noteMask) <= 1) {
6715c4254
<                 sn = CG_NOTES(cg) + index;
---
>                 sn = cg->notes + index;
6717c4256
<             CG_NOTE_COUNT(cg) += 2;
---
>             cg->noteCount += 2;
6719c4258
<             diff = CG_NOTE_COUNT(cg) - (index + 3);
---
>             diff = cg->noteCount - (index + 3);
6731,6733c4270,4274
< #ifdef DEBUG_notme
< #define DEBUG_srcnotesize
< #endif
---
> jssrcnote *
> js_FinishTakingSrcNotes(JSContext *cx, JSCodeGenerator *cg)
> {
>     uintN count;
>     jssrcnote *tmp, *final;
6735,6757c4276,4284
< #ifdef DEBUG_srcnotesize
< #define NBINS 10
< static uint32 hist[NBINS];
< 
< void DumpSrcNoteSizeHist()
< {
<     static FILE *fp;
<     int i, n;
< 
<     if (!fp) {
<         fp = fopen("/tmp/srcnotes.hist", "w");
<         if (!fp)
<             return;
<         setvbuf(fp, NULL, _IONBF, 0);
<     }
<     fprintf(fp, "SrcNote size histogram:\n");
<     for (i = 0; i < NBINS; i++) {
<         fprintf(fp, "%4u %4u ", JS_BIT(i), hist[i]);
<         for (n = (int) JS_HOWMANY(hist[i], 10); n > 0; --n)
<             fputc('*', fp);
<         fputc('\n', fp);
<     }
<     fputc('\n', fp);
---
>     count = cg->noteCount;
>     tmp   = cg->notes;
>  	XMEMTAG("jsemit js_FinishTakingSrcNotes");
>     final = (jssrcnote *) JS_malloc(cx, SRCNOTE_SIZE(count + 1));
>     if (!final)
>         return NULL;
>     memcpy(final, tmp, SRCNOTE_SIZE(count));
>     SN_MAKE_TERMINATOR(&final[count]);
>     return final;
6759d4285
< #endif
6761,6766d4286
< /*
<  * Fill in the storage at notes with prolog and main srcnotes; the space at
<  * notes was allocated using the CG_COUNT_FINAL_SRCNOTES macro from jsemit.h.
<  * SO DON'T CHANGE THIS FUNCTION WITHOUT AT LEAST CHECKING WHETHER jsemit.h's
<  * CG_COUNT_FINAL_SRCNOTES MACRO NEEDS CORRESPONDING CHANGES!
<  */
6768c4288
< js_FinishTakingSrcNotes(JSContext *cx, JSCodeGenerator *cg, jssrcnote *notes)
---
> js_AllocTryNotes(JSContext *cx, JSCodeGenerator *cg)
6770,6772c4290,4291
<     uintN prologCount, mainCount, totalCount;
<     ptrdiff_t offset, delta;
<     jssrcnote *sn;
---
>     size_t size, incr;
>     ptrdiff_t delta;
6774c4293,4295
<     JS_ASSERT(cg->current == &cg->main);
---
>     size = TRYNOTE_SIZE(cg->treeContext.tryCount);
>     if (size <= cg->tryNoteSpace)
>         return JS_TRUE;
6776,6779c4297,4308
<     prologCount = cg->prolog.noteCount;
<     if (prologCount && cg->prolog.currentLine != cg->firstLine) {
<         CG_SWITCH_TO_PROLOG(cg);
<         if (js_NewSrcNote2(cx, cg, SRC_SETLINE, (ptrdiff_t)cg->firstLine) < 0)
---
>     /*
>      * Allocate trynotes from cx->tempPool.
>      * XXX Too much growing and we bloat, as other tempPool allocators block
>      * in-place growth, and we never recycle old free space in an arena.
>      * YYY But once we consume an entire arena, we'll realloc it, letting the
>      * malloc heap recycle old space, while still freeing _en masse_ via the
>      * arena pool.
>      */
>     if (!cg->tryBase) {
>         size = JS_ROUNDUP(size, TRYNOTE_SIZE(TRYNOTE_GRAIN));
>         JS_ARENA_ALLOCATE_CAST(cg->tryBase, JSTryNote *, &cx->tempPool, size);
>         if (!cg->tryBase)
6781,6782c4310,4311
<         prologCount = cg->prolog.noteCount;
<         CG_SWITCH_TO_MAIN(cg);
---
>         cg->tryNoteSpace = size;
>         cg->tryNext = cg->tryBase;
6784,6844c4313,4321
<         /*
<          * Either no prolog srcnotes, or no line number change over prolog.
<          * We don't need a SRC_SETLINE, but we may need to adjust the offset
<          * of the first main note, by adding to its delta and possibly even
<          * prepending SRC_XDELTA notes to it to account for prolog bytecodes
<          * that came at and after the last annotated bytecode.
<          */
<         offset = CG_PROLOG_OFFSET(cg) - cg->prolog.lastNoteOffset;
<         JS_ASSERT(offset >= 0);
<         if (offset > 0 && cg->main.noteCount != 0) {
<             /* NB: Use as much of the first main note's delta as we can. */
<             sn = cg->main.notes;
<             delta = SN_IS_XDELTA(sn)
<                     ? SN_XDELTA_MASK - (*sn & SN_XDELTA_MASK)
<                     : SN_DELTA_MASK - (*sn & SN_DELTA_MASK);
<             if (offset < delta)
<                 delta = offset;
<             for (;;) {
<                 if (!js_AddToSrcNoteDelta(cx, cg, sn, delta))
<                     return JS_FALSE;
<                 offset -= delta;
<                 if (offset == 0)
<                     break;
<                 delta = JS_MIN(offset, SN_XDELTA_MASK);
<                 sn = cg->main.notes;
<             }
<         }
<     }
< 
<     mainCount = cg->main.noteCount;
<     totalCount = prologCount + mainCount;
<     if (prologCount)
<         memcpy(notes, cg->prolog.notes, SRCNOTE_SIZE(prologCount));
<     memcpy(notes + prologCount, cg->main.notes, SRCNOTE_SIZE(mainCount));
<     SN_MAKE_TERMINATOR(&notes[totalCount]);
< 
< #ifdef DEBUG_notme
<   { int bin = JS_CeilingLog2(totalCount);
<     if (bin >= NBINS)
<         bin = NBINS - 1;
<     ++hist[bin];
<   }
< #endif
<     return JS_TRUE;
< }
< 
< static JSBool
< NewTryNote(JSContext *cx, JSCodeGenerator *cg, JSTryNoteKind kind,
<            uintN stackDepth, size_t start, size_t end)
< {
<     JSTryNode *tryNode;
< 
<     JS_ASSERT((uintN)(uint16)stackDepth == stackDepth);
<     JS_ASSERT(start <= end);
<     JS_ASSERT((size_t)(uint32)start == start);
<     JS_ASSERT((size_t)(uint32)end == end);
< 
<     JS_ARENA_ALLOCATE_TYPE(tryNode, JSTryNode, &cx->tempPool);
<     if (!tryNode) {
<         js_ReportOutOfScriptQuota(cx);
<         return JS_FALSE;
---
>         delta = PTRDIFF((char *)cg->tryNext, (char *)cg->tryBase, char);
>         incr = size - cg->tryNoteSpace;
>         incr = JS_ROUNDUP(incr, TRYNOTE_SIZE(TRYNOTE_GRAIN));
>         size = cg->tryNoteSpace;
>         JS_ARENA_GROW_CAST(cg->tryBase, JSTryNote *, &cx->tempPool, size, incr);
>         if (!cg->tryBase)
>             return JS_FALSE;
>         cg->tryNoteSpace = size + incr;
>         cg->tryNext = (JSTryNote *)((char *)cg->tryBase + delta);
6846,6853d4322
< 
<     tryNode->note.kind = kind;
<     tryNode->note.stackDepth = (uint16)stackDepth;
<     tryNode->note.start = (uint32)start;
<     tryNode->note.length = (uint32)(end - start);
<     tryNode->prev = cg->lastTryNode;
<     cg->lastTryNode = tryNode;
<     cg->ntrynotes++;
6857,6858c4326,4328
< void
< js_FinishTakingTryNotes(JSCodeGenerator *cg, JSTryNoteArray *array)
---
> JSTryNote *
> js_NewTryNote(JSContext *cx, JSCodeGenerator *cg, ptrdiff_t start,
>               ptrdiff_t end, ptrdiff_t catchStart)
6860d4329
<     JSTryNode *tryNode;
6863,6921c4332,4338
<     JS_ASSERT(array->length > 0 && array->length == cg->ntrynotes);
<     tn = array->vector + array->length;
<     tryNode = cg->lastTryNode;
<     do {
<         *--tn = tryNode->note;
<     } while ((tryNode = tryNode->prev) != NULL);
<     JS_ASSERT(tn == array->vector);
< }
< 
< /*
<  * Find the index of the given object for code generator.
<  *
<  * Since the emitter refers to each parsed object only once, for the index we
<  * use the number of already indexes objects. We also add the object to a list
<  * to convert the list to a fixed-size array when we complete code generation,
<  * see FinishParsedObjects bellow.
<  *
<  * Most of the objects go to JSCodeGenerator.objectList but for regexp we use
<  * a separated JSCodeGenerator.regexpList. In this way the emitted index can
<  * be directly used to store and fetch a reference to a cloned RegExp object
<  * that shares the same JSRegExp private data created for the object literal
<  * in pob. We need clones to hold lastIndex and other direct properties that
<  * should not be shared among threads sharing a precompiled function or
<  * script.
<  *
<  * If the code being compiled is function code, allocate a reserved slot in
<  * the cloned function object that shares its precompiled script with other
<  * cloned function objects and with the compiler-created clone-parent. There
<  * are script->nregexps such reserved slots in each function object cloned
<  * from fun->object. NB: during compilation, funobj slots must never be
<  * allocated, because js_AllocSlot could hand out one of the slots that should
<  * be given to a regexp clone.
<  *
<  * If the code being compiled is global code, the cloned regexp are stored in
<  * fp->vars slot after cg->treeContext.ngvars and to protect regexp slots from
<  * GC we set fp->nvars to ngvars + nregexps.
<  *
<  * The slots initially contain undefined or null. We populate them lazily when
<  * JSOP_REGEXP is executed for the first time.
<  *
<  * Why clone regexp objects?  ECMA specifies that when a regular expression
<  * literal is scanned, a RegExp object is created.  In the spec, compilation
<  * and execution happen indivisibly, but in this implementation and many of
<  * its embeddings, code is precompiled early and re-executed in multiple
<  * threads, or using multiple global objects, or both, for efficiency.
<  *
<  * In such cases, naively following ECMA leads to wrongful sharing of RegExp
<  * objects, which makes for collisions on the lastIndex property (especially
<  * for global regexps) and on any ad-hoc properties.  Also, __proto__ and
<  * __parent__ refer to the pre-compilation prototype and global objects, a
<  * pigeon-hole problem for instanceof tests.
<  */
< static uintN
< IndexParsedObject(JSParsedObjectBox *pob, JSEmittedObjectList *list)
< {
<     JS_ASSERT(!pob->emitLink);
<     pob->emitLink = list->lastPob;
<     list->lastPob = pob;
<     return list->length++;
---
>     JS_ASSERT(cg->tryBase <= cg->tryNext);
>     JS_ASSERT(catchStart >= 0);
>     tn = cg->tryNext++;
>     tn->start = start;
>     tn->length = end - start;
>     tn->catchStart = catchStart;
>     return tn;
6924,6925c4341,4342
< void
< FinishParsedObjects(JSEmittedObjectList *emittedList, JSObjectArray *array)
---
> JSBool
> js_FinishTakingTryNotes(JSContext *cx, JSCodeGenerator *cg, JSTryNote **tryp)
6927,6928c4344,4345
<     JSObject **cursor;
<     JSParsedObjectBox *pob;
---
>     uintN count;
>     JSTryNote *tmp, *final;
6930,6931c4347,4351
<     JS_ASSERT(emittedList->length <= INDEX_LIMIT);
<     JS_ASSERT(emittedList->length == array->length);
---
>     count = PTRDIFF(cg->tryNext, cg->tryBase, JSTryNote);
>     if (!count) {
>         *tryp = NULL;
>         return JS_TRUE;
>     }
6933,6940c4353,4365
<     cursor = array->vector + array->length;
<     pob = emittedList->lastPob;
<     do {
<         --cursor;
<         JS_ASSERT(!*cursor);
<         *cursor = pob->object;
<     } while ((pob = pob->emitLink) != NULL);
<     JS_ASSERT(cursor == array->vector);
---
>     tmp = cg->tryBase;
>     XMEMTAG("js_FinishTakingTryNotes");
>     final = (JSTryNote *) JS_malloc(cx, TRYNOTE_SIZE(count + 1));
>     if (!final) {
>         *tryp = NULL;
>         return JS_FALSE;
>     }
>     memcpy(final, tmp, TRYNOTE_SIZE(count));
>     final[count].start = 0;
>     final[count].length = CG_OFFSET(cg);
>     final[count].catchStart = 0;
>     *tryp = final;
>     return JS_TRUE;
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsemit.h /Volumes/Swap/js_D11/src/jsemit.h
2d1
<  * vim: set ts=8 sw=4 et tw=78:
4,15c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
20,23c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
27,39c23,33
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
51d44
< #include "jsscript.h"
58,63c51,52
<  * NB: If you add enumerators for scope statements, add them between STMT_WITH
<  * and STMT_CATCH, or you will break the STMT_TYPE_IS_SCOPE macro. If you add
<  * non-looping statement enumerators, add them before STMT_DO_LOOP or you will
<  * break the STMT_TYPE_IS_LOOP macro.
<  *
<  * Also remember to keep the statementName array in jsemit.c in sync.
---
>  * NB: If you add non-loop STMT_* enumerators, do so before STMT_DO_LOOP or
>  * you will break the STMT_IS_LOOP macro, just below this enum.
66,82c55,68
<     STMT_LABEL,                 /* labeled statement:  L: s */
<     STMT_IF,                    /* if (then) statement */
<     STMT_ELSE,                  /* else clause of if statement */
<     STMT_BODY,                  /* synthetic body of function with
<                                    destructuring formal parameters */
<     STMT_BLOCK,                 /* compound statement: { s1[;... sN] } */
<     STMT_SWITCH,                /* switch statement */
<     STMT_WITH,                  /* with statement */
<     STMT_CATCH,                 /* catch block */
<     STMT_TRY,                   /* try block */
<     STMT_FINALLY,               /* finally block */
<     STMT_SUBROUTINE,            /* gosub-target subroutine body */
<     STMT_DO_LOOP,               /* do/while loop statement */
<     STMT_FOR_LOOP,              /* for loop statement */
<     STMT_FOR_IN_LOOP,           /* for/in loop statement */
<     STMT_WHILE_LOOP,            /* while loop statement */
<     STMT_LIMIT
---
>     STMT_BLOCK        = 0,      /* compound statement: { s1[;... sN] } */
>     STMT_LABEL        = 1,      /* labeled statement:  L: s */
>     STMT_IF           = 2,      /* if (then) statement */
>     STMT_ELSE         = 3,      /* else clause of if statement */
>     STMT_SWITCH       = 4,      /* switch statement */
>     STMT_WITH         = 5,      /* with statement */
>     STMT_TRY          = 6,      /* try statement */
>     STMT_CATCH        = 7,      /* catch block */
>     STMT_FINALLY      = 8,      /* finally statement */
>     STMT_SUBROUTINE   = 9,      /* gosub-target subroutine body */
>     STMT_DO_LOOP      = 10,     /* do/while loop statement */
>     STMT_FOR_LOOP     = 11,     /* for loop statement */
>     STMT_FOR_IN_LOOP  = 12,     /* for/in loop statement */
>     STMT_WHILE_LOOP   = 13      /* while loop statement */
85,122c71
< #define STMT_TYPE_IN_RANGE(t,b,e) ((uint)((t) - (b)) <= (uintN)((e) - (b)))
< 
< /*
<  * A comment on the encoding of the JSStmtType enum and type-testing macros:
<  *
<  * STMT_TYPE_MAYBE_SCOPE tells whether a statement type is always, or may
<  * become, a lexical scope.  It therefore includes block and switch (the two
<  * low-numbered "maybe" scope types) and excludes with (with has dynamic scope
<  * pending the "reformed with" in ES4/JS2).  It includes all try-catch-finally
<  * types, which are high-numbered maybe-scope types.
<  *
<  * STMT_TYPE_LINKS_SCOPE tells whether a JSStmtInfo of the given type eagerly
<  * links to other scoping statement info records.  It excludes the two early
<  * "maybe" types, block and switch, as well as the try and both finally types,
<  * since try and the other trailing maybe-scope types don't need block scope
<  * unless they contain let declarations.
<  *
<  * We treat WITH as a static scope because it prevents lexical binding from
<  * continuing further up the static scope chain. With the "reformed with"
<  * proposal for JS2, we'll be able to model it statically, too.
<  */
< #define STMT_TYPE_MAYBE_SCOPE(type)                                           \
<     (type != STMT_WITH &&                                                     \
<      STMT_TYPE_IN_RANGE(type, STMT_BLOCK, STMT_SUBROUTINE))
< 
< #define STMT_TYPE_LINKS_SCOPE(type)                                           \
<     STMT_TYPE_IN_RANGE(type, STMT_WITH, STMT_CATCH)
< 
< #define STMT_TYPE_IS_TRYING(type)                                             \
<     STMT_TYPE_IN_RANGE(type, STMT_TRY, STMT_SUBROUTINE)
< 
< #define STMT_TYPE_IS_LOOP(type) ((type) >= STMT_DO_LOOP)
< 
< #define STMT_MAYBE_SCOPE(stmt)  STMT_TYPE_MAYBE_SCOPE((stmt)->type)
< #define STMT_LINKS_SCOPE(stmt)  (STMT_TYPE_LINKS_SCOPE((stmt)->type) ||       \
<                                  ((stmt)->flags & SIF_SCOPE))
< #define STMT_IS_TRYING(stmt)    STMT_TYPE_IS_TRYING((stmt)->type)
< #define STMT_IS_LOOP(stmt)      STMT_TYPE_IS_LOOP((stmt)->type)
---
> #define STMT_IS_LOOP(stmt)      ((stmt)->type >= STMT_DO_LOOP)
127,128c76
<     uint16          type;           /* statement type */
<     uint16          flags;          /* flags, see below */
---
>     JSStmtType      type;           /* statement type */
132,135c80,82
<     union {
<         JSAtom      *label;         /* name of LABEL */
<         JSObject    *blockObj;      /* block scope object */
<     } u;
---
>     ptrdiff_t       gosub;          /* offset of last GOSUB for this finally */
>     ptrdiff_t       catchJump;      /* offset of last end-of-catch jump */
>     JSAtom          *label;         /* name of LABEL or CATCH var */
137d83
<     JSStmtInfo      *downScope;     /* next enclosing lexical scope */
140,158d85
< #define SIF_SCOPE        0x0001     /* statement has its own lexical scope */
< #define SIF_BODY_BLOCK   0x0002     /* STMT_BLOCK type is a function body */
< #define SIF_FOR_BLOCK    0x0004     /* for (let ...) induced block scope */
< 
< /*
<  * To reuse space in JSStmtInfo, rename breaks and continues for use during
<  * try/catch/finally code generation and backpatching. To match most common
<  * use cases, the macro argument is a struct, not a struct pointer. Only a
<  * loop, switch, or label statement info record can have breaks and continues,
<  * and only a for loop has an update backpatch chain, so it's safe to overlay
<  * these for the "trying" JSStmtTypes.
<  */
< #define CATCHNOTE(stmt)  ((stmt).update)
< #define GOSUBS(stmt)     ((stmt).breaks)
< #define GUARDJUMP(stmt)  ((stmt).continues)
< 
< #define AT_TOP_LEVEL(tc)                                                      \
<     (!(tc)->topStmt || ((tc)->topStmt->flags & SIF_BODY_BLOCK))
< 
160c87,88
<     ((stmt)->update = (top), (stmt)->breaks = (stmt)->continues = (-1))
---
>     ((stmt)->update = (top), (stmt)->breaks =                                 \
>      (stmt)->continues = (stmt)->catchJump = (stmt)->gosub = (-1))
163,168c91,92
<     uint16          flags;          /* statement state flags, see below */
<     uint16          ngvars;         /* max. no. of global variables/regexps */
<     uint32          globalUses;     /* optimizable global var uses in total */
<     uint32          loopyGlobalUses;/* optimizable global var uses in loops */
<     uint16          scopeDepth;     /* current lexical scope chain depth */
<     uint16          maxScopeDepth;  /* maximum lexical scope chain depth */
---
>     uint32          flags;          /* statement state flags, see below */
>     uint32          tryCount;       /* total count of try statements parsed */
170,175d93
<     JSStmtInfo      *topScopeStmt;  /* top lexical scope statement */
<     JSObject        *blockChain;    /* compile time block scope chain (NB: one
<                                        deeper than the topScopeStmt/downScope
<                                        chain when in head of let block/expr) */
<     JSParseNode     *blockNode;     /* parse node for a lexical scope.
<                                        XXX combine with blockChain? */
177,179c95
<     JSParseContext  *parseContext;
<     JSFunction      *fun;           /* function to store argument and variable
<                                        names when flags & TCF_IN_FUNCTION */
---
>     JSParseNode     *nodeList;      /* list of recyclable parse-node structs */
182,219c98,110
< #define TCF_IN_FUNCTION        0x01 /* parsing inside function body */
< #define TCF_RETURN_EXPR        0x02 /* function has 'return expr;' */
< #define TCF_RETURN_VOID        0x04 /* function has 'return;' */
< #define TCF_IN_FOR_INIT        0x08 /* parsing init expr of for; exclude 'in' */
< #define TCF_FUN_CLOSURE_VS_VAR 0x10 /* function and var with same name */
< #define TCF_FUN_USES_NONLOCALS 0x20 /* function refers to non-local names */
< #define TCF_FUN_HEAVYWEIGHT    0x40 /* function needs Call object per call */
< #define TCF_FUN_IS_GENERATOR   0x80 /* parsed yield statement in function */
< #define TCF_HAS_DEFXMLNS      0x100 /* default xml namespace = ...; parsed */
< #define TCF_HAS_FUNCTION_STMT 0x200 /* block contains a function statement */
< #define TCF_GENEXP_LAMBDA     0x400 /* flag lambda from generator expression */
< #define TCF_COMPILE_N_GO      0x800 /* compiler-and-go mode of script, can
<                                        optimize name references based on scope
<                                        chain */
< 
< /*
<  * Flags to propagate out of the blocks.
<  */
< #define TCF_RETURN_FLAGS        (TCF_RETURN_EXPR | TCF_RETURN_VOID)
< 
< /*
<  * Flags to propagate from FunctionBody.
<  */
< #define TCF_FUN_FLAGS           (TCF_FUN_IS_GENERATOR   |                     \
<                                  TCF_FUN_HEAVYWEIGHT    |                     \
<                                  TCF_FUN_USES_NONLOCALS |                     \
<                                  TCF_FUN_CLOSURE_VS_VAR)
< 
< #define TREE_CONTEXT_INIT(tc, pc)                                             \
<     ((tc)->flags = (tc)->ngvars = 0,                                          \
<      (tc)->globalUses = (tc)->loopyGlobalUses = 0,                            \
<      (tc)->scopeDepth = (tc)->maxScopeDepth = 0,                              \
<      (tc)->topStmt = (tc)->topScopeStmt = NULL,                               \
<      (tc)->blockChain = NULL,                                                 \
<      ATOM_LIST_INIT(&(tc)->decls),                                            \
<      (tc)->blockNode = NULL,                                                  \
<      (tc)->parseContext = (pc),                                               \
<      (tc)->fun = NULL)
---
> #define TCF_COMPILING          0x01 /* generating bytecode; this tc is a cg */
> #define TCF_IN_FUNCTION        0x02 /* parsing inside function body */
> #define TCF_RETURN_EXPR        0x04 /* function has 'return expr;' */
> #define TCF_RETURN_VOID        0x08 /* function has 'return;' */
> #define TCF_IN_FOR_INIT        0x10 /* parsing init expr of for; exclude 'in' */
> #define TCF_FUN_CLOSURE_VS_VAR 0x20 /* function and var with same name */
> #define TCF_FUN_USES_NONLOCALS 0x40 /* function refers to non-local names */
> #define TCF_FUN_HEAVYWEIGHT    0x80 /* function needs Call object per call */
> #define TCF_FUN_FLAGS          0xE0 /* flags to propagate from FunctionBody */
> 
> #define TREE_CONTEXT_INIT(tc)                                                 \
>     ((tc)->flags = 0, (tc)->tryCount = 0, (tc)->topStmt = NULL,               \
>      ATOM_LIST_INIT(&(tc)->decls), (tc)->nodeList = NULL)
240c131
<  * sorted by offset from left to right, so that targets after a span-dependent
---
>  * sorted by offset from left to right, so that targets above a span-dependent
274,275d164
< #define SD_GET_TARGET(sd)       (JS_ASSERT(JT_HAS_TAG((sd)->target)),         \
<                                  JT_CLR_TAG((sd)->target))
279,298c168,169
< 
< /* Avoid asserting twice by expanding SD_GET_TARGET in the "then" clause. */
< #define SD_SPAN(sd,pivot)       (SD_GET_TARGET(sd)                            \
<                                  ? JT_CLR_TAG((sd)->target)->offset - (pivot) \
<                                  : 0)
< 
< typedef struct JSTryNode JSTryNode;
< 
< struct JSTryNode {
<     JSTryNote       note;
<     JSTryNode       *prev;
< };
< 
< typedef struct JSEmittedObjectList {
<     uint32              length;     /* number of emitted so far objects */
<     JSParsedObjectBox   *lastPob;   /* last emitted object */
< } JSEmittedObjectList;
< 
< extern void
< FinishParsedObjects(JSEmittedObjectList *emittedList, JSObjectArray *objectMap);
---
> #define SD_TARGET_OFFSET(sd)    (JS_ASSERT(JT_HAS_TAG((sd)->target)),         \
>                                  JT_CLR_TAG((sd)->target)->offset)
302,307c173,175
< 
<     JSArenaPool     *codePool;      /* pointer to thread code arena pool */
<     JSArenaPool     *notePool;      /* pointer to thread srcnote arena pool */
<     void            *codeMark;      /* low watermark in cg->codePool */
<     void            *noteMark;      /* low watermark in cg->notePool */
< 
---
>     void            *codeMark;      /* low watermark in cx->codePool */
>     void            *noteMark;      /* low watermark in cx->notePool */
>     void            *tempMark;      /* low watermark in cx->tempPool */
312,316d179
<         jssrcnote   *notes;         /* source notes, see below */
<         uintN       noteCount;      /* number of source notes so far */
<         uintN       noteMask;       /* growth increment for notes */
<         ptrdiff_t   lastNoteOffset; /* code offset for last source note */
<         uintN       currentLine;    /* line number for tree-based srcnote gen */
318c181
< 
---
>     const char      *filename;      /* null or weak link to source filename */
319a183,184
>     uintN           currentLine;    /* line number for tree-based srcnote gen */
>     JSPrincipals    *principals;    /* principals for constant folding eval */
321d185
< 
324,327c188,194
< 
<     uintN           ntrynotes;      /* number of allocated so far try notes */
<     JSTryNode       *lastTryNode;   /* the last allocated try node */
< 
---
>     jssrcnote       *notes;         /* source notes, see below */
>     uintN           noteCount;      /* number of source notes so far */
>     uintN           noteMask;       /* growth increment for notes */
>     ptrdiff_t       lastNoteOffset; /* code offset for last source note */
>     JSTryNote       *tryBase;       /* first exception handling note */
>     JSTryNote       *tryNext;       /* next available note */
>     size_t          tryNoteSpace;   /* # of bytes allocated at tryBase */
333,337d199
<     ptrdiff_t       spanDepTodo;    /* offset from main.base of potentially
<                                        unoptimized spandeps */
< 
<     uintN           arrayCompSlot;  /* stack slot of array in comprehension */
< 
339,345d200
<     JSAtomList      constList;      /* compile time constants */
< 
<     JSEmittedObjectList objectList; /* list of emitted so far objects */
<     JSEmittedObjectList regexpList; /* list of emitted so far regexp
<                                        that will be cloned during execution */
< 
<     JSCodeGenerator *parent;        /* enclosing function or global context */
354,359d208
< #define CG_NOTES(cg)            ((cg)->current->notes)
< #define CG_NOTE_COUNT(cg)       ((cg)->current->noteCount)
< #define CG_NOTE_MASK(cg)        ((cg)->current->noteMask)
< #define CG_LAST_NOTE_OFFSET(cg) ((cg)->current->lastNoteOffset)
< #define CG_CURRENT_LINE(cg)     ((cg)->current->currentLine)
< 
371,377c220,228
<  * Initialize cg to allocate bytecode space from codePool, source note space
<  * from notePool, and all other arena-allocated temporaries from cx->tempPool.
<  */
< extern JS_FRIEND_API(void)
< js_InitCodeGenerator(JSContext *cx, JSCodeGenerator *cg, JSParseContext *pc,
<                      JSArenaPool *codePool, JSArenaPool *notePool,
<                      uintN lineno);
---
>  * Initialize cg to allocate bytecode space from cx->codePool, source note
>  * space from cx->notePool, and all other arena-allocated temporaries from
>  * cx->tempPool.  Return true on success.  Report an error and return false
>  * if the initial code segment can't be allocated.
>  */
> extern JS_FRIEND_API(JSBool)
> js_InitCodeGenerator(JSContext *cx, JSCodeGenerator *cg,
> 		     const char *filename, uintN lineno,
> 		     JSPrincipals *principals);
380,381c231,232
<  * Release cg->codePool, cg->notePool, and cx->tempPool to marks set by
<  * js_InitCodeGenerator. Note that cgs are magic: they own the arena pool
---
>  * Release cx->codePool, cx->notePool, and cx->tempPool to marks set by
>  * js_InitCodeGenerator.  Note that cgs are magic: they own the arena pool
406c257
<          jsbytecode op2);
---
> 	 jsbytecode op2);
419,420c270,271
<         if (!js_SetJumpOffset(cx, cg, pc, off))                               \
<             return JS_FALSE;                                                  \
---
> 	if (!js_SetJumpOffset(cx, cg, pc, off))                               \
> 	    return JS_FALSE;                                                  \
428,432c279
<                  ptrdiff_t off);
< 
< /* Test whether we're in a statement of given type. */
< extern JSBool
< js_InStatement(JSTreeContext *tc, JSStmtType type);
---
> 		 ptrdiff_t off);
435c282,283
< #define js_InWithStatement(tc)      js_InStatement(tc, STMT_WITH)
---
> extern JSBool
> js_InWithStatement(JSTreeContext *tc);
437,441c285
< /*
<  * Test whether atom refers to a global variable (or is a reference error).
<  * Return true in *loopyp if any loops enclose the lexical reference, false
<  * otherwise.
<  */
---
> /* Test whether we're in a catch block with exception named by atom. */
443c287
< js_IsGlobalReference(JSTreeContext *tc, JSAtom *atom, JSBool *loopyp);
---
> js_InCatchBlock(JSTreeContext *tc, JSAtom *atom);
450,459c294
<                  ptrdiff_t top);
< 
< /*
<  * Push a block scope statement and link blockObj into tc->blockChain. To pop
<  * this statement info record, use js_PopStatement as usual, or if appropriate
<  * (if generating code), js_PopStatementCG.
<  */
< extern void
< js_PushBlockScope(JSTreeContext *tc, JSStmtInfo *stmt, JSObject *blockObj,
<                   ptrdiff_t top);
---
> 		 ptrdiff_t top);
462c297
<  * Pop tc->topStmt. If the top JSStmtInfo struct is not stack-allocated, it
---
>  * Pop tc->topStmt.  If the top JSStmtInfo struct is not stack-allocated, it
469,470c304
<  * Like js_PopStatement(&cg->treeContext), also patch breaks and continues
<  * unless the top statement info record represents a try-catch-finally suite.
---
>  * Like js_PopStatement(&cg->treeContext), also patch breaks and continues.
477,510d310
<  * Define and lookup a primitive jsval associated with the const named by atom.
<  * js_DefineCompileTimeConstant analyzes the constant-folded initializer at pn
<  * and saves the const's value in cg->constList, if it can be used at compile
<  * time. It returns true unless an error occurred.
<  *
<  * If the initializer's value could not be saved, js_DefineCompileTimeConstant
<  * calls will return the undefined value. js_DefineCompileTimeConstant tries
<  * to find a const value memorized for atom, returning true with *vp set to a
<  * value other than undefined if the constant was found, true with *vp set to
<  * JSVAL_VOID if not found, and false on error.
<  */
< extern JSBool
< js_DefineCompileTimeConstant(JSContext *cx, JSCodeGenerator *cg, JSAtom *atom,
<                              JSParseNode *pn);
< 
< /*
<  * Find a lexically scoped variable (one declared by let, catch, or an array
<  * comprehension) named by atom, looking in tc's compile-time scopes.
<  *
<  * If a WITH statement is reached along the scope stack, return its statement
<  * info record, so callers can tell that atom is ambiguous. If slotp is not
<  * null, then if atom is found, set *slotp to its stack slot, otherwise to -1.
<  * This means that if slotp is not null, all the block objects on the lexical
<  * scope chain must have had their depth slots computed by the code generator,
<  * so the caller must be under js_EmitTree.
<  *
<  * In any event, directly return the statement info record in which atom was
<  * found. Otherwise return null.
<  */
< extern JSStmtInfo *
< js_LexicalLookup(JSTreeContext *tc, JSAtom *atom, jsint *slotp,
<                  uintN decltype);
< 
< /*
517c317,318
<  * Emit function code using cg for the tree rooted at body.
---
>  * Emit code into cg for the tree rooted at body, then create a persistent
>  * script for fun from cg.
520c321,322
< js_EmitFunctionScript(JSContext *cx, JSCodeGenerator *cg, JSParseNode *body);
---
> js_EmitFunctionBody(JSContext *cx, JSCodeGenerator *cg, JSParseNode *body,
> 		    JSFunction *fun);
525c327
<  * the previous note. If 3 bits of offset aren't enough, extended delta notes
---
>  * the previous note.  If 3 bits of offset aren't enough, extended delta notes
527c329
<  * are emitted before the next note. Some notes have operand offsets encoded
---
>  * are emitted before the next note.  Some notes have operand offsets encoded
540,550d341
<  *
<  * Note on adding new source notes: every pair of bytecodes (A, B) where A and
<  * B have disjoint sets of source notes that could apply to each bytecode may
<  * reuse the same note type value for two notes (snA, snB) that have the same
<  * arity, offsetBias, and isSpanDep initializers in js_SrcNoteSpec. This is
<  * why SRC_IF and SRC_INITPROP have the same value below. For bad historical
<  * reasons, some bytecodes below that could be overlayed have not been, but
<  * before using SRC_EXTENDED, consider compressing the existing note types.
<  *
<  * Don't forget to update JSXDR_BYTECODE_VERSION in jsxdrapi.h for all such
<  * incompatible source note or other bytecode changes.
555,558d345
<     SRC_INITPROP    = 1,        /* disjoint meaning applied to JSOP_INITELEM or
<                                    to an index label in a regular (structuring)
<                                    or a destructuring object initialiser */
<     SRC_GENEXP      = 1,        /* JSOP_ANONFUNOBJ from generator expression */
565,571c352,354
<     SRC_DECL        = 6,        /* type of a declaration (var, const, let*) */
<     SRC_DESTRUCT    = 6,        /* JSOP_DUP starting a destructuring assignment
<                                    operation, with SRC_DECL_* offset operand */
<     SRC_PCDELTA     = 7,        /* distance forward from comma-operator to
<                                    next POP, or from CONDSWITCH to first CASE
<                                    opcode, etc. -- always a forward delta */
<     SRC_GROUPASSIGN = 7,        /* SRC_DESTRUCT variant for [a, b] = [c, d] */
---
>     SRC_VAR         = 6,        /* JSOP_NAME/SETNAME/FORNAME in a var decl */
>     SRC_PCDELTA     = 7,        /* offset from comma-operator to next POP,
> 				   or from CONDSWITCH to first CASE opcode */
574,575c357
<     SRC_BRACE       = 10,       /* mandatory brace, for scope or to avoid
<                                    dangling else */
---
>     SRC_RESERVED0   = 10,       /* reserved for future use */
577,579c359
<     SRC_PCBASE      = 12,       /* distance back from annotated getprop or
<                                    setprop op to left-most obj.prop.subprop
<                                    bytecode -- always a backward delta */
---
>     SRC_PCBASE      = 12,       /* offset of first obj.prop.subprop bytecode */
586c366
<                                    2nd off to first JSOP_CASE if condswitch */
---
> 				   2nd off to first JSOP_CASE if condswitch */
589c369
<     SRC_EXTENDED    = 21,       /* extended source note, 32-159, in next byte */
---
>     SRC_CONST       = 21,       /* JSOP_SETCONST in a const decl */
595,609d374
< /*
<  * Constants for the SRC_DECL source note. Note that span-dependent bytecode
<  * selection means that any SRC_DECL offset greater than SRC_DECL_LET may need
<  * to be adjusted, but these "offsets" are too small to span a span-dependent
<  * instruction, so can be used to denote distinct declaration syntaxes to the
<  * decompiler.
<  *
<  * NB: the var_prefix array in jsopcode.c depends on these dense indexes from
<  * SRC_DECL_VAR through SRC_DECL_LET.
<  */
< #define SRC_DECL_VAR            0
< #define SRC_DECL_CONST          1
< #define SRC_DECL_LET            2
< #define SRC_DECL_NONE           3
< 
618,619c383,384
<                                           (((t) << SN_DELTA_BITS)             \
<                                            | ((d) & SN_DELTA_MASK)))
---
> 					  (((t) << SN_DELTA_BITS)             \
> 					   | ((d) & SN_DELTA_MASK)))
621,622c386,387
<                                           ((SRC_XDELTA << SN_DELTA_BITS)      \
<                                            | ((d) & SN_XDELTA_MASK)))
---
> 					  ((SRC_XDELTA << SN_DELTA_BITS)      \
> 					   | ((d) & SN_XDELTA_MASK)))
625,627c390,391
< #define SN_TYPE(sn)             ((JSSrcNoteType)(SN_IS_XDELTA(sn)             \
<                                                  ? SRC_XDELTA                 \
<                                                  : *(sn) >> SN_DELTA_BITS))
---
> #define SN_TYPE(sn)             (SN_IS_XDELTA(sn) ? SRC_XDELTA                \
> 						  : *(sn) >> SN_DELTA_BITS)
632,633c396,397
<                                              ? *(sn) & SN_XDELTA_MASK         \
<                                              : *(sn) & SN_DELTA_MASK))
---
> 					     ? *(sn) & SN_XDELTA_MASK         \
> 					     : *(sn) & SN_DELTA_MASK))
635,636c399,400
<                                  ? SN_MAKE_XDELTA(sn, delta)                  \
<                                  : SN_MAKE_NOTE(sn, SN_TYPE(sn), delta))
---
> 				 ? SN_MAKE_XDELTA(sn, delta)                  \
> 				 : SN_MAKE_NOTE(sn, SN_TYPE(sn), delta))
661c425
<                                  : js_SrcNoteLength(sn))
---
> 				 : js_SrcNoteLength(sn))
670,672c434,435
<  * notes dynamic array, updating cg->noteCount. Return the new note's index
<  * within the array pointed at by cg->current->notes. Return -1 if out of
<  * memory.
---
>  * notes dynamic array, updating cg->noteCount.  Return the new note's index
>  * within the array pointed at by cg->notes.  Return -1 if out of memory.
679c442
<                ptrdiff_t offset);
---
> 	       ptrdiff_t offset);
683c446
<                ptrdiff_t offset1, ptrdiff_t offset2);
---
> 	       ptrdiff_t offset1, ptrdiff_t offset2);
700c463
<                     uintN which, ptrdiff_t offset);
---
> 		    uintN which, ptrdiff_t offset);
703,710c466,468
<  * Finish taking source notes in cx's notePool, copying final notes to the new
<  * stable store allocated by the caller and passed in via notes. Return false
<  * on malloc failure, which means this function reported an error.
<  *
<  * To compute the number of jssrcnotes to allocate and pass in via notes, use
<  * the CG_COUNT_FINAL_SRCNOTES macro. This macro knows a lot about details of
<  * js_FinishTakingSrcNotes, SO DON'T CHANGE jsemit.c's js_FinishTakingSrcNotes
<  * FUNCTION WITHOUT CHECKING WHETHER THIS MACRO NEEDS CORRESPONDING CHANGES!
---
>  * Finish taking source notes in cx's notePool by copying them to new
>  * stable store allocated via JS_malloc.  Return null on malloc failure,
>  * which means this function reported an error.
712,731c470,471
< #define CG_COUNT_FINAL_SRCNOTES(cg, cnt)                                      \
<     JS_BEGIN_MACRO                                                            \
<         ptrdiff_t diff_ = CG_PROLOG_OFFSET(cg) - (cg)->prolog.lastNoteOffset; \
<         cnt = (cg)->prolog.noteCount + (cg)->main.noteCount + 1;              \
<         if ((cg)->prolog.noteCount &&                                         \
<             (cg)->prolog.currentLine != (cg)->firstLine) {                    \
<             if (diff_ > SN_DELTA_MASK)                                        \
<                 cnt += JS_HOWMANY(diff_ - SN_DELTA_MASK, SN_XDELTA_MASK);     \
<             cnt += 2 + (((cg)->firstLine > SN_3BYTE_OFFSET_MASK) << 1);       \
<         } else if (diff_ > 0) {                                               \
<             if (cg->main.noteCount) {                                         \
<                 jssrcnote *sn_ = (cg)->main.notes;                            \
<                 diff_ -= SN_IS_XDELTA(sn_)                                    \
<                          ? SN_XDELTA_MASK - (*sn_ & SN_XDELTA_MASK)           \
<                          : SN_DELTA_MASK - (*sn_ & SN_DELTA_MASK);            \
<             }                                                                 \
<             if (diff_ > 0)                                                    \
<                 cnt += JS_HOWMANY(diff_, SN_XDELTA_MASK);                     \
<         }                                                                     \
<     JS_END_MACRO
---
> extern jssrcnote *
> js_FinishTakingSrcNotes(JSContext *cx, JSCodeGenerator *cg);
732a473,477
> /*
>  * Allocate cg->treeContext.tryCount notes (plus one for the end sentinel)
>  * from cx->tempPool and set up cg->tryBase/tryNext for exactly tryCount
>  * js_NewTryNote calls.  The storage is freed by js_FinishCodeGenerator.
>  */
734c479
< js_FinishTakingSrcNotes(JSContext *cx, JSCodeGenerator *cg, jssrcnote *notes);
---
> js_AllocTryNotes(JSContext *cx, JSCodeGenerator *cg);
736,737c481,493
< extern void
< js_FinishTakingTryNotes(JSCodeGenerator *cg, JSTryNoteArray *array);
---
> /*
>  * Grab the next trynote slot in cg, filling it in appropriately.
>  */
> extern JSTryNote *
> js_NewTryNote(JSContext *cx, JSCodeGenerator *cg, ptrdiff_t start,
> 	      ptrdiff_t end, ptrdiff_t catchStart);
> 
> /*
>  * Finish generating exception information, and copy it to JS_malloc
>  * storage.
>  */
> extern JSBool
> js_FinishTakingTryNotes(JSContext *cx, JSCodeGenerator *cg, JSTryNote **tryp);
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsexn.c /Volumes/Swap/js_D11/src/jsexn.c
2d1
<  * vim: set ts=8 sw=4 et tw=78:
4,5c3,6
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
7,15c8,11
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
20,23c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
27,39c23,33
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
46c40
< #include <stdlib.h>
---
> #include "xstdlib.h"
55d48
< #include "jsdbgapi.h"
59d51
< #include "jsnum.h"
60a53
> #include "jsnum.h"
63,65d55
< /* Forward declarations for js_ErrorClass's initializer. */
< static JSBool
< Exception(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
67,68c57
< static void
< exn_finalize(JSContext *cx, JSObject *obj);
---
> //#include "_optimize.h"
70,71c59,62
< static void
< exn_trace(JSTracer *trc, JSObject *obj);
---
> #if JS_HAS_ERROR_EXCEPTIONS
> #if !JS_HAS_EXCEPTIONS
> # error "JS_HAS_EXCEPTIONS must be defined to use JS_HAS_ERROR_EXCEPTIONS"
> #endif
73,74c64,68
< static void
< exn_finalize(JSContext *cx, JSObject *obj);
---
> /* XXX consider adding rt->atomState.messageAtom */
> static char js_message_str[]  = "message";
> static char js_filename_str[] = "fileName";
> static char js_lineno_str[]   = "lineNumber";
> static char js_stack_str[]    = "stack";
75a70
> /* Forward declarations for ExceptionClass's initializer. */
77c72
< exn_enumerate(JSContext *cx, JSObject *obj);
---
> Exception(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
79,81c74,75
< static JSBool
< exn_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
<             JSObject **objp);
---
> static void
> exn_finalize(JSContext *cx, JSObject *obj);
83,86c77,79
< JSClass js_ErrorClass = {
<     js_Error_str,
<     JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE | JSCLASS_MARK_IS_TRACE |
<     JSCLASS_HAS_CACHED_PROTO(JSProto_Error),
---
> static JSClass ExceptionClass = {
>     "Error",
>     JSCLASS_HAS_PRIVATE,
88c81
<     exn_enumerate,    (JSResolveOp)exn_resolve, JS_ConvertStub, exn_finalize,
---
>     JS_EnumerateStub, JS_ResolveStub,   JS_ConvertStub,   exn_finalize,
90c83
<     NULL,             NULL,             JS_CLASS_TRACE(exn_trace), NULL
---
>     NULL,             NULL,             NULL,             0
93,99c86,88
< typedef struct JSStackTraceElem {
<     JSString            *funName;
<     size_t              argc;
<     const char          *filename;
<     uintN               ulineno;
< } JSStackTraceElem;
< 
---
> /*
>  * A copy of the JSErrorReport originally generated.
>  */
101,107c90
<     /* A copy of the JSErrorReport originally generated. */
<     JSErrorReport       *errorReport;
<     JSString            *message;
<     JSString            *filename;
<     uintN               lineno;
<     size_t              stackDepth;
<     JSStackTraceElem    stackElems[1];
---
>     JSErrorReport *errorReport;
110,114c93,97
< static JSString *
< StackTraceToString(JSContext *cx, JSExnPrivate *priv);
< 
< static JSErrorReport *
< CopyErrorReport(JSContext *cx, JSErrorReport *report)
---
> /*
>  * Undo all the damage done by exn_newPrivate.
>  */
> static void
> exn_destroyPrivate(JSContext *cx, JSExnPrivate *privateData)
116,130c99,100
<     /*
<      * We use a single malloc block to make a deep copy of JSErrorReport with
<      * the following layout:
<      *   JSErrorReport
<      *   array of copies of report->messageArgs
<      *   jschar array with characters for all messageArgs
<      *   jschar array with characters for ucmessage
<      *   jschar array with characters for uclinebuf and uctokenptr
<      *   char array with characters for linebuf and tokenptr
<      *   char array with characters for filename
<      * Such layout together with the properties enforced by the following
<      * asserts does not need any extra alignment padding.
<      */
<     JS_STATIC_ASSERT(sizeof(JSErrorReport) % sizeof(const char *) == 0);
<     JS_STATIC_ASSERT(sizeof(const char *) % sizeof(jschar) == 0);
---
>     JSErrorReport *report;
>     const jschar **args;
132,150c102,111
<     size_t filenameSize;
<     size_t linebufSize;
<     size_t uclinebufSize;
<     size_t ucmessageSize;
<     size_t i, argsArraySize, argsCopySize, argSize;
<     size_t mallocSize;
<     JSErrorReport *copy;
<     uint8 *cursor;
< 
< #define JS_CHARS_SIZE(jschars) ((js_strlen(jschars) + 1) * sizeof(jschar))
< 
<     filenameSize = report->filename ? strlen(report->filename) + 1 : 0;
<     linebufSize = report->linebuf ? strlen(report->linebuf) + 1 : 0;
<     uclinebufSize = report->uclinebuf ? JS_CHARS_SIZE(report->uclinebuf) : 0;
<     ucmessageSize = 0;
<     argsArraySize = 0;
<     argsCopySize = 0;
<     if (report->ucmessage) {
<         ucmessageSize = JS_CHARS_SIZE(report->ucmessage);
---
>     if (!privateData)
>         return;
>     report = privateData->errorReport;
>     if (report) {
>         if (report->uclinebuf)
>             JS_free(cx, (void *)report->uclinebuf);
>         if (report->filename)
>             JS_free(cx, (void *)report->filename);
>         if (report->ucmessage)
>             JS_free(cx, (void *)report->ucmessage);
152,210c113,116
<             for (i = 0; report->messageArgs[i]; ++i)
<                 argsCopySize += JS_CHARS_SIZE(report->messageArgs[i]);
< 
<             /* Non-null messageArgs should have at least one non-null arg. */
<             JS_ASSERT(i != 0);
<             argsArraySize = (i + 1) * sizeof(const jschar *);
<         }
<     }
< 
<     /*
<      * The mallocSize can not overflow since it represents the sum of the
<      * sizes of already allocated objects.
<      */
<     mallocSize = sizeof(JSErrorReport) + argsArraySize + argsCopySize +
<                  ucmessageSize + uclinebufSize + linebufSize + filenameSize;
<     cursor = (uint8 *)JS_malloc(cx, mallocSize);
<     if (!cursor)
<         return NULL;
< 
<     copy = (JSErrorReport *)cursor;
<     memset(cursor, 0, sizeof(JSErrorReport));
<     cursor += sizeof(JSErrorReport);
< 
<     if (argsArraySize != 0) {
<         copy->messageArgs = (const jschar **)cursor;
<         cursor += argsArraySize;
<         for (i = 0; report->messageArgs[i]; ++i) {
<             copy->messageArgs[i] = (const jschar *)cursor;
<             argSize = JS_CHARS_SIZE(report->messageArgs[i]);
<             memcpy(cursor, report->messageArgs[i], argSize);
<             cursor += argSize;
<         }
<         copy->messageArgs[i] = NULL;
<         JS_ASSERT(cursor == (uint8 *)copy->messageArgs[0] + argsCopySize);
<     }
< 
<     if (report->ucmessage) {
<         copy->ucmessage = (const jschar *)cursor;
<         memcpy(cursor, report->ucmessage, ucmessageSize);
<         cursor += ucmessageSize;
<     }
< 
<     if (report->uclinebuf) {
<         copy->uclinebuf = (const jschar *)cursor;
<         memcpy(cursor, report->uclinebuf, uclinebufSize);
<         cursor += uclinebufSize;
<         if (report->uctokenptr) {
<             copy->uctokenptr = copy->uclinebuf + (report->uctokenptr -
<                                                   report->uclinebuf);
<         }
<     }
< 
<     if (report->linebuf) {
<         copy->linebuf = (const char *)cursor;
<         memcpy(cursor, report->linebuf, linebufSize);
<         cursor += linebufSize;
<         if (report->tokenptr) {
<             copy->tokenptr = copy->linebuf + (report->tokenptr -
<                                               report->linebuf);
---
>             args = report->messageArgs;
>             while (*args != NULL)
>                 JS_free(cx, (void *)*args++);
>             JS_free(cx, (void *)report->messageArgs);
211a118
>         JS_free(cx, report);
213,228c120
< 
<     if (report->filename) {
<         copy->filename = (const char *)cursor;
<         memcpy(cursor, report->filename, filenameSize);
<     }
<     JS_ASSERT(cursor + filenameSize == (uint8 *)copy + mallocSize);
< 
<     /* Copy non-pointer members. */
<     copy->lineno = report->lineno;
<     copy->errorNumber = report->errorNumber;
< 
<     /* Note that this is before it gets flagged with JSREPORT_EXCEPTION */
<     copy->flags = report->flags;
< 
< #undef JS_CHARS_SIZE
<     return copy;
---
>     JS_free(cx, privateData);
231,232c123,127
< static jsval *
< GetStackTraceValueBuffer(JSExnPrivate *priv)
---
> /*
>  * Copy everything interesting about an error into allocated memory.
>  */
> static JSExnPrivate *
> exn_newPrivate(JSContext *cx, JSErrorReport *report)
234,243c129,138
<     /*
<      * We use extra memory after JSExnPrivateInfo.stackElems to store jsvals
<      * that helps to produce more informative stack traces. The following
<      * assert allows us to assume that no gap after stackElems is necessary to
<      * align the buffer properly.
<      */
<     JS_STATIC_ASSERT(sizeof(JSStackTraceElem) % sizeof(jsval) == 0);
< 
<     return (jsval *)(priv->stackElems + priv->stackDepth);
< }
---
>     intN i;
>     JSExnPrivate *newPrivate;
>     JSErrorReport *newReport;
>     size_t capacity;
>     
>     XMEMTAG("exn_newPrivate JSExnPrivate");
>     newPrivate = (JSExnPrivate *)JS_malloc(cx, sizeof (JSExnPrivate));
>     if (!newPrivate)
>         return NULL;
>     memset(newPrivate, 0, sizeof (JSExnPrivate));
245,258c140,154
< static JSBool
< InitExnPrivate(JSContext *cx, JSObject *exnObject, JSString *message,
<                JSString *filename, uintN lineno, JSErrorReport *report)
< {
<     JSCheckAccessOp checkAccess;
<     JSErrorReporter older;
<     JSExceptionState *state;
<     jsval callerid, v;
<     JSStackFrame *fp, *fpstop;
<     size_t stackDepth, valueCount, size;
<     JSBool overflow;
<     JSExnPrivate *priv;
<     JSStackTraceElem *elem;
<     jsval *values;
---
>     /* Copy the error report */
>     XMEMTAG("exn_newPrivate JSErrorReport");
>     newReport = (JSErrorReport *)JS_malloc(cx, sizeof (JSErrorReport));
>     if (!newReport)
>         goto error;
>     memset(newReport, 0, sizeof (JSErrorReport));
>     newPrivate->errorReport = newReport;
> 
>     if (report->filename != NULL) {
>         newReport->filename = JS_strdup(cx, report->filename);
>         if (!newReport->filename)
>             goto error;
>     } else {
>         newReport->filename = NULL;
>     }
260c156
<     JS_ASSERT(OBJ_GET_CLASS(cx, exnObject) == &js_ErrorClass);
---
>     newReport->lineno = report->lineno;
263,267c159,160
<      * Prepare stack trace data.
<      *
<      * Set aside any error reporter for cx and save its exception state
<      * so we can suppress any checkAccess failures.  Such failures should stop
<      * the backtrace procedure, not result in a failure of this constructor.
---
>      * We don't need to copy linebuf and tokenptr, because they
>      * point into the deflated string cache.  (currently?)
269,302c162,163
<     checkAccess = cx->runtime->checkObjectAccess;
<     older = JS_SetErrorReporter(cx, NULL);
<     state = JS_SaveExceptionState(cx);
< 
<     callerid = ATOM_KEY(cx->runtime->atomState.callerAtom);
<     stackDepth = 0;
<     valueCount = 0;
<     for (fp = cx->fp; fp; fp = fp->down) {
<         if (fp->fun && fp->argv) {
<             v = JSVAL_NULL;
<             if (checkAccess &&
<                 !checkAccess(cx, fp->callee, callerid, JSACC_READ, &v)) {
<                 break;
<             }
<             valueCount += fp->argc;
<         }
<         ++stackDepth;
<     }
<     JS_RestoreExceptionState(cx, state);
<     JS_SetErrorReporter(cx, older);
<     fpstop = fp;
< 
<     size = offsetof(JSExnPrivate, stackElems);
<     overflow = (stackDepth > ((size_t)-1 - size) / sizeof(JSStackTraceElem));
<     size += stackDepth * sizeof(JSStackTraceElem);
<     overflow |= (valueCount > ((size_t)-1 - size) / sizeof(jsval));
<     size += valueCount * sizeof(jsval);
<     if (overflow) {
<         JS_ReportOutOfMemory(cx);
<         return JS_FALSE;
<     }
<     priv = (JSExnPrivate *)JS_malloc(cx, size);
<     if (!priv)
<         return JS_FALSE;
---
>     newReport->linebuf = report->linebuf;
>     newReport->tokenptr = report->tokenptr;
305,307c166,167
<      * We initialize errorReport with a copy of report after setting the
<      * private slot, to prevent GC accessing a junk value we clear the field
<      * here.
---
>      * But we do need to copy uclinebuf, uctokenptr, because they're
>      * pointers into internal tokenstream structs, and may go away.
309,336c169,180
<     priv->errorReport = NULL;
<     priv->message = message;
<     priv->filename = filename;
<     priv->lineno = lineno;
<     priv->stackDepth = stackDepth;
< 
<     values = GetStackTraceValueBuffer(priv);
<     elem = priv->stackElems;
<     for (fp = cx->fp; fp != fpstop; fp = fp->down) {
<         if (!fp->fun) {
<             elem->funName = NULL;
<             elem->argc = 0;
<         } else {
<             elem->funName = fp->fun->atom
<                             ? ATOM_TO_STRING(fp->fun->atom)
<                             : cx->runtime->emptyString;
<             elem->argc = fp->argc;
<             memcpy(values, fp->argv, fp->argc * sizeof(jsval));
<             values += fp->argc;
<         }
<         elem->ulineno = 0;
<         elem->filename = NULL;
<         if (fp->script) {
<             elem->filename = fp->script->filename;
<             if (fp->pc)
<                 elem->ulineno = js_PCToLineNumber(cx, fp->script, fp->pc);
<         }
<         ++elem;
---
>     if (report->uclinebuf != NULL) {
>         capacity = js_strlen(report->uclinebuf) + 1;
>         XMEMTAG("exn_newPrivate uclinebuf");
>         newReport->uclinebuf =
>             (const jschar *)JS_malloc(cx, capacity * sizeof(jschar));
>         if (!newReport->uclinebuf)
>             goto error;
>         js_strncpy((jschar *)newReport->uclinebuf, report->uclinebuf, capacity);
>         newReport->uctokenptr = newReport->uclinebuf + (report->uctokenptr -
>                                                         report->uclinebuf);
>     } else {
>         newReport->uclinebuf = newReport->uctokenptr = NULL;
338,339d181
<     JS_ASSERT(priv->stackElems + stackDepth == elem);
<     JS_ASSERT(GetStackTraceValueBuffer(priv) + valueCount == values);
341c183,190
<     STOBJ_SET_SLOT(exnObject, JSSLOT_PRIVATE, PRIVATE_TO_JSVAL(priv));
---
>     if (report->ucmessage != NULL) {
>         capacity = js_strlen(report->ucmessage) + 1;
> 		XMEMTAG("exn_newPrivate ucmessage");
>         newReport->ucmessage = (const jschar *)
>             JS_malloc(cx, capacity * sizeof(jschar));
>         if (!newReport->ucmessage)
>             goto error;
>         js_strncpy((jschar *)newReport->ucmessage, report->ucmessage, capacity);
343,353c192,213
<     if (report) {
<         /*
<          * Construct a new copy of the error report struct. We can't use the
<          * error report struct that was passed in, because it's allocated on
<          * the stack, and also because it may point to transient data in the
<          * JSTokenStream.
<          */
<         priv->errorReport = CopyErrorReport(cx, report);
<         if (!priv->errorReport) {
<             /* The finalizer realeases priv since it is in the private slot. */
<             return JS_FALSE;
---
>         if (report->messageArgs) {
>             for (i = 0; report->messageArgs[i] != NULL; i++)
>                 continue;
>             JS_ASSERT(i);
>             XMEMTAG("exn_newPrivate messageArgs");
>             newReport->messageArgs =
>                 (const jschar **)JS_malloc(cx, (i + 1) * sizeof(jschar *));
>             if (!newReport->messageArgs)
>                 goto error;
>             for (i = 0; report->messageArgs[i] != NULL; i++) {
>                 capacity = js_strlen(report->messageArgs[i]) + 1;
>                 XMEMTAG("exn_newPrivate messageArgs 2");
>                 newReport->messageArgs[i] =
>                     (const jschar *)JS_malloc(cx, capacity * sizeof(jschar));
>                 if (!newReport->messageArgs[i])
>                     goto error;
>                 js_strncpy((jschar *)(newReport->messageArgs[i]),
>                            report->messageArgs[i], capacity);
>             }
>             newReport->messageArgs[i] = NULL;
>         } else {
>             newReport->messageArgs = NULL;
354a215,217
>     } else {
>         newReport->ucmessage = NULL;
>         newReport->messageArgs = NULL;
355a219
>     newReport->errorNumber = report->errorNumber;
357,373c221,222
<     return JS_TRUE;
< }
< 
< static JSExnPrivate *
< GetExnPrivate(JSContext *cx, JSObject *obj)
< {
<     jsval privateValue;
<     JSExnPrivate *priv;
< 
<     JS_ASSERT(OBJ_GET_CLASS(cx, obj) == &js_ErrorClass);
<     privateValue = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
<     if (JSVAL_IS_VOID(privateValue))
<         return NULL;
<     priv = (JSExnPrivate *)JSVAL_TO_PRIVATE(privateValue);
<     JS_ASSERT(priv);
<     return priv;
< }
---
>     /* Note that this is before it gets flagged with JSREPORT_EXCEPTION */
>     newReport->flags = report->flags;
375,405c224,229
< static void
< exn_trace(JSTracer *trc, JSObject *obj)
< {
<     JSExnPrivate *priv;
<     JSStackTraceElem *elem;
<     size_t vcount, i;
<     jsval *vp, v;
< 
<     priv = GetExnPrivate(trc->context, obj);
<     if (priv) {
<         if (priv->message)
<             JS_CALL_STRING_TRACER(trc, priv->message, "exception message");
<         if (priv->filename)
<             JS_CALL_STRING_TRACER(trc, priv->filename, "exception filename");
< 
<         elem = priv->stackElems;
<         for (vcount = i = 0; i != priv->stackDepth; ++i, ++elem) {
<             if (elem->funName) {
<                 JS_CALL_STRING_TRACER(trc, elem->funName,
<                                       "stack trace function name");
<             }
<             if (IS_GC_MARKING_TRACER(trc) && elem->filename)
<                 js_MarkScriptFilename(elem->filename);
<             vcount += elem->argc;
<         }
<         vp = GetStackTraceValueBuffer(priv);
<         for (i = 0; i != vcount; ++i, ++vp) {
<             v = *vp;
<             JS_CALL_VALUE_TRACER(trc, v, "stack trace argument");
<         }
<     }
---
> 	newReport->lscript = report->lscript; // !!dp
> 	
>     return newPrivate;
> error:
>     exn_destroyPrivate(cx, newPrivate);
>     return NULL;
411,477c235,236
<     JSExnPrivate *priv;
< 
<     priv = GetExnPrivate(cx, obj);
<     if (priv) {
<         if (priv->errorReport)
<             JS_free(cx, priv->errorReport);
<         JS_free(cx, priv);
<     }
< }
< 
< static JSBool
< exn_enumerate(JSContext *cx, JSObject *obj)
< {
<     JSAtomState *atomState;
<     uintN i;
<     JSAtom *atom;
<     JSObject *pobj;
<     JSProperty *prop;
< 
<     JS_STATIC_ASSERT(sizeof(JSAtomState) <= (size_t)(uint16)-1);
<     static const uint16 offsets[] = {
<         (uint16)offsetof(JSAtomState, messageAtom),
<         (uint16)offsetof(JSAtomState, fileNameAtom),
<         (uint16)offsetof(JSAtomState, lineNumberAtom),
<         (uint16)offsetof(JSAtomState, stackAtom),
<     };
< 
<     atomState = &cx->runtime->atomState;
<     for (i = 0; i != JS_ARRAY_LENGTH(offsets); ++i) {
<         atom = *(JSAtom **)((uint8 *)atomState + offsets[i]);
<         if (!js_LookupProperty(cx, obj, ATOM_TO_JSID(atom), &pobj, &prop))
<             return JS_FALSE;
<         if (prop)
<             OBJ_DROP_PROPERTY(cx, pobj, prop);
<     }
<     return JS_TRUE;
< }
< 
< static JSBool
< exn_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
<             JSObject **objp)
< {
<     JSExnPrivate *priv;
<     JSString *str;
<     JSAtom *atom;
<     JSString *stack;
<     const char *prop;
<     jsval v;
< 
<     *objp = NULL;
<     priv = GetExnPrivate(cx, obj);
<     if (priv && JSVAL_IS_STRING(id)) {
<         str = JSVAL_TO_STRING(id);
< 
<         atom = cx->runtime->atomState.messageAtom;
<         if (str == ATOM_TO_STRING(atom)) {
<             prop = js_message_str;
<             v = STRING_TO_JSVAL(priv->message);
<             goto define;
<         }
< 
<         atom = cx->runtime->atomState.fileNameAtom;
<         if (str == ATOM_TO_STRING(atom)) {
<             prop = js_fileName_str;
<             v = STRING_TO_JSVAL(priv->filename);
<             goto define;
<         }
---
>     JSExnPrivate *privateData;
>     jsval privateValue;
479,484c238
<         atom = cx->runtime->atomState.lineNumberAtom;
<         if (str == ATOM_TO_STRING(atom)) {
<             prop = js_lineNumber_str;
<             v = INT_TO_JSVAL(priv->lineno);
<             goto define;
<         }
---
>     privateValue = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
486,497c240,243
<         atom = cx->runtime->atomState.stackAtom;
<         if (str == ATOM_TO_STRING(atom)) {
<             stack = StackTraceToString(cx, priv);
<             if (!stack)
<                 return JS_FALSE;
< 
<             /* Allow to GC all things that were used to build stack trace. */
<             priv->stackDepth = 0;
<             prop = js_stack_str;
<             v = STRING_TO_JSVAL(stack);
<             goto define;
<         }
---
>     if (!JSVAL_IS_VOID(privateValue)) {
>         privateData = (JSExnPrivate*) JSVAL_TO_PRIVATE(privateValue);
>         if (privateData)
>             exn_destroyPrivate(cx, privateData);
499,505d244
<     return JS_TRUE;
< 
<   define:
<     if (!JS_DefineProperty(cx, obj, prop, v, NULL, NULL, JSPROP_ENUMERATE))
<         return JS_FALSE;
<     *objp = obj;
<     return JS_TRUE;
512c251,252
<     JSExnPrivate *priv;
---
>     JSExnPrivate *privateData;
>     jsval privateValue;
517c257,260
<     if (OBJ_GET_CLASS(cx, obj) != &js_ErrorClass)
---
>     if (OBJ_GET_CLASS(cx, obj) != &ExceptionClass)
>         return NULL;
>     privateValue = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
>     if (JSVAL_IS_VOID(privateValue))
519,520c262,263
<     priv = GetExnPrivate(cx, obj);
<     if (!priv)
---
>     privateData = (JSExnPrivate*) JSVAL_TO_PRIVATE(privateValue);
>     if (!privateData)
522c265,267
<     return priv->errorReport;
---
> 
>     JS_ASSERT(privateData->errorReport);
>     return privateData->errorReport;
524a270,286
> /*
>  * This must be kept in synch with the exceptions array below.
>  * XXX use a jsexn.tbl file a la jsopcode.tbl
>  */
> typedef enum JSExnType {
>     JSEXN_NONE = -1,
>       JSEXN_ERR,
>         JSEXN_INTERNALERR,
>         JSEXN_EVALERR,
>         JSEXN_RANGEERR,
>         JSEXN_REFERENCEERR,
>         JSEXN_SYNTAXERR,
>         JSEXN_TYPEERR,
>         JSEXN_URIERR,
>         JSEXN_LIMIT
> } JSExnType;
> 
528d289
<     JSProtoKey key;
533c294
<  * All *Error constructors share the same JSClass, js_ErrorClass.  But each
---
>  * All *Error constructors share the same JSClass, ExceptionClass.  But each
538a300
> const char js_##name##_str[] = #name;                                         \
557,565c319,327
<     {JSEXN_NONE, js_Error_str,          JSProto_Error,          Error},
<     {JSEXN_ERR,  js_InternalError_str,  JSProto_InternalError,  InternalError},
<     {JSEXN_ERR,  js_EvalError_str,      JSProto_EvalError,      EvalError},
<     {JSEXN_ERR,  js_RangeError_str,     JSProto_RangeError,     RangeError},
<     {JSEXN_ERR,  js_ReferenceError_str, JSProto_ReferenceError, ReferenceError},
<     {JSEXN_ERR,  js_SyntaxError_str,    JSProto_SyntaxError,    SyntaxError},
<     {JSEXN_ERR,  js_TypeError_str,      JSProto_TypeError,      TypeError},
<     {JSEXN_ERR,  js_URIError_str,       JSProto_URIError,       URIError},
<     {0,          NULL,                  JSProto_Null,           NULL}
---
>     { JSEXN_NONE,       js_Error_str,           Error },
>     { JSEXN_ERR,        js_InternalError_str,   InternalError },
>     { JSEXN_ERR,        js_EvalError_str,       EvalError },
>     { JSEXN_ERR,        js_RangeError_str,      RangeError },
>     { JSEXN_ERR,        js_ReferenceError_str,  ReferenceError },
>     { JSEXN_ERR,        js_SyntaxError_str,     SyntaxError },
>     { JSEXN_ERR,        js_TypeError_str,       TypeError },
>     { JSEXN_ERR,        js_URIError_str,        URIError },
>     {0,NULL,NULL}
568,603c330,332
< static JSString *
< ValueToShortSource(JSContext *cx, jsval v)
< {
<     JSString *str;
< 
<     /* Avoid toSource bloat and fallibility for object types. */
<     if (JSVAL_IS_PRIMITIVE(v)) {
<         str = js_ValueToSource(cx, v);
<     } else if (VALUE_IS_FUNCTION(cx, v)) {
<         /*
<          * XXX Avoid function decompilation bloat for now.
<          */
<         str = JS_GetFunctionId(JS_ValueToFunction(cx, v));
<         if (!str && !(str = js_ValueToSource(cx, v))) {
<             /*
<              * Continue to soldier on if the function couldn't be
<              * converted into a string.
<              */
<             JS_ClearPendingException(cx);
<             str = JS_NewStringCopyZ(cx, "[unknown function]");
<         }
<     } else {
<         /*
<          * XXX Avoid toString on objects, it takes too long and uses too much
<          * memory, for too many classes (see Mozilla bug 166743).
<          */
<         char buf[100];
<         JS_snprintf(buf, sizeof buf, "[object %s]",
<                     OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(v))->name);
<         str = JS_NewStringCopyZ(cx, buf);
<     }
<     return str;
< }
< 
< static JSString *
< StackTraceToString(JSContext *cx, JSExnPrivate *priv)
---
> static JSBool
> InitExceptionObject(JSContext *cx, JSObject *obj, JSString *message,
>                     JSString *filename, uintN lineno)
604a334,336
>     JSCheckAccessOp checkAccess;
>     JSErrorReporter older;
>     JSExceptionState *state;
607,610c339,343
<     JSStackTraceElem *elem, *endElem;
<     jsval *values;
<     size_t i;
<     JSString *str;
---
>     JSStackFrame *fp;
>     jsval callerid, v;
>     JSBool ok;
>     JSString *argsrc, *stack;
>     uintN i, ulineno;
614c347,392
<     /* After this point, failing control flow must goto bad. */
---
>     if (!JS_DefineProperty(cx, obj, js_message_str, STRING_TO_JSVAL(message),
>                            NULL, NULL, JSPROP_ENUMERATE)) {
>         return JS_FALSE;
>     }
> 
>     if (!JS_DefineProperty(cx, obj, js_filename_str,
>                            STRING_TO_JSVAL(filename),
>                            NULL, NULL, JSPROP_ENUMERATE)) {
>         return JS_FALSE;
>     }
> 
>     if (!JS_DefineProperty(cx, obj, js_lineno_str,
>                            INT_TO_JSVAL(lineno),
>                            NULL, NULL, JSPROP_ENUMERATE)) {
>         return JS_FALSE;
>     }
> 
>     /*
>      * Set the 'stack' property.
>      *
>      * First, set aside any error reporter for cx and save its exception state
>      * so we can suppress any checkAccess failures.  Such failures should stop
>      * the backtrace procedure, not result in a failure of this constructor.
>      */
>     checkAccess = cx->runtime->checkObjectAccess;
>     if (checkAccess) {
>         older = JS_SetErrorReporter(cx, NULL);
>         state = JS_SaveExceptionState(cx);
>     }
> #ifdef __GNUC__         /* suppress bogus gcc warnings */
>     else {
>         older = NULL;
>         state = NULL;
>     }
> #endif
>     callerid = ATOM_KEY(cx->runtime->atomState.callerAtom);
> 
>     /*
>      * Prepare to allocate a jschar buffer at stackbuf, where stacklen indexes
>      * the next free jschar slot, and with room for at most stackmax non-null
>      * jschars.  If stackbuf is non-null, it always contains an extra slot for
>      * the null terminator we'll store at the end, as a backstop.
>      *
>      * All early returns must goto done after this point, till the after-loop
>      * cleanup code has run!
>      */
617,619c395
< 
< /* Limit the stackbuf length to a reasonable value to avoid overflow checks. */
< #define STACK_LENGTH_LIMIT JS_BIT(20)
---
>     ok = JS_TRUE;
625,626d400
<             if (stackmax >= STACK_LENGTH_LIMIT)                               \
<                 goto done;                                                    \
629,631c403,407
<             if (!ptr_)                                                        \
<                 goto bad;                                                     \
<             stackbuf = (jschar *) ptr_;                                       \
---
>             if (!ptr_) {                                                      \
>                 ok = JS_FALSE;                                                \
>                 goto done;                                                    \
>             }                                                                 \
>             stackbuf = ptr_;                                                  \
639,643c415,416
<         jschar *chars_;                                                       \
<         size_t length_;                                                       \
<                                                                               \
<         JSSTRING_CHARS_AND_LENGTH(str_, chars_, length_);                     \
<         if (length_ > stackmax - stacklen) {                                  \
---
>         size_t length_ = JSSTRING_LENGTH(str_);                               \
>         if (stacklen + length_ > stackmax) {                                  \
645,648d417
<             if (stackmax >= STACK_LENGTH_LIMIT ||                             \
<                 length_ >= STACK_LENGTH_LIMIT - stacklen) {                   \
<                 goto done;                                                    \
<             }                                                                 \
651,653c420,424
<             if (!ptr_)                                                        \
<                 goto bad;                                                     \
<             stackbuf = (jschar *) ptr_;                                       \
---
>             if (!ptr_) {                                                      \
>                 ok = JS_FALSE;                                                \
>                 goto done;                                                    \
>             }                                                                 \
>             stackbuf = ptr_;                                                  \
655c426
<         js_strncpy(stackbuf + stacklen, chars_, length_);                     \
---
>         js_strncpy(stackbuf + stacklen, JSSTRING_CHARS(str_), length_);       \
659,663c430,445
<     values = GetStackTraceValueBuffer(priv);
<     elem = priv->stackElems;
<     for (endElem = elem + priv->stackDepth; elem != endElem; elem++) {
<         if (elem->funName) {
<             APPEND_STRING_TO_STACK(elem->funName);
---
>     for (fp = cx->fp; fp; fp = fp->down) {
>         if (checkAccess) {
>             v = (fp->fun && fp->argv) ? fp->argv[-2] : JSVAL_NULL;
>             if (!JSVAL_IS_PRIMITIVE(v)) {
>                 ok = checkAccess(cx, fp->fun->object, callerid, JSACC_READ, &v);
>                 if (!ok) {
>                     ok = JS_TRUE;
>                     break;
>                 }
>             }
>         }
> 
>         if (fp->fun) {
>             if (fp->fun->atom)
>                 APPEND_STRING_TO_STACK(ATOM_TO_STRING(fp->fun->atom));
> 
665c447,469
<             for (i = 0; i != elem->argc; i++, values++) {
---
>             for (i = 0; i < fp->argc; i++) {
>                 /* Avoid toSource bloat and fallibility for object types. */
>                 v = fp->argv[i];
>                 if (JSVAL_IS_PRIMITIVE(v)) {
>                     argsrc = js_ValueToSource(cx, v);
>                 } else if (JSVAL_IS_FUNCTION(cx, v)) {
>                     /* XXX Avoid function decompilation bloat for now. */
>                     argsrc = JS_GetFunctionId(JS_ValueToFunction(cx, v));
>                     if (!argsrc)
>                         argsrc = js_ValueToSource(cx, v);
>                 } else {
>                     /* XXX Avoid toString on objects, it takes too long and
>                            uses too much memory, for too many classes (see
>                            Mozilla bug 166743). */
>                     char buf[100];
>                     JS_snprintf(buf, sizeof buf, "[object %s]",
>                                 OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(v))->name);
>                     argsrc = JS_NewStringCopyZ(cx, buf);
>                 }
>                 if (!argsrc) {
>                     ok = JS_FALSE;
>                     goto done;
>                 }
668,671c472
<                 str = ValueToShortSource(cx, *values);
<                 if (!str)
<                     goto bad;
<                 APPEND_STRING_TO_STACK(str);
---
>                 APPEND_STRING_TO_STACK(argsrc);
674a476
> 
676,677c478,479
<         if (elem->filename) {
<             for (cp = elem->filename; *cp; cp++)
---
>         if (fp->script && fp->script->filename) {
>             for (cp = fp->script->filename; *cp; cp++)
681,683c483,490
<         JS_snprintf(ulnbuf, sizeof ulnbuf, "%u", elem->ulineno);
<         for (cp = ulnbuf; *cp; cp++)
<             APPEND_CHAR_TO_STACK(*cp);
---
>         if (fp->script && fp->pc) {
>             ulineno = js_PCToLineNumber(fp->script, fp->pc);
>             JS_snprintf(ulnbuf, sizeof ulnbuf, "%u", ulineno);
>             for (cp = ulnbuf; *cp; cp++)
>                 APPEND_CHAR_TO_STACK(*cp);
>         } else {
>             APPEND_CHAR_TO_STACK('0');
>         }
685a493
> 
688d495
< #undef STACK_LENGTH_LIMIT
690,693c497,503
<   done:
<     if (stacklen == 0) {
<         JS_ASSERT(!stackbuf);
<         return cx->runtime->emptyString;
---
> done:
>     if (checkAccess) {
>         if (ok)
>             JS_RestoreExceptionState(cx, state);
>         else
>             JS_DropExceptionState(cx, state);
>         JS_SetErrorReporter(cx, older);
695,712c505
<     if (stacklen < stackmax) {
<         /*
<          * Realloc can fail when shrinking on some FreeBSD versions, so
<          * don't use JS_realloc here; simply let the oversized allocation
<          * be owned by the string in that rare case.
<          */
<         void *shrunk = JS_realloc(cx, stackbuf, (stacklen+1) * sizeof(jschar));
<         if (shrunk)
<             stackbuf = (jschar *) shrunk;
<     }
< 
<     stackbuf[stacklen] = 0;
<     str = js_NewString(cx, stackbuf, stacklen);
<     if (str)
<         return str;
< 
<   bad:
<     if (stackbuf)
---
>     if (!ok) {
714,723c507,508
<     return NULL;
< }
< 
< /* XXXbe Consolidate the ugly truth that we don't treat filename as UTF-8
<          with these two functions. */
< static JSString *
< FilenameToString(JSContext *cx, const char *filename)
< {
<     return JS_NewStringCopyZ(cx, filename);
< }
---
>         return JS_FALSE;
>     }
725,728c510,534
< static const char *
< StringToFilename(JSContext *cx, JSString *str)
< {
<     return js_GetStringBytes(cx, str);
---
>     if (!stackbuf) {
>         stack = cx->runtime->emptyString;
>     } else {
>         /* NB: if stackbuf was allocated, it has room for the terminator. */
>         JS_ASSERT(stacklen <= stackmax);
>         if (stacklen < stackmax) {
>             /*
>              * Realloc can fail when shrinking on some FreeBSD versions, so
>              * don't use JS_realloc here; simply let the oversized allocation
>              * be owned by the string in that rare case.
>              */
>             void *shrunk = xrealloc(stackbuf, (stacklen+1) * sizeof(jschar));
>             if (shrunk)
>                 stackbuf = shrunk;
>         }
>         stackbuf[stacklen] = 0;
>         stack = js_NewString(cx, stackbuf, stacklen, 0);
>         if (!stack) {
>             JS_free(cx, stackbuf);
>             return JS_FALSE;
>         }
>     }
>     return JS_DefineProperty(cx, obj, js_stack_str,
>                              STRING_TO_JSVAL(stack),
>                              NULL, NULL, JSPROP_ENUMERATE);
734c540,542
<     uint32 lineno;
---
>     JSBool ok;
>     jsval pval;
>     int32 lineno;
736c544,547
<     JSStackFrame *fp;
---
> 
>     if (cx->creatingException)
>         return JS_FALSE;
>     cx->creatingException = JS_TRUE;
746,753c557,566
<         if (!OBJ_GET_PROPERTY(cx, JSVAL_TO_OBJECT(argv[-2]),
<                               ATOM_TO_JSID(cx->runtime->atomState
<                                            .classPrototypeAtom),
<                               rval))
<             return JS_FALSE;
<         obj = js_NewObject(cx, &js_ErrorClass, JSVAL_TO_OBJECT(*rval), NULL);
<         if (!obj)
<             return JS_FALSE;
---
>         ok = OBJ_GET_PROPERTY(cx, JSVAL_TO_OBJECT(argv[-2]),
>                               (jsid)cx->runtime->atomState.classPrototypeAtom,
>                               &pval);
>         if (!ok)
>             goto out;
>         obj = js_NewObject(cx, &ExceptionClass, JSVAL_TO_OBJECT(pval), NULL);
>         if (!obj) {
>             ok = JS_FALSE;
>             goto out;
>         }
761,762c574,575
<     if (OBJ_GET_CLASS(cx, obj) == &js_ErrorClass)
<         STOBJ_SET_SLOT(obj, JSSLOT_PRIVATE, JSVAL_VOID);
---
>     if (OBJ_GET_CLASS(cx, obj) == &ExceptionClass)
>         OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, JSVAL_VOID);
767,769c580,583
<         if (!message)
<             return JS_FALSE;
<         argv[0] = STRING_TO_JSVAL(message);
---
>         if (!message) {
>             ok = JS_FALSE;
>             goto out;
>         }
777,788c591,593
<         if (!filename)
<             return JS_FALSE;
<         argv[1] = STRING_TO_JSVAL(filename);
<         fp = NULL;
<     } else {
<         fp = JS_GetScriptedCaller(cx, NULL);
<         if (fp) {
<             filename = FilenameToString(cx, fp->script->filename);
<             if (!filename)
<                 return JS_FALSE;
<         } else {
<             filename = cx->runtime->emptyString;
---
>         if (!filename) {
>             ok = JS_FALSE;
>             goto out;
789a595,596
>     } else {
>         filename = cx->runtime->emptyString;
794,795c601,603
<         if (!js_ValueToECMAUint32(cx, argv[2], &lineno))
<             return JS_FALSE;
---
>         ok = js_ValueToInt32(cx, argv[2], &lineno);
>         if (!ok)
>             goto out;
797,799c605
<         if (!fp)
<             fp = JS_GetScriptedCaller(cx, NULL);
<         lineno = (fp && fp->pc) ? js_PCToLineNumber(cx, fp->script, fp->pc) : 0;
---
>         lineno = 0;
802,803c608,612
<     return (OBJ_GET_CLASS(cx, obj) != &js_ErrorClass) ||
<             InitExnPrivate(cx, obj, message, filename, lineno, NULL);
---
>     ok = InitExceptionObject(cx, obj, message, filename, lineno);
> 
> out:
>     cx->creatingException = JS_FALSE;
>     return ok;
814c623
< exn_toString(JSContext *cx, uintN argc, jsval *vp)
---
> exn_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
816d624
<     JSObject *obj;
822,825c630,633
<     obj = JSVAL_TO_OBJECT(vp[1]);
<     if (!OBJ_GET_PROPERTY(cx, obj,
<                           ATOM_TO_JSID(cx->runtime->atomState.nameAtom),
<                           &v)) {
---
>     if (!OBJ_GET_PROPERTY(cx, obj, (jsid)cx->runtime->atomState.nameAtom, &v))
>         return JS_FALSE;
>     name = js_ValueToString(cx, v);
>     if (!name)
827,829d634
<     }
<     name = JSVAL_IS_STRING(v) ? JSVAL_TO_STRING(v) : cx->runtime->emptyString;
<     *vp = STRING_TO_JSVAL(name);
831c636,637
<     if (!JS_GetProperty(cx, obj, js_message_str, &v))
---
>     if (!JS_GetProperty(cx, obj, js_message_str, &v) ||
>         !(message = js_ValueToString(cx, v))) {
833,834c639
<     message = JSVAL_IS_STRING(v) ? JSVAL_TO_STRING(v)
<                                  : cx->runtime->emptyString;
---
>     }
839,840c644,646
<         length = (name_length ? name_length + 2 : 0) + message_length;
<         cp = chars = (jschar *) JS_malloc(cx, (length + 1) * sizeof(jschar));
---
>         length = name_length + message_length + 2;
>         XMEMTAG("exn_toString ");
>         cp = chars = (jschar*) JS_malloc(cx, (length + 1) * sizeof(jschar));
844,848c650,652
<         if (name_length) {
<             js_strncpy(cp, JSSTRING_CHARS(name), name_length);
<             cp += name_length;
<             *cp++ = ':'; *cp++ = ' ';
<         }
---
>         js_strncpy(cp, JSSTRING_CHARS(name), name_length);
>         cp += name_length;
>         *cp++ = ':'; *cp++ = ' ';
853c657
<         result = js_NewString(cx, chars, length);
---
>         result = js_NewString(cx, chars, length, 0);
862c666
<     *vp = STRING_TO_JSVAL(result);
---
>     *rval = STRING_TO_JSVAL(result);
871c675
< exn_toSource(JSContext *cx, uintN argc, jsval *vp)
---
> exn_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
873c677
<     JSObject *obj;
---
>     jsval v;
875,878c679
<     jsval localroots[3] = {JSVAL_NULL, JSVAL_NULL, JSVAL_NULL};
<     JSTempValueRooter tvr;
<     JSBool ok;
<     uint32 lineno;
---
>     int32 lineno;
882,885c683
<     obj = JS_THIS_OBJECT(cx, vp);
<     if (!OBJ_GET_PROPERTY(cx, obj,
<                           ATOM_TO_JSID(cx->runtime->atomState.nameAtom),
<                           vp)) {
---
>     if (!OBJ_GET_PROPERTY(cx, obj, (jsid)cx->runtime->atomState.nameAtom, &v))
887,888c685
<     }
<     name = js_ValueToString(cx, *vp);
---
>     name = js_ValueToString(cx, v);
891d687
<     *vp = STRING_TO_JSVAL(name);
893,900c689,692
<     /* After this, control must flow through label out: to exit. */
<     JS_PUSH_TEMP_ROOT(cx, 3, localroots, &tvr);
< 
<     ok = JS_GetProperty(cx, obj, js_message_str, &localroots[0]) &&
<          (message = js_ValueToSource(cx, localroots[0]));
<     if (!ok)
<         goto out;
<     localroots[0] = STRING_TO_JSVAL(message);
---
>     if (!JS_GetProperty(cx, obj, js_message_str, &v) ||
>         !(message = js_ValueToSource(cx, v))) {
>         return JS_FALSE;
>     }
902,906c694,697
<     ok = JS_GetProperty(cx, obj, js_fileName_str, &localroots[1]) &&
<          (filename = js_ValueToSource(cx, localroots[1]));
<     if (!ok)
<         goto out;
<     localroots[1] = STRING_TO_JSVAL(filename);
---
>     if (!JS_GetProperty(cx, obj, js_filename_str, &v) ||
>         !(filename = js_ValueToSource(cx, v))) {
>         return JS_FALSE;
>     }
908,911c699,702
<     ok = JS_GetProperty(cx, obj, js_lineNumber_str, &localroots[2]) &&
<          js_ValueToECMAUint32 (cx, localroots[2], &lineno);
<     if (!ok)
<         goto out;
---
>     if (!JS_GetProperty(cx, obj, js_lineno_str, &v) ||
>         !js_ValueToInt32 (cx, v, &lineno)) {
>         return JS_FALSE;
>     }
914,917c705,706
<         lineno_as_str = js_ValueToString(cx, localroots[2]);
<         if (!lineno_as_str) {
<             ok = JS_FALSE;
<             goto out;
---
>         if (!(lineno_as_str = js_ValueToString(cx, v))) {
>             return JS_FALSE;
948,952c737,740
<     cp = chars = (jschar *) JS_malloc(cx, (length + 1) * sizeof(jschar));
<     if (!chars) {
<         ok = JS_FALSE;
<         goto out;
<     }
---
> 	XMEMTAG("exn_toString 2");
>     cp = chars = (jschar*) JS_malloc(cx, (length + 1) * sizeof(jschar));
>     if (!chars)
>         return JS_FALSE;
986c774
<     result = js_NewString(cx, chars, length);
---
>     result = js_NewString(cx, chars, length, 0);
989,990c777
<         ok = JS_FALSE;
<         goto out;
---
>         return JS_FALSE;
992,997c779,780
<     *vp = STRING_TO_JSVAL(result);
<     ok = JS_TRUE;
< 
< out:
<     JS_POP_TEMP_ROOT(cx, &tvr);
<     return ok;
---
>     *rval = STRING_TO_JSVAL(result);
>     return JS_TRUE;
1003c786
<     JS_FN(js_toSource_str,   exn_toSource,           0,0,0),
---
>     {js_toSource_str,   exn_toSource,           0,0,0},
1005,1006c788,789
<     JS_FN(js_toString_str,   exn_toString,           0,0,0),
<     JS_FS_END
---
>     {js_toString_str,   exn_toString,           0,0,0},
>     {0,0,0,0,0}
1012d794
<     JSObject *obj_proto, *protos[JSEXN_LIMIT];
1014,1031c796
< 
<     /*
<      * If lazy class initialization occurs for any Error subclass, then all
<      * classes are initialized, starting with Error.  To avoid reentry and
<      * redundant initialization, we must not pass a null proto parameter to
<      * js_NewObject below, when called for the Error superclass.  We need to
<      * ensure that Object.prototype is the proto of Error.prototype.
<      *
<      * See the equivalent code to ensure that parent_proto is non-null when
<      * JS_InitClass calls js_NewObject, in jsapi.c.
<      */
<     if (!js_GetClassPrototype(cx, obj, INT_TO_JSID(JSProto_Object),
<                               &obj_proto)) {
<         return NULL;
<     }
< 
<     if (!js_EnterLocalRootScope(cx))
<         return NULL;
---
>     JSObject *protos[JSEXN_LIMIT];
1037d801
<         JSObject *funobj;
1042c806
<         protos[i] = js_NewObject(cx, &js_ErrorClass,
---
>         protos[i] = js_NewObject(cx, &ExceptionClass,
1045c809
<                                  : obj_proto,
---
>                                  : NULL,
1048c812
<             break;
---
>             return NULL;
1051c815,819
<         STOBJ_SET_SLOT(protos[i], JSSLOT_PRIVATE, JSVAL_VOID);
---
>         OBJ_SET_SLOT(cx, protos[i], JSSLOT_PRIVATE, JSVAL_VOID);
> 
>         atom = js_Atomize(cx, exceptions[i].name, strlen(exceptions[i].name), 0);
>         if (!atom)
>             return NULL;
1054d821
<         atom = cx->runtime->atomState.classAtoms[exceptions[i].key];
1057c824
<             break;
---
>             return NULL;
1060,1063c827
<         fun->u.n.clasp = &js_ErrorClass;
< 
<         /* Extract the constructor object. */
<         funobj = fun->object;
---
>         fun->clasp = &ExceptionClass;
1066c830
<         if (!js_SetClassPrototype(cx, funobj, protos[i],
---
>         if (!js_SetClassPrototype(cx, fun->object, protos[i],
1068c832
<             break;
---
>             return NULL;
1074c838
<             break;
---
>             return NULL;
1081c845
<             break;
---
>             return NULL;
1083,1086d846
< 
<         /* Finally, stash the constructor for later uses. */
<         if (!js_SetClassObject(cx, obj, exceptions[i].key, funobj))
<             break;
1089,1092d848
<     js_LeaveLocalRootScope(cx);
<     if (exceptions[i].name)
<         return NULL;
< 
1103c859
<     if (!JS_DefineProperty(cx, protos[0], js_fileName_str,
---
>     if (!JS_DefineProperty(cx, protos[0], js_filename_str,
1108c864
<     if (!JS_DefineProperty(cx, protos[0], js_lineNumber_str,
---
>     if (!JS_DefineProperty(cx, protos[0], js_lineno_str,
1124,1137c880,885
< const JSErrorFormatString*
< js_GetLocalizedErrorMessage(JSContext* cx, void *userRef, const char *locale,
<                             const uintN errorNumber)
< {
<     const JSErrorFormatString *errorString = NULL;
< 
<     if (cx->localeCallbacks && cx->localeCallbacks->localeGetErrorMessage) {
<         errorString = cx->localeCallbacks
<                         ->localeGetErrorMessage(userRef, locale, errorNumber);
<     }
<     if (!errorString)
<         errorString = js_GetErrorMessage(userRef, locale, errorNumber);
<     return errorString;
< }
---
> static JSExnType errorToExceptionNum[] = {
> #define MSG_DEF(name, number, count, exception, format) \
>     exception,
> #include "js.msg"
> #undef MSG_DEF
> };
1153d900
<     const JSErrorFormatString *errorString;
1155,1156d901
<     jsval tv[4];
<     JSTempValueRooter tvr;
1159a905,906
>     uintN lineno;
>     JSExnPrivate *privateData;
1171,1172c918
<     errorString = js_GetLocalizedErrorMessage(cx, NULL, NULL, errorNumber);
<     exn = errorString ? (JSExnType) errorString->exnType : JSEXN_NONE;
---
>     exn = errorToExceptionNum[errorNumber];
1190,1193c936,940
<      * Prevent runaway recursion, via cx->generatingError.  If an out-of-memory
<      * error occurs, no exception object will be created, but we don't assume
<      * that OOM is the only kind of error that subroutines of this function
<      * called below might raise.
---
>      * Prevent runaway recursion, just as the Exception native constructor
>      * must do, via cx->creatingException.  If an out-of-memory error occurs,
>      * no exception object will be created, but we don't assume that OOM is
>      * the only kind of error that subroutines of this function called below
>      * might raise.
1195c942
<     if (cx->generatingError)
---
>     if (cx->creatingException)
1197,1203c944
< 
<     /* After this point the control must flow through the label out. */
<     cx->generatingError = JS_TRUE;
< 
<     /* Protect the newly-created strings below from nesting GCs. */
<     memset(tv, 0, sizeof tv);
<     JS_PUSH_TEMP_ROOT(cx, JS_ARRAY_LENGTH(tv), tv, &tvr);
---
>     cx->creatingException = JS_TRUE;
1208a950,957
>      *
>      * XXXbe hack around JSCLASS_NEW_RESOLVE code in js_LookupProperty that
>      *       checks cx->fp, cx->fp->pc, and js_CodeSpec[*cx->fp->pc] in order
>      *       to compute resolve flags such as JSRESOLVE_ASSIGNING.  The bug
>      *       is that this "internal" js_GetClassPrototype call may trigger a
>      *       resolve of exceptions[exn].name if the global object uses a lazy
>      *       standard class resolver (see JS_ResolveStandardClass), but the
>      *       current frame and bytecode end up affecting the resolve flags.
1210,1214c959,972
<     ok = js_GetClassPrototype(cx, NULL, INT_TO_JSID(exceptions[exn].key),
<                               &errProto);
<     if (!ok)
<         goto out;
<     tv[0] = OBJECT_TO_JSVAL(errProto);
---
>     {
>         JSStackFrame *fp = cx->fp;
>         jsbytecode *pc = NULL;
> 
>         if (fp) {
>             pc = fp->pc;
>             fp->pc = NULL;
>         }
>         ok = js_GetClassPrototype(cx, exceptions[exn].name, &errProto);
>         if (pc)
>             fp->pc = pc;
>         if (!ok)
>             goto out;
>     }
1216c974
<     errObject = js_NewObject(cx, &js_ErrorClass, errProto, NULL);
---
>     errObject = js_NewObject(cx, &ExceptionClass, errProto, NULL);
1221c979,987
<     tv[1] = OBJECT_TO_JSVAL(errObject);
---
> 
>     /*
>      * Set the generated Exception object early, so it won't be GC'd by a last
>      * ditch attempt to collect garbage, or a GC that otherwise nests or races
>      * under any of the following calls.  If one of the following calls fails,
>      * it will overwrite this exception object with one of its own (except in
>      * case of OOM errors, of course).
>      */
>     JS_SetPendingException(cx, OBJECT_TO_JSVAL(errObject));
1228d993
<     tv[2] = STRING_TO_JSVAL(messageStr);
1230,1233c995,1004
<     filenameStr = JS_NewStringCopyZ(cx, reportp->filename);
<     if (!filenameStr) {
<         ok = JS_FALSE;
<         goto out;
---
>     if (reportp) {
>         filenameStr = JS_NewStringCopyZ(cx, reportp->filename);
>         if (!filenameStr) {
>             ok = JS_FALSE;
>             goto out;
>         }
>         lineno = reportp->lineno;
>     } else {
>         filenameStr = cx->runtime->emptyString;
>         lineno = 0;
1235,1238c1006
<     tv[3] = STRING_TO_JSVAL(filenameStr);
< 
<     ok = InitExnPrivate(cx, errObject, messageStr, filenameStr,
<                         reportp->lineno, reportp);
---
>     ok = InitExceptionObject(cx, errObject, messageStr, filenameStr, lineno);
1242c1010,1021
<     JS_SetPendingException(cx, OBJECT_TO_JSVAL(errObject));
---
>     /*
>      * Construct a new copy of the error report struct, and store it in the
>      * exception object's private data.  We can't use the error report struct
>      * that was passed in, because it's stack-allocated, and also because it
>      * may point to transient data in the JSTokenStream.
>      */
>     privateData = exn_newPrivate(cx, reportp);
>     if (!privateData) {
>         ok = JS_FALSE;
>         goto out;
>     }
>     OBJ_SET_SLOT(cx, errObject, JSSLOT_PRIVATE, PRIVATE_TO_JSVAL(privateData));
1248,1249c1027
<     JS_POP_TEMP_ROOT(cx, &tvr);
<     cx->generatingError = JS_FALSE;
---
>     cx->creatingException = JS_FALSE;
1251a1030,1032
> #endif /* JS_HAS_ERROR_EXCEPTIONS */
> 
> #if JS_HAS_EXCEPTIONS
1256d1036
<     jsval exn;
1258,1260d1037
<     jsval roots[5];
<     JSTempValueRooter tvr;
<     JSErrorReport *reportp, report;
1261a1039,1040
>     jsval exn;
>     JSErrorReport *reportp;
1263d1041
<     JSBool ok;
1266c1044
<         return JS_TRUE;
---
>         return JS_FALSE;
1271,1273d1048
<     memset(roots, 0, sizeof roots);
<     JS_PUSH_TEMP_ROOT(cx, JS_ARRAY_LENGTH(roots), roots, &tvr);
< 
1276,1278c1051
<      * could become unrooted, we must root exnObject.  Later, if exnObject is
<      * non-null, we need to root other intermediates, so allocate an operand
<      * stack segment to protect all of these values.
---
>      * could become unrooted, we root it here.
1280,1282c1053
<     if (JSVAL_IS_PRIMITIVE(exn)) {
<         exnObject = NULL;
<     } else {
---
>     if (JSVAL_IS_OBJECT(exn) && exn != JSVAL_NULL) {
1284c1055,1058
<         roots[0] = exn;
---
>         if (!js_AddRoot(cx, &exnObject, "exn.report.root"))
>             return JS_FALSE;
>     } else {
>         exnObject = NULL;
1287c1061
<     JS_ClearPendingException(cx);
---
> #if JS_HAS_ERROR_EXCEPTIONS
1288a1063,1065
> #else
>     reportp = NULL;
> #endif
1290d1066
<     /* XXX L10N angels cry once again (see also jsemit.c, /L10N gaffes/) */
1292,1346c1068
<     if (!str) {
<         bytes = "unknown (can't convert to string)";
<     } else {
<         roots[1] = STRING_TO_JSVAL(str);
<         bytes = js_GetStringBytes(cx, str);
<         if (!bytes) {
<             ok = JS_FALSE;
<             goto out;
<         }
<     }
<     ok = JS_TRUE;
< 
<     if (!reportp &&
<         exnObject &&
<         OBJ_GET_CLASS(cx, exnObject) == &js_ErrorClass) {
<         const char *filename;
<         uint32 lineno;
< 
<         ok = JS_GetProperty(cx, exnObject, js_message_str, &roots[2]);
<         if (!ok)
<             goto out;
<         if (JSVAL_IS_STRING(roots[2])) {
<             bytes = js_GetStringBytes(cx, JSVAL_TO_STRING(roots[2]));
<             if (!bytes) {
<                 ok = JS_FALSE;
<                 goto out;
<             }
<         }
< 
<         ok = JS_GetProperty(cx, exnObject, js_fileName_str, &roots[3]);
<         if (!ok)
<             goto out;
<         str = js_ValueToString(cx, roots[3]);
<         if (!str) {
<             ok = JS_FALSE;
<             goto out;
<         }
<         filename = StringToFilename(cx, str);
<         if (!filename) {
<             ok = JS_FALSE;
<             goto out;
<         }
< 
<         ok = JS_GetProperty(cx, exnObject, js_lineNumber_str, &roots[4]);
<         if (!ok)
<             goto out;
<         ok = js_ValueToECMAUint32 (cx, roots[4], &lineno);
<         if (!ok)
<             goto out;
< 
<         reportp = &report;
<         memset(&report, 0, sizeof report);
<         report.filename = filename;
<         report.lineno = (uintN) lineno;
<     }
---
>     bytes = str ? js_GetStringBytes(str) : "null";
1348c1070,1075
<     if (!reportp) {
---
>     if (reportp == NULL) {
>         /*
>          * XXXmccabe todo: Instead of doing this, synthesize an error report
>          * struct that includes the filename, lineno where the exception was
>          * originally thrown.
>          */
1357,1359c1084,1086
< out:
<     JS_POP_TEMP_ROOT(cx, &tvr);
<     return ok;
---
>     if (exnObject != NULL)
>         js_RemoveRoot(cx->runtime, &exnObject);
>     return JS_TRUE;
1360a1088,1089
> 
> #endif /* JS_HAS_EXCEPTIONS */
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsexn.h /Volumes/Swap/js_D11/src/jsexn.h
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
49,50d43
< extern JSClass js_ErrorClass;
< 
57a51,62
>  * String constants naming the exception classes.
>  */
> extern const char js_Error_str[];
> extern const char js_InternalError_str[];
> extern const char js_EvalError_str[];
> extern const char js_RangeError_str[];
> extern const char js_ReferenceError_str[];
> extern const char js_SyntaxError_str[];
> extern const char js_TypeError_str[];
> extern const char js_URIError_str[];
> 
> /*
90,93d94
< extern const JSErrorFormatString *
< js_GetLocalizedErrorMessage(JSContext* cx, void *userRef, const char *locale,
<                             const uintN errorNumber);
< 
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsfile.c /Volumes/Swap/js_D11/src/jsfile.c
2d1
<  * vim: set ts=8 sw=4 et tw=78:
4,5c3,6
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
7,15c8,11
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
20,25c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
27,37c21
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
---
>  * Contributor(s): 
39c23,33
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
47c41,43
< #include "jsfile.h"
---
> 
> 
> //#include "_optimize.h"
50c46,51
< #if defined(XP_WIN) || defined(XP_OS2)
---
> #ifdef XP_MAC
> #   define FILESEPARATOR         ':'
> #   define FILESEPARATOR2        '\0'
> #   define CURRENT_DIR          "HARD DISK:Desktop Folder"
> /*  TODO: #include <???> */
> #elif defined(XP_WIN) || defined(XP_OS2)
63c64
< #   include <stdlib.h>
---
> #   include "xstdlib.h"
118c119
< #define RESOLVE_PATH            js_canonicalPath        /* js_absolutePath */
---
> #define RESOLVE_PATH            js_canonicalPath	/* js_absolutePath */
135c136
<     { format, count },
---
>     { format, count } ,
138c139
<     { NULL, count },
---
>     { NULL, count } ,
150,151c151,152
<     else
<         return NULL;
---
> 	else
> 	    return NULL;
154,207c155,209
< #define JSFILE_CHECK_NATIVE(op)                                               \
<     if (file->isNative) {                                                     \
<         JS_ReportWarning(cx, "Cannot call or access \"%s\" on native file %s",\
<                          op, file->path);                                     \
<         goto out;                                                             \
<     }
< 
< #define JSFILE_CHECK_WRITE                                                    \
<     if (!file->isOpen) {                                                      \
<         JS_ReportWarning(cx,                                                  \
<                 "File %s is closed, will open it for writing, proceeding",    \
<                 file->path);                                                  \
<         js_FileOpen(cx, obj, file, "write,append,create");                    \
<     }                                                                         \
<     if (!js_canWrite(cx, file)) {                                             \
<         JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,                \
<                              JSFILEMSG_CANNOT_WRITE, file->path);             \
<         goto out;                                                             \
<     }
< 
< #define JSFILE_CHECK_READ                                                     \
<     if (!file->isOpen) {                                                      \
<         JS_ReportWarning(cx,                                                  \
<                 "File %s is closed, will open it for reading, proceeding",    \
<                 file->path);                                                  \
<         js_FileOpen(cx, obj, file, "read");                                   \
<     }                                                                         \
<     if (!js_canRead(cx, file)) {                                              \
<         JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,                \
<                              JSFILEMSG_CANNOT_READ, file->path);              \
<         goto out;                                                             \
<     }
< 
< #define JSFILE_CHECK_OPEN(op)                                                 \
<     if (!file->isOpen) {                                                      \
<         JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,                \
<                              JSFILEMSG_FILE_MUST_BE_OPEN, op);                \
<         goto out;                                                             \
<     }
< 
< #define JSFILE_CHECK_CLOSED(op)                                               \
<     if (file->isOpen) {                                                       \
<         JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,                \
<                              JSFILEMSG_FILE_MUST_BE_CLOSED, op);              \
<         goto out;                                                             \
<     }
< 
< #define JSFILE_CHECK_ONE_ARG(op)                                              \
<     if (argc != 1) {                                                          \
<         char str[NUMBER_SIZE];                                                \
<         sprintf(str, "%d", argc);                                             \
<         JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,                \
<                              JSFILEMSG_EXPECTS_ONE_ARG_ERROR, op, str);       \
<         goto out;                                                             \
---
> #define JSFILE_CHECK_NATIVE(op)     \
>     if(file->isNative){         \
>         JS_ReportWarning(cx, "Cannot call or access \"%s\" on native file %s", \
> 						op, file->path);   \
>         goto out;   \
>     }
> 
> #define JSFILE_CHECK_WRITE      \
>     if (!file->isOpen){     \
>         JS_ReportWarning(cx,    \
>                 "File %s is closed, will open it for writing, proceeding",  \
>                 file->path);    \
>         js_FileOpen(cx, obj, file, "write,append,create");     \
>     }else   \
>     if(!js_canWrite(cx, file)){     \
>         JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,  \
>             JSFILEMSG_CANNOT_WRITE, file->path);    \
>         goto out;   \
>     }
> 
> #define JSFILE_CHECK_READ      \
>     if (!file->isOpen){     \
>         JS_ReportWarning(cx,    \
>                 "File %s is closed, will open it for reading, proceeding",  \
>                 file->path); \
>         js_FileOpen(cx, obj, file, "read");     \
>     }else   \
>     if(!js_canRead(cx, file)){     \
>         JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,  \
>             JSFILEMSG_CANNOT_READ, file->path);    \
>         goto out;   \
>     }
> 
> #define JSFILE_CHECK_OPEN(op)      \
>     if(!file->isOpen){     \
>         JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,  \
>             JSFILEMSG_FILE_MUST_BE_CLOSED, op);    \
>         goto out;   \
>     }
> 
> #define JSFILE_CHECK_CLOSED(op)      \
>     if(file->isOpen){     \
>         JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,  \
>             JSFILEMSG_FILE_MUST_BE_OPEN, op);    \
>         goto out;   \
>     }
> 
> #define JSFILE_CHECK_ONE_ARG(op)      \
>     if (argc!=1){   \
>         char str[NUMBER_SIZE];  \
>                                 \
>         sprintf(str, "%d", argc);   \
>         JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,  \
>             JSFILEMSG_EXPECTS_ONE_ARG_ERROR, op, str);  \
>         goto out;   \
215,216d216
<     XXX Should this be a real function returning a JSBool result (and getting
<     some typesafety help from the compiler?).
225a226
>     JSString    *linebuffer;    /* temp buffer used by readln. */
232c233
<     JSBool      hasRandomAccess;/* can the file be randomly accessed? false for stdin, and
---
>     JSBool      hasRandomAccess;   /* can the file be randomly accessed? false for stdin, and
242a244
> static JSClass file_class;
247c249
< /* New filename manipulation procesures */
---
> /* --------------------------- New filename manipulation procesures -------------------------- */
252,256c254,261
<     if (!filename)
<         return JS_FALSE;
< 
<     return  filename[0] == PIPE_SYMBOL ||
<             filename[strlen(filename) - 1] == PIPE_SYMBOL;
---
> #ifdef XP_MAC
>     /* pipes are not supported on the MAC */
>     return JS_FALSE;
> #else
>     if(!filename) return JS_FALSE;
>     return  filename[0]==PIPE_SYMBOL ||
>             filename[strlen(filename)-1]==PIPE_SYMBOL;
> #endif
263c268
<     return *name && name[1] == ':';
---
>     return (strlen(name)>1)?((name[1]==':')?JS_TRUE:JS_FALSE):JS_FALSE;
271c276
<             FILESEPARATOR);
---
>             FILESEPARATOR)?JS_TRUE:JS_FALSE;
276,277c281,282
<  * Concatenates base and name to produce a valid filename.
<  * Returned string must be freed.
---
>     Concatinates base and name to produce a valid filename.
>     Returned string must be freed.
283c288
<     char* result = JS_malloc(cx, len + strlen(name) + 2);
---
>     char* result = (char*)JS_malloc(cx, len+strlen(name)+2);
285,286c290
<     if (!result)
<         return NULL;
---
>     if (!result)  return NULL;
290,292c294,300
<     if (base[len - 1] != FILESEPARATOR && base[len - 1] != FILESEPARATOR2) {
<         result[len] = FILESEPARATOR;
<         result[len + 1] = '\0';
---
>     if (base[len-1]!=FILESEPARATOR
> #if defined(XP_WIN) || defined(XP_OS2)
>             && base[len-1]!=FILESEPARATOR2
> #endif
>             ) {
>       result[len] = FILESEPARATOR;
>       result[len+1] = '\0';
305,310c313,316
<     index = strlen(pathname)-1;
< 
<     /* Chop off trailing seperators. */
<     while (index > 0 && (pathname[index]==FILESEPARATOR ||
<                          pathname[index]==FILESEPARATOR2)) {
<         --index;
---
> #if defined(XP_WIN) || defined(XP_OS2)
>     /* First, get rid of the drive selector */
>     if ((strlen(pathname)>=2)&&(pathname[1]==':')) {
>         pathname = &pathname[2];
312c318,325
< 
---
> #endif
>     index = strlen(pathname)-1;
>     /*
>         remove trailing separators -- don't necessarily need to check for
>         FILESEPARATOR2, but that's fine
>     */
>     while ((index>0)&&((pathname[index]==FILESEPARATOR)||
>                        (pathname[index]==FILESEPARATOR2))) index--;
314,326c327,334
< 
<     /* Now find the next separator. */
<     while (index >= 0 && pathname[index] != FILESEPARATOR &&
<                          pathname[index] != FILESEPARATOR2) {
<         --index;
<     }
< 
<     /* Allocate and copy. */
<     result = JS_malloc(cx, aux - index + 1);
<     if (!result)
<         return NULL;
<     strncpy(result, pathname + index + 1, aux - index);
<     result[aux - index] = '\0';
---
>     /* now find the next separator */
>     while ((index>=0)&&(pathname[index]!=FILESEPARATOR)&&
>                       (pathname[index]!=FILESEPARATOR2)) index--;
>     /* allocate and copy */
>     result = (char*)JS_malloc(cx, aux-index+1);
>     if (!result)  return NULL;
>     strncpy(result, &pathname[index+1], aux-index);
>     result[aux-index] = '\0';
331,333c339,341
<  * Returns everything but the last component from a path name.
<  * Returned string must be freed.
<  */
---
>     Returns everytynig but the last component from a path name.
>     Returned string must be freed. Returned string must be freed.
> */
337,349c345,346
<     char *result;
<     const char *cp, *end;
<     size_t pathsize;
< 
<     end = pathname + strlen(pathname);
<     cp = end - 1;
< 
<     /* If this is already a directory, chop off the trailing /s. */
<     while (cp >= pathname) {
<         if (*cp != FILESEPARATOR && *cp != FILESEPARATOR2)
<             break;
<         --cp;
<     }
---
>     jsint index;
>     char  *result;
351,357c348,350
<     if (cp < pathname && end != pathname) {
<         /* There were just /s, return the root. */
<         result = JS_malloc(cx, 1 + 1); /* The separator + trailing NUL. */
<         result[0] = FILESEPARATOR;
<         result[1] = '\0';
<         return result;
<     }
---
> #if defined(XP_WIN) || defined(XP_OS2)
>     char  drive = '\0';
>     const char *oldpathname = pathname;
359,363c352,355
<     /* Now chop off the last portion. */
<     while (cp >= pathname) {
<         if (*cp == FILESEPARATOR || *cp == FILESEPARATOR2)
<             break;
<         --cp;
---
>     /* First, get rid of the drive selector */
>     if ((strlen(pathname)>=2)&&(pathname[1]==':')) {
>         drive = pathname[0];
>         pathname = &pathname[2];
365,371c357,377
< 
<     /* Check if this is a leaf. */
<     if (cp < pathname) {
<         /* It is, return "pathname/". */
<         if (end[-1] == FILESEPARATOR || end[-1] == FILESEPARATOR2) {
<             /* Already has its terminating /. */
<             return JS_strdup(cx, pathname);
---
> #endif
>     index = strlen(pathname)-1;
>     while ((index>0)&&((pathname[index]==FILESEPARATOR)||
>                        (pathname[index]==FILESEPARATOR2))) index--;
>     while ((index>0)&&(pathname[index]!=FILESEPARATOR)&&
>                       (pathname[index]!=FILESEPARATOR2)) index--;
> 
>     if (index>=0){
>         result = (char*)JS_malloc(cx, index+4);
>         if (!result)  return NULL;
> #if defined(XP_WIN) || defined(XP_OS2)
>         if (drive!='\0') {
>             result[0] = toupper(drive);
>             result[1] = ':';
>             strncpy(&result[2], pathname, index);
> 			result[index+3] = '\0';
>         }else
> #endif
>         {
>             strncpy(result, pathname, index);
> 			result[index] = '\0';
374,383c380,389
<         pathsize = end - pathname + 1;
<         result = JS_malloc(cx, pathsize + 1);
<         if (!result)
<             return NULL;
< 
<         strcpy(result, pathname);
<         result[pathsize - 1] = FILESEPARATOR;
<         result[pathsize] = '\0';
< 
<         return result;
---
>         /* add terminating separator */
>         index = strlen(result)-1;
>         result[index] = FILESEPARATOR;
>         result[index+1] = '\0';
>     } else{
> #if defined(XP_WIN) || defined(XP_OS2)
>         result = JS_strdup(cx, oldpathname); /* may include drive selector */
> #else
>         result = JS_strdup(cx, pathname);
> #endif
386,394d391
<     /* Return everything up to and including the seperator. */
<     pathsize = cp - pathname + 1;
<     result = JS_malloc(cx, pathsize + 1);
<     if (!result)
<         return NULL;
< 
<     strncpy(result, pathname, pathsize);
<     result[pathsize] = '\0';
< 
405c402
<     if (js_isAbsolute(path)) {
---
>     if (js_isAbsolute(path)){
407c404
<     } else {
---
>     }else{
411c408
<                                  JSFILEMSG_FILE_CONSTRUCTOR_UNDEFINED_ERROR);
---
>                  JSFILEMSG_FILE_CONSTRUCTOR_UNDEFINED_ERROR);
414d410
< 
418c414
<                                  JSFILEMSG_FILE_CURRENTDIR_UNDEFINED_ERROR);
---
>                  JSFILEMSG_FILE_CURRENTDIR_UNDEFINED_ERROR);
421d416
< 
423c418
<         if (!str)
---
>         if (!str ) {
425c420
< 
---
>         }
444,451c439,440
<     while (i < j && path[i] == ' ')
<         i++;
<     while (j >= 0 && path[j] == ' ')
<         j--;
< 
<     tmp = JS_malloc(cx, j-i+2);
<     if (!tmp)
<         return NULL;
---
>     while(i<strlen(path)-1 && path[i]==' ') i++;
> 	while(j>=0 && path[j]==' ') j--;
453,454c442,444
<     strncpy(tmp, path + i, j - i + 1);
<     tmp[j - i + 1] = '\0';
---
> 	tmp = JS_malloc(cx, j-i+2);
> 	strncpy(tmp, &path[i], j-i+1);
>     tmp[j-i+1] = '\0';
458,475c448,458
<     /* Pipe support. */
<     if (js_filenameHasAPipe(path))
<         return path;
< 
<     /* file:// support. */
<     if (!strncmp(path, URL_PREFIX, strlen(URL_PREFIX))) {
<         tmp = js_canonicalPath(cx, path + strlen(URL_PREFIX));
<         JS_free(cx, path);
<         return tmp;
<     }
< 
<     if (!js_isAbsolute(path)) {
<         tmp = js_absolutePath(cx, path);
<         if (!tmp)
<             return NULL;
<         JS_free(cx, path);
<         path = tmp;
<     }
---
>     /* pipe support */
>     if(js_filenameHasAPipe(path))
>         return JS_strdup(cx, path);
>     /* file:// support */
>     if(!strncmp(path, URL_PREFIX, strlen(URL_PREFIX)))
>         return js_canonicalPath(cx, &path[strlen(URL_PREFIX)-1]);
> 
>     if (!js_isAbsolute(path))
>         path = js_absolutePath(cx, path);
>     else
>         path = JS_strdup(cx, path);
483a467
>     /* TODO: MAC -- not going to work??? */
486a471,473
>         } else
>         if(!strcmp(base, ".")){
>             /* ??? */
488c475
<             if (back > 0) {
---
>             if (back>0)
490c477
<             } else {
---
>             else {
492,495c479,485
<                 result = JS_malloc(cx, strlen(base) + 1 + strlen(tmp) + 1);
<                 if (!result)
<                     goto out;
< 
---
>                 result = JS_malloc(cx, strlen(base)+1+strlen(tmp)+1);
>                 if (!result) {
>                     JS_free(cx, dir);
>                     JS_free(cx, base);
>                     JS_free(cx, current);
>                     return NULL;
>                 }
500c490
<                     result[c + 1] = '\0';
---
>                     result[c+1] = '\0';
515,517c505,510
<     if (!result)
<         goto out;
< 
---
>     if (!result) {
>         JS_free(cx, dir);
>         JS_free(cx, base);
>         JS_free(cx, current);
>         return NULL;
>     }
527,536c520,523
< 
< out:
<     if (tmp)
<         JS_free(cx, tmp);
<     if (dir)
<         JS_free(cx, dir);
<     if (base)
<         JS_free(cx, base);
<     if (current)
<         JS_free(cx, current);
---
>     JS_free(cx, tmp);
>     JS_free(cx, dir);
>     JS_free(cx, base);
>     JS_free(cx, current);
595,596c582
<                                    unsigned char *tobufendp,
<                                    uint16 onechar)
---
>         unsigned char *tobufendp, uint16 onechar)
598d583
<     int16 numUTF8bytes = 0;
600c585,588
<     if (onechar == LINE_SEPARATOR || onechar == PARAGRAPH_SEPARATOR) {
---
>      int16 numUTF8bytes = 0;
> 
>     if((onechar == LINE_SEPARATOR)||(onechar == PARAGRAPH_SEPARATOR))
>     {
602c590
<         return strlen((char*)tobufp);
---
>         return strlen((char*)tobufp);;
605,612c593,598
<     if (onechar < 0x80) {
<         numUTF8bytes = 1;
<     } else if (onechar < 0x800) {
<         numUTF8bytes = 2;
<     } else {
<         /* 0x800 >= onechar <= MAX_UCS2 */
<         numUTF8bytes = 3;
<     }
---
>         if (onechar < 0x80) {               numUTF8bytes = 1;
>         } else if (onechar < 0x800) {       numUTF8bytes = 2;
>         } else if (onechar <= MAX_UCS2) {   numUTF8bytes = 3;
>         } else { numUTF8bytes = 2;
>                  onechar = DEFAULT_CHAR;
>         }
614c600
<     tobufp += numUTF8bytes;
---
>         tobufp += numUTF8bytes;
616,619c602,605
<     /* return error if we don't have space for the whole character */
<     if (tobufp > tobufendp) {
<         return(-1);
<     }
---
>         /* return error if we don't have space for the whole character */
>         if (tobufp > tobufendp) {
>             return(-1);
>         }
621,625d606
<     switch(numUTF8bytes) {
<       case 3: *--tobufp = (onechar | BYTE_MARK) & BYTE_MASK; onechar >>=6;
<               *--tobufp = (onechar | BYTE_MARK) & BYTE_MASK; onechar >>=6;
<               *--tobufp = onechar |  THREE_OCTET_BASE;
<               break;
627,629c608
<       case 2: *--tobufp = (onechar | BYTE_MARK) & BYTE_MASK; onechar >>=6;
<               *--tobufp = onechar | TWO_OCTET_BASE;
<               break;
---
>         switch(numUTF8bytes) {
631,633c610,613
<       case 1: *--tobufp = (unsigned char)onechar;
<               break;
<     }
---
>             case 3: *--tobufp = (onechar | BYTE_MARK) & BYTE_MASK; onechar >>=6;
>                     *--tobufp = (onechar | BYTE_MARK) & BYTE_MASK; onechar >>=6;
>                     *--tobufp = onechar |  THREE_OCTET_BASE;
>                     break;
635c615,621
<     return numUTF8bytes;
---
>             case 2: *--tobufp = (onechar | BYTE_MARK) & BYTE_MASK; onechar >>=6;
>                     *--tobufp = onechar | TWO_OCTET_BASE;
>                     break;
>             case 1: *--tobufp = (unsigned char)onechar;  break;
>         }
> 
>         return(numUTF8bytes);
722c708
<     current = options;
---
> 	current = options;
749a736
>     file->linebuffer = NULL;    /* TODO: check for mem. leak? */
754,756c741,742
< js_ResetAttributes(JSFile * file)
< {
<     file->mode = file->type = 0;
---
> js_ResetAttributes(JSFile * file){
> 	file->mode = file->type = 0;
760,761c746,747
<     file->hasRandomAccess = JS_TRUE; /* Innocent until proven guilty. */
<     file->hasAutoflush = JS_FALSE;
---
>     file->hasRandomAccess = JS_TRUE; /* innocent until proven guilty */
> 	file->hasAutoflush = JS_FALSE;
765c751
<     js_ResetBuffers(file);
---
> 	js_ResetBuffers(file);
779c765
<     if (!file_open(cx, obj, 2, v, &rval))
---
>     if (!file_open(cx, obj, 2, v, &rval)) {
780a767
>     }
786c773
< js_BufferedRead(JSFile *f, unsigned char *buf, int32 len)
---
> js_BufferedRead(JSFile * f, char *buf, int32 len)
800,803c787,790
<     if (len > 0) {
<         count += (!f->isNative)
<                  ? PR_Read(f->handle, buf, len)
<                  : fread(buf, 1, len, f->nativehandle);
---
>     if (len>0) {
>         count+= (!f->isNative)?
>                     PR_Read(f->handle, buf, len):
>                     fread(buf, 1, len, f->nativehandle);
809c796
< js_FileRead(JSContext *cx, JSFile *file, jschar *buf, int32 len, int32 mode)
---
> js_FileRead(JSContext *cx, JSFile * file, jschar*buf, int32 len, int32 mode)
811,812c798,799
<     unsigned char *aux;
<     int32 count = 0, i;
---
>     unsigned char*aux;
>     int32 count, i;
824c811
<       case ASCII:
---
>     case ASCII:
826,828c813,815
<         if (!aux)
<             return 0;
< 
---
>         if (!aux) {
>         return 0;
>         }
830,832c817,822
<         if (count == -1) {
<             JS_free(cx, aux);
<             return 0;
---
>         if (count==-1) {
>         JS_free(cx, aux);
>         return 0;
>         }
>         for (i = 0;i<len;i++) {
>         buf[i] = (jschar)aux[i];
834,837d823
< 
<         for (i = 0; i < len; i++)
<             buf[i] = (jschar)aux[i];
< 
840,841c826
< 
<       case UTF8:
---
>     case UTF8:
856c841,842
<                 } else if (i==2) {
---
>                 } else
>                 if (i==2) {
859c845,846
<                 } else if (i==3) {
---
>                 } else
>                 if (i==3)
861d847
<                 }
872,875c858,860
< 
<       case UCS2:
<         count = js_BufferedRead(file, (unsigned char *)buf, len * 2) >> 1;
<         if (count == -1)
---
>     case UCS2:
>         count = js_BufferedRead(file, (char*)buf, len*2)>>1;
>         if (count==-1) {
877c862
< 
---
>         }
879,882d863
< 
<       default:
<         /* Not reached. */
<         JS_ASSERT(0);
885c866
<     if(count == -1) {
---
>     if(count==-1){
887c868
<                              JSFILEMSG_OP_FAILED, "read", file->path);
---
>             JSFILEMSG_OP_FAILED, "read", file->path);
896c877
<     int32 count = 0, i;
---
>     int32 count, i;
902c883
<       case ASCII:
---
>     case ASCII:
905,906c886
< 
<       case UTF8:
---
>     case UTF8:
916a897
> 
921c902,903
<                 } else if (i==2) {
---
>                 } else
>                 if (i==2) {
924c906,907
<                 } else if (i==3) {
---
>                 } else
>                 if (i==3)
926d908
<                 }
936,938c918,919
<         break;
< 
<       case UCS2:
---
>       break;
>     case UCS2:
941,944d921
< 
<       default:
<         /* Not reached. */
<         JS_ASSERT(0);
947c924
<     if(count == -1) {
---
>     if(count==-1){
949c926
<                              JSFILEMSG_OP_FAILED, "seek", file->path);
---
>             JSFILEMSG_OP_FAILED, "seek", file->path);
959c936
<     int32           count = 0, i, j;
---
>     int32           count, i, j;
963c940
<       case ASCII:
---
>     case ASCII:
965,966c942
<         if (!aux)
<             return 0;
---
>         if (!aux)  return 0;
968,969c944,946
<         for (i = 0; i<len; i++)
<             aux[i] = buf[i] % 256;
---
>         for (i = 0; i<len; i++) {
>             aux[i]=buf[i]%256;
>         }
971,973c948,950
<         count = (!file->isNative)
<                 ? PR_Write(file->handle, aux, len)
<                 : fwrite(aux, 1, len, file->nativehandle);
---
>         count = (!file->isNative)?
>                     PR_Write(file->handle, aux, len):
>                     fwrite(aux, 1, len, file->nativehandle);
979d955
< 
982,983c958
< 
<       case UTF8:
---
>     case UTF8:
995,997c970,972
<         j = (!file->isNative)
<             ? PR_Write(file->handle, utfbuf, i)
<             : fwrite(utfbuf, 1, i, file->nativehandle);
---
>         j = (!file->isNative)?
>                 PR_Write(file->handle, utfbuf, i):
>                 fwrite(utfbuf, 1, i, file->nativehandle);
1004,1009c979,983
<         break;
< 
<       case UCS2:
<         count = (!file->isNative)
<                 ? PR_Write(file->handle, buf, len*2) >> 1
<                 : fwrite(buf, 1, len*2, file->nativehandle) >> 1;
---
>       break;
>     case UCS2:
>         count = (!file->isNative)?
>                 PR_Write(file->handle, buf, len*2)>>1:
>                 fwrite(buf, 1, len*2, file->nativehandle)>>1;
1011c985
<         if (count == -1)
---
>         if (count==-1) {
1012a987
>         }
1014,1017d988
< 
<       default:
<         /* Not reached. */
<         JS_ASSERT(0);
1019,1020c990
< 
<     if(count == -1) {
---
>     if(count==-1){
1022c992
<                              JSFILEMSG_OP_FAILED, "write", file->path);
---
>             JSFILEMSG_OP_FAILED, "write", file->path);
1024d993
< 
1032,1033c1001,1004
<     if (file->isNative) {
<         /* It doesn't make sense for a pipe of stdstream. */
---
>     if(!file->isNative){
>         return (PR_Access(file->path, PR_ACCESS_EXISTS)==PR_SUCCESS);
>     }else{
>         /* doesn't make sense for a pipe of stdstream */
1036,1037d1006
< 
<     return PR_Access(file->path, PR_ACCESS_EXISTS) == PR_SUCCESS;
1043,1051c1012,1021
<     if (!file->isNative) {
<         if (file->isOpen && !(file->mode & PR_RDONLY))
<             return JS_FALSE;
<         return PR_Access(file->path, PR_ACCESS_READ_OK) == PR_SUCCESS;
<     }
< 
<     if (file->isPipe) {
<         /* Is this pipe open for reading? */
<         return file->path[0] == PIPE_SYMBOL;
---
>     if(!file->isNative){
>         if(file->isOpen&&!(file->mode&PR_RDONLY)) return JS_FALSE;
>         return (PR_Access(file->path, PR_ACCESS_READ_OK)==PR_SUCCESS);
>     }else{
>         if(file->isPipe){
>             /* pipe open for reading */
>             return file->path[0]==PIPE_SYMBOL;
>         }else{
>             return !strcmp(file->path, STDINPUT_NAME);
>         }
1053,1054d1022
< 
<     return !strcmp(file->path, STDINPUT_NAME);
1060,1068c1028,1038
<     if (!file->isNative) {
<         if (file->isOpen && !(file->mode & PR_WRONLY))
<             return JS_FALSE;
<         return PR_Access(file->path, PR_ACCESS_WRITE_OK) == PR_SUCCESS;
<     }
< 
<     if(file->isPipe) {
<         /* Is this pipe open for writing? */
<         return file->path[strlen(file->path)-1] == PIPE_SYMBOL;
---
>     if(!file->isNative){
>         if(file->isOpen&&!(file->mode&PR_WRONLY)) return JS_FALSE;
>         return (PR_Access(file->path, PR_ACCESS_WRITE_OK)==PR_SUCCESS);
>     }else{
>         if(file->isPipe){
>             /* pipe open for writing */
>             return file->path[strlen(file->path)-1]==PIPE_SYMBOL;
>         }else{
>             return  !strcmp(file->path, STDOUTPUT_NAME) ||
>                     !strcmp(file->path, STDERROR_NAME);
>         }
1070,1072d1039
< 
<     return !strcmp(file->path, STDOUTPUT_NAME) ||
<            !strcmp(file->path, STDERROR_NAME);
1078c1045
<     if (!file->isNative) {
---
>     if(!file->isNative){
1081,1083c1048,1050
<         if (file->isOpen
<             ? PR_GetOpenFileInfo(file->handle, &info)
<             : PR_GetFileInfo(file->path, &info) != PR_SUCCESS) {
---
>         if ((file->isOpen)?
>                         PR_GetOpenFileInfo(file->handle, &info):
>                         PR_GetFileInfo(file->path, &info)!=PR_SUCCESS){
1085c1052
<                                  JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path);
---
>                 JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path);
1087,1089c1054,1058
<         }
< 
<         return info.type == PR_FILE_FILE;
---
>         }else
>             return (info.type==PR_FILE_FILE);
>     }else{
>         /* doesn't make sense for a pipe of stdstream */
>         return JS_FALSE;
1091,1093d1059
< 
<     /* This doesn't make sense for a pipe of stdstream. */
<     return JS_FALSE;
1102,1104c1068,1069
<         /* Hack needed to get get_property to work. */
<         if (!js_exists(cx, file))
<             return JS_FALSE;
---
> 		/* hack needed to get get_property to work */
> 		if(!js_exists(cx, file)) return JS_FALSE;
1106,1108c1071,1073
<         if (file->isOpen
<             ? PR_GetOpenFileInfo(file->handle, &info)
<             : PR_GetFileInfo(file->path, &info) != PR_SUCCESS) {
---
>         if ((file->isOpen)?
>                         PR_GetOpenFileInfo(file->handle, &info):
>                         PR_GetFileInfo(file->path, &info)!=PR_SUCCESS){
1110c1075
<                                  JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path);
---
>                 JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path);
1112,1114c1077,1081
<         }
< 
<         return info.type == PR_FILE_DIRECTORY;
---
>         }else
>             return (info.type==PR_FILE_DIRECTORY);
>     }else{
>         /* doesn't make sense for a pipe of stdstream */
>         return JS_FALSE;
1116,1118d1082
< 
<     /* This doesn't make sense for a pipe of stdstream. */
<     return JS_FALSE;
1128,1130c1092,1094
<     if (file->isOpen
<         ? PR_GetOpenFileInfo(file->handle, &info)
<         : PR_GetFileInfo(file->path, &info) != PR_SUCCESS) {
---
>     if ((file->isOpen)?
>                     PR_GetOpenFileInfo(file->handle, &info):
>                     PR_GetFileInfo(file->path, &info)!=PR_SUCCESS){
1132,1137c1096,1099
<                              JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path);
<         return JSVAL_VOID;
<     }
< 
<     return INT_TO_JSVAL(info.size);
< 
---
>             JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path);
>         goto out;
>     }else
>         return INT_TO_JSVAL(info.size);
1142,1146c1104,1106
< /*
<  * Return the parent object
<  */
< static JSBool
< js_parent(JSContext *cx, JSFile *file, jsval *resultp)
---
> /* Return the parent object */
> static jsval
> js_parent(JSContext *cx, JSFile *file)
1150,1154c1110,1111
<     /* Since we only care about pipes and native files, return NULL. */
<     if (file->isNative) {
<         *resultp = JSVAL_VOID;
<         return JS_TRUE;
<     }
---
>     /* since we only care about pipes and native files, return NULL */
>     if(file->isNative)  return JSVAL_VOID;
1157,1169c1114,1121
<     if (!str)
<         return JS_FALSE;
< 
<     /* If the directory is equal to the original path, we're at the root. */
<     if (!strcmp(file->path, str)) {
<         *resultp = JSVAL_NULL;
<     } else {
<         JSObject *obj = js_NewFileObject(cx, str);
<         if (!obj) {
<             JS_free(cx, str);
<             return JS_FALSE;
<         }
<         *resultp = OBJECT_TO_JSVAL(obj);
---
>     /* root.parent = null ??? */
>     if(!strcmp(file->path, str) ||
>             (!strncmp(str, file->path, strlen(str)-1)&&
>             file->path[strlen(file->path)]-1)==FILESEPARATOR){
>         return JSVAL_NULL;
>     }else{
>         return OBJECT_TO_JSVAL(js_NewFileObject(cx, str));
>         JS_free(cx, str);
1171,1173d1122
< 
<     JS_free(cx, str);
<     return JS_TRUE;
1176,1198c1125,1129
< static JSBool
< js_name(JSContext *cx, JSFile *file, jsval *vp)
< {
<     char *name;
<     JSString *str;
< 
<     if (file->isPipe) {
<         *vp = JSVAL_VOID;
<         return JS_TRUE;
<     }
< 
<     name = js_fileBaseName(cx, file->path);
<     if (!name)
<         return JS_FALSE;
< 
<     str = JS_NewString(cx, name, strlen(name));
<     if (!str) {
<         JS_free(cx, name);
<         return JS_FALSE;
<     }
< 
<     *vp = STRING_TO_JSVAL(str);
<     return JS_TRUE;
---
> static jsval
> js_name(JSContext *cx, JSFile *file){
>     return  file->isPipe?
>                 JSVAL_VOID:
>                 STRING_TO_JSVAL(JS_NewStringCopyZ(cx, js_fileBaseName(cx, file->path)));
1205c1136
<     JSFile      *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
---
>     JSFile      *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
1211,1212d1141
<     mode = NULL;
< 
1216c1145
<     if(file->isOpen && file->isNative) {
---
>     if(file->isOpen && file->isNative){
1218c1147
<                          file->path);
---
>             file->path);
1224,1227c1153,1156
<         JS_ReportWarning(cx, "File %s is already open, we will close it and "
<                          "reopen, proceeding", file->path);
<         if(!file_close(cx, obj, 0, NULL, rval))
<             goto out;
---
>         JS_ReportWarning(cx,
>             "File %s is already open, we will close it and reopen, proceeding",
>             file->path);
>         if(!file_close(cx, obj, 0, NULL, rval)) goto out;
1230c1159
<     if (js_isDirectory(cx, file)) {
---
>     if(js_isDirectory(cx, file)){
1232c1161
<                          "trying to open it, proceeding", file->path);
---
>                 "trying to open it, proceeding", file->path);
1240c1169
<     if (argc >= 1) {
---
>     if (argc>=1){
1242c1171
<         if (!strmode) {
---
>         if (!strmode){
1244,1245c1173
<                                  JSFILEMSG_FIRST_ARGUMENT_OPEN_NOT_STRING_ERROR,
<                                  argv[0]);
---
>                 JSFILEMSG_FIRST_ARGUMENT_OPEN_NOT_STRING_ERROR, argv[0]);
1249,1250c1177,1178
<     } else {
<         if(file->path[0]==PIPE_SYMBOL) {
---
>     }else{
>         if(file->path[0]==PIPE_SYMBOL){
1253c1181,1182
<         } else if(file->path[len-1]==PIPE_SYMBOL) {
---
>         }else
>         if(file->path[len-1]==PIPE_SYMBOL){
1256c1185
<         } else {
---
>         }else{
1264,1275c1193,1202
<     /* TODO: this is pretty ugly, we walk thru the string too many times */
<     mask |= js_FileHasOption(cx, mode, "read")     ? PR_RDONLY       :   0;
<     mask |= js_FileHasOption(cx, mode, "write")    ? PR_WRONLY       :   0;
<     mask |= js_FileHasOption(cx, mode, "readWrite")? PR_RDWR         :   0;
<     mask |= js_FileHasOption(cx, mode, "append")   ? PR_APPEND       :   0;
<     mask |= js_FileHasOption(cx, mode, "create")   ? PR_CREATE_FILE  :   0;
<     mask |= js_FileHasOption(cx, mode, "replace")  ? PR_TRUNCATE     :   0;
< 
<     if (mask & PR_RDWR)
<         mask |= (PR_RDONLY | PR_WRONLY);
<     if ((mask & PR_RDONLY) && (mask & PR_WRONLY))
<         mask |= PR_RDWR;
---
>     /* TODO: this is pretty ugly, BTW, we walk thru the string too many times */
>     mask|=(js_FileHasOption(cx, mode, "read"))?      PR_RDONLY       :   0;
>     mask|=(js_FileHasOption(cx, mode, "write"))?     PR_WRONLY       :   0;
>     mask|=(js_FileHasOption(cx, mode, "readWrite"))? PR_RDWR         :   0;
>     mask|=(js_FileHasOption(cx, mode, "append"))?    PR_APPEND       :   0;
>     mask|=(js_FileHasOption(cx, mode, "create"))?    PR_CREATE_FILE  :   0;
>     mask|=(js_FileHasOption(cx, mode, "replace"))?   PR_TRUNCATE     :   0;
> 
>     if((mask&PR_RDWR)) mask|=(PR_RDONLY|PR_WRONLY);
>     if((mask&PR_RDONLY)&&(mask&PR_WRONLY)) mask|=PR_RDWR;
1277c1204
<     file->hasAutoflush |= js_FileHasOption(cx, mode, "autoflush");
---
>     file->hasAutoflush|=(js_FileHasOption(cx, mode, "autoflush"));
1280c1207
<     if (argc > 1) {
---
>     if (argc>1) {
1284,1285c1211
<                                 JSFILEMSG_SECOND_ARGUMENT_OPEN_NOT_STRING_ERROR,
<                                  argv[1]);
---
>                 JSFILEMSG_SECOND_ARGUMENT_OPEN_NOT_STRING_ERROR, argv[1]);
1290c1216
<         if(!strcmp(ctype, utfstring)) {
---
>         if(!strcmp(ctype, utfstring))
1292c1218,1219
<         } else if (!strcmp(ctype, unicodestring)) {
---
>         else
>         if (!strcmp(ctype, unicodestring))
1294,1295c1221,1222
<         } else {
<             if (strcmp(ctype, asciistring)) {
---
>         else{
>             if(strcmp(ctype, asciistring)){
1297c1224
<                                  "'text' instead, proceeding", ctype);
---
>                         "'text' instead, proceeding", ctype);
1301c1228
<     } else {
---
>     }else{
1309c1236
<     file->hasRandomAccess = (type != UTF8);
---
>     file->hasRandomAccess = (type!=UTF8);
1312,1316c1239,1243
<      * Deal with pipes here. We can't use NSPR for pipes, so we have to use
<      * POPEN.
<      */
<     if (file->path[0]==PIPE_SYMBOL || file->path[len-1]==PIPE_SYMBOL) {
<         if (file->path[0] == PIPE_SYMBOL && file->path[len-1] == PIPE_SYMBOL) {
---
> 		Deal with pipes here. We can't use NSPR for pipes,
>         so we have to use POPEN.
> 	*/
>     if(file->path[0]==PIPE_SYMBOL || file->path[len-1]==PIPE_SYMBOL){
>         if(file->path[0]==PIPE_SYMBOL && file->path[len-1]==PIPE_SYMBOL){
1318,1321c1245,1247
<                                  JSFILEMSG_BIDIRECTIONAL_PIPE_NOT_SUPPORTED);
<             goto out;
<         } else {
<             int i = 0;
---
> 				JSFILEMSG_BIDIRECTIONAL_PIPE_NOT_SUPPORTED);
>                 goto out;
>         }else{
1328,1329c1254,1255
<                                    JSFILEMSG_OPEN_MODE_NOT_SUPPORTED_WITH_PIPES,
<                                          mode, file->path);
---
> 						JSFILEMSG_OPEN_MODE_NOT_SUPPORTED_WITH_PIPES,
> 						mode, file->path);
1333,1337c1259,1261
<                 pipemode[i++] = 'r';
< #ifndef XP_UNIX
<                 pipemode[i++] = file->type==UTF8 ? 'b' : 't';
< #endif
<                 pipemode[i++] = '\0';
---
>                 pipemode[0] = 'r';
>                 pipemode[1] = file->type==UTF8?'b':'t';
>                 pipemode[2] = '\0';
1339c1263,1264
<             } else if(file->path[len-1] == PIPE_SYMBOL) {
---
>             }else
>             if(file->path[len-1] == PIPE_SYMBOL){
1345,1349c1270,1272
<                 pipemode[i++] = 'w';
< #ifndef XP_UNIX
<                 pipemode[i++] = file->type==UTF8 ? 'b' : 't';
< #endif
<                 pipemode[i++] = '\0';
---
>                 pipemode[0] = 'w';
>                 pipemode[1] = file->type==UTF8?'b':'t';
>                 pipemode[2] = '\0';
1351c1274
<                 JS_free(cx, command);
---
> 				JS_free(cx, command);
1358c1281
<     } else {
---
>     }else{
1368,1369c1291,1292
<     if (file->handle == NULL && file->nativehandle == NULL) {
<         file->isOpen = JS_FALSE;
---
>     if (file->handle==NULL && file->nativehandle==NULL){
> 		file->isOpen = JS_FALSE;
1372c1295
<                              JSFILEMSG_OP_FAILED, "open", file->path);
---
>             JSFILEMSG_OP_FAILED, "open", file->path);
1374,1375c1297,1298
<     }
< 
---
>     }else
>         goto good;
1380d1302
< 
1382,1383c1304,1305
<     if(mode)
<         JS_free(cx, mode);
---
>     if(mode) JS_free(cx, mode);
>     *rval = JSVAL_VOID;
1390c1312
<     JSFile  *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
---
>     JSFile  *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
1423d1344
< 
1424a1346
>     *rval = JSVAL_FALSE;
1432c1354
< 	JSFile  *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
---
> 	JSFile  *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
1457c1379
<     JSFile      *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
---
>     JSFile      *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
1552c1474
<     JSFile  *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
---
>     JSFile  *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
1581c1503
<     JSFile *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
---
>     JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
1603c1525
<     JSFile      *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
---
>     JSFile      *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
1631c1553
<     JSFile      *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
---
>     JSFile      *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
1662c1584
<     JSFile      *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
---
>     JSFile      *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
1699c1621
<     JSFile      *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
---
>     JSFile      *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
1737c1659
<     JSFile      *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
---
>     JSFile      *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
1739,1740c1661,1662
<     jschar      *buf = NULL, *tmp;
<     int32       offset, read;
---
>     jschar      *buf;
>     int32       offset;
1742a1665
>     JSBool      endofline;
1747,1751c1670,1675
<     buf = JS_malloc(cx, MAX_LINE_LENGTH * sizeof data);
<     if (!buf)
<         return JS_FALSE;
< 
<     room = MAX_LINE_LENGTH - 1;
---
>     if (!file->linebuffer) {
>         buf = JS_malloc(cx, MAX_LINE_LENGTH*(sizeof data));
>         if (!buf) goto out;
>         file->linebuffer = JS_NewUCString(cx, buf, MAX_LINE_LENGTH);
>     }
>     room = JS_GetStringLength(file->linebuffer);
1754,1760c1678,1683
<     for (;;) {
<         read = js_FileRead(cx, file, &data, 1, file->type);
<         if (read < 0)
<             goto out;
<         if (read == 0)
<             goto eof;
< 
---
>     /* XXX TEST ME!! TODO: yes, please do */
>     for(;;) {
>         if (!js_FileRead(cx, file, &data, 1, file->type)) {
>             endofline = JS_FALSE;
>             goto loop;
>         }
1762,1768c1685,1693
<           case '\r':
<             read = js_FileRead(cx, file, &data2, 1, file->type);
<             if (read < 0)
<                 goto out;
< 
<             if (read == 1 && data2 != '\n') {
<                 /* We read one char too far.  Buffer it. */
---
>         case '\n' :
>             endofline = JS_TRUE;
>             goto loop;
>         case '\r' :
>             if (!js_FileRead(cx, file, &data2, 1, file->type)) {
>                 endofline = JS_TRUE;
>                 goto loop;
>             }
>             if (data2!='\n') { /* We read one char too far.  Buffer it. */
1772,1777c1697,1699
< 
<             /* Fall through. */
<           case '\n':
<             goto done;
< 
<           default:
---
>             endofline = JS_TRUE;
>             goto loop;
>         default:
1779,1785c1701,1708
<                 tmp = JS_realloc(cx, buf,
<                                  (offset + MAX_LINE_LENGTH) * sizeof data);
<                 if (!tmp)
<                     goto out;
< 
<                 room = MAX_LINE_LENGTH - 1;
<                 buf = tmp;
---
>                 buf = JS_malloc(cx, (offset+MAX_LINE_LENGTH)*sizeof data);
>                 if (!buf) return JS_FALSE;
>                 room = MAX_LINE_LENGTH-1;
>                 memcpy(buf, JS_GetStringChars(file->linebuffer),
>                     JS_GetStringLength(file->linebuffer));
>                 /* what follows may not be the cleanest way. */
>                 file->linebuffer->chars = buf;
>                 file->linebuffer->length =  offset+MAX_LINE_LENGTH;
1787,1788c1710
< 
<             buf[offset++] = data;
---
>             file->linebuffer->chars[offset++] = data;
1792,1795c1714,1719
< 
< eof:
<     if (offset == 0) {
<         *rval = JSVAL_NULL;
---
> loop:
>     file->linebuffer->chars[offset] = 0;
>     if ((endofline==JS_TRUE)) {
>         str = JS_NewUCStringCopyN(cx, JS_GetStringChars(file->linebuffer),
>                                     offset);
>         *rval = STRING_TO_JSVAL(str);
1797,1806c1721
<     }
< 
< done:
<     buf[offset] = 0;
<     tmp = JS_realloc(cx, buf, (offset + 1) * sizeof data);
<     if (!tmp)
<         goto out;
< 
<     str = JS_NewUCString(cx, tmp, offset);
<     if (!str)
---
>     }else{
1808,1811c1723
< 
<     *rval = STRING_TO_JSVAL(str);
<     return JS_TRUE;
< 
---
>     }
1813,1815c1725
<     if (buf)
<         JS_free(cx, buf);
< 
---
>     *rval = JSVAL_NULL;
1822c1732
<     JSFile      *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
---
>     JSFile      *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
1826d1735
<     JSBool      lineok = JS_FALSE;
1832,1835d1740
<     if (!array)
<         return JS_FALSE;
<     *rval = OBJECT_TO_JSVAL(array);
< 
1838,1841c1743,1745
<     lineok = file_readln(cx, obj, 0, NULL, &line);
<     while (lineok && !JSVAL_IS_NULL(line)) {
<         JS_SetElement(cx, array, len++, &line);
<         lineok = file_readln(cx, obj, 0, NULL, &line);
---
>     while(file_readln(cx, obj, 0, NULL, &line)){
>         JS_SetElement(cx, array, len, &line);
>         len++;
1843a1748,1749
>     *rval = OBJECT_TO_JSVAL(array);
>     return JS_TRUE;
1845c1751,1752
<     return lineok;
---
>     *rval = JSVAL_FALSE;
>     return JS_FALSE;
1851c1758
<     JSFile      *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
---
>     JSFile      *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
1893c1800
<     JSFile      *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
---
>     JSFile      *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
1911c1818
<         if (VALUE_IS_FUNCTION(cx, argv[0])) {
---
>         if (JSVAL_IS_FUNCTION(cx, argv[0])) {
1993c1900
<     JSFile      *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
---
>     JSFile      *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
2035,2036c1942
<     JSFile *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
<     JSString *str;
---
>     JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
2038,2041c1944
<     str = JS_NewStringCopyZ(cx, file->path);
<     if (!str)
<         return JS_FALSE;
<     *rval = STRING_TO_JSVAL(str);
---
>     *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, file->path));
2044a1948
> #ifdef _UTF8
2048c1952
<     JSFile *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
---
>     JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
2051,2052c1955
<     size_t len;
<     JSString *str;
---
> 	int wLength;
2054c1957
<     JSFILE_CHECK_NATIVE("toURL");
---
> 	JSFILE_CHECK_NATIVE("toURL");
2056a1960
>     /* TODO: js_escape in jsstr.h may go away at some point */
2058,2067c1962,1965
<     len = strlen(url);
<     urlChars = js_InflateString(cx, url, &len);
<     if (!urlChars)
<         return JS_FALSE;
<     str = js_NewString(cx, urlChars, len);
<     if (!str) {
<         JS_free(cx, urlChars);
<         return JS_FALSE;
<     }
<     *rval = STRING_TO_JSVAL(str);
---
>     urlChars = js_InflateString(cx, url, strlen(url),&wLength);
>     if (urlChars == NULL) return JS_FALSE;
>     *rval = STRING_TO_JSVAL(js_NewString(cx, urlChars, wLength, 0));
>     if (!js_str_escape(cx, obj, 0, rval, rval)) return JS_FALSE;
2068a1967,1983
>     return JS_TRUE;
> out:
>     *rval = JSVAL_VOID;
>     return JS_FALSE;
> }
> #else //#ifdef _UTF8
> static JSBool
> file_toURL(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
> {
>     JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
>     char url[MAX_PATH_LENGTH];
>     jschar *urlChars;
> 	int wLength;
> 
> 	JSFILE_CHECK_NATIVE("toURL");
> 
>     sprintf(url, "file://%s", file->path);
2070d1984
<     return js_str_escape(cx, obj, 0, rval, rval);
2071a1986,1991
>     urlChars = js_InflateString(cx, url, strlen(url),&wLength);
>     if (urlChars == NULL) return JS_FALSE;
>     *rval = STRING_TO_JSVAL(js_NewString(cx, urlChars, strlen(url), 0));
>     if (!js_str_escape(cx, obj, 0, rval, rval)) return JS_FALSE;
> 
>     return JS_TRUE;
2076c1996
< 
---
> #endif //#ifdef _UTF8
2081c2001
<     JSFile *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
---
>     JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
2083,2085c2003,2005
<     if(file) {
<         /* Close the file before exiting. */
<         if(file->isOpen && !file->isNative) {
---
> 	if(file){
>         /* close the file before exiting */
>         if(file->isOpen && !file->isNative){
2090,2091c2010,2011
<         if (file->path)
<             JS_free(cx, file->path);
---
> 		if (file->path)
> 			JS_free(cx, file->path);
2093,2094c2013,2014
<         JS_free(cx, file);
<     }
---
> 		JS_free(cx, file);
> 	}
2103c2023
<     JSFile *file;
---
>     JSFile      *file;
2106,2107c2026
<     if (!file)
<         return NULL;
---
>     if (!file) return NULL;
2116c2035
<                              JSFILEMSG_CANNOT_SET_PRIVATE_FILE, file->path);
---
>             JSFILEMSG_CANNOT_SET_PRIVATE_FILE, file->path);
2119,2121c2038,2039
<     }
< 
<     return file;
---
>     }else
>         return file;
2131c2049
<     obj = JS_NewObject(cx, &js_FileClass, NULL, NULL);
---
>     obj = JS_NewObject(cx, &file_class, NULL, NULL);
2148a2067,2069
> #ifdef XP_MAC
>     JS_ReportWarning(cx, "Native files are not fully supported on the MAC");
> #endif
2150c2071
<     obj = JS_NewObject(cx, &js_FileClass, NULL, NULL);
---
>     obj = JS_NewObject(cx, &file_class, NULL, NULL);
2179c2100
<                  jsval *rval)
---
>     jsval *rval)
2184,2194c2105
<     if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) {
<         /* Replace obj with a new File object. */
<         obj = JS_NewObject(cx, &js_FileClass, NULL, NULL);
<         if (!obj)
<             return JS_FALSE;
<         *rval = OBJECT_TO_JSVAL(obj);
<     }
< 
<     str = (argc == 0)
<           ? JS_InternString(cx, "")
<           : JS_ValueToString(cx, argv[0]);
---
>     str = (argc==0)?JS_InternString(cx, ""):JS_ValueToString(cx, argv[0]);
2196c2107
<     if (!str) {
---
>     if (!str){
2198,2200c2109,2110
<                          JSFILEMSG_FIRST_ARGUMENT_CONSTRUCTOR_NOT_STRING_ERROR,
<                              argv[0]);
<         return JS_FALSE;
---
>             JSFILEMSG_FIRST_ARGUMENT_CONSTRUCTOR_NOT_STRING_ERROR, argv[0]);
>         goto out;
2204,2205c2114
<     if (!file)
<         return JS_FALSE;
---
>     if (!file)  goto out;
2209a2119,2121
> out:
>     *rval = JSVAL_VOID;
>     return JS_FALSE;
2229,2230c2141,2142
<     { "toString",       file_toString, 0},
<     { "toURL",          file_toURL, 0},
---
> 	{ "toString",       file_toString, 0},
>     { "toURL",			file_toURL, 0},
2287,2289c2199,2200
<     JSFile      *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
<     char        *bytes;
<     JSString    *str;
---
>     JSFile      *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
>     char        *str;
2292,2293c2203,2205
<     JSBool      flag;
<     PRExplodedTime expandedTime;
---
> 	JSBool		flag;
>     PRExplodedTime
>                 expandedTime;
2296,2297c2208
<     if (!file)
<         return JS_TRUE;
---
>     if(!file) return JS_TRUE;
2302,2303c2213
<         if (!js_parent(cx, file, vp))
<             return JS_FALSE;
---
>         *vp = js_parent(cx, file);
2306,2309c2216
<         str = JS_NewStringCopyZ(cx, file->path);
<         if (!str)
<             return JS_FALSE;
<         *vp = STRING_TO_JSVAL(str);
---
>         *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, file->path));
2312,2313c2219
<         if (!js_name(cx, file, vp))
<             return JS_FALSE;
---
>         *vp = js_name(cx, file);
2386,2387c2292,2293
<         bytes = JS_malloc(cx, MODE_SIZE);
<         bytes[0] = '\0';
---
>         str = (char*)JS_malloc(cx, MODE_SIZE);
>         str[0] = '\0';
2391,2392c2297,2298
<             if (flag) strcat(bytes, ",");
<             strcat(bytes, "read");
---
>             if (flag) strcat(str, ",");
>             strcat(str, "read");
2396,2397c2302,2303
<             if (flag) strcat(bytes, ",");
<             strcat(bytes, "write");
---
>             if (flag) strcat(str, ",");
>             strcat(str, "write");
2401,2402c2307,2308
<             if (flag) strcat(bytes, ",");
<             strcat(bytes, "readWrite");
---
>             if (flag) strcat(str, ",");
>             strcat(str, "readWrite");
2406,2407c2312,2313
<             if (flag) strcat(bytes, ",");
<             strcat(bytes, "append");
---
>             if (flag) strcat(str, ",");
>             strcat(str, "append");
2411,2412c2317,2318
<             if (flag) strcat(bytes, ",");
<             strcat(bytes, "create");
---
>             if (flag) strcat(str, ",");
>             strcat(str, "create");
2416,2417c2322,2323
<             if (flag) strcat(bytes, ",");
<             strcat(bytes, "replace");
---
>             if (flag) strcat(str, ",");
>             strcat(str, "replace");
2421,2422c2327,2328
<             if (flag) strcat(bytes, ",");
<             strcat(bytes, "hasAutoFlush");
---
>             if (flag) strcat(str, ",");
>             strcat(str, "hasAutoFlush");
2425,2426c2331,2332
<         *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, bytes));
<         JS_free(cx, bytes);
---
>         *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, str));
>         JS_free(cx, str);
2536,2547c2442,2446
< 
<         /* this is some other property -- try to use the dir["file"] syntax */
<         if (js_isDirectory(cx, file)) {
<             PRDir *dir = NULL;
<             PRDirEntry *entry = NULL;
<             char *prop_name;
< 
<             str = JS_ValueToString(cx, id);
<             if (!str)
<                 return JS_FALSE;
< 
<             prop_name = JS_GetStringBytes(str);
---
> 		/* this is some other property -- try to use the dir["file"] syntax */
>         if(js_isDirectory(cx, file)){
> 			PRDir *dir = NULL;
> 			PRDirEntry *entry = NULL;
>             char *prop_name = JS_GetStringBytes(JS_ValueToString(cx, id));
2553c2452
<                 JS_ReportWarning(cx, "Can't open directory %s", file->path);
---
> 				JS_ReportWarning(cx, "Can't open directory %s", file->path);
2557,2567c2456,2464
<             while ((entry = PR_ReadDir(dir, PR_SKIP_NONE)) != NULL) {
<                 if (!strcmp(entry->name, prop_name)){
<                     bytes = js_combinePath(cx, file->path, prop_name);
<                     *vp = OBJECT_TO_JSVAL(js_NewFileObject(cx, bytes));
<                     PR_CloseDir(dir);
<                     JS_free(cx, bytes);
<                     return !JSVAL_IS_NULL(*vp);
<                 }
<             }
<             PR_CloseDir(dir);
<         }
---
>             while((entry = PR_ReadDir(dir, PR_SKIP_NONE))!=NULL){
> 				if(!strcmp(entry->name, prop_name)){
>                     str = js_combinePath(cx, file->path, prop_name);
>                     *vp = OBJECT_TO_JSVAL(js_NewFileObject(cx, str));
> 					JS_free(cx, str);
>                     return JS_TRUE;
> 				}
> 			}
> 		}
2570d2466
< 
2571a2468
> 	*vp = JSVAL_VOID;
2578c2475
<     JSFile  *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
---
>     JSFile  *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
2627c2524,2525
<     return JS_FALSE;
---
> 	*vp = JSVAL_VOID;
> 	return JS_FALSE;
2636,2638c2534,2536
<     JSFile   *file;
< 
<     file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
---
>     JSObject *rhsObject;
>     char     *path;
>     JSFile   *file = JS_GetInstancePrivate(cx, rhsObject, &file_class, NULL);
2641,2642c2539,2540
<     if (JSVAL_IS_OBJECT(*vp)) {
<         if (JS_InstanceOf(cx, obj, &js_FileClass, NULL)) {
---
>     if (JSVAL_IS_OBJECT(*vp)){
>         if (JS_InstanceOf(cx, rhsObject, &file_class, NULL)){
2644c2542
<             if (file && (!js_exists(cx, file) || !js_isDirectory(cx, file))) {
---
>             if (file && (!js_exists(cx, file) || !js_isDirectory(cx, file))){
2646,2647c2544,2546
<                 return JS_FALSE;
<             } else {
---
>                 goto out;
>             }else{
>                 rhsObject = JSVAL_TO_OBJECT(*vp);
2651,2657c2550,2552
<         } else {
<             return JS_FALSE;
<         }
<     } else {
<         JSObject *rhsObject;
<         char     *path;
< 
---
>         }else
>             goto out;
>     }else{
2660,2661c2555
<         if (!rhsObject)
<             return JS_FALSE;
---
>         if (!rhsObject)  goto out;
2665c2559
<         } else {
---
>         }else{
2670d2563
< 
2671a2565,2567
> out:
> 	*vp = JSVAL_VOID;
> 	return JS_FALSE;
2675,2676c2571,2572
< JSClass js_FileClass = {
<     "File", JSCLASS_HAS_PRIVATE | JSCLASS_HAS_CACHED_PROTO(JSProto_File),
---
> static JSClass file_class = {
>     FILE_CONSTRUCTOR, JSCLASS_HAS_PRIVATE,
2678c2574
<     JS_EnumerateStub, JS_ResolveStub,   JS_ConvertStub,    file_finalize
---
>     JS_EnumerateStub, JS_ResolveStub,   JS_ConvertStub,   file_finalize
2683c2579
< js_InitFileClass(JSContext *cx, JSObject* obj)
---
> js_InitFileClass(JSContext *cx, JSObject* obj, JSBool initStandardStreams)
2690c2586
<     file = JS_InitClass(cx, obj, NULL, &js_FileClass, file_constructor, 1,
---
>     file = JS_InitClass(cx, obj, NULL, &file_class, file_constructor, 1,
2713,2727c2609,2625
<     /* Define input */
<     vp = OBJECT_TO_JSVAL(js_NewFileObjectFromFILE(cx, stdin,
<             STDINPUT_NAME, PR_RDONLY, JS_TRUE, JS_FALSE));
<     JS_SetProperty(cx, ctor, "input", &vp);
< 
<     /* Define output */
<     vp = OBJECT_TO_JSVAL(js_NewFileObjectFromFILE(cx, stdout,
<             STDOUTPUT_NAME, PR_WRONLY, JS_TRUE, JS_FALSE));
<     JS_SetProperty(cx, ctor, "output", &vp);
< 
<     /* Define error */
<     vp = OBJECT_TO_JSVAL(js_NewFileObjectFromFILE(cx, stderr,
<             STDERROR_NAME, PR_WRONLY, JS_TRUE, JS_FALSE));
<     JS_SetProperty(cx, ctor, "error", &vp);
< 
---
>     if(initStandardStreams){
>         /* Code to create stdin, stdout, and stderr. Insert in the appropriate place. */
>         /* Define input */
>         vp = OBJECT_TO_JSVAL(js_NewFileObjectFromFILE(cx, stdin,
>                 STDINPUT_NAME, PR_RDONLY, JS_TRUE, JS_FALSE));
>         JS_SetProperty(cx, ctor, "input", &vp);
> 
>         /* Define output */
>         vp = OBJECT_TO_JSVAL(js_NewFileObjectFromFILE(cx, stdout,
>                 STDOUTPUT_NAME, PR_WRONLY, JS_TRUE, JS_FALSE));
>         JS_SetProperty(cx, ctor, "output", &vp);
> 
>         /* Define error */
>         vp = OBJECT_TO_JSVAL(js_NewFileObjectFromFILE(cx, stderr,
>                 STDERROR_NAME, PR_WRONLY, JS_TRUE, JS_FALSE));
>         JS_SetProperty(cx, ctor, "error", &vp);
>     }
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsfile.h /Volumes/Swap/js_D11/src/jsfile.h
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
44,46d38
< 
< #include "jsobj.h"
< 
48c40
< js_InitFileClass(JSContext *cx, JSObject* obj);
---
> js_InitFileClass(JSContext *cx, JSObject* obj, JSBool initStandardStreams);
52,54d43
< 
< extern JSClass js_FileClass;
< 
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsfile.msg /Volumes/Swap/js_D11/src/jsfile.msg
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
58d52
< MSG_DEF(JSFILEMSG_UNUSED0,                                        14, 0, JSEXN_NONE, "Unused error message slot")
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsfun.c /Volumes/Swap/js_D11/src/jsfun.c
2d1
<  * vim: set ts=8 sw=4 et tw=78:
4,5c3,6
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
7,15c8,11
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
20,23c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
27,39c23,33
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
54d47
< #include "jsdbgapi.h"
69,71d61
< #if JS_HAS_GENERATORS
< # include "jsiter.h"
< #endif
73,75c63
< #if JS_HAS_XDR
< # include "jsxdrapi.h"
< #endif
---
> //#include "_optimize.h"
80,84c68,73
<     ARGS_LENGTH     = -2,       /* number of actual args, arity if inactive */
<     ARGS_CALLEE     = -3,       /* reference from arguments to active funobj */
<     FUN_ARITY       = -4,       /* number of formal parameters; desired argc */
<     FUN_NAME        = -5,       /* function name, "" if anonymous */
<     FUN_CALLER      = -6        /* Function.prototype.caller, backward compat */
---
>     CALL_CALLEE     = -2,       /* reference to active function's object */
>     ARGS_LENGTH     = -3,       /* number of actual args, arity if inactive */
>     ARGS_CALLEE     = -4,       /* reference from arguments to active funobj */
>     FUN_ARITY       = -5,       /* number of formal parameters; desired argc */
>     FUN_NAME        = -6,       /* function name, "" if anonymous */
>     FUN_CALLER      = -7        /* Function.prototype.caller, backward compat */
96a86,87
> #if JS_HAS_ARGS_OBJECT
> 
105,106c96
<                                 ATOM_TO_JSID(cx->runtime->atomState
<                                              .argumentsAtom),
---
>                                 (jsid) cx->runtime->atomState.argumentsAtom,
126c116
<     nbits = fp->argc;
---
>     nbits = JS_MAX(fp->argc, fp->fun->nargs);
133a124
>             XMEMTAG("jsfun jsbitmap");
169c160
<     if (fp->argc <= JSVAL_INT_BITS) {
---
>     if (JS_MAX(fp->argc, fp->fun->nargs) <= JSVAL_INT_BITS) {
179c170,171
< js_GetArgsProperty(JSContext *cx, JSStackFrame *fp, jsid id, jsval *vp)
---
> js_GetArgsProperty(JSContext *cx, JSStackFrame *fp, jsid id,
>                    JSObject **objp, jsval *vp)
188,189c180
<                               ATOM_TO_JSID(cx->runtime->atomState
<                                            .argumentsAtom),
---
>                               (jsid) cx->runtime->atomState.argumentsAtom,
199a191
>         *objp = obj;
202a195
>     *objp = NULL;
204,206c197,199
<     if (JSID_IS_INT(id)) {
<         slot = (uintN) JSID_TO_INT(id);
<         if (slot < fp->argc) {
---
>     if (JSVAL_IS_INT(id)) {
>         slot = (uintN) JSVAL_TO_INT(id);
>         if (slot < JS_MAX(fp->argc, fp->fun->nargs)) {
210,224d202
<         } else {
<             /*
<              * Per ECMA-262 Ed. 3, 10.1.8, last bulleted item, do not share
<              * storage between the formal parameter and arguments[k] for all
<              * fp->argc <= k && k < fp->fun->nargs.  For example, in
<              *
<              *   function f(x) { x = 42; return arguments[0]; }
<              *   f();
<              *
<              * the call to f should return undefined, not 42.  If fp->argsobj
<              * is null at this point, as it would be in the example, return
<              * undefined in *vp.
<              */
<             if (fp->argsobj)
<                 return OBJ_GET_PROPERTY(cx, fp->argsobj, id, vp);
227c205
<         if (id == ATOM_TO_JSID(cx->runtime->atomState.lengthAtom)) {
---
>         if (id == (jsid) cx->runtime->atomState.lengthAtom) {
239,249c217
<     JSObject *argsobj, *global, *parent;
< 
<     /*
<      * We must be in a function activation; the function must be lightweight
<      * or else fp must have a variable object.
<      */
<     JS_ASSERT(fp->fun && (!(fp->fun->flags & JSFUN_HEAVYWEIGHT) || fp->varobj));
< 
<     /* Skip eval and debugger frames. */
<     while (fp->flags & JSFRAME_SPECIAL)
<         fp = fp->down;
---
>     JSObject *argsobj;
251a220
>     JS_ASSERT(fp->fun);
259c228
<         cx->weakRoots.newborn[GCX_OBJECT] = NULL;
---
>         cx->newborn[GCX_OBJECT] = NULL;
262,277d230
< 
<     /*
<      * Give arguments an intrinsic scope chain link to fp's global object.
<      * Since the arguments object lacks a prototype because js_ArgumentsClass
<      * is not initialized, js_NewObject won't assign a default parent to it.
<      *
<      * Therefore if arguments is used as the head of an eval scope chain (via
<      * a direct or indirect call to eval(program, arguments)), any reference
<      * to a standard class object in the program will fail to resolve due to
<      * js_GetClassPrototype not being able to find a global object containing
<      * the standard prototype by starting from arguments and following parent.
<      */
<     global = fp->scopeChain;
<     while ((parent = OBJ_GET_PARENT(cx, global)) != NULL)
<         global = parent;
<     STOBJ_SET_PARENT(argsobj, global);
285c238
< JS_FRIEND_API(JSBool)
---
> JSBool
308c261
<         if (fp->argc > JSVAL_INT_BITS)
---
>         if (JS_MAX(fp->argc, fp->fun->nargs) > JSVAL_INT_BITS)
317,324c270,273
<     ok &= js_GetProperty(cx, argsobj, ATOM_TO_JSID(rt->atomState.calleeAtom),
<                          &rval);
<     ok &= js_SetProperty(cx, argsobj, ATOM_TO_JSID(rt->atomState.calleeAtom),
<                          &rval);
<     ok &= js_GetProperty(cx, argsobj, ATOM_TO_JSID(rt->atomState.lengthAtom),
<                          &rval);
<     ok &= js_SetProperty(cx, argsobj, ATOM_TO_JSID(rt->atomState.lengthAtom),
<                          &rval);
---
>     ok &= js_GetProperty(cx, argsobj, (jsid)rt->atomState.calleeAtom, &rval);
>     ok &= js_SetProperty(cx, argsobj, (jsid)rt->atomState.calleeAtom, &rval);
>     ok &= js_GetProperty(cx, argsobj, (jsid)rt->atomState.lengthAtom, &rval);
>     ok &= js_SetProperty(cx, argsobj, (jsid)rt->atomState.lengthAtom, &rval);
348a298
>     JS_ASSERT(fp->fun);
358c308,309
<         if ((uintN)slot < fp->argc && !MarkArgDeleted(cx, fp, slot))
---
>         if ((uintN)slot < JS_MAX(fp->argc, fp->fun->nargs) &&
>             !MarkArgDeleted(cx, fp, slot)) {
359a311
>         }
377a330
>     JS_ASSERT(fp->fun);
383c336
<             *vp = OBJECT_TO_JSVAL(fp->callee);
---
>             *vp = fp->argv ? fp->argv[-2] : OBJECT_TO_JSVAL(fp->fun->object);
392c345,346
<         if ((uintN)slot < fp->argc && !ArgWasDeleted(cx, fp, slot))
---
>         if ((uintN)slot < JS_MAX(fp->argc, fp->fun->nargs) &&
>             !ArgWasDeleted(cx, fp, slot)) {
393a348
>         }
411a367
>     JS_ASSERT(fp->fun);
421,422c377
<         if (FUN_INTERPRETED(fp->fun) &&
<             (uintN)slot < fp->argc &&
---
>         if ((uintN)slot < JS_MAX(fp->argc, fp->fun->nargs) &&
447a403
>     JS_ASSERT(fp->fun);
451c407,408
<         if (slot < fp->argc && !ArgWasDeleted(cx, fp, slot)) {
---
>         if (slot < JS_MAX(fp->argc, fp->fun->nargs) &&
>             !ArgWasDeleted(cx, fp, slot)) {
453,454c410
<             if (!js_DefineProperty(cx, obj, INT_JSVAL_TO_JSID(id),
<                                    fp->argv[slot],
---
>             if (!js_DefineProperty(cx, obj, (jsid) id, fp->argv[slot],
456c412,415
<                                    0, NULL)) {
---
>                                    JSVERSION_IS_ECMA(cx->version)
>                                    ? 0
>                                    : JSPROP_ENUMERATE,
>                                    NULL)) {
471c430,431
<                 value = OBJECT_TO_JSVAL(fp->callee);
---
>                 value = fp->argv ? fp->argv[-2]
>                                  : OBJECT_TO_JSVAL(fp->fun->object);
482c442
<             if (!js_DefineNativeProperty(cx, obj, ATOM_TO_JSID(atom), value,
---
>             if (!js_DefineNativeProperty(cx, obj, (jsid) atom, value,
500c460
<     uintN slot, argc;
---
>     uintN slot, nargs;
506a467
>     JS_ASSERT(fp->fun);
515,516c476
<     if (!js_LookupProperty(cx, obj,
<                            ATOM_TO_JSID(cx->runtime->atomState.lengthAtom),
---
>     if (!js_LookupProperty(cx, obj, (jsid) cx->runtime->atomState.lengthAtom,
523,524c483
<     if (!js_LookupProperty(cx, obj,
<                            ATOM_TO_JSID(cx->runtime->atomState.calleeAtom),
---
>     if (!js_LookupProperty(cx, obj, (jsid) cx->runtime->atomState.calleeAtom,
531,533c490,493
<     argc = fp->argc;
<     for (slot = 0; slot < argc; slot++) {
<         if (!js_LookupProperty(cx, obj, INT_TO_JSID((jsint)slot), &pobj, &prop))
---
>     nargs = JS_MAX(fp->argc, fp->fun->nargs);
>     for (slot = 0; slot < nargs; slot++) {
>         if (!js_LookupProperty(cx, obj, (jsid) INT_TO_JSVAL((jsint)slot),
>                                &pobj, &prop)) {
534a495
>         }
541,560d501
< #if JS_HAS_GENERATORS
< /*
<  * If a generator-iterator's arguments or call object escapes, it needs to
<  * mark its generator object.
<  */
< static void
< args_or_call_trace(JSTracer *trc, JSObject *obj)
< {
<     JSStackFrame *fp;
< 
<     fp = (JSStackFrame *) JS_GetPrivate(trc->context, obj);
<     if (fp && (fp->flags & JSFRAME_GENERATOR)) {
<         JS_CALL_OBJECT_TRACER(trc, FRAME_TO_GENERATOR(fp)->obj,
<                               "FRAME_TO_GENERATOR(fp)->obj");
<     }
< }
< #else
< # define args_or_call_trace NULL
< #endif
< 
574,583c515,520
<     JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE | JSCLASS_HAS_RESERVED_SLOTS(1) |
<     JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_Object),
<     JS_PropertyStub,    args_delProperty,
<     args_getProperty,   args_setProperty,
<     args_enumerate,     (JSResolveOp) args_resolve,
<     JS_ConvertStub,     JS_FinalizeStub,
<     NULL,               NULL,
<     NULL,               NULL,
<     NULL,               NULL,
<     JS_CLASS_TRACE(args_or_call_trace), NULL
---
>     JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE | JSCLASS_HAS_RESERVED_SLOTS(1),
>     JS_PropertyStub,  args_delProperty,
>     args_getProperty, args_setProperty,
>     args_enumerate,   (JSResolveOp) args_resolve,
>     JS_ConvertStub,   JS_FinalizeStub,
>     JSCLASS_NO_OPTIONAL_MEMBERS
585a523,526
> #endif /* JS_HAS_ARGS_OBJECT */
> 
> #if JS_HAS_CALL_OBJECT
> 
595a537
>     JS_ASSERT(fp->fun);
599c541
<         funobj = fp->callee;
---
>         funobj = fp->argv ? JSVAL_TO_OBJECT(fp->argv[-2]) : fp->fun->object;
607c549
<         cx->weakRoots.newborn[GCX_OBJECT] = NULL;
---
>         cx->newborn[GCX_OBJECT] = NULL;
613d554
<     JS_ASSERT(fp->scopeChain == parent);
622c563
< JS_FRIEND_API(JSBool)
---
> JSBool
643,647c584,586
<         if (!TEST_OVERRIDE_BIT(fp, CALL_ARGUMENTS)) {
<             argsid = ATOM_TO_JSID(cx->runtime->atomState.argumentsAtom);
<             aval = OBJECT_TO_JSVAL(fp->argsobj);
<             ok &= js_SetProperty(cx, callobj, argsid, &aval);
<         }
---
>         argsid = (jsid) cx->runtime->atomState.argumentsAtom;
>         ok &= js_GetProperty(cx, callobj, argsid, &aval);
>         ok &= js_SetProperty(cx, callobj, argsid, &aval);
660a600,605
> static JSPropertySpec call_props[] = {
>     {js_arguments_str,  CALL_ARGUMENTS, JSPROP_PERMANENT,0,0},
>     {"__callee__",      CALL_CALLEE,    0,0,0},
>     {0,0,0,0,0}
> };
> 
684a630,634
>       case CALL_CALLEE:
>         if (!TEST_OVERRIDE_BIT(fp, slot))
>             *vp = fp->argv ? fp->argv[-2] : OBJECT_TO_JSVAL(fp->fun->object);
>         break;
> 
708a659
>       case CALL_CALLEE:
728,729c679,681
<         JS_ASSERT((uintN) JSVAL_TO_INT(id) < fp->nvars);
<         *vp = fp->vars[JSVAL_TO_INT(id)];
---
>         /* XXX no jsint slot commoning here to avoid MSVC1.52 crashes */
>         if ((uintN)JSVAL_TO_INT(id) < fp->nvars)
>             *vp = fp->vars[JSVAL_TO_INT(id)];
742,743c694,697
<         JS_ASSERT((uintN) JSVAL_TO_INT(id) < fp->nvars);
<         fp->vars[JSVAL_TO_INT(id)] = *vp;
---
>         /* XXX jsint slot is block-local here to avoid MSVC1.52 crashes */
>         jsint slot = JSVAL_TO_INT(id);
>         if ((uintN)slot < fp->nvars)
>             fp->vars[slot] = *vp;
752,758c706,710
<     JSFunction *fun;
<     uintN n, i, slot;
<     void *mark;
<     jsuword *names;
<     JSBool ok;
<     JSAtom *name;
<     JSObject *pobj;
---
>     JSObject *funobj;
>     JSScope *scope;
>     JSScopeProperty *sprop, *cprop;
>     JSPropertyOp getter;
>     jsval *vec;
760d711
<     jsval v;
765c716,731
<     JS_ASSERT(GET_FUNCTION_PRIVATE(cx, fp->callee) == fp->fun);
---
> 
>     /*
>      * Do not enumerate a cloned function object at fp->argv[-2], it may have
>      * gained its own (mutable) scope (e.g., a brutally-shared XUL script sets
>      * the clone's prototype property).  We must enumerate the function object
>      * that was decorated with parameter and local variable properties by the
>      * compiler when the compiler created fp->fun, namely fp->fun->object.
>      *
>      * Contrast with call_resolve, where we prefer fp->argv[-2], because we'll
>      * use js_LookupProperty to find any overridden properties in that object,
>      * if it was a mutated clone; and if not, we will search its prototype,
>      * fp->fun->object, to find compiler-created params and locals.
>      */
>     funobj = fp->fun->object;
>     if (!funobj)
>         return JS_TRUE;
772,788c738,745
<     fun = fp->fun;
<     n = JS_GET_LOCAL_NAME_COUNT(fun);
<     if (n == 0)
<         return JS_TRUE;
< 
<     mark = JS_ARENA_MARK(&cx->tempPool);
< 
<     /* From this point the control must flow through the label out. */
<     names = js_GetLocalNameArray(cx, fun, &cx->tempPool);
<     if (!names) {
<         ok = JS_FALSE;
<         goto out;
<     }
< 
<     for (i = 0; i != n; ++i) {
<         name = JS_LOCAL_NAME_TO_ATOM(names[i]);
<         if (!name)
---
>     scope = OBJ_SCOPE(funobj);
>     for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) {
>         getter = sprop->getter;
>         if (getter == js_GetArgument)
>             vec = fp->argv;
>         else if (getter == js_GetLocalVariable)
>             vec = fp->vars;
>         else
791,809c748,754
<         /*
<          * Trigger reflection by looking up the name of the argument or
<          * variable.
<          */
<         ok = js_LookupProperty(cx, obj, ATOM_TO_JSID(name), &pobj, &prop);
<         if (!ok)
<             goto out;
< 
<         /*
<          * At this point the call object always has a property corresponding
<          * to the local name because call_resolve creates the property using
<          * JSPROP_PERMANENT.
<          */
<         JS_ASSERT(prop && pobj == obj);
<         slot = ((JSScopeProperty *) prop)->slot;
<         OBJ_DROP_PROPERTY(cx, pobj, prop);
< 
<         v = (i < fun->nargs) ? fp->argv[i] : fp->vars[i - fun->nargs];
<         LOCKED_OBJ_SET_SLOT(obj, slot, v);
---
>         /* Trigger reflection in call_resolve by doing a lookup. */
>         if (!js_LookupProperty(cx, obj, sprop->id, &obj, &prop))
>             return JS_FALSE;
>         JS_ASSERT(obj && prop);
>         cprop = (JSScopeProperty *)prop;
>         LOCKED_OBJ_SET_SLOT(obj, cprop->slot, vec[sprop->shortid]);
>         OBJ_DROP_PROPERTY(cx, obj, prop);
811d755
<     ok = JS_TRUE;
813,815c757
<   out:
<     JS_ARENA_RELEASE(&cx->tempPool, mark);
<     return ok;
---
>     return JS_TRUE;
819c761
< call_resolve(JSContext *cx, JSObject *obj, jsval idval, uintN flags,
---
> call_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
823,824c765,770
<     jsid id;
<     JSLocalKind localKind;
---
>     JSObject *funobj;
>     JSString *str;
>     JSAtom *atom;
>     JSObject *obj2;
>     JSScopeProperty *sprop;
>     jsid propid;
826,827c772,774
<     uintN slot, attrs;
<     jsval *vp;
---
>     uintN attrs, slot, nslots, spflags;
>     jsval *vp, value;
>     intN shortid;
833d779
<     JS_ASSERT(GET_FUNCTION_PRIVATE(cx, fp->callee) == fp->fun);
835c781
<     if (!JSVAL_IS_STRING(idval))
---
>     if (!JSVAL_IS_STRING(id))
838,864c784,785
<     if (!js_ValueToStringId(cx, idval, &id))
<         return JS_FALSE;
< 
<     localKind = js_LookupLocal(cx, fp->fun, JSID_TO_ATOM(id), &slot);
<     if (localKind != JSLOCAL_NONE) {
<         if (localKind == JSLOCAL_ARG) {
<             JS_ASSERT(slot < fp->fun->nargs);
<             vp = fp->argv;
<             getter = setter = NULL;
<             attrs = JSPROP_PERMANENT;
<         } else {
<             JS_ASSERT(localKind == JSLOCAL_VAR || localKind == JSLOCAL_CONST);
<             JS_ASSERT(fp->fun->u.i.nvars == fp->nvars);
<             JS_ASSERT(slot < fp->nvars);
<             vp = fp->vars;
<             getter = js_GetCallVariable;
<             setter = js_SetCallVariable;
<             attrs = (localKind == JSLOCAL_CONST)
<                     ? JSPROP_PERMANENT | JSPROP_READONLY
<                     : JSPROP_PERMANENT;
<         }
<         if (!js_DefineNativeProperty(cx, obj, id, vp[slot], getter, setter,
<                                      attrs, SPROP_HAS_SHORTID, (int) slot,
<                                      NULL)) {
<             return JS_FALSE;
<         }
<         *objp = obj;
---
>     funobj = fp->argv ? JSVAL_TO_OBJECT(fp->argv[-2]) : fp->fun->object;
>     if (!funobj)
865a787,794
> 
>     str = JSVAL_TO_STRING(id);
>     atom = js_AtomizeString(cx, str, 0);
>     if (!atom)
>         return JS_FALSE;
>     if (!js_LookupProperty(cx, funobj, (jsid)atom, &obj2,
>                            (JSProperty **)&sprop)) {
>         return JS_FALSE;
868,877c797,828
<     /*
<      * Resolve arguments so that we never store a particular Call object's
<      * arguments object reference in a Call prototype's |arguments| slot.
<      */
<     if (id == ATOM_TO_JSID(cx->runtime->atomState.argumentsAtom)) {
<         if (!js_DefineNativeProperty(cx, obj, id, JSVAL_VOID,
<                                      NULL, NULL, JSPROP_PERMANENT,
<                                      SPROP_HAS_SHORTID, CALL_ARGUMENTS,
<                                      NULL)) {
<             return JS_FALSE;
---
>     if (sprop && OBJ_IS_NATIVE(obj2)) {
>         propid = sprop->id;
>         getter = sprop->getter;
>         attrs = sprop->attrs & ~JSPROP_SHARED;
>         slot = (uintN) sprop->shortid;
>         OBJ_DROP_PROPERTY(cx, obj2, (JSProperty *)sprop);
>         if (getter == js_GetArgument || getter == js_GetLocalVariable) {
>             if (getter == js_GetArgument) {
>                 vp = fp->argv;
>                 nslots = JS_MAX(fp->argc, fp->fun->nargs);
>                 getter = setter = NULL;
>             } else {
>                 vp = fp->vars;
>                 nslots = fp->nvars;
>                 getter = js_GetCallVariable;
>                 setter = js_SetCallVariable;
>             }
>             if (slot < nslots) {
>                 value = vp[slot];
>                 spflags = SPROP_HAS_SHORTID;
>                 shortid = (intN) slot;
>             } else {
>                 value = JSVAL_VOID;
>                 spflags = 0;
>                 shortid = 0;
>             }
>             if (!js_DefineNativeProperty(cx, obj, propid, value,
>                                          getter, setter, attrs,
>                                          spflags, shortid, NULL)) {
>                 return JS_FALSE;
>             }
>             *objp = obj;
879,880d829
<         *objp = obj;
<         return JS_TRUE;
894c843
<             *vp = OBJECT_TO_JSVAL(fp->callee);
---
>             *vp = fp->argv ? fp->argv[-2] : OBJECT_TO_JSVAL(fp->fun->object);
900c849
< JS_FRIEND_DATA(JSClass) js_CallClass = {
---
> JSClass js_CallClass = {
902,911c851,856
<     JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE | JSCLASS_IS_ANONYMOUS |
<     JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_Call),
<     JS_PropertyStub,    JS_PropertyStub,
<     call_getProperty,   call_setProperty,
<     call_enumerate,     (JSResolveOp)call_resolve,
<     call_convert,       JS_FinalizeStub,
<     NULL,               NULL,
<     NULL,               NULL,
<     NULL,               NULL,
<     JS_CLASS_TRACE(args_or_call_trace), NULL,
---
>     JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE,
>     JS_PropertyStub,  JS_PropertyStub,
>     call_getProperty, call_setProperty,
>     call_enumerate,   (JSResolveOp)call_resolve,
>     call_convert,     JS_FinalizeStub,
>     JSCLASS_NO_OPTIONAL_MEMBERS
914,928c859,862
< /*
<  * ECMA-262 specifies that length is a property of function object instances,
<  * but we can avoid that space cost by delegating to a prototype property that
<  * is JSPROP_PERMANENT and JSPROP_SHARED.  Each fun_getProperty call computes
<  * a fresh length value based on the arity of the individual function object's
<  * private data.
<  *
<  * The extensions below other than length, i.e., the ones not in ECMA-262,
<  * are neither JSPROP_READONLY nor JSPROP_SHARED, because for compatibility
<  * with ECMA we must allow a delegating object to override them. Therefore to
<  * avoid entraining garbage in Function.prototype slots, they must be resolved
<  * in non-prototype function objects, wherefore the lazy_function_props table
<  * and fun_resolve's use of it.
<  */
< #define LENGTH_PROP_ATTRS (JSPROP_READONLY|JSPROP_PERMANENT|JSPROP_SHARED)
---
> #endif /* JS_HAS_CALL_OBJECT */
> 
> /* SHARED because fun_getProperty always computes a new value. */
> #define FUNCTION_PROP_ATTRS (JSPROP_READONLY|JSPROP_PERMANENT|JSPROP_SHARED)
931c865,869
<     {js_length_str,    ARGS_LENGTH,    LENGTH_PROP_ATTRS, 0,0},
---
>     {js_arguments_str, CALL_ARGUMENTS, FUNCTION_PROP_ATTRS,0,0},
>     {js_arity_str,     FUN_ARITY,      FUNCTION_PROP_ATTRS,0,0},
>     {js_length_str,    ARGS_LENGTH,    FUNCTION_PROP_ATTRS,0,0},
>     {js_name_str,      FUN_NAME,       FUNCTION_PROP_ATTRS,0,0},
>     {js_caller_str,    FUN_CALLER,     FUNCTION_PROP_ATTRS,0,0},
935,948d872
< typedef struct LazyFunctionProp {
<     uint16      atomOffset;
<     int8        tinyid;
<     uint8       attrs;
< } LazyFunctionProp;
< 
< /* NB: no sentinel at the end -- use JS_ARRAY_LENGTH to bound loops. */
< static LazyFunctionProp lazy_function_props[] = {
<     {ATOM_OFFSET(arguments), CALL_ARGUMENTS, JSPROP_PERMANENT},
<     {ATOM_OFFSET(arity),     FUN_ARITY,      JSPROP_PERMANENT},
<     {ATOM_OFFSET(caller),    FUN_CALLER,     JSPROP_PERMANENT},
<     {ATOM_OFFSET(name),      FUN_NAME,       JSPROP_PERMANENT},
< };
< 
954a879,882
> #if defined _MSC_VER &&_MSC_VER <= 800
>     /* MSVC1.5 coredumps */
>     jsval bogus = *vp;
> #endif
960,987c888,891
<     /*
<      * Loop because getter and setter can be delegated from another class,
<      * but loop only for ARGS_LENGTH because we must pretend that f.length
<      * is in each function instance f, per ECMA-262, instead of only in the
<      * Function.prototype object (we use JSPROP_PERMANENT with JSPROP_SHARED
<      * to make it appear so).
<      *
<      * This code couples tightly to the attributes for the function_props[]
<      * initializers above, and to js_SetProperty and js_HasOwnPropertyHelper.
<      *
<      * It's important to allow delegating objects, even though they inherit
<      * this getter (fun_getProperty), to override arguments, arity, caller,
<      * and name.  If we didn't return early for slot != ARGS_LENGTH, we would
<      * clobber *vp with the native property value, instead of letting script
<      * override that value in delegating objects.
<      *
<      * Note how that clobbering is what simulates JSPROP_READONLY for all of
<      * the non-standard properties when the directly addressed object (obj)
<      * is a function object (i.e., when this loop does not iterate).
<      */
<     while (!(fun = (JSFunction *)
<                    JS_GetInstancePrivate(cx, obj, &js_FunctionClass, NULL))) {
<         if (slot != ARGS_LENGTH)
<             return JS_TRUE;
<         obj = OBJ_GET_PROTO(cx, obj);
<         if (!obj)
<             return JS_TRUE;
<     }
---
>     /* No valid function object should lack private data, but check anyway. */
>     fun = (JSFunction *)JS_GetInstancePrivate(cx, obj, &js_FunctionClass, NULL);
>     if (!fun)
>         return JS_TRUE;
996a901
> #if JS_HAS_ARGS_OBJECT
1011a917,920
> #else  /* !JS_HAS_ARGS_OBJECT */
>         *vp = OBJECT_TO_JSVAL(fp ? obj : NULL);
>         break;
> #endif /* !JS_HAS_ARGS_OBJECT */
1013a923,925
>         if (!JSVERSION_IS_ECMA(cx->version))
>             *vp = INT_TO_JSVAL((jsint)(fp && fp->fun ? fp->argc : fun->nargs));
>         else
1025,1026c937,938
<         if (fp && fp->down && fp->down->fun)
<             *vp = OBJECT_TO_JSVAL(fp->down->callee);
---
>         if (fp && fp->down && fp->down->fun && fp->down->argv)
>             *vp = fp->down->argv[-2];
1038a951,954
> #if defined _MSC_VER &&_MSC_VER <= 800
>           /* MSVC1.5 coredumps */
>           if (bogus == *vp)
> #endif
1047,1061d962
< fun_enumerate(JSContext *cx, JSObject *obj)
< {
<     jsid prototypeId;
<     JSObject *pobj;
<     JSProperty *prop;
< 
<     prototypeId = ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom);
<     if (!OBJ_LOOKUP_PROPERTY(cx, obj, prototypeId, &pobj, &prop))
<         return JS_FALSE;
<     if (prop)
<         OBJ_DROP_PROPERTY(cx, pobj, prop);
<     return JS_TRUE;
< }
< 
< static JSBool
1066,1067c967,968
<     JSAtom *atom;
<     uintN i;
---
>     JSString *str;
>     JSAtom *prototypeAtom;
1072,1073c973,976
<     fun = GET_FUNCTION_PRIVATE(cx, obj);
<     JS_ASSERT(fun->object);
---
>     /* No valid function object should lack private data, but check anyway. */
>     fun = (JSFunction *)JS_GetInstancePrivate(cx, obj, &js_FunctionClass, NULL);
>     if (!fun || !fun->object)
>         return JS_TRUE;
1075,1086c978
<     /*
<      * No need to reflect fun.prototype in 'fun.prototype = ... '.
<      *
<      * This is not just an optimization, because we must not resolve when
<      * defining hidden properties during compilation. The setup code for the
<      * prototype and the lazy properties below eventually calls the property
<      * hooks for the function object. That in turn calls fun_reserveSlots to
<      * get the number of the reserved slots which is just the number of
<      * regular expressions literals in the function. When compiling, that
<      * number is not yet ready so we must make sure that fun_resolve does
<      * nothing until the code for the function is generated.
<      */
---
>     /* No need to reflect fun.prototype in 'fun.prototype = ...'. */
1094,1096c986,1002
<     atom = cx->runtime->atomState.classPrototypeAtom;
<     if (id == ATOM_KEY(atom)) {
<         JSObject *proto;
---
>     str = JSVAL_TO_STRING(id);
>     prototypeAtom = cx->runtime->atomState.classPrototypeAtom;
>     if (str == ATOM_TO_STRING(prototypeAtom)) {
>         JSObject *proto, *parentProto;
>         jsval pval;
> 
>         proto = parentProto = NULL;
>         if (fun->object != obj && fun->object) {
>             /*
>              * Clone of a function: make its prototype property value have the
>              * same class as the clone-parent's prototype.
>              */
>             if (!OBJ_GET_PROPERTY(cx, fun->object, (jsid)prototypeAtom, &pval))
>                 return JS_FALSE;
>             if (JSVAL_IS_OBJECT(pval))
>                 parentProto = JSVAL_TO_OBJECT(pval);
>         }
1100c1006
<          * to find a prototype for that will recur back here _ad perniciem_.
---
>          * to find a prototype for that will recur back here ad perniciem.
1102c1008
<         if (fun->atom == CLASS_ATOM(cx, Object))
---
>         if (!parentProto && fun->atom == cx->runtime->atomState.ObjectAtom)
1106,1107c1012,1014
<          * Make the prototype object to have the same parent as the function
<          * object itself.
---
>          * If resolving "prototype" in a clone, clone the parent's prototype.
>          * Pass the constructor's (obj's) parent as the prototype parent, to
>          * avoid defaulting to parentProto.constructor.__parent__.
1109c1016
<         proto = js_NewObject(cx, &js_ObjectClass, NULL,
---
>         proto = js_NewObject(cx, &js_ObjectClass, parentProto,
1115c1022
<          * ECMA (15.3.5.2) says that constructor.prototype is DontDelete for
---
>          * ECMA says that constructor.prototype is DontEnum | DontDelete for
1121,1123c1028,1029
<         if (!js_SetClassPrototype(cx, obj, proto,
<                                   JSPROP_ENUMERATE | JSPROP_PERMANENT)) {
<             cx->weakRoots.newborn[GCX_OBJECT] = NULL;
---
>         if (!js_SetClassPrototype(cx, obj, proto, JSPROP_PERMANENT)) {
>             cx->newborn[GCX_OBJECT] = NULL;
1127,1144d1032
<         return JS_TRUE;
<     }
< 
<     for (i = 0; i < JS_ARRAY_LENGTH(lazy_function_props); i++) {
<         LazyFunctionProp *lfp = &lazy_function_props[i];
< 
<         atom = OFFSET_TO_ATOM(cx->runtime, lfp->atomOffset);
<         if (id == ATOM_KEY(atom)) {
<             if (!js_DefineNativeProperty(cx, obj,
<                                          ATOM_TO_JSID(atom), JSVAL_VOID,
<                                          NULL, NULL, lfp->attrs,
<                                          SPROP_HAS_SHORTID, lfp->tinyid,
<                                          NULL)) {
<                 return JS_FALSE;
<             }
<             *objp = obj;
<             return JS_TRUE;
<         }
1161a1050,1068
> static void
> fun_finalize(JSContext *cx, JSObject *obj)
> {
>     JSFunction *fun;
> 
>     /* No valid function object should lack private data, but check anyway. */
>     fun = (JSFunction *) JS_GetPrivate(cx, obj);
>     if (!fun)
>         return;
>     if (fun->object == obj)
>         fun->object = NULL;
>     JS_ATOMIC_DECREMENT(&fun->nrefs);
>     if (fun->nrefs)
>         return;
>     if (fun->script)
>         js_DestroyScript(cx, fun->script);
>     JS_free(cx, fun);
> }
> 
1163a1071,1078
> #include "jsxdrapi.h"
> 
> enum {
>     JSXDR_FUNARG = 1,
>     JSXDR_FUNVAR = 2,
>     JSXDR_FUNCONST = 3
> };
> 
1170,1175c1085,1094
<     uint32 nullAtom;            /* flag to indicate if fun->atom is NULL */
<     uintN nargs, nvars, n;
<     uint32 localsword;          /* word to xdr argument and variable counts */
<     uint32 flagsword;           /* originally only flags was JS_XDRUint8'd */
<     JSTempValueRooter tvr;
<     JSBool ok;
---
>     JSString *atomstr;
>     char *propname;
>     JSScopeProperty *sprop;
>     jsid userid;
>     JSAtom *atom;
>     uintN i, n, dupflag;
>     uint32 type;
> #ifdef DEBUG
>     uintN nvars = 0, nargs = 0;
> #endif
1179,1190c1098,1106
<         fun = GET_FUNCTION_PRIVATE(cx, *objp);
<         if (!FUN_INTERPRETED(fun)) {
<             JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
<                                  JSMSG_NOT_SCRIPTED_FUNCTION,
<                                  JS_GetFunctionName(fun));
<             return JS_FALSE;
<         }
<         nullAtom = !fun->atom;
<         nargs = fun->nargs;
<         nvars = fun->u.i.nvars;
<         localsword = (nargs << 16) | nvars;
<         flagsword = fun->flags;
---
>         /*
>          * No valid function object should lack private data, but fail soft
>          * (return true, no error report) in case one does due to API pilot
>          * or internal error.
>          */
>         fun = (JSFunction *) JS_GetPrivate(cx, *objp);
>         if (!fun)
>             return JS_TRUE;
>         atomstr = fun->atom ? ATOM_TO_STRING(fun->atom) : NULL;
1192c1108
<         fun = js_NewFunction(cx, NULL, NULL, 0, JSFUN_INTERPRETED, NULL, NULL);
---
>         fun = js_NewFunction(cx, NULL, NULL, 0, 0, NULL, NULL);
1195,1212c1111
<         STOBJ_SET_PARENT(fun->object, NULL);
<         STOBJ_SET_PROTO(fun->object, NULL);
< #ifdef __GNUC__
<         nvars = nargs = 0;   /* quell GCC uninitialized warning */
< #endif
<     }
< 
<     /* From here on, control flow must flow through label out. */
<     JS_PUSH_TEMP_ROOT_OBJECT(cx, fun->object, &tvr);
<     ok = JS_TRUE;
< 
<     if (!JS_XDRUint32(xdr, &nullAtom))
<         goto bad;
<     if (!nullAtom && !js_XDRStringAtom(xdr, &fun->atom))
<         goto bad;
<     if (!JS_XDRUint32(xdr, &localsword) ||
<         !JS_XDRUint32(xdr, &flagsword)) {
<         goto bad;
---
>         atomstr = NULL;
1215,1219c1114,1119
<     if (xdr->mode == JSXDR_DECODE) {
<         nargs = localsword >> 16;
<         nvars = localsword & JS_BITMASK(16);
<         JS_ASSERT(flagsword | JSFUN_INTERPRETED);
<         fun->flags = (uint16) flagsword;
---
>     if (!JS_XDRStringOrNull(xdr, &atomstr) ||
>         !JS_XDRUint16(xdr, &fun->nargs) ||
>         !JS_XDRUint16(xdr, &fun->extra) ||
>         !JS_XDRUint16(xdr, &fun->nvars) ||
>         !JS_XDRUint8(xdr, &fun->flags)) {
>         return JS_FALSE;
1223,1251c1123,1124
<     if (fun->object && (n = nargs + nvars) != 0) {
<         void *mark;
<         uintN i;
<         uintN bitmapLength;
<         uint32 *bitmap;
<         jsuword *names;
<         JSAtom *name;
<         JSLocalKind localKind;
< 
<         mark = JS_ARENA_MARK(&xdr->cx->tempPool);
< 
<         /*
<          * From this point the control must flow via the label release_mark.
<          *
<          * To xdr the names we prefix the names with a bitmap descriptor and
<          * then xdr the names as strings. For argument names (indexes below
<          * nargs) the corresponding bit in the bitmap is unset when the name
<          * is null. Such null names are not encoded or decoded. For variable
<          * names (indexes starting from nargs) bitmap's bit is set when the
<          * name is declared as const, not as ordinary var.
<          * */
<         bitmapLength = JS_HOWMANY(n, JS_BITS_PER_UINT32);
<         JS_ARENA_ALLOCATE_CAST(bitmap, uint32 *, &xdr->cx->tempPool,
<                                bitmapLength * sizeof *bitmap);
<         if (!bitmap) {
<             js_ReportOutOfScriptQuota(xdr->cx);
<             ok = JS_FALSE;
<             goto release_mark;
<         }
---
>     if (fun->object) {
>         n = fun->nargs + fun->nvars;
1253,1264c1126,1139
<             names = js_GetLocalNameArray(xdr->cx, fun, &xdr->cx->tempPool);
<             if (!names) {
<                 ok = JS_FALSE;
<                 goto release_mark;
<             }
<             memset(bitmap, 0, bitmapLength * sizeof *bitmap);
<             for (i = 0; i != n; ++i) {
<                 if (i < fun->nargs
<                     ? JS_LOCAL_NAME_TO_ATOM(names[i]) != NULL
<                     : JS_LOCAL_NAME_IS_CONST(names[i])) {
<                     bitmap[i >> JS_BITS_PER_UINT32_LOG2] |=
<                         JS_BIT(i & (JS_BITS_PER_UINT32 - 1));
---
>             JSScope *scope;
>             JSScopeProperty **spvec, *auto_spvec[8];
>             void *mark;
> 
>             if (n <= sizeof auto_spvec / sizeof auto_spvec[0]) {
>                 spvec = auto_spvec;
>                 mark = NULL;
>             } else {
>                 mark = JS_ARENA_MARK(&cx->tempPool);
>                 JS_ARENA_ALLOCATE_CAST(spvec, JSScopeProperty **, &cx->tempPool,
>                                        n * sizeof(JSScopeProperty *));
>                 if (!spvec) {
>                     JS_ReportOutOfMemory(cx);
>                     return JS_FALSE;
1267,1287c1142,1156
<         }
< #ifdef __GNUC__
<         else {
<             names = NULL;   /* quell GCC uninitialized warning */
<         }
< #endif
<         for (i = 0; i != bitmapLength; ++i) {
<             ok = JS_XDRUint32(xdr, &bitmap[i]);
<             if (!ok)
<                 goto release_mark;
<         }
<         for (i = 0; i != n; ++i) {
<             if (i < nargs &&
<                 !(bitmap[i >> JS_BITS_PER_UINT32_LOG2] &
<                   JS_BIT(i & (JS_BITS_PER_UINT32 - 1)))) {
<                 if (xdr->mode == JSXDR_DECODE) {
<                     ok = js_AddLocal(xdr->cx, fun, NULL, JSLOCAL_ARG);
<                     if (!ok)
<                         goto release_mark;
<                 } else {
<                     JS_ASSERT(!JS_LOCAL_NAME_TO_ATOM(names[i]));
---
>             // 2003.11.14 jht: Init spvec. Prevent failure in jstest suite ecma_3:ExecutionContexts:10.1.3.js
>             scope = OBJ_SCOPE(fun->object);
>             sprop = SCOPE_LAST_PROP(scope);
>             for (i = 0; i < n; i++) {
>                 spvec[i] = sprop;
> 			}
>             scope = OBJ_SCOPE(fun->object);
>             for (sprop = SCOPE_LAST_PROP(scope); sprop;
>                  sprop = sprop->parent) {
>                 if (sprop->getter == js_GetArgument) {
>                     JS_ASSERT(nargs++ <= fun->nargs);
>                     spvec[sprop->shortid] = sprop;
>                 } else if (sprop->getter == js_GetLocalVariable) {
>                     JS_ASSERT(nvars++ <= fun->nvars);
>                     spvec[fun->nargs + sprop->shortid] = sprop;
1289d1157
<                 continue;
1291,1305c1159,1175
<             if (xdr->mode == JSXDR_ENCODE)
<                 name = JS_LOCAL_NAME_TO_ATOM(names[i]);
<             ok = js_XDRStringAtom(xdr, &name);
<             if (!ok)
<                 goto release_mark;
<             if (xdr->mode == JSXDR_DECODE) {
<                 localKind = (i < nargs)
<                             ? JSLOCAL_ARG
<                             : bitmap[i >> JS_BITS_PER_UINT32_LOG2] &
<                               JS_BIT(i & (JS_BITS_PER_UINT32 - 1))
<                             ? JSLOCAL_CONST
<                             : JSLOCAL_VAR;
<                 ok = js_AddLocal(xdr->cx, fun, name, localKind);
<                 if (!ok)
<                     goto release_mark;
---
>             for (i = 0; i < n; i++) {
>                 sprop = spvec[i];
>                 JS_ASSERT(sprop->flags & SPROP_HAS_SHORTID);
>                 type = (i < fun->nargs)
>                        ? JSXDR_FUNARG
>                        : (sprop->attrs & JSPROP_READONLY)
>                        ? JSXDR_FUNCONST
>                        : JSXDR_FUNVAR;
>                 userid = INT_TO_JSVAL(sprop->shortid);
>                 propname = ATOM_BYTES((JSAtom *)sprop->id);
>                 if (!JS_XDRUint32(xdr, &type) ||
>                     !JS_XDRUint32(xdr, (uint32 *)&userid) ||
>                     !JS_XDRCString(xdr, &propname)) {
>                     if (mark)
>                         JS_ARENA_RELEASE(&cx->tempPool, mark);
>                     return JS_FALSE;
>                 }
1307,1308c1177,1180
<         }
<         ok = JS_TRUE;
---
>             if (mark)
>                 JS_ARENA_RELEASE(&cx->tempPool, mark);
>         } else {
>             JSPropertyOp getter, setter;
1310,1313c1182,1209
<       release_mark:
<         JS_ARENA_RELEASE(&xdr->cx->tempPool, mark);
<         if (!ok)
<             goto out;
---
>             for (i = n; i != 0; i--) {
>                 uintN attrs = JSPROP_ENUMERATE | JSPROP_PERMANENT;
> 
>                 if (!JS_XDRUint32(xdr, &type) ||
>                     !JS_XDRUint32(xdr, (uint32 *)&userid) ||
>                     !JS_XDRCString(xdr, &propname)) {
>                     return JS_FALSE;
>                 }
>                 JS_ASSERT(type == JSXDR_FUNARG || type == JSXDR_FUNVAR ||
>                           type == JSXDR_FUNCONST);
>                 if (type == JSXDR_FUNARG) {
>                     getter = js_GetArgument;
>                     setter = js_SetArgument;
>                     JS_ASSERT(nargs++ <= fun->nargs);
>                 } else if (type == JSXDR_FUNVAR || type == JSXDR_FUNCONST) {
>                     getter = js_GetLocalVariable;
>                     setter = js_SetLocalVariable;
>                     if (type == JSXDR_FUNCONST)
>                         attrs |= JSPROP_READONLY;
>                     JS_ASSERT(nvars++ <= fun->nvars);
>                 } else {
>                     getter = NULL;
>                     setter = NULL;
>                 }
>                 atom = js_Atomize(cx, propname, strlen(propname), 0);
>                 JS_free(cx, propname);
>                 if (!atom)
>                     return JS_FALSE;
1315,1316c1211,1224
<         if (xdr->mode == JSXDR_DECODE)
<             js_FreezeLocalNames(cx, fun);
---
>                 /* Flag duplicate argument if atom is bound in fun->object. */
>                 dupflag = SCOPE_GET_PROPERTY(OBJ_SCOPE(fun->object), (jsid)atom)
>                           ? SPROP_IS_DUPLICATE
>                           : 0;
> 
>                 if (!js_AddNativeProperty(cx, fun->object, (jsid)atom,
>                                           getter, setter, SPROP_INVALID_SLOT,
>                                           attrs | JSPROP_SHARED,
>                                           SPROP_HAS_SHORTID | dupflag,
>                                           JSVAL_TO_INT(userid))) {
>                     return JS_FALSE;
>                 }
>             }
>         }
1319,1320c1227,1228
<     if (!js_XDRScript(xdr, &fun->u.i.script, NULL))
<         goto bad;
---
>     if (!js_XDRScript(xdr, &fun->script, NULL))
>         return JS_FALSE;
1324,1328c1232,1235
< #ifdef CHECK_SCRIPT_OWNER
<         fun->u.i.script->owner = NULL;
< #endif
<         js_CallNewScriptHook(cx, fun->u.i.script, fun);
<     }
---
>         if (atomstr) {
>             fun->atom = js_AtomizeString(cx, atomstr, 0);
>             if (!fun->atom)
>                 return JS_FALSE;
1330,1332c1237,1243
< out:
<     JS_POP_TEMP_ROOT(cx, &tvr);
<     return ok;
---
>             if (!OBJ_DEFINE_PROPERTY(cx, cx->globalObject,
>                                      (jsid)fun->atom, OBJECT_TO_JSVAL(*objp),
>                                      NULL, NULL, JSPROP_ENUMERATE,
>                                      NULL)) {
>                 return JS_FALSE;
>             }
>         }
1334,1336c1245,1248
< bad:
<     ok = JS_FALSE;
<     goto out;
---
>         js_CallNewScriptHook(cx, fun->script, fun);
>     }
> 
>     return JS_TRUE;
1344a1257,1258
> #if JS_HAS_INSTANCEOF
> 
1353c1267,1270
<     jsval pval;
---
>     jsval pval, cval;
>     JSString *str;
>     JSObject *proto, *obj2;
>     JSFunction *cfun, *ofun;
1356,1357c1273
<                           ATOM_TO_JSID(cx->runtime->atomState
<                                        .classPrototypeAtom),
---
>                           (jsid)cx->runtime->atomState.classPrototypeAtom,
1367,1368c1283,1287
<         js_ReportValueError(cx, JSMSG_BAD_PROTOTYPE,
<                             -1, OBJECT_TO_JSVAL(obj), NULL);
---
>         str = js_DecompileValueGenerator(cx, -1, OBJECT_TO_JSVAL(obj), NULL);
>         if (str) {
>             JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
>                                  JSMSG_BAD_PROTOTYPE, JS_GetStringBytes(str));
>         }
1372,1373c1291,1293
<     return js_IsDelegate(cx, JSVAL_TO_OBJECT(pval), v, bp);
< }
---
>     proto = JSVAL_TO_OBJECT(pval);
>     if (!js_IsDelegate(cx, proto, v, bp))
>         return JS_FALSE;
1375,1378c1295,1319
< static void
< fun_trace(JSTracer *trc, JSObject *obj)
< {
<     JSFunction *fun;
---
>     if (!*bp && !JSVAL_IS_PRIMITIVE(v)) {
>         /*
>          * Extension for "brutal sharing" of standard class constructors: if
>          * a script is compiled using a single, shared set of constructors, in
>          * particular Function and RegExp, but executed many times using other
>          * sets of standard constructors, then (/re/ instanceof RegExp), e.g.,
>          * will be false.
>          *
>          * We extend instanceof in this case to look for a matching native or
>          * script underlying the function object found in the 'constructor'
>          * property of the object in question (which is JSVAL_TO_OBJECT(v)),
>          * or found in the 'constructor' property of one of its prototypes.
>          *
>          * See also jsexn.c, where the *Error constructors are defined, each
>          * with its own native function, to satisfy (e instanceof Error) even
>          * when exceptions cross standard-class sharing boundaries.  Note that
>          * Error.prototype may not lie on e's __proto__ chain in that case.
>          */
>         obj2 = JSVAL_TO_OBJECT(v);
>         do {
>             if (!OBJ_GET_PROPERTY(cx, obj2,
>                                   (jsid)cx->runtime->atomState.constructorAtom,
>                                   &cval)) {
>                 return JS_FALSE;
>             }
1380,1383c1321,1333
<     /* A newborn function object may have a not yet initialized private slot. */
<     fun = (JSFunction *) JS_GetPrivate(trc->context, obj);
<     if (fun)
<         JS_CALL_TRACER(trc, fun, JSTRACE_FUNCTION, "private");
---
>             if (JSVAL_IS_FUNCTION(cx, cval)) {
>                 cfun = (JSFunction *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(cval));
>                 ofun = (JSFunction *) JS_GetPrivate(cx, obj);
>                 if (cfun->native == ofun->native &&
>                     cfun->script == ofun->script) {
>                     *bp = JS_TRUE;
>                     break;
>                 }
>             }
>         } while ((obj2 = OBJ_GET_PROTO(cx, obj2)) != NULL);
>     }
> 
>     return JS_TRUE;
1385a1336,1341
> #else  /* !JS_HAS_INSTANCEOF */
> 
> #define fun_hasInstance NULL
> 
> #endif /* !JS_HAS_INSTANCEOF */
> 
1387c1343
< fun_reserveSlots(JSContext *cx, JSObject *obj)
---
> fun_mark(JSContext *cx, JSObject *obj, void *arg)
1391,1395d1346
<     /*
<      * We use JS_GetPrivate and not GET_FUNCTION_PRIVATE because during
<      * js_InitFunctionClass invocation the function is called before the
<      * private slot of the function object is set.
<      */
1397,1400c1348,1354
<     return (fun && FUN_INTERPRETED(fun) &&
<             fun->u.i.script && fun->u.i.script->regexpsOffset != 0)
<            ? JS_SCRIPT_REGEXPS(fun->u.i.script)->length
<            : 0;
---
>     if (fun) {
>         if (fun->atom)
>             GC_MARK_ATOM(cx, fun->atom, arg);
>         if (fun->script)
>             js_MarkScript(cx, fun->script, arg);
>     }
>     return 0;
1408c1362
< JS_FRIEND_DATA(JSClass) js_FunctionClass = {
---
> JSClass js_FunctionClass = {
1410,1411c1364
<     JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE | JSCLASS_HAS_RESERVED_SLOTS(2) |
<     JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_Function),
---
>     JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE | JSCLASS_HAS_RESERVED_SLOTS(2),
1414,1415c1367,1368
<     fun_enumerate,    (JSResolveOp)fun_resolve,
<     fun_convert,      JS_FinalizeStub,
---
>     JS_EnumerateStub, (JSResolveOp)fun_resolve,
>     fun_convert,      fun_finalize,
1419c1372
<     JS_CLASS_TRACE(fun_trace), fun_reserveSlots
---
>     fun_mark,         0
1422,1423c1375,1377
< static JSBool
< fun_toStringHelper(JSContext *cx, uint32 indent, uintN argc, jsval *vp)
---
> JSBool
> js_fun_toString(JSContext *cx, JSObject *obj, uint32 indent,
>                 uintN argc, jsval *argv, jsval *rval)
1426d1379
<     JSObject *obj;
1430,1439c1383,1404
<     fval = vp[1];
<     if (!VALUE_IS_FUNCTION(cx, fval)) {
<         /*
<          * If we don't have a function to start off with, try converting the
<          * object to a function. If that doesn't work, complain.
<          */
<         if (!JSVAL_IS_PRIMITIVE(fval)) {
<             obj = JSVAL_TO_OBJECT(fval);
<             if (!OBJ_GET_CLASS(cx, obj)->convert(cx, obj, JSTYPE_FUNCTION,
<                                                  &fval)) {
---
>     if (!argv) {
>         JS_ASSERT(JS_ObjectIsFunction(cx, obj));
>     } else {
>         fval = argv[-1];
>         if (!JSVAL_IS_FUNCTION(cx, fval)) {
>             /*
>              * If we don't have a function to start off with, try converting
>              * the object to a function.  If that doesn't work, complain.
>              */
>             if (JSVAL_IS_OBJECT(fval)) {
>                 obj = JSVAL_TO_OBJECT(fval);
>                 if (!OBJ_GET_CLASS(cx, obj)->convert(cx, obj, JSTYPE_FUNCTION,
>                                                      &fval)) {
>                     return JS_FALSE;
>                 }
>             }
>             if (!JSVAL_IS_FUNCTION(cx, fval)) {
>                 JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
>                                      JSMSG_INCOMPATIBLE_PROTO,
>                                      js_Function_str, js_toString_str,
>                                      JS_GetTypeName(cx,
>                                                     JS_TypeOfValue(cx, fval)));
1442,1449d1406
<             vp[1] = fval;
<         }
<         if (!VALUE_IS_FUNCTION(cx, fval)) {
<             JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
<                                  JSMSG_INCOMPATIBLE_PROTO,
<                                  js_Function_str, js_toString_str,
<                                  JS_GetTypeName(cx, JS_TypeOfValue(cx, fval)));
<             return JS_FALSE;
1451d1407
<     }
1453,1455c1409,1410
<     obj = JSVAL_TO_OBJECT(fval);
<     if (argc != 0 && !js_ValueToECMAUint32(cx, vp[2], &indent))
<         return JS_FALSE;
---
>         obj = JSVAL_TO_OBJECT(fval);
>     }
1457,1458c1412
<     JS_ASSERT(JS_ObjectIsFunction(cx, obj));
<     fun = GET_FUNCTION_PRIVATE(cx, obj);
---
>     fun = (JSFunction *) JS_GetPrivate(cx, obj);
1460a1415,1416
>     if (argc && !js_ValueToECMAUint32(cx, argv[0], &indent))
>         return JS_FALSE;
1464c1420
<     *vp = STRING_TO_JSVAL(str);
---
>     *rval = STRING_TO_JSVAL(str);
1469c1425
< fun_toString(JSContext *cx, uintN argc, jsval *vp)
---
> fun_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1471c1427
<     return fun_toStringHelper(cx, 0, argc,  vp);
---
>     return js_fun_toString(cx, obj, 0, argc, argv, rval);
1476c1432
< fun_toSource(JSContext *cx, uintN argc, jsval *vp)
---
> fun_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1478c1434
<     return fun_toStringHelper(cx, JS_DONT_PRETTY_PRINT, argc, vp);
---
>     return js_fun_toString(cx, obj, JS_DONT_PRETTY_PRINT, argc, argv, rval);
1482c1438
< static const char call_str[] = "call";
---
> static const char js_call_str[] = "call";
1483a1440
> #if JS_HAS_CALL_FUNCTION
1485c1442
< fun_call(JSContext *cx, uintN argc, jsval *vp)
---
> fun_call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1487,1489c1444
<     JSObject *obj;
<     jsval fval, *argv, *invokevp;
<     JSString *str;
---
>     jsval fval, *sp, *oldsp;
1490a1446,1447
>     uintN i;
>     JSStackFrame *fp;
1493,1494c1450
<     obj = JSVAL_TO_OBJECT(vp[1]);
<     if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_FUNCTION, &vp[1]))
---
>     if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_FUNCTION, &argv[-1]))
1496c1452
<     fval = vp[1];
---
>     fval = argv[-1];
1498,1509c1454,1458
<     if (!VALUE_IS_FUNCTION(cx, fval)) {
<         str = JS_ValueToString(cx, fval);
<         if (str) {
<             const char *bytes = js_GetStringBytes(cx, str);
< 
<             if (bytes) {
<                 JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
<                                      JSMSG_INCOMPATIBLE_PROTO,
<                                      js_Function_str, call_str,
<                                      bytes);
<             }
<         }
---
>     if (!JSVAL_IS_FUNCTION(cx, fval)) {
>         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
>                              JSMSG_INCOMPATIBLE_PROTO,
>                              js_Function_str, js_call_str,
>                              JS_GetStringBytes(JS_ValueToString(cx, fval)));
1513d1461
<     argv = vp + 2;
1515,1516c1463,1464
<         /* Call fun with its global object as the 'this' param if no args. */
<         obj = NULL;
---
>         /* Call fun with its parent as the 'this' parameter if no args. */
>         obj = OBJ_GET_PARENT(cx, obj);
1519,1521c1467
<         if (!JSVAL_IS_PRIMITIVE(argv[0]))
<             obj = JSVAL_TO_OBJECT(argv[0]);
<         else if (!js_ValueToObject(cx, argv[0], &obj))
---
>         if (!js_ValueToObject(cx, argv[0], &obj))
1528,1529c1474,1475
<     invokevp = js_AllocStack(cx, 2 + argc, &mark);
<     if (!invokevp)
---
>     sp = js_AllocStack(cx, 2 + argc, &mark);
>     if (!sp)
1533,1535c1479,1482
<     invokevp[0] = fval;
<     invokevp[1] = OBJECT_TO_JSVAL(obj);
<     memcpy(invokevp + 2, argv, argc * sizeof *argv);
---
>     *sp++ = fval;
>     *sp++ = OBJECT_TO_JSVAL(obj);
>     for (i = 0; i < argc; i++)
>         *sp++ = argv[i];
1537,1538c1484,1492
<     ok = js_Invoke(cx, argc, invokevp, JSINVOKE_INTERNAL);
<     *vp = *invokevp;
---
>     /* Lift current frame to include the args and do the call. */
>     fp = cx->fp;
>     oldsp = fp->sp;
>     fp->sp = sp;
>     ok = js_Invoke(cx, argc, JSINVOKE_INTERNAL);
> 
>     /* Store rval and pop stack back to our frame's sp. */
>     *rval = fp->sp[-1];
>     fp->sp = oldsp;
1541a1496
> #endif /* JS_HAS_CALL_FUNCTION */
1542a1498
> #if JS_HAS_APPLY_FUNCTION
1544c1500
< fun_apply(JSContext *cx, uintN argc, jsval *vp)
---
> fun_apply(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1546,1548c1502,1503
<     JSObject *obj, *aobj;
<     jsval fval, *invokevp, *sp;
<     JSString *str;
---
>     jsval fval, *sp, *oldsp;
>     JSObject *aobj;
1550d1504
<     JSBool arraylike, ok;
1552a1507,1508
>     JSBool ok;
>     JSStackFrame *fp;
1555,1556c1511,1512
<         /* Will get globalObject as 'this' and no other arguments. */
<         return fun_call(cx, argc, vp);
---
>         /* Will get globalObject as 'this' and no other agurments. */
>         return fun_call(cx, obj, argc, argv, rval);
1559,1560c1515
<     obj = JSVAL_TO_OBJECT(vp[1]);
<     if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_FUNCTION, &vp[1]))
---
>     if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_FUNCTION, &argv[-1]))
1562c1517
<     fval = vp[1];
---
>     fval = argv[-1];
1564,1575c1519,1523
<     if (!VALUE_IS_FUNCTION(cx, fval)) {
<         str = JS_ValueToString(cx, fval);
<         if (str) {
<             const char *bytes = js_GetStringBytes(cx, str);
< 
<             if (bytes) {
<                 JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
<                                      JSMSG_INCOMPATIBLE_PROTO,
<                                      js_Function_str, "apply",
<                                      bytes);
<             }
<         }
---
>     if (!JSVAL_IS_FUNCTION(cx, fval)) {
>         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
>                              JSMSG_INCOMPATIBLE_PROTO,
>                              js_Function_str, "apply",
>                              JS_GetStringBytes(JS_ValueToString(cx, fval)));
1585c1533
<         if (JSVAL_IS_NULL(vp[3]) || JSVAL_IS_VOID(vp[3])) {
---
>         if (JSVAL_IS_NULL(argv[1]) || JSVAL_IS_VOID(argv[1])) {
1589,1595c1537,1541
<             arraylike = JS_FALSE;
<             if (!JSVAL_IS_PRIMITIVE(vp[3])) {
<                 aobj = JSVAL_TO_OBJECT(vp[3]);
<                 if (!js_IsArrayLike(cx, aobj, &arraylike, &length))
<                     return JS_FALSE;
<             }
<             if (!arraylike) {
---
>             if (JSVAL_IS_PRIMITIVE(argv[1]) ||
>                 (aobj = JSVAL_TO_OBJECT(argv[1]),
>                 OBJ_GET_CLASS(cx, aobj) != &js_ArgumentsClass &&
>                 OBJ_GET_CLASS(cx, aobj) != &js_ArrayClass))
>             {
1597c1543
<                                      JSMSG_BAD_APPLY_ARGS, "apply");
---
>                                      JSMSG_BAD_APPLY_ARGS);
1599a1546,1547
>             if (!js_GetLengthProperty(cx, aobj, &length))
>                 return JS_FALSE;
1604,1606c1552
<     if (!JSVAL_IS_PRIMITIVE(vp[2]))
<         obj = JSVAL_TO_OBJECT(vp[2]);
<     else if (!js_ValueToObject(cx, vp[2], &obj))
---
>     if (!js_ValueToObject(cx, argv[0], &obj))
1610,1612c1556,1558
<     argc = (uintN)JS_MIN(length, ARRAY_INIT_LIMIT - 1);
<     invokevp = js_AllocStack(cx, 2 + argc, &mark);
<     if (!invokevp)
---
>     argc = (uintN)length;
>     sp = js_AllocStack(cx, 2 + argc, &mark);
>     if (!sp)
1616d1561
<     sp = invokevp;
1626,1672c1571,1579
<     ok = js_Invoke(cx, argc, invokevp, JSINVOKE_INTERNAL);
<     *vp = *invokevp;
< out:
<     js_FreeStack(cx, mark);
<     return ok;
< }
< 
< #ifdef NARCISSUS
< static JSBool
< fun_applyConstructor(JSContext *cx, uintN argc, jsval *vp)
< {
<     JSObject *aobj;
<     uintN length, i;
<     void *mark;
<     jsval *invokevp, *sp;
<     JSBool ok;
< 
<     if (JSVAL_IS_PRIMITIVE(vp[2]) ||
<         (aobj = JSVAL_TO_OBJECT(vp[2]),
<          OBJ_GET_CLASS(cx, aobj) != &js_ArrayClass &&
<          OBJ_GET_CLASS(cx, aobj) != &js_ArgumentsClass)) {
<         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
<                              JSMSG_BAD_APPLY_ARGS, "__applyConstruct__");
<         return JS_FALSE;
<     }
< 
<     if (!js_GetLengthProperty(cx, aobj, &length))
<         return JS_FALSE;
< 
<     if (length >= ARRAY_INIT_LIMIT)
<         length = ARRAY_INIT_LIMIT - 1;
<     invokevp = js_AllocStack(cx, 2 + length, &mark);
<     if (!invokevp)
<         return JS_FALSE;
< 
<     sp = invokevp;
<     *sp++ = vp[1];
<     *sp++ = JSVAL_NULL; /* This is filled automagically. */
<     for (i = 0; i < length; i++) {
<         ok = JS_GetElement(cx, aobj, (jsint)i, sp);
<         if (!ok)
<             goto out;
<         sp++;
<     }
< 
<     ok = js_InvokeConstructor(cx, invokevp, length);
<     *vp = *invokevp;
---
>     /* Lift current frame to include the args and do the call. */
>     fp = cx->fp;
>     oldsp = fp->sp;
>     fp->sp = sp;
>     ok = js_Invoke(cx, argc, JSINVOKE_INTERNAL);
> 
>     /* Store rval and pop stack back to our frame's sp. */
>     *rval = fp->sp[-1];
>     fp->sp = oldsp;
1677c1584
< #endif
---
> #endif /* JS_HAS_APPLY_FUNCTION */
1681c1588,1592
<     JS_FN(js_toSource_str,   fun_toSource,   0,0,0),
---
>     {js_toSource_str,   fun_toSource,   0,0,0},
> #endif
>     {js_toString_str,   fun_toString,   1,0,0},
> #if JS_HAS_APPLY_FUNCTION
>     {"apply",           fun_apply,      2,0,0},
1683,1687c1594,1595
<     JS_FN(js_toString_str,   fun_toString,   0,0,0),
<     JS_FN("apply",           fun_apply,      0,2,0),
<     JS_FN(call_str,          fun_call,       0,1,0),
< #ifdef NARCISSUS
<     JS_FN("__applyConstructor__", fun_applyConstructor, 0,1,0),
---
> #if JS_HAS_CALL_FUNCTION
>     {js_call_str,       fun_call,       1,0,0},
1689c1597
<     JS_FS_END
---
>     {0,0,0,0,0}
1691a1600,1623
> JSBool
> js_IsIdentifier(JSString *str)
> {
>     size_t n;
>     jschar *s, c;
> 
>     n = JSSTRING_LENGTH(str);
>     s = JSSTRING_CHARS(str);
>     c = *s;
>     /*
>      * We don't handle unicode escape sequences here
>      * because they won't be in the input string.
>      * (Right?)
>      */
>     if (n == 0 || !JS_ISIDENT_START(c))
>         return JS_FALSE;
>     for (n--; n != 0; n--) {
>         c = *++s;
>         if (!JS_ISIDENT(c))
>             return JS_FALSE;
>     }
>     return JS_TRUE;
> }
> 
1695d1626
<     JSStackFrame *fp, *caller;
1698c1629
<     uintN i, n, lineno;
---
>     uintN i, n, lineno, dupflag;
1701c1632,1633
<     JSBool ok;
---
>     JSObject *obj2;
>     JSScopeProperty *sprop;
1703c1635,1637
<     JSTokenStream ts;
---
>     JSStackFrame *fp;
>     void *mark;
>     JSTokenStream *ts;
1706,1707c1640
<     void *mark;
<     size_t arg_length, args_length, old_args_length;
---
>     size_t arg_length, args_length;
1708a1642
>     JSBool ok;
1710,1711c1644
<     fp = cx->fp;
<     if (!(fp->flags & JSFRAME_CONSTRUCTING)) {
---
>     if (cx->fp && !(cx->fp->flags & JSFRAME_CONSTRUCTING)) {
1717,1721d1649
< 
<     /*
<      * The constructor is called before the private slot is initialized so we
<      * must use JS_GetPrivate, not GET_FUNCTION_PRIVATE here.
<      */
1725a1654
> #if JS_HAS_CALL_OBJECT
1736a1666,1669
> #else
>     /* Set up for dynamic parenting (see js_Invoke in jsinterp.c). */
>     parent = NULL;
> #endif
1738,1739c1671,1674
<     fun = js_NewFunction(cx, obj, NULL, 0, JSFUN_LAMBDA | JSFUN_INTERPRETED,
<                          parent, cx->runtime->atomState.anonymousAtom);
---
>     fun = js_NewFunction(cx, obj, NULL, 0, JSFUN_LAMBDA, parent,
>                          (JSVERSION_IS_ECMA(cx->version))
>                          ? cx->runtime->atomState.anonymousAtom
>                          : NULL);
1751,1759c1686,1691
<     JS_ASSERT(!fp->script && fp->fun && fp->fun->u.n.native == Function);
<     caller = JS_GetScriptedCaller(cx, fp);
<     if (caller) {
<         principals = JS_EvalFramePrincipals(cx, fp, caller);
<         if (principals == caller->script->principals) {
<             filename = caller->script->filename;
<             lineno = js_PCToLineNumber(cx, caller->script, caller->pc);
<         } else {
<             filename = principals->codebase;
---
>     fp = cx->fp;
>     JS_ASSERT(!fp->script && fp->fun && fp->fun->native == Function);
>     for (;;) {
>         fp = fp->down;
>         if (!fp) {
>             filename = NULL;
1760a1693,1704
>             principals = NULL;
>             break;
>         }
>         if (fp->script) {
>             /*
>              * Load fp->script->* before calling js_PCToLineNumber, to avoid
>              * a pessimal reload of fp->script.
>              */
>             principals = fp->script->principals;
>             filename = fp->script->filename;
>             lineno = js_PCToLineNumber(fp->script, fp->pc);
>             break;
1762,1771d1705
<     } else {
<         filename = NULL;
<         lineno = 0;
<         principals = NULL;
<     }
< 
<     /* Belt-and-braces: check that the caller has access to parent. */
<     if (!js_CheckPrincipalsAccess(cx, parent, principals,
<                                   CLASS_ATOM(cx, Function))) {
<         return JS_FALSE;
1776,1777d1709
<         enum { OK, BAD, BAD_FORMAL } state;
< 
1788d1719
<         state = BAD_FORMAL;
1796,1815c1727
< 
<             /*
<              * Check for overflow.  The < test works because the maximum
<              * JSString length fits in 2 fewer bits than size_t has.
<              */
<             old_args_length = args_length;
<             args_length = old_args_length + JSSTRING_LENGTH(arg);
<             if (args_length < old_args_length) {
<                 JS_ReportOutOfMemory(cx);
<                 return JS_FALSE;
<             }
<         }
< 
<         /* Add 1 for each joining comma and check for overflow (two ways). */
<         old_args_length = args_length;
<         args_length = old_args_length + n - 1;
<         if (args_length < old_args_length ||
<             args_length >= ~(size_t)0 / sizeof(jschar)) {
<             JS_ReportOutOfMemory(cx);
<             return JS_FALSE;
---
>             args_length += JSSTRING_LENGTH(arg);
1816a1729,1730
>         /* Add 1 for each joining comma. */
>         args_length += n - 1;
1826,1827c1740
<         if (!cp) {
<             js_ReportOutOfScriptQuota(cx);
---
>         if (!cp)
1829d1741
<         }
1845,1847c1757,1763
<         /* Initialize a tokenstream that reads from the given string. */
<         if (!js_InitTokenStream(cx, &ts, collected_args, args_length,
<                                 NULL, filename, lineno)) {
---
>         /*
>          * Make a tokenstream (allocated from cx->tempPool) that reads from
>          * the given string.
>          */
>         ts = js_NewTokenStream(cx, collected_args, args_length, filename,
>                                lineno, principals);
>         if (!ts) {
1853c1769
<         tt = js_GetToken(cx, &ts);
---
>         tt = js_GetToken(cx, ts);
1855c1771
<             for (;;) {
---
>             while (1) {
1861c1777
<                     goto after_args;
---
>                     goto bad_formal;
1864,1866c1780,1781
<                  * Get the atom corresponding to the name from the token
<                  * stream; we're assured at this point that it's a valid
<                  * identifier.
---
>                  * Get the atom corresponding to the name from the tokenstream;
>                  * we're assured at this point that it's a valid identifier.
1868,1880c1783,1807
<                 atom = CURRENT_TOKEN(&ts).t_atom;
< 
<                 /* Check for a duplicate parameter name. */
<                 if (js_LookupLocal(cx, fun, atom, NULL) != JSLOCAL_NONE) {
<                     const char *name;
< 
<                     name = js_AtomToPrintableString(cx, atom);
<                     ok = name &&
<                          js_ReportCompileErrorNumber(cx, &ts, NULL,
<                                                      JSREPORT_WARNING |
<                                                      JSREPORT_STRICT,
<                                                      JSMSG_DUPLICATE_FORMAL,
<                                                      name);
---
>                 atom = CURRENT_TOKEN(ts).t_atom;
>                 if (!js_LookupProperty(cx, obj, (jsid)atom, &obj2,
>                                        (JSProperty **)&sprop)) {
>                     goto bad_formal;
>                 }
>                 dupflag = 0;
>                 if (sprop) {
>                     ok = JS_TRUE;
>                     if (obj2 == obj) {
>                         /*
>                          * A duplicate parameter name. We force a duplicate
>                          * node on the SCOPE_LAST_PROP(scope) list with the
>                          * same id, distinguished by the SPROP_IS_DUPLICATE
>                          * flag, and not mapped by an entry in scope.
>                          */
>                         JS_ASSERT(sprop->getter == js_GetArgument);
>                         ok = js_ReportCompileErrorNumber(cx, ts, NULL,
>                                                          JSREPORT_WARNING |
>                                                          JSREPORT_STRICT,
>                                                          JSMSG_DUPLICATE_FORMAL,
>                                                          ATOM_BYTES(atom));
> 
>                         dupflag = SPROP_IS_DUPLICATE;
>                     }
>                     OBJ_DROP_PROPERTY(cx, obj2, (JSProperty *)sprop);
1882c1809,1819
<                         goto after_args;
---
>                         goto bad_formal;
>                     sprop = NULL;
>                 }
>                 if (!js_AddNativeProperty(cx, fun->object, (jsid)atom,
>                                           js_GetArgument, js_SetArgument,
>                                           SPROP_INVALID_SLOT,
>                                           JSPROP_ENUMERATE | JSPROP_PERMANENT |
>                                           JSPROP_SHARED,
>                                           SPROP_HAS_SHORTID | dupflag,
>                                           fun->nargs)) {
>                     goto bad_formal;
1884,1885c1821
<                 if (!js_AddLocal(cx, fun, atom, JSLOCAL_ARG))
<                     goto after_args;
---
>                 fun->nargs++;
1891c1827
<                 tt = js_GetToken(cx, &ts);
---
>                 tt = js_GetToken(cx, ts);
1895,1896c1831,1832
<                     goto after_args;
<                 tt = js_GetToken(cx, &ts);
---
>                     goto bad_formal;
>                 tt = js_GetToken(cx, ts);
1900,1910c1836,1837
<         state = OK;
<       after_args:
<         if (state == BAD_FORMAL && !(ts.flags & TSF_ERROR)) {
<             /*
<              * Report "malformed formal parameter" iff no illegal char or
<              * similar scanner error was already reported.
<              */
<             JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
<                                  JSMSG_BAD_FORMAL);
<         }
<         js_CloseTokenStream(cx, &ts);
---
>         /* Clean up. */
>         ok = js_CloseTokenStream(cx, ts);
1912c1839
<         if (state != OK)
---
>         if (!ok)
1918,1920d1844
<         if (!str)
<             return JS_FALSE;
<         argv[argc-1] = STRING_TO_JSVAL(str);
1922c1846,1863
<         str = cx->runtime->emptyString;
---
>         /* Can't use cx->runtime->emptyString because we're called too early. */
>         str = js_NewStringCopyZ(cx, js_empty_ucstr, 0);
>     }
>     if (!str)
>         return JS_FALSE;
>     if (argv) {
>         /* Use the last arg (or this if argc == 0) as a local GC root. */
>         argv[(intN)(argc-1)] = STRING_TO_JSVAL(str);
>     }
> 
>     mark = JS_ARENA_MARK(&cx->tempPool);
>     ts = js_NewTokenStream(cx, JSSTRING_CHARS(str), JSSTRING_LENGTH(str),
>                            filename, lineno, principals);
>     if (!ts) {
>         ok = JS_FALSE;
>     } else {
>         ok = js_CompileFunctionBody(cx, ts, fun) &&
>              js_CloseTokenStream(cx, ts);
1923a1865,1874
>     JS_ARENA_RELEASE(&cx->tempPool, mark);
>     return ok;
> 
> bad_formal:
>     /*
>      * Report "malformed formal parameter" iff no illegal char or similar
>      * scanner error was already reported.
>      */
>     if (!(ts->flags & TSF_ERROR))
>         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_FORMAL);
1925,1927c1876,1882
<     return js_CompileFunctionBody(cx, fun, principals,
<                                   JSSTRING_CHARS(str), JSSTRING_LENGTH(str),
<                                   filename, lineno);
---
>     /*
>      * Clean up the arguments string and tokenstream if we failed to parse
>      * the arguments.
>      */
>     (void)js_CloseTokenStream(cx, ts);
>     JS_ARENA_RELEASE(&cx->tempPool, mark);
>     return JS_FALSE;
1945c1900
<     fun = js_NewFunction(cx, proto, NULL, 0, JSFUN_INTERPRETED, obj, NULL);
---
>     fun = js_NewFunction(cx, proto, NULL, 0, 0, obj, NULL);
1948,1949c1903,1904
<     fun->u.i.script = js_NewScript(cx, 1, 0, 0, 0, 0, 0);
<     if (!fun->u.i.script)
---
>     fun->script = js_NewScript(cx, 0);
>     if (!fun->script)
1951,1954d1905
<     fun->u.i.script->code[0] = JSOP_STOP;
< #ifdef CHECK_SCRIPT_OWNER
<     fun->u.i.script->owner = NULL;
< #endif
1958c1909
<     cx->weakRoots.newborn[GCX_OBJECT] = NULL;
---
>     cx->newborn[GCX_OBJECT] = NULL;
1961a1913
> #if JS_HAS_CALL_OBJECT
1965,1977c1917,1918
<     JSObject *proto;
< 
<     proto = JS_InitClass(cx, obj, NULL, &js_CallClass, NULL, 0,
<                          NULL, NULL, NULL, NULL);
<     if (!proto)
<         return NULL;
< 
<     /*
<      * Null Call.prototype's proto slot so that Object.prototype.* does not
<      * pollute the scope of heavyweight functions.
<      */
<     OBJ_SET_PROTO(cx, proto, NULL);
<     return proto;
---
>     return JS_InitClass(cx, obj, NULL, &js_CallClass, NULL, 0,
>                         call_props, NULL, NULL, NULL);
1978a1920
> #endif
1985c1927,1932
<     JSTempValueRooter tvr;
---
> 
>     /* Allocate a function struct. */
>     XMEMTAG("js_NewFunction ");
>     fun = (JSFunction *) JS_malloc(cx, sizeof *fun);
>     if (!fun)
>         return NULL;
1992c1939,1940
<         if (!funobj)
---
>         if (!funobj) {
>             JS_free(cx, fun);
1993a1942
>         }
1996,2006d1944
<     /* Protect fun from any potential GC callback. */
<     JS_PUSH_SINGLE_TEMP_ROOT(cx, OBJECT_TO_JSVAL(funobj), &tvr);
< 
<     /*
<      * Allocate fun after allocating funobj so allocations in js_NewObject
<      * and hooks called from it do not wipe out fun from newborn[GCX_FUNCTION].
<      */
<     fun = (JSFunction *) js_NewGCThing(cx, GCX_FUNCTION, sizeof(JSFunction));
<     if (!fun)
<         goto out;
< 
2007a1946
>     fun->nrefs = 0;
2008a1948,1949
>     fun->native = native;
>     fun->script = NULL;
2010,2025c1951,1954
<     fun->flags = flags & (JSFUN_FLAGS_MASK | JSFUN_INTERPRETED);
<     if (flags & JSFUN_INTERPRETED) {
<         JS_ASSERT(!native);
<         JS_ASSERT(nargs == 0);
<         fun->u.i.nvars = 0;
<         fun->u.i.spare = 0;
<         fun->u.i.script = NULL;
< #ifdef DEBUG
<         fun->u.i.names.taggedAtom = 0;
< #endif
<     } else {
<         fun->u.n.native = native;
<         fun->u.n.extra = 0;
<         fun->u.n.minargs = 0;
<         fun->u.n.clasp = NULL;
<     }
---
>     fun->extra = 0;
>     fun->nvars = 0;
>     fun->flags = flags & JSFUN_FLAGS_MASK;
>     fun->spare = 0;
2026a1956
>     fun->clasp = NULL;
2030,2031c1960,1962
<         cx->weakRoots.newborn[GCX_OBJECT] = NULL;
<         fun = NULL;
---
>         cx->newborn[GCX_OBJECT] = NULL;
>         JS_free(cx, fun);
>         return NULL;
2033,2035d1963
< 
< out:
<     JS_POP_TEMP_ROOT(cx, &tvr);
2039,2072d1966
< static void
< TraceLocalNames(JSTracer *trc, JSFunction *fun);
< 
< void
< js_TraceFunction(JSTracer *trc, JSFunction *fun)
< {
<     if (fun->object)
<         JS_CALL_OBJECT_TRACER(trc, fun->object, "object");
<     if (fun->atom)
<         JS_CALL_STRING_TRACER(trc, ATOM_TO_STRING(fun->atom), "atom");
<     if (FUN_INTERPRETED(fun)) {
<         if (fun->u.i.script)
<             js_TraceScript(trc, fun->u.i.script);
<         TraceLocalNames(trc, fun);
<     }
< }
< 
< static void
< DestroyLocalNames(JSContext *cx, JSFunction *fun);
< 
< void
< js_FinalizeFunction(JSContext *cx, JSFunction *fun)
< {
<     /*
<      * Null-check of i.script is required since the parser sets interpreted
<      * very early.
<      */
<     if (FUN_INTERPRETED(fun)) {
<         if (fun->u.i.script)
<             js_DestroyScript(cx, fun->u.i.script);
<         DestroyLocalNames(cx, fun);
<     }
< }
< 
2080c1974
<     newfunobj = js_NewObject(cx, &js_FunctionClass, NULL, parent);
---
>     newfunobj = js_NewObject(cx, &js_FunctionClass, funobj, parent);
2083c1977
<     fun = GET_FUNCTION_PRIVATE(cx, funobj);
---
>     fun = (JSFunction *) JS_GetPrivate(cx, funobj);
2085c1979
<         cx->weakRoots.newborn[GCX_OBJECT] = NULL;
---
>         cx->newborn[GCX_OBJECT] = NULL;
2096c1990,1993
<     return JS_SetPrivate(cx, funobj, fun);
---
>     if (!JS_SetPrivate(cx, funobj, fun))
>         return JS_FALSE;
>     JS_ATOMIC_INCREMENT(&fun->nrefs);
>     return JS_TRUE;
2104d2000
<     JSPropertyOp gsop;
2109,2113c2005,2006
<     gsop = (attrs & JSFUN_STUB_GSOPS) ? JS_PropertyStub : NULL;
<     if (!OBJ_DEFINE_PROPERTY(cx, obj, ATOM_TO_JSID(atom),
<                              OBJECT_TO_JSVAL(fun->object),
<                              gsop, gsop,
<                              attrs & ~JSFUN_FLAGS_MASK, NULL)) {
---
>     if (!OBJ_DEFINE_PROPERTY(cx, obj, (jsid)atom, OBJECT_TO_JSVAL(fun->object),
>                              NULL, NULL, attrs & ~JSFUN_FLAGS_MASK, NULL)) {
2119,2122d2011
< #if (JSV2F_CONSTRUCT & JSV2F_SEARCH_STACK)
< # error "JSINVOKE_CONSTRUCT and JSV2F_SEARCH_STACK are not disjoint!"
< #endif
< 
2124c2013
< js_ValueToFunction(JSContext *cx, jsval *vp, uintN flags)
---
> js_ValueToFunction(JSContext *cx, jsval *vp, JSBool constructing)
2136c2025
<             obj = VALUE_IS_FUNCTION(cx, v) ? JSVAL_TO_OBJECT(v) : NULL;
---
>             obj = JSVAL_IS_FUNCTION(cx, v) ? JSVAL_TO_OBJECT(v) : NULL;
2140c2029
<         js_ReportIsNotFunction(cx, vp, flags);
---
>         js_ReportIsNotFunction(cx, vp, constructing);
2143,2194c2032
<     return GET_FUNCTION_PRIVATE(cx, obj);
< }
< 
< JSObject *
< js_ValueToFunctionObject(JSContext *cx, jsval *vp, uintN flags)
< {
<     JSFunction *fun;
<     JSObject *funobj;
<     JSStackFrame *caller;
<     JSPrincipals *principals;
< 
<     if (VALUE_IS_FUNCTION(cx, *vp))
<         return JSVAL_TO_OBJECT(*vp);
< 
<     fun = js_ValueToFunction(cx, vp, flags);
<     if (!fun)
<         return NULL;
<     funobj = fun->object;
<     *vp = OBJECT_TO_JSVAL(funobj);
< 
<     caller = JS_GetScriptedCaller(cx, cx->fp);
<     if (caller) {
<         principals = JS_StackFramePrincipals(cx, caller);
<     } else {
<         /* No scripted caller, don't allow access. */
<         principals = NULL;
<     }
< 
<     if (!js_CheckPrincipalsAccess(cx, funobj, principals,
<                                   fun->atom
<                                   ? fun->atom
<                                   : cx->runtime->atomState.anonymousAtom)) {
<         return NULL;
<     }
<     return funobj;
< }
< 
< JSObject *
< js_ValueToCallableObject(JSContext *cx, jsval *vp, uintN flags)
< {
<     JSObject *callable;
< 
<     callable = JSVAL_IS_PRIMITIVE(*vp) ? NULL : JSVAL_TO_OBJECT(*vp);
<     if (callable &&
<         ((callable->map->ops == &js_ObjectOps)
<          ? OBJ_GET_CLASS(cx, callable)->call
<          : callable->map->ops->call)) {
<         *vp = OBJECT_TO_JSVAL(callable);
<     } else {
<         callable = js_ValueToFunctionObject(cx, vp, flags);
<     }
<     return callable;
---
>     return (JSFunction *) JS_GetPrivate(cx, obj);
2198c2036
< js_ReportIsNotFunction(JSContext *cx, jsval *vp, uintN flags)
---
> js_ReportIsNotFunction(JSContext *cx, jsval *vp, JSBool constructing)
2199a2038,2039
>     JSType type;
>     JSString *fallback;
2201,2526c2041
<     uintN error;
<     const char *name, *source;
< 
<     for (fp = cx->fp; fp && !fp->spbase; fp = fp->down)
<         continue;
<     name = NULL;
<     source = NULL;
<     if (flags & JSV2F_ITERATOR) {
<         error = JSMSG_BAD_ITERATOR;
<         name = js_iterator_str;
<         source = js_ValueToPrintableSource(cx, *vp);
<         if (!source)
<             return;
<     } else if (flags & JSV2F_CONSTRUCT) {
<         error = JSMSG_NOT_CONSTRUCTOR;
<     } else {
<         error = JSMSG_NOT_FUNCTION;
<     }
< 
<     js_ReportValueError3(cx, error,
<                          (fp && fp->spbase <= vp && vp < fp->sp)
<                          ? vp - fp->sp
<                          : (flags & JSV2F_SEARCH_STACK)
<                          ? JSDVG_SEARCH_STACK
<                          : JSDVG_IGNORE_STACK,
<                          *vp, NULL,
<                          name, source);
< }
< 
< /*
<  * When a function has between 2 and MAX_ARRAY_LOCALS arguments and variables,
<  * their name are stored as the JSLocalNames.array.
<  */
< #define MAX_ARRAY_LOCALS 8
< 
< JS_STATIC_ASSERT(2 <= MAX_ARRAY_LOCALS);
< JS_STATIC_ASSERT(MAX_ARRAY_LOCALS < JS_BITMASK(16));
< 
< /*
<  * We use the lowest bit of the string atom to distinguish const from var
<  * name when there is only single name or when names are stored as an array.
<  */
< JS_STATIC_ASSERT((JSVAL_STRING & 1) == 0);
< 
< /*
<  * When we use a hash table to store the local names, we use a singly linked
<  * list to record the indexes of duplicated parameter names to preserve the
<  * duplicates for the decompiler.
<  */
< typedef struct JSNameIndexPair JSNameIndexPair;
< 
< struct JSNameIndexPair {
<     JSAtom          *name;
<     uint16          index;
<     JSNameIndexPair *link;
< };
< 
< struct JSLocalNameMap {
<     JSDHashTable    names;
<     JSNameIndexPair *lastdup;
< };
< 
< typedef struct JSLocalNameHashEntry {
<     JSDHashEntryHdr hdr;
<     JSAtom          *name;
<     uint16          index;
<     uint8           localKind;
< } JSLocalNameHashEntry;
< 
< static void
< FreeLocalNameHash(JSContext *cx, JSLocalNameMap *map)
< {
<     JSNameIndexPair *dup, *next;
< 
<     for (dup = map->lastdup; dup; dup = next) {
<         next = dup->link;
<         JS_free(cx, dup);
<     }
<     JS_DHashTableFinish(&map->names);
<     JS_free(cx, map);
< }
< 
< static JSBool
< HashLocalName(JSContext *cx, JSLocalNameMap *map, JSAtom *name,
<               JSLocalKind localKind, uintN index)
< {
<     JSLocalNameHashEntry *entry;
<     JSNameIndexPair *dup;
< 
<     JS_ASSERT(index <= JS_BITMASK(16));
< #if JS_HAS_DESTRUCTURING
<     if (!name) {
<         /* A destructuring pattern does not need a hash entry. */
<         JS_ASSERT(localKind == JSLOCAL_ARG);
<         return JS_TRUE;
<     }
< #endif
<     JS_ASSERT(ATOM_IS_STRING(name));
<     entry = (JSLocalNameHashEntry *)
<             JS_DHashTableOperate(&map->names, name, JS_DHASH_ADD);
<     if (!entry) {
<         JS_ReportOutOfMemory(cx);
<         return JS_FALSE;
<     }
<     if (entry->name) {
<         JS_ASSERT(entry->name == name);
<         JS_ASSERT(entry->localKind == JSLOCAL_ARG);
<         dup = (JSNameIndexPair *) JS_malloc(cx, sizeof *dup);
<         if (!dup)
<             return JS_FALSE;
<         dup->name = entry->name;
<         dup->index = entry->index;
<         dup->link = map->lastdup;
<         map->lastdup = dup;
<     }
<     entry->name = name;
<     entry->index = (uint16) index;
<     entry->localKind = (uint8) localKind;
<     return JS_TRUE;
< }
< 
< JSBool
< js_AddLocal(JSContext *cx, JSFunction *fun, JSAtom *atom, JSLocalKind kind)
< {
<     jsuword taggedAtom;
<     uint16 *indexp;
<     uintN n, i;
<     jsuword *array;
<     JSLocalNameMap *map;
< 
<     JS_ASSERT(FUN_INTERPRETED(fun));
<     JS_ASSERT(!fun->u.i.script);
<     JS_ASSERT(((jsuword) atom & 1) == 0);
<     taggedAtom = (jsuword) atom;
<     if (kind == JSLOCAL_ARG) {
<         indexp = &fun->nargs;
<     } else {
<         indexp = &fun->u.i.nvars;
<         if (kind == JSLOCAL_CONST)
<             taggedAtom |= 1;
<         else
<             JS_ASSERT(kind == JSLOCAL_VAR);
<     }
<     n = JS_GET_LOCAL_NAME_COUNT(fun);
<     if (n == 0) {
<         JS_ASSERT(fun->u.i.names.taggedAtom == 0);
<         fun->u.i.names.taggedAtom = taggedAtom;
<     } else if (n < MAX_ARRAY_LOCALS) {
<         if (n > 1) {
<             array = fun->u.i.names.array;
<         } else {
<             array = (jsuword *) JS_malloc(cx, MAX_ARRAY_LOCALS * sizeof *array);
<             if (!array)
<                 return JS_FALSE;
<             array[0] = fun->u.i.names.taggedAtom;
<             fun->u.i.names.array = array;
<         }
<         if (kind == JSLOCAL_ARG) {
<             /*
<              * A destructuring argument pattern adds variables, not arguments,
<              * so for the following arguments nvars != 0.
<              */
< #if JS_HAS_DESTRUCTURING
<             if (fun->u.i.nvars != 0) {
<                 memmove(array + fun->nargs + 1, array + fun->nargs,
<                         fun->u.i.nvars * sizeof *array);
<             }
< #else
<             JS_ASSERT(fun->u.i.nvars == 0);
< #endif
<             array[fun->nargs] = taggedAtom;
<         } else {
<             array[n] = taggedAtom;
<         }
<     } else if (n == MAX_ARRAY_LOCALS) {
<         array = fun->u.i.names.array;
<         map = (JSLocalNameMap *) JS_malloc(cx, sizeof *map);
<         if (!map)
<             return JS_FALSE;
<         if (!JS_DHashTableInit(&map->names, JS_DHashGetStubOps(),
<                                NULL, sizeof(JSLocalNameHashEntry),
<                                JS_DHASH_DEFAULT_CAPACITY(MAX_ARRAY_LOCALS
<                                                          * 2))) {
<             JS_ReportOutOfMemory(cx);
<             JS_free(cx, map);
<             return JS_FALSE;
<         }
< 
<         map->lastdup = NULL;
<         for (i = 0; i != MAX_ARRAY_LOCALS; ++i) {
<             taggedAtom = array[i];
<             if (!HashLocalName(cx, map, (JSAtom *) (taggedAtom & ~1),
<                                (i < fun->nargs)
<                                ? JSLOCAL_ARG
<                                : (taggedAtom & 1) ? JSLOCAL_CONST : JSLOCAL_VAR,
<                                (i < fun->nargs) ? i : i - fun->nargs)) {
<                 FreeLocalNameHash(cx, map);
<                 return JS_FALSE;
<             }
<         }
<         if (!HashLocalName(cx, map, atom, kind, *indexp)) {
<             FreeLocalNameHash(cx, map);
<             return JS_FALSE;
<         }
< 
<         /*
<          * At this point the entry is added and we cannot fail. It is time
<          * to replace fun->u.i.names with the built map.
<          */
<         fun->u.i.names.map = map;
<         JS_free(cx, array);
<     } else {
<         if (*indexp == JS_BITMASK(16)) {
<             JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
<                                  (kind == JSLOCAL_ARG)
<                                  ? JSMSG_TOO_MANY_FUN_ARGS
<                                  : JSMSG_TOO_MANY_FUN_VARS);
<             return JS_FALSE;
<         }
<         if (!HashLocalName(cx, fun->u.i.names.map, atom, kind, *indexp))
<             return JS_FALSE;
<     }
< 
<     /* Update the argument or variable counter. */
<     ++*indexp;
<     return JS_TRUE;
< }
< 
< JSLocalKind
< js_LookupLocal(JSContext *cx, JSFunction *fun, JSAtom *atom, uintN *indexp)
< {
<     uintN n, i;
<     jsuword *array;
<     JSLocalNameHashEntry *entry;
< 
<     JS_ASSERT(FUN_INTERPRETED(fun));
<     n = JS_GET_LOCAL_NAME_COUNT(fun);
<     if (n == 0)
<         return JSLOCAL_NONE;
<     if (n <= MAX_ARRAY_LOCALS) {
<         array = (n == 1) ? &fun->u.i.names.taggedAtom : fun->u.i.names.array;
< 
<         /* Search from the tail to pick up the last duplicated name. */
<         i = n;
<         do {
<             --i;
<             if (atom == JS_LOCAL_NAME_TO_ATOM(array[i])) {
<                 if (i < fun->nargs) {
<                     if (indexp)
<                         *indexp = i;
<                     return JSLOCAL_ARG;
<                 }
<                 if (indexp)
<                     *indexp = i - fun->nargs;
<                 return JS_LOCAL_NAME_IS_CONST(array[i])
<                        ? JSLOCAL_CONST
<                        : JSLOCAL_VAR;
<             }
<         } while (i != 0);
<     } else {
<         entry = (JSLocalNameHashEntry *)
<                 JS_DHashTableOperate(&fun->u.i.names.map->names, atom,
<                                      JS_DHASH_LOOKUP);
<         if (JS_DHASH_ENTRY_IS_BUSY(&entry->hdr)) {
<             JS_ASSERT(entry->localKind != JSLOCAL_NONE);
<             if (indexp)
<                 *indexp = entry->index;
<             return (JSLocalKind) entry->localKind;
<         }
<     }
<     return JSLOCAL_NONE;
< }
< 
< typedef struct JSLocalNameEnumeratorArgs {
<     JSFunction      *fun;
<     jsuword         *names;
< #ifdef DEBUG
<     uintN           nCopiedArgs;
<     uintN           nCopiedVars;
< #endif
< } JSLocalNameEnumeratorArgs;
< 
< JS_STATIC_DLL_CALLBACK(JSDHashOperator)
< get_local_names_enumerator(JSDHashTable *table, JSDHashEntryHdr *hdr,
<                            uint32 number, void *arg)
< {
<     JSLocalNameHashEntry *entry;
<     JSLocalNameEnumeratorArgs *args;
<     uint i;
<     jsuword constFlag;
< 
<     entry = (JSLocalNameHashEntry *) hdr;
<     args = (JSLocalNameEnumeratorArgs *) arg;
<     JS_ASSERT(entry->name);
<     if (entry->localKind == JSLOCAL_ARG) {
<         JS_ASSERT(entry->index < args->fun->nargs);
<         JS_ASSERT(args->nCopiedArgs++ < args->fun->nargs);
<         i = entry->index;
<         constFlag = 0;
<     } else {
<         JS_ASSERT(entry->localKind == JSLOCAL_VAR ||
<                   entry->localKind == JSLOCAL_CONST);
<         JS_ASSERT(entry->index < args->fun->u.i.nvars);
<         JS_ASSERT(args->nCopiedVars++ < args->fun->u.i.nvars);
<         i = args->fun->nargs + entry->index;
<         constFlag = (entry->localKind == JSLOCAL_CONST);
<     }
<     args->names[i] = (jsuword) entry->name | constFlag;
<     return JS_DHASH_NEXT;
< }
< 
< jsuword *
< js_GetLocalNameArray(JSContext *cx, JSFunction *fun, JSArenaPool *pool)
< {
<     uintN n;
<     jsuword *names;
<     JSLocalNameMap *map;
<     JSLocalNameEnumeratorArgs args;
<     JSNameIndexPair *dup;
< 
<     JS_ASSERT(FUN_INTERPRETED(fun));
<     n = JS_GET_LOCAL_NAME_COUNT(fun);
<     JS_ASSERT(n != 0);
< 
<     if (n <= MAX_ARRAY_LOCALS)
<         return (n == 1) ? &fun->u.i.names.taggedAtom : fun->u.i.names.array;
---
>     JSString *str;
2529,2530c2044,2047
<      * No need to check for overflow of the allocation size as we are making a
<      * copy of already allocated data. As such it must fit size_t.
---
>      * We provide the typename as the fallback to handle the case when
>      * valueOf is not a function, which prevents ValueToString from being
>      * called as the default case inside js_DecompileValueGenerator (and
>      * so recursing back to here).
2532,2643c2049,2058
<     JS_ARENA_ALLOCATE_CAST(names, jsuword *, pool, (size_t) n * sizeof *names);
<     if (!names) {
<         js_ReportOutOfScriptQuota(cx);
<         return NULL;
<     }
< 
< #if JS_HAS_DESTRUCTURING
<     /* Some parameter names can be NULL due to destructuring patterns. */
<     memset(names, 0, fun->nargs * sizeof *names);
< #endif
<     map = fun->u.i.names.map;
<     args.fun = fun;
<     args.names = names;
< #ifdef DEBUG
<     args.nCopiedArgs = 0;
<     args.nCopiedVars = 0;
< #endif
<     JS_DHashTableEnumerate(&map->names, get_local_names_enumerator, &args);
<     for (dup = map->lastdup; dup; dup = dup->link) {
<         JS_ASSERT(dup->index < fun->nargs);
<         JS_ASSERT(args.nCopiedArgs++ < fun->nargs);
<         names[dup->index] = (jsuword) dup->name;
<     }
< #if !JS_HAS_DESTRUCTURING
<     JS_ASSERT(args.nCopiedArgs == fun->nargs);
< #endif
<     JS_ASSERT(args.nCopiedVars == fun->u.i.nvars);
< 
<     return names;
< }
< 
< JS_STATIC_DLL_CALLBACK(JSDHashOperator)
< trace_local_names_enumerator(JSDHashTable *table, JSDHashEntryHdr *hdr,
<                              uint32 number, void *arg)
< {
<     JSLocalNameHashEntry *entry;
<     JSTracer *trc;
< 
<     entry = (JSLocalNameHashEntry *) hdr;
<     JS_ASSERT(entry->name);
<     trc = (JSTracer *) arg;
<     JS_SET_TRACING_INDEX(trc,
<                          entry->localKind == JSLOCAL_ARG ? "arg" : "var",
<                          entry->index);
<     JS_CallTracer(trc, ATOM_TO_STRING(entry->name), JSTRACE_STRING);
<     return JS_DHASH_NEXT;
< }
< 
< static void
< TraceLocalNames(JSTracer *trc, JSFunction *fun)
< {
<     uintN n, i;
<     JSAtom *atom;
<     jsuword *array;
< 
<     JS_ASSERT(FUN_INTERPRETED(fun));
<     n = JS_GET_LOCAL_NAME_COUNT(fun);
<     if (n == 0)
<         return;
<     if (n <= MAX_ARRAY_LOCALS) {
<         array = (n == 1) ? &fun->u.i.names.taggedAtom : fun->u.i.names.array;
<         i = n;
<         do {
<             --i;
<             atom = (JSAtom *) (array[i] & ~1);
<             if (atom) {
<                 JS_SET_TRACING_INDEX(trc,
<                                      i < fun->nargs ? "arg" : "var",
<                                      i < fun->nargs ? i : i - fun->nargs);
<                 JS_CallTracer(trc, ATOM_TO_STRING(atom), JSTRACE_STRING);
<             }
<         } while (i != 0);
<     } else {
<         JS_DHashTableEnumerate(&fun->u.i.names.map->names,
<                                trace_local_names_enumerator, trc);
< 
<         /*
<          * No need to trace the list of duplicates in map->lastdup as the
<          * names there are traced when enumerating the hash table.
<          */
<     }
< }
< 
< void
< DestroyLocalNames(JSContext *cx, JSFunction *fun)
< {
<     uintN n;
< 
<     n = fun->nargs + fun->u.i.nvars;
<     if (n <= 1)
<         return;
<     if (n <= MAX_ARRAY_LOCALS)
<         JS_free(cx, fun->u.i.names.array);
<     else
<         FreeLocalNameHash(cx, fun->u.i.names.map);
< }
< 
< void
< js_FreezeLocalNames(JSContext *cx, JSFunction *fun)
< {
<     uintN n;
<     jsuword *array;
< 
<     JS_ASSERT(FUN_INTERPRETED(fun));
<     JS_ASSERT(!fun->u.i.script);
<     n = fun->nargs + fun->u.i.nvars;
<     if (2 <= n && n < MAX_ARRAY_LOCALS) {
<         /* Shrink over-allocated array ignoring realloc failures. */
<         array = (jsuword *) JS_realloc(cx, fun->u.i.names.array,
<                                        n * sizeof *array);
<         if (array)
<             fun->u.i.names.array = array;
---
>     type = JS_TypeOfValue(cx, *vp);
>     fallback = ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[type]);
>     fp = cx->fp;
>     str = js_DecompileValueGenerator(cx, fp ? vp - fp->sp : JSDVG_IGNORE_STACK,
>                                      *vp, fallback);
>     if (str) {
>         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
>                              (uintN)(constructing ? JSMSG_NOT_CONSTRUCTOR
>                                                   : JSMSG_NOT_FUNCTION),
>                              JS_GetStringBytes(str));
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsfun.h /Volumes/Swap/js_D11/src/jsfun.h
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,22c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
26,38c23,33
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
50,64d44
< typedef struct JSLocalNameMap JSLocalNameMap;
< 
< /*
<  * Depending on the number of arguments and variables in the function their
<  * names and attributes are stored either as a single atom or as an array of
<  * tagged atoms (when there are few locals) or as a hash-based map (when there
<  * are many locals). In the first 2 cases the lowest bit of the atom is used
<  * as a tag to distinguish const from var. See jsfun.c for details.
<  */
< typedef union JSLocalNames {
<     jsuword         taggedAtom;
<     jsuword         *array;
<     JSLocalNameMap  *map;
< } JSLocalNames;
< 
66,85c46,57
<     JSObject        *object;    /* back-pointer to GC'ed object header */
<     uint16          nargs;      /* maximum number of specified arguments,
<                                    reflected as f.length/f.arity */
<     uint16          flags;      /* bound method and other flags, see jsapi.h */
<     union {
<         struct {
<             uint16      extra;  /* number of arg slots for local GC roots */
<             uint16      minargs;/* minimum number of specified arguments, used
<                                    only when calling fast native */
<             JSNative    native; /* native method pointer or null */
<             JSClass     *clasp; /* if non-null, constructor for this class */
<         } n;
<         struct {
<             uint16      nvars;  /* number of local variables */
<             uint16      spare;  /* reserved for future use */
<             JSScript    *script;/* interpreted bytecode descriptor or null */
<             JSLocalNames names; /* argument and variable names */
<         } i;
<     } u;
<     JSAtom          *atom;      /* name for diagnostics and decompiling */
---
>     jsrefcount	 nrefs;		/* number of referencing objects */
>     JSObject     *object;       /* back-pointer to GC'ed object header */
>     JSNative     native;        /* native method pointer or null */
>     JSScript     *script;       /* interpreted bytecode descriptor or null */
>     uint16       nargs;         /* minimum number of actual arguments */
>     uint16       extra;         /* number of arg slots for local GC roots */
>     uint16       nvars;         /* number of local variables */
>     uint8        flags;         /* bound method and other flags, see jsapi.h */
>     uint8        spare;         /* reserved for future use */
>     JSAtom       *atom;         /* name for diagnostics and decompiling */
>     JSClass      *clasp;        /* if non-null, constructor for this class */
>     long		refCon;			// !!DP 2004.01.22 jht: For Lingo symbol + flags
88,103d59
< #define JSFUN_EXPR_CLOSURE   0x4000 /* expression closure: function(x)x*x */
< #define JSFUN_INTERPRETED    0x8000 /* use u.i if set, u.n if unset */
< 
< #define JSFUN_SCRIPT_OR_FAST_NATIVE (JSFUN_INTERPRETED | JSFUN_FAST_NATIVE)
< 
< #define FUN_INTERPRETED(fun) ((fun)->flags & JSFUN_INTERPRETED)
< #define FUN_SLOW_NATIVE(fun) (!((fun)->flags & JSFUN_SCRIPT_OR_FAST_NATIVE))
< #define FUN_SCRIPT(fun)      (FUN_INTERPRETED(fun) ? (fun)->u.i.script : NULL)
< #define FUN_NATIVE(fun)      (FUN_SLOW_NATIVE(fun) ? (fun)->u.n.native : NULL)
< #define FUN_FAST_NATIVE(fun) (((fun)->flags & JSFUN_FAST_NATIVE)              \
<                               ? (JSFastNative) (fun)->u.n.native              \
<                               : NULL)
< #define FUN_MINARGS(fun)     (((fun)->flags & JSFUN_FAST_NATIVE)              \
<                               ? (fun)->u.n.minargs                            \
<                               : (fun)->nargs)
< 
105c61
< extern JS_FRIEND_DATA(JSClass) js_CallClass;
---
> extern JSClass js_CallClass;
107c63
< /* JS_FRIEND_DATA so that VALUE_IS_FUNCTION is callable from the shell. */
---
> /* JS_FRIEND_DATA so that JSVAL_IS_FUNCTION is callable from outside */
113,114c69,70
< #define VALUE_IS_FUNCTION(cx, v)                                              \
<     (!JSVAL_IS_PRIMITIVE(v) &&                                                \
---
> #define JSVAL_IS_FUNCTION(cx, v)                                              \
>     (JSVAL_IS_OBJECT(v) && JSVAL_TO_OBJECT(v) &&                              \
117,123c73,78
< /*
<  * Macro to access the private slot of the function object after the slot is
<  * initialized.
<  */
< #define GET_FUNCTION_PRIVATE(cx, funobj)                                      \
<     (JS_ASSERT(OBJ_GET_CLASS(cx, funobj) == &js_FunctionClass),               \
<      (JSFunction *) OBJ_GET_PRIVATE(cx, funobj))
---
> extern JSBool
> js_fun_toString(JSContext *cx, JSObject *obj, uint32 indent,
>                 uintN argc, jsval *argv, jsval *rval);
> 
> extern JSBool
> js_IsIdentifier(JSString *str);
136,142c91
<                uintN flags, JSObject *parent, JSAtom *atom);
< 
< extern void
< js_TraceFunction(JSTracer *trc, JSFunction *fun);
< 
< extern void
< js_FinalizeFunction(JSContext *cx, JSFunction *fun);
---
> 	       uintN flags, JSObject *parent, JSAtom *atom);
152,161c101
<                   uintN nargs, uintN flags);
< 
< /*
<  * Flags for js_ValueToFunction and js_ReportIsNotFunction.  We depend on the
<  * fact that JSINVOKE_CONSTRUCT (aka JSFRAME_CONSTRUCTING) is 1, and test that
<  * with #if/#error in jsfun.c.
<  */
< #define JSV2F_CONSTRUCT         JSINVOKE_CONSTRUCT
< #define JSV2F_ITERATOR          JSINVOKE_ITERATOR
< #define JSV2F_SEARCH_STACK      0x10000
---
> 		  uintN nargs, uintN flags);
164,170c104
< js_ValueToFunction(JSContext *cx, jsval *vp, uintN flags);
< 
< extern JSObject *
< js_ValueToFunctionObject(JSContext *cx, jsval *vp, uintN flags);
< 
< extern JSObject *
< js_ValueToCallableObject(JSContext *cx, jsval *vp, uintN flags);
---
> js_ValueToFunction(JSContext *cx, jsval *vp, JSBool constructing);
173c107
< js_ReportIsNotFunction(JSContext *cx, jsval *vp, uintN flags);
---
> js_ReportIsNotFunction(JSContext *cx, jsval *vp, JSBool constructing);
178c112
< extern JS_FRIEND_API(JSBool)
---
> extern JSBool
191c125,126
< js_GetArgsProperty(JSContext *cx, JSStackFrame *fp, jsid id, jsval *vp);
---
> js_GetArgsProperty(JSContext *cx, JSStackFrame *fp, jsid id,
>                    JSObject **objp, jsval *vp);
196c131
< extern JS_FRIEND_API(JSBool)
---
> extern JSBool
202,248d136
< typedef enum JSLocalKind {
<     JSLOCAL_NONE,
<     JSLOCAL_ARG,
<     JSLOCAL_VAR,
<     JSLOCAL_CONST
< } JSLocalKind;
< 
< #define JS_GET_LOCAL_NAME_COUNT(fun)    ((fun)->nargs + (fun)->u.i.nvars)
< 
< extern JSBool
< js_AddLocal(JSContext *cx, JSFunction *fun, JSAtom *atom, JSLocalKind kind);
< 
< /*
<  * Look up an argument or variable name returning its kind when found or
<  * JSLOCAL_NONE when no such name exists. When indexp is not null and the name
<  * exists, *indexp will receive the index of the corresponding argument or
<  * variable.
<  */
< extern JSLocalKind
< js_LookupLocal(JSContext *cx, JSFunction *fun, JSAtom *atom, uintN *indexp);
< 
< /*
<  * Functions to work with local names as an array of words.
<  *
<  * js_GetLocalNameArray returns the array or null when it cannot be allocated
<  * The function must be called only when JS_GET_LOCAL_NAME_COUNT(fun) is not
<  * zero. The function use the supplied pool to allocate the array.
<  *
<  * The elements of the array with index below fun->nargs correspond to the
<  * names of function arguments and of function variables otherwise. Use
<  * JS_LOCAL_NAME_TO_ATOM to convert array's element into an atom. It can be
<  * null when the element is an argument corresponding to a destructuring
<  * pattern. For a variable use JS_LOCAL_NAME_IS_CONST to check if it
<  * corresponds to the const declaration.
<  */
< extern jsuword *
< js_GetLocalNameArray(JSContext *cx, JSFunction *fun, JSArenaPool *pool);
< 
< #define JS_LOCAL_NAME_TO_ATOM(nameWord)                                       \
<     ((JSAtom *) ((nameWord) & ~(jsuword) 1))
< 
< #define JS_LOCAL_NAME_IS_CONST(nameWord)                                      \
<     ((((nameWord) & (jsuword) 1)) != 0)
< 
< extern void
< js_FreezeLocalNames(JSContext *cx, JSFunction *fun);
< 
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsgc.c /Volumes/Swap/js_D11/src/jsgc.c
2d1
<  * vim: set ts=8 sw=4 et tw=78:
4,5c3,6
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
7,15c8,11
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
20,23c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
27,39c23,33
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
44,46c38,40
<  * This GC allocates fixed-sized things with sizes up to GC_NBYTES_MAX (see
<  * jsgc.h). It allocates from a special GC arena pool with each arena allocated
<  * using malloc. It uses an ideally parallel array of flag bytes to hold the
---
>  * This GC allocates only fixed-sized things big enough to contain two words
>  * (pointers) on any host architecture.  It allocates from an arena pool (see
>  * jsarena.h).  It uses an ideally parallel array of flag bytes to hold the
52,53c46,47
< #include <stdlib.h>     /* for free */
< #include <string.h>     /* for memset used when DEBUG */
---
> #include "xstdlib.h"     /* for free, called by JS_ARENA_DESTROY */
> #include <string.h>     /* for memset, called by jsarena.h macros if DEBUG */
54a49
> #include "jsarena.h" /* Added by JSIFY */
59,60d53
< #include "jsbit.h"
< #include "jsclist.h"
63,64d55
< #include "jsdbgapi.h"
< #include "jsexn.h"
68d58
< #include "jsiter.h"
72d61
< #include "jsparse.h"
77,79c66,67
< #if JS_HAS_XML_SUPPORT
< #include "jsxml.h"
< #endif
---
> 
> //#include "_optimize.h"
82c70,76
<  * Deduce if mmap or similar is available.
---
>  * GC arena sizing depends on amortizing arena overhead using a large number
>  * of things per arena, and on the thing/flags ratio of 8:1 on most platforms.
>  *
>  * On 64-bit platforms, we would have half as many things per arena because
>  * pointers are twice as big, so we double the bytes for things per arena.
>  * This preserves the 1024 byte flags sub-arena size, which relates to the
>  * GC_PAGE_SIZE (see below for why).
84,110c78,81
< #ifndef JS_GC_USE_MMAP
< # if defined(XP_WIN)
< #  define JS_GC_USE_MMAP 1
< # elif defined(XP_UNIX) || defined(XP_BEOS)
< #  include <unistd.h>
< #  if defined(_POSIX_MAPPED_FILES) && _POSIX_MAPPED_FILES > 0
< #   define JS_GC_USE_MMAP 1
< #  endif
< # endif
< #endif
< 
< #ifndef JS_GC_USE_MMAP
< # define JS_GC_USE_MMAP 0
< #endif
< 
< #if JS_GC_USE_MMAP
< # if defined(XP_WIN)
< #  include <windows.h>
< # elif defined(XP_UNIX) || defined(XP_BEOS)
< #  include <sys/mman.h>
< 
< /* On Mac OS X MAP_ANONYMOUS is not defined. */
< #  if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
< #   define MAP_ANONYMOUS MAP_ANON
< #  endif
< 
< # endif
---
> #if JS_BYTES_PER_WORD == 8
> # define GC_THINGS_SHIFT 14     /* 16KB for things on Alpha, etc. */
> #else
> # define GC_THINGS_SHIFT 13     /* 8KB for things on most platforms */
111a83,93
> #define GC_THINGS_SIZE  JS_BIT(GC_THINGS_SHIFT)
> #define GC_FLAGS_SIZE   (GC_THINGS_SIZE / sizeof(JSGCThing))
> #define GC_ARENA_SIZE   (GC_THINGS_SIZE + GC_FLAGS_SIZE)
> 
> /*
>  * The private JSGCThing struct, which describes a gcFreeList element.
>  */
> struct JSGCThing {
>     JSGCThing   *next;
>     uint8       *flagp;
> };
117,119c99,104
<  * To implement this, we allocate things of the same size from a GC arena
<  * containing GC_ARENA_SIZE bytes aligned on GC_ARENA_SIZE boundary. The
<  * following picture shows arena's layout:
---
>  * To implement this, we take advantage of the thing/flags numerology: given
>  * the 8K bytes worth of GC-things, there are 1K flag bytes.  We mask a thing's
>  * address with ~1023 to find a JSGCPageInfo record at the front of a mythical
>  * "GC page" within the larger 8K thing arena.  That JSGCPageInfo contains a
>  * pointer to the 128 flag bytes corresponding to the things in the page, so we
>  * index into this flags array using the thing's index within its page.
121,123c106,113
<  *  +------------------------------+--------------------+---------------+
<  *  | allocation area for GC thing | flags of GC things | JSGCArenaInfo |
<  *  +------------------------------+--------------------+---------------+
---
>  * To align thing pages on 1024-byte boundaries, we must allocate the 9KB of
>  * flags+things arena payload, then find the first 0 mod 1024 boundary after
>  * the first payload address.  That's where things start, with a JSGCPageInfo
>  * taking up the first thing-slot, as usual for 0 mod 1024 byte boundaries.
>  * The effect of this alignment trick is to split the flags into at most 2
>  * discontiguous spans, one before the things and one after (if we're really
>  * lucky, and the arena payload starts on a 0 mod 1024 byte boundary, no need
>  * to split).
125,127c115,116
<  * For a GC thing of size thingSize the number of things that the arena can
<  * hold is given by:
<  *   (GC_ARENA_SIZE - sizeof(JSGCArenaInfo)) / (thingSize + 1)
---
>  * The overhead of this scheme for most platforms is (16+8*(8+1))/(16+9K) or
>  * .95% (assuming 16 byte JSArena header size, and 8 byte JSGCThing size).
129,137c118
<  * The address of thing's flag is given by:
<  *   flagByteAddress =
<  *       (thingAddress | GC_ARENA_MASK) - sizeof(JSGCArenaInfo) -
<  *       (thingAddress & GC_ARENA_MASK) / thingSize
<  * where
<  *   (thingAddress | GC_ARENA_MASK) - sizeof(JSGCArenaInfo)
<  * is the last byte of flags' area and
<  *   (thingAddress & GC_ARENA_MASK) / thingSize
<  * is thing's index counting from arena's start.
---
>  * Here's some ASCII art showing an arena:
139,141c120,128
<  * Things are allocated from the start of their area and flags are allocated
<  * from the end of their area. This avoids calculating the location of the
<  * boundary separating things and flags.
---
>  *   split
>  *     |
>  *     V
>  *  +--+-------+-------+-------+-------+-------+-------+-------+-------+-----+
>  *  |fB|  tp0  |  tp1  |  tp2  |  tp3  |  tp4  |  tp5  |  tp6  |  tp7  | fA  |
>  *  +--+-------+-------+-------+-------+-------+-------+-------+-------+-----+
>  *              ^                                 ^
>  *  tI ---------+                                 |
>  *  tJ -------------------------------------------+
143,150c130,133
<  * JS_GC_USE_MMAP macros governs the allocation of aligned arenas. When the
<  * macro is true, a platform specific allocation code like POSIX mmap is used
<  * with no extra overhead. If the macro is false, the code uses malloc to
<  * allocate a chunk of
<  *   GC_ARENA_SIZE * (js_gcArenasPerChunk + 1)
<  * bytes. The chunk contains at least js_gcArenasPerChunk aligned arenas so
<  * the overhead of this schema is approximately 1/js_gcArenasPerChunk. See
<  * NewGCChunk/DestroyGCChunk below for details.
---
>  *  - fB are the "before split" flags, fA are the "after split" flags
>  *  - tp0-tp7 are the 8 thing pages
>  *  - thing tI points into tp1, whose flags are below the split, in fB
>  *  - thing tJ points into tp5, clearly above the split
152,226c135,142
<  * Note that even when JS_GC_USE_MMAP is true the code still allocates arenas
<  * in chunks to minimize the overhead of mmap/munmap.
<  */
< 
< /*
<  * When mmap is available, use the minimal known CPU page size as the size of
<  * GC arena. Otherwise use 1K arenas to minimize the overhead of the aligned
<  * allocation.
<  */
< #if JS_GC_USE_MMAP
< # define GC_ARENA_SHIFT              12
< #else
< # define GC_ARENA_SHIFT              10
< #endif
< 
< #define GC_ARENA_MASK               ((jsuword) JS_BITMASK(GC_ARENA_SHIFT))
< #define GC_ARENA_SIZE               JS_BIT(GC_ARENA_SHIFT)
< 
< struct JSGCArenaInfo {
<     /*
<      * Allocation list for the arena.
<      */
<     JSGCArenaList   *list;
< 
<     /*
<      * Pointer to the previous arena in a linked list. The arena can either
<      * belong to one of JSContext.gcArenaList lists or, when it does not have
<      * any allocated GC things, to the list of free arenas in the chunk with
<      * head stored in JSGCChunkInfo.lastFreeArena.
<      */
<     JSGCArenaInfo   *prev;
< 
<     /*
<      * A link field for the list of arenas with marked but not yet traced
<      * things. The field is encoded as arena's page to share the space with
<      * firstArena and arenaIndex fields.
<      */
<     jsuword         prevUntracedPage :  JS_BITS_PER_WORD - GC_ARENA_SHIFT;
< 
<     /*
<      * When firstArena is false, the index of arena in the chunk. When
<      * firstArena is true, the index of a free arena holding JSGCChunkInfo or
<      * NO_FREE_ARENAS if there are no free arenas in the chunk.
<      *
<      * GET_ARENA_INDEX and GET_CHUNK_INFO_INDEX are convenience macros to
<      * access either of indexes.
<      */
<     jsuword         arenaIndex :        GC_ARENA_SHIFT - 1;
< 
<     /*
<      * Flag indicating if the arena is the first in the chunk.
<      */
<     jsuword         firstArena :        1;
< 
<     /*
<      * Bitset for fast search of marked but not yet traced things.
<      */
<     jsuword         untracedThings;
< };
< 
< /*
<  * Verify that the bit fields are indeed shared and JSGCArenaInfo is as small
<  * as possible. The code does not rely on this check so if on a particular
<  * platform this does not compile, then, as a workaround, comment the assert
<  * out and submit a bug report.
<  */
< JS_STATIC_ASSERT(sizeof(JSGCArenaInfo) == 4 * sizeof(jsuword));
< 
< #define NO_FREE_ARENAS              JS_BITMASK(GC_ARENA_SHIFT - 1)
< 
< /*
<  * All chunks that have at least one free arena are put on the doubly-linked
<  * list with the head stored in JSRuntime.gcChunkList. JSGCChunkInfo contains
<  * the head of the chunk's free arena list together with the link fields for
<  * gcChunkList.
---
>  * In general, one of the thing pages will have some of its things' flags on
>  * the low side of the split, and the rest of its things' flags on the high
>  * side.  All the other pages have flags only below or only above.  Therefore
>  * we'll have to test something to decide whether the split divides flags in
>  * a given thing's page.  So we store the split pointer (the pointer to tp0)
>  * in each JSGCPageInfo, along with the flags pointer for the 128 flag bytes
>  * ideally starting, for tp0 things, at the beginning of the arena's payload
>  * (at the start of fB).
228,346c144,149
<  * The structure is stored in one of chunk's free arenas. GET_CHUNK_INFO_INDEX
<  * macro gives the index of this arena. When all arenas in the chunk are used,
<  * it is removed from the list and the index is set to NO_FREE_ARENAS
<  * indicating that the chunk is not on gcChunkList and has no JSGCChunkInfo
<  * available.
<  */
< struct JSGCChunkInfo {
<     JSGCChunkInfo   **prevp;
<     JSGCChunkInfo   *next;
<     JSGCArenaInfo   *lastFreeArena;
<     uint32          numFreeArenas;
< };
< 
< /*
<  * Even when mmap is available, its overhead may be too big so the final
<  * decision to use it is done at runtime.
<  */
< #if JS_GC_USE_MMAP
< static uint32 js_gcArenasPerChunk = 0;
< static JSBool js_gcUseMmap = JS_FALSE;
< #else
< # define js_gcArenasPerChunk 31
< #endif
< 
< /*
<  * Macros to convert between JSGCArenaInfo, the start address of the arena and
<  * arena's page defined as (start address) >> GC_ARENA_SHIFT.
<  */
< #define ARENA_INFO_OFFSET (GC_ARENA_SIZE - (uint32) sizeof(JSGCArenaInfo))
< 
< #define IS_ARENA_INFO_ADDRESS(arena)                                          \
<     (((jsuword) (arena) & GC_ARENA_MASK) == ARENA_INFO_OFFSET)
< 
< #define ARENA_START_TO_INFO(arenaStart)                                       \
<     (JS_ASSERT(((arenaStart) & (jsuword) GC_ARENA_MASK) == 0),                \
<      (JSGCArenaInfo *) ((arenaStart) + (jsuword) ARENA_INFO_OFFSET))
< 
< #define ARENA_INFO_TO_START(arena)                                            \
<     (JS_ASSERT(IS_ARENA_INFO_ADDRESS(arena)),                                 \
<      (jsuword) (arena) & ~(jsuword) GC_ARENA_MASK)
< 
< #define ARENA_PAGE_TO_INFO(arenaPage)                                         \
<     (JS_ASSERT(arenaPage != 0),                                               \
<      JS_ASSERT(!((jsuword)(arenaPage) >> (JS_BITS_PER_WORD-GC_ARENA_SHIFT))), \
<      ARENA_START_TO_INFO((arenaPage) << GC_ARENA_SHIFT))
< 
< #define ARENA_INFO_TO_PAGE(arena)                                             \
<     (JS_ASSERT(IS_ARENA_INFO_ADDRESS(arena)),                                 \
<      ((jsuword) (arena) >> GC_ARENA_SHIFT))
< 
< #define GET_ARENA_INFO(chunk, index)                                          \
<     (JS_ASSERT((index) < js_gcArenasPerChunk),                                \
<      ARENA_START_TO_INFO(chunk + ((index) << GC_ARENA_SHIFT)))
< 
< /*
<  * Macros to access/modify information about the chunk of GC arenas.
<  */
< #define GET_ARENA_CHUNK(arena, index)                                         \
<     (JS_ASSERT(GET_ARENA_INDEX(arena) == index),                              \
<      ARENA_INFO_TO_START(arena) - ((index) << GC_ARENA_SHIFT))
< 
< #define GET_ARENA_INDEX(arena)                                                \
<     ((arena)->firstArena ? 0 : (uint32) (arena)->arenaIndex)
< 
< #define GET_CHUNK_INFO_INDEX(chunk)                                           \
<     ((uint32) ARENA_START_TO_INFO(chunk)->arenaIndex)
< 
< #define SET_CHUNK_INFO_INDEX(chunk, index)                                    \
<     (JS_ASSERT((index) < js_gcArenasPerChunk || (index) == NO_FREE_ARENAS),   \
<      (void) (ARENA_START_TO_INFO(chunk)->arenaIndex = (jsuword) (index)))
< 
< #define GET_CHUNK_INFO(chunk, infoIndex)                                      \
<     (JS_ASSERT(GET_CHUNK_INFO_INDEX(chunk) == (infoIndex)),                   \
<      JS_ASSERT((uint32) (infoIndex) < js_gcArenasPerChunk),                   \
<      (JSGCChunkInfo *) ((chunk) + ((infoIndex) << GC_ARENA_SHIFT)))
< 
< #define CHUNK_INFO_TO_INDEX(ci)                                               \
<     GET_ARENA_INDEX(ARENA_START_TO_INFO((jsuword)ci))
< 
< /*
<  * Macros for GC-thing operations.
<  */
< #define THINGS_PER_ARENA(thingSize)                                           \
<     ((GC_ARENA_SIZE - (uint32) sizeof(JSGCArenaInfo)) / ((thingSize) + 1U))
< 
< #define THING_TO_ARENA(thing)                                                 \
<     ((JSGCArenaInfo *)(((jsuword) (thing) | GC_ARENA_MASK) +                  \
<                        1 - sizeof(JSGCArenaInfo)))
< 
< #define THING_TO_INDEX(thing, thingSize)                                      \
<     ((uint32) ((jsuword) (thing) & GC_ARENA_MASK) / (uint32) (thingSize))
< 
< #define THING_FLAGS_END(arena) ((uint8 *)(arena))
< 
< #define THING_FLAGP(arena, thingIndex)                                        \
<     (JS_ASSERT((jsuword) (thingIndex)                                         \
<                < (jsuword) THINGS_PER_ARENA((arena)->list->thingSize)),       \
<      (uint8 *)(arena) - 1 - (thingIndex))
< 
< #define THING_TO_FLAGP(thing, thingSize)                                      \
<     THING_FLAGP(THING_TO_ARENA(thing), THING_TO_INDEX(thing, thingSize))
< 
< #define FLAGP_TO_ARENA(flagp) THING_TO_ARENA(flagp)
< 
< #define FLAGP_TO_INDEX(flagp)                                                 \
<     (JS_ASSERT(((jsuword) (flagp) & GC_ARENA_MASK) < ARENA_INFO_OFFSET),      \
<      (ARENA_INFO_OFFSET - 1 - (uint32) ((jsuword) (flagp) & GC_ARENA_MASK)))
< 
< #define FLAGP_TO_THING(flagp, thingSize)                                      \
<     (JS_ASSERT(((jsuword) (flagp) & GC_ARENA_MASK) >=                         \
<                (ARENA_INFO_OFFSET - THINGS_PER_ARENA(thingSize))),            \
<      (JSGCThing *)(((jsuword) (flagp) & ~GC_ARENA_MASK) +                     \
<                    (thingSize) * FLAGP_TO_INDEX(flagp)))
< 
< #ifdef JS_THREADSAFE
< /*
<  * The maximum number of things to put on the local free list by taking
<  * several things from the global free list or from the tail of the last
<  * allocated arena to amortize the cost of rt->gcLock.
---
>  * That is, each JSGCPageInfo's flags pointer is 128 bytes from the previous,
>  * or at the start of the arena if there is no previous page in this arena.
>  * Thus these ideal 128-byte flag pages run contiguously from the start of the
>  * arena (right over the split!), and the JSGCPageInfo flags pointers contain
>  * no discontinuities over the split created by the thing pages.  So if, for a
>  * given JSGCPageInfo *pi, we find that
348,521c151,162
<  * We use number 8 based on benchmarks from bug 312238.
<  */
< #define MAX_THREAD_LOCAL_THINGS 8
< 
< #endif
< 
< JS_STATIC_ASSERT(sizeof(JSStackHeader) >= 2 * sizeof(jsval));
< 
< JS_STATIC_ASSERT(sizeof(JSGCThing) >= sizeof(JSString));
< JS_STATIC_ASSERT(sizeof(JSGCThing) >= sizeof(jsdouble));
< 
< /* We want to use all the available GC thing space for object's slots. */
< JS_STATIC_ASSERT(sizeof(JSObject) % sizeof(JSGCThing) == 0);
< 
< /*
<  * Ensure that JSObject is allocated from a different GC-list rather than
<  * jsdouble and JSString so we can easily finalize JSObject before these 2
<  * types of GC things. See comments in js_GC.
<  */
< JS_STATIC_ASSERT(GC_FREELIST_INDEX(sizeof(JSString)) !=
<                  GC_FREELIST_INDEX(sizeof(JSObject)));
< JS_STATIC_ASSERT(GC_FREELIST_INDEX(sizeof(jsdouble)) !=
<                  GC_FREELIST_INDEX(sizeof(JSObject)));
< 
< /*
<  * JSPtrTable capacity growth descriptor. The table grows by powers of two
<  * starting from capacity JSPtrTableInfo.minCapacity, but switching to linear
<  * growth when capacity reaches JSPtrTableInfo.linearGrowthThreshold.
<  */
< typedef struct JSPtrTableInfo {
<     uint16      minCapacity;
<     uint16      linearGrowthThreshold;
< } JSPtrTableInfo;
< 
< #define GC_ITERATOR_TABLE_MIN     4
< #define GC_ITERATOR_TABLE_LINEAR  1024
< 
< static const JSPtrTableInfo iteratorTableInfo = {
<     GC_ITERATOR_TABLE_MIN,
<     GC_ITERATOR_TABLE_LINEAR
< };
< 
< /* Calculate table capacity based on the current value of JSPtrTable.count. */
< static size_t
< PtrTableCapacity(size_t count, const JSPtrTableInfo *info)
< {
<     size_t linear, log, capacity;
< 
<     linear = info->linearGrowthThreshold;
<     JS_ASSERT(info->minCapacity <= linear);
< 
<     if (count == 0) {
<         capacity = 0;
<     } else if (count < linear) {
<         log = JS_CEILING_LOG2W(count);
<         JS_ASSERT(log != JS_BITS_PER_WORD);
<         capacity = (size_t)1 << log;
<         if (capacity < info->minCapacity)
<             capacity = info->minCapacity;
<     } else {
<         capacity = JS_ROUNDUP(count, linear);
<     }
< 
<     JS_ASSERT(capacity >= count);
<     return capacity;
< }
< 
< static void
< FreePtrTable(JSPtrTable *table, const JSPtrTableInfo *info)
< {
<     if (table->array) {
<         JS_ASSERT(table->count > 0);
<         free(table->array);
<         table->array = NULL;
<         table->count = 0;
<     }
<     JS_ASSERT(table->count == 0);
< }
< 
< static JSBool
< AddToPtrTable(JSContext *cx, JSPtrTable *table, const JSPtrTableInfo *info,
<               void *ptr)
< {
<     size_t count, capacity;
<     void **array;
< 
<     count = table->count;
<     capacity = PtrTableCapacity(count, info);
< 
<     if (count == capacity) {
<         if (capacity < info->minCapacity) {
<             JS_ASSERT(capacity == 0);
<             JS_ASSERT(!table->array);
<             capacity = info->minCapacity;
<         } else {
<             /*
<              * Simplify the overflow detection assuming pointer is bigger
<              * than byte.
<              */
<             JS_STATIC_ASSERT(2 <= sizeof table->array[0]);
<             capacity = (capacity < info->linearGrowthThreshold)
<                        ? 2 * capacity
<                        : capacity + info->linearGrowthThreshold;
<             if (capacity > (size_t)-1 / sizeof table->array[0])
<                 goto bad;
<         }
<         array = (void **) realloc(table->array,
<                                   capacity * sizeof table->array[0]);
<         if (!array)
<             goto bad;
< #ifdef DEBUG
<         memset(array + count, JS_FREE_PATTERN,
<                (capacity - count) * sizeof table->array[0]);
< #endif
<         table->array = array;
<     }
< 
<     table->array[count] = ptr;
<     table->count = count + 1;
< 
<     return JS_TRUE;
< 
<   bad:
<     JS_ReportOutOfMemory(cx);
<     return JS_FALSE;
< }
< 
< static void
< ShrinkPtrTable(JSPtrTable *table, const JSPtrTableInfo *info,
<                size_t newCount)
< {
<     size_t oldCapacity, capacity;
<     void **array;
< 
<     JS_ASSERT(newCount <= table->count);
<     if (newCount == table->count)
<         return;
< 
<     oldCapacity = PtrTableCapacity(table->count, info);
<     table->count = newCount;
<     capacity = PtrTableCapacity(newCount, info);
< 
<     if (oldCapacity != capacity) {
<         array = table->array;
<         JS_ASSERT(array);
<         if (capacity == 0) {
<             free(array);
<             table->array = NULL;
<             return;
<         }
<         array = (void **) realloc(array, capacity * sizeof array[0]);
<         if (array)
<             table->array = array;
<     }
< #ifdef DEBUG
<     memset(table->array + newCount, JS_FREE_PATTERN,
<            (capacity - newCount) * sizeof table->array[0]);
< #endif
< }
< 
< #ifdef JS_GCMETER
< # define METER(x)               ((void) (x))
< # define METER_IF(condition, x) ((void) ((condition) && (x)))
< #else
< # define METER(x)               ((void) 0)
< # define METER_IF(condition, x) ((void) 0)
< #endif
< 
< #define METER_UPDATE_MAX(maxLval, rval)                                       \
<     METER_IF((maxLval) < (rval), (maxLval) = (rval))
< 
< /*
<  * For chunks allocated via over-sized malloc, get a pointer to store the gap
<  * between the malloc's result and the first arena in the chunk.
---
>  *  pi->flags + ((jsuword)thing % 1024) / sizeof(JSGCThing) >= pi->split
>  *
>  * then we must add GC_THINGS_SIZE to the nominal flags pointer to jump over
>  * all the thing pages that split the flags into two discontiguous spans.
>  *
>  * (If we need to implement card-marking for an incremental GC write barrier,
>  * we can use the low byte of the pi->split pointer as the card-mark, for an
>  * extremely efficient write barrier: when mutating an object obj, just store
>  * a 1 byte at (uint8 *) ((jsuword)obj & ~1023) for little-endian platforms.
>  * When finding flags, we'll of course have to mask split with ~255, but it is
>  * guaranteed to be 1024-byte aligned, so no information is lost by overlaying
>  * the card-mark byte on split's low byte.)
523,526c164,166
< static uint32 *
< GetMallocedChunkGapPtr(jsuword chunk)
< {
<     JS_ASSERT((chunk & GC_ARENA_MASK) == 0);
---
> #define GC_PAGE_SHIFT   10
> #define GC_PAGE_MASK    ((jsuword) JS_BITMASK(GC_PAGE_SHIFT))
> #define GC_PAGE_SIZE    JS_BIT(GC_PAGE_SHIFT)
528,530c168,171
<     /* Use the memory after the chunk, see NewGCChunk for details. */
<     return (uint32 *) (chunk + (js_gcArenasPerChunk << GC_ARENA_SHIFT));
< }
---
> typedef struct JSGCPageInfo {
>     uint8       *split;
>     uint8       *flags;
> } JSGCPageInfo;
532,552c173
< static jsuword
< NewGCChunk()
< {
<     void *p;
<     jsuword chunk;
< 
< #if JS_GC_USE_MMAP
<     if (js_gcUseMmap) {
< # if defined(XP_WIN)
<         p = VirtualAlloc(NULL, js_gcArenasPerChunk << GC_ARENA_SHIFT,
<                          MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
<         return (jsuword) p;
< # elif defined(XP_UNIX) || defined(XP_BEOS)
<         p = mmap(NULL, js_gcArenasPerChunk << GC_ARENA_SHIFT,
<                  PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
<         return (p == MAP_FAILED) ? 0 : (jsuword) p;
< # else
< #  error "Not implemented"
< # endif
<     }
< #endif
---
> #define FIRST_THING_PAGE(a)     (((a)->base + GC_FLAGS_SIZE) & ~GC_PAGE_MASK)
554,576c175,176
<     /*
<      * Implement the chunk allocation using over sized malloc if mmap cannot
<      * be used. FIXME bug 396007: the code should use posix_memalign when it
<      * is available.
<      *
<      * Since malloc allocates pointers aligned on the word boundary, to get
<      * js_gcArenasPerChunk aligned arenas, we need to malloc only
<      *   ((js_gcArenasPerChunk + 1) << GC_ARENA_SHIFT) - sizeof(size_t)
<      * bytes. But since we stores the gap between the malloced pointer and the
<      * first arena in the chunk after the chunk, we need to ask for
<      *   ((js_gcArenasPerChunk + 1) << GC_ARENA_SHIFT)
<      * bytes to ensure that we always have room to store the gap.
<      */
<     p = malloc((js_gcArenasPerChunk + 1) << GC_ARENA_SHIFT);
<     if (!p)
<         return 0;
<     chunk = ((jsuword) p + GC_ARENA_MASK) & ~GC_ARENA_MASK;
<     *GetMallocedChunkGapPtr(chunk) = (uint32) (chunk - (jsuword) p);
<     return chunk;
< }
< 
< static void
< DestroyGCChunk(jsuword chunk)
---
> static JSGCThing *
> gc_new_arena(JSArenaPool *pool)
578,595c178,181
<     JS_ASSERT((chunk & GC_ARENA_MASK) == 0);
< #if JS_GC_USE_MMAP
<     if (js_gcUseMmap) {
< # if defined(XP_WIN)
<         VirtualFree((void *) chunk, 0, MEM_RELEASE);
< # elif defined(XP_UNIX) || defined(XP_BEOS)
<         munmap((void *) chunk, js_gcArenasPerChunk << GC_ARENA_SHIFT);
< # else
< #  error "Not implemented"
< # endif
<         return;
<     }
< #endif
< 
<     /* See comments in NewGCChunk. */
<     JS_ASSERT(*GetMallocedChunkGapPtr(chunk) < GC_ARENA_SIZE);
<     free((void *) (chunk - *GetMallocedChunkGapPtr(chunk)));
< }
---
>     uint8 *flagp, *split, *pagep, *limit;
>     JSArena *a;
>     JSGCThing *thing;
>     JSGCPageInfo *pi;
597,607c183,187
< static void
< AddChunkToList(JSRuntime *rt, JSGCChunkInfo *ci)
< {
<     ci->prevp = &rt->gcChunkList;
<     ci->next = rt->gcChunkList;
<     if (rt->gcChunkList) {
<         JS_ASSERT(rt->gcChunkList->prevp == &rt->gcChunkList);
<         rt->gcChunkList->prevp = &ci->next;
<     }
<     rt->gcChunkList = ci;
< }
---
>     /* Use JS_ArenaAllocate to grab another 9K-net-size hunk of space. */
>     flagp = (uint8 *) JS_ArenaAllocate(pool, GC_ARENA_SIZE);
>     if (!flagp)
>         return NULL;
>     a = pool->current;
609,616c189,205
< static void
< RemoveChunkFromList(JSRuntime *rt, JSGCChunkInfo *ci)
< {
<     *ci->prevp = ci->next;
<     if (ci->next) {
<         JS_ASSERT(ci->next->prevp == &ci->next);
<         ci->next->prevp = ci->prevp;
<     }
---
>     /* Reset a->avail to start at the flags split, aka the first thing page. */
>     a->avail = FIRST_THING_PAGE(a);
>     split = pagep = (uint8 *) a->avail;
>     a->avail += sizeof(JSGCPageInfo);
>     thing = (JSGCThing *) a->avail;
>     a->avail += sizeof(JSGCThing);
> 
>     /* Initialize the JSGCPageInfo records at the start of every thing page. */
>     limit = pagep + GC_THINGS_SIZE;
>     do {
>         pi = (JSGCPageInfo *) pagep;
>         pi->split = split;
>         pi->flags = flagp;
>         flagp += GC_PAGE_SIZE >> (GC_THINGS_SHIFT -  GC_PAGE_SHIFT);
>         pagep += GC_PAGE_SIZE;
>     } while (pagep < limit);
>     return thing;
619,620c208,209
< static JSGCArenaInfo *
< NewGCArena(JSRuntime *rt)
---
> uint8 *
> js_GetGCThingFlags(void *thing)
622,671c211,212
<     jsuword chunk;
<     JSGCChunkInfo *ci;
<     uint32 i;
<     JSGCArenaInfo *a, *aprev;
< 
<     if (js_gcArenasPerChunk == 1) {
<         chunk = NewGCChunk();
<         return (chunk == 0) ? NULL : ARENA_START_TO_INFO(chunk);
<     }
< 
<     ci = rt->gcChunkList;
<     if (!ci) {
<         chunk = NewGCChunk();
<         if (chunk == 0)
<             return NULL;
<         JS_ASSERT((chunk & GC_ARENA_MASK) == 0);
<         a = GET_ARENA_INFO(chunk, 0);
<         a->firstArena = JS_TRUE;
<         a->arenaIndex = 0;
<         aprev = NULL;
<         i = 0;
<         do {
<             a->prev = aprev;
<             aprev = a;
<             ++i;
<             a = GET_ARENA_INFO(chunk, i);
<             a->firstArena = JS_FALSE;
<             a->arenaIndex = i;
<         } while (i != js_gcArenasPerChunk - 1);
<         ci = GET_CHUNK_INFO(chunk, 0);
<         ci->lastFreeArena = aprev;
<         ci->numFreeArenas = js_gcArenasPerChunk - 1;
<         AddChunkToList(rt, ci);
<     } else {
<         JS_ASSERT(ci->prevp == &rt->gcChunkList);
<         a = ci->lastFreeArena;
<         aprev = a->prev;
<         if (!aprev) {
<             JS_ASSERT(ci->numFreeArenas == 1);
<             JS_ASSERT(ARENA_INFO_TO_START(a) == (jsuword) ci);
<             RemoveChunkFromList(rt, ci);
<             chunk = GET_ARENA_CHUNK(a, GET_ARENA_INDEX(a));
<             SET_CHUNK_INFO_INDEX(chunk, NO_FREE_ARENAS);
<         } else {
<             JS_ASSERT(ci->numFreeArenas >= 2);
<             JS_ASSERT(ARENA_INFO_TO_START(a) != (jsuword) ci);
<             ci->lastFreeArena = aprev;
<             ci->numFreeArenas--;
<         }
<     }
---
>     JSGCPageInfo *pi;
>     uint8 *flagp;
673c214,218
<     return a;
---
>     pi = (JSGCPageInfo *) ((jsuword)thing & ~GC_PAGE_MASK);
>     flagp = pi->flags + ((jsuword)thing & GC_PAGE_MASK) / sizeof(JSGCThing);
>     if (flagp >= pi->split)
>         flagp += GC_THINGS_SIZE;
>     return flagp;
676,677c221,222
< static void
< DestroyGCArena(JSRuntime *rt, JSGCArenaInfo *a)
---
> JSBool
> js_IsAboutToBeFinalized(JSContext *cx, void *thing)
679,689c224
<     uint32 arenaIndex;
<     jsuword chunk;
<     uint32 chunkInfoIndex;
<     JSGCChunkInfo *ci;
< 
<     METER(rt->gcStats.afree++);
< 
<     if (js_gcArenasPerChunk == 1) {
<         DestroyGCChunk(ARENA_INFO_TO_START(a));
<         return;
<     }
---
>     uint8 flags = *js_GetGCThingFlags(thing);
691,729c226
< #ifdef DEBUG
<     {
<         jsuword firstArena, arenaIndex;
< 
<         firstArena = a->firstArena;
<         arenaIndex = a->arenaIndex;
<         memset((void *) ARENA_INFO_TO_START(a), JS_FREE_PATTERN,
<                GC_ARENA_SIZE);
<         a->firstArena = firstArena;
<         a->arenaIndex = arenaIndex;
<     }
< #endif
< 
<     arenaIndex = GET_ARENA_INDEX(a);
<     chunk = GET_ARENA_CHUNK(a, arenaIndex);
<     chunkInfoIndex = GET_CHUNK_INFO_INDEX(chunk);
<     if (chunkInfoIndex == NO_FREE_ARENAS) {
<         chunkInfoIndex = arenaIndex;
<         SET_CHUNK_INFO_INDEX(chunk, arenaIndex);
<         ci = GET_CHUNK_INFO(chunk, chunkInfoIndex);
<         a->prev = NULL;
<         ci->lastFreeArena = a;
<         ci->numFreeArenas = 1;
<         AddChunkToList(rt, ci);
<     } else {
<         JS_ASSERT(chunkInfoIndex != arenaIndex);
<         ci = GET_CHUNK_INFO(chunk, chunkInfoIndex);
<         JS_ASSERT(ci->numFreeArenas != 0);
<         JS_ASSERT(ci->lastFreeArena);
<         JS_ASSERT(a != ci->lastFreeArena);
<         if (ci->numFreeArenas == js_gcArenasPerChunk - 1) {
<             RemoveChunkFromList(rt, ci);
<             DestroyGCChunk(chunk);
<         } else {
<             ++ci->numFreeArenas;
<             a->prev = ci->lastFreeArena;
<             ci->lastFreeArena = a;
<         }
<     }
---
>     return !(flags & (GCF_MARK | GCF_LOCKMASK | GCF_FINAL));
732,736c229
< static void
< InitGCArenaLists(JSRuntime *rt)
< {
<     uintN i, thingSize;
<     JSGCArenaList *arenaList;
---
> typedef void (*GCFinalizeOp)(JSContext *cx, JSGCThing *thing);
738,747c231
<     for (i = 0; i < GC_NUM_FREELISTS; i++) {
<         arenaList = &rt->gcArenaList[i];
<         thingSize = GC_FREELIST_NBYTES(i);
<         JS_ASSERT((size_t)(uint16)thingSize == thingSize);
<         arenaList->last = NULL;
<         arenaList->lastCount = THINGS_PER_ARENA(thingSize);
<         arenaList->thingSize = (uint16)thingSize;
<         arenaList->freeList = NULL;
<     }
< }
---
> static GCFinalizeOp gc_finalizers[GCX_NTYPES];
749,750c233,235
< static void
< FinishGCArenaLists(JSRuntime *rt)
---
> intN
> js_ChangeExternalStringFinalizer(JSStringFinalizeOp oldop,
>                                  JSStringFinalizeOp newop)
753,754d237
<     JSGCArenaList *arenaList;
<     JSGCArenaInfo *a, *aprev;
756,761c239,242
<     for (i = 0; i < GC_NUM_FREELISTS; i++) {
<         arenaList = &rt->gcArenaList[i];
< 
<         for (a = arenaList->last; a; a = aprev) {
<             aprev = a->prev;
<             DestroyGCArena(rt, a);
---
>     for (i = GCX_EXTERNAL_STRING; i < GCX_NTYPES; i++) {
>         if (gc_finalizers[i] == (GCFinalizeOp) oldop) {
>             gc_finalizers[i] = (GCFinalizeOp) newop;
>             return (intN) i;
763,766d243
<         arenaList->last = NULL;
<         arenaList->lastCount = THINGS_PER_ARENA(arenaList->thingSize);
<         arenaList->freeList = NULL;
<         METER(rt->gcStats.arenas[i].narenas = 0);
768,827c245
<     rt->gcBytes = 0;
<     JS_ASSERT(rt->gcChunkList == 0);
< }
< 
< static uint8 *
< GetGCThingFlags(void *thing)
< {
<     JSGCArenaInfo *a;
<     uint32 index;
< 
<     a = THING_TO_ARENA(thing);
<     index = THING_TO_INDEX(thing, a->list->thingSize);
<     return THING_FLAGP(a, index);
< }
< 
< intN
< js_GetExternalStringGCType(JSString *str)
< {
<     uintN type;
< 
<     type = (uintN) *GetGCThingFlags(str) & GCF_TYPEMASK;
<     JS_ASSERT(type == GCX_STRING || type >= GCX_EXTERNAL_STRING);
<     return (type == GCX_STRING) ? -1 : (intN) (type - GCX_EXTERNAL_STRING);
< }
< 
< static uint32
< MapGCFlagsToTraceKind(uintN flags)
< {
<     uint32 type;
< 
<     type = flags & GCF_TYPEMASK;
<     JS_ASSERT(type < GCX_NTYPES);
<     return (type < GCX_EXTERNAL_STRING) ? type : JSTRACE_STRING;
< }
< 
< JS_FRIEND_API(uint32)
< js_GetGCThingTraceKind(void *thing)
< {
<     return MapGCFlagsToTraceKind(*GetGCThingFlags(thing));
< }
< 
< JSRuntime*
< js_GetGCStringRuntime(JSString *str)
< {
<     JSGCArenaList *list;
< 
<     list = THING_TO_ARENA(str)->list;
< 
<     JS_ASSERT(list->thingSize == sizeof(JSGCThing));
<     JS_ASSERT(GC_FREELIST_INDEX(sizeof(JSGCThing)) == 0);
< 
<     return (JSRuntime *)((uint8 *)list - offsetof(JSRuntime, gcArenaList));
< }
< 
< JSBool
< js_IsAboutToBeFinalized(JSContext *cx, void *thing)
< {
<     uint8 flags = *GetGCThingFlags(thing);
< 
<     return !(flags & (GCF_MARK | GCF_LOCK | GCF_FINAL));
---
>     return -1;
830,835c248,252
< /* This is compatible with JSDHashEntryStub. */
< typedef struct JSGCRootHashEntry {
<     JSDHashEntryHdr hdr;
<     void            *root;
<     const char      *name;
< } JSGCRootHashEntry;
---
> #ifdef JS_GCMETER
> #define METER(x) x
> #else
> #define METER(x) /* nothing */
> #endif
839,846c256
< 
< /*
<  * For a CPU with extremely large pages using them for GC things wastes
<  * too much memory.
<  */
< #define GC_ARENAS_PER_CPU_PAGE_LIMIT JS_BIT(18 - GC_ARENA_SHIFT)
< 
< JS_STATIC_ASSERT(GC_ARENAS_PER_CPU_PAGE_LIMIT <= NO_FREE_ARENAS);
---
> #define GC_FINALIZE_LEN 1024
851,867c261,270
< #if JS_GC_USE_MMAP
<     if (js_gcArenasPerChunk == 0) {
<         size_t cpuPageSize, arenasPerPage;
< # if defined(XP_WIN)
<         SYSTEM_INFO si;
< 
<         GetSystemInfo(&si);
<         cpuPageSize = si.dwPageSize;
< 
< # elif defined(XP_UNIX) || defined(XP_BEOS)
<         cpuPageSize = (size_t) sysconf(_SC_PAGESIZE);
< # else
< #  error "Not implemented"
< # endif
<         /* cpuPageSize is a power of 2. */
<         JS_ASSERT((cpuPageSize & (cpuPageSize - 1)) == 0);
<         arenasPerPage = cpuPageSize >> GC_ARENA_SHIFT;
---
>     JS_ASSERT(sizeof(JSGCThing) == sizeof(JSGCPageInfo));
>     JS_ASSERT(sizeof(JSGCThing) >= sizeof(JSObject));
>     JS_ASSERT(sizeof(JSGCThing) >= sizeof(JSString));
>     JS_ASSERT(sizeof(JSGCThing) >= sizeof(jsdouble));
>     JS_ASSERT(GC_FLAGS_SIZE >= GC_PAGE_SIZE);
>     JS_ASSERT(sizeof(JSStackHeader) >= 2 * sizeof(jsval));
> 
>     if (!gc_finalizers[GCX_OBJECT]) {
>         gc_finalizers[GCX_OBJECT] = (GCFinalizeOp)js_FinalizeObject;
>         gc_finalizers[GCX_STRING] = (GCFinalizeOp)js_FinalizeString;
869,874c272
<         if (arenasPerPage == 0) {
<             fprintf(stderr,
< "JS engine warning: the size of the CPU page, %u bytes, is too low to use\n"
< "paged allocation for the garbage collector. Please report this.\n",
<                     (unsigned) cpuPageSize);
<         }
---
>         gc_finalizers[GCX_DOUBLE] = (GCFinalizeOp)js_FinalizeDouble;
876,886c274
<         if (arenasPerPage - 1 <= (size_t) (GC_ARENAS_PER_CPU_PAGE_LIMIT - 1)) {
<             /*
<              * Use at least 4 GC arenas per paged allocation chunk to minimize
<              * the overhead of mmap/VirtualAlloc.
<              */
<             js_gcUseMmap = JS_TRUE;
<             js_gcArenasPerChunk = JS_MAX((uint32) arenasPerPage, 4);
<         } else {
<             js_gcUseMmap = JS_FALSE;
<             js_gcArenasPerChunk = 7;
<         }
---
>         gc_finalizers[GCX_MUTABLE_STRING] = (GCFinalizeOp)js_FinalizeString;
888,890d275
< #endif
<     JS_ASSERT(1 <= js_gcArenasPerChunk &&
<               js_gcArenasPerChunk <= NO_FREE_ARENAS);
892c277,278
<     InitGCArenaLists(rt);
---
>     JS_InitArenaPool(&rt->gcArenaPool, "gc-arena", GC_ARENA_SIZE,
>                      sizeof(JSGCThing));
899,907c285
< 
<     /*
<      * Separate gcMaxMallocBytes from gcMaxBytes but initialize to maxbytes
<      * for default backward API compatibility.
<      */
<     rt->gcMaxBytes = rt->gcMaxMallocBytes = maxbytes;
<     rt->gcStackPoolLifespan = 30000;
< 
<     METER(memset(&rt->gcStats, 0, sizeof rt->gcStats));
---
>     rt->gcMaxBytes = maxbytes;
912c290
< JS_FRIEND_API(void)
---
> void
915,922d292
<     uintN i;
<     size_t thingsPerArena;
<     size_t totalThings, totalMaxThings, totalBytes;
<     size_t sumArenas, sumTotalArenas;
<     size_t sumFreeSize, sumTotalFreeSize;
<     JSGCArenaList *list;
<     JSGCArenaStats *stats;
< 
924,1013c294,311
< 
< #define UL(x)       ((unsigned long)(x))
< #define ULSTAT(x)   UL(rt->gcStats.x)
<     totalThings = 0;
< 
<     totalMaxThings = 0;
<     totalBytes = 0;
<     sumArenas = 0;
<     sumTotalArenas = 0;
<     sumFreeSize = 0;
<     sumTotalFreeSize = 0;
<     for (i = 0; i < GC_NUM_FREELISTS; i++) {
<         list = &rt->gcArenaList[i];
<         stats = &rt->gcStats.arenas[i];
<         if (stats->maxarenas == 0) {
<             fprintf(fp, "ARENA LIST %u (thing size %lu): NEVER USED\n",
<                     i, UL(GC_FREELIST_NBYTES(i)));
<             continue;
<         }
<         thingsPerArena = THINGS_PER_ARENA(list->thingSize);
<         fprintf(fp, "ARENA LIST %u (thing size %lu):\n",
<                 i, UL(GC_FREELIST_NBYTES(i)));
<         fprintf(fp, "                     arenas: %lu\n", UL(stats->narenas));
<         fprintf(fp, "                 max arenas: %lu\n", UL(stats->maxarenas));
<         fprintf(fp, "                     things: %lu\n", UL(stats->nthings));
<         fprintf(fp, "                 max things: %lu\n", UL(stats->maxthings));
<         fprintf(fp, "                  free list: %lu\n", UL(stats->freelen));
<         fprintf(fp, "          free list density: %.1f%%\n",
<                 stats->narenas == 0
<                 ? 0.0
<                 : 100.0 * stats->freelen / (thingsPerArena * stats->narenas));
<         fprintf(fp, "  average free list density: %.1f%%\n",
<                 stats->totalarenas == 0
<                 ? 0.0
<                 : 100.0 * stats->totalfreelen /
<                   (thingsPerArena * stats->totalarenas));
<         fprintf(fp, "                   recycles: %lu\n", UL(stats->recycle));
<         fprintf(fp, "        recycle/alloc ratio: %.2f\n",
<                 (double) stats->recycle / (stats->totalnew - stats->recycle));
<         totalThings += stats->nthings;
<         totalMaxThings += stats->maxthings;
<         totalBytes += list->thingSize * stats->nthings;
<         sumArenas += stats->narenas;
<         sumTotalArenas += stats->totalarenas;
<         sumFreeSize += list->thingSize * stats->freelen;
<         sumTotalFreeSize += list->thingSize * stats->totalfreelen;
<     }
<     fprintf(fp, "TOTAL STATS:\n");
<     fprintf(fp, "            bytes allocated: %lu\n", UL(rt->gcBytes));
<     fprintf(fp, "             alloc attempts: %lu\n", ULSTAT(alloc));
< #ifdef JS_THREADSAFE
<     fprintf(fp, "        alloc without locks: %1u\n", ULSTAT(localalloc));
< #endif
<     fprintf(fp, "            total GC things: %lu\n", UL(totalThings));
<     fprintf(fp, "        max total GC things: %lu\n", UL(totalMaxThings));
<     fprintf(fp, "             GC things size: %lu\n", UL(totalBytes));
<     fprintf(fp, "            total GC arenas: %lu\n", UL(sumArenas));
<     fprintf(fp, "    total free list density: %.1f%%\n",
<             sumArenas == 0
<             ? 0.0
<             : 100.0 * sumFreeSize / (sumArenas << GC_ARENA_SHIFT));
<     fprintf(fp, "  average free list density: %.1f%%\n",
<             sumTotalFreeSize == 0
<             ? 0.0
<             : 100.0 * sumTotalFreeSize / (sumTotalArenas << GC_ARENA_SHIFT));
<     fprintf(fp, "allocation retries after GC: %lu\n", ULSTAT(retry));
<     fprintf(fp, "        allocation failures: %lu\n", ULSTAT(fail));
<     fprintf(fp, "         things born locked: %lu\n", ULSTAT(lockborn));
<     fprintf(fp, "           valid lock calls: %lu\n", ULSTAT(lock));
<     fprintf(fp, "         valid unlock calls: %lu\n", ULSTAT(unlock));
<     fprintf(fp, "       mark recursion depth: %lu\n", ULSTAT(depth));
<     fprintf(fp, "     maximum mark recursion: %lu\n", ULSTAT(maxdepth));
<     fprintf(fp, "     mark C recursion depth: %lu\n", ULSTAT(cdepth));
<     fprintf(fp, "   maximum mark C recursion: %lu\n", ULSTAT(maxcdepth));
<     fprintf(fp, "      delayed tracing calls: %lu\n", ULSTAT(untraced));
< #ifdef DEBUG
<     fprintf(fp, "      max trace later count: %lu\n", ULSTAT(maxuntraced));
< #endif
<     fprintf(fp, "   maximum GC nesting level: %lu\n", ULSTAT(maxlevel));
<     fprintf(fp, "potentially useful GC calls: %lu\n", ULSTAT(poke));
<     fprintf(fp, "  thing arenas freed so far: %lu\n", ULSTAT(afree));
<     fprintf(fp, "     stack segments scanned: %lu\n", ULSTAT(stackseg));
<     fprintf(fp, "stack segment slots scanned: %lu\n", ULSTAT(segslots));
<     fprintf(fp, "reachable closeable objects: %lu\n", ULSTAT(nclose));
<     fprintf(fp, "    max reachable closeable: %lu\n", ULSTAT(maxnclose));
<     fprintf(fp, "      scheduled close hooks: %lu\n", ULSTAT(closelater));
<     fprintf(fp, "  max scheduled close hooks: %lu\n", ULSTAT(maxcloselater));
< #undef UL
< #undef US
< 
---
>     fprintf(fp, "     bytes currently allocated: %lu\n", rt->gcBytes);
>     fprintf(fp, "                alloc attempts: %lu\n", rt->gcStats.alloc);
>     fprintf(fp, "            GC freelist length: %lu\n", rt->gcStats.freelen);
>     fprintf(fp, "  recycles through GC freelist: %lu\n", rt->gcStats.recycle);
>     fprintf(fp, "alloc retries after running GC: %lu\n", rt->gcStats.retry);
>     fprintf(fp, "           allocation failures: %lu\n", rt->gcStats.fail);
>     fprintf(fp, "              valid lock calls: %lu\n", rt->gcStats.lock);
>     fprintf(fp, "            valid unlock calls: %lu\n", rt->gcStats.unlock);
>     fprintf(fp, "   locks that hit stuck counts: %lu\n", rt->gcStats.stuck);
>     fprintf(fp, " unlocks that saw stuck counts: %lu\n", rt->gcStats.unstuck);
>     fprintf(fp, "          mark recursion depth: %lu\n", rt->gcStats.depth);
>     fprintf(fp, "  maximum mark recursion depth: %lu\n", rt->gcStats.maxdepth);
>     fprintf(fp, "      maximum GC nesting level: %lu\n", rt->gcStats.maxlevel);
>     fprintf(fp, "   potentially useful GC calls: %lu\n", rt->gcStats.poke);
>     fprintf(fp, "              useless GC calls: %lu\n", rt->gcStats.nopoke);
>     fprintf(fp, "     thing arenas freed so far: %lu\n", rt->gcStats.afree);
>     fprintf(fp, "  extra stack segments scanned: %lu\n", rt->gcStats.stackseg);
>     fprintf(fp, "   stack segment slots scanned: %lu\n", rt->gcStats.segslots);
1021,1022c319,331
< static void
< CheckLeakedRoots(JSRuntime *rt);
---
> JS_STATIC_DLL_CALLBACK(JSDHashOperator)
> js_root_printer(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 i, void *arg)
> {
>     uint32 *leakedroots = (uint32 *)arg;
>     JSGCRootHashEntry *rhe = (JSGCRootHashEntry *)hdr;
> 
>     (*leakedroots)++;
>     fprintf(stderr,
>             "JS engine warning: leaking GC root \'%s\' at %p\n",
>             rhe->name ? (char *)rhe->name : "", rhe->root);
> 
>     return JS_DHASH_NEXT;
> }
1034,1036c343,344
< 
<     FreePtrTable(&rt->gcIteratorTable, &iteratorTableInfo);
<     FinishGCArenaLists(rt);
---
>     JS_FinishArenaPool(&rt->gcArenaPool);
>     JS_ArenaFinish();
1040c348,366
<         CheckLeakedRoots(rt);
---
>         uint32 leakedroots = 0;
> 
>         /* Warn (but don't assert) debug builds of any remaining roots. */
>         JS_DHashTableEnumerate(&rt->gcRootsHash, js_root_printer,
>                                &leakedroots);
>         if (leakedroots > 0) {
>             if (leakedroots == 1) {
>                 fprintf(stderr,
> "JS engine warning: 1 GC root remains after destroying the JSRuntime.\n"
> "                   This root may point to freed memory. Objects reachable\n"
> "                   through it have not been finalized.\n");
>             } else {
>                 fprintf(stderr,
> "JS engine warning: %lu GC roots remain after destroying the JSRuntime.\n"
> "                   These roots may point to freed memory. Objects reachable\n"
> "                   through them have not been finalized.\n",
>                         (unsigned long) leakedroots);
>             }
>         }
1041a368
> 
1048a376
>     rt->gcFreeList = NULL;
1082c410
<     if (rt->gcRunning && rt->gcThread->id != js_CurrentThreadId()) {
---
>     if (rt->gcRunning && rt->gcThread != js_CurrentThreadId()) {
1088,1089c416,417
<     rhe = (JSGCRootHashEntry *)
<           JS_DHashTableOperate(&rt->gcRootsHash, rp, JS_DHASH_ADD);
---
>     rhe = (JSGCRootHashEntry *) JS_DHashTableOperate(&rt->gcRootsHash, rp,
>                                                      JS_DHASH_ADD);
1092,1249c420,424
<         rhe->name = name;
<         ok = JS_TRUE;
<     } else {
<         ok = JS_FALSE;
<     }
<     JS_UNLOCK_GC(rt);
<     return ok;
< }
< 
< JSBool
< js_RemoveRoot(JSRuntime *rt, void *rp)
< {
<     /*
<      * Due to the JS_RemoveRootRT API, we may be called outside of a request.
<      * Same synchronization drill as above in js_AddRoot.
<      */
<     JS_LOCK_GC(rt);
< #ifdef JS_THREADSAFE
<     JS_ASSERT(!rt->gcRunning || rt->gcLevel > 0);
<     if (rt->gcRunning && rt->gcThread->id != js_CurrentThreadId()) {
<         do {
<             JS_AWAIT_GC_DONE(rt);
<         } while (rt->gcLevel > 0);
<     }
< #endif
<     (void) JS_DHashTableOperate(&rt->gcRootsHash, rp, JS_DHASH_REMOVE);
<     rt->gcPoke = JS_TRUE;
<     JS_UNLOCK_GC(rt);
<     return JS_TRUE;
< }
< 
< #ifdef DEBUG
< 
< JS_STATIC_DLL_CALLBACK(JSDHashOperator)
< js_root_printer(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 i, void *arg)
< {
<     uint32 *leakedroots = (uint32 *)arg;
<     JSGCRootHashEntry *rhe = (JSGCRootHashEntry *)hdr;
< 
<     (*leakedroots)++;
<     fprintf(stderr,
<             "JS engine warning: leaking GC root \'%s\' at %p\n",
<             rhe->name ? (char *)rhe->name : "", rhe->root);
< 
<     return JS_DHASH_NEXT;
< }
< 
< static void
< CheckLeakedRoots(JSRuntime *rt)
< {
<     uint32 leakedroots = 0;
< 
<     /* Warn (but don't assert) debug builds of any remaining roots. */
<     JS_DHashTableEnumerate(&rt->gcRootsHash, js_root_printer,
<                            &leakedroots);
<     if (leakedroots > 0) {
<         if (leakedroots == 1) {
<             fprintf(stderr,
< "JS engine warning: 1 GC root remains after destroying the JSRuntime.\n"
< "                   This root may point to freed memory. Objects reachable\n"
< "                   through it have not been finalized.\n");
<         } else {
<             fprintf(stderr,
< "JS engine warning: %lu GC roots remain after destroying the JSRuntime.\n"
< "                   These roots may point to freed memory. Objects reachable\n"
< "                   through them have not been finalized.\n",
<                         (unsigned long) leakedroots);
<         }
<     }
< }
< 
< typedef struct NamedRootDumpArgs {
<     void (*dump)(const char *name, void *rp, void *data);
<     void *data;
< } NamedRootDumpArgs;
< 
< JS_STATIC_DLL_CALLBACK(JSDHashOperator)
< js_named_root_dumper(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 number,
<                      void *arg)
< {
<     NamedRootDumpArgs *args = (NamedRootDumpArgs *) arg;
<     JSGCRootHashEntry *rhe = (JSGCRootHashEntry *)hdr;
< 
<     if (rhe->name)
<         args->dump(rhe->name, rhe->root, args->data);
<     return JS_DHASH_NEXT;
< }
< 
< void
< js_DumpNamedRoots(JSRuntime *rt,
<                   void (*dump)(const char *name, void *rp, void *data),
<                   void *data)
< {
<     NamedRootDumpArgs args;
< 
<     args.dump = dump;
<     args.data = data;
<     JS_DHashTableEnumerate(&rt->gcRootsHash, js_named_root_dumper, &args);
< }
< 
< #endif /* DEBUG */
< 
< typedef struct GCRootMapArgs {
<     JSGCRootMapFun map;
<     void *data;
< } GCRootMapArgs;
< 
< JS_STATIC_DLL_CALLBACK(JSDHashOperator)
< js_gcroot_mapper(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 number,
<                  void *arg)
< {
<     GCRootMapArgs *args = (GCRootMapArgs *) arg;
<     JSGCRootHashEntry *rhe = (JSGCRootHashEntry *)hdr;
<     intN mapflags;
<     int op;
< 
<     mapflags = args->map(rhe->root, rhe->name, args->data);
< 
< #if JS_MAP_GCROOT_NEXT == JS_DHASH_NEXT &&                                     \
<     JS_MAP_GCROOT_STOP == JS_DHASH_STOP &&                                     \
<     JS_MAP_GCROOT_REMOVE == JS_DHASH_REMOVE
<     op = (JSDHashOperator)mapflags;
< #else
<     op = JS_DHASH_NEXT;
<     if (mapflags & JS_MAP_GCROOT_STOP)
<         op |= JS_DHASH_STOP;
<     if (mapflags & JS_MAP_GCROOT_REMOVE)
<         op |= JS_DHASH_REMOVE;
< #endif
< 
<     return (JSDHashOperator) op;
< }
< 
< uint32
< js_MapGCRoots(JSRuntime *rt, JSGCRootMapFun map, void *data)
< {
<     GCRootMapArgs args;
<     uint32 rv;
< 
<     args.map = map;
<     args.data = data;
<     JS_LOCK_GC(rt);
<     rv = JS_DHashTableEnumerate(&rt->gcRootsHash, js_gcroot_mapper, &args);
<     JS_UNLOCK_GC(rt);
<     return rv;
< }
< 
< JSBool
< js_RegisterCloseableIterator(JSContext *cx, JSObject *obj)
< {
<     JSRuntime *rt;
<     JSBool ok;
< 
<     rt = cx->runtime;
<     JS_ASSERT(!rt->gcRunning);
< 
<     JS_LOCK_GC(rt);
<     ok = AddToPtrTable(cx, &rt->gcIteratorTable, &iteratorTableInfo, obj);
---
>         rhe->name = name;
>         ok = JS_TRUE;
>     } else {
>         ok = JS_FALSE;
>     }
1254,1255c429,430
< static void
< CloseNativeIterators(JSContext *cx)
---
> JSBool
> js_RemoveRoot(JSRuntime *rt, void *rp)
1257,1272c432,442
<     JSRuntime *rt;
<     size_t count, newCount, i;
<     void **array;
<     JSObject *obj;
< 
<     rt = cx->runtime;
<     count = rt->gcIteratorTable.count;
<     array = rt->gcIteratorTable.array;
< 
<     newCount = 0;
<     for (i = 0; i != count; ++i) {
<         obj = (JSObject *)array[i];
<         if (js_IsAboutToBeFinalized(cx, obj))
<             js_CloseNativeIterator(cx, obj);
<         else
<             array[newCount++] = obj;
---
>     /*
>      * Due to the JS_RemoveRootRT API, we may be called outside of a request.
>      * Same synchronization drill as above in js_AddRoot.
>      */
>     JS_LOCK_GC(rt);
> #ifdef JS_THREADSAFE
>     JS_ASSERT(!rt->gcRunning || rt->gcLevel > 0);
>     if (rt->gcRunning && rt->gcThread != js_CurrentThreadId()) {
>         do {
>             JS_AWAIT_GC_DONE(rt);
>         } while (rt->gcLevel > 0);
1274,1289d443
<     ShrinkPtrTable(&rt->gcIteratorTable, &iteratorTableInfo, newCount);
< }
< 
< #if defined(DEBUG_brendan) || defined(DEBUG_timeless)
< #define DEBUG_gchist
< #endif
< 
< #ifdef DEBUG_gchist
< #define NGCHIST 64
< 
< static struct GCHist {
<     JSBool      lastDitch;
<     JSGCThing   *freeList;
< } gchist[NGCHIST];
< 
< unsigned gchpos = 0;
1290a445,449
>     (void) JS_DHashTableOperate(&rt->gcRootsHash, rp, JS_DHASH_REMOVE);
>     rt->gcPoke = JS_TRUE;
>     JS_UNLOCK_GC(rt);
>     return JS_TRUE;
> }
1293c452
< js_NewGCThing(JSContext *cx, uintN flags, size_t nbytes)
---
> js_AllocGCThing(JSContext *cx, uintN flags)
1294a454
>     JSBool tried_gc;
1296,1297d455
<     uintN flindex;
<     JSBool doGC;
1300,1313c458,463
<     JSGCArenaList *arenaList;
< #ifdef JS_GCMETER
<     JSGCArenaStats *listStats;
< #endif
<     JSGCArenaInfo *a;
<     uintN thingsLimit;
<     JSLocalRootStack *lrs;
< #ifdef JS_THREADSAFE
<     JSBool gcLocked;
<     uintN localMallocBytes;
<     JSGCThing **flbase, **lastptr;
<     JSGCThing *tmpthing;
<     uint8 *tmpflagp;
<     uintN maxFreeThings;         /* max to take from the global free list */
---
> 
> #ifdef TOO_MUCH_GC
>     js_GC(cx, GC_KEEP_ATOMS);
>     tried_gc = JS_TRUE;
> #else
>     tried_gc = JS_FALSE;
1317,1335d466
<     METER(rt->gcStats.alloc++);        /* this is not thread-safe */
<     nbytes = JS_ROUNDUP(nbytes, sizeof(JSGCThing));
<     flindex = GC_FREELIST_INDEX(nbytes);
<     METER(listStats = &rt->gcStats.arenas[flindex]);
< 
< #ifdef JS_THREADSAFE
<     gcLocked = JS_FALSE;
<     JS_ASSERT(cx->thread);
<     flbase = cx->thread->gcFreeLists;
<     JS_ASSERT(flbase);
<     thing = flbase[flindex];
<     localMallocBytes = cx->thread->gcMallocBytes;
<     if (thing && rt->gcMaxMallocBytes - rt->gcMallocBytes > localMallocBytes) {
<         flagp = thing->flagp;
<         flbase[flindex] = thing->next;
<         METER(rt->gcStats.localalloc++);  /* this is not thread-safe */
<         goto success;
<     }
< 
1337,1347d467
<     gcLocked = JS_TRUE;
< 
<     /* Transfer thread-local counter to global one. */
<     if (localMallocBytes != 0) {
<         cx->thread->gcMallocBytes = 0;
<         if (rt->gcMaxMallocBytes - rt->gcMallocBytes < localMallocBytes)
<             rt->gcMallocBytes = rt->gcMaxMallocBytes;
<         else
<             rt->gcMallocBytes += localMallocBytes;
<     }
< #endif
1354,1362c474,485
< 
<     doGC = (rt->gcMallocBytes >= rt->gcMaxMallocBytes && rt->gcPoke);
< #ifdef JS_GC_ZEAL
<     doGC = doGC || rt->gcZeal >= 2 || (rt->gcZeal >= 1 && rt->gcPoke);
< #endif
< 
<     arenaList = &rt->gcArenaList[flindex];
<     for (;;) {
<         if (doGC) {
---
>     METER(rt->gcStats.alloc++);
> retry:
>     thing = rt->gcFreeList;
>     if (thing) {
>         rt->gcFreeList = thing->next;
>         flagp = thing->flagp;
>         METER(rt->gcStats.freelen--);
>         METER(rt->gcStats.recycle++);
>     } else {
>         if (rt->gcBytes < rt->gcMaxBytes &&
>             (tried_gc || rt->gcMallocBytes < rt->gcMaxBytes))
>         {
1364,1369c487,490
<              * Keep rt->gcLock across the call into js_GC so we don't starve
<              * and lose to racing threads who deplete the heap just after
<              * js_GC has replenished it (or has synchronized with a racing
<              * GC that collected a bunch of garbage).  This unfair scheduling
<              * can happen on certain operating systems. For the gory details,
<              * see bug 162779 at https://bugzilla.mozilla.org/.
---
>              * Inline form of JS_ARENA_ALLOCATE adapted to truncate the current
>              * arena's limit to a GC_PAGE_SIZE boundary, and to skip over every
>              * GC_PAGE_SIZE-byte-aligned thing (which is actually not a thing,
>              * it's a JSGCPageInfo record).
1371,1382c492,496
<             js_GC(cx, GC_LAST_DITCH);
<             METER(rt->gcStats.retry++);
<         }
< 
<         /* Try to get thing from the free list. */
<         thing = arenaList->freeList;
<         if (thing) {
<             arenaList->freeList = thing->next;
<             flagp = thing->flagp;
<             JS_ASSERT(*flagp & GCF_FINAL);
<             METER(listStats->freelen--);
<             METER(listStats->recycle++);
---
>             JSArenaPool *pool = &rt->gcArenaPool;
>             JSArena *a = pool->current;
>             size_t nb = sizeof(JSGCThing);
>             jsuword p = a->avail;
>             jsuword q = p + nb;
1384,1406c498,508
< #ifdef JS_THREADSAFE
<             /*
<              * Refill the local free list by taking several things from the
<              * global free list unless we are still at rt->gcMaxMallocBytes
<              * barrier or the free list is already populated. The former
<              * happens when GC is canceled due to !gcCallback(cx, JSGC_BEGIN)
<              * or no gcPoke. The latter is caused via allocating new things
<              * in gcCallback(cx, JSGC_END).
<              */
<             if (rt->gcMallocBytes >= rt->gcMaxMallocBytes || flbase[flindex])
<                 break;
<             tmpthing = arenaList->freeList;
<             if (tmpthing) {
<                 maxFreeThings = MAX_THREAD_LOCAL_THINGS;
<                 do {
<                     if (!tmpthing->next)
<                         break;
<                     tmpthing = tmpthing->next;
<                 } while (--maxFreeThings != 0);
< 
<                 flbase[flindex] = arenaList->freeList;
<                 arenaList->freeList = tmpthing->next;
<                 tmpthing->next = NULL;
---
>             if (q > (a->limit & ~GC_PAGE_MASK)) {
>                 thing = gc_new_arena(pool);
>             } else {
>                 if ((p & GC_PAGE_MASK) == 0) {
>                     /* Beware, p points to a JSGCPageInfo record! */
>                     p = q;
>                     q += nb;
>                     JS_ArenaCountAllocation(pool, nb);
>                 }
>                 a->avail = q;
>                 thing = (JSGCThing *)p;
1408,1409c510
< #endif
<             break;
---
>             JS_ArenaCountAllocation(pool, nb);
1413,1415c514,521
<          * Try to allocate things from the last arena. If it is fully used,
<          * check if we can allocate a new one and, if we cannot, consider
<          * doing a "last ditch" GC unless already tried.
---
>          * Consider doing a "last ditch" GC if thing couldn't be allocated.
>          *
>          * Keep rt->gcLock across the call into js_GC so we don't starve and
>          * lose to racing threads who deplete the heap just after js_GC has
>          * replenished it (or has synchronized with a racing GC that collected
>          * a bunch of garbage).  This unfair scheduling can happen on certain
>          * operating systems.  For the gory details, see Mozilla bug 162779
>          * (http://bugzilla.mozilla.org/show_bug.cgi?id=162779).
1417,1426c523,529
<         thingsLimit = THINGS_PER_ARENA(nbytes);
<         if (arenaList->lastCount != thingsLimit) {
<             JS_ASSERT(arenaList->lastCount < thingsLimit);
<             a = arenaList->last;
<         } else {
<             if (rt->gcBytes >= rt->gcMaxBytes || !(a = NewGCArena(rt))) {
<                 if (doGC)
<                     goto fail;
<                 doGC = JS_TRUE;
<                 continue;
---
>         if (!thing) {
>             if (!tried_gc) {
>                 rt->gcPoke = JS_TRUE;
>                 js_GC(cx, GC_KEEP_ATOMS | GC_ALREADY_LOCKED);
>                 tried_gc = JS_TRUE;
>                 METER(rt->gcStats.retry++);
>                 goto retry;
1428,1468c531,534
< 
<             rt->gcBytes += GC_ARENA_SIZE;
<             METER(listStats->narenas++);
<             METER_UPDATE_MAX(listStats->maxarenas, listStats->narenas);
< 
<             a->list = arenaList;
<             a->prev = arenaList->last;
<             a->prevUntracedPage = 0;
<             a->untracedThings = 0;
<             arenaList->last = a;
<             arenaList->lastCount = 0;
<         }
< 
<         flagp = THING_FLAGP(a, arenaList->lastCount);
<         thing = FLAGP_TO_THING(flagp, nbytes);
<         arenaList->lastCount++;
< 
< #ifdef JS_THREADSAFE
<         /*
<          * Refill the local free list by taking free things from the last
<          * arena. Prefer to order free things by ascending address in the
<          * (unscientific) hope of better cache locality.
<          */
<         if (rt->gcMallocBytes >= rt->gcMaxMallocBytes || flbase[flindex])
<             break;
<         lastptr = &flbase[flindex];
<         maxFreeThings = thingsLimit - arenaList->lastCount;
<         if (maxFreeThings > MAX_THREAD_LOCAL_THINGS)
<             maxFreeThings = MAX_THREAD_LOCAL_THINGS;
<         METER(listStats->freelen += maxFreeThings);
<         while (maxFreeThings != 0) {
<             --maxFreeThings;
< 
<             tmpflagp = THING_FLAGP(a, arenaList->lastCount);
<             tmpthing = FLAGP_TO_THING(tmpflagp, nbytes);
<             arenaList->lastCount++;
<             tmpthing->flagp = tmpflagp;
<             *tmpflagp = GCF_FINAL;    /* signifying that thing is free */
< 
<             *lastptr = tmpthing;
<             lastptr = &tmpthing->next;
---
>             METER(rt->gcStats.fail++);
>             JS_UNLOCK_GC(rt);
>             JS_ReportOutOfMemory(cx);
>             return NULL;
1470,1473d535
<         *lastptr = NULL;
< #endif
<         break;
<     }
1475,1503c537,538
<     /* We successfully allocated the thing. */
< #ifdef JS_THREADSAFE
<   success:
< #endif
<     lrs = cx->localRootStack;
<     if (lrs) {
<         /*
<          * If we're in a local root scope, don't set newborn[type] at all, to
<          * avoid entraining garbage from it for an unbounded amount of time
<          * on this context.  A caller will leave the local root scope and pop
<          * this reference, allowing thing to be GC'd if it has no other refs.
<          * See JS_EnterLocalRootScope and related APIs.
<          */
<         if (js_PushLocalRoot(cx, lrs, (jsval) thing) < 0) {
<             /*
<              * When we fail for a thing allocated through the tail of the last
<              * arena, thing's flag byte is not initialized. So to prevent GC
<              * accessing the uninitialized flags during the finalization, we
<              * always mark the thing as final. See bug 337407.
<              */
<             *flagp = GCF_FINAL;
<             goto fail;
<         }
<     } else {
<         /*
<          * No local root scope, so we're stuck with the old, fragile model of
<          * depending on a pigeon-hole newborn per type per context.
<          */
<         cx->weakRoots.newborn[flags & GCF_TYPEMASK] = thing;
---
>         /* Find the flags pointer given thing's address. */
>         flagp = js_GetGCThingFlags(thing);
1505,1506d539
< 
<     /* We can't fail now, so update flags. */
1507a541,542
>     rt->gcBytes += sizeof(JSGCThing) + sizeof(uint8);
>     cx->newborn[flags & GCF_TYPEMASK] = thing;
1509,1526c544,550
< #ifdef DEBUG_gchist
<     gchist[gchpos].lastDitch = doGC;
<     gchist[gchpos].freeList = rt->gcArenaList[flindex].freeList;
<     if (++gchpos == NGCHIST)
<         gchpos = 0;
< #endif
< 
<     /* This is not thread-safe for thread-local allocations. */
<     METER_IF(flags & GCF_LOCK, rt->gcStats.lockborn++);
<     METER(listStats->totalnew++);
<     METER(listStats->nthings++);
<     METER_UPDATE_MAX(listStats->maxthings, listStats->nthings);
< 
< #ifdef JS_THREADSAFE
<     if (gcLocked)
<         JS_UNLOCK_GC(rt);
< #endif
<     JS_COUNT_OPERATION(cx, JSOW_ALLOCATION);
---
>     /*
>      * Clear thing before unlocking in case a GC run is about to scan it,
>      * finding it via cx->newborn[].
>      */
>     thing->next = NULL;
>     thing->flagp = NULL;
>     JS_UNLOCK_GC(rt);
1528,1536d551
< 
< fail:
< #ifdef JS_THREADSAFE
<     if (gcLocked)
<         JS_UNLOCK_GC(rt);
< #endif
<     METER(rt->gcStats.fail++);
<     JS_ReportOutOfMemory(cx);
<     return NULL;
1548,1572d562
< /*
<  * Deep GC-things can't be locked just by setting the GCF_LOCK bit, because
<  * their descendants must be marked by the GC.  To find them during the mark
<  * phase, they are added to rt->gcLocksHash, which is created lazily.
<  *
<  * NB: we depend on the order of GC-thing type indexes here!
<  */
< #define GC_TYPE_IS_STRING(t)    ((t) == GCX_STRING ||                         \
<                                  (t) >= GCX_EXTERNAL_STRING)
< #define GC_TYPE_IS_XML(t)       ((unsigned)((t) - GCX_NAMESPACE) <=           \
<                                  (unsigned)(GCX_XML - GCX_NAMESPACE))
< #define GC_TYPE_IS_DEEP(t)      ((t) == GCX_OBJECT || GC_TYPE_IS_XML(t))
< 
< #define IS_DEEP_STRING(t,o)     (GC_TYPE_IS_STRING(t) &&                      \
<                                  JSSTRING_IS_DEPENDENT((JSString *)(o)))
< 
< #define GC_THING_IS_DEEP(t,o)   (GC_TYPE_IS_DEEP(t) || IS_DEEP_STRING(t, o))
< 
< /* This is compatible with JSDHashEntryStub. */
< typedef struct JSGCLockHashEntry {
<     JSDHashEntryHdr hdr;
<     const JSGCThing *thing;
<     uint32          count;
< } JSGCLockHashEntry;
< 
1576,1578c566,567
<     JSBool ok, deep;
<     uint8 *flagp;
<     uintN flags, lock, type;
---
>     uint8 *flagp, flags, lockbits;
>     JSBool ok;
1581d569
<     ok = JS_TRUE;
1583,1585c571,573
<         return ok;
< 
<     flagp = GetGCThingFlags(thing);
---
>         return JS_TRUE;
>     flagp = js_GetGCThingFlags(thing);
>     flags = *flagp;
1586a575
>     ok = JS_FALSE;
1588,1591c577
<     flags = *flagp;
<     lock = (flags & GCF_LOCK);
<     type = (flags & GCF_TYPEMASK);
<     deep = GC_THING_IS_DEEP(type, thing);
---
>     lockbits = (flags & GCF_LOCKMASK);
1593,1607c579,590
<     /*
<      * Avoid adding a rt->gcLocksHash entry for shallow things until someone
<      * nests a lock -- then start such an entry with a count of 2, not 1.
<      */
<     if (lock || deep) {
<         if (!rt->gcLocksHash) {
<             rt->gcLocksHash =
<                 JS_NewDHashTable(JS_DHashGetStubOps(), NULL,
<                                  sizeof(JSGCLockHashEntry),
<                                  GC_ROOTS_SIZE);
<             if (!rt->gcLocksHash) {
<                 ok = JS_FALSE;
<                 goto done;
<             }
<         } else if (lock == 0) {
---
>     if (lockbits != GCF_LOCKMASK) {
>         if ((flags & GCF_TYPEMASK) == GCX_OBJECT) {
>             /* Objects may require "deep locking", i.e., rooting by value. */
>             if (lockbits == 0) {
>                 if (!rt->gcLocksHash) {
>                     rt->gcLocksHash = 
>                         JS_NewDHashTable(JS_DHashGetStubOps(), NULL,
>                                          sizeof(JSGCLockHashEntry),
>                                          GC_ROOTS_SIZE);
>                     if (!rt->gcLocksHash)
>                         goto error;
>                 } else {
1609,1612c592,595
<             JSDHashEntryHdr *hdr =
<                 JS_DHashTableOperate(rt->gcLocksHash, thing,
<                                      JS_DHASH_LOOKUP);
<             JS_ASSERT(JS_DHASH_ENTRY_IS_FREE(hdr));
---
>                     JSDHashEntryHdr *hdr = 
>                         JS_DHashTableOperate(rt->gcLocksHash, thing,
>                                              JS_DHASH_LOOKUP);
>                     JS_ASSERT(JS_DHASH_ENTRY_IS_FREE(hdr));
1614,1624c597,615
<         }
< 
<         lhe = (JSGCLockHashEntry *)
<               JS_DHashTableOperate(rt->gcLocksHash, thing, JS_DHASH_ADD);
<         if (!lhe) {
<             ok = JS_FALSE;
<             goto done;
<         }
<         if (!lhe->thing) {
<             lhe->thing = (JSGCThing *) thing;
<             lhe->count = deep ? 1 : 2;
---
>                 }
>                 lhe = (JSGCLockHashEntry *)
>                     JS_DHashTableOperate(rt->gcLocksHash, thing, JS_DHASH_ADD);
>                 if (!lhe)
>                     goto error;
>                 lhe->thing = thing;
>                 lhe->count = 1;
>                 *flagp = (uint8)(flags + GCF_LOCK);
>             } else {
>                 JS_ASSERT(lockbits == GCF_LOCK);
>                 lhe = (JSGCLockHashEntry *)
>                     JS_DHashTableOperate(rt->gcLocksHash, thing,
>                                          JS_DHASH_LOOKUP);
>                 JS_ASSERT(JS_DHASH_ENTRY_IS_BUSY(&lhe->hdr));
>                 if (JS_DHASH_ENTRY_IS_BUSY(&lhe->hdr)) {
>                     JS_ASSERT(lhe->count >= 1);
>                     lhe->count++;
>                 }
>             }
1626,1627c617
<             JS_ASSERT(lhe->count >= 1);
<             lhe->count++;
---
>             *flagp = (uint8)(flags + GCF_LOCK);
1628a619,620
>     } else {
>         METER(rt->gcStats.stuck++);
1631d622
<     *flagp = (uint8)(flags | GCF_LOCK);
1634c625
< done:
---
> error:
1642c633
<     uint8 *flagp, flags;
---
>     uint8 *flagp, flags, lockbits;
1646a638,639
>     flagp = js_GetGCThingFlags(thing);
>     flags = *flagp;
1648d640
<     flagp = GetGCThingFlags(thing);
1650c642
<     flags = *flagp;
---
>     lockbits = (flags & GCF_LOCKMASK);
1652,1659c644,659
<     if (flags & GCF_LOCK) {
<         if (!rt->gcLocksHash ||
<             (lhe = (JSGCLockHashEntry *)
<                    JS_DHashTableOperate(rt->gcLocksHash, thing,
<                                         JS_DHASH_LOOKUP),
<              JS_DHASH_ENTRY_IS_FREE(&lhe->hdr))) {
<             /* Shallow GC-thing with an implicit lock count of 1. */
<             JS_ASSERT(!GC_THING_IS_DEEP(flags & GCF_TYPEMASK, thing));
---
>     if (lockbits != GCF_LOCKMASK) {
>         if ((flags & GCF_TYPEMASK) == GCX_OBJECT) {
>             /* Defend against a call on an unlocked object. */
>             if (lockbits != 0) {
>                 JS_ASSERT(lockbits == GCF_LOCK);
>                 lhe = (JSGCLockHashEntry *)
>                     JS_DHashTableOperate(rt->gcLocksHash, thing,
>                                          JS_DHASH_LOOKUP);
>                 JS_ASSERT(JS_DHASH_ENTRY_IS_BUSY(&lhe->hdr));
>                 if (JS_DHASH_ENTRY_IS_BUSY(&lhe->hdr) &&
>                     --lhe->count == 0) {
>                     (void) JS_DHashTableOperate(rt->gcLocksHash, thing,
>                                                 JS_DHASH_REMOVE);
>                     *flagp = (uint8)(flags & ~GCF_LOCKMASK);
>                 }
>             }
1661,1664c661
<             /* Basis or nested unlock of a deep thing, or nested of shallow. */
<             if (--lhe->count != 0)
<                 goto out;
<             JS_DHashTableOperate(rt->gcLocksHash, thing, JS_DHASH_REMOVE);
---
>             *flagp = (uint8)(flags - GCF_LOCK);
1666c663,664
<         *flagp = (uint8)(flags & ~GCF_LOCK);
---
>     } else {
>         METER(rt->gcStats.unstuck++);
1670d667
< out:
1676,1682c673
< JS_PUBLIC_API(void)
< JS_TraceChildren(JSTracer *trc, void *thing, uint32 kind)
< {
<     JSObject *obj;
<     size_t nslots, i;
<     jsval v;
<     JSString *str;
---
> #ifdef GC_MARK_DEBUG
1684,1700c675,708
<     switch (kind) {
<       case JSTRACE_OBJECT:
<         /* If obj has no map, it must be a newborn. */
<         obj = (JSObject *) thing;
<         if (!obj->map)
<             break;
<         if (obj->map->ops->trace) {
<             obj->map->ops->trace(trc, obj);
<         } else {
<             nslots = STOBJ_NSLOTS(obj);
<             for (i = 0; i != nslots; ++i) {
<                 v = STOBJ_GET_SLOT(obj, i);
<                 if (JSVAL_IS_TRACEABLE(v)) {
<                     JS_SET_TRACING_INDEX(trc, "slot", i);
<                     JS_CallTracer(trc, JSVAL_TO_TRACEABLE(v),
<                                   JSVAL_TRACE_KIND(v));
<                 }
---
> #include <stdio.h>
> #include "xstdlib.h"
> #include "jsprf.h"
> 
> JS_FRIEND_DATA(FILE *) js_DumpGCHeap;
> JS_EXPORT_DATA(void *) js_LiveThingToFind;
> 
> #ifdef HAVE_XPCONNECT
> #include "dump_xpc.h"
> #endif
> 
> static const char *
> gc_object_class_name(void* thing)
> {
>     uint8 *flagp = js_GetGCThingFlags(thing);
>     const char *className = "";
>     static char depbuf[32];
> 
>     switch (*flagp & GCF_TYPEMASK) {
>       case GCX_OBJECT: {
>         JSObject  *obj = (JSObject *)thing;
>         JSClass   *clasp = JSVAL_TO_PRIVATE(obj->slots[JSSLOT_CLASS]);
>         className = clasp->name;
> #ifdef HAVE_XPCONNECT
>         if (clasp->flags & JSCLASS_PRIVATE_IS_NSISUPPORTS) {
>             jsval privateValue = obj->slots[JSSLOT_PRIVATE];
> 
>             JS_ASSERT(clasp->flags & JSCLASS_HAS_PRIVATE);
>             if (!JSVAL_IS_VOID(privateValue)) {
>                 void  *privateThing = JSVAL_TO_PRIVATE(privateValue);
>                 const char *xpcClassName = GetXPCObjectClassName(privateThing);
> 
>                 if (xpcClassName)
>                     className = xpcClassName;
1702a711
> #endif
1703a713
>       }
1705,1708c715,724
<       case JSTRACE_STRING:
<         str = (JSString *)thing;
<         if (JSSTRING_IS_DEPENDENT(str))
<             JS_CALL_STRING_TRACER(trc, JSSTRDEP_BASE(str), "base");
---
>       case GCX_STRING:
>       case GCX_MUTABLE_STRING: {
>         JSString *str = (JSString *)thing;
>         if (JSSTRING_IS_DEPENDENT(str)) {
>             JS_snprintf(depbuf, sizeof depbuf, "start:%u, length:%u",
>                         JSSTRDEP_START(str), JSSTRDEP_LENGTH(str));
>             className = depbuf;
>         } else {
>             className = "string";
>         }
1709a726
>       }
1711,1712c728,729
<       case JSTRACE_FUNCTION:
<         js_TraceFunction(trc, (JSFunction *)thing);
---
>       case GCX_DOUBLE:
>         className = "double";
1713a731
>     }
1715,1718c733,734
< #if JS_HAS_XML_SUPPORT
<       case JSTRACE_NAMESPACE:
<         js_TraceXMLNamespace(trc, (JSXMLNamespace *)thing);
<         break;
---
>     return className;
> }
1720,1722c736,753
<       case JSTRACE_QNAME:
<         js_TraceXMLQName(trc, (JSXMLQName *)thing);
<         break;
---
> static void
> gc_dump_thing(JSGCThing *thing, uint8 flags, GCMarkNode *prev, FILE *fp)
> {
>     GCMarkNode *next = NULL;
>     char *path = NULL;
> 
>     while (prev) {
>         next = prev;
>         prev = prev->prev;
>     }
>     while (next) {
>         path = JS_sprintf_append(path, "%s(%s).",
>                                  next->name,
>                                  gc_object_class_name(next->thing));
>         next = next->next;
>     }
>     if (!path)
>         return;
1724,1725c755,772
<       case JSTRACE_XML:
<         js_TraceXML(trc, (JSXML *)thing);
---
>     fprintf(fp, "%08lx ", (long)thing);
>     switch (flags & GCF_TYPEMASK) {
>       case GCX_OBJECT:
>       {
>         JSObject  *obj = (JSObject *)thing;
>         jsval     privateValue = obj->slots[JSSLOT_PRIVATE];
>         void      *privateThing = JSVAL_IS_VOID(privateValue)
>                                   ? NULL
>                                   : JSVAL_TO_PRIVATE(privateValue);
>         const char *className = gc_object_class_name(thing);
>         fprintf(fp, "object %8p %s", privateThing, className);
>         break;
>       }
>       case GCX_DOUBLE:
>         fprintf(fp, "double %g", *(jsdouble *)thing);
>         break;
>       default:
>         fprintf(fp, "string %s", JS_GetStringBytes((JSString *)thing));
1727d773
< #endif
1728a775,776
>     fprintf(fp, " via %s\n", path);
>     free(path);
1731,1735c779
< /*
<  * Number of things covered by a single bit of JSGCArenaInfo.untracedThings.
<  */
< #define THINGS_PER_UNTRACED_BIT(thingSize)                                    \
<     JS_HOWMANY(THINGS_PER_ARENA(thingSize), JS_BITS_PER_WORD)
---
> #endif /* !GC_MARK_DEBUG */
1738c782
< DelayTracingChildren(JSRuntime *rt, uint8 *flagp)
---
> gc_mark_atom_key_thing(void *thing, void *arg)
1740,1755c784
<     JSGCArenaInfo *a;
<     uint32 untracedBitIndex;
<     jsuword bit;
< 
<     /*
<      * Things with children to be traced later are marked with
<      * GCF_MARK | GCF_FINAL flags.
<      */
<     JS_ASSERT((*flagp & (GCF_MARK | GCF_FINAL)) == GCF_MARK);
<     *flagp |= GCF_FINAL;
< 
<     METER(rt->gcStats.untraced++);
< #ifdef DEBUG
<     ++rt->gcTraceLaterCount;
<     METER_UPDATE_MAX(rt->gcStats.maxuntraced, rt->gcTraceLaterCount);
< #endif
---
>     JSContext *cx = (JSContext *) arg;
1757,1795c786
<     a = FLAGP_TO_ARENA(flagp);
<     untracedBitIndex = FLAGP_TO_INDEX(flagp) /
<                        THINGS_PER_UNTRACED_BIT(a->list->thingSize);
<     JS_ASSERT(untracedBitIndex < JS_BITS_PER_WORD);
<     bit = (jsuword)1 << untracedBitIndex;
<     if (a->untracedThings != 0) {
<         JS_ASSERT(rt->gcUntracedArenaStackTop);
<         if (a->untracedThings & bit) {
<             /* bit already covers things with children to trace later. */
<             return;
<         }
<         a->untracedThings |= bit;
<     } else {
<         /*
<          * The thing is the first thing with not yet traced children in the
<          * whole arena, so push the arena on the stack of arenas with things
<          * to be traced later unless the arena has already been pushed. We
<          * detect that through checking prevUntracedPage as the field is 0
<          * only for not yet pushed arenas. To ensure that
<          *   prevUntracedPage != 0
<          * even when the stack contains one element, we make prevUntracedPage
<          * for the arena at the bottom to point to itself.
<          *
<          * See comments in TraceDelayedChildren.
<          */
<         a->untracedThings = bit;
<         if (a->prevUntracedPage == 0) {
<             if (!rt->gcUntracedArenaStackTop) {
<                 /* Stack was empty, mark the arena as the bottom element. */
<                 a->prevUntracedPage = ARENA_INFO_TO_PAGE(a);
<             } else {
<                 JS_ASSERT(rt->gcUntracedArenaStackTop->prevUntracedPage != 0);
<                 a->prevUntracedPage =
<                     ARENA_INFO_TO_PAGE(rt->gcUntracedArenaStackTop);
<             }
<             rt->gcUntracedArenaStackTop = a;
<         }
<     }
<     JS_ASSERT(rt->gcUntracedArenaStackTop);
---
>     GC_MARK(cx, thing, "atom", NULL);
1798,1799c789,790
< static void
< TraceDelayedChildren(JSTracer *trc)
---
> void
> js_MarkAtom(JSContext *cx, JSAtom *atom, void *arg)
1801,1807c792
<     JSRuntime *rt;
<     JSGCArenaInfo *a, *aprev;
<     uint32 thingSize;
<     uint32 thingsPerUntracedBit;
<     uint32 untracedBitIndex, thingIndex, indexLimit, endIndex;
<     JSGCThing *thing;
<     uint8 *flagp;
---
>     jsval key;
1809,1812c794
<     rt = trc->context->runtime;
<     a = rt->gcUntracedArenaStackTop;
<     if (!a) {
<         JS_ASSERT(rt->gcTraceLaterCount == 0);
---
>     if (atom->flags & ATOM_MARK)
1814,1886c796,804
<     }
< 
<     for (;;) {
<         /*
<          * The following assert verifies that the current arena belongs to the
<          * untraced stack, since DelayTracingChildren ensures that even for
<          * stack's bottom prevUntracedPage != 0 but rather points to itself.
<          */
<         JS_ASSERT(a->prevUntracedPage != 0);
<         JS_ASSERT(rt->gcUntracedArenaStackTop->prevUntracedPage != 0);
<         thingSize = a->list->thingSize;
<         indexLimit = (a == a->list->last)
<                      ? a->list->lastCount
<                      : THINGS_PER_ARENA(thingSize);
<         thingsPerUntracedBit = THINGS_PER_UNTRACED_BIT(thingSize);
< 
<         /*
<          * We can not use do-while loop here as a->untracedThings can be zero
<          * before the loop as a leftover from the previous iterations. See
<          * comments after the loop.
<          */
<         while (a->untracedThings != 0) {
<             untracedBitIndex = JS_FLOOR_LOG2W(a->untracedThings);
<             a->untracedThings &= ~((jsuword)1 << untracedBitIndex);
<             thingIndex = untracedBitIndex * thingsPerUntracedBit;
<             endIndex = thingIndex + thingsPerUntracedBit;
< 
<             /*
<              * endIndex can go beyond the last allocated thing as the real
<              * limit can be "inside" the bit.
<              */
<             if (endIndex > indexLimit)
<                 endIndex = indexLimit;
<             JS_ASSERT(thingIndex < indexLimit);
< 
<             do {
<                 /*
<                  * Skip free or already traced things that share the bit
<                  * with untraced ones.
<                  */
<                 flagp = THING_FLAGP(a, thingIndex);
<                 if ((*flagp & (GCF_MARK|GCF_FINAL)) != (GCF_MARK|GCF_FINAL))
<                     continue;
<                 *flagp &= ~GCF_FINAL;
< #ifdef DEBUG
<                 JS_ASSERT(rt->gcTraceLaterCount != 0);
<                 --rt->gcTraceLaterCount;
< #endif
<                 thing = FLAGP_TO_THING(flagp, thingSize);
<                 JS_TraceChildren(trc, thing, MapGCFlagsToTraceKind(*flagp));
<             } while (++thingIndex != endIndex);
<         }
< 
<         /*
<          * We finished tracing of all things in the the arena but we can only
<          * pop it from the stack if the arena is the stack's top.
<          *
<          * When JS_TraceChildren from the above calls JS_CallTracer that in
<          * turn on low C stack calls DelayTracingChildren and the latter
<          * pushes new arenas to the untraced stack, we have to skip popping
<          * of this arena until it becomes the top of the stack again.
<          */
<         if (a == rt->gcUntracedArenaStackTop) {
<             aprev = ARENA_PAGE_TO_INFO(a->prevUntracedPage);
<             a->prevUntracedPage = 0;
<             if (a == aprev) {
<                 /*
<                  * prevUntracedPage points to itself and we reached the
<                  * bottom of the stack.
<                  */
<                 break;
<             }
<             rt->gcUntracedArenaStackTop = a = aprev;
---
>     atom->flags |= ATOM_MARK;
>     key = ATOM_KEY(atom);
>     if (JSVAL_IS_GCTHING(key)) {
> #ifdef GC_MARK_DEBUG
>         char name[32];
> 
>         if (JSVAL_IS_STRING(key)) {
>             JS_snprintf(name, sizeof name, "'%s'",
>                         JS_GetStringBytes(JSVAL_TO_STRING(key)));
1888c806
<             a = rt->gcUntracedArenaStackTop;
---
>             JS_snprintf(name, sizeof name, "<%x>", key);
1889a808,809
> #endif
>         GC_MARK(cx, JSVAL_TO_GCTHING(key), name, arg);
1891,1894d810
<     JS_ASSERT(rt->gcUntracedArenaStackTop);
<     JS_ASSERT(rt->gcUntracedArenaStackTop->prevUntracedPage == 0);
<     rt->gcUntracedArenaStackTop = NULL;
<     JS_ASSERT(rt->gcTraceLaterCount == 0);
1897,1898c813,814
< JS_PUBLIC_API(void)
< JS_CallTracer(JSTracer *trc, void *thing, uint32 kind)
---
> void
> js_MarkGCThing(JSContext *cx, void *thing, void *arg)
1900c816
<     JSContext *cx;
---
>     uint8 flags, *flagp;
1902c818,825
<     uint8 *flagp;
---
>     JSObject *obj;
>     uint32 nslots;
>     jsval v, *vp, *end;
>     JSString *str;
> #ifdef GC_MARK_DEBUG
>     JSScope *scope;
>     JSScopeProperty *sprop;
> #endif
1904,1906c827,828
<     JS_ASSERT(thing);
<     JS_ASSERT(JS_IS_VALID_TRACE_KIND(kind));
<     JS_ASSERT(trc->debugPrinter || trc->debugPrintArg);
---
>     if (!thing)
>         return;
1908,1911c830,839
<     if (!IS_GC_MARKING_TRACER(trc)) {
<         trc->callback(trc, thing, kind);
<         goto out;
<     }
---
>     flagp = js_GetGCThingFlags(thing);
>     flags = *flagp;
>     JS_ASSERT(flags != GCF_FINAL);
> #ifdef GC_MARK_DEBUG
>     if (js_LiveThingToFind == thing)
>         gc_dump_thing(thing, flags, arg, stderr);
> #endif
> 
>     if (flags & GCF_MARK)
>         return;
1913c841
<     cx = trc->context;
---
>     *flagp |= GCF_MARK;
1915,1916c843,844
<     JS_ASSERT(rt->gcMarkingTracer == trc);
<     JS_ASSERT(rt->gcLevel > 0);
---
>     METER(if (++rt->gcStats.depth > rt->gcStats.maxdepth)
>               rt->gcStats.maxdepth = rt->gcStats.depth);
1918,1928c846,849
<     /*
<      * Optimize for string and double as their size is known and their tracing
<      * is not recursive.
<      */
<     switch (kind) {
<       case JSTRACE_DOUBLE:
<         flagp = THING_TO_FLAGP(thing, sizeof(JSGCThing));
<         JS_ASSERT((*flagp & GCF_FINAL) == 0);
<         JS_ASSERT(kind == MapGCFlagsToTraceKind(*flagp));
<         *flagp |= GCF_MARK;
<         goto out;
---
> #ifdef GC_MARK_DEBUG
>     if (js_DumpGCHeap)
>         gc_dump_thing(thing, flags, arg, js_DumpGCHeap);
> #endif
1930,1937c851,916
<       case JSTRACE_STRING:
<         for (;;) {
<             flagp = THING_TO_FLAGP(thing, sizeof(JSGCThing));
<             JS_ASSERT((*flagp & GCF_FINAL) == 0);
<             JS_ASSERT(kind == MapGCFlagsToTraceKind(*flagp));
<             if (!JSSTRING_IS_DEPENDENT((JSString *) thing)) {
<                 *flagp |= GCF_MARK;
<                 goto out;
---
>     switch (flags & GCF_TYPEMASK) {
>       case GCX_OBJECT:
>         obj = (JSObject *) thing;
>         vp = obj->slots;
>         if (!vp) {
>             /* If obj->slots is null, obj must be a newborn. */
>             JS_ASSERT(!obj->map);
>             goto out;
>         }
>         nslots = (obj->map->ops->mark)
>                  ? obj->map->ops->mark(cx, obj, arg)
>                  : JS_MIN(obj->map->freeslot, obj->map->nslots);
> #ifdef GC_MARK_DEBUG
>         scope = OBJ_IS_NATIVE(obj) ? OBJ_SCOPE(obj) : NULL;
> #endif
>         for (end = vp + nslots; vp < end; vp++) {
>             v = *vp;
>             if (JSVAL_IS_GCTHING(v)) {
> #ifdef GC_MARK_DEBUG
>                 char name[32];
> 
>                 if (scope) {
>                     uint32 slot;
>                     jsval nval;
> 
>                     slot = vp - obj->slots;
>                     for (sprop = SCOPE_LAST_PROP(scope); ;
>                          sprop = sprop->parent) {
>                         if (!sprop) {
>                             switch (slot) {
>                               case JSSLOT_PROTO:
>                                 strcpy(name, "__proto__");
>                                 break;
>                               case JSSLOT_PARENT:
>                                 strcpy(name, "__parent__");
>                                 break;
>                               case JSSLOT_PRIVATE:
>                                 strcpy(name, "__private__");
>                                 break;
>                               default:
>                                 JS_snprintf(name, sizeof name,
>                                             "**UNKNOWN SLOT %ld**",
>                                             (long)slot);
>                                 break;
>                             }
>                             break;
>                         }
>                         if (sprop->slot == slot) {
>                             nval = ID_TO_VALUE(sprop->id);
>                             if (JSVAL_IS_INT(nval)) {
>                                 JS_snprintf(name, sizeof name, "%ld",
>                                             (long)JSVAL_TO_INT(nval));
>                             } else if (JSVAL_IS_STRING(nval)) {
>                                 JS_snprintf(name, sizeof name, "%s",
>                                   JS_GetStringBytes(JSVAL_TO_STRING(nval)));
>                             } else {
>                                 strcpy(name, "**FINALIZED ATOM KEY**");
>                             }
>                             break;
>                         }
>                     }
>                 } else {
>                     strcpy(name, "**UNKNOWN OBJECT MAP ENTRY**");
>                 }
> #endif
>                 GC_MARK(cx, JSVAL_TO_GCTHING(v), name, arg);
1939,1942d917
<             if (*flagp & GCF_MARK)
<                 goto out;
<             *flagp |= GCF_MARK;
<             thing = JSSTRDEP_BASE((JSString *) thing);
1944,1994c919
<         /* NOTREACHED */
<     }
< 
<     flagp = GetGCThingFlags(thing);
<     JS_ASSERT(kind == MapGCFlagsToTraceKind(*flagp));
<     if (*flagp & GCF_MARK)
<         goto out;
< 
<     /*
<      * We check for non-final flag only if mark is unset as
<      * DelayTracingChildren uses the flag. See comments in the function.
<      */
<     JS_ASSERT(*flagp != GCF_FINAL);
<     *flagp |= GCF_MARK;
<     if (!cx->insideGCMarkCallback) {
<         /*
<          * With JS_GC_ASSUME_LOW_C_STACK defined the mark phase of GC always
<          * uses the non-recursive code that otherwise would be called only on
<          * a low C stack condition.
<          */
< #ifdef JS_GC_ASSUME_LOW_C_STACK
< # define RECURSION_TOO_DEEP() JS_TRUE
< #else
<         int stackDummy;
< # define RECURSION_TOO_DEEP() (!JS_CHECK_STACK_SIZE(cx, stackDummy))
< #endif
<         if (RECURSION_TOO_DEEP())
<             DelayTracingChildren(rt, flagp);
<         else
<             JS_TraceChildren(trc, thing, kind);
<     } else {
<         /*
<          * For API compatibility we allow for the callback to assume that
<          * after it calls JS_MarkGCThing for the last time, the callback can
<          * start to finalize its own objects that are only referenced by
<          * unmarked GC things.
<          *
<          * Since we do not know which call from inside the callback is the
<          * last, we ensure that children of all marked things are traced and
<          * call TraceDelayedChildren(trc) after tracing the thing.
<          *
<          * As TraceDelayedChildren unconditionally invokes JS_TraceChildren
<          * for the things with untraced children, calling DelayTracingChildren
<          * is useless here. Hence we always trace thing's children even with a
<          * low native stack.
<          */
<         cx->insideGCMarkCallback = JS_FALSE;
<         JS_TraceChildren(trc, thing, kind);
<         TraceDelayedChildren(trc);
<         cx->insideGCMarkCallback = JS_TRUE;
<     }
---
>         break;
1996d920
<   out:
1998,1999c922,925
<     trc->debugPrinter = NULL;
<     trc->debugPrintArg = NULL;
---
>       case GCX_STRING:
>         str = (JSString *)thing;
>         JS_ASSERT(!JSSTRING_IS_DEPENDENT(str));
>         break;
2001,2008d926
<     return;     /* to avoid out: right_curl when DEBUG is not defined */
< }
< 
< void
< js_CallValueTracerIfGCThing(JSTracer *trc, jsval v)
< {
<     void *thing;
<     uint32 kind;
2010,2019c928,932
<     if (JSVAL_IS_DOUBLE(v) || JSVAL_IS_STRING(v)) {
<         thing = JSVAL_TO_TRACEABLE(v);
<         kind = JSVAL_TRACE_KIND(v);
<         JS_ASSERT(kind == js_GetGCThingTraceKind(JSVAL_TO_GCTHING(v)));
<     } else if (JSVAL_IS_OBJECT(v) && v != JSVAL_NULL) {
<         /* v can be an arbitrary GC thing reinterpreted as an object. */
<         thing = JSVAL_TO_OBJECT(v);
<         kind = js_GetGCThingTraceKind(thing);
<     } else {
<         return;
---
>       case GCX_MUTABLE_STRING:
>         str = (JSString *)thing;
>         if (JSSTRING_IS_DEPENDENT(str))
>             GC_MARK(cx, JSSTRDEP_BASE(str), "base", arg);
>         break;
2021c934,936
<     JS_CallTracer(trc, thing, kind);
---
> 
> out:
>     METER(rt->gcStats.depth--);
2025,2026c940
< gc_root_traversal(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 num,
<                   void *arg)
---
> gc_root_marker(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 num, void *arg)
2029d942
<     JSTracer *trc = (JSTracer *)arg;
2034a948
>         JSContext *cx = (JSContext *)arg;
2036,2053c950,959
<         JSBool root_points_to_gcArenaList = JS_FALSE;
<         jsuword thing = (jsuword) JSVAL_TO_GCTHING(v);
<         uintN i;
<         JSGCArenaList *arenaList;
<         uint32 thingSize;
<         JSGCArenaInfo *a;
<         size_t limit;
< 
<         for (i = 0; i < GC_NUM_FREELISTS; i++) {
<             arenaList = &trc->context->runtime->gcArenaList[i];
<             thingSize = arenaList->thingSize;
<             limit = (size_t) arenaList->lastCount * thingSize;
<             for (a = arenaList->last; a; a = a->prev) {
<                 if (thing - ARENA_INFO_TO_START(a) < limit) {
<                     root_points_to_gcArenaList = JS_TRUE;
<                     break;
<                 }
<                 limit = (size_t) THINGS_PER_ARENA(thingSize) * thingSize;
---
>         JSArena *a;
>         jsuword firstpage;
>         JSBool root_points_to_gcArenaPool = JS_FALSE;
>         void *thing = JSVAL_TO_GCTHING(v);
> 
>         for (a = cx->runtime->gcArenaPool.first.next; a; a = a->next) {
>             firstpage = FIRST_THING_PAGE(a);
>             if (JS_UPTRDIFF(thing, firstpage) < a->avail - firstpage) {
>                 root_points_to_gcArenaPool = JS_TRUE;
>                 break;
2056c962
<         if (!root_points_to_gcArenaList && rhe->name) {
---
>         if (!root_points_to_gcArenaPool && rhe->name) {
2063c969
<         JS_ASSERT(root_points_to_gcArenaList);
---
>         JS_ASSERT(root_points_to_gcArenaPool);
2065,2067d970
<         JS_SET_TRACING_NAME(trc, rhe->name ? rhe->name : "root");
<         js_CallValueTracerIfGCThing(trc, v);
<     }
2068a972,973
>         GC_MARK(cx, JSVAL_TO_GCTHING(v), rhe->name ? rhe->name : "root", NULL);
>     }
2073,2074c978
< gc_lock_traversal(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 num,
<                   void *arg)
---
> gc_lock_marker(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 num, void *arg)
2078,2079c982
<     JSTracer *trc = (JSTracer *)arg;
<     uint32 traceKind;
---
>     JSContext *cx = (JSContext *)arg;
2081,2083c984
<     JS_ASSERT(lhe->count >= 1);
<     traceKind = js_GetGCThingTraceKind(thing);
<     JS_CALL_TRACER(trc, thing, traceKind, "locked object");
---
>     GC_MARK(cx, thing, "locked object", NULL);
2087c988,1001
< #define TRACE_JSVALS(trc, len, vec, name)                                     \
---
> void
> js_ForceGC(JSContext *cx, uintN gcflags)
> {
>     uintN i;
> 
>     for (i = 0; i < GCX_NTYPES; i++)
>         cx->newborn[i] = NULL;
>     cx->lastAtom = NULL;
>     cx->runtime->gcPoke = JS_TRUE;
>     js_GC(cx, gcflags);
>     JS_ArenaFinish();
> }
> 
> #define GC_MARK_JSVALS(cx, len, vec, name)                                    \
2089c1003
<     jsval _v, *_vp, *_end;                                                    \
---
>         jsval _v, *_vp, *_end;                                                \
2093,2097c1007,1008
<             if (JSVAL_IS_TRACEABLE(_v)) {                                     \
<                 JS_SET_TRACING_INDEX(trc, name, _vp - (vec));                 \
<                 JS_CallTracer(trc, JSVAL_TO_TRACEABLE(_v),                    \
<                               JSVAL_TRACE_KIND(_v));                          \
<             }                                                                 \
---
>             if (JSVAL_IS_GCTHING(_v))                                         \
>                 GC_MARK(cx, JSVAL_TO_GCTHING(_v), name, NULL);                \
2102,2411c1013
< js_TraceStackFrame(JSTracer *trc, JSStackFrame *fp)
< {
<     uintN nslots, minargs, skip;
< 
<     if (fp->callobj)
<         JS_CALL_OBJECT_TRACER(trc, fp->callobj, "call");
<     if (fp->argsobj)
<         JS_CALL_OBJECT_TRACER(trc, fp->argsobj, "arguments");
<     if (fp->varobj)
<         JS_CALL_OBJECT_TRACER(trc, fp->varobj, "variables");
<     if (fp->script) {
<         js_TraceScript(trc, fp->script);
<         if (fp->spbase) {
<             /*
<              * Don't mark what has not been pushed yet, or what has been
<              * popped already.
<              */
<             JS_ASSERT(JS_UPTRDIFF(fp->sp, fp->spbase) <=
<                       fp->script->depth * sizeof(jsval));
<             nslots = (uintN) (fp->sp - fp->spbase);
<             TRACE_JSVALS(trc, nslots, fp->spbase, "operand");
<         }
<     }
< 
<     /* Allow for primitive this parameter due to JSFUN_THISP_* flags. */
<     JS_ASSERT(JSVAL_IS_OBJECT((jsval)fp->thisp) ||
<               (fp->fun && JSFUN_THISP_FLAGS(fp->fun->flags)));
<     JS_CALL_VALUE_TRACER(trc, (jsval)fp->thisp, "this");
< 
<     if (fp->callee)
<         JS_CALL_OBJECT_TRACER(trc, fp->callee, "callee");
< 
<     if (fp->argv) {
<         nslots = fp->argc;
<         skip = 0;
<         if (fp->fun) {
<             minargs = FUN_MINARGS(fp->fun);
<             if (minargs > nslots)
<                 nslots = minargs;
<             if (!FUN_INTERPRETED(fp->fun)) {
<                 JS_ASSERT(!(fp->fun->flags & JSFUN_FAST_NATIVE));
<                 nslots += fp->fun->u.n.extra;
<             }
<             if (fp->fun->flags & JSFRAME_ROOTED_ARGV)
<                 skip = 2 + fp->argc;
<         }
<         TRACE_JSVALS(trc, 2 + nslots - skip, fp->argv - 2 + skip, "operand");
<     }
<     JS_CALL_VALUE_TRACER(trc, fp->rval, "rval");
<     if (fp->vars)
<         TRACE_JSVALS(trc, fp->nvars, fp->vars, "var");
<     if (fp->scopeChain)
<         JS_CALL_OBJECT_TRACER(trc, fp->scopeChain, "scope chain");
<     if (fp->sharpArray)
<         JS_CALL_OBJECT_TRACER(trc, fp->sharpArray, "sharp array");
< 
<     if (fp->xmlNamespace)
<         JS_CALL_OBJECT_TRACER(trc, fp->xmlNamespace, "xmlNamespace");
< }
< 
< static void
< TraceWeakRoots(JSTracer *trc, JSWeakRoots *wr)
< {
<     uint32 i;
<     void *thing;
< 
< #ifdef DEBUG
<     static const char *weakRootNames[JSTRACE_LIMIT] = {
<         "newborn object",
<         "newborn double",
<         "newborn string",
<         "newborn function",
<         "newborn namespace",
<         "newborn qname",
<         "newborn xml"
<     };
< #endif
< 
<     for (i = 0; i != JSTRACE_LIMIT; i++) {
<         thing = wr->newborn[i];
<         if (thing)
<             JS_CALL_TRACER(trc, thing, i, weakRootNames[i]);
<     }
<     JS_ASSERT(i == GCX_EXTERNAL_STRING);
<     for (; i != GCX_NTYPES; ++i) {
<         thing = wr->newborn[i];
<         if (thing) {
<             JS_SET_TRACING_INDEX(trc, "newborn external string",
<                                  i - GCX_EXTERNAL_STRING);
<             JS_CallTracer(trc, thing, JSTRACE_STRING);
<         }
<     }
< 
<     JS_CALL_VALUE_TRACER(trc, wr->lastAtom, "lastAtom");
<     JS_SET_TRACING_NAME(trc, "lastInternalResult");
<     js_CallValueTracerIfGCThing(trc, wr->lastInternalResult);
< }
< 
< JS_FRIEND_API(void)
< js_TraceContext(JSTracer *trc, JSContext *acx)
< {
<     JSArena *a;
<     int64 age;
<     JSStackFrame *fp, *nextChain;
<     JSStackHeader *sh;
<     JSTempValueRooter *tvr;
< 
<     if (IS_GC_MARKING_TRACER(trc)) {
<         /*
<          * Release stackPool here, if it has been in existence for longer than
<          * the limit specified by gcStackPoolLifespan.
<          */
<         a = acx->stackPool.current;
<         if (a == acx->stackPool.first.next &&
<             a->avail == a->base + sizeof(int64)) {
<             age = JS_Now() - *(int64 *) a->base;
<             if (age > (int64) acx->runtime->gcStackPoolLifespan * 1000)
<                 JS_FinishArenaPool(&acx->stackPool);
<         }
<     }
< 
<     /*
<      * Iterate frame chain and dormant chains.
<      *
<      * (NB: see comment on this whole "dormant" thing in js_Execute.)
<      */
<     fp = acx->fp;
<     nextChain = acx->dormantFrameChain;
<     if (!fp)
<         goto next_chain;
< 
<     /* The top frame must not be dormant. */
<     JS_ASSERT(!fp->dormantNext);
<     for (;;) {
<         do {
<             js_TraceStackFrame(trc, fp);
<         } while ((fp = fp->down) != NULL);
< 
<       next_chain:
<         if (!nextChain)
<             break;
<         fp = nextChain;
<         nextChain = nextChain->dormantNext;
<     }
< 
<     /* Mark other roots-by-definition in acx. */
<     if (acx->globalObject)
<         JS_CALL_OBJECT_TRACER(trc, acx->globalObject, "global object");
<     TraceWeakRoots(trc, &acx->weakRoots);
<     if (acx->throwing) {
<         JS_CALL_VALUE_TRACER(trc, acx->exception, "exception");
<     } else {
<         /* Avoid keeping GC-ed junk stored in JSContext.exception. */
<         acx->exception = JSVAL_NULL;
<     }
< #if JS_HAS_LVALUE_RETURN
<     if (acx->rval2set)
<         JS_CALL_VALUE_TRACER(trc, acx->rval2, "rval2");
< #endif
< 
<     for (sh = acx->stackHeaders; sh; sh = sh->down) {
<         METER(trc->context->runtime->gcStats.stackseg++);
<         METER(trc->context->runtime->gcStats.segslots += sh->nslots);
<         TRACE_JSVALS(trc, sh->nslots, JS_STACK_SEGMENT(sh), "stack");
<     }
< 
<     if (acx->localRootStack)
<         js_TraceLocalRoots(trc, acx->localRootStack);
< 
<     for (tvr = acx->tempValueRooters; tvr; tvr = tvr->down) {
<         switch (tvr->count) {
<           case JSTVU_SINGLE:
<             JS_SET_TRACING_NAME(trc, "tvr->u.value");
<             js_CallValueTracerIfGCThing(trc, tvr->u.value);
<             break;
<           case JSTVU_TRACE:
<             tvr->u.trace(trc, tvr);
<             break;
<           case JSTVU_SPROP:
<             TRACE_SCOPE_PROPERTY(trc, tvr->u.sprop);
<             break;
<           case JSTVU_WEAK_ROOTS:
<             TraceWeakRoots(trc, tvr->u.weakRoots);
<             break;
<           case JSTVU_PARSE_CONTEXT:
<             js_TraceParseContext(trc, tvr->u.parseContext);
<             break;
<           case JSTVU_SCRIPT:
<             js_TraceScript(trc, tvr->u.script);
<             break;
<           default:
<             JS_ASSERT(tvr->count >= 0);
<             TRACE_JSVALS(trc, tvr->count, tvr->u.array, "tvr->u.array");
<         }
<     }
< 
<     if (acx->sharpObjectMap.depth > 0)
<         js_TraceSharpMap(trc, &acx->sharpObjectMap);
< }
< 
< void
< js_TraceRuntime(JSTracer *trc, JSBool allAtoms)
< {
<     JSRuntime *rt = trc->context->runtime;
<     JSContext *iter, *acx;
< 
<     JS_DHashTableEnumerate(&rt->gcRootsHash, gc_root_traversal, trc);
<     if (rt->gcLocksHash)
<         JS_DHashTableEnumerate(rt->gcLocksHash, gc_lock_traversal, trc);
<     js_TraceAtomState(trc, allAtoms);
<     js_TraceNativeIteratorStates(trc);
< 
<     iter = NULL;
<     while ((acx = js_ContextIterator(rt, JS_TRUE, &iter)) != NULL)
<         js_TraceContext(trc, acx);
< 
<     if (rt->gcExtraRootsTraceOp)
<         rt->gcExtraRootsTraceOp(trc, rt->gcExtraRootsData);
< }
< 
< static void
< ProcessSetSlotRequest(JSContext *cx, JSSetSlotRequest *ssr)
< {
<     JSObject *obj, *pobj;
<     uint32 slot;
< 
<     obj = ssr->obj;
<     pobj = ssr->pobj;
<     slot = ssr->slot;
< 
<     while (pobj) {
<         JSClass *clasp = STOBJ_GET_CLASS(pobj);
<         if (clasp->flags & JSCLASS_IS_EXTENDED) {
<             JSExtendedClass *xclasp = (JSExtendedClass *) clasp;
<             if (xclasp->wrappedObject) {
<                 /* If there is no wrapped object, use the wrapper. */
<                 JSObject *wrapped = xclasp->wrappedObject(cx, pobj);
<                 if (wrapped)
<                     pobj = wrapped;
<             }
<         }
< 
<         if (pobj == obj) {
<             ssr->errnum = JSMSG_CYCLIC_VALUE;
<             return;
<         }
<         pobj = JSVAL_TO_OBJECT(STOBJ_GET_SLOT(pobj, slot));
<     }
< 
<     pobj = ssr->pobj;
< 
<     if (slot == JSSLOT_PROTO && OBJ_IS_NATIVE(obj)) {
<         JSScope *scope, *newscope;
<         JSObject *oldproto;
< 
<         /* Check to see whether obj shares its prototype's scope. */
<         scope = OBJ_SCOPE(obj);
<         oldproto = STOBJ_GET_PROTO(obj);
<         if (oldproto && OBJ_SCOPE(oldproto) == scope) {
<             /* Either obj needs a new empty scope, or it should share pobj's. */
<             if (!pobj ||
<                 !OBJ_IS_NATIVE(pobj) ||
<                 OBJ_GET_CLASS(cx, pobj) != STOBJ_GET_CLASS(oldproto)) {
<                 /*
<                  * With no proto and no scope of its own, obj is truly empty.
<                  *
<                  * If pobj is not native, obj needs its own empty scope -- it
<                  * should not continue to share oldproto's scope once oldproto
<                  * is not on obj's prototype chain.  That would put properties
<                  * from oldproto's scope ahead of properties defined by pobj,
<                  * in lookup order.
<                  *
<                  * If pobj's class differs from oldproto's, we may need a new
<                  * scope to handle differences in private and reserved slots,
<                  * so we suboptimally but safely make one.
<                  */
<                 if (!js_GetMutableScope(cx, obj)) {
<                     ssr->errnum = JSMSG_OUT_OF_MEMORY;
<                     return;
<                 }
<             } else if (OBJ_SCOPE(pobj) != scope) {
<                 newscope = (JSScope *) js_HoldObjectMap(cx, pobj->map);
<                 obj->map = &newscope->map;
<                 js_DropObjectMap(cx, &scope->map, obj);
<                 JS_TRANSFER_SCOPE_LOCK(cx, scope, newscope);
<             }
<         }
< 
<         /*
<          * Regenerate property cache shape ids for all of the scopes along the
<          * old prototype chain, in case any property cache entries were filled
<          * by looking up starting from obj.
<          */
<         while (oldproto && OBJ_IS_NATIVE(oldproto)) {
<             scope = OBJ_SCOPE(oldproto);
<             SCOPE_GENERATE_PCTYPE(cx, scope);
<             oldproto = STOBJ_GET_PROTO(scope->object);
<         }
<     }
< 
<     /* Finally, do the deed. */
<     STOBJ_SET_SLOT(obj, slot, OBJECT_TO_JSVAL(pobj));
< }
< 
< /*
<  * The gckind flag bit GC_LOCK_HELD indicates a call from js_NewGCThing with
<  * rt->gcLock already held, so the lock should be kept on return.
<  */
< void
< js_GC(JSContext *cx, JSGCInvocationKind gckind)
---
> js_GC(JSContext *cx, uintN gcflags)
2414,2423c1016,1024
<     JSBool keepAtoms;
<     JSGCCallback callback;
<     uintN i, type;
<     JSTracer trc;
<     uint32 thingSize, indexLimit;
<     JSGCArenaInfo *a, **ap, *emptyArenas;
<     uint8 flags, *flagp;
<     JSGCThing *thing, *freeList;
<     JSGCArenaList *arenaList;
<     JSBool allClear;
---
>     JSContext *iter, *acx;
>     JSStackFrame *fp, *chain;
>     uintN i, depth, nslots, type;
>     JSStackHeader *sh;
>     JSArena *a, **ap;
>     uint8 flags, *flagp, *split;
>     JSGCThing *thing, *limit, **flp, **oflp;
>     GCFinalizeOp finalizer;
>     JSBool all_clear;
2424a1026
>     jsword currentThread;
2426,2430d1027
<     JSContext *acx, *iter;
< #endif
< #ifdef JS_GCMETER
<     JSGCArenaStats *listStats;
<     size_t nfree;
2439,2450d1035
<     if (gckind & GC_KEEP_ATOMS) {
<         /*
<          * The set slot request and last ditch GC kinds preserve all atoms and
<          * weak roots.
<          */
<         keepAtoms = JS_TRUE;
<     } else {
<         /* Keep atoms when a suspended compile is running on another context. */
<         keepAtoms = (rt->gcKeepAtoms != 0);
<         JS_CLEAR_WEAK_ROOTS(&cx->weakRoots);
<     }
< 
2452,2455c1037,1040
<      * Don't collect garbage if the runtime isn't up, and cx is not the last
<      * context in the runtime.  The last context must force a GC, and nothing
<      * should suppress that final collection or there may be shutdown leaks,
<      * or runtime bloat until the next context is created.
---
>      * Don't collect garbage if the runtime is down or if GC is disabled, and
>      * we're not the last context in the runtime.  The last context must force
>      * a GC, and nothing should disable that final collection or there may be
>      * shutdown leaks, or runtime bloat until the next context is created.
2457c1042,1043
<     if (rt->state != JSRTS_UP && gckind != GC_LAST_CONTEXT)
---
>     if ((rt->state != JSRTS_UP || rt->gcDisabled) &&
>         !(gcflags & GC_LAST_CONTEXT)) {
2458a1045
>     }
2460d1046
<   restart_at_beginning:
2463,2465c1049
<      * is the last context).  Invoke the callback regardless. Sample the
<      * callback in case we are freely racing with a JS_SetGCCallback{,RT} on
<      * another thread.
---
>      * is the last context).  Invoke the callback regardless.
2467,2475c1051,1052
<     if (gckind != GC_SET_SLOT_REQUEST && (callback = rt->gcCallback)) {
<         JSBool ok;
< 
<         if (gckind & GC_LOCK_HELD)
<             JS_UNLOCK_GC(rt);
<         ok = callback(cx, JSGC_BEGIN);
<         if (gckind & GC_LOCK_HELD)
<             JS_LOCK_GC(rt);
<         if (!ok && gckind != GC_LAST_CONTEXT)
---
>     if (rt->gcCallback) {
>         if (!rt->gcCallback(cx, JSGC_BEGIN) && !(gcflags & GC_LAST_CONTEXT))
2480c1057
<     if (!(gckind & GC_LOCK_HELD))
---
>     if (!(gcflags & GC_ALREADY_LOCKED))
2482a1060,1066
>     /* Do nothing if no assignment has executed since the last GC. */
>     if (!rt->gcPoke) {
>         METER(rt->gcStats.nopoke++);
>         if (!(gcflags & GC_ALREADY_LOCKED))
>             JS_UNLOCK_GC(rt);
>         return;
>     }
2484d1067
<     rt->gcPoke = JS_FALSE;
2485a1069,1075
> 	// !!@ 2003.12.03 jht: Set gcPoke FALSE earlier to enable finalizers to restart gc 
> 	// when context is been shutdown
> 	#define DP_FIX
> 	#ifdef DP_FIX
> 	rt->gcPoke = JS_FALSE;
> 	#endif
> 	
2487,2488d1076
<     JS_ASSERT(cx->thread->id == js_CurrentThreadId());
< 
2490c1078,1079
<     if (rt->gcThread == cx->thread) {
---
>     currentThread = js_CurrentThreadId();
>     if (rt->gcThread == currentThread) {
2493,2494c1082,1084
<         METER_UPDATE_MAX(rt->gcStats.maxlevel, rt->gcLevel);
<         if (!(gckind & GC_LOCK_HELD))
---
>         METER(if (rt->gcLevel > rt->gcStats.maxlevel)
>                   rt->gcStats.maxlevel = rt->gcLevel);
>         if (!(gcflags & GC_ALREADY_LOCKED))
2502c1092
<      * requests are inactive.  If cx->thread is NULL, then cx is not using
---
>      * requests are inactive.  NB: if cx->thread is 0, then cx is not using
2507,2508d1096
<         JSCList *head, *link;
< 
2510,2511c1098,1099
<          * Check all contexts on cx->thread->contextList for active requests,
<          * counting each such context against requestDebit.
---
>          * Check all contexts for any with the same thread-id.  XXX should we
>          * keep a sub-list of contexts having the same id?
2513,2517c1101,1103
<         head = &cx->thread->contextList;
<         for (link = head->next; link != head; link = link->next) {
<             acx = CX_FROM_THREAD_LINKS(link);
<             JS_ASSERT(acx->thread == cx->thread);
<             if (acx->requestDepth)
---
>         iter = NULL;
>         while ((acx = js_ContextIterator(rt, JS_FALSE, &iter)) != NULL) {
>             if (acx->thread == cx->thread && acx->requestDepth)
2524c1110
<          * that the GC runs only on request-less contexts with null threads,
---
>          * that the GC runs only on request-less contexts with 0 thread-ids,
2543c1129,1130
<         METER_UPDATE_MAX(rt->gcStats.maxlevel, rt->gcLevel);
---
>         METER(if (rt->gcLevel > rt->gcStats.maxlevel)
>                   rt->gcStats.maxlevel = rt->gcLevel);
2550c1137
<         if (!(gckind & GC_LOCK_HELD))
---
>         if (!(gcflags & GC_ALREADY_LOCKED))
2557c1144
<     rt->gcThread = cx->thread;
---
>     rt->gcThread = currentThread;
2567c1154,1155
<     METER_UPDATE_MAX(rt->gcStats.maxlevel, rt->gcLevel);
---
>     METER(if (rt->gcLevel > rt->gcStats.maxlevel)
>               rt->gcStats.maxlevel = rt->gcLevel);
2582,2614d1169
< 
<     if (gckind == GC_SET_SLOT_REQUEST) {
<         JSSetSlotRequest *ssr;
< 
<         while ((ssr = rt->setSlotRequests) != NULL) {
<             rt->setSlotRequests = ssr->next;
<             JS_UNLOCK_GC(rt);
<             ssr->next = NULL;
<             ProcessSetSlotRequest(cx, ssr);
<             JS_LOCK_GC(rt);
<         }
< 
<         /*
<          * We assume here that killing links to parent and prototype objects
<          * does not create garbage (such objects typically are long-lived and
<          * widely shared, e.g. global objects, Function.prototype, etc.). We
<          * collect garbage only if a racing thread attempted GC and is waiting
<          * for us to finish (gcLevel > 1) or if someone already poked us.
<          */
<         if (rt->gcLevel == 1 && !rt->gcPoke)
<             goto done_running;
< 
<         rt->gcLevel = 0;
<         rt->gcPoke = JS_FALSE;
<         rt->gcRunning = JS_FALSE;
< #ifdef JS_THREADSAFE
<         rt->gcThread = NULL;
<         rt->requestCount += requestDebit;
< #endif
<         gckind = GC_LOCK_HELD;
<         goto restart_at_beginning;
<     }
< 
2617c1172
<     /* Reset malloc counter. */
---
>     /* Reset malloc counter */
2620c1175,1178
< #ifdef JS_DUMP_SCOPE_METERS
---
>     /* Drop atoms held by the property cache, and clear property weak links. */
>     js_DisablePropertyCache(cx);
>     js_FlushPropertyCache(cx);
> #ifdef DEBUG_brendan
2626,2661c1184
<     /*
<      * Clear property cache weak references and disable the cache so nothing
<      * can fill it during GC (this is paranoia, since scripts should not run
<      * during GC).
<      */
<     js_DisablePropertyCache(cx);
<     js_FlushPropertyCache(cx);
< 
< #ifdef JS_THREADSAFE
<     /*
<      * Set all thread local freelists to NULL. We may visit a thread's
<      * freelist more than once. To avoid redundant clearing we unroll the
<      * current thread's step.
<      *
<      * Also, in case a JSScript wrapped within an object was finalized, we
<      * null acx->thread->gsnCache.script and finish the cache's hashtable.
<      * Note that js_DestroyScript, called from script_finalize, will have
<      * already cleared cx->thread->gsnCache above during finalization, so we
<      * don't have to here.
<      */
<     memset(cx->thread->gcFreeLists, 0, sizeof cx->thread->gcFreeLists);
<     iter = NULL;
<     while ((acx = js_ContextIterator(rt, JS_FALSE, &iter)) != NULL) {
<         if (!acx->thread || acx->thread == cx->thread)
<             continue;
<         memset(acx->thread->gcFreeLists, 0, sizeof acx->thread->gcFreeLists);
<         GSN_CACHE_CLEAR(&acx->thread->gsnCache);
<         js_DisablePropertyCache(acx);
<         js_FlushPropertyCache(acx);
<     }
< #else
<     /* The thread-unsafe case just has to clear the runtime's GSN cache. */
<     GSN_CACHE_CLEAR(&rt->gsnCache);
< #endif
< 
<   restart:
---
> restart:
2663,2667d1185
<     JS_ASSERT(!rt->gcUntracedArenaStackTop);
<     JS_ASSERT(rt->gcTraceLaterCount == 0);
< 
<     /* Reset the property cache's type id generator so we can compress ids. */
<     rt->shapeGen = 0;
2672,2676c1190,1208
<     JS_TRACER_INIT(&trc, cx, NULL);
<     rt->gcMarkingTracer = &trc;
<     JS_ASSERT(IS_GC_MARKING_TRACER(&trc));
<     js_TraceRuntime(&trc, keepAtoms);
<     js_MarkScriptFilenames(rt, keepAtoms);
---
>     JS_DHashTableEnumerate(&rt->gcRootsHash, gc_root_marker, cx);
>     if (rt->gcLocksHash)
>         JS_DHashTableEnumerate(rt->gcLocksHash, gc_lock_marker, cx);
>     js_MarkAtomState(&rt->atomState, gcflags, gc_mark_atom_key_thing, cx);
>     iter = NULL;
>     while ((acx = js_ContextIterator(rt, JS_TRUE, &iter)) != NULL) {
>         /*
>          * Iterate frame chain and dormant chains. Temporarily tack current
>          * frame onto the head of the dormant list to ease iteration.
>          *
>          * (NB: see comment on this whole "dormant" thing in js_Execute.)
>          */
>         chain = acx->fp;
>         if (chain) {
>             JS_ASSERT(!chain->dormantNext);
>             chain->dormantNext = acx->dormantFrameChain;
>         } else {
>             chain = acx->dormantFrameChain;
>         }
2678,2682c1210,1260
<     /*
<      * Mark children of things that caused too deep recursion during the above
<      * tracing.
<      */
<     TraceDelayedChildren(&trc);
---
>         for (fp = chain; fp; fp = chain = chain->dormantNext) {
>             do {
>                 if (fp->callobj)
>                     GC_MARK(cx, fp->callobj, "call object", NULL);
>                 if (fp->argsobj)
>                     GC_MARK(cx, fp->argsobj, "arguments object", NULL);
>                 if (fp->varobj)
>                     GC_MARK(cx, fp->varobj, "variables object", NULL);
>                 if (fp->script) {
>                     js_MarkScript(cx, fp->script, NULL);
>                     if (fp->spbase) {
>                         /*
>                          * Don't mark what has not been pushed yet, or what
>                          * has been popped already.
>                          */
>                         depth = fp->script->depth;
>                         nslots = (JS_UPTRDIFF(fp->sp, fp->spbase)
>                                   < depth * sizeof(jsval))
>                                  ? (uintN)(fp->sp - fp->spbase)
>                                  : depth;
>                         GC_MARK_JSVALS(cx, nslots, fp->spbase, "operand");
>                     }
>                 }
>                 GC_MARK(cx, fp->thisp, "this", NULL);
>                 if (fp->argv) {
>                     nslots = fp->argc;
>                     if (fp->fun && fp->fun->nargs > nslots)
>                         nslots = fp->fun->nargs;
>                     GC_MARK_JSVALS(cx, nslots, fp->argv, "arg");
>                 }
>                 if (JSVAL_IS_GCTHING(fp->rval))
>                     GC_MARK(cx, JSVAL_TO_GCTHING(fp->rval), "rval", NULL);
>                 if (fp->vars)
>                     GC_MARK_JSVALS(cx, fp->nvars, fp->vars, "var");
>                 GC_MARK(cx, fp->scopeChain, "scope chain", NULL);
>                 if (fp->sharpArray)
>                     GC_MARK(cx, fp->sharpArray, "sharp array", NULL);
> 
>                 if (fp->objAtomMap) {
>                     JSAtom **vector, *atom;
> 
>                     nslots = fp->objAtomMap->length;
>                     vector = fp->objAtomMap->vector;
>                     for (i = 0; i < nslots; i++) {
>                         atom = vector[i];
>                         if (atom)
>                             GC_MARK_ATOM(cx, atom, NULL);
>                     }
>                 }
>             } while ((fp = fp->down) != NULL);
>         }
2684,2689c1262,1290
<     JS_ASSERT(!cx->insideGCMarkCallback);
<     if (rt->gcCallback) {
<         cx->insideGCMarkCallback = JS_TRUE;
<         (void) rt->gcCallback(cx, JSGC_MARK_END);
<         JS_ASSERT(cx->insideGCMarkCallback);
<         cx->insideGCMarkCallback = JS_FALSE;
---
>         /* Cleanup temporary "dormant" linkage. */
>         if (acx->fp)
>             acx->fp->dormantNext = NULL;
> 
>         /* Mark other roots-by-definition in acx. */
>         GC_MARK(cx, acx->globalObject, "global object", NULL);
>         GC_MARK(cx, acx->newborn[GCX_OBJECT], "newborn object", NULL);
>         GC_MARK(cx, acx->newborn[GCX_STRING], "newborn string", NULL);
>         GC_MARK(cx, acx->newborn[GCX_DOUBLE], "newborn double", NULL);
>         GC_MARK(cx, acx->newborn[GCX_MUTABLE_STRING], "newborn mutable string",
>                 NULL);
>         for (i = GCX_EXTERNAL_STRING; i < GCX_NTYPES; i++)
>             GC_MARK(cx, acx->newborn[i], "newborn external string", NULL);
>         if (acx->lastAtom)
>             GC_MARK_ATOM(cx, acx->lastAtom, NULL);
> #if JS_HAS_EXCEPTIONS
>         if (acx->throwing && JSVAL_IS_GCTHING(acx->exception))
>             GC_MARK(cx, JSVAL_TO_GCTHING(acx->exception), "exception", NULL);
> #endif
> #if JS_HAS_LVALUE_RETURN
>         if (acx->rval2set && JSVAL_IS_GCTHING(acx->rval2))
>             GC_MARK(cx, JSVAL_TO_GCTHING(acx->rval2), "rval2", NULL);
> #endif
> 
>         for (sh = acx->stackHeaders; sh; sh = sh->down) {
>             METER(rt->gcStats.stackseg++);
>             METER(rt->gcStats.segslots += sh->nslots);
>             GC_MARK_JSVALS(cx, sh->nslots, JS_STACK_SEGMENT(sh), "stack");
>         }
2691d1291
<     JS_ASSERT(rt->gcTraceLaterCount == 0);
2693c1293,1294
<     rt->gcMarkingTracer = NULL;
---
>     if (rt->gcCallback)
>         (void) rt->gcCallback(cx, JSGC_MARK_END);
2697,2698c1298
<      *
<      * Finalize as we sweep, outside of rt->gcLock but with rt->gcRunning set
---
>      * Finalize as we sweep, outside of rt->gcLock, but with rt->gcRunning set
2701,2728d1300
<      *
<      * We first sweep atom state so we can use js_IsAboutToBeFinalized on
<      * JSString or jsdouble held in a hashtable to check if the hashtable
<      * entry can be freed. Note that even after the entry is freed, JSObject
<      * finalizers can continue to access the corresponding jsdouble* and
<      * JSString* assuming that they are unique. This works since the
<      * atomization API must not be called during GC.
<      */
<     js_SweepAtomState(cx);
< 
<     /* Finalize iterator states before the objects they iterate over. */
<     CloseNativeIterators(cx);
< 
<     /* Finalize watch points associated with unreachable objects. */
<     js_SweepWatchPoints(cx);
< 
< #ifdef DEBUG
<     /* Save the pre-sweep count of scope-mapped properties. */
<     rt->liveScopePropsPreSweep = rt->liveScopeProps;
< #endif
< 
<     /*
<      * Here we need to ensure that JSObject instances are finalized before GC-
<      * allocated JSString and jsdouble instances so object's finalizer can
<      * access them even if they will be freed. For that we simply finalize the
<      * list containing JSObject first since the static assert at the beginning
<      * of the file guarantees that JSString and jsdouble instances are
<      * allocated from a different list.
2730,2807c1302,1324
<     emptyArenas = NULL;
<     for (i = 0; i < GC_NUM_FREELISTS; i++) {
<         arenaList = &rt->gcArenaList[i == 0
<                                      ? GC_FREELIST_INDEX(sizeof(JSObject))
<                                      : i == GC_FREELIST_INDEX(sizeof(JSObject))
<                                      ? 0
<                                      : i];
<         ap = &arenaList->last;
<         if (!(a = *ap))
<             continue;
< 
<         JS_ASSERT(arenaList->lastCount > 0);
<         arenaList->freeList = NULL;
<         freeList = NULL;
< 
<         /* Here i is not the list index due to the above swap. */
<         METER(listStats = &rt->gcStats.arenas[arenaList - &rt->gcArenaList[0]]);
<         METER(listStats->nthings = 0);
<         METER(listStats->freelen = 0);
<         thingSize = arenaList->thingSize;
<         indexLimit = THINGS_PER_ARENA(thingSize);
<         flagp = THING_FLAGP(a, arenaList->lastCount - 1);
<         for (;;) {
<             JS_ASSERT(a->prevUntracedPage == 0);
<             JS_ASSERT(a->untracedThings == 0);
<             allClear = JS_TRUE;
<             METER(nfree = 0);
<             do {
<                 flags = *flagp;
<                 if (flags & (GCF_MARK | GCF_LOCK)) {
<                     *flagp &= ~GCF_MARK;
<                     allClear = JS_FALSE;
<                     METER(listStats->nthings++);
<                 } else {
<                     thing = FLAGP_TO_THING(flagp, thingSize);
<                     if (!(flags & GCF_FINAL)) {
<                         /*
<                          * Call the finalizer with GCF_FINAL ORed into flags.
<                          */
<                         *flagp = (uint8)(flags | GCF_FINAL);
<                         type = flags & GCF_TYPEMASK;
<                         switch (type) {
<                           case GCX_OBJECT:
<                             js_FinalizeObject(cx, (JSObject *) thing);
<                             break;
<                           case GCX_DOUBLE:
<                             /* Do nothing. */
<                             break;
<                           case GCX_FUNCTION:
<                             js_FinalizeFunction(cx, (JSFunction *) thing);
<                             break;
< #if JS_HAS_XML_SUPPORT
<                           case GCX_NAMESPACE:
<                             js_FinalizeXMLNamespace(cx,
<                                                     (JSXMLNamespace *) thing);
<                             break;
<                           case GCX_QNAME:
<                             js_FinalizeXMLQName(cx, (JSXMLQName *) thing);
<                             break;
<                           case GCX_XML:
<                             js_FinalizeXML(cx, (JSXML *) thing);
<                             break;
< #endif
<                           default:
<                             JS_ASSERT(type == GCX_STRING ||
<                                       type - GCX_EXTERNAL_STRING <
<                                       GCX_NTYPES - GCX_EXTERNAL_STRING);
<                             js_FinalizeStringRT(rt, (JSString *) thing,
<                                                 (intN) (type -
<                                                         GCX_EXTERNAL_STRING),
<                                                 cx);
<                             break;
<                         }
<                     }
<                     thing->flagp = flagp;
<                     thing->next = freeList;
<                     freeList = thing;
<                     METER(++nfree);
---
>     js_SweepAtomState(&rt->atomState);
>     js_SweepScopeProperties(rt);
>     for (a = rt->gcArenaPool.first.next; a; a = a->next) {
>         flagp = (uint8 *) a->base;
>         split = (uint8 *) FIRST_THING_PAGE(a);
>         limit = (JSGCThing *) a->avail;
>         for (thing = (JSGCThing *) split; thing < limit; thing++) {
>             if (((jsuword)thing & GC_PAGE_MASK) == 0) {
>                 flagp++;
>                 thing++;
>             }
>             flags = *flagp;
>             if (flags & GCF_MARK) {
>                 *flagp &= ~GCF_MARK;
>             } else if (!(flags & (GCF_LOCKMASK | GCF_FINAL))) {
>                 /* Call the finalizer with GCF_FINAL ORed into flags. */
>                 type = flags & GCF_TYPEMASK;
>                 finalizer = gc_finalizers[type];
>                 if (finalizer) {
>                     *flagp = (uint8)(flags | GCF_FINAL);
>                     if (type >= GCX_EXTERNAL_STRING)
>                         js_PurgeDeflatedStringCache((JSString *)thing);
>                     finalizer(cx, thing);
2809d1325
<             } while (++flagp != THING_FLAGS_END(a));
2811,2829c1327,1331
<             if (allClear) {
<                 /*
<                  * Forget just assembled free list head for the arena and
<                  * add the arena itself to the destroy list.
<                  */
<                 freeList = arenaList->freeList;
<                 if (a == arenaList->last)
<                     arenaList->lastCount = indexLimit;
<                 *ap = a->prev;
<                 JS_ASSERT(rt->gcBytes >= GC_ARENA_SIZE);
<                 rt->gcBytes -= GC_ARENA_SIZE;
<                 a->prev = emptyArenas;
<                 emptyArenas = a;
<             } else {
<                 arenaList->freeList = freeList;
<                 ap = &a->prev;
<                 METER(listStats->freelen += nfree);
<                 METER(listStats->totalfreelen += nfree);
<                 METER(listStats->totalarenas++);
---
>                 /* Set flags to GCF_FINAL, signifying that thing is free. */
>                 *flagp = GCF_FINAL;
> 
>                 JS_ASSERT(rt->gcBytes >= sizeof(JSGCThing) + sizeof(uint8));
>                 rt->gcBytes -= sizeof(JSGCThing) + sizeof(uint8);
2831,2833c1333,1334
<             if (!(a = *ap))
<                 break;
<             flagp = THING_FLAGP(a, indexLimit - 1);
---
>             if (++flagp == split)
>                 flagp += GC_THINGS_SIZE;
2838,2839c1339,1340
<      * Sweep the runtime's property tree after finalizing objects, in case any
<      * had watchpoints referencing tree nodes.
---
>      * Free phase.
>      * Free any unused arenas and rebuild the JSGCThing freelist.
2841c1342,1370
<     js_SweepScopeProperties(cx);
---
>     ap = &rt->gcArenaPool.first.next;
>     a = *ap;
>     if (!a)
>         goto out;
>     all_clear = JS_TRUE;
>     flp = oflp = &rt->gcFreeList;
>     *flp = NULL;
>     METER(rt->gcStats.freelen = 0);
> 
>     do {
>         flagp = (uint8 *) a->base;
>         split = (uint8 *) FIRST_THING_PAGE(a);
>         limit = (JSGCThing *) a->avail;
>         for (thing = (JSGCThing *) split; thing < limit; thing++) {
>             if (((jsuword)thing & GC_PAGE_MASK) == 0) {
>                 flagp++;
>                 thing++;
>             }
>             if (*flagp != GCF_FINAL) {
>                 all_clear = JS_FALSE;
>             } else {
>                 thing->flagp = flagp;
>                 *flp = thing;
>                 flp = &thing->next;
>                 METER(rt->gcStats.freelen++);
>             }
>             if (++flagp == split)
>                 flagp += GC_THINGS_SIZE;
>         }
2843,2849c1372,1381
<     /*
<      * Sweep script filenames after sweeping functions in the generic loop
<      * above. In this way when a scripted function's finalizer destroys the
<      * script and calls rt->destroyScriptHook, the hook can still access the
<      * script's filename. See bug 323267.
<      */
<     js_SweepScriptFilenames(rt);
---
>         if (all_clear) {
>             JS_ARENA_DESTROY(&rt->gcArenaPool, a, ap);
>             flp = oflp;
>             METER(rt->gcStats.afree++);
>         } else {
>             ap = &a->next;
>             all_clear = JS_TRUE;
>             oflp = flp;
>         }
>     } while ((a = *ap) != NULL);
2851,2859c1383,1384
<     /*
<      * Destroy arenas after we finished the sweeping sofinalizers can safely
<      * use js_IsAboutToBeFinalized().
<      */
<     while (emptyArenas) {
<         a = emptyArenas;
<         emptyArenas = emptyArenas->prev;
<         DestroyGCArena(rt, a);
<     }
---
>     /* Terminate the new freelist. */
>     *flp = NULL;
2863,2885d1387
< #ifdef DEBUG_srcnotesize
<   { extern void DumpSrcNoteSizeHist();
<     DumpSrcNoteSizeHist();
<     printf("GC HEAP SIZE %lu\n", (unsigned long)rt->gcBytes);
<   }
< #endif
< 
< #ifdef JS_SCOPE_DEPTH_METER
<   { static FILE *fp;
<     if (!fp)
<         fp = fopen("/tmp/scopedepth.stats", "w");
< 
<     if (fp) {
<         JS_DumpBasicStats(&rt->protoLookupDepthStats, "proto-lookup depth", fp);
<         JS_DumpBasicStats(&rt->scopeSearchDepthStats, "scope-search depth", fp);
<         JS_DumpBasicStats(&rt->hostenvScopeDepthStats, "hostenv scope depth", fp);
<         JS_DumpBasicStats(&rt->lexicalScopeDepthStats, "lexical scope depth", fp);
< 
<         putc('\n', fp);
<         fflush(fp);
<     }
<   }
< #endif /* JS_SCOPE_DEPTH_METER */
2886a1389
> out:
2888,2893c1391
< 
<     /*
<      * We want to restart GC if js_GC was called recursively or if any of the
<      * finalizers called js_RemoveRoot or js_UnlockGCThingRT.
<      */
<     if (rt->gcLevel > 1 || rt->gcPoke) {
---
>     if (rt->gcLevel > 1) {
2895d1392
<         rt->gcPoke = JS_FALSE;
2899,2913c1396
< 
<     if (!(rt->shapeGen & SHAPE_OVERFLOW_BIT)) {
<         js_EnablePropertyCache(cx);
< #ifdef JS_THREADSAFE
<         iter = NULL;
<         while ((acx = js_ContextIterator(rt, JS_FALSE, &iter)) != NULL) {
<             if (!acx->thread || acx->thread == cx->thread)
<                 continue;
<             js_EnablePropertyCache(acx);
<         }
< #endif
<     }
< 
<     rt->gcLastBytes = rt->gcBytes;
<   done_running:
---
>     js_EnablePropertyCache(cx);
2914a1398,1399
>     rt->gcLastBytes = rt->gcBytes;
>     #ifdef DP_FIX
2916c1401,1404
< 
---
>     #else
>     rt->gcPoke = rt->gcRunning = JS_FALSE;
> 	#endif
> 	
2921c1409
<     rt->gcThread = NULL;
---
>     rt->gcThread = 0;
2923,2927c1411
< 
<     /*
<      * Unlock unless we have GC_LOCK_HELD which requires locked GC on return.
<      */
<     if (!(gckind & GC_LOCK_HELD))
---
>     if (!(gcflags & GC_ALREADY_LOCKED))
2931,2948c1415,1416
<     /*
<      * Execute JSGC_END callback outside the lock. Again, sample the callback
<      * pointer in case it changes, since we are outside of the GC vs. requests
<      * interlock mechanism here.
<      */
<     if (gckind != GC_SET_SLOT_REQUEST && (callback = rt->gcCallback)) {
<         JSWeakRoots savedWeakRoots;
<         JSTempValueRooter tvr;
< 
<         if (gckind & GC_KEEP_ATOMS) {
<             /*
<              * We allow JSGC_END implementation to force a full GC or allocate
<              * new GC things. Thus we must protect the weak roots from garbage
<              * collection and overwrites.
<              */
<             savedWeakRoots = cx->weakRoots;
<             JS_PUSH_TEMP_ROOT_WEAK_COPY(cx, &savedWeakRoots, &tvr);
<             JS_KEEP_ATOMS(rt);
---
>     if (rt->gcCallback) {
>         if (gcflags & GC_ALREADY_LOCKED)
2950,2954c1418,1419
<         }
< 
<         (void) callback(cx, JSGC_END);
< 
<         if (gckind & GC_KEEP_ATOMS) {
---
>         (void) rt->gcCallback(cx, JSGC_END);
>         if (gcflags & GC_ALREADY_LOCKED)
2956,2964d1420
<             JS_UNKEEP_ATOMS(rt);
<             JS_POP_TEMP_ROOT(cx, &tvr);
<         } else if (gckind == GC_LAST_CONTEXT && rt->gcPoke) {
<             /*
<              * On shutdown iterate until JSGC_END callback stops creating
<              * garbage.
<              */
<             goto restart_at_beginning;
<         }
2967,2980d1422
< 
< void
< js_UpdateMallocCounter(JSContext *cx, size_t nbytes)
< {
<     uint32 *pbytes, bytes;
< 
< #ifdef JS_THREADSAFE
<     pbytes = &cx->thread->gcMallocBytes;
< #else
<     pbytes = &cx->runtime->gcMallocBytes;
< #endif
<     bytes = *pbytes;
<     *pbytes = ((uint32)-1 - bytes <= nbytes) ? (uint32)-1 : bytes + nbytes;
< }
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsgc.h /Volumes/Swap/js_D11/src/jsgc.h
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,22c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
26,38c23,33
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
48d42
< #include "jsutil.h"
52,88c46,54
< JS_STATIC_ASSERT(JSTRACE_STRING == 2);
< 
< #define JSTRACE_FUNCTION    3
< #define JSTRACE_NAMESPACE   4
< #define JSTRACE_QNAME       5
< #define JSTRACE_XML         6
< 
< /*
<  * One past the maximum trace kind.
<  */
< #define JSTRACE_LIMIT       7
< 
< /*
<  * We use the trace kinds as the types for all GC things except external
<  * strings.
<  */
< #define GCX_OBJECT              JSTRACE_OBJECT      /* JSObject */
< #define GCX_DOUBLE              JSTRACE_DOUBLE      /* jsdouble */
< #define GCX_STRING              JSTRACE_STRING      /* JSString */
< #define GCX_FUNCTION            JSTRACE_FUNCTION    /* JSFunction */
< #define GCX_NAMESPACE           JSTRACE_NAMESPACE   /* JSXMLNamespace */
< #define GCX_QNAME               JSTRACE_QNAME       /* JSXMLQName */
< #define GCX_XML                 JSTRACE_XML         /* JSXML */
< #define GCX_EXTERNAL_STRING     JSTRACE_LIMIT       /* JSString with external
<                                                        chars */
< /*
<  * The number of defined GC types.
<  */
< #define GCX_NTYPES              (GCX_EXTERNAL_STRING + 8)
< 
< /*
<  * The maximum limit for the number of GC types.
<  */
< #define GCX_LIMIT_LOG2         4           /* type index bits */
< #define GCX_LIMIT              JS_BIT(GCX_LIMIT_LOG2)
< 
< JS_STATIC_ASSERT(GCX_NTYPES <= GCX_LIMIT);
---
> /* GC thing type indexes. */
> #define GCX_OBJECT              0               /* JSObject */
> #define GCX_STRING              1               /* JSString */
> #define GCX_DOUBLE              2               /* jsdouble */
> #define GCX_MUTABLE_STRING      3               /* JSString that's mutable --
>                                                    single-threaded only! */
> #define GCX_EXTERNAL_STRING     4               /* JSString w/ external chars */
> #define GCX_NTYPES_LOG2         3               /* type index bits */
> #define GCX_NTYPES              JS_BIT(GCX_NTYPES_LOG2)
91,94c57,61
< #define GCF_TYPEMASK    JS_BITMASK(GCX_LIMIT_LOG2)
< #define GCF_MARK        JS_BIT(GCX_LIMIT_LOG2)
< #define GCF_FINAL       JS_BIT(GCX_LIMIT_LOG2 + 1)
< #define GCF_LOCKSHIFT   (GCX_LIMIT_LOG2 + 2)   /* lock bit shift */
---
> #define GCF_TYPEMASK    JS_BITMASK(GCX_NTYPES_LOG2)
> #define GCF_MARK        JS_BIT(GCX_NTYPES_LOG2)
> #define GCF_FINAL       JS_BIT(GCX_NTYPES_LOG2 + 1)
> #define GCF_LOCKSHIFT   (GCX_NTYPES_LOG2 + 2)   /* lock bit shift and mask */
> #define GCF_LOCKMASK    (JS_BITMASK(8 - GCF_LOCKSHIFT) << GCF_LOCKSHIFT)
97,102c64,65
< /*
<  * Get the type of the external string or -1 if the string was not created
<  * with JS_NewExternalString.
<  */
< extern intN
< js_GetExternalStringGCType(JSString *str);
---
> /* Pseudo-flag that modifies GCX_STRING to make GCX_MUTABLE_STRING. */
> #define GCF_MUTABLE     2
104,105c67,69
< extern JS_FRIEND_API(uint32)
< js_GetGCThingTraceKind(void *thing);
---
> #if (GCX_STRING | GCF_MUTABLE) != GCX_MUTABLE_STRING
> # error "mutable string type index botch!"
> #endif
107,112c71,85
< /*
<  * The sole purpose of the function is to preserve public API compatibility
<  * in JS_GetStringBytes which takes only single JSString* argument.
<  */
< JSRuntime*
< js_GetGCStringRuntime(JSString *str);
---
> extern uint8 *
> js_GetGCThingFlags(void *thing);
> 
> /* These are compatible with JSDHashEntryStub. */
> struct JSGCRootHashEntry {
>     JSDHashEntryHdr hdr;
>     void            *root;
>     const char      *name;
> };
> 
> struct JSGCLockHashEntry {
>     JSDHashEntryHdr hdr;
>     const JSGCThing *thing;
>     uint32          count;
> };
125,143c98,100
< /*
<  * Write barrier macro monitoring property update from oldval to newval in
<  * scope->object.
<  *
<  * Since oldval is used only for the branded scope case, and the oldval actual
<  * argument expression is typically not used otherwise by callers, performance
<  * benefits if oldval is *not* evaluated into a callsite temporary variable,
<  * and instead passed to GC_WRITE_BARRIER for conditional evaluation (we rely
<  * on modern compilers to do a good CSE job). Yay, C macros.
<  */
< #define GC_WRITE_BARRIER(cx,scope,oldval,newval)                              \
<     JS_BEGIN_MACRO                                                            \
<         if (SCOPE_IS_BRANDED(scope) &&                                        \
<             (oldval) != (newval) &&                                           \
<             (VALUE_IS_FUNCTION(cx,oldval) || VALUE_IS_FUNCTION(cx,newval))) { \
<             SCOPE_GENERATE_PCTYPE(cx, scope);                                 \
<         }                                                                     \
<         GC_POKE(cx, oldval);                                                  \
<     JS_END_MACRO
---
> extern intN
> js_ChangeExternalStringFinalizer(JSStringFinalizeOp oldop,
>                                  JSStringFinalizeOp newop);
151,154d107
< extern intN
< js_ChangeExternalStringFinalizer(JSStringFinalizeOp oldop,
<                                  JSStringFinalizeOp newop);
< 
164,201d116
< #ifdef DEBUG
< extern void
< js_DumpNamedRoots(JSRuntime *rt,
<                   void (*dump)(const char *name, void *rp, void *data),
<                   void *data);
< #endif
< 
< extern uint32
< js_MapGCRoots(JSRuntime *rt, JSGCRootMapFun map, void *data);
< 
< /* Table of pointers with count valid members. */
< typedef struct JSPtrTable {
<     size_t      count;
<     void        **array;
< } JSPtrTable;
< 
< extern JSBool
< js_RegisterCloseableIterator(JSContext *cx, JSObject *obj);
< 
< /*
<  * The private JSGCThing struct, which describes a gcFreeList element.
<  */
< struct JSGCThing {
<     JSGCThing   *next;
<     uint8       *flagp;
< };
< 
< #define GC_NBYTES_MAX           (10 * sizeof(JSGCThing))
< #define GC_NUM_FREELISTS        (GC_NBYTES_MAX / sizeof(JSGCThing))
< #define GC_FREELIST_NBYTES(i)   (((i) + 1) * sizeof(JSGCThing))
< #define GC_FREELIST_INDEX(n)    (((n) / sizeof(JSGCThing)) - 1)
< 
< /*
<  * Allocates a new GC thing of the given size. After a successful allocation
<  * the caller must fully initialize the thing before calling any function that
<  * can potentially trigger GC. This will ensure that GC tracing never sees junk
<  * values stored in the partially initialized thing.
<  */
203c118
< js_NewGCThing(JSContext *cx, uintN flags, size_t nbytes);
---
> js_AllocGCThing(JSContext *cx, uintN flags);
214c129
< extern JSBool
---
> extern JSBool 
217,239d131
< /*
<  * Macro to test if a traversal is the marking phase of GC to avoid exposing
<  * ScriptFilenameEntry to traversal implementations.
<  */
< #define IS_GC_MARKING_TRACER(trc) ((trc)->callback == NULL)
< 
< #if JS_HAS_XML_SUPPORT
< # define JS_IS_VALID_TRACE_KIND(kind) ((uint32)(kind) <= JSTRACE_XML)
< #else
< # define JS_IS_VALID_TRACE_KIND(kind) ((uint32)(kind) <= JSTRACE_FUNCTION)
< #endif
< 
< /*
<  * JS_IS_VALID_TRACE_KIND assumes that JSTRACE_FUNCTION is the last non-xml
<  * trace kind when JS_HAS_XML_SUPPORT is false.
<  */
< JS_STATIC_ASSERT(JSTRACE_FUNCTION + 1 == JSTRACE_NAMESPACE);
< 
< /*
<  * Trace jsval when JSVAL_IS_OBJECT(v) can be an arbitrary GC thing casted as
<  * JSVAL_OBJECT and js_GetGCThingTraceKind has to be used to find the real
<  * type behind v.
<  */
241c133
< js_CallValueTracerIfGCThing(JSTracer *trc, jsval v);
---
> js_MarkAtom(JSContext *cx, JSAtom *atom, void *arg);
243,244c135,140
< extern void
< js_TraceStackFrame(JSTracer *trc, JSStackFrame *fp);
---
> /* We avoid a large number of unnecessary calls by doing the flag check first */
> #define GC_MARK_ATOM(cx, atom, arg)                                           \
>     JS_BEGIN_MACRO                                                            \
>         if (!((atom)->flags & ATOM_MARK))                                     \
>             js_MarkAtom(cx, atom, arg);                                       \
>     JS_END_MACRO
247c143
< js_TraceRuntime(JSTracer *trc, JSBool allAtoms);
---
> js_MarkGCThing(JSContext *cx, void *thing, void *arg);
249,250c145
< extern JS_FRIEND_API(void)
< js_TraceContext(JSTracer *trc, JSContext *acx);
---
> #ifdef GC_MARK_DEBUG
252,284c147
< /*
<  * Kinds of js_GC invocation.
<  */
< typedef enum JSGCInvocationKind {
<     /* Normal invocation. */
<     GC_NORMAL           = 0,
< 
<     /*
<      * Called from js_DestroyContext for last JSContext in a JSRuntime, when
<      * it is imperative that rt->gcPoke gets cleared early in js_GC.
<      */
<     GC_LAST_CONTEXT     = 1,
< 
<     /*
<      * Flag bit telling js_GC that the caller has already acquired rt->gcLock.
<      * Currently, this flag is set for the invocation kinds that also preserve
<      * atoms and weak roots, so we don't need another bit for GC_KEEP_ATOMS.
<      */
<     GC_LOCK_HELD        = 0x10,
<     GC_KEEP_ATOMS       = GC_LOCK_HELD,
< 
<     /*
<      * Called from js_SetProtoOrParent with a request to set an object's proto
<      * or parent slot inserted on rt->setSlotRequests.
<      */
<     GC_SET_SLOT_REQUEST = GC_LOCK_HELD | 1,
< 
<     /*
<      * Called from js_NewGCThing as a last-ditch GC attempt. See comments
<      * in jsgc.c just before js_GC's definition for details.
<      */
<     GC_LAST_DITCH       = GC_LOCK_HELD | 2
< } JSGCInvocationKind;
---
> typedef struct GCMarkNode GCMarkNode;
286,287c149,154
< extern void
< js_GC(JSContext *cx, JSGCInvocationKind gckind);
---
> struct GCMarkNode {
>     void        *thing;
>     const char  *name;
>     GCMarkNode  *next;
>     GCMarkNode  *prev;
> };
289,291c156,165
< /* Call this after succesful malloc of memory for GC-related things. */
< extern void
< js_UpdateMallocCounter(JSContext *cx, size_t nbytes);
---
> #define GC_MARK(_cx, _thing, _name, _prev)                                    \
>     JS_BEGIN_MACRO                                                            \
>         GCMarkNode _node;                                                     \
>         _node.thing = _thing;                                                 \
>         _node.name  = _name;                                                  \
>         _node.next  = NULL;                                                   \
>         _node.prev  = _prev;                                                  \
>         if (_prev) ((GCMarkNode *)(_prev))->next = &_node;                    \
>         js_MarkGCThing(_cx, _thing, &_node);                                  \
>     JS_END_MACRO
293,304c167
< typedef struct JSGCArenaInfo JSGCArenaInfo;
< typedef struct JSGCArenaList JSGCArenaList;
< typedef struct JSGCChunkInfo JSGCChunkInfo;
< 
< struct JSGCArenaList {
<     JSGCArenaInfo   *last;          /* last allocated GC arena */
<     uint16          lastCount;      /* number of allocated things in the last
<                                        arena */
<     uint16          thingSize;      /* size of things to allocate on this list
<                                      */
<     JSGCThing       *freeList;      /* list of free GC things */
< };
---
> #else  /* !GC_MARK_DEBUG */
306,308c169
< struct JSWeakRoots {
<     /* Most recently created things by type, members of the GC's root set. */
<     void            *newborn[GCX_NTYPES];
---
> #define GC_MARK(cx, thing, name, prev)   js_MarkGCThing(cx, thing, NULL)
310,311c171
<     /* Atom root for the last-looked-up atom on this context. */
<     jsval           lastAtom;
---
> #endif /* !GC_MARK_DEBUG */
313,315c173,187
<     /* Root for the result of the most recent js_InternalInvoke call. */
<     jsval           lastInternalResult;
< };
---
> /*
>  * Flags to modify how a GC marks and sweeps:
>  *   GC_KEEP_ATOMS      Don't sweep unmarked atoms, they may be in use by the
>  *                      compiler, or by an API function that calls js_Atomize,
>  *                      when the GC is called from js_AllocGCThing, due to a
>  *                      malloc failure or runtime GC-thing limit.
>  *   GC_LAST_CONTEXT    Called from js_DestroyContext for last JSContext in a
>  *                      JSRuntime, when it is imperative that rt->gcPoke gets
>  *                      cleared early in js_GC, if it is set.
>  *   GC_ALREADY_LOCKED  rt->gcLock is already held on entry to js_GC, and kept
>  *                      on return to its caller.
>  */
> #define GC_KEEP_ATOMS       0x1
> #define GC_LAST_CONTEXT     0x2
> #define GC_ALREADY_LOCKED   0x4
317,318c189,190
< JS_STATIC_ASSERT(JSVAL_NULL == 0);
< #define JS_CLEAR_WEAK_ROOTS(wr) (memset((wr), 0, sizeof(JSWeakRoots)))
---
> extern void
> js_ForceGC(JSContext *cx, uintN gcflags);
320,322c192,193
< #ifdef DEBUG_notme
< #define JS_GCMETER 1
< #endif
---
> extern void
> js_GC(JSContext *cx, uintN gcflags);
326,339d196
< typedef struct JSGCArenaStats {
<     uint32  narenas;        /* number of arena in list */
<     uint32  maxarenas;      /* maximun number of allocated arenas */
<     uint32  nthings;        /* number of allocates JSGCThing */
<     uint32  maxthings;      /* maximum number number of allocates JSGCThing */
<     uint32  totalnew;       /* number of succeeded calls to js_NewGCThing */
<     uint32  freelen;        /* freeList lengths */
<     uint32  recycle;        /* number of things recycled through freeList */
<     uint32  totalarenas;    /* total number of arenas with live things that
<                                GC scanned so far */
<     uint32  totalfreelen;   /* total number of things that GC put to free
<                                list so far */
< } JSGCArenaStats;
< 
341,343d197
< #ifdef JS_THREADSAFE
<     uint32  localalloc; /* number of succeeded allocations from local lists */
< #endif
344a199,200
>     uint32  freelen;    /* gcFreeList length */
>     uint32  recycle;    /* number of things recycled through gcFreeList */
346,347d201
<     uint32  retryhalt;  /* allocation retries halted by the operation
<                            callback */
350d203
<     uint32  lockborn;   /* things born locked */
353,362c206,209
<     uint32  depth;      /* mark tail recursion depth */
<     uint32  maxdepth;   /* maximum mark tail recursion depth */
<     uint32  cdepth;     /* mark recursion depth of C functions */
<     uint32  maxcdepth;  /* maximum mark recursion depth of C functions */
<     uint32  untraced;   /* number of times tracing of GC thing's children were
<                            delayed due to a low C stack */
< #ifdef DEBUG
<     uint32  maxuntraced;/* maximum number of things with children to trace
<                            later */
< #endif
---
>     uint32  stuck;      /* stuck reference counts seen by lock calls */
>     uint32  unstuck;    /* unlock calls that saw a stuck lock count */
>     uint32  depth;      /* mark recursion depth */
>     uint32  maxdepth;   /* maximum mark recursion depth */
364a212
>     uint32  nopoke;     /* useless GC calls where js_PokeGC was not set */
368,373d215
<     uint32  nclose;     /* number of objects with close hooks */
<     uint32  maxnclose;  /* max number of objects with close hooks */
<     uint32  closelater; /* number of close hooks scheduled to run */
<     uint32  maxcloselater; /* max number of close hooks scheduled to run */
< 
<     JSGCArenaStats  arenas[GC_NUM_FREELISTS];
376c218
< extern JS_FRIEND_API(void)
---
> extern void
diff -r /Volumes/Swap/js-14-2-2008/js/src/jshash.c /Volumes/Swap/js_D11/src/jshash.c
3,4c3,6
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
6,14c8,11
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,24c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
26,36c21
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
---
>  * Contributor(s): 
38c23,33
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
44c39
< #include <stdlib.h>
---
> #include "xstdlib.h"
49a45,48
> #include "jsapi.h"
> 
> 
> //#include "_optimize.h"
70c69,70
<     return malloc(size);
---
> 	XMEMTAG("jshash DefaultAllocTable ");
>     return xmalloc(size);
76c76
<     free(item);
---
>     xfree(item);
82c82,83
<     return (JSHashEntry*) malloc(sizeof(JSHashEntry));
---
> 	XMEMTAG("jshash DefaultAllocEntry ");
>     return (JSHashEntry*) xmalloc(sizeof(JSHashEntry));
89c90
<         free(he);
---
>         xfree(he);
115c116
<     ht = (JSHashTable*) allocOps->allocTable(allocPriv, sizeof *ht);
---
>     ht = (JSHashTable*) (*allocOps->allocTable)(allocPriv, sizeof *ht);
117c118
<         return NULL;
---
> 	return NULL;
120a122,127
> #if defined _MSC_VER && _MSC_VER <= 800
>     if (n > 16000) {
>         (*allocOps->freeTable)(allocPriv, ht);
>         return NULL;
>     }
> #endif  /* WIN16 */
122c129
<     ht->buckets = (JSHashEntry**) allocOps->allocTable(allocPriv, nb);
---
>     ht->buckets = (JSHashEntry**) (*allocOps->allocTable)(allocPriv, nb);
124c131
<         allocOps->freeTable(allocPriv, ht);
---
>         (*allocOps->freeTable)(allocPriv, ht);
150c157
<             allocOps->freeEntry(allocPriv, he, HT_FREE_ENTRY);
---
>             (*allocOps->freeEntry)(allocPriv, he, HT_FREE_ENTRY);
156c163
<     allocOps->freeTable(allocPriv, ht->buckets);
---
>     (*allocOps->freeTable)(allocPriv, ht->buckets);
160c167
<     allocOps->freeTable(allocPriv, ht);
---
>     (*allocOps->freeTable)(allocPriv, ht);
164,168c171,172
<  * Multiplicative hash, from Knuth 6.4.
<  */
< #define BUCKET_HEAD(ht, keyHash)                                              \
<     (&(ht)->buckets[((keyHash) * JS_GOLDEN_RATIO) >> (ht)->shift])
< 
---
> ** Multiplicative hash, from Knuth 6.4.
> */
172a177
>     JSHashNumber h;
174c179
< #ifdef JS_HASHMETER
---
> #ifdef HASHMETER
177c182,184
<     hep = hep0 = BUCKET_HEAD(ht, keyHash);
---
>     h = keyHash * JS_GOLDEN_RATIO;
>     h >>= ht->shift;
>     hep = hep0 = &ht->buckets[h];
179c186
<         if (he->keyHash == keyHash && ht->keyCompare(key, he->key)) {
---
>         if (he->keyHash == keyHash && (*ht->keyCompare)(key, he->key)) {
189c196
< #ifdef JS_HASHMETER
---
> #ifdef HASHMETER
196,246d202
< static JSBool
< Resize(JSHashTable *ht, uint32 newshift)
< {
<     size_t nb, nentries, i;
<     JSHashEntry **oldbuckets, *he, *next, **hep;
< #ifdef DEBUG
<     size_t nold = NBUCKETS(ht);
< #endif
< 
<     JS_ASSERT(newshift < JS_HASH_BITS);
< 
<     nb = (size_t)1 << (JS_HASH_BITS - newshift);
< 
<     /* Integer overflow protection. */
<     if (nb > (size_t)-1 / sizeof(JSHashEntry*))
<         return JS_FALSE;
<     nb *= sizeof(JSHashEntry*);
< 
<     oldbuckets = ht->buckets;
<     ht->buckets = (JSHashEntry**)ht->allocOps->allocTable(ht->allocPriv, nb);
<     if (!ht->buckets) {
<         ht->buckets = oldbuckets;
<         return JS_FALSE;
<     }
<     memset(ht->buckets, 0, nb);
< 
<     ht->shift = newshift;
<     nentries = ht->nentries;
< 
<     for (i = 0; nentries != 0; i++) {
<         for (he = oldbuckets[i]; he; he = next) {
<             JS_ASSERT(nentries != 0);
<             --nentries;
<             next = he->next;
<             hep = BUCKET_HEAD(ht, he->keyHash);
< 
<             /*
<              * Since he comes from the old table, it must be unique and we
<              * simply add it to the head of bucket chain without chain lookup.
<              */
<             he->next = *hep;
<             *hep = he;
<         }
<     }
< #ifdef DEBUG
<     memset(oldbuckets, 0xDB, nold * sizeof oldbuckets[0]);
< #endif
<     ht->allocOps->freeTable(ht->allocPriv, oldbuckets);
<     return JS_TRUE;
< }
< 
251,252c207,209
<     uint32 n;
<     JSHashEntry *he;
---
>     uint32 i, n;
>     JSHashEntry *he, *next, **oldbuckets;
>     size_t nb;
257c214,216
<         if (!Resize(ht, ht->shift - 1))
---
>         oldbuckets = ht->buckets;
> #if defined _MSC_VER && _MSC_VER <= 800
>         if (2 * n > 16000)
259c218,226
< #ifdef JS_HASHMETER
---
> #endif  /* WIN16 */
>         nb = 2 * n * sizeof(JSHashEntry *);
>         ht->buckets = (JSHashEntry**) (*ht->allocOps->allocTable)(ht->allocPriv, nb);
>         if (!ht->buckets) {
>             ht->buckets = oldbuckets;
>             return NULL;
> 	}
>         memset(ht->buckets, 0, nb);
> #ifdef HASHMETER
261a229,243
>         ht->shift--;
> 
>         for (i = 0; i < n; i++) {
>             for (he = oldbuckets[i]; he; he = next) {
>                 next = he->next;
>                 hep = JS_HashTableRawLookup(ht, he->keyHash, he->key);
>                 JS_ASSERT(*hep == NULL);
>                 he->next = NULL;
>                 *hep = he;
>             }
>         }
> #ifdef DEBUG
>         memset(oldbuckets, 0xDB, n * sizeof oldbuckets[0]);
> #endif
>         (*ht->allocOps->freeTable)(ht->allocPriv, oldbuckets);
266c248
<     he = ht->allocOps->allocEntry(ht->allocPriv, key);
---
>     he = (*ht->allocOps->allocEntry)(ht->allocPriv, key);
268c250
<         return NULL;
---
> 	return NULL;
284c266
<     keyHash = ht->keyHash(key);
---
>     keyHash = (*ht->keyHash)(key);
288c270
<         if (ht->valueCompare(he->value, value)) {
---
>         if ((*ht->valueCompare)(he->value, value)) {
293c275
<             ht->allocOps->freeEntry(ht->allocPriv, he, HT_FREE_VALUE);
---
>             (*ht->allocOps->freeEntry)(ht->allocPriv, he, HT_FREE_VALUE);
303c285,287
<     uint32 n;
---
>     uint32 i, n;
>     JSHashEntry *next, **oldbuckets;
>     size_t nb;
306c290
<     ht->allocOps->freeEntry(ht->allocPriv, he, HT_FREE_ENTRY);
---
>     (*ht->allocOps->freeEntry)(ht->allocPriv, he, HT_FREE_ENTRY);
311,312c295,303
<         Resize(ht, ht->shift + 1);
< #ifdef JS_HASHMETER
---
>         oldbuckets = ht->buckets;
>         nb = n * sizeof(JSHashEntry*) / 2;
>         ht->buckets = (JSHashEntry**) (*ht->allocOps->allocTable)(ht->allocPriv, nb);
>         if (!ht->buckets) {
>             ht->buckets = oldbuckets;
>             return;
>         }
>         memset(ht->buckets, 0, nb);
> #ifdef HASHMETER
314a306,320
>         ht->shift++;
> 
>         for (i = 0; i < n; i++) {
>             for (he = oldbuckets[i]; he; he = next) {
>                 next = he->next;
>                 hep = JS_HashTableRawLookup(ht, he->keyHash, he->key);
>                 JS_ASSERT(*hep == NULL);
>                 he->next = NULL;
>                 *hep = he;
>             }
>         }
> #ifdef DEBUG
>         memset(oldbuckets, 0xDB, n * sizeof oldbuckets[0]);
> #endif
>         (*ht->allocOps->freeTable)(ht->allocPriv, oldbuckets);
324c330
<     keyHash = ht->keyHash(key);
---
>     keyHash = (*ht->keyHash)(key);
340c346
<     keyHash = ht->keyHash(key);
---
>     keyHash = (*ht->keyHash)(key);
356,363c362,369
<     JSHashEntry *he, **hep, **bucket;
<     uint32 nlimit, n, nbuckets, newlog2;
<     int rv;
< 
<     nlimit = ht->nentries;
<     n = 0;
<     for (bucket = ht->buckets; n != nlimit; ++bucket) {
<         hep = bucket;
---
>     JSHashEntry *he, **hep;
>     uint32 i, nbuckets;
>     int rv, n = 0;
>     JSHashEntry *todo = NULL;
> 
>     nbuckets = NBUCKETS(ht);
>     for (i = 0; i < nbuckets; i++) {
>         hep = &ht->buckets[i];
365,366c371
<             JS_ASSERT(n < nlimit);
<             rv = f(he, n, arg);
---
>             rv = (*f)(he, n, arg);
368c373
<             if (rv & HT_ENUMERATE_REMOVE) {
---
>             if (rv & (HT_ENUMERATE_REMOVE | HT_ENUMERATE_UNHASH)) {
370,371c375,378
<                 ht->allocOps->freeEntry(ht->allocPriv, he, HT_FREE_ENTRY);
<                 --ht->nentries;
---
>                 if (rv & HT_ENUMERATE_REMOVE) {
>                     he->next = todo;
>                     todo = he;
>                 }
382,394c389,391
<     /* Shrink table if removal of entries made it underloaded */
<     if (ht->nentries != nlimit) {
<         JS_ASSERT(ht->nentries < nlimit);
<         nbuckets = NBUCKETS(ht);
<         if (MINBUCKETS < nbuckets && ht->nentries < UNDERLOADED(nbuckets)) {
<             newlog2 = JS_CeilingLog2(ht->nentries);
<             if (newlog2 < MINBUCKETSLOG2)
<                 newlog2 = MINBUCKETSLOG2;
< 
<             /*  Check that we really shrink the table. */
<             JS_ASSERT(JS_HASH_BITS - ht->shift > newlog2);
<             Resize(ht, JS_HASH_BITS - newlog2);
<         }
---
>     hep = &todo;
>     while ((he = *hep) != NULL) {
>         JS_HashTableRawRemove(ht, hep, he);
396c393
<     return (int)n;
---
>     return n;
399c396,397
< #ifdef JS_HASHMETER
---
> #ifdef HASHMETER
> #include <math.h>
405,406c403,404
<     double sqsum, mean, sigma;
<     uint32 nchains, nbuckets;
---
>     double sqsum, mean, variance, sigma;
>     uint32 nchains, nbuckets, nentries;
412c410
<     maxChain = maxChainLen = 0;
---
>     maxChainLen = 0;
427,428c425,432
< 
<     mean = JS_MeanAndStdDev(nchains, ht->nentries, sqsum, &sigma);
---
>     nentries = ht->nentries;
>     mean = (double)nentries / nchains;
>     variance = nchains * sqsum - nentries * nentries;
>     if (variance < 0 || nchains == 1)
>         variance = 0;
>     else
>         variance /= nchains * (nchains - 1);
>     sigma = sqrt(variance);
443c447
<         if (dump(he, i, fp) != HT_ENUMERATE_NEXT)
---
>         if ((*dump)(he, i, fp) != HT_ENUMERATE_NEXT)
446c450
< #endif /* JS_HASHMETER */
---
> #endif /* HASHMETER */
454c458
< #ifdef JS_HASHMETER
---
> #ifdef HASHMETER
468c472
<         h = JS_ROTATE_LEFT32(h, 4) ^ *s;
---
>         h = (h >> (JS_HASH_BITS - 4)) ^ (h << 4) ^ *s;
diff -r /Volumes/Swap/js-14-2-2008/js/src/jshash.h /Volumes/Swap/js_D11/src/jshash.h
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
66a62
> #define HT_ENUMERATE_UNHASH     4       /* just unhash the current entry */
94c90
< #ifdef JS_HASHMETER
---
> #ifdef HASHMETER
Only in /Volumes/Swap/js-14-2-2008/js/src: jsinterp.c
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsinterp.h /Volumes/Swap/js_D11/src/jsinterp.h
2d1
<  * vim: set ts=8 sw=4 et tw=78:
4,15c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
20,39c16,33
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
48d41
< #include "jsopcode.h"
53,60c46
<  * JS stack frame, may be allocated on the C stack by native callers.  Always
<  * allocated on cx->stackPool for calls from the interpreter to an interpreted
<  * function.
<  *
<  * NB: This struct is manually initialized in jsinterp.c and jsiter.c.  If you
<  * add new members, update both files.  But first, try to remove members.  The
<  * sharp* and xml* members should be moved onto the stack as local variables
<  * with well-known slots, if possible.
---
>  * JS stack frame, allocated on the C stack.
66d51
<     JSObject        *callee;        /* function or script object */
85,89c70,71
<     JSObject        *xmlNamespace;  /* null or default xml namespace in E4X */
<     JSObject        *blockChain;    /* active compile-time block scopes */
< #ifdef DEBUG
<     jsrefcount      pcDisabledSave; /* for balanced property cache control */
< #endif
---
>     JSAtomMap       *objAtomMap;    /* object atom map, non-null only if we
>                                        hit a regexp object literal */
94d75
<     jsval           *rvp;           /* ptr to caller's return value slot */
101,103c82,83
< #define JSFRAME_CONSTRUCTING  0x01  /* frame is for a constructor invocation */
< #define JSFRAME_INTERNAL      0x02  /* internal call, not invoked by a script */
< #define JSFRAME_ASSIGNING     0x04  /* a complex (not simplex JOF_ASSIGNING) op
---
> #define JSFRAME_CONSTRUCTING   0x1  /* frame is for a constructor invocation */
> #define JSFRAME_ASSIGNING      0x2  /* a complex (not simplex JOF_ASSIGNING) op
105,113c85,87
< #define JSFRAME_DEBUGGER      0x08  /* frame for JS_EvaluateInStackFrame */
< #define JSFRAME_EVAL          0x10  /* frame for obj_eval */
< #define JSFRAME_SCRIPT_OBJECT 0x20  /* compiling source for a Script object */
< #define JSFRAME_YIELDING      0x40  /* js_Interpret dispatched JSOP_YIELD */
< #define JSFRAME_ITERATOR      0x80  /* trying to get an iterator for for-in */
< #define JSFRAME_POP_BLOCKS   0x100  /* scope chain contains blocks to pop */
< #define JSFRAME_GENERATOR    0x200  /* frame belongs to generator-iterator */
< #define JSFRAME_ROOTED_ARGV  0x400  /* frame.argv is rooted by the caller */
< 
---
> #define JSFRAME_DEBUGGER       0x4  /* frame for JS_EvaluateInStackFrame */
> #define JSFRAME_EVAL           0x8  /* frame for obj_eval */
> #define JSFRAME_SPECIAL        0xc  /* special evaluation frame flags */
117,118d90
< #define JSFRAME_SPECIAL       (JSFRAME_DEBUGGER | JSFRAME_EVAL)
< 
120,123c92
<  * Property cache with structurally typed capabilities for invalidation, for
<  * polymorphic callsite method/get/set speedups.
<  *
<  * See bug https://bugzilla.mozilla.org/show_bug.cgi?id=365851.
---
>  * Property cache for quickened get/set property opcodes.
125c94
< #define PROPERTY_CACHE_LOG2     12
---
> #define PROPERTY_CACHE_LOG2     10
129,131c98,99
< #define PROPERTY_CACHE_HASH(pc,kshape)                                        \
<     ((((jsuword)(pc) >> PROPERTY_CACHE_LOG2) ^ (jsuword)(pc) ^ (kshape)) &    \
<      PROPERTY_CACHE_MASK)
---
> #define PROPERTY_CACHE_HASH(obj, id) \
>     ((((jsuword)(obj) >> JSVAL_TAGBITS) ^ (jsuword)(id)) & PROPERTY_CACHE_MASK)
133,134c101
< #define PROPERTY_CACHE_HASH_PC(pc,kshape)                                     \
<     PROPERTY_CACHE_HASH(pc, kshape)
---
> #ifdef JS_THREADSAFE
136,137c103
< #define PROPERTY_CACHE_HASH_ATOM(atom,obj,pobj)                               \
<     PROPERTY_CACHE_HASH((jsuword)(atom) >> 2, OBJ_SCOPE(obj)->shape)
---
> #if HAVE_ATOMIC_DWORD_ACCESS
139,172c105,147
< /*
<  * Property cache value capability macros.
<  */
< #define PCVCAP_PROTOBITS        4
< #define PCVCAP_PROTOSIZE        JS_BIT(PCVCAP_PROTOBITS)
< #define PCVCAP_PROTOMASK        JS_BITMASK(PCVCAP_PROTOBITS)
< 
< #define PCVCAP_SCOPEBITS        4
< #define PCVCAP_SCOPESIZE        JS_BIT(PCVCAP_SCOPEBITS)
< #define PCVCAP_SCOPEMASK        JS_BITMASK(PCVCAP_SCOPEBITS)
< 
< #define PCVCAP_TAGBITS          (PCVCAP_PROTOBITS + PCVCAP_SCOPEBITS)
< #define PCVCAP_TAGMASK          JS_BITMASK(PCVCAP_TAGBITS)
< #define PCVCAP_TAG(t)           ((t) & PCVCAP_TAGMASK)
< 
< #define PCVCAP_MAKE(t,s,p)      (((t) << PCVCAP_TAGBITS) |                    \
<                                  ((s) << PCVCAP_PROTOBITS) |                  \
<                                  (p))
< #define PCVCAP_PCTYPE(t)        ((t) >> PCVCAP_TAGBITS)
< 
< #define SHAPE_OVERFLOW_BIT      JS_BIT(32 - PCVCAP_TAGBITS)
< 
< extern uint32
< js_GenerateShape(JSContext *cx);
< 
< struct JSPropCacheEntry {
<     jsbytecode          *kpc;           /* pc if vcap tag is <= 1, else atom */
<     jsuword             kshape;         /* key shape if pc, else obj for atom */
<     jsuword             vcap;           /* value capability, see above */
<     jsuword             vword;          /* value word, see PCVAL_* below */
< };
< 
< #if defined DEBUG_brendan || defined DEBUG_brendaneich
< #define JS_PROPERTY_CACHE_METERING 1
---
> #define PCE_LOAD(cache, pce, entry)     JS_ATOMIC_DWORD_LOAD(pce, entry)
> #define PCE_STORE(cache, pce, entry)    JS_ATOMIC_DWORD_STORE(pce, entry)
> 
> #else  /* !HAVE_ATOMIC_DWORD_ACCESS */
> 
> #define JS_PROPERTY_CACHE_METERING      1
> 
> #define PCE_LOAD(cache, pce, entry)                                           \
>     JS_BEGIN_MACRO                                                            \
>         uint32 prefills_;                                                     \
>         uint32 fills_ = (cache)->fills;                                       \
>         do {                                                                  \
>             /* Load until cache->fills is stable (see FILL macro below). */   \
>             prefills_ = fills_;                                               \
>             (entry) = *(pce);                                                 \
>         } while ((fills_ = (cache)->fills) != prefills_);                     \
>     JS_END_MACRO
> 
> #define PCE_STORE(cache, pce, entry)                                          \
>     JS_BEGIN_MACRO                                                            \
>         do {                                                                  \
>             /* Store until no racing collider stores half or all of pce. */   \
>             *(pce) = (entry);                                                 \
>         } while (PCE_OBJECT(*pce) != PCE_OBJECT(entry) ||                     \
>                  PCE_PROPERTY(*pce) != PCE_PROPERTY(entry));                  \
>     JS_END_MACRO
> 
> #endif /* !HAVE_ATOMIC_DWORD_ACCESS */
> 
> #else  /* !JS_THREADSAFE */
> 
> #define PCE_LOAD(cache, pce, entry)     ((entry) = *(pce))
> #define PCE_STORE(cache, pce, entry)    (*(pce) = (entry))
> 
> #endif /* !JS_THREADSAFE */
> 
> typedef union JSPropertyCacheEntry {
>     struct {
>         JSObject        *object;        /* weak link to object */
>         JSScopeProperty *property;      /* weak link to property */
>     } s;
> #ifdef HAVE_ATOMIC_DWORD_ACCESS
>     prdword align;
173a149,153
> } JSPropertyCacheEntry;
> 
> /* These may be called in lvalue or rvalue position. */
> #define PCE_OBJECT(entry)       ((entry).s.object)
> #define PCE_PROPERTY(entry)     ((entry).s.property)
176,178c156,158
<     JSPropCacheEntry    table[PROPERTY_CACHE_SIZE];
<     JSBool              empty;
<     jsrefcount          disabled;       /* signed for anti-underflow asserts */
---
>     JSPropertyCacheEntry table[PROPERTY_CACHE_SIZE];
>     JSBool               empty;
>     JSBool               disabled;
180,205c160,165
<     uint32              fills;          /* number of cache entry fills */
<     uint32              nofills;        /* couldn't fill (e.g. default get) */
<     uint32              rofills;        /* set on read-only prop can't fill */
<     uint32              disfills;       /* fill attempts on disabled cache */
<     uint32              oddfills;       /* fill attempt after setter deleted */
<     uint32              modfills;       /* fill that rehashed to a new entry */
<     uint32              brandfills;     /* scope brandings to type structural
<                                            method fills */
<     uint32              longchains;     /* overlong scope and/or proto chain */
<     uint32              recycles;       /* cache entries recycled by fills */
<     uint32              pcrecycles;     /* pc-keyed entries recycled by atom-
<                                            keyed fills */
<     uint32              tests;          /* cache probes */
<     uint32              pchits;         /* fast-path polymorphic op hits */
<     uint32              protopchits;    /* pchits hitting immediate prototype */
<     uint32              settests;       /* cache probes from JOF_SET opcodes */
<     uint32              addpchits;      /* adding next property pchit case */
<     uint32              setpchits;      /* setting existing property pchit */
<     uint32              setpcmisses;    /* setting/adding property pc misses */
<     uint32              setmisses;      /* JSOP_SET{NAME,PROP} total misses */
<     uint32              idmisses;       /* slow-path key id == atom misses */
<     uint32              komisses;       /* slow-path key object misses */
<     uint32              vcmisses;       /* value capability misses */
<     uint32              misses;         /* cache misses */
<     uint32              flushes;        /* cache flushes */
< # define PCMETER(x)     x
---
>     uint32               fills;
>     uint32               recycles;
>     uint32               tests;
>     uint32               misses;
>     uint32               flushes;
> # define PCMETER(x)      x
207c167
< # define PCMETER(x)     ((void)0)
---
> # define PCMETER(x)      /* nothing */
211,251c171,189
< /*
<  * Property cache value tagging/untagging macros.
<  */
< #define PCVAL_OBJECT            0
< #define PCVAL_SLOT              1
< #define PCVAL_SPROP             2
< 
< #define PCVAL_TAGBITS           2
< #define PCVAL_TAGMASK           JS_BITMASK(PCVAL_TAGBITS)
< #define PCVAL_TAG(v)            ((v) & PCVAL_TAGMASK)
< #define PCVAL_CLRTAG(v)         ((v) & ~(jsuword)PCVAL_TAGMASK)
< #define PCVAL_SETTAG(v,t)       ((jsuword)(v) | (t))
< 
< #define PCVAL_NULL              0
< #define PCVAL_IS_NULL(v)        ((v) == PCVAL_NULL)
< 
< #define PCVAL_IS_OBJECT(v)      (PCVAL_TAG(v) == PCVAL_OBJECT)
< #define PCVAL_TO_OBJECT(v)      ((JSObject *) (v))
< #define OBJECT_TO_PCVAL(obj)    ((jsuword) (obj))
< 
< #define PCVAL_OBJECT_TO_JSVAL(v) OBJECT_TO_JSVAL(PCVAL_TO_OBJECT(v))
< #define JSVAL_OBJECT_TO_PCVAL(v) OBJECT_TO_PCVAL(JSVAL_TO_OBJECT(v))
< 
< #define PCVAL_IS_SLOT(v)        ((v) & PCVAL_SLOT)
< #define PCVAL_TO_SLOT(v)        ((jsuint)(v) >> 1)
< #define SLOT_TO_PCVAL(i)        (((jsuword)(i) << 1) | PCVAL_SLOT)
< 
< #define PCVAL_IS_SPROP(v)       (PCVAL_TAG(v) == PCVAL_SPROP)
< #define PCVAL_TO_SPROP(v)       ((JSScopeProperty *) PCVAL_CLRTAG(v))
< #define SPROP_TO_PCVAL(sprop)   PCVAL_SETTAG(sprop, PCVAL_SPROP)
< 
< /*
<  * Fill property cache entry for key cx->fp->pc, optimized value word computed
<  * from obj and sprop, and entry capability forged from OBJ_SCOPE(obj)->shape,
<  * scopeIndex, and protoIndex.
<  */
< extern void
< js_FillPropertyCache(JSContext *cx, JSObject *obj, jsuword kshape,
<                      uintN scopeIndex, uintN protoIndex,
<                      JSObject *pobj, JSScopeProperty *sprop,
<                      JSPropCacheEntry **entryp);
---
> #define PROPERTY_CACHE_FILL(cache, obj, id, sprop)                            \
>     JS_BEGIN_MACRO                                                            \
>         JSPropertyCache *cache_ = (cache);                                    \
>         if (!cache_->disabled) {                                              \
>             uintN hashIndex_ = (uintN) PROPERTY_CACHE_HASH(obj, id);          \
>             JSPropertyCacheEntry *pce_ = &cache_->table[hashIndex_];          \
>             JSPropertyCacheEntry entry_;                                      \
>             JSScopeProperty *pce_sprop_;                                      \
>             PCE_LOAD(cache_, pce_, entry_);                                   \
>             pce_sprop_ = PCE_PROPERTY(entry_);                                \
>             PCMETER(if (pce_sprop_ && pce_sprop_ != sprop)                    \
>                         cache_->recycles++);                                  \
>             PCE_OBJECT(entry_) = obj;                                         \
>             PCE_PROPERTY(entry_) = sprop;                                     \
>             cache_->empty = JS_FALSE;                                         \
>             PCMETER(cache_->fills++);                                         \
>             PCE_STORE(cache_, pce_, entry_);                                  \
>         }                                                                     \
>     JS_END_MACRO
253,273c191,199
< /*
<  * Property cache lookup macros. PROPERTY_CACHE_TEST is designed to inline the
<  * fast path in js_Interpret, so it makes "just-so" restrictions on parameters,
<  * e.g. pobj and obj should not be the same variable, since for JOF_PROP-mode
<  * opcodes, obj must not be changed because of a cache miss.
<  *
<  * On return from PROPERTY_CACHE_TEST, if atom is null then obj points to the
<  * scope chain element in which the property was found, pobj is locked, and
<  * entry is valid. If atom is non-null then no object is locked but entry is
<  * still set correctly for use, e.g., by js_FillPropertyCache and atom should
<  * be used as the id to find.
<  *
<  * We must lock pobj on a hit in order to close races with threads that might
<  * be deleting a property from its scope, or otherwise invalidating property
<  * caches (on all threads) by re-generating scope->shape.
<  */
< #define PROPERTY_CACHE_TEST(cx, pc, obj, pobj, entry, atom)                   \
<     do {                                                                      \
<         JSPropertyCache *cache_ = &JS_PROPERTY_CACHE(cx);                     \
<         uint32 kshape_ = OBJ_SCOPE(obj)->shape;                               \
<         entry = &cache_->table[PROPERTY_CACHE_HASH_PC(pc, kshape_)];          \
---
> #define PROPERTY_CACHE_TEST(cache, obj, id, sprop)                            \
>     JS_BEGIN_MACRO                                                            \
>         uintN hashIndex_ = (uintN) PROPERTY_CACHE_HASH(obj, id);              \
>         JSPropertyCache *cache_ = (cache);                                    \
>         JSPropertyCacheEntry *pce_ = &cache_->table[hashIndex_];              \
>         JSPropertyCacheEntry entry_;                                          \
>         JSScopeProperty *pce_sprop_;                                          \
>         PCE_LOAD(cache_, pce_, entry_);                                       \
>         pce_sprop_ = PCE_PROPERTY(entry_);                                    \
275,297c201,205
<         JS_ASSERT(&obj != &pobj);                                             \
<         if (entry->kpc == pc && entry->kshape == kshape_) {                   \
<             JSObject *tmp_;                                                   \
<             pobj = obj;                                                       \
<             JS_LOCK_OBJ(cx, pobj);                                            \
<             JS_ASSERT(PCVCAP_TAG(entry->vcap) <= 1);                          \
<             if (PCVCAP_TAG(entry->vcap) == 1 &&                               \
<                 (tmp_ = LOCKED_OBJ_GET_PROTO(pobj)) != NULL) {                \
<                 JS_UNLOCK_OBJ(cx, pobj);                                      \
<                 pobj = tmp_;                                                  \
<                 JS_LOCK_OBJ(cx, pobj);                                        \
<             }                                                                 \
<             if (PCVCAP_PCTYPE(entry->vcap) == OBJ_SCOPE(pobj)->shape) {       \
<                 PCMETER(cache_->pchits++);                                    \
<                 PCMETER(!PCVCAP_TAG(entry->vcap) || cache_->protopchits++);   \
<                 pobj = OBJ_SCOPE(pobj)->object;                               \
<                 atom = NULL;                                                  \
<                 break;                                                        \
<             }                                                                 \
<             JS_UNLOCK_OBJ(cx, pobj);                                          \
<         }                                                                     \
<         atom = js_FullTestPropertyCache(cx, pc, &obj, &pobj, &entry);         \
<         if (atom)                                                             \
---
>         if (pce_sprop_ &&                                                     \
>             PCE_OBJECT(entry_) == obj &&                                      \
>             pce_sprop_->id == id) {                                           \
>             sprop = pce_sprop_;                                               \
>         } else {                                                              \
299,304c207,209
<     } while (0)
< 
< extern JSAtom *
< js_FullTestPropertyCache(JSContext *cx, jsbytecode *pc,
<                          JSObject **objp, JSObject **pobjp,
<                          JSPropCacheEntry **entryp);
---
>             sprop = NULL;                                                     \
>         }                                                                     \
>     JS_END_MACRO
310,312d214
< js_FlushPropertyCacheForScript(JSContext *cx, JSScript *script);
< 
< extern void
318,320d219
< /*
<  * Interpreter stack arena-pool alloc and free functions.
<  */
327,335c226,227
< /*
<  * Refresh and return fp->scopeChain.  It may be stale if block scopes are
<  * active but not yet reflected by objects in the scope chain.  If a block
<  * scope contains a with, eval, XML filtering predicate, or similar such
<  * dynamically scoped construct, then compile-time block scope at fp->blocks
<  * must reflect at runtime.
<  */
< extern JSObject *
< js_GetScopeChain(JSContext *cx, JSStackFrame *fp);
---
> extern JSBool
> js_GetArgument(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
337,345d228
< /*
<  * Given a context and a vector of [callee, this, args...] for a function that
<  * was specified with a JSFUN_THISP_PRIMITIVE flag, get the primitive value of
<  * |this| into *thisvp. In doing so, if |this| is an object, insist it is an
<  * instance of clasp and extract its private slot value to return via *thisvp.
<  *
<  * NB: this function loads and uses *vp before storing *thisvp, so the two may
<  * alias the same jsval.
<  */
347c230,233
< js_GetPrimitiveThis(JSContext *cx, jsval *vp, JSClass *clasp, jsval *thisvp);
---
> js_SetArgument(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
> 
> extern JSBool
> js_GetLocalVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
349,355d234
< /*
<  * For a call with arguments argv including argv[-1] (nominal |this|) and
<  * argv[-2] (callee) replace null |this| with callee's parent, replace
<  * primitive values with the equivalent wrapper objects and censor activation
<  * objects as, per ECMA-262, they may not be referred to by |this|. argv[-1]
<  * must not be a JSVAL_VOID.
<  */
357c236
< js_ComputeThis(JSContext *cx, jsval *argv);
---
> js_SetLocalVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
361,366c240
<  * is non-null), and that vp points to the callee, |this| parameter, and
<  * actual arguments of the call. [vp .. vp + 2 + argc) must belong to the last
<  * JS stack segment that js_AllocStack or js_AllocRawStack allocated. The
<  * function may use the space available after vp + 2 + argc in the stack
<  * segment for temporaries so the caller should not use that space for values
<  * that must be preserved across the call.
---
>  * is non-null).
369c243
< js_Invoke(JSContext *cx, uintN argc, jsval *vp, uintN flags);
---
> js_Invoke(JSContext *cx, uintN argc, uintN flags);
372,382c246,248
<  * Consolidated js_Invoke flags simply rename certain JSFRAME_* flags, so that
<  * we can share bits stored in JSStackFrame.flags and passed to:
<  *
<  *   js_Invoke
<  *   js_InternalInvoke
<  *   js_ValueToFunction
<  *   js_ValueToFunctionObject
<  *   js_ValueToCallableObject
<  *   js_ReportIsNotFunction
<  *
<  * See jsfun.h for the latter four and flag renaming macros.
---
>  * Consolidated js_Invoke flags.  NB: JSINVOKE_CONSTRUCT must be the same bit
>  * as JSFRAME_CONSTRUCTING (see js_Invoke's initialization of frame.flags --
>  * there's a #error check to ensure this identity in jsinterp.c).
384,391c250,251
< #define JSINVOKE_CONSTRUCT      JSFRAME_CONSTRUCTING
< #define JSINVOKE_INTERNAL       JSFRAME_INTERNAL
< #define JSINVOKE_ITERATOR       JSFRAME_ITERATOR
< 
< /*
<  * Mask to isolate construct and iterator flags for use with jsfun.h functions.
<  */
< #define JSINVOKE_FUNFLAGS       (JSINVOKE_CONSTRUCT | JSINVOKE_ITERATOR)
---
> #define JSINVOKE_CONSTRUCT      0x1     /* construct object rather than call */
> #define JSINVOKE_INTERNAL       0x2     /* internal call, not from a script */
417,423c277
<                       JSObject **objp, JSProperty **propp);
< 
< extern JSBool
< js_StrictlyEqual(JSContext *cx, jsval lval, jsval rval);
< 
< extern JSBool
< js_InvokeConstructor(JSContext *cx, jsval *vp, uintN argc);
---
>                       JSBool *foundp);
426c280
< js_Interpret(JSContext *cx, jsbytecode *pc, jsval *result);
---
> js_Interpret(JSContext *cx, jsval *result);
Only in /Volumes/Swap/js-14-2-2008/js/src: jsiter.c
Only in /Volumes/Swap/js-14-2-2008/js/src: jsiter.h
Only in /Volumes/Swap/js-14-2-2008/js/src: jskeyword.tbl
Only in /Volumes/Swap/js-14-2-2008/js/src: jskwgen.c
diff -r /Volumes/Swap/js-14-2-2008/js/src/jslibmath.h /Volumes/Swap/js_D11/src/jslibmath.h
3,4c3,6
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
6,14c8,11
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,22c16,21
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
24,25c23,32
<  * Contributor(s):
<  *   IBM Corp.
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
27,37c34,37
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
---
>  * This Original Code has been modified by IBM Corporation.
>  * Modifications made by IBM described herein are
>  * Copyright (c) International Business Machines
>  * Corporation, 2000
39c39,44
<  * ***** END LICENSE BLOCK ***** */
---
>  * Modifications to Mozilla code or documentation
>  * identified per MPL Section 3.3
>  *
>  * Date             Modified by     Description of modification
>  * 04/20/2000       IBM Corp.      OS/2 VisualAge build.
>  */
53,58c58,59
<  * Define on which platforms to use fdlibm. Not used by default under
<  * assumption that native math library works unless proved guilty.
<  * Plus there can be problems with endian-ness and such in fdlibm itself.
<  *
<  * fdlibm compatibility notes:
<  * - fdlibm broken on OSF1/alpha
---
>  * Define which platforms on which to use fdlibm.  Not used
>  * by default since there can be problems with endian-ness and such.
61c62,90
< #ifndef JS_USE_FDLIBM_MATH
---
> #if defined(_WIN32) && !defined(__MWERKS__)
> #define JS_USE_FDLIBM_MATH 1
> 
> #elif defined(SUNOS4)
> #define JS_USE_FDLIBM_MATH 1
> 
> #elif defined(IRIX)
> #define JS_USE_FDLIBM_MATH 1
> 
> #elif defined(SOLARIS)
> #define JS_USE_FDLIBM_MATH 1
> 
> #elif defined(HPUX)
> #define JS_USE_FDLIBM_MATH 1
> 
> #elif defined(linux)
> #define JS_USE_FDLIBM_MATH 1
> 
> #elif defined(OSF1)
> /* Want to use some fdlibm functions but fdlibm broken on OSF1/alpha. */
> #define JS_USE_FDLIBM_MATH 0
> 
> #elif defined(AIX)
> #define JS_USE_FDLIBM_MATH 1
> 
> #elif defined(XP_OS2_VACPP)
> #define JS_USE_FDLIBM_MATH 1
> 
> #else
76,90d104
< 
< /* The right copysign function is not always named the same thing. */
< #if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
< #define fd_copysign __builtin_copysign
< #elif defined WINCE
< #define fd_copysign _copysign
< #elif defined _WIN32
< #if _MSC_VER < 1400
< /* Try to work around apparent _copysign bustage in VC6 and VC7. */
< #define fd_copysign js_copysign
< extern double js_copysign(double, double);
< #else
< #define fd_copysign _copysign
< #endif
< #else
92,93d105
< #endif
< 
118c130
< #if (defined _WIN32 && !defined WINCE) || defined SUNOS4
---
> #if defined _WIN32 || defined SUNOS4 
198a211,230
> #elif defined(linux)
> 
> #define fd_atan atan
> #define fd_atan2 atan2
> #define fd_ceil ceil
> #define fd_cos cos
> #define fd_fabs fabs
> #define fd_floor floor
> #define fd_fmod fmod
> #define fd_sin sin
> #define fd_sqrt sqrt
> #define fd_tan tan
> #define fd_copysign copysign
> 
> extern double fd_asin __P((double));
> extern double fd_acos __P((double));
> extern double fd_exp __P((double));
> extern double fd_log __P((double));
> extern double fd_pow __P((double, double));
> 
238a271,291
> #elif defined(XP_OS2_VACPP)
> 
> #define fd_acos acos
> #define fd_asin asin
> #define fd_atan2 atan2
> #define fd_cos cos
> #define fd_exp exp
> #define fd_fabs fabs
> #define fd_floor floor
> #define fd_fmod fmod
> #define fd_log log
> #define fd_sin sin
> #define fd_sqrt sqrt
> #define fd_atan atan
> #define fd_ceil ceil
> #define fd_pow pow
> #define fd_tan tan
> 
> /* OS2 lacks copysign */
> extern double fd_copysign __P((double, double));
> 
247c300
< 
---
>  
diff -r /Volumes/Swap/js-14-2-2008/js/src/jslock.c /Volumes/Swap/js_D11/src/jslock.c
3,4c3,6
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
6,14c8,11
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,22c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
26,38c23,33
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
46c41
< #include <stdlib.h>
---
> #include "xstdlib.h"
47a43
> #include "prthread.h"
54d49
< #include "jsfun.h"      /* for VALUE_IS_FUNCTION used by *_WRITE_BARRIER */
64a60,61
> //#include "_optimize.h"
> 
89,91d85
< extern long __cdecl
< _InterlockedCompareExchange(long *volatile dest, long exchange, long comp);
< #pragma intrinsic(_InterlockedCompareExchange)
93,94c87,88
< JS_INLINE(static int
< js_CompareAndSwapHelper(jsword *w, jsword ov, jsword nv))
---
> static JS_INLINE int
> js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
96d89
<     _InterlockedCompareExchange(w, nv, ov);
97a91,94
>         mov eax, ov
>         mov ecx, nv
>         mov ebx, w
>         lock cmpxchg [ebx], ecx
98a96
>         and eax, 1h
102,122d99
< JS_INLINE(static int
< js_CompareAndSwap(jsword *w, jsword ov, jsword nv))
< {
<     return (js_CompareAndSwapHelper(w, ov, nv) & 1);
< }
< 
< #elif defined(XP_MACOSX) || defined(DARWIN)
< 
< #include <libkern/OSAtomic.h>
< 
< JS_INLINE(static int
< js_CompareAndSwap(jsword *w, jsword ov, jsword nv))
< {
<     /* Details on these functions available in the manpage for atomic */
< #if JS_BYTES_PER_WORD == 8 && JS_BYTES_PER_LONG != 8
<     return OSAtomicCompareAndSwap64Barrier(ov, nv, (int64_t*) w);
< #else
<     return OSAtomicCompareAndSwap32Barrier(ov, nv, (int32_t*) w);
< #endif
< }
< 
126,127c103,104
< JS_INLINE(static int
< js_CompareAndSwap(jsword *w, jsword ov, jsword nv))
---
> static JS_INLINE int
> js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
142,179d118
< #elif (defined(__USLC__) || defined(_SCO_DS)) && defined(i386)
< 
< /* Note: This fails on 386 cpus, cmpxchgl is a >= 486 instruction */
< 
< asm int
< js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
< {
< %ureg w, nv;
< 	movl	ov,%eax
< 	lock
< 	cmpxchgl nv,(w)
< 	sete	%al
< 	andl	$1,%eax
< %ureg w;  mem ov, nv;
< 	movl	ov,%eax
< 	movl	nv,%ecx
< 	lock
< 	cmpxchgl %ecx,(w)
< 	sete	%al
< 	andl	$1,%eax
< %ureg nv;
< 	movl	ov,%eax
< 	movl	w,%edx
< 	lock
< 	cmpxchgl nv,(%edx)
< 	sete	%al
< 	andl	$1,%eax
< %mem w, ov, nv;
< 	movl	ov,%eax
< 	movl	nv,%ecx
< 	movl	w,%edx
< 	lock
< 	cmpxchgl %ecx,(%edx)
< 	sete	%al
< 	andl	$1,%eax
< }
< #pragma asm full_optimization js_CompareAndSwap
< 
182,183c121,122
< JS_INLINE(static int
< js_CompareAndSwap(jsword *w, jsword ov, jsword nv))
---
> static JS_INLINE int
> js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
210,211c149,150
< JS_INLINE(static int
< js_CompareAndSwap(jsword *w, jsword ov, jsword nv))
---
> static JS_INLINE int
> js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
215a155,158
> #elif defined(XP_OS2_VACPP)
> 
> /* js_CompareAndSwap implemented in jslocko.asm */
> 
223a167,172
> jsword
> js_CurrentThreadId()
> {
>     return CurrentThreadId();
> }
> 
248d196
< #ifndef NSPR_LOCK
250d197
< #endif
343c290
< ShareScope(JSContext *cx, JSScope *scope)
---
> ShareScope(JSRuntime *rt, JSScope *scope)
345d291
<     JSRuntime *rt;
348d293
<     rt = cx->runtime;
359,360c304,328
<     scope->u.count = 0;
<     js_FinishSharingScope(cx, scope);
---
>     if (scope == rt->setSlotScope) {
>         /*
>          * Nesting locks on another thread that's using scope->ownercx: give
>          * the held lock a reentrancy count of 1 and set its lock.owner field
>          * directly (no compare-and-swap needed while scope->ownercx is still
>          * non-null).  See below in ClaimScope, before the ShareScope call,
>          * for more on why this is necessary.
>          *
>          * If NSPR_LOCK is defined, we cannot deadlock holding rt->gcLock and
>          * acquiring scope->lock.fat here, against another thread holding that
>          * fat lock and trying to grab rt->gcLock.  This is because no other
>          * thread can attempt to acquire scope->lock.fat until scope->ownercx
>          * is null *and* our thread has released rt->gcLock, which interlocks
>          * scope->ownercx's transition to null against tests of that member
>          * in ClaimScope.
>          */
>         scope->lock.owner = scope->ownercx->thread;
> #ifdef NSPR_LOCK
>         JS_ACQUIRE_LOCK((JSLock*)scope->lock.fat);
> #endif
>         scope->u.count = 1;
>     } else {
>         scope->u.count = 0;
>     }
>     js_FinishSharingScope(rt, scope);
374a343,356
> #define MAKE_STRING_IMMUTABLE(rt, v, vp)                                      \
>     JS_BEGIN_MACRO                                                            \
>         JSString *str_ = JSVAL_TO_STRING(v);                                  \
>         uint8 *flagp_ = js_GetGCThingFlags(str_);                             \
>         if (*flagp_ & GCF_MUTABLE) {                                          \
>             if (JSSTRING_IS_DEPENDENT(str_) &&                                \
>                 !js_UndependString(NULL, str_)) {                             \
>                 JS_RUNTIME_METER(rt, badUndependStrings);                     \
>                 *vp = JSVAL_VOID;                                             \
>             } else {                                                          \
>                 *flagp_ &= ~GCF_MUTABLE;                                      \
>             }                                                                 \
>         }                                                                     \
>     JS_END_MACRO
377c359
< js_FinishSharingScope(JSContext *cx, JSScope *scope)
---
> js_FinishSharingScope(JSRuntime *rt, JSScope *scope)
380,381c362,363
<     uint32 nslots, i;
<     jsval v;
---
>     uint32 nslots;
>     jsval v, *vp, *end;
384,396c366,370
<     nslots = LOCKED_OBJ_NSLOTS(obj);
<     for (i = 0; i != nslots; ++i) {
<         v = STOBJ_GET_SLOT(obj, i);
<         if (JSVAL_IS_STRING(v) &&
<             !js_MakeStringImmutable(cx, JSVAL_TO_STRING(v))) {
<             /*
<              * FIXME bug 363059: The following error recovery changes runtime
<              * execution semantics, arbitrarily and silently ignoring errors
<              * except out-of-memory, which should have been reported through
<              * JS_ReportOutOfMemory at this point.
<              */
<             STOBJ_SET_SLOT(obj, i, JSVAL_VOID);
<         }
---
>     nslots = JS_MIN(obj->map->freeslot, obj->map->nslots);
>     for (vp = obj->slots, end = vp + nslots; vp < end; vp++) {
>         v = *vp;
>         if (JSVAL_IS_STRING(v))
>             MAKE_STRING_IMMUTABLE(rt, v, vp);
400c374
<     JS_RUNTIME_METER(cx->runtime, sharedScopes);
---
>     JS_RUNTIME_METER(rt, sharedScopes);
453c427,428
<          * avoidance works because the engine never nests scope locks.
---
>          * avoidance works because the engine never nests scope locks, except
>          * for the notable case of js_SetProtoOrParent (see jsobj.c).
459,460c434,445
<          * The engine promotes a scope from exclusive to shared access only
<          * when locking, never when holding or unlocking.
---
>          * Apart from the js_SetProtoOrParent exception, the engine promotes
>          * a scope from exclusive to shared access only when locking, never
>          * when holding or unlocking.
>          *
>          * If ownercx's thread is calling js_SetProtoOrParent, trying to lock
>          * the inner scope (the scope of the object being set as the prototype
>          * of the outer object), ShareScope will find the outer object's scope
>          * at rt->setSlotScope.  If it's the same as scope, we give it a lock
>          * held by ownercx's thread with reentrancy count of 1, then we return
>          * here and break.  After that we unwind to js_[GS]etSlotThreadSafe or
>          * js_LockScope (our caller), where we wait on the newly-fattened lock
>          * until ownercx's thread unwinds from js_SetProtoOrParent.
465c450
<          * a finalizer) that can't be claimed must become shared.
---
>          * a finalizer) that can't be claimed must be slated for sharing.
470c455
<             ShareScope(cx, scope);
---
>             ShareScope(rt, scope);
578,589c563,566
<     JS_ASSERT(slot < obj->map->freeslot);
< 
<     /*
<      * Avoid locking if called from the GC.  Also avoid locking an object
<      * owning a sealed scope.  If neither of those special cases applies, try
<      * to claim scope's flyweight lock from whatever context may have had it in
<      * an earlier request.
<      */
<     if (CX_THREAD_IS_RUNNING_GC(cx) ||
<         (SCOPE_IS_SEALED(scope) && scope->object == obj) ||
<         (scope->ownercx && ClaimScope(scope, cx))) {
<         return STOBJ_GET_SLOT(obj, slot);
---
>     JS_ASSERT(obj->slots && slot < obj->map->freeslot);
>     if ((scope->ownercx && ClaimScope(scope, cx)) ||
>         CX_THREAD_IS_RUNNING_GC(cx)) {
>         return obj->slots[slot];
594,595c571,572
<     me = CX_THINLOCK_ID(cx);
<     JS_ASSERT(CURRENT_THREAD_IS_ME(me));
---
>     me = cx->thread;
>     JS_ASSERT(me == CurrentThreadId());
604c581
<             v = STOBJ_GET_SLOT(obj, slot);
---
>             v = obj->slots[slot];
618c595
<         return STOBJ_GET_SLOT(obj, slot);
---
>         return obj->slots[slot];
623c600
<     v = STOBJ_GET_SLOT(obj, slot);
---
>     v = obj->slots[slot];
650,654c627,628
<     if (JSVAL_IS_STRING(v) &&
<         !js_MakeStringImmutable(cx, JSVAL_TO_STRING(v))) {
<         /* FIXME bug 363059: See comments in js_FinishSharingScope. */
<         v = JSVAL_NULL;
<     }
---
>     if (JSVAL_IS_STRING(v))
>         MAKE_STRING_IMMUTABLE(cx->runtime, v, &v);
671,682c645,648
<     JS_ASSERT(slot < obj->map->freeslot);
< 
<     /*
<      * Avoid locking if called from the GC.  Also avoid locking an object
<      * owning a sealed scope.  If neither of those special cases applies, try
<      * to claim scope's flyweight lock from whatever context may have had it in
<      * an earlier request.
<      */
<     if (CX_THREAD_IS_RUNNING_GC(cx) ||
<         (SCOPE_IS_SEALED(scope) && scope->object == obj) ||
<         (scope->ownercx && ClaimScope(scope, cx))) {
<         LOCKED_OBJ_WRITE_BARRIER(cx, obj, slot, v);
---
>     JS_ASSERT(obj->slots && slot < obj->map->freeslot);
>     if ((scope->ownercx && ClaimScope(scope, cx)) ||
>         CX_THREAD_IS_RUNNING_GC(cx)) {
>         obj->slots[slot] = v;
688,689c654,655
<     me = CX_THINLOCK_ID(cx);
<     JS_ASSERT(CURRENT_THREAD_IS_ME(me));
---
>     me = cx->thread;
>     JS_ASSERT(me == CurrentThreadId());
692c658
<             LOCKED_OBJ_WRITE_BARRIER(cx, obj, slot, v);
---
>             obj->slots[slot] = v;
706c672
<         LOCKED_OBJ_WRITE_BARRIER(cx, obj, slot, v);
---
>         obj->slots[slot] = v;
712c678
<     LOCKED_OBJ_WRITE_BARRIER(cx, obj, slot, v);
---
>     obj->slots[slot] = v;
715c681,685
<      * Same drill as above, in js_GetSlotThreadSafe.
---
>      * Same drill as above, in js_GetSlotThreadSafe.  Note that we cannot
>      * assume obj has its own mutable scope (where scope->object == obj) yet,
>      * because OBJ_SET_SLOT is called for the "universal", common slots such
>      * as JSSLOT_PROTO and JSSLOT_PARENT, without a prior js_GetMutableScope.
>      * See also the JSPROP_SHARED attribute and its usage.
727c697
<     JSFatLock *fl = (JSFatLock *)malloc(sizeof(JSFatLock)); /* for now */
---
>     JSFatLock *fl = (JSFatLock *)xmalloc(sizeof(JSFatLock)); /* for now */
742c712
<     free(fl);
---
>     xfree(fl);
836c806
<     global_locks = (PRLock **) malloc(global_lock_count * sizeof(PRLock*));
---
>     global_locks = (PRLock **) xmalloc(global_lock_count * sizeof(PRLock*));
847c817
<     fl_list_table = (JSFatLockTable *) malloc(i * sizeof(JSFatLockTable));
---
>     fl_list_table = (JSFatLockTable *) xmalloc(i * sizeof(JSFatLockTable));
869c839
<         free(global_locks);
---
>         xfree(global_locks);
882c852
<         free(fl_list_table);
---
>         xfree(fl_list_table);
886a857,864
>     js_FinishDtoa();
> }
> 
> void
> js_InitContextForLocking(JSContext *cx)
> {
>     cx->thread = CurrentThreadId();
>     JS_ASSERT(Thin_GetWait(cx->thread) == 0);
1006,1007c984,985
< JS_INLINE(void
< js_Lock(JSThinLock *tl, jsword me))
---
> JS_INLINE void
> js_Lock(JSThinLock *tl, jsword me)
1009c987
<     JS_ASSERT(CURRENT_THREAD_IS_ME(me));
---
>     JS_ASSERT(me == CurrentThreadId());
1020,1021c998,999
< JS_INLINE(void
< js_Unlock(JSThinLock *tl, jsword me))
---
> JS_INLINE void
> js_Unlock(JSThinLock *tl, jsword me)
1023,1028c1001
<     JS_ASSERT(CURRENT_THREAD_IS_ME(me));
< 
<     /*
<      * Since we can race with the CompareAndSwap in js_Enqueue, we need
<      * to use a C_A_S here as well -- Arjan van de Ven 30/1/08
<      */
---
>     JS_ASSERT(me == CurrentThreadId());
1031,1032d1003
< 
<     JS_ASSERT(Thin_GetWait(tl->owner));
1037c1008
<         JS_ASSERT(0);   /* unbalanced unlock */
---
>         JS_ASSERT(0);
1048c1019
<     rt->rtLockOwner = js_CurrentThreadId();
---
>     rt->rtLockOwner = CurrentThreadId();
1064c1035
<     jsword me = CX_THINLOCK_ID(cx);
---
>     jsword me = cx->thread;
1066c1037
<     JS_ASSERT(CURRENT_THREAD_IS_ME(me));
---
>     JS_ASSERT(me == CurrentThreadId());
1068,1069d1038
<     if (CX_THREAD_IS_RUNNING_GC(cx))
<         return;
1071a1041,1042
>     if (CX_THREAD_IS_RUNNING_GC(cx))
>         return;
1089c1060
<     jsword me = CX_THINLOCK_ID(cx);
---
>     jsword me = cx->thread;
1094,1118d1064
<     if (cx->lockedSealedScope == scope) {
<         cx->lockedSealedScope = NULL;
<         return;
<     }
< 
<     /*
<      * If scope->ownercx is not null, it's likely that two contexts not using
<      * requests nested locks for scope.  The first context, cx here, claimed
<      * scope; the second, scope->ownercx here, re-claimed it because the first
<      * was not in a request, or was on the same thread.  We don't want to keep
<      * track of such nesting, because it penalizes the common non-nested case.
<      * Instead of asserting here and silently coping, we simply re-claim scope
<      * for cx and return.
<      *
<      * See http://bugzilla.mozilla.org/show_bug.cgi?id=229200 for a real world
<      * case where an asymmetric thread model (Mozilla's main thread is known
<      * to be the only thread that runs the GC) combined with multiple contexts
<      * per thread has led to such request-less nesting.
<      */
<     if (scope->ownercx) {
<         JS_ASSERT(scope->u.count == 0);
<         JS_ASSERT(scope->lock.owner == 0);
<         scope->ownercx = cx;
<         return;
<     }
1119a1066
>     JS_ASSERT(scope->ownercx == NULL);
1142c1089
<     JS_ASSERT(JS_IS_SCOPE_LOCKED(cx, newscope));
---
>     JS_ASSERT(JS_IS_SCOPE_LOCKED(newscope));
1149,1172c1096,1097
<         return;
<     JS_ASSERT(JS_IS_SCOPE_LOCKED(cx, oldscope));
< 
<     /*
<      * Special case in js_LockScope and js_UnlockScope for the GC calling
<      * code that locks, unlocks, or mutates.  Nothing to do in these cases,
<      * because scope and newscope were "locked" by the GC thread, so neither
<      * was actually locked.
<      */
<     if (CX_THREAD_IS_RUNNING_GC(cx))
<         return;
< 
<     /*
<      * Special case in js_LockObj and js_UnlockScope for locking the sealed
<      * scope of an object that owns that scope (the prototype or mutated obj
<      * for which OBJ_SCOPE(obj)->object == obj), and unlocking it.
<      */
<     JS_ASSERT(cx->lockedSealedScope != newscope);
<     if (cx->lockedSealedScope == oldscope) {
<         JS_ASSERT(newscope->ownercx == cx ||
<                   (!newscope->ownercx && newscope->u.count == 1));
<         cx->lockedSealedScope = NULL;
<         return;
<     }
---
> 	return;
>     JS_ASSERT(JS_IS_SCOPE_LOCKED(oldscope));
1175a1101
>      * XXX if (!newscope->ownercx), assume newscope->u.count is properly set
1179,1180c1105
<         JS_ASSERT(newscope->ownercx == cx ||
<                   (!newscope->ownercx && newscope->u.count == 1));
---
>         JS_ASSERT(newscope->ownercx == cx || !newscope->ownercx);
1201c1126
<     me = CX_THINLOCK_ID(cx);
---
>     me = cx->thread;
1211,1219d1135
< 
<     /*
<      * We must test whether the GC is calling and return without mutating any
<      * state, especially cx->lockedSealedScope.  Note asymmetry with respect to
<      * js_UnlockObj, which is a thin-layer on top of js_UnlockScope.
<      */
<     if (CX_THREAD_IS_RUNNING_GC(cx))
<         return;
< 
1222,1227d1137
<         if (SCOPE_IS_SEALED(scope) && scope->object == obj &&
<             !cx->lockedSealedScope) {
<             cx->lockedSealedScope = scope;
<             return;
<         }
< 
1247d1156
< 
1251c1160
<     return js_CurrentThreadId() == rt->rtLockOwner;
---
>     return CurrentThreadId() == rt->rtLockOwner;
1255c1164
< js_IsObjLocked(JSContext *cx, JSObject *obj)
---
> js_IsObjLocked(JSObject *obj)
1259c1168,1170
<     return MAP_IS_NATIVE(&scope->map) && js_IsScopeLocked(cx, scope);
---
>     return MAP_IS_NATIVE(&scope->map) &&
>            (scope->ownercx ||
>             CurrentThreadId() == Thin_RemoveWait(ReadWord(scope->lock.owner)));
1263c1174
< js_IsScopeLocked(JSContext *cx, JSScope *scope)
---
> js_IsScopeLocked(JSScope *scope)
1265,1282c1176,1177
<     /* Special case: the GC locking any object's scope, see js_LockScope. */
<     if (CX_THREAD_IS_RUNNING_GC(cx))
<         return JS_TRUE;
< 
<     /* Special case: locked object owning a sealed scope, see js_LockObj. */
<     if (cx->lockedSealedScope == scope)
<         return JS_TRUE;
< 
<     /*
<      * General case: the scope is either exclusively owned (by cx), or it has
<      * a thin or fat lock to cope with shared (concurrent) ownership.
<      */
<     if (scope->ownercx) {
<         JS_ASSERT(scope->ownercx == cx || scope->ownercx->thread == cx->thread);
<         return JS_TRUE;
<     }
<     return js_CurrentThreadId() ==
<            ((JSThread *)Thin_RemoveWait(ReadWord(scope->lock.owner)))->id;
---
>     return scope->ownercx ||
>            CurrentThreadId() == Thin_RemoveWait(ReadWord(scope->lock.owner));
1283a1179
> #endif
1285d1180
< #endif /* DEBUG */
diff -r /Volumes/Swap/js-14-2-2008/js/src/jslock.h /Volumes/Swap/js_D11/src/jslock.h
3,4c3,6
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
6,14c8,11
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,22c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
26,38c23,33
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
48d42
< #include "prthread.h"
53,54d46
< JS_BEGIN_EXTERN_C
< 
74,76d65
< #define CX_THINLOCK_ID(cx)       ((jsword)(cx)->thread)
< #define CURRENT_THREAD_IS_ME(me) (((JSThread *)me)->id == js_CurrentThreadId())
< 
90d78
< #define JS_ATOMIC_ADD(p,v)          PR_AtomicAdd((PRInt32 *)(p), (PRInt32)(v))
92c80,81
< #define js_CurrentThreadId()        (jsword)PR_GetCurrentThread()
---
> #define CurrentThreadId()           (jsword)PR_GetCurrentThread()
> #define JS_CurrentThreadId()        js_CurrentThreadId()
115,121c104,109
<  * We also need jsscope.h #ifdef JS_DEBUG_SCOPE_LOCKS for SET_OBJ_INFO and
<  * SET_SCOPE_INFO, but we do not want any nested includes that depend on DEBUG.
<  * Those lead to build bustage when someone makes a change that depends in a
<  * subtle way on jsscope.h being included directly or indirectly, but does not
<  * test by building optimized as well as DEBUG.
<   */
< JS_END_EXTERN_C
---
>  * We also need jsscope.h #ifdef DEBUG for SET_OBJ_INFO and SET_SCOPE_INFO,
>  * but we do not want any nested includes that depend on DEBUG.  Those lead
>  * to build bustage when someone makes a change that depends in a subtle way
>  * on jsscope.h being included directly or indirectly, but does not test by
>  * building optimized as well as DEBUG.
>  */
123d110
< JS_BEGIN_EXTERN_C
125c112
< #ifdef JS_DEBUG_SCOPE_LOCKS
---
> #ifdef DEBUG
132,133c119
<      (JS_ASSERT((0 < (scope_)->u.count && (scope_)->u.count <= 4) ||          \
<                 SCOPE_IS_SEALED(scope_)),                                     \
---
>      (JS_ASSERT((scope_)->u.count > 0 && (scope_)->u.count <= 4),             \
136,137c122
< 
< #endif
---
> #endif /* DEBUG */
149,154c134,139
< #define JS_LOCK_OBJ(cx,obj)       ((OBJ_SCOPE(obj)->ownercx == (cx))          \
<                                    ? (void)0                                  \
<                                    : (js_LockObj(cx, obj),                    \
<                                       SET_OBJ_INFO(obj,__FILE__,__LINE__)))
< #define JS_UNLOCK_OBJ(cx,obj)     ((OBJ_SCOPE(obj)->ownercx == (cx))          \
<                                    ? (void)0 : js_UnlockObj(cx, obj))
---
> #define JS_LOCK_OBJ(cx,obj)         ((OBJ_SCOPE(obj)->ownercx == (cx))        \
>                                      ? (void)0                                \
>                                      : (js_LockObj(cx, obj),                  \
>                                         SET_OBJ_INFO(obj,__FILE__,__LINE__)))
> #define JS_UNLOCK_OBJ(cx,obj)       ((OBJ_SCOPE(obj)->ownercx == (cx))        \
>                                      ? (void)0 : js_UnlockObj(cx, obj))
156,157c141,142
< #define JS_LOCK_SCOPE(cx,scope)   ((scope)->ownercx == (cx) ? (void)0         \
<                                    : (js_LockScope(cx, scope),                \
---
> #define JS_LOCK_SCOPE(cx,scope)     ((scope)->ownercx == (cx) ? (void)0 :     \
>                                      (js_LockScope(cx, scope),                \
159,160c144,145
< #define JS_UNLOCK_SCOPE(cx,scope) ((scope)->ownercx == (cx) ? (void)0         \
<                                    : js_UnlockScope(cx, scope))
---
> #define JS_UNLOCK_SCOPE(cx,scope)   ((scope)->ownercx == (cx) ? (void)0 :     \
>                                      js_UnlockScope(cx, scope))
162c147
<                                   js_TransferScopeLock(cx, scope, newscope)
---
>                                     js_TransferScopeLock(cx, scope, newscope)
163a149
> extern jsword js_CurrentThreadId();
171a158
> extern void js_InitContextForLocking(JSContext *);
178c165
< extern void js_FinishSharingScope(JSContext *cx, JSScope *scope);
---
> extern void js_FinishSharingScope(JSRuntime *rt, JSScope *scope);
182,184c169,171
< #define JS_IS_RUNTIME_LOCKED(rt)        js_IsRuntimeLocked(rt)
< #define JS_IS_OBJ_LOCKED(cx,obj)        js_IsObjLocked(cx,obj)
< #define JS_IS_SCOPE_LOCKED(cx,scope)    js_IsScopeLocked(cx,scope)
---
> #define JS_IS_RUNTIME_LOCKED(rt)    js_IsRuntimeLocked(rt)
> #define JS_IS_OBJ_LOCKED(obj)       js_IsObjLocked(obj)
> #define JS_IS_SCOPE_LOCKED(scope)   js_IsScopeLocked(scope)
187,188c174,175
< extern JSBool js_IsObjLocked(JSContext *cx, JSObject *obj);
< extern JSBool js_IsScopeLocked(JSContext *cx, JSScope *scope);
---
> extern JSBool js_IsObjLocked(JSObject *obj);
> extern JSBool js_IsScopeLocked(JSScope *scope);
192,194c179,181
< #define JS_IS_RUNTIME_LOCKED(rt)        0
< #define JS_IS_OBJ_LOCKED(cx,obj)        1
< #define JS_IS_SCOPE_LOCKED(cx,scope)    1
---
> #define JS_IS_RUNTIME_LOCKED(rt)    0
> #define JS_IS_OBJ_LOCKED(obj)       1
> #define JS_IS_SCOPE_LOCKED(scope)   1
214d200
<        ((defined(__USLC__) || defined(_SCO_DS)) && defined(i386)) ||          \
216c202
<        defined(AIX) )
---
>        defined(AIX) || defined(XP_OS2_VACPP) )
229,230c215,216
< extern void js_Lock(JSThinLock *tl, jsword me);
< extern void js_Unlock(JSThinLock *tl, jsword me);
---
> extern JS_INLINE void js_Lock(JSThinLock *tl, jsword me);
> extern JS_INLINE void js_Unlock(JSThinLock *tl, jsword me);
236,237d221
< JS_BEGIN_EXTERN_C
< 
240d223
< #define JS_ATOMIC_ADD(p,v)          (*(p) += (v))
265,268c248,251
< #define JS_IS_RUNTIME_LOCKED(rt)        1
< #define JS_IS_OBJ_LOCKED(cx,obj)        1
< #define JS_IS_SCOPE_LOCKED(cx,scope)    1
< #define JS_LOCK_VOID(cx, e)             JS_LOCK_RUNTIME_VOID((cx)->runtime, e)
---
> #define JS_IS_RUNTIME_LOCKED(rt)    1
> #define JS_IS_OBJ_LOCKED(obj)       1
> #define JS_IS_SCOPE_LOCKED(scope)   1
> #define JS_LOCK_VOID(cx, e)         JS_LOCK_RUNTIME_VOID((cx)->runtime, e)
288,290c271,273
< #define JS_LOCK(P,CX)               JS_LOCK0(P, CX_THINLOCK_ID(CX))
< #define JS_UNLOCK(P,CX)             JS_UNLOCK0(P, CX_THINLOCK_ID(CX))
<  
---
> #define JS_LOCK(P,CX)               JS_LOCK0(P,(CX)->thread)
> #define JS_UNLOCK(P,CX)             JS_UNLOCK0(P,(CX)->thread)
> 
298,299d280
< JS_END_EXTERN_C
< 
diff -r /Volumes/Swap/js-14-2-2008/js/src/jslocko.asm /Volumes/Swap/js_D11/src/jslocko.asm
1c1,3
< ; -*- Mode: asm; tab-width: 8; c-basic-offset: 4 -*-
---
> COMMENT | -*- Mode: asm; tab-width: 8; c-basic-offset: 4 -*-
> ***** BEGIN LICENSE BLOCK *****
> Version: MPL 1.1/GPL 2.0/LGPL 2.1
3,37c5,37
< ; ***** BEGIN LICENSE BLOCK *****
< ; Version: MPL 1.1/GPL 2.0/LGPL 2.1
< ; 
< ; The contents of this file are subject to the Mozilla Public License Version 
< ; 1.1 (the "License"); you may not use this file except in compliance with 
< ; the License. You may obtain a copy of the License at 
< ; http://www.mozilla.org/MPL/
< ; 
< ; Software distributed under the License is distributed on an "AS IS" basis,
< ; WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
< ; for the specific language governing rights and limitations under the
< ; License.
< ; 
< ; The Original Code is an OS/2 implementation of js_CompareAndSwap in assembly.
< ; 
< ; The Initial Developer of the Original Code is
< ; IBM Corporation.
< ; Portions created by the Initial Developer are Copyright (C) 2001
< ; the Initial Developer. All Rights Reserved.
< ; 
< ; Contributor(s):
< ; 
< ; Alternatively, the contents of this file may be used under the terms of
< ; either the GNU General Public License Version 2 or later (the "GPL"), or
< ; the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
< ; in which case the provisions of the GPL or the LGPL are applicable instead
< ; of those above. If you wish to allow use of your version of this file only
< ; under the terms of either the GPL or the LGPL, and not to allow others to
< ; use your version of this file under the terms of the MPL, indicate your
< ; decision by deleting the provisions above and replace them with the notice
< ; and other provisions required by the GPL or the LGPL. If you do not delete
< ; the provisions above, a recipient may use your version of this file under
< ; the terms of any one of the MPL, the GPL or the LGPL.
< ; 
< ; ***** END LICENSE BLOCK *****
---
> The contents of this file are subject to the Mozilla Public License Version 
> 1.1 (the "License"); you may not use this file except in compliance with 
> the License. You may obtain a copy of the License at 
> http://www.mozilla.org/MPL/
> 
> Software distributed under the License is distributed on an "AS IS" basis,
> WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
> for the specific language governing rights and limitations under the
> License.
> 
> The Original Code is an OS/2 implementation of js_CompareAndSwap in assembly
> 
> The Initial Developer of the Original Code is
> IBM Corporation.
> Portions created by the Initial Developer are Copyright (C) 2001
> the Initial Developer. All Rights Reserved.
> 
> Contributor(s):
> 
> Alternatively, the contents of this file may be used under the terms of
> either the GNU General Public License Version 2 or later (the "GPL"), or
> the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
> in which case the provisions of the GPL or the LGPL are applicable instead
> of those above. If you wish to allow use of your version of this file only
> under the terms of either the GPL or the LGPL, and not to allow others to
> use your version of this file under the terms of the MPL, indicate your
> decision by deleting the provisions above and replace them with the notice
> and other provisions required by the GPL or the LGPL. If you do not delete
> the provisions above, a recipient may use your version of this file under
> the terms of any one of the MPL, the GPL or the LGPL.
> 
> ***** END LICENSE BLOCK *****
>         |
diff -r /Volumes/Swap/js-14-2-2008/js/src/jslog2.c /Volumes/Swap/js_D11/src/jslog2.c
1,13c1,11
< /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
< /* ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
> /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
> /*
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
18,37c16,33
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
41c37,38
< #include "jsutil.h"
---
> 
> //#include "_optimize.h"
48c45
<     JSIntn log2;
---
>     JSIntn log2 = 0;
50c47,58
<     JS_CEILING_LOG2(log2, n);
---
>     if (n & (n-1))
> 	log2++;
>     if (n >> 16)
> 	log2 += 16, n >>= 16;
>     if (n >> 8)
> 	log2 += 8, n >>= 8;
>     if (n >> 4)
> 	log2 += 4, n >>= 4;
>     if (n >> 2)
> 	log2 += 2, n >>= 2;
>     if (n >> 1)
> 	log2++;
60c68
<     JSIntn log2;
---
>     JSIntn log2 = 0;
62c70,79
<     JS_FLOOR_LOG2(log2, n);
---
>     if (n >> 16)
> 	log2 += 16, n >>= 16;
>     if (n >> 8)
> 	log2 += 8, n >>= 8;
>     if (n >> 4)
> 	log2 += 4, n >>= 4;
>     if (n >> 2)
> 	log2 += 2, n >>= 2;
>     if (n >> 1)
> 	log2++;
65,94d81
< 
< /*
<  * js_FloorLog2wImpl has to be defined only for 64-bit non-GCC case.
<  */
< #if !defined(JS_HAS_BUILTIN_BITSCAN64) && JS_BYTES_PER_WORD == 8
< 
< JSUword
< js_FloorLog2wImpl(JSUword n)
< {
<     JSUword log2, m;
< 
<     JS_ASSERT(n != 0);
< 
<     log2 = 0;
<     m = n >> 32;
<     if (m != 0) { n = m; log2 = 32; }
<     m = n >> 16;
<     if (m != 0) { n = m; log2 |= 16; }
<     m = n >> 8;
<     if (m != 0) { n = m; log2 |= 8; }
<     m = n >> 4;
<     if (m != 0) { n = m; log2 |= 4; }
<     m = n >> 2;
<     if (m != 0) { n = m; log2 |= 2; }
<     log2 |= (n >> 1);
< 
<     return log2;
< }
< 
< #endif
diff -r /Volumes/Swap/js-14-2-2008/js/src/jslong.c /Volumes/Swap/js_D11/src/jslong.c
2,8c2,6
< /* ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
---
> /*
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
10,13c8,11
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
18,21c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
23c21
<  * Contributor(s):
---
>  * Contributor(s): 
25,37c23,33
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
42a39,40
> #include "_optimize.h"
> 
77,80c75,78
<         if (r1 >= b     /* i.e., we didn't get a carry when adding to r1 */
<             && r1 < m) {
<             q1--, r1 += b;
<         }
---
>         if (r1 >= b	/* i.e., we didn't get a carry when adding to r1 */
> 	    && r1 < m) {
> 	    q1--, r1 += b;
> 	}
90,92c88,90
<             && r0 < m) {
<             q0--, r0 += b;
<         }
---
> 	    && r0 < m) {
> 	    q0--, r0 += b;
> 	}
104c102
<         r -= 16, a = t;
---
> 	r -= 16, a = t;
106c104
<         r -= 8, a = t;
---
> 	r -= 8, a = t;
108c106
<         r -= 4, a = t;
---
> 	r -= 4, a = t;
110c108
<         r -= 2, a = t;
---
> 	r -= 2, a = t;
112c110
<         r -= 1, a = t;
---
> 	r -= 1, a = t;
114c112
<         r--;
---
> 	r--;
128,129c126,127
<         if (b.lo > n1) {
<             /* (0 q0) = (n1 n0) / (0 D0) */
---
> 	if (b.lo > n1) {
> 	    /* (0 q0) = (n1 n0) / (0 D0) */
131c129
<             lsh = CountLeadingZeros(b.lo);
---
> 	    lsh = CountLeadingZeros(b.lo);
133,195c131,193
<             if (lsh) {
<                 /*
<                  * Normalize, i.e. make the most significant bit of the
<                  * denominator be set.
<                  */
<                 b.lo = b.lo << lsh;
<                 n1 = (n1 << lsh) | (n0 >> (32 - lsh));
<                 n0 = n0 << lsh;
<             }
< 
<             a.lo = n0, a.hi = n1;
<             norm_udivmod32(&q0, &n0, a, b.lo);
<             q1 = 0;
< 
<             /* remainder is in n0 >> lsh */
<         } else {
<             /* (q1 q0) = (n1 n0) / (0 d0) */
< 
<             if (b.lo == 0)              /* user wants to divide by zero! */
<                 b.lo = 1 / b.lo;        /* so go ahead and crash */
< 
<             lsh = CountLeadingZeros(b.lo);
< 
<             if (lsh == 0) {
<                 /*
<                  * From (n1 >= b.lo)
<                  *   && (the most significant bit of b.lo is set),
<                  * conclude that
<                  *      (the most significant bit of n1 is set)
<                  *   && (the leading quotient digit q1 = 1).
<                  *
<                  * This special case is necessary, not an optimization
<                  * (Shifts counts of 32 are undefined).
<                  */
<                 n1 -= b.lo;
<                 q1 = 1;
<             } else {
<                 /*
<                  * Normalize.
<                  */
<                 rsh = 32 - lsh;
< 
<                 b.lo = b.lo << lsh;
<                 n2 = n1 >> rsh;
<                 n1 = (n1 << lsh) | (n0 >> rsh);
<                 n0 = n0 << lsh;
< 
<                 a.lo = n1, a.hi = n2;
<                 norm_udivmod32(&q1, &n1, a, b.lo);
<             }
< 
<             /* n1 != b.lo... */
< 
<             a.lo = n0, a.hi = n1;
<             norm_udivmod32(&q0, &n0, a, b.lo);
< 
<             /* remainder in n0 >> lsh */
<         }
< 
<         if (rp) {
<             rp->lo = n0 >> lsh;
<             rp->hi = 0;
<         }
---
> 	    if (lsh) {
> 		/*
> 		 * Normalize, i.e. make the most significant bit of the
> 		 * denominator be set.
> 		 */
> 		b.lo = b.lo << lsh;
> 		n1 = (n1 << lsh) | (n0 >> (32 - lsh));
> 		n0 = n0 << lsh;
> 	    }
> 
> 	    a.lo = n0, a.hi = n1;
> 	    norm_udivmod32(&q0, &n0, a, b.lo);
> 	    q1 = 0;
> 
> 	    /* remainder is in n0 >> lsh */
> 	} else {
> 	    /* (q1 q0) = (n1 n0) / (0 d0) */
> 
> 	    if (b.lo == 0)		/* user wants to divide by zero! */
> 		b.lo = 1 / b.lo;	/* so go ahead and crash */
> 
> 	    lsh = CountLeadingZeros(b.lo);
> 
> 	    if (lsh == 0) {
> 		/*
> 		 * From (n1 >= b.lo)
> 		 *   && (the most significant bit of b.lo is set),
> 		 * conclude that
> 		 *	(the most significant bit of n1 is set)
> 		 *   && (the leading quotient digit q1 = 1).
> 		 *
> 		 * This special case is necessary, not an optimization
> 		 * (Shifts counts of 32 are undefined).
> 		 */
> 		n1 -= b.lo;
> 		q1 = 1;
> 	    } else {
> 		/*
> 		 * Normalize.
> 		 */
> 		rsh = 32 - lsh;
> 
> 		b.lo = b.lo << lsh;
> 		n2 = n1 >> rsh;
> 		n1 = (n1 << lsh) | (n0 >> rsh);
> 		n0 = n0 << lsh;
> 
> 		a.lo = n1, a.hi = n2;
> 		norm_udivmod32(&q1, &n1, a, b.lo);
> 	    }
> 
> 	    /* n1 != b.lo... */
> 
> 	    a.lo = n0, a.hi = n1;
> 	    norm_udivmod32(&q0, &n0, a, b.lo);
> 
> 	    /* remainder in n0 >> lsh */
> 	}
> 
> 	if (rp) {
> 	    rp->lo = n0 >> lsh;
> 	    rp->hi = 0;
> 	}
197,198c195,196
<         if (b.hi > n1) {
<             /* (0 0) = (n1 n0) / (D1 d0) */
---
> 	if (b.hi > n1) {
> 	    /* (0 0) = (n1 n0) / (D1 d0) */
200,201c198,199
<             q0 = 0;
<             q1 = 0;
---
> 	    q0 = 0;
> 	    q1 = 0;
203,273c201,271
<             /* remainder in (n1 n0) */
<             if (rp) {
<                 rp->lo = n0;
<                 rp->hi = n1;
<             }
<         } else {
<             /* (0 q0) = (n1 n0) / (d1 d0) */
< 
<             lsh = CountLeadingZeros(b.hi);
<             if (lsh == 0) {
<                 /*
<                  * From (n1 >= b.hi)
<                  *   && (the most significant bit of b.hi is set),
<                  * conclude that
<                  *      (the most significant bit of n1 is set)
<                  *   && (the quotient digit q0 = 0 or 1).
<                  *
<                  * This special case is necessary, not an optimization.
<                  */
< 
<                 /*
<                  * The condition on the next line takes advantage of that
<                  * n1 >= b.hi (true due to control flow).
<                  */
<                 if (n1 > b.hi || n0 >= b.lo) {
<                     q0 = 1;
<                     a.lo = n0, a.hi = n1;
<                     JSLL_SUB(a, a, b);
<                 } else {
<                     q0 = 0;
<                 }
<                 q1 = 0;
< 
<                 if (rp) {
<                     rp->lo = n0;
<                     rp->hi = n1;
<                 }
<             } else {
<                 JSInt64 m;
< 
<                 /*
<                  * Normalize.
<                  */
<                 rsh = 32 - lsh;
< 
<                 b.hi = (b.hi << lsh) | (b.lo >> rsh);
<                 b.lo = b.lo << lsh;
<                 n2 = n1 >> rsh;
<                 n1 = (n1 << lsh) | (n0 >> rsh);
<                 n0 = n0 << lsh;
< 
<                 a.lo = n1, a.hi = n2;
<                 norm_udivmod32(&q0, &n1, a, b.hi);
<                 JSLL_MUL32(m, q0, b.lo);
< 
<                 if ((m.hi > n1) || ((m.hi == n1) && (m.lo > n0))) {
<                     q0--;
<                     JSLL_SUB(m, m, b);
<                 }
< 
<                 q1 = 0;
< 
<                 /* Remainder is ((n1 n0) - (m1 m0)) >> lsh */
<                 if (rp) {
<                     a.lo = n0, a.hi = n1;
<                     JSLL_SUB(a, a, m);
<                     rp->lo = (a.hi << rsh) | (a.lo >> lsh);
<                     rp->hi = a.hi >> lsh;
<                 }
<             }
<         }
---
> 	    /* remainder in (n1 n0) */
> 	    if (rp) {
> 		rp->lo = n0;
> 		rp->hi = n1;
> 	    }
> 	} else {
> 	    /* (0 q0) = (n1 n0) / (d1 d0) */
> 
> 	    lsh = CountLeadingZeros(b.hi);
> 	    if (lsh == 0) {
> 		/*
> 		 * From (n1 >= b.hi)
> 		 *   && (the most significant bit of b.hi is set),
> 		 * conclude that
> 		 *      (the most significant bit of n1 is set)
> 		 *   && (the quotient digit q0 = 0 or 1).
> 		 *
> 		 * This special case is necessary, not an optimization.
> 		 */
> 
> 		/*
> 		 * The condition on the next line takes advantage of that
> 		 * n1 >= b.hi (true due to control flow).
> 		 */
> 		if (n1 > b.hi || n0 >= b.lo) {
> 		    q0 = 1;
> 		    a.lo = n0, a.hi = n1;
> 		    JSLL_SUB(a, a, b);
> 		} else {
> 		    q0 = 0;
> 		}
> 		q1 = 0;
> 
> 		if (rp) {
> 		    rp->lo = n0;
> 		    rp->hi = n1;
> 		}
> 	    } else {
> 		JSInt64 m;
> 
> 		/*
> 		 * Normalize.
> 		 */
> 		rsh = 32 - lsh;
> 
> 		b.hi = (b.hi << lsh) | (b.lo >> rsh);
> 		b.lo = b.lo << lsh;
> 		n2 = n1 >> rsh;
> 		n1 = (n1 << lsh) | (n0 >> rsh);
> 		n0 = n0 << lsh;
> 
> 		a.lo = n1, a.hi = n2;
> 		norm_udivmod32(&q0, &n1, a, b.hi);
> 		JSLL_MUL32(m, q0, b.lo);
> 
> 		if ((m.hi > n1) || ((m.hi == n1) && (m.lo > n0))) {
> 		    q0--;
> 		    JSLL_SUB(m, m, b);
> 		}
> 
> 		q1 = 0;
> 
> 		/* Remainder is ((n1 n0) - (m1 m0)) >> lsh */
> 		if (rp) {
> 		    a.lo = n0, a.hi = n1;
> 		    JSLL_SUB(a, a, m);
> 		    rp->lo = (a.hi << rsh) | (a.lo >> lsh);
> 		    rp->hi = a.hi >> lsh;
> 		}
> 	    }
> 	}
277,278c275,276
<         qp->lo = q0;
<         qp->hi = q1;
---
> 	qp->lo = q0;
> 	qp->hi = q1;
diff -r /Volumes/Swap/js-14-2-2008/js/src/jslong.h /Volumes/Swap/js_D11/src/jslong.h
2,8c2,6
< /* ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
---
> /*
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
10,13c8,11
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
18,23c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
25,35c21
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
---
>  * Contributor(s): 
37c23,33
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
188c184
< **  Produce both a quotient and a remainder given an unsigned
---
> **  Produce both a quotient and a remainder given an unsigned 
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsmath.c /Volumes/Swap/js_D11/src/jsmath.c
3,4c3,6
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
6,14c8,11
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,24c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
26,36c21
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
---
>  * Contributor(s): 
38c23,33
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
45c40
< #include <stdlib.h>
---
> #include "xstdlib.h"
57a53,54
> //#include "_optimize.h"
> 
59c56
< #define M_E             2.7182818284590452354
---
> #define M_E		2.7182818284590452354
62c59
< #define M_LOG2E         1.4426950408889634074
---
> #define M_LOG2E		1.4426950408889634074
65c62
< #define M_LOG10E        0.43429448190325182765
---
> #define M_LOG10E	0.43429448190325182765
68c65
< #define M_LN2           0.69314718055994530942
---
> #define M_LN2		0.69314718055994530942
71c68
< #define M_LN10          2.30258509299404568402
---
> #define M_LN10		2.30258509299404568402
74c71
< #define M_PI            3.14159265358979323846
---
> #define M_PI		3.14159265358979323846
77c74
< #define M_SQRT2         1.41421356237309504880
---
> #define M_SQRT2		1.41421356237309504880
80c77
< #define M_SQRT1_2       0.70710678118654752440
---
> #define M_SQRT1_2	0.70710678118654752440
95,97c92,94
< JSClass js_MathClass = {
<     js_Math_str,
<     JSCLASS_HAS_CACHED_PROTO(JSProto_Math),
---
> static JSClass math_class = {
>     "Math",
>     0,
104c101
< math_abs(JSContext *cx, uintN argc, jsval *vp)
---
> math_abs(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
108c105
<     if (!js_ValueToNumber(cx, vp[2], &x))
---
>     if (!js_ValueToNumber(cx, argv[0], &x))
111c108
<     return js_NewNumberValue(cx, z, vp);
---
>     return js_NewNumberValue(cx, z, rval);
115c112
< math_acos(JSContext *cx, uintN argc, jsval *vp)
---
> math_acos(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
119c116
<     if (!js_ValueToNumber(cx, vp[2], &x))
---
>     if (!js_ValueToNumber(cx, argv[0], &x))
122c119
<     return js_NewNumberValue(cx, z, vp);
---
>     return js_NewNumberValue(cx, z, rval);
126c123
< math_asin(JSContext *cx, uintN argc, jsval *vp)
---
> math_asin(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
130c127
<     if (!js_ValueToNumber(cx, vp[2], &x))
---
>     if (!js_ValueToNumber(cx, argv[0], &x))
131a129,132
> #ifdef XP_MAC
>     if (x == 0)
>         return js_NewNumberValue(cx, x, rval);
> #endif    
133c134
<     return js_NewNumberValue(cx, z, vp);
---
>     return js_NewNumberValue(cx, z, rval);
137c138
< math_atan(JSContext *cx, uintN argc, jsval *vp)
---
> math_atan(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
141c142
<     if (!js_ValueToNumber(cx, vp[2], &x))
---
>     if (!js_ValueToNumber(cx, argv[0], &x))
142a144,147
> #ifdef XP_MAC
>     if (x == 0)
>         return js_NewNumberValue(cx, x, rval);
> #endif    
144c149
<     return js_NewNumberValue(cx, z, vp);
---
>     return js_NewNumberValue(cx, z, rval);
148c153
< math_atan2(JSContext *cx, uintN argc, jsval *vp)
---
> math_atan2(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
152,170c157,160
<     if (!js_ValueToNumber(cx, vp[2], &x))
<         return JS_FALSE;
<     if (!js_ValueToNumber(cx, vp[3], &y))
<         return JS_FALSE;
< #if !JS_USE_FDLIBM_MATH && defined(_MSC_VER)
<     /*
<      * MSVC's atan2 does not yield the result demanded by ECMA when both x
<      * and y are infinite.
<      * - The result is a multiple of pi/4.
<      * - The sign of x determines the sign of the result.
<      * - The sign of y determines the multiplicator, 1 or 3.
<      */
<     if (JSDOUBLE_IS_INFINITE(x) && JSDOUBLE_IS_INFINITE(y)) {
<         z = fd_copysign(M_PI / 4, x);
<         if (y < 0)
<             z *= 3;
<         return js_NewDoubleValue(cx, z, vp);
<     }
< #endif
---
>     if (!js_ValueToNumber(cx, argv[0], &x))
> 	return JS_FALSE;
>     if (!js_ValueToNumber(cx, argv[1], &y))
> 	return JS_FALSE;
172c162
<     return js_NewNumberValue(cx, z, vp);
---
>     return js_NewNumberValue(cx, z, rval);
176c166
< math_ceil(JSContext *cx, uintN argc, jsval *vp)
---
> math_ceil(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
180c170
<     if (!js_ValueToNumber(cx, vp[2], &x))
---
>     if (!js_ValueToNumber(cx, argv[0], &x))
183c173
<     return js_NewNumberValue(cx, z, vp);
---
>     return js_NewNumberValue(cx, z, rval);
187c177
< math_cos(JSContext *cx, uintN argc, jsval *vp)
---
> math_cos(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
191c181
<     if (!js_ValueToNumber(cx, vp[2], &x))
---
>     if (!js_ValueToNumber(cx, argv[0], &x))
194c184
<     return js_NewNumberValue(cx, z, vp);
---
>     return js_NewNumberValue(cx, z, rval);
198c188
< math_exp(JSContext *cx, uintN argc, jsval *vp)
---
> math_exp(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
202c192
<     if (!js_ValueToNumber(cx, vp[2], &x))
---
>     if (!js_ValueToNumber(cx, argv[0], &x))
207c197
<             *vp = DOUBLE_TO_JSVAL(cx->runtime->jsPositiveInfinity);
---
>             *rval = DOUBLE_TO_JSVAL(cx->runtime->jsPositiveInfinity);
211c201
<             *vp = JSVAL_ZERO;
---
>             *rval = JSVAL_ZERO;
217c207
<     return js_NewNumberValue(cx, z, vp);
---
>     return js_NewNumberValue(cx, z, rval);
221c211
< math_floor(JSContext *cx, uintN argc, jsval *vp)
---
> math_floor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
225c215
<     if (!js_ValueToNumber(cx, vp[2], &x))
---
>     if (!js_ValueToNumber(cx, argv[0], &x))
228c218
<     return js_NewNumberValue(cx, z, vp);
---
>     return js_NewNumberValue(cx, z, rval);
232c222
< math_log(JSContext *cx, uintN argc, jsval *vp)
---
> math_log(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
236c226
<     if (!js_ValueToNumber(cx, vp[2], &x))
---
>     if (!js_ValueToNumber(cx, argv[0], &x))
239c229
<     return js_NewNumberValue(cx, z, vp);
---
>     return js_NewNumberValue(cx, z, rval);
243c233
< math_max(JSContext *cx, uintN argc, jsval *vp)
---
> math_max(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
246d235
<     jsval *argv;
250c239
<         *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNegativeInfinity);
---
>         *rval = DOUBLE_TO_JSVAL(cx->runtime->jsNegativeInfinity);
253d241
<     argv = vp + 2;
258c246
<             *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
---
>             *rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
261c249
<         if (x == 0 && x == z && fd_copysign(1.0, z) == -1)
---
>         if ((x==0)&&(x==z)&&(fd_copysign(1.0,z)==-1))
266c254
<     return js_NewNumberValue(cx, z, vp);
---
>     return js_NewNumberValue(cx, z, rval);
270c258
< math_min(JSContext *cx, uintN argc, jsval *vp)
---
> math_min(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
273d260
<     jsval *argv;
277c264
<         *vp = DOUBLE_TO_JSVAL(cx->runtime->jsPositiveInfinity);
---
>         *rval = DOUBLE_TO_JSVAL(cx->runtime->jsPositiveInfinity);
280d266
<     argv = vp + 2;
285c271
<             *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
---
>             *rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
288c274
<         if (x == 0 && x == z && fd_copysign(1.0,x) == -1)
---
>         if ((x==0)&&(x==z)&&(fd_copysign(1.0,x)==-1))
293c279
<     return js_NewNumberValue(cx, z, vp);
---
>     return js_NewNumberValue(cx, z, rval);
297c283
< math_pow(JSContext *cx, uintN argc, jsval *vp)
---
> math_pow(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
301c287,289
<     if (!js_ValueToNumber(cx, vp[2], &x))
---
>     if (!js_ValueToNumber(cx, argv[0], &x))
> 	return JS_FALSE;
>     if (!js_ValueToNumber(cx, argv[1], &y))
303,319d290
<     if (!js_ValueToNumber(cx, vp[3], &y))
<         return JS_FALSE;
< #if !JS_USE_FDLIBM_MATH
<     /*
<      * Because C99 and ECMA specify different behavior for pow(),
<      * we need to wrap the libm call to make it ECMA compliant.
<      */
<     if (!JSDOUBLE_IS_FINITE(y) && (x == 1.0 || x == -1.0)) {
<         *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
<         return JS_TRUE;
<     }
<     /* pow(x, +-0) is always 1, even for x = NaN. */
<     if (y == 0) {
<         *vp = JSVAL_ONE;
<         return JS_TRUE;
<     }
< #endif
321c292
<     return js_NewNumberValue(cx, z, vp);
---
>     return js_NewNumberValue(cx, z, rval);
345c316
<         return;
---
> 	return;
349,350c320,321
<     JSLL_ISHL(tmp, 0x5, 32);
<     JSLL_UI2L(tmp2, 0xDEECE66DL);
---
>     JSLL_ISHL(tmp, 0x5D, 32);
>     JSLL_UI2L(tmp2, 0xEECE66DL);
361,362c332,333
<     /* rt->rngDscale = (jsdouble)(1L << 53) */
<     JSLL_SHL(tmp2, tmp, 53);
---
>     /* rt->rngDscale = (jsdouble)(1L << 54) */
>     JSLL_SHL(tmp2, tmp, 54);
390c361
<     JSLL_ISHL(tmp, random_next(rt, 26), 27);
---
>     JSLL_ISHL(tmp, random_next(rt, 27), 27);
398c369
< math_random(JSContext *cx, uintN argc, jsval *vp)
---
> math_random(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
408,422c379
<     return js_NewNumberValue(cx, z, vp);
< }
< 
< #if defined _WIN32 && !defined WINCE && _MSC_VER < 1400
< /* Try to work around apparent _copysign bustage in VC6 and VC7. */
< double
< js_copysign(double x, double y)
< {
<     jsdpun xu, yu;
< 
<     xu.d = x;
<     yu.d = y;
<     xu.s.hi &= ~JSDOUBLE_HI32_SIGNBIT;
<     xu.s.hi |= yu.s.hi & JSDOUBLE_HI32_SIGNBIT;
<     return xu.d;
---
>     return js_NewNumberValue(cx, z, rval);
424d380
< #endif
427c383
< math_round(JSContext *cx, uintN argc, jsval *vp)
---
> math_round(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
431c387
<     if (!js_ValueToNumber(cx, vp[2], &x))
---
>     if (!js_ValueToNumber(cx, argv[0], &x))
434c390
<     return js_NewNumberValue(cx, z, vp);
---
>     return js_NewNumberValue(cx, z, rval);
438c394
< math_sin(JSContext *cx, uintN argc, jsval *vp)
---
> math_sin(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
442c398
<     if (!js_ValueToNumber(cx, vp[2], &x))
---
>     if (!js_ValueToNumber(cx, argv[0], &x))
445c401
<     return js_NewNumberValue(cx, z, vp);
---
>     return js_NewNumberValue(cx, z, rval);
449c405
< math_sqrt(JSContext *cx, uintN argc, jsval *vp)
---
> math_sqrt(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
453c409
<     if (!js_ValueToNumber(cx, vp[2], &x))
---
>     if (!js_ValueToNumber(cx, argv[0], &x))
456c412
<     return js_NewNumberValue(cx, z, vp);
---
>     return js_NewNumberValue(cx, z, rval);
460c416
< math_tan(JSContext *cx, uintN argc, jsval *vp)
---
> math_tan(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
464c420
<     if (!js_ValueToNumber(cx, vp[2], &x))
---
>     if (!js_ValueToNumber(cx, argv[0], &x))
467c423
<     return js_NewNumberValue(cx, z, vp);
---
>     return js_NewNumberValue(cx, z, rval);
472c428,429
< math_toSource(JSContext *cx, uintN argc, jsval *vp)
---
> math_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
> 	      jsval *rval)
474c431
<     *vp = ATOM_KEY(CLASS_ATOM(cx, Math));
---
>     *rval = ATOM_KEY(cx->runtime->atomState.MathAtom);
481c438
<     JS_FN(js_toSource_str,  math_toSource,      0, 0, 0),
---
>     {js_toSource_str,   math_toSource,		0, 0, 0},
483,501c440,458
<     JS_FN("abs",            math_abs,           1, 1, 0),
<     JS_FN("acos",           math_acos,          1, 1, 0),
<     JS_FN("asin",           math_asin,          1, 1, 0),
<     JS_FN("atan",           math_atan,          1, 1, 0),
<     JS_FN("atan2",          math_atan2,         2, 2, 0),
<     JS_FN("ceil",           math_ceil,          1, 1, 0),
<     JS_FN("cos",            math_cos,           1, 1, 0),
<     JS_FN("exp",            math_exp,           1, 1, 0),
<     JS_FN("floor",          math_floor,         1, 1, 0),
<     JS_FN("log",            math_log,           1, 1, 0),
<     JS_FN("max",            math_max,           0, 2, 0),
<     JS_FN("min",            math_min,           0, 2, 0),
<     JS_FN("pow",            math_pow,           2, 2, 0),
<     JS_FN("random",         math_random,        0, 0, 0),
<     JS_FN("round",          math_round,         1, 1, 0),
<     JS_FN("sin",            math_sin,           1, 1, 0),
<     JS_FN("sqrt",           math_sqrt,          1, 1, 0),
<     JS_FN("tan",            math_tan,           1, 1, 0),
<     JS_FS_END
---
>     {"abs",		math_abs,		1, 0, 0},
>     {"acos",		math_acos,		1, 0, 0},
>     {"asin",		math_asin,		1, 0, 0},
>     {"atan",		math_atan,		1, 0, 0},
>     {"atan2",		math_atan2,		2, 0, 0},
>     {"ceil",		math_ceil,		1, 0, 0},
>     {"cos",		math_cos,		1, 0, 0},
>     {"exp",		math_exp,		1, 0, 0},
>     {"floor",		math_floor,		1, 0, 0},
>     {"log",		math_log,		1, 0, 0},
>     {"max",		math_max,		2, 0, 0},
>     {"min",		math_min,		2, 0, 0},
>     {"pow",		math_pow,		2, 0, 0},
>     {"random",		math_random,		0, 0, 0},
>     {"round",		math_round,		1, 0, 0},
>     {"sin",		math_sin,		1, 0, 0},
>     {"sqrt",		math_sqrt,		1, 0, 0},
>     {"tan",		math_tan,		1, 0, 0},
>     {0,0,0,0,0}
508,510c465,466
< 
<     Math = JS_DefineObject(cx, obj, js_Math_str, &js_MathClass, NULL,
<                            JSPROP_READONLY | JSPROP_PERMANENT);
---
>     
>     Math = JS_DefineObject(cx, obj, "Math", &math_class, NULL, 0);
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsmath.h /Volumes/Swap/js_D11/src/jsmath.h
1,13c1,11
< /* ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
<  *
---
> /* 
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  * 
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
>  * 
16,21c14,19
<  *
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998-1999
<  * the Initial Developer. All Rights Reserved.
<  *
---
>  * 
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation. Portions created by Netscape are
>  * Copyright (C) 1998-1999 Netscape Communications Corporation. All
>  * Rights Reserved.
>  * 
23,36c21,32
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * 
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
50,51d45
< extern JSClass js_MathClass;
< 
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsnum.c /Volumes/Swap/js_D11/src/jsnum.c
3,4c3,6
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
6,14c8,11
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,22c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
25d21
<  *   IBM Corp.
27,37c23,40
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  *
>  * This Original Code has been modified by IBM Corporation.
>  * Modifications made by IBM described herein are
>  * Copyright (c) International Business Machines
>  * Corporation, 2000
>  *
>  * Modifications to Mozilla code or documentation
>  * identified per MPL Section 3.3
39c42,44
<  * ***** END LICENSE BLOCK ***** */
---
>  * Date         Modified by     Description of modification
>  * 05/15/2000  IBM Corp.       Modified OS/2 floating point init.
>  */
48,49d52
< #include <locale.h>
< #include <limits.h>
51c54
< #include <stdlib.h>
---
> #include "xstdlib.h"
67a71,83
> //#include "_optimize.h"
> 
> union dpun {
>     struct {
> #ifdef IS_LITTLE_ENDIAN
> 	uint32 lo, hi;
> #else
> 	uint32 hi, lo;
> #endif
>     } s;
>     jsdouble d;
> };
> 
69c85
< num_isNaN(JSContext *cx, uintN argc, jsval *vp)
---
> num_isNaN(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
73,75c89,91
<     if (!js_ValueToNumber(cx, vp[2], &x))
<         return JS_FALSE;
<     *vp = BOOLEAN_TO_JSVAL(JSDOUBLE_IS_NaN(x));
---
>     if (!js_ValueToNumber(cx, argv[0], &x))
> 	return JS_FALSE;
>     *rval = BOOLEAN_TO_JSVAL(JSDOUBLE_IS_NaN(x));
80c96
< num_isFinite(JSContext *cx, uintN argc, jsval *vp)
---
> num_isFinite(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
84,86c100,102
<     if (!js_ValueToNumber(cx, vp[2], &x))
<         return JS_FALSE;
<     *vp = BOOLEAN_TO_JSVAL(JSDOUBLE_IS_FINITE(x));
---
>     if (!js_ValueToNumber(cx, argv[0], &x))
> 	return JS_FALSE;
>     *rval = BOOLEAN_TO_JSVAL(JSDOUBLE_IS_FINITE(x));
91c107
< num_parseFloat(JSContext *cx, uintN argc, jsval *vp)
---
> num_parseFloat(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
95c111
<     const jschar *bp, *end, *ep;
---
>     const jschar *bp, *ep;
97c113
<     str = js_ValueToString(cx, vp[2]);
---
>     str = js_ValueToString(cx, argv[0]);
99,102c115,121
<         return JS_FALSE;
<     JSSTRING_CHARS_AND_END(str, bp, end);
<     if (!js_strtod(cx, bp, end, &ep, &d))
<         return JS_FALSE;
---
> 	return JS_FALSE;
>     /* XXXbe js_strtod shouldn't require NUL termination */
>     bp = js_UndependString(cx, str);
>     if (!bp)
> 	return JS_FALSE;
>     if (!js_strtod(cx, bp, &ep, &d))
> 	return JS_FALSE;
104,105c123,124
<         *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
<         return JS_TRUE;
---
> 	*rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
> 	return JS_TRUE;
107c126
<     return js_NewNumberValue(cx, d, vp);
---
>     return js_NewNumberValue(cx, d, rval);
112c131
< num_parseInt(JSContext *cx, uintN argc, jsval *vp)
---
> num_parseInt(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
114d132
<     jsint radix;
115a134
>     jsint radix;
117c136,140
<     const jschar *bp, *end, *ep;
---
>     const jschar *bp, *ep;
> 
>     str = js_ValueToString(cx, argv[0]);
>     if (!str)
> 	return JS_FALSE;
120,124c143,147
<         if (!js_ValueToECMAInt32(cx, vp[3], &radix))
<             return JS_FALSE;
<     } else {
<         radix = 0;
<     }
---
> 	if (!js_ValueToECMAInt32(cx, argv[1], &radix))
> 	    return JS_FALSE;
>     } else
> 	radix = 0;
> 
126,127c149,150
<         *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
<         return JS_TRUE;
---
> 	*rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
> 	return JS_TRUE;
129,135c152,157
< 
<     str = js_ValueToString(cx, vp[2]);
<     if (!str)
<         return JS_FALSE;
<     JSSTRING_CHARS_AND_END(str, bp, end);
<     if (!js_strtointeger(cx, bp, end, &ep, radix, &d))
<         return JS_FALSE;
---
>     /* XXXbe js_strtointeger shouldn't require NUL termination */
>     bp = js_UndependString(cx, str);
>     if (!bp)
> 	return JS_FALSE;
>     if (!js_strtointeger(cx, bp, &ep, radix, &d))
> 	return JS_FALSE;
137,138c159,160
<         *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
<         return JS_TRUE;
---
> 	*rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
> 	return JS_TRUE;
140c162
<     return js_NewNumberValue(cx, d, vp);
---
>     return js_NewNumberValue(cx, d, rval);
151,155c173,177
<     JS_FN(js_isNaN_str,         num_isNaN,              1,1,0),
<     JS_FN(js_isFinite_str,      num_isFinite,           1,1,0),
<     JS_FN(js_parseFloat_str,    num_parseFloat,         1,1,0),
<     JS_FN(js_parseInt_str,      num_parseInt,           1,2,0),
<     JS_FS_END
---
>     {"isNaN",           num_isNaN,              1,0,0},
>     {"isFinite",        num_isFinite,           1,0,0},
>     {"parseFloat",      num_parseFloat,         1,0,0},
>     {"parseInt",        num_parseInt,           2,0,0},
>     {0,0,0,0,0}
158,160c180,182
< JSClass js_NumberClass = {
<     js_Number_str,
<     JSCLASS_HAS_PRIVATE | JSCLASS_HAS_CACHED_PROTO(JSProto_Number),
---
> static JSClass number_class = {
>     "Number",
>     JSCLASS_HAS_PRIVATE,
173,174c195,196
<         if (!js_ValueToNumber(cx, argv[0], &d))
<             return JS_FALSE;
---
> 	if (!js_ValueToNumber(cx, argv[0], &d))
> 	    return JS_FALSE;
176c198
<         d = 0.0;
---
> 	d = 0.0;
179c201
<         return JS_FALSE;
---
> 	return JS_FALSE;
181,182c203,204
<         *rval = v;
<         return JS_TRUE;
---
> 	*rval = v;
> 	return JS_TRUE;
184c206
<     STOBJ_SET_SLOT(obj, JSSLOT_PRIVATE, v);
---
>     OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, v);
190c212
< num_toSource(JSContext *cx, uintN argc, jsval *vp)
---
> num_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
198,199c220,222
<     if (!js_GetPrimitiveThis(cx, vp, &js_NumberClass, &v))
<         return JS_FALSE;
---
>     if (!JS_InstanceOf(cx, obj, &number_class, argv))
> 	return JS_FALSE;
>     v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
204,205c227,228
<         JS_ReportOutOfMemory(cx);
<         return JS_FALSE;
---
> 	JS_ReportOutOfMemory(cx);
> 	return JS_FALSE;
207c230
<     JS_snprintf(buf, sizeof buf, "(new %s(%s))", js_NumberClass.name, numStr);
---
>     JS_snprintf(buf, sizeof buf, "(new %s(%s))", number_class.name, numStr);
210,211c233,234
<         return JS_FALSE;
<     *vp = STRING_TO_JSVAL(str);
---
> 	return JS_FALSE;
>     *rval = STRING_TO_JSVAL(str);
217,218c240,241
< char *
< js_IntToCString(jsint i, char *buf, size_t bufSize)
---
> static char *
> IntToString(jsint i, char *buf, size_t bufSize)
222c245
< 
---
>     
227c250
< 
---
>     
237c260
< 
---
>     
241d263
<     JS_ASSERT(cp >= buf);
246c268
< num_toString(JSContext *cx, uintN argc, jsval *vp)
---
> num_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
253,254c275,277
<     if (!js_GetPrimitiveThis(cx, vp, &js_NumberClass, &v))
<         return JS_FALSE;
---
>     if (!JS_InstanceOf(cx, obj, &number_class, argv))
> 	return JS_FALSE;
>     v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
258,278c281,301
<     if (argc != 0 && !JSVAL_IS_VOID(vp[2])) {
<         if (!js_ValueToECMAInt32(cx, vp[2], &base))
<             return JS_FALSE;
<         if (base < 2 || base > 36) {
<             char numBuf[12];
<             char *numStr = js_IntToCString(base, numBuf, sizeof numBuf);
<             JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_RADIX,
<                                  numStr);
<             return JS_FALSE;
<         }
<     }
<     if (base == 10) {
<         str = js_NumberToString(cx, d);
<     } else {
<         char *dStr = JS_dtobasestr(base, d);
<         if (!dStr) {
<             JS_ReportOutOfMemory(cx);
<             return JS_FALSE;
<         }
<         str = JS_NewStringCopyZ(cx, dStr);
<         free(dStr);
---
>     if (argc != 0) {
> 	if (!js_ValueToECMAInt32(cx, argv[0], &base))
> 	    return JS_FALSE;
> 	if (base < 2 || base > 36) {
> 	    char numBuf[12];
> 	    char *numStr = IntToString(base, numBuf, sizeof numBuf);
> 	    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_RADIX,
> 	    			 numStr);
> 	    return JS_FALSE;
> 	}
>     }
>     if (base == 10)
> 	str = js_NumberToString(cx, d);
>     else {
> 	char *dStr = JS_dtobasestr(base, d);
> 	if (!dStr) {
> 	    JS_ReportOutOfMemory(cx);
> 	    return JS_FALSE;
> 	}
> 	str = JS_NewStringCopyZ(cx, dStr);
> 	xfree(dStr);
281,282c304,305
<         return JS_FALSE;
<     *vp = STRING_TO_JSVAL(str);
---
> 	return JS_FALSE;
>     *rval = STRING_TO_JSVAL(str);
287c310,311
< num_toLocaleString(JSContext *cx, uintN argc, jsval *vp)
---
> num_toLocaleString(JSContext *cx, JSObject *obj, uintN argc,
>                    jsval *argv, jsval *rval)
289,380c313,319
<     char thousandsLength, decimalLength;
<     const char *numGrouping, *tmpGroup;
<     JSRuntime *rt;
<     JSString *numStr, *str;
<     const char *num, *end, *tmpSrc;
<     char *buf, *tmpDest;
<     const char *dec;
<     int digits, size, remainder, nrepeat;
< 
<     /*
<      * Create the string, move back to bytes to make string twiddling
<      * a bit easier and so we can insert platform charset seperators.
<      */
<     if (!num_toString(cx, 0, vp))
<         return JS_FALSE;
<     JS_ASSERT(JSVAL_IS_STRING(*vp));
<     numStr = JSVAL_TO_STRING(*vp);
<     num = js_GetStringBytes(cx, numStr);
<     if (!num)
<         return JS_FALSE;
< 
<     /* Find bit before the decimal. */
<     dec = strchr(num, '.');
<     digits = dec ? dec - num : (int)strlen(num);
<     end = num + digits;
< 
<     rt = cx->runtime;
<     thousandsLength = strlen(rt->thousandsSeparator);
<     decimalLength = strlen(rt->decimalSeparator);
< 
<     /* Figure out how long resulting string will be. */
<     size = digits + (dec ? decimalLength + strlen(dec + 1) : 0);
< 
<     numGrouping = tmpGroup = rt->numGrouping;
<     remainder = digits;
<     if (*num == '-')
<         remainder--;
< 
<     while (*tmpGroup != CHAR_MAX && *tmpGroup != '\0') {
<         if (*tmpGroup >= remainder)
<             break;
<         size += thousandsLength;
<         remainder -= *tmpGroup;
<         tmpGroup++;
<     }
<     if (*tmpGroup == '\0' && *numGrouping != '\0') {
<         nrepeat = (remainder - 1) / tmpGroup[-1];
<         size += thousandsLength * nrepeat;
<         remainder -= nrepeat * tmpGroup[-1];
<     } else {
<         nrepeat = 0;
<     }
<     tmpGroup--;
< 
<     buf = (char *)JS_malloc(cx, size + 1);
<     if (!buf)
<         return JS_FALSE;
< 
<     tmpDest = buf;
<     tmpSrc = num;
< 
<     while (*tmpSrc == '-' || remainder--)
<         *tmpDest++ = *tmpSrc++;
<     while (tmpSrc < end) {
<         strcpy(tmpDest, rt->thousandsSeparator);
<         tmpDest += thousandsLength;
<         memcpy(tmpDest, tmpSrc, *tmpGroup);
<         tmpDest += *tmpGroup;
<         tmpSrc += *tmpGroup;
<         if (--nrepeat < 0)
<             tmpGroup--;
<     }
< 
<     if (dec) {
<         strcpy(tmpDest, rt->decimalSeparator);
<         tmpDest += decimalLength;
<         strcpy(tmpDest, dec + 1);
<     } else {
<         *tmpDest++ = '\0';
<     }
< 
<     if (cx->localeCallbacks && cx->localeCallbacks->localeToUnicode)
<         return cx->localeCallbacks->localeToUnicode(cx, buf, vp);
< 
<     str = JS_NewString(cx, buf, size);
<     if (!str) {
<         JS_free(cx, buf);
<         return JS_FALSE;
<     }
< 
<     *vp = STRING_TO_JSVAL(str);
<     return JS_TRUE;
---
> /*
>  *  For now, forcibly ignore the first (or any) argument and return toString().
>  *  ECMA allows this, although it doesn't 'encourage it'.
>  *  [The first argument is being reserved by ECMA and we don't want it confused
>  *  with a radix]
>  */
>     return num_toString(cx, obj, 0, argv, rval);
384c323
< num_valueOf(JSContext *cx, uintN argc, jsval *vp)
---
> num_valueOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
386,397c325,327
<     jsval v;
<     JSObject *obj;
< 
<     v = vp[1];
<     if (JSVAL_IS_NUMBER(v)) {
<         *vp = v;
<         return JS_TRUE;
<     }
<     obj = JSVAL_TO_OBJECT(v);
<     if (!JS_InstanceOf(cx, obj, &js_NumberClass, vp + 2))
<         return JS_FALSE;
<     *vp = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
---
>     if (!JS_InstanceOf(cx, obj, &number_class, argv))
> 	return JS_FALSE;
>     *rval = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
401a332
> #if JS_HAS_NUMBER_FORMATS
405,407c336,337
< num_to(JSContext *cx, JSDToStrMode zeroArgMode, JSDToStrMode oneArgMode,
<        jsint precisionMin, jsint precisionMax, jsint precisionOffset,
<        uintN argc, jsval *vp)
---
> num_to(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval, JSDToStrMode zeroArgMode,
>        JSDToStrMode oneArgMode, jsint precisionMin, jsint precisionMax, jsint precisionOffset)
411a342
>     char buf[DTOSTR_VARIABLE_BUFFER_SIZE(MAX_PRECISION+1)], *numStr; /* Use MAX_PRECISION+1 because precisionOffset can be 1 */
413,418c344,346
<     /* Use MAX_PRECISION+1 because precisionOffset can be 1. */
<     char buf[DTOSTR_VARIABLE_BUFFER_SIZE(MAX_PRECISION+1)];
<     char *numStr;
< 
<     if (!js_GetPrimitiveThis(cx, vp, &js_NumberClass, &v))
<         return JS_FALSE;
---
>     if (!JS_InstanceOf(cx, obj, &number_class, argv))
> 	return JS_FALSE;
>     v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
422,424c350,352
<     if (argc == 0) {
<         precision = 0.0;
<         oneArgMode = zeroArgMode;
---
>     if (JSVAL_IS_VOID(argv[0])) {
> 	precision = 0.0;
> 	oneArgMode = zeroArgMode;
426,428c354,356
<         if (!js_ValueToNumber(cx, vp[2], &precision))
<             return JS_FALSE;
<         precision = js_DoubleToInteger(precision);
---
> 	if (!js_ValueToNumber(cx, argv[0], &precision))
> 	    return JS_FALSE;
> 	precision = js_DoubleToInteger(precision);
441,442c369,370
<         JS_ReportOutOfMemory(cx);
<         return JS_FALSE;
---
> 	JS_ReportOutOfMemory(cx);
> 	return JS_FALSE;
446,447c374,375
<         return JS_FALSE;
<     *vp = STRING_TO_JSVAL(str);
---
> 	return JS_FALSE;
>     *rval = STRING_TO_JSVAL(str);
451,454d378
< /*
<  * In the following three implementations, we allow a larger range of precision
<  * than ECMA requires; this is permitted by ECMA-262.
<  */
456c380
< num_toFixed(JSContext *cx, uintN argc, jsval *vp)
---
> num_toFixed(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
458,459c382,383
<     return num_to(cx, DTOSTR_FIXED, DTOSTR_FIXED, -20, MAX_PRECISION, 0,
<                   argc, vp);
---
>     /* We allow a larger range of precision than ECMA requires; this is permitted by ECMA. */
>     return num_to(cx, obj, argc, argv, rval, DTOSTR_FIXED, DTOSTR_FIXED, -20, MAX_PRECISION, 0);
463c387
< num_toExponential(JSContext *cx, uintN argc, jsval *vp)
---
> num_toExponential(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
465,466c389,390
<     return num_to(cx, DTOSTR_STANDARD_EXPONENTIAL, DTOSTR_EXPONENTIAL, 0,
<                   MAX_PRECISION, 1, argc, vp);
---
>     /* We allow a larger range of precision than ECMA requires; this is permitted by ECMA. */
>     return num_to(cx, obj, argc, argv, rval, DTOSTR_STANDARD_EXPONENTIAL, DTOSTR_EXPONENTIAL, 0, MAX_PRECISION, 1);
470c394
< num_toPrecision(JSContext *cx, uintN argc, jsval *vp)
---
> num_toPrecision(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
472,475c396,397
<     if (JSVAL_IS_VOID(vp[2]))
<         return num_toString(cx, 0, vp);
<     return num_to(cx, DTOSTR_STANDARD, DTOSTR_PRECISION, 1, MAX_PRECISION, 0,
<                   argc, vp);
---
>     /* We allow a larger range of precision than ECMA requires; this is permitted by ECMA. */
>     return num_to(cx, obj, argc, argv, rval, DTOSTR_STANDARD, DTOSTR_PRECISION, 1, MAX_PRECISION, 0);
476a399,400
> #endif /* JS_HAS_NUMBER_FORMATS */
> 
480c404
<     JS_FN(js_toSource_str,       num_toSource,       0,0,JSFUN_THISP_NUMBER),
---
>     {js_toSource_str,       num_toSource,       0,0,0},
482,488c406,414
<     JS_FN(js_toString_str,       num_toString,       0,1,JSFUN_THISP_NUMBER),
<     JS_FN(js_toLocaleString_str, num_toLocaleString, 0,0,JSFUN_THISP_NUMBER),
<     JS_FN(js_valueOf_str,        num_valueOf,        0,0,JSFUN_THISP_NUMBER),
<     JS_FN("toFixed",             num_toFixed,        1,1,JSFUN_THISP_NUMBER),
<     JS_FN("toExponential",       num_toExponential,  1,1,JSFUN_THISP_NUMBER),
<     JS_FN("toPrecision",         num_toPrecision,    1,1,JSFUN_THISP_NUMBER),
<     JS_FS_END
---
>     {js_toString_str,	    num_toString,       0,0,0},
>     {js_toLocaleString_str, num_toLocaleString, 0,0,0},
>     {js_valueOf_str,	    num_valueOf,        0,0,0},
> #if JS_HAS_NUMBER_FORMATS
>     {"toFixed",             num_toFixed,        1,0,0},
>     {"toExponential",       num_toExponential,  1,0,0},
>     {"toPrecision",         num_toPrecision,    1,0,0},
> #endif
>     {0,0,0,0,0}
504c430
<  * using union jsdpun.
---
>  * using union dpun.
516a443
> 
518d444
<     !defined WINCE &&                                                         \
521c447
<      (defined __GNUC__ && !defined __MINGW32__))
---
>     (defined __GNUC__ && !defined __MINGW32__ && !defined __EMX__))
540,541c466
<     jsdpun u;
<     struct lconv *locale;
---
>     union dpun u;
551,552c476,477
<     rt->jsNaN = js_NewDouble(cx, NaN, GCF_LOCK);
<     if (!rt->jsNaN)
---
>     rt->jsNaN = js_NewDouble(cx, NaN);
>     if (!rt->jsNaN || !js_LockGCThing(cx, rt->jsNaN))
558,559c483,485
<     rt->jsPositiveInfinity = js_NewDouble(cx, u.d, GCF_LOCK);
<     if (!rt->jsPositiveInfinity)
---
>     rt->jsPositiveInfinity = js_NewDouble(cx, u.d);
>     if (!rt->jsPositiveInfinity ||
>         !js_LockGCThing(cx, rt->jsPositiveInfinity)) {
560a487
>     }
565,566c492,494
<     rt->jsNegativeInfinity = js_NewDouble(cx, u.d, GCF_LOCK);
<     if (!rt->jsNegativeInfinity)
---
>     rt->jsNegativeInfinity = js_NewDouble(cx, u.d);
>     if (!rt->jsNegativeInfinity ||
>         !js_LockGCThing(cx, rt->jsNegativeInfinity)) {
567a496
>     }
573,581c502
<     locale = localeconv();
<     rt->thousandsSeparator =
<         JS_strdup(cx, locale->thousands_sep ? locale->thousands_sep : "'");
<     rt->decimalSeparator =
<         JS_strdup(cx, locale->decimal_point ? locale->decimal_point : ".");
<     rt->numGrouping =
<         JS_strdup(cx, locale->grouping ? locale->grouping : "\3\0");
< 
<     return rt->thousandsSeparator && rt->decimalSeparator && rt->numGrouping;
---
>     return JS_TRUE;
596,600d516
< 
<     JS_free(cx, (void *)rt->thousandsSeparator);
<     JS_free(cx, (void *)rt->decimalSeparator);
<     JS_free(cx, (void *)rt->numGrouping);
<     rt->thousandsSeparator = rt->decimalSeparator = rt->numGrouping = NULL;
613c529
<         return NULL;
---
> 	return NULL;
615,616c531,532
<     proto = JS_InitClass(cx, obj, NULL, &js_NumberClass, Number, 1,
<                          NULL, number_methods, NULL, NULL);
---
>     proto = JS_InitClass(cx, obj, NULL, &number_class, Number, 1,
> 			 NULL, number_methods, NULL, NULL);
618,619c534,535
<         return NULL;
<     STOBJ_SET_SLOT(proto, JSSLOT_PRIVATE, JSVAL_ZERO);
---
> 	return NULL;
>     OBJ_SET_SLOT(cx, proto, JSSLOT_PRIVATE, JSVAL_ZERO);
621c537
<         return NULL;
---
> 	return NULL;
626,627c542,543
<                            NULL, NULL, JSPROP_PERMANENT)) {
<         return NULL;
---
> 			   NULL, NULL, JSPROP_PERMANENT)) {
> 	return NULL;
632,634c548,550
<                            DOUBLE_TO_JSVAL(rt->jsPositiveInfinity),
<                            NULL, NULL, JSPROP_PERMANENT)) {
<         return NULL;
---
> 			   DOUBLE_TO_JSVAL(rt->jsPositiveInfinity),
> 			   NULL, NULL, JSPROP_PERMANENT)) {
> 	return NULL;
640c556
< js_NewDouble(JSContext *cx, jsdouble d, uintN gcflag)
---
> js_NewDouble(JSContext *cx, jsdouble d)
644c560
<     dp = (jsdouble *) js_NewGCThing(cx, gcflag | GCX_DOUBLE, sizeof(jsdouble));
---
>     dp = (jsdouble *) js_AllocGCThing(cx, GCX_DOUBLE);
646c562
<         return NULL;
---
> 	return NULL;
662c578
<     dp = js_NewDouble(cx, d, 0);
---
>     dp = js_NewDouble(cx, d);
664c580
<         return JS_FALSE;
---
> 	return JS_FALSE;
675c591
<         *rval = INT_TO_JSVAL(i);
---
> 	*rval = INT_TO_JSVAL(i);
677,678c593,594
<         if (!js_NewDoubleValue(cx, d, rval))
<             return JS_FALSE;
---
> 	if (!js_NewDoubleValue(cx, d, rval))
> 	    return JS_FALSE;
683,684c599,600
< char *
< js_NumberToCString(JSContext *cx, jsdouble d, char *buf, size_t bufSize)
---
> JSObject *
> js_NumberToObject(JSContext *cx, jsdouble d)
686,687c602,603
<     jsint i;
<     char *numStr;
---
>     JSObject *obj;
>     jsval v;
689,697c605,610
<     JS_ASSERT(bufSize >= DTOSTR_STANDARD_BUFFER_SIZE);
<     if (JSDOUBLE_IS_INT(d, i)) {
<         numStr = js_IntToCString(i, buf, bufSize);
<     } else {
<         numStr = JS_dtostr(buf, bufSize, DTOSTR_STANDARD, 0, d);
<         if (!numStr) {
<             JS_ReportOutOfMemory(cx);
<             return NULL;
<         }
---
>     obj = js_NewObject(cx, &number_class, NULL, NULL);
>     if (!obj)
> 	return NULL;
>     if (!js_NewNumberValue(cx, d, &v)) {
> 	cx->newborn[GCX_OBJECT] = NULL;
> 	return NULL;
699c612,613
<     return numStr;
---
>     OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, v);
>     return obj;
704a619
>     jsint i;
708,710c623,631
<     numStr = js_NumberToCString(cx, d, buf, sizeof buf);
<     if (!numStr)
<         return NULL;
---
>     if (JSDOUBLE_IS_INT(d, i))
> 	numStr = IntToString(i, buf, sizeof buf);
>     else {
> 	numStr = JS_dtostr(buf, sizeof buf, DTOSTR_STANDARD, 0, d);
> 	if (!numStr) {
> 	    JS_ReportOutOfMemory(cx);
> 	    return NULL;
> 	}
>     }
719c640
<     const jschar *bp, *end, *ep;
---
>     const jschar *bp, *ep;
722,728c643,649
<         obj = JSVAL_TO_OBJECT(v);
<         if (!obj) {
<             *dp = 0;
<             return JS_TRUE;
<         }
<         if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_NUMBER, &v))
<             return JS_FALSE;
---
> 	obj = JSVAL_TO_OBJECT(v);
> 	if (!obj) {
> 	    *dp = 0;
> 	    return JS_TRUE;
> 	}
> 	if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_NUMBER, &v))
> 	    return JS_FALSE;
731c652
<         *dp = (jsdouble)JSVAL_TO_INT(v);
---
> 	*dp = (jsdouble)JSVAL_TO_INT(v);
733c654
<         *dp = *JSVAL_TO_DOUBLE(v);
---
> 	*dp = *JSVAL_TO_DOUBLE(v);
735,737c656,657
<         str = JSVAL_TO_STRING(v);
< 
<         /*
---
> 	str = JSVAL_TO_STRING(v);
> 	/*
743,749c663,672
<         JSSTRING_CHARS_AND_END(str, bp, end);
<         if ((!js_strtod(cx, bp, end, &ep, dp) ||
<              js_SkipWhiteSpace(ep, end) != end) &&
<              (!js_strtointeger(cx, bp, end, &ep, 0, dp) ||
<               js_SkipWhiteSpace(ep, end) != end)) {
<             goto badstr;
<         }
---
>         /* XXXbe js_strtod shouldn't require NUL termination */
>         bp = js_UndependString(cx, str);
>         if (!bp)
>             return JS_FALSE;
>         if ((!js_strtod(cx, bp, &ep, dp) ||
>              js_SkipWhiteSpace(ep) != bp + str->length) &&
> 	    (!js_strtointeger(cx, bp, &ep, 0, dp) ||
>              js_SkipWhiteSpace(ep) != bp + str->length)) {
> 	    goto badstr;
> 	}
751c674
<         *dp = JSVAL_TO_BOOLEAN(v) ? 1 : 0;
---
> 	*dp = JSVAL_TO_BOOLEAN(v) ? 1 : 0;
752a676,685
> #if JS_BUG_FALLIBLE_TONUM
> 	str = js_DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, NULL);
> badstr:
> 	if (str) {
> 	    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NAN,
> 				 JS_GetStringBytes(str));
> 
> 	}
> 	return JS_FALSE;
> #else
754c687,688
<         *dp = *cx->runtime->jsNaN;
---
> 	*dp = *cx->runtime->jsNaN;
> #endif
765,767c699,700
<         return JS_FALSE;
<     *ip = js_DoubleToECMAInt32(d);
<     return JS_TRUE;
---
> 	return JS_FALSE;
>     return js_DoubleToECMAInt32(cx, d, ip);
770,771c703,704
< int32
< js_DoubleToECMAInt32(jsdouble d)
---
> JSBool
> js_DoubleToECMAInt32(JSContext *cx, jsdouble d, int32 *ip)
776,778c709,712
<     if (!JSDOUBLE_IS_FINITE(d) || d == 0)
<         return 0;
< 
---
>     if (!JSDOUBLE_IS_FINITE(d) || d == 0) {
>         *ip = 0;
>         return JS_TRUE;
>     }
781c715,719
<     return (int32) (d >= two31 ? d - two32 : d);
---
>     if (d >= two31)
>         *ip = (int32)(d - two32);
>     else
>         *ip = (int32)d;
>     return JS_TRUE;
790,792c728,729
<         return JS_FALSE;
<     *ip = js_DoubleToECMAUint32(d);
<     return JS_TRUE;
---
> 	return JS_FALSE;
>     return js_DoubleToECMAUint32(cx, d, ip);
795,796c732,733
< uint32
< js_DoubleToECMAUint32(jsdouble d)
---
> JSBool
> js_DoubleToECMAUint32(JSContext *cx, jsdouble d, uint32 *ip)
801,802c738,741
<     if (!JSDOUBLE_IS_FINITE(d) || d == 0)
<         return 0;
---
>     if (!JSDOUBLE_IS_FINITE(d) || d == 0) {
> 	*ip = 0;
> 	return JS_TRUE;
>     }
810c749,751
<     return (uint32) (d >= 0 ? d : d + two32);
---
>     d = (d >= 0) ? d : d + two32;
>     *ip = (uint32)d;
>     return JS_TRUE;
816a758
>     JSString *str;
823c765
<         return JS_FALSE;
---
> 	return JS_FALSE;
825,827c767,773
<         js_ReportValueError(cx, JSMSG_CANT_CONVERT,
<                             JSDVG_SEARCH_STACK, v, NULL);
<         return JS_FALSE;
---
> 	str = js_DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, NULL);
> 	if (str) {
> 	    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
> 				 JSMSG_CANT_CONVERT, JS_GetStringBytes(str));
> 
> 	}
> 	return JS_FALSE;
841c787
<         return JS_FALSE;
---
> 	return JS_FALSE;
843,844c789,790
<         *ip = 0;
<         return JS_TRUE;
---
> 	*ip = 0;
> 	return JS_TRUE;
848,849c794,795
<         *ip = (uint16)i;
<         return JS_TRUE;
---
> 	*ip = (uint16)i;
> 	return JS_TRUE;
857c803
<         d += m;
---
> 	d += m;
868c814
<         return d;
---
> 	return d;
870,872c816,818
<         if (JSDOUBLE_IS_NaN(d))
<             return 0;
<         return d;
---
> 	if (JSDOUBLE_IS_NaN(d))
> 	    return 0;
> 	return d;
881,882c827
< js_strtod(JSContext *cx, const jschar *s, const jschar *send,
<           const jschar **ep, jsdouble *dp)
---
> js_strtod(JSContext *cx, const jschar *s, const jschar **ep, jsdouble *dp)
884,885d828
<     const jschar *s1;
<     size_t length, i;
886a830
>     size_t i;
890,892c834,835
< 
<     s1 = js_SkipWhiteSpace(s, send);
<     length = send - s1;
---
>     const jschar *s1 = js_SkipWhiteSpace(s);
>     size_t length = js_strlen(s1);
902,904c845,848
< 
<     for (i = 0; i != length; i++) {
<         if (s1[i] >> 8)
---
>    
>     for (i = 0; i <= length; i++) {
>         if (s1[i] >> 8) {
>             cstr[i] = 0;
905a850
>         }
908d852
<     cstr[i] = 0;
985,986c929
< js_strtointeger(JSContext *cx, const jschar *s, const jschar *send,
<                 const jschar **ep, jsint base, jsdouble *dp)
---
> js_strtointeger(JSContext *cx, const jschar *s, const jschar **ep, jsint base, jsdouble *dp)
988d930
<     const jschar *s1, *start;
990a933,934
>     const jschar *start;
>     const jschar *s1 = js_SkipWhiteSpace(s);
992,995c936
<     s1 = js_SkipWhiteSpace(s, send);
<     if (s1 == send)
<         goto no_digits;
<     if ((negative = (*s1 == '-')) != 0 || *s1 == '+') {
---
>     if ((negative = (*s1 == '-')) != 0 || *s1 == '+')
997,999d937
<         if (s1 == send)
<             goto no_digits;
<     }
1005,1006c943
<             if (s1 + 1 != send && (s1[1] == 'X' || s1[1] == 'x')) {
<                 base = 16;
---
>             if (s1[1] == 'X' || s1[1] == 'x') { /* Hex */
1008,1010c945,946
<                 if (s1 == send)
<                     goto no_digits;
<             } else {
---
>                 base = 16;
>             } else {    /* Octal */
1016c952
<     } else if (base == 16) {
---
>     } else if (base == 16 && *s1 == '0' && (s1[1] == 'X' || s1[1] == 'x')) {
1018,1022c954
<         if (*s1 == '0' && s1 + 1 != send && (s1[1] == 'X' || s1[1] == 'x')) {
<             s1 += 2;
<             if (s1 == send)
<                 goto no_digits;
<         }
---
>         s1 += 2;
1029,1030c961
<     JS_ASSERT(s1 < send);
<     start = s1;
---
>     start = s1; /* Mark - if string is empty, we return NaN. */
1032c963
<     do {
---
>     while (1) {
1046c977,978
<     } while (++s1 != send);
---
>         s1++;
>     }
1132d1063
<       no_digits:
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsnum.h /Volumes/Swap/js_D11/src/jsnum.h
3,4c3,6
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
6,14c8,11
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,22c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
26,38c23,33
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
48a44,46
>  *
>  * When a JS number is treated as an object (followed by . or []), the runtime
>  * wraps it with a JSObject whose valueOf method returns the unwrapped number.
54,56c52,55
<  * The ARM architecture supports two floating point models: VFP and FPA. When
<  * targetting FPA, doubles are mixed-endian on little endian ARMs (meaning that
<  * the high and low words are in big endian order).
---
>  * Stefan Hanske <sh990154@mail.uni-greifswald.de> reports:
>  *  ARM is a little endian architecture but 64 bit double words are stored
>  * differently: the 32 bit words are in little endian byte order, the two words
>  * are stored in big endian`s way.
58,62d56
< #if defined(__arm) || defined(__arm32__) || defined(__arm26__) || defined(__arm__)
< #if !defined(__VFP_FP__)
< #define FPU_IS_ARM_FPA
< #endif
< #endif
64,69c58,59
< typedef union jsdpun {
<     struct {
< #if defined(IS_LITTLE_ENDIAN) && !defined(FPU_IS_ARM_FPA)
<         uint32 lo, hi;
< #else
<         uint32 hi, lo;
---
> #if defined(__arm) || defined(__arm32__) || defined(__arm26__) || defined(__arm__)
> #define CPU_IS_ARM
71,73d60
<     } s;
<     jsdouble d;
< } jsdpun;
79a67,78
> typedef union {
>     jsdouble value;
>     struct {
> #if defined(IS_LITTLE_ENDIAN) && !defined(CPU_IS_ARM)
>         uint32 lsw;
>         uint32 msw;
> #else
>         uint32 msw;
>         uint32 lsw;
> #endif
>     } parts;
> } js_ieee_double_shape_type;
81,86c80,95
< #define JSDOUBLE_HI32(x) (__extension__ ({ jsdpun u; u.d = (x); u.s.hi; }))
< #define JSDOUBLE_LO32(x) (__extension__ ({ jsdpun u; u.d = (x); u.s.lo; }))
< #define JSDOUBLE_SET_HI32(x, y) \
<     (__extension__ ({ jsdpun u; u.d = (x); u.s.hi = (y); (x) = u.d; }))
< #define JSDOUBLE_SET_LO32(x, y) \
<     (__extension__ ({ jsdpun u; u.d = (x); u.s.lo = (y); (x) = u.d; }))
---
> #define JSDOUBLE_HI32(x)   (__extension__ ({ js_ieee_double_shape_type sh_u;  \
>                                              sh_u.value = (x);                \
>                                              sh_u.parts.msw; }))
> #define JSDOUBLE_LO32(x)   (__extension__ ({ js_ieee_double_shape_type sh_u;  \
>                                              sh_u.value = (x);                \
>                                              sh_u.parts.lsw; }))
> #define JSDOUBLE_SET_HI32(x, y)  (__extension__ ({                            \
>                                              js_ieee_double_shape_type sh_u;  \
>                                              sh_u.value = (x);                \
>                                              sh_u.parts.msw = (y);            \
>                                              (x) = sh_u.value; }))
> #define JSDOUBLE_SET_LO32(x, y)  (__extension__ ({                            \
>                                              js_ieee_double_shape_type sh_u;  \
>                                              sh_u.value = (x);                \
>                                              sh_u.parts.lsw = (y);            \
>                                              (x) = sh_u.value; }))
88c97
< #else /* not or old GNUC */
---
> #else /* GNUC */
95c104
< #if defined(IS_LITTLE_ENDIAN) && !defined(FPU_IS_ARM_FPA)
---
> #if defined(IS_LITTLE_ENDIAN) && !defined(CPU_IS_ARM)
106c115
< #endif /* not or old GNUC */
---
> #endif /* GNUC */
124c133
<                                  JSDOUBLE_LO32(d) == 0)
---
> 				 JSDOUBLE_LO32(d) == 0)
134,143c143
<                                && ((d) == (i = (jsint)(d))))
< 
< #if defined(XP_WIN)
< #define JSDOUBLE_COMPARE(LVAL, OP, RVAL, IFNAN)                               \
<     ((JSDOUBLE_IS_NaN(LVAL) || JSDOUBLE_IS_NaN(RVAL))                         \
<      ? (IFNAN)                                                                \
<      : (LVAL) OP (RVAL))
< #else
< #define JSDOUBLE_COMPARE(LVAL, OP, RVAL, IFNAN) ((LVAL) OP (RVAL))
< #endif
---
> 			       && ((d) == (i = (jsint)(d))))
153,154d152
< extern JSClass js_NumberClass;
< 
170c168
< js_NewDouble(JSContext *cx, jsdouble d, uintN gcflag);
---
> js_NewDouble(JSContext *cx, jsdouble d);
180a179,182
> /* Construct a Number instance that wraps around d. */
> extern JSObject *
> js_NumberToObject(JSContext *cx, jsdouble d);
> 
186,199d187
<  * Convert int to C string. The buf must be big enough for MIN_INT to fit
<  * including '-' and '\0'.
<  */
< char *
< js_IntToCString(jsint i, char *buf, size_t bufSize);
< 
< /*
<  * Convert a number to C string. The buf must be at least
<  * DTOSTR_STANDARD_BUFFER_SIZE.
<  */
< char *
< js_NumberToCString(JSContext *cx, jsdouble d, char *buf, size_t bufSize);
< 
< /*
213,214c201,202
< extern int32
< js_DoubleToECMAInt32(jsdouble d);
---
> extern JSBool
> js_DoubleToECMAInt32(JSContext *cx, jsdouble d, int32 *ip);
223,224c211,212
< extern uint32
< js_DoubleToECMAUint32(jsdouble d);
---
> extern JSBool
> js_DoubleToECMAUint32(JSContext *cx, jsdouble d, uint32 *ip);
259,260c247
< js_strtod(JSContext *cx, const jschar *s, const jschar *send,
<           const jschar **ep, jsdouble *dp);
---
> js_strtod(JSContext *cx, const jschar *s, const jschar **ep, jsdouble *dp);
272,273c259
< js_strtointeger(JSContext *cx, const jschar *s, const jschar *send,
<                 const jschar **ep, jsint radix, jsdouble *dp);
---
> js_strtointeger(JSContext *cx, const jschar *s, const jschar **ep, jsint radix, jsdouble *dp);
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsobj.c /Volumes/Swap/js_D11/src/jsobj.c
2d1
<  * vim: set ts=8 sw=4 et tw=78:
4,5c3,6
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
7,15c8,11
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
20,23c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
27,39c23,33
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
45c39
< #include <stdlib.h>
---
> #include "xstdlib.h"
49d42
< #include "jsbit.h"
60d52
< #include "jsemit.h"
67,68d58
< #include "jsopcode.h"
< #include "jsparse.h"
71a62
> #include "jsopcode.h"
75,89c66
< #if JS_HAS_GENERATORS
< #include "jsiter.h"
< #endif
< 
< #if JS_HAS_XML_SUPPORT
< #include "jsxml.h"
< #endif
< 
< #if JS_HAS_XDR
< #include "jsxdrapi.h"
< #endif
< 
< #ifdef INCLUDE_MOZILLA_DTRACE
< #include "jsdtracef.h"
< #endif
---
> //#include "_optimize.h"
99a77,80
> #ifdef XP_MAC
> #pragma export on
> #endif
> 
101a83,85
> #if defined JS_THREADSAFE && defined DEBUG
>     _js_LookupProperty,     js_DefineProperty,
> #else
102a87
> #endif
111c96
<     js_TraceObject,         js_Clear,
---
>     js_Mark,                js_Clear,
114a100,103
> #ifdef XP_MAC
> #pragma export off
> #endif
> 
117c106
<     JSCLASS_HAS_CACHED_PROTO(JSProto_Object),
---
>     0,
163d151
<     jsid propid;
166,168d153
<     JSObject *pobj;
<     JSClass *clasp;
<     JSExtendedClass *xclasp;
170a156,157
>     if (JS_HAS_STRICT_OPTION(cx) && !ReportStrictSlot(cx, slot))
>         return JS_FALSE;
172c159
<         propid = ATOM_TO_JSID(cx->runtime->atomState.protoAtom);
---
>         id = (jsid)cx->runtime->atomState.protoAtom;
175c162
<         propid = ATOM_TO_JSID(cx->runtime->atomState.parentAtom);
---
>         id = (jsid)cx->runtime->atomState.parentAtom;
178,180c165
< 
<     /* Let OBJ_CHECK_ACCESS get the slot's value, based on the access mode. */
<     if (!OBJ_CHECK_ACCESS(cx, obj, propid, mode, vp, &attrs))
---
>     if (!OBJ_CHECK_ACCESS(cx, obj, id, mode, vp, &attrs))
182,198c167
< 
<     pobj = JSVAL_TO_OBJECT(*vp);
<     if (pobj) {
<         clasp = OBJ_GET_CLASS(cx, pobj);
<         if (clasp == &js_CallClass || clasp == &js_BlockClass) {
<             /* Censor activations and lexical scopes per ECMA-262. */
<             *vp = JSVAL_NULL;
<         } else if (clasp->flags & JSCLASS_IS_EXTENDED) {
<             xclasp = (JSExtendedClass *) clasp;
<             if (xclasp->outerObject) {
<                 pobj = xclasp->outerObject(cx, pobj);
<                 if (!pobj)
<                     return JS_FALSE;
<                 *vp = OBJECT_TO_JSVAL(pobj);
<             }
<         }
<     }
---
>     *vp = OBJ_GET_SLOT(cx, obj, slot);
207d175
<     jsid propid;
213,223d180
< 
<     if (pobj) {
<         /*
<          * Innerize pobj here to avoid sticking unwanted properties on the
<          * outer object. This ensures that any with statements only grant
<          * access to the inner object.
<          */
<         OBJ_TO_INNER_OBJECT(cx, pobj);
<         if (!pobj)
<             return JS_FALSE;
<     }
229,232c186
<     propid = ATOM_TO_JSID(cx->runtime->atomState.protoAtom);
<     if (!OBJ_CHECK_ACCESS(cx, obj, propid,
<                           (JSAccessMode)(JSACC_PROTO|JSACC_WRITE), vp,
<                           &attrs)) {
---
>     if (!OBJ_CHECK_ACCESS(cx, obj, id, (JSAccessMode)(JSACC_PROTO | JSACC_WRITE), vp, &attrs))
234d187
<     }
277d229
<     JSSetSlotRequest ssr;
278a231,232
>     JSObject *obj2, *oldproto;
>     JSScope *scope, *newscope;
280,284c234,295
<     /* Optimize the null case to avoid the unnecessary overhead of js_GC. */
<     if (!pobj) {
<         JS_LOCK_OBJ(cx, obj);
<         if (slot == JSSLOT_PROTO && !js_GetMutableScope(cx, obj)) {
<             JS_UNLOCK_OBJ(cx, obj);
---
>     /*
>      * Serialize all proto and parent setting in order to detect cycles.
>      * We nest locks in this function, and only here, in the following orders:
>      *
>      * (1)  rt->setSlotLock < pobj's scope lock;
>      *      rt->setSlotLock < pobj's proto-or-parent's scope lock;
>      *      rt->setSlotLock < pobj's grand-proto-or-parent's scope lock;
>      *      etc...
>      * (2)  rt->setSlotLock < obj's scope lock < pobj's scope lock.
>      *
>      * We avoid AB-BA deadlock by restricting obj from being on pobj's parent
>      * or proto chain (pobj may already be on obj's parent or proto chain; it
>      * could be moving up or down).  We finally order obj with respect to pobj
>      * at the bottom of this routine (just before releasing rt->setSlotLock),
>      * by making pobj be obj's prototype or parent.
>      *
>      * After we have set the slot and released rt->setSlotLock, another call
>      * to js_SetProtoOrParent could nest locks according to the first order
>      * list above, but it cannot deadlock with any other thread.  For there
>      * to be a deadlock, other parts of the engine would have to nest scope
>      * locks in the opposite order.  XXXbe ensure they don't!
>      */
>     rt = cx->runtime;
> #ifdef JS_THREADSAFE
> 
>     JS_ACQUIRE_LOCK(rt->setSlotLock);
>     while (rt->setSlotBusy) {
>         jsrefcount saveDepth;
> 
>         /* Take pains to avoid nesting rt->gcLock inside rt->setSlotLock! */
>         JS_RELEASE_LOCK(rt->setSlotLock);
>         saveDepth = JS_SuspendRequest(cx);
>         JS_ACQUIRE_LOCK(rt->setSlotLock);
>         if (rt->setSlotBusy)
>             JS_WAIT_CONDVAR(rt->setSlotDone, JS_NO_TIMEOUT);
>         JS_RELEASE_LOCK(rt->setSlotLock);
>         JS_ResumeRequest(cx, saveDepth);
>         JS_ACQUIRE_LOCK(rt->setSlotLock);
>     }
>     rt->setSlotBusy = JS_TRUE;
>     JS_RELEASE_LOCK(rt->setSlotLock);
> 
> #define SET_SLOT_DONE(rt)                                                     \
>     JS_BEGIN_MACRO                                                            \
>         JS_ACQUIRE_LOCK((rt)->setSlotLock);                                   \
>         (rt)->setSlotBusy = JS_FALSE;                                         \
>         JS_NOTIFY_ALL_CONDVAR((rt)->setSlotDone);                             \
>         JS_RELEASE_LOCK((rt)->setSlotLock);                                   \
>     JS_END_MACRO
> 
> #else
> 
> #define SET_SLOT_DONE(rt)       /* nothing */
> 
> #endif
> 
>     obj2 = pobj;
>     while (obj2) {
>         if (obj2 == obj) {
>             SET_SLOT_DONE(rt);
>             JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
>                                  JSMSG_CYCLIC_VALUE, object_props[slot].name);
287,289c298
<         LOCKED_OBJ_SET_SLOT(obj, slot, JSVAL_NULL);
<         JS_UNLOCK_OBJ(cx, obj);
<         return JS_TRUE;
---
>         obj2 = JSVAL_TO_OBJECT(OBJ_GET_SLOT(cx, obj2, slot));
292,302c301,341
<     ssr.obj = obj;
<     ssr.pobj = pobj;
<     ssr.slot = (uint16) slot;
<     ssr.errnum = (uint16) JSMSG_NOT_AN_ERROR;
< 
<     rt = cx->runtime;
<     JS_LOCK_GC(rt);
<     ssr.next = rt->setSlotRequests;
<     rt->setSlotRequests = &ssr;
<     js_GC(cx, GC_SET_SLOT_REQUEST);
<     JS_UNLOCK_GC(rt);
---
>     if (slot == JSSLOT_PROTO && OBJ_IS_NATIVE(obj)) {
>         /* Check to see whether obj shares its prototype's scope. */
>         JS_LOCK_OBJ(cx, obj);
>         scope = OBJ_SCOPE(obj);
>         oldproto = JSVAL_TO_OBJECT(LOCKED_OBJ_GET_SLOT(obj, JSSLOT_PROTO));
>         if (oldproto && OBJ_SCOPE(oldproto) == scope) {
>             /* Either obj needs a new empty scope, or it should share pobj's. */
>             if (!pobj ||
>                 !OBJ_IS_NATIVE(pobj) ||
>                 OBJ_GET_CLASS(cx, pobj) != LOCKED_OBJ_GET_CLASS(oldproto)) {
>                 /*
>                  * With no proto and no scope of its own, obj is truly empty.
>                  *
>                  * If pobj is not native, obj needs its own empty scope -- it
>                  * should not continue to share oldproto's scope once oldproto
>                  * is not on obj's prototype chain.  That would put properties
>                  * from oldproto's scope ahead of properties defined by pobj,
>                  * in lookup order.
>                  *
>                  * If pobj's class differs from oldproto's, we may need a new
>                  * scope to handle differences in private and reserved slots,
>                  * so we suboptimally but safely make one.
>                  */
>                 scope = js_GetMutableScope(cx, obj);
>                 if (!scope) {
>                     JS_UNLOCK_OBJ(cx, obj);
>                     SET_SLOT_DONE(rt);
>                     return JS_FALSE;
>                 }
>             } else if (OBJ_SCOPE(pobj) != scope) {
> #ifdef JS_THREADSAFE
>                 /*
>                  * We are about to nest scope locks.  Help jslock.c:ShareScope
>                  * keep scope->u.count balanced for the JS_UNLOCK_SCOPE, while
>                  * avoiding deadlock, by recording scope in rt->setSlotScope.
>                  */
>                 if (scope->ownercx) {
>                     JS_ASSERT(scope->ownercx == cx);
>                     rt->setSlotScope = scope;
>                 }
> #endif
304,313c343,351
<     if (ssr.errnum != JSMSG_NOT_AN_ERROR) {
<         if (ssr.errnum == JSMSG_OUT_OF_MEMORY) {
<             JS_ReportOutOfMemory(cx);
<         } else {
<             JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, ssr.errnum,
< #if JS_HAS_OBJ_PROTO_PROP
<                                  object_props[slot].name
< #else
<                                  (slot == JSSLOT_PROTO) ? js_proto_str
<                                                         : js_parent_str
---
>                 /* We can't deadlock because we checked for cycles above (2). */
>                 JS_LOCK_OBJ(cx, pobj);
>                 newscope = (JSScope *) js_HoldObjectMap(cx, pobj->map);
>                 obj->map = &newscope->map;
>                 js_DropObjectMap(cx, &scope->map, obj);
>                 JS_TRANSFER_SCOPE_LOCK(cx, scope, newscope);
>                 scope = newscope;
> #ifdef JS_THREADSAFE
>                 rt->setSlotScope = NULL;
315c353
<                                  );
---
>             }
317c355,358
<         return JS_FALSE;
---
>         LOCKED_OBJ_SET_SLOT(obj, JSSLOT_PROTO, OBJECT_TO_JSVAL(pobj));
>         JS_UNLOCK_SCOPE(cx, scope);
>     } else {
>         OBJ_SET_SLOT(cx, obj, slot, OBJECT_TO_JSVAL(pobj));
318a360,361
> 
>     SET_SLOT_DONE(rt);
319a363,364
> 
> #undef SET_SLOT_DONE
325c370
<     return (JSHashNumber)JS_PTR_TO_UINT32(key) >> JSVAL_TAGBITS;
---
>     return (JSHashNumber)key >> JSVAL_TAGBITS;
347,348d391
<     JS_CHECK_RECURSION(cx, return NULL);
< 
356,357c399
<         he = JS_HashTableRawAdd(table, hep, hash, obj,
<                                 JS_UINT32_TO_PTR(sharpid));
---
>         he = JS_HashTableRawAdd(table, hep, hash, obj, (void *)sharpid);
362,369d403
< 
<         /*
<          * Increment map->depth to protect js_EnterSharpObject from reentering
<          * itself badly.  Without this fix, if we reenter the basis case where
<          * map->depth == 0, when unwinding the inner call we will destroy the
<          * newly-created hash table and crash.
<          */
<         ++map->depth;
371d404
<         --map->depth;
374d406
< 
382,396c414,429
<             if (!prop)
<                 continue;
<             ok = OBJ_GET_ATTRIBUTES(cx, obj2, id, prop, &attrs);
<             if (ok) {
<                 if (OBJ_IS_NATIVE(obj2) &&
<                     (attrs & (JSPROP_GETTER | JSPROP_SETTER))) {
<                     val = JSVAL_NULL;
<                     if (attrs & JSPROP_GETTER)
<                         val = (jsval) ((JSScopeProperty*)prop)->getter;
<                     if (attrs & JSPROP_SETTER) {
<                         if (val != JSVAL_NULL) {
<                             /* Mark the getter, then set val to setter. */
<                             ok = (MarkSharpObjects(cx, JSVAL_TO_OBJECT(val),
<                                                    NULL)
<                                   != NULL);
---
>             if (prop) {
>                 ok = OBJ_GET_ATTRIBUTES(cx, obj2, id, prop, &attrs);
>                 if (ok) {
>                     if (OBJ_IS_NATIVE(obj2) &&
>                         (attrs & (JSPROP_GETTER | JSPROP_SETTER))) {
>                         val = JSVAL_NULL;
>                         if (attrs & JSPROP_GETTER)
>                             val = (jsval) ((JSScopeProperty*)prop)->getter;
>                         if (attrs & JSPROP_SETTER) {
>                             if (val != JSVAL_NULL) {
>                                 /* Mark the getter, then set val to setter. */
>                                 ok = (MarkSharpObjects(cx, JSVAL_TO_OBJECT(val),
>                                                        NULL)
>                                       != NULL);
>                             }
>                             val = (jsval) ((JSScopeProperty*)prop)->setter;
398c431,432
<                         val = (jsval) ((JSScopeProperty*)prop)->setter;
---
>                     } else {
>                         ok = OBJ_GET_PROPERTY(cx, obj, id, &val);
400,401d433
<                 } else {
<                     ok = OBJ_GET_PROPERTY(cx, obj, id, &val);
402a435
>                 OBJ_DROP_PROPERTY(cx, obj2, prop);
404d436
<             OBJ_DROP_PROPERTY(cx, obj2, prop);
421c453
<         sharpid = JS_PTR_TO_UINT32(he->value);
---
>         sharpid = (jsatomid) he->value;
424c456
<             he->value = JS_UINT32_TO_PTR(sharpid);
---
>             he->value = (void *) sharpid;
432a465
> #ifdef _UTF8
446,448d478
<     if (!JS_CHECK_OPERATION_LIMIT(cx, JSOW_ENTER_SHARP))
<         return NULL;
< 
461d490
<         JS_KEEP_ATOMS(cx->runtime);
464d492
<     /* From this point the control must flow either through out: or bad:. */
470c498
<         JS_ASSERT((JS_PTR_TO_UINT32(he->value) & SHARP_BIT) == 0);
---
>         JS_ASSERT((((jsatomid) he->value) & SHARP_BIT) == 0);
492a521
>             *sp = NULL;
498,499c527,531
<     sharpid = JS_PTR_TO_UINT32(he->value);
<     if (sharpid != 0) {
---
>     sharpid = (jsatomid) he->value;
>     if (sharpid == 0) {
>         *sp = NULL;
>     } else {
> 		size_t wLength;
503c535
<         *sp = js_InflateString(cx, buf, &len);
---
>         *sp = js_InflateString(cx, buf, len,&wLength);
534d565
<         JS_UNKEEP_ATOMS(cx->runtime);
540a572,667
> #else //#ifdef _UTF8
> JSHashEntry *
> js_EnterSharpObject(JSContext *cx, JSObject *obj, JSIdArray **idap,
>                     jschar **sp)
> {
>     JSSharpObjectMap *map;
>     JSHashTable *table;
>     JSIdArray *ida;
>     JSHashNumber hash;
>     JSHashEntry *he, **hep;
>     jsatomid sharpid;
>     char buf[20];
>     size_t len;
> 
>     /* Set to null in case we return an early error. */
>     *sp = NULL;
>     map = &cx->sharpObjectMap;
>     table = map->table;
>     if (!table) {
>         table = JS_NewHashTable(8, js_hash_object, JS_CompareValues,
>                                 JS_CompareValues, NULL, NULL);
>         if (!table) {
>             JS_ReportOutOfMemory(cx);
>             return NULL;
>         }
>         map->table = table;
>     }
> 
>     ida = NULL;
>     if (map->depth == 0) {
>         he = MarkSharpObjects(cx, obj, &ida);
>         if (!he)
>             goto bad;
>         JS_ASSERT((((jsatomid) he->value) & SHARP_BIT) == 0);
>         if (!idap) {
>             JS_DestroyIdArray(cx, ida);
>             ida = NULL;
>         }
>     } else {
>         hash = js_hash_object(obj);
>         hep = JS_HashTableRawLookup(table, hash, obj);
>         he = *hep;
> 
>         /*
>          * It's possible that the value of a property has changed from the
>          * first time the object's properties are traversed (when the property
>          * ids are entered into the hash table) to the second (when they are
>          * converted to strings), i.e., the OBJ_GET_PROPERTY() call is not
>          * idempotent.
>          */
>         if (!he) {
>             he = JS_HashTableRawAdd(table, hep, hash, obj, NULL);
>             if (!he) {
>                 JS_ReportOutOfMemory(cx);
>                 goto bad;
>             }
>             *sp = NULL;
>             sharpid = 0;
>             goto out;
>         }
>     }
> 
>     sharpid = (jsatomid) he->value;
>     if (sharpid == 0) {
>         *sp = NULL;
>     } else {
>         len = JS_snprintf(buf, sizeof buf, "#%u%c",
>                           sharpid >> SHARP_ID_SHIFT,
>                           (sharpid & SHARP_BIT) ? '#' : '=');
>         *sp = js_InflateString(cx, buf, len);
>         if (!*sp) {
>             if (ida)
>                 JS_DestroyIdArray(cx, ida);
>             goto bad;
>         }
>     }
> 
> out:
>     JS_ASSERT(he);
>     if ((sharpid & SHARP_BIT) == 0) {
>         if (idap && !ida) {
>             ida = JS_Enumerate(cx, obj);
>             if (!ida) {
>                 if (*sp) {
>                     JS_free(cx, *sp);
>                     *sp = NULL;
>                 }
>                 goto bad;
>             }
>         }
>         map->depth++;
>     }
> 
>     if (idap)
>         *idap = ida;
>     return he;
541a669,678
> bad:
>     /* Clean up the sharpObjectMap table on outermost error. */
>     if (map->depth == 0) {
>         map->sharpgen = 0;
>         JS_HashTableDestroy(map->table);
>         map->table = NULL;
>     }
>     return NULL;
> }
> #endif //#ifdef _UTF8
551d687
<         JS_UNKEEP_ATOMS(cx->runtime);
565,600c701
< JS_STATIC_DLL_CALLBACK(intN)
< gc_sharp_table_entry_marker(JSHashEntry *he, intN i, void *arg)
< {
<     JS_CALL_OBJECT_TRACER((JSTracer *)arg, (JSObject *)he->key,
<                           "sharp table entry");
<     return JS_DHASH_NEXT;
< }
< 
< void
< js_TraceSharpMap(JSTracer *trc, JSSharpObjectMap *map)
< {
<     JS_ASSERT(map->depth > 0);
<     JS_ASSERT(map->table);
< 
<     /*
<      * During recursive calls to MarkSharpObjects a non-native object or
<      * object with a custom getProperty method can potentially return an
<      * unrooted value or even cut from the object graph an argument of one of
<      * MarkSharpObjects recursive invocations. So we must protect map->table
<      * entries against GC.
<      *
<      * We can not simply use JSTempValueRooter to mark the obj argument of
<      * MarkSharpObjects during recursion as we have to protect *all* entries
<      * in JSSharpObjectMap including those that contains otherwise unreachable
<      * objects just allocated through custom getProperty. Otherwise newer
<      * allocations can re-use the address of an object stored in the hashtable
<      * confusing js_EnterSharpObject. So to address the problem we simply
<      * mark all objects from map->table.
<      *
<      * An alternative "proper" solution is to use JSTempValueRooter in
<      * MarkSharpObjects with code to remove during finalization entries
<      * with otherwise unreachable objects. But this is way too complex
<      * to justify spending efforts.
<      */
<     JS_HashTableEnumerateEntries(map->table, gc_sharp_table_entry_marker, trc);
< }
---
> #define OBJ_TOSTRING_EXTRA      3       /* for 3 local GC roots */
602,604c703,706
< #if JS_HAS_TOSOURCE
< static JSBool
< obj_toSource(JSContext *cx, uintN argc, jsval *vp)
---
> #if JS_HAS_INITIALIZERS || JS_HAS_TOSOURCE
> JSBool
> js_obj_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
>                 jsval *rval)
607d708
<     JSObject *obj;
612c713
<     size_t nchars, idstrlength, gsoplength, vlength, vsharplength, curlen;
---
>     size_t nchars, idstrlength, gsoplength, vlength, vsharplength;
621,624c722
<     jsval *val;
<     jsval localroot[4] = {JSVAL_NULL, JSVAL_NULL, JSVAL_NULL, JSVAL_NULL};
<     JSTempValueRooter tvr;
<     JSString *gsopold[2];
---
>     jsval val[2];
625a724
>     JSAtom *atom;
628,635c727,731
<     JS_CHECK_RECURSION(cx, return JS_FALSE);
< 
<     /* After this, control must flow through out: to exit. */
<     JS_PUSH_TEMP_ROOT(cx, 4, localroot, &tvr);
< 
<     /* If outermost, we need parentheses to be an expression, not a block. */
<     outermost = (cx->sharpObjectMap.depth == 0);
<     obj = JSVAL_TO_OBJECT(vp[1]);
---
>     /*
>      * obj_toString for 1.2 calls toSource, and doesn't want the extra parens
>      * on the outside.
>      */
>     outermost = (cx->version != JSVERSION_1_2 && cx->sharpObjectMap.depth == 0);
637,640c733,734
<     if (!he) {
<         ok = JS_FALSE;
<         goto out;
<     }
---
>     if (!he)
>         return JS_FALSE;
663c757,758
<         chars = (jschar *) malloc(((outermost ? 4 : 2) + 1) * sizeof(jschar));
---
>         XMEMTAG("js_obj_toSource xmalloc");
>         chars = (jschar *) xmalloc(((outermost ? 4 : 2) + 1) * sizeof(jschar));
672a768
>         XMEMTAG("js_obj_toSource xrealloc");
674c770
<             realloc((ochars = chars), (nchars + 2 + 1) * sizeof(jschar));
---
>             xrealloc((ochars = chars), (nchars + 2 + 1) * sizeof(jschar));
676c772
<             free(ochars);
---
>             xfree(ochars);
693,699d788
<     /*
<      * We have four local roots for cooked and raw value GC safety.  Hoist the
<      * "localroot + 2" out of the loop using the val local, which refers to
<      * the raw (unconverted, "uncooked") values.
<      */
<     val = localroot + 2;
< 
701,703c790
<         JSBool idIsLexicalIdentifier, needOldStyleGetterSetter;
< 
<         /* Get strings for id and value and GC-root them via vp. */
---
>         /* Get strings for id and value and GC-root them via argv. */
706a794
> 
710,730d797
< #endif
< 
<         /*
<          * Convert id to a jsval and then to a string.  Decide early whether we
<          * prefer get/set or old getter/setter syntax.
<          */
<         idstr = js_ValueToString(cx, ID_TO_VALUE(id));
<         if (!idstr) {
<             ok = JS_FALSE;
<             OBJ_DROP_PROPERTY(cx, obj2, prop);
<             goto error;
<         }
<         *vp = STRING_TO_JSVAL(idstr);                   /* local root */
<         idIsLexicalIdentifier = js_IsIdentifier(idstr);
<         needOldStyleGetterSetter =
<             !idIsLexicalIdentifier ||
<             js_CheckKeyword(JSSTRING_CHARS(idstr),
<                             JSSTRING_LENGTH(idstr)) != TOK_EOF;
< 
< #if JS_HAS_GETTER_SETTER
< 
742c809,810
<                     gsopold[valcnt] =
---
> #ifdef OLD_GETTER_SETTER
>                     gsop[valcnt] =
743a812
> #else
746c815
< 
---
> #endif
751c820,821
<                     gsopold[valcnt] =
---
> #ifdef OLD_GETTER_SETTER
>                     gsop[valcnt] =
752a823
> #else
755c826
< 
---
> #endif
761d831
<                 gsopold[0] = NULL;
769,774d838
<         /*
<          * We simplify the source code at the price of minor dead code bloat in
<          * the ECMA version (for testing only, see jsconfig.h).  The null
<          * default values in gsop[j] suffice to disable non-ECMA getter and
<          * setter code.
<          */
777d840
<         gsopold[0] = NULL;
784a848,857
>         /* Convert id to a jsval and then to a string. */
>         atom = JSVAL_IS_INT(id) ? NULL : (JSAtom *)id;
>         id = ID_TO_VALUE(id);
>         idstr = js_ValueToString(cx, id);
>         if (!idstr) {
>             ok = JS_FALSE;
>             goto error;
>         }
>         argv[0] = STRING_TO_JSVAL(idstr);
> 
786,787c859,860
<          * If id is a string that's not an identifier, then it needs to be
<          * quoted.  Also, negative integer ids must be quoted.
---
>          * If id is a string that's a reserved identifier, or else id is not
>          * an identifier at all, then it needs to be quoted.
789,791c862
<         if (JSID_IS_ATOM(id)
<             ? !idIsLexicalIdentifier
<             : (!JSID_IS_INT(id) || JSID_TO_INT(id) < 0)) {
---
>         if (atom && (ATOM_KEYWORD(atom) || !js_IsIdentifier(idstr))) {
797c868
<             *vp = STRING_TO_JSVAL(idstr);               /* local root */
---
>             argv[0] = STRING_TO_JSVAL(idstr);
799c870,871
<         JSSTRING_CHARS_AND_LENGTH(idstr, idstrchars, idstrlength);
---
>         idstrchars = JSSTRING_CHARS(idstr);
>         idstrlength = JSSTRING_LENGTH(idstr);
808,809c880,882
<             localroot[j] = STRING_TO_JSVAL(valstr);     /* local root */
<             JSSTRING_CHARS_AND_LENGTH(valstr, vchars, vlength);
---
>             argv[1+j] = STRING_TO_JSVAL(valstr);
>             vchars = JSSTRING_CHARS(valstr);
>             vlength = JSSTRING_LENGTH(valstr);
811,815c884,891
<             if (vchars[0] == '#')
<                 needOldStyleGetterSetter = JS_TRUE;
< 
<             if (needOldStyleGetterSetter)
<                 gsop[j] = gsopold[j];
---
> #ifndef OLD_GETTER_SETTER
>             /* Remove 'function ' from beginning of valstr. */
>             if (gsop[j]) {
>                 int n = strlen(js_function_str) + 1;
>                 vchars += n;
>                 vlength -= n;
>             }
> #endif
831,832d906
<                     needOldStyleGetterSetter = JS_TRUE;
<                     gsop[j] = gsopold[j];
837,838d910
<                         needOldStyleGetterSetter = JS_TRUE;
<                         gsop[j] = gsopold[j];
845,914d916
< #ifndef OLD_GETTER_SETTER
<             /*
<              * Remove '(function ' from the beginning of valstr and ')' from the
<              * end so that we can put "get" in front of the function definition.
<              */
<             if (gsop[j] && VALUE_IS_FUNCTION(cx, val[j]) &&
<                 !needOldStyleGetterSetter) {
<                 JSFunction *fun = JS_ValueToFunction(cx, val[j]);
<                 const jschar *start = vchars;
<                 const jschar *end = vchars + vlength;
< 
<                 uint8 parenChomp = 0;
<                 if (vchars[0] == '(') {
<                     vchars++;
<                     parenChomp = 1;
<                 }
< 
<                 /*
<                  * Try to jump "getter" or "setter" keywords, if we suspect
<                  * they might appear here.  This code can be confused by people
<                  * defining Function.prototype.toString, so let's be cautious.
<                  */
<                 if (JSFUN_GETTER_TEST(fun->flags) ||
<                     JSFUN_SETTER_TEST(fun->flags)) { /* skip "getter/setter" */
<                     const jschar *tmp = js_strchr_limit(vchars, ' ', end);
<                     if (tmp)
<                         vchars = tmp + 1;
<                 }
< 
<                 /* Try to jump "function" keyword. */
<                 if (vchars)
<                     vchars = js_strchr_limit(vchars, ' ', end);
< 
<                 if (vchars) {
<                     if (*vchars == ' ')
<                         vchars++;
<                     vlength = end - vchars - parenChomp;
<                 } else {
<                     gsop[j] = NULL;
<                     vchars = start;
<                 }
<             }
< #else
<             needOldStyleGetterSetter = JS_TRUE;
<             gsop[j] = gsopold[j];
< #endif
< 
< #define SAFE_ADD(n)                                                          \
<     JS_BEGIN_MACRO                                                           \
<         size_t n_ = (n);                                                     \
<         curlen += n_;                                                        \
<         if (curlen < n_)                                                     \
<             goto overflow;                                                   \
<     JS_END_MACRO
< 
<             curlen = nchars;
<             if (comma)
<                 SAFE_ADD(2);
<             SAFE_ADD(idstrlength + 1);
<             if (gsop[j])
<                 SAFE_ADD(JSSTRING_LENGTH(gsop[j]) + 1);
<             SAFE_ADD(vsharplength);
<             SAFE_ADD(vlength);
<             /* Account for the trailing null. */
<             SAFE_ADD((outermost ? 2 : 1) + 1);
< #undef SAFE_ADD
< 
<             if (curlen > (size_t)-1 / sizeof(jschar))
<                 goto overflow;
< 
917c919,924
<                 realloc((ochars = chars), curlen * sizeof(jschar));
---
>                 xrealloc((ochars = chars),
>                         (nchars + (comma ? 2 : 0) +
>                          idstrlength + 1 +
>                          (gsop[j] ? 1 + JSSTRING_LENGTH(gsop[j]) : 0) +
>                          vsharplength + vlength +
>                          (outermost ? 2 : 1) + 1) * sizeof(jschar));
921c928
<                 free(ochars);
---
>                 xfree(ochars);
931,953c938,945
<             if (needOldStyleGetterSetter) {
<                 js_strncpy(&chars[nchars], idstrchars, idstrlength);
<                 nchars += idstrlength;
<                 if (gsop[j]) {
<                     chars[nchars++] = ' ';
<                     gsoplength = JSSTRING_LENGTH(gsop[j]);
<                     js_strncpy(&chars[nchars], JSSTRING_CHARS(gsop[j]),
<                                gsoplength);
<                     nchars += gsoplength;
<                 }
<                 chars[nchars++] = ':';
<             } else {  /* New style "decompilation" */
<                 if (gsop[j]) {
<                     gsoplength = JSSTRING_LENGTH(gsop[j]);
<                     js_strncpy(&chars[nchars], JSSTRING_CHARS(gsop[j]),
<                                gsoplength);
<                     nchars += gsoplength;
<                     chars[nchars++] = ' ';
<                 }
<                 js_strncpy(&chars[nchars], idstrchars, idstrlength);
<                 nchars += idstrlength;
<                 /* Extraneous space after id here will be extracted later */
<                 chars[nchars++] = gsop[j] ? ' ' : ':';
---
> #ifdef OLD_GETTER_SETTER
>             js_strncpy(&chars[nchars], idstrchars, idstrlength);
>             nchars += idstrlength;
>             if (gsop[j]) {
>                 chars[nchars++] = ' ';
>                 gsoplength = JSSTRING_LENGTH(gsop[j]);
>                 js_strncpy(&chars[nchars], JSSTRING_CHARS(gsop[j]), gsoplength);
>                 nchars += gsoplength;
955c947,959
< 
---
>             chars[nchars++] = ':';
> #else
>             if (gsop[j]) {
>                 gsoplength = JSSTRING_LENGTH(gsop[j]);
>                 js_strncpy(&chars[nchars], JSSTRING_CHARS(gsop[j]), gsoplength);
>                 nchars += gsoplength;
>                 chars[nchars++] = ' ';
>             }
>             js_strncpy(&chars[nchars], idstrchars, idstrlength);
>             nchars += idstrlength;
>             if (!gsop[j])
>                 chars[nchars++] = ':';
> #endif
978,979c982,983
<             free(chars);
<         goto out;
---
>             xfree(chars);
>         return ok;
984,985c988
<         ok = JS_FALSE;
<         goto out;
---
>         return JS_FALSE;
988c991
<     str = js_NewString(cx, chars, nchars);
---
>     str = js_NewString(cx, chars, nchars, 0);
990,992c993,994
<         free(chars);
<         ok = JS_FALSE;
<         goto out;
---
>         xfree(chars);
>         return JS_FALSE;
994,1004c996,997
<     *vp = STRING_TO_JSVAL(str);
<     ok = JS_TRUE;
<   out:
<     JS_POP_TEMP_ROOT(cx, &tvr);
<     return ok;
< 
<   overflow:
<     JS_free(cx, vsharp);
<     free(chars);
<     chars = NULL;
<     goto error;
---
>     *rval = STRING_TO_JSVAL(str);
>     return JS_TRUE;
1006c999
< #endif /* JS_HAS_TOSOURCE */
---
> #endif /* JS_HAS_INITIALIZERS || JS_HAS_TOSOURCE */
1008,1009c1001,1003
< static JSBool
< obj_toString(JSContext *cx, uintN argc, jsval *vp)
---
> JSBool
> js_obj_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
>                 jsval *rval)
1016c1010,1015
<     clazz = OBJ_GET_CLASS(cx, JS_THIS_OBJECT(cx, vp))->name;
---
> #if JS_HAS_INITIALIZERS
>     if (cx->version == JSVERSION_1_2)
>         return js_obj_toSource(cx, obj, argc, argv, rval);
> #endif
> 
>     clazz = OBJ_GET_CLASS(cx, obj)->name;
1017a1017
>     XMEMTAG("js_obj_toString");
1031c1031
<     str = js_NewString(cx, chars, nchars);
---
>     str = js_NewString(cx, chars, nchars, 0);
1036,1049c1036
<     *vp = STRING_TO_JSVAL(str);
<     return JS_TRUE;
< }
< 
< static JSBool
< obj_toLocaleString(JSContext *cx, uintN argc, jsval *vp)
< {
<     JSString *str;
< 
<     str = js_ValueToString(cx, vp[1]);
<     if (!str)
<         return JS_FALSE;
< 
<     *vp = STRING_TO_JSVAL(str);
---
>     *rval = STRING_TO_JSVAL(str);
1054,1067c1041
< obj_valueOf(JSContext *cx, uintN argc, jsval *vp)
< {
<     *vp = vp[1];
<     return JS_TRUE;
< }
< 
< /*
<  * Check whether principals subsumes scopeobj's principals, and return true
<  * if so (or if scopeobj has no principals, for backward compatibility with
<  * the JS API, which does not require principals), and false otherwise.
<  */
< JSBool
< js_CheckPrincipalsAccess(JSContext *cx, JSObject *scopeobj,
<                          JSPrincipals *principals, JSAtom *caller)
---
> obj_valueOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1069,1085c1043
<     JSRuntime *rt;
<     JSPrincipals *scopePrincipals;
<     const char *callerstr;
< 
<     rt = cx->runtime;
<     if (rt->findObjectPrincipals) {
<         scopePrincipals = rt->findObjectPrincipals(cx, scopeobj);
<         if (!principals || !scopePrincipals ||
<             !principals->subsume(principals, scopePrincipals)) {
<             callerstr = js_AtomToPrintableString(cx, caller);
<             if (!callerstr)
<                 return JS_FALSE;
<             JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
<                                  JSMSG_BAD_INDIRECT_CALL, callerstr);
<             return JS_FALSE;
<         }
<     }
---
>     *rval = OBJECT_TO_JSVAL(obj);
1089,1126d1046
< JSObject *
< js_CheckScopeChainValidity(JSContext *cx, JSObject *scopeobj, const char *caller)
< {
<     JSClass *clasp;
<     JSExtendedClass *xclasp;
<     JSObject *inner;
< 
<     if (!scopeobj)
<         goto bad;
< 
<     OBJ_TO_INNER_OBJECT(cx, scopeobj);
<     if (!scopeobj)
<         return NULL;
< 
<     inner = scopeobj;
< 
<     /* XXX This is an awful gross hack. */
<     while (scopeobj) {
<         clasp = OBJ_GET_CLASS(cx, scopeobj);
<         if (clasp->flags & JSCLASS_IS_EXTENDED) {
<             xclasp = (JSExtendedClass*)clasp;
<             if (xclasp->innerObject &&
<                 xclasp->innerObject(cx, scopeobj) != scopeobj) {
<                 goto bad;
<             }
<         }
< 
<         scopeobj = OBJ_GET_PARENT(cx, scopeobj);
<     }
< 
<     return inner;
< 
< bad:
<     JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
<                          JSMSG_BAD_INDIRECT_CALL, caller);
<     return NULL;
< }
< 
1133d1052
<     JSClass *clasp;
1142,1143c1061
<     JSObject *setCallerScopeChain = NULL;
<     JSBool setCallerVarObj = JS_FALSE;
---
>     JSBool setCallerScopeChain = JS_FALSE, setCallerVarObj = JS_FALSE;
1147,1165c1065,1066
<     caller = JS_GetScriptedCaller(cx, fp);
<     JS_ASSERT(!caller || caller->pc);
<     indirectCall = (caller && *caller->pc != JSOP_EVAL);
< 
<     /*
<      * Ban all indirect uses of eval (global.foo = eval; global.foo(...)) and
<      * calls that attempt to use a non-global object as the "with" object in
<      * the former indirect case.
<      */
<     scopeobj = OBJ_GET_PARENT(cx, obj);
<     if (scopeobj &&
<         ((clasp = OBJ_GET_CLASS(cx, obj))->flags & JSCLASS_IS_EXTENDED)) {
<         JSExtendedClass *xclasp = (JSExtendedClass *) clasp;
<         if (xclasp->wrappedObject) {
<             JSObject *wrapped = xclasp->wrappedObject(cx, obj);
<             if (wrapped)
<                 scopeobj = OBJ_GET_PARENT(cx, wrapped);
<         }
<     }
---
>     caller = fp->down;
>     indirectCall = (!caller->pc || *caller->pc != JSOP_EVAL);
1167,1175c1068,1075
<     if (indirectCall || scopeobj) {
<         uintN flags = scopeobj
<                       ? JSREPORT_ERROR
<                       : JSREPORT_STRICT | JSREPORT_WARNING;
<         if (!JS_ReportErrorFlagsAndNumber(cx, flags, js_GetErrorMessage, NULL,
<                                           JSMSG_BAD_INDIRECT_CALL,
<                                           js_eval_str)) {
<             return JS_FALSE;
<         }
---
>     if (JSVERSION_IS_ECMA(cx->version) &&
>         indirectCall &&
>         !JS_ReportErrorFlagsAndNumber(cx,
>                                       JSREPORT_WARNING | JSREPORT_STRICT,
>                                       js_GetErrorMessage, NULL,
>                                       JSMSG_BAD_INDIRECT_CALL,
>                                       js_eval_str)) {
>         return JS_FALSE;
1183,1190c1083
<     /*
<      * If the caller is a lightweight function and doesn't have a variables
<      * object, then we need to provide one for the compiler to stick any
<      * declared (var) variables into.
<      */
<     if (caller && !caller->varobj && !js_GetCallObject(cx, caller, NULL))
<         return JS_FALSE;
< 
---
> #if JS_HAS_SCRIPT_OBJECT
1194a1088
>     scopeobj = NULL;
1200,1204c1094,1096
< 
<     /* From here on, control must exit through label out with ok set. */
<     js_DisablePropertyCache(cx);
< 
<     if (!scopeobj) {
---
>     if (!scopeobj)
> #endif
>     {
1208,1217c1100
<             callerScopeChain = js_GetScopeChain(cx, caller);
<             if (!callerScopeChain) {
<                 ok = JS_FALSE;
<                 goto out;
<             }
<             OBJ_TO_INNER_OBJECT(cx, obj);
<             if (!obj) {
<                 ok = JS_FALSE;
<                 goto out;
<             }
---
>             callerScopeChain = caller->scopeChain;
1219,1229c1102,1105
<                 ok = js_CheckPrincipalsAccess(cx, obj,
<                                               caller->script->principals,
<                                               cx->runtime->atomState.evalAtom);
<                 if (!ok)
<                     goto out;
< 
<                 scopeobj = js_NewWithObject(cx, obj, callerScopeChain, -1);
<                 if (!scopeobj) {
<                     ok = JS_FALSE;
<                     goto out;
<                 }
---
>                 scopeobj = js_NewObject(cx, &js_WithClass, obj,
>                                         callerScopeChain);
>                 if (!scopeobj)
>                     return JS_FALSE;
1233,1235c1109
< 
<                 /* Remember scopeobj so we can null its private when done. */
<                 setCallerScopeChain = scopeobj;
---
>                 setCallerScopeChain = JS_TRUE;
1244a1119
>         /* From here on, control must exit through label out with ok set. */
1247,1266c1122,1128
<         /*
<          * Compile using caller's current scope object.
<          *
<          * NB: This means that native callers (who reach this point through
<          * the C API) must use the two parameter form.
<          */
<         if (caller) {
<             scopeobj = js_GetScopeChain(cx, caller);
<             if (!scopeobj) {
<                 ok = JS_FALSE;
<                 goto out;
<             }
<         }
<     }
< 
<     /* Ensure we compile this eval with the right object in the scope chain. */
<     scopeobj = js_CheckScopeChainValidity(cx, scopeobj, js_eval_str);
<     if (!scopeobj) {
<         ok = JS_FALSE;
<         goto out;
---
> #if JS_BUG_EVAL_THIS_SCOPE
>         /* An old version used the object in which eval was found for scope. */
>         scopeobj = obj;
> #else
>         /* Compile using caller's current scope object. */
>         scopeobj = caller->scopeChain;
> #endif
1270,1278c1132,1135
<     if (caller) {
<         principals = JS_EvalFramePrincipals(cx, fp, caller);
<         if (principals == caller->script->principals) {
<             file = caller->script->filename;
<             line = js_PCToLineNumber(cx, caller->script, caller->pc);
<         } else {
<             file = principals->codebase;
<             line = 0;
<         }
---
>     if (caller->script) {
>         file = caller->script->filename;
>         line = js_PCToLineNumber(caller->script, caller->pc);
>         principals = caller->script->principals;
1285,1299c1142,1146
<     /*
<      * Set JSFRAME_EVAL on fp and any frames (e.g., fun_call if eval.call was
<      * invoked) between fp and its scripted caller, to help the compiler easily
<      * find the same caller whose scope and var obj we've set.
<      *
<      * XXX this nonsense could, and perhaps should, go away with a better way
<      * to pass params to the compiler than via the top-most frame.
<      */
<     do {
<         fp->flags |= JSFRAME_EVAL;
<     } while ((fp = fp->down) != caller);
< 
<     script = js_CompileScript(cx, scopeobj, principals, TCF_COMPILE_N_GO,
<                               JSSTRING_CHARS(str), JSSTRING_LENGTH(str),
<                               NULL, file, line);
---
>     fp->flags |= JSFRAME_EVAL;
>     script = JS_CompileUCScriptForPrincipals(cx, scopeobj, principals,
>                                              JSSTRING_CHARS(str),
>                                              JSSTRING_LENGTH(str),
>                                              file, line);
1305c1152,1156
<     if (argc < 2) {
---
> #if !JS_BUG_EVAL_THIS_SCOPE
> #if JS_HAS_SCRIPT_OBJECT
>     if (argc < 2)
> #endif
>     {
1307,1308c1158
<         if (caller)
<             scopeobj = caller->scopeChain;
---
>         scopeobj = caller->scopeChain;
1310,1319c1160,1161
< 
<     /*
<      * Belt-and-braces: check that the lesser of eval's principals and the
<      * caller's principals has access to scopeobj.
<      */
<     ok = js_CheckPrincipalsAccess(cx, scopeobj, principals,
<                                   cx->runtime->atomState.evalAtom);
<     if (ok)
<         ok = js_Execute(cx, scopeobj, script, caller, JSFRAME_EVAL, rval);
< 
---
> #endif
>     ok = js_Execute(cx, scopeobj, script, caller, JSFRAME_EVAL, rval);
1325c1167
<     if (setCallerScopeChain) {
---
>     if (setCallerScopeChain)
1327,1329d1168
<         JS_ASSERT(OBJ_GET_CLASS(cx, setCallerScopeChain) == &js_WithClass);
<         JS_SetPrivate(cx, setCallerScopeChain, NULL);
<     }
1333,1334d1171
< 
<     js_EnablePropertyCache(cx);
1344,1350c1181
<     JSObject *callable;
<     JSRuntime *rt;
<     JSStackFrame *caller;
<     JSPrincipals *subject, *watcher;
<     JSResolvingKey key;
<     JSResolvingEntry *entry;
<     uint32 generation;
---
>     JSObject *funobj;
1352,1382d1182
<     JSBool ok;
< 
<     callable = (JSObject *) closure;
< 
<     rt = cx->runtime;
<     if (rt->findObjectPrincipals) {
<         /* Skip over any obj_watch_* frames between us and the real subject. */
<         caller = JS_GetScriptedCaller(cx, cx->fp);
<         if (caller) {
<             /*
<              * Only call the watch handler if the watcher is allowed to watch
<              * the currently executing script.
<              */
<             watcher = rt->findObjectPrincipals(cx, callable);
<             subject = JS_StackFramePrincipals(cx, caller);
< 
<             if (watcher && subject && !watcher->subsume(watcher, subject)) {
<                 /* Silently don't call the watch handler. */
<                 return JS_TRUE;
<             }
<         }
<     }
< 
<     /* Avoid recursion on (obj, id) already being watched on cx. */
<     key.obj = obj;
<     key.id = id;
<     if (!js_StartResolving(cx, &key, JSRESFLAG_WATCH, &entry))
<         return JS_FALSE;
<     if (!entry)
<         return JS_TRUE;
<     generation = cx->resolvingTable->generation;
1383a1184
>     funobj = (JSObject *) closure;
1387,1389c1188
<     ok = js_InternalCall(cx, obj, OBJECT_TO_JSVAL(callable), 3, argv, nvp);
<     js_StopResolving(cx, &key, JSRESFLAG_WATCH, entry, generation);
<     return ok;
---
>     return js_InternalCall(cx, obj, OBJECT_TO_JSVAL(funobj), 3, argv, nvp);
1393c1192
< obj_watch(JSContext *cx, uintN argc, jsval *vp)
---
> obj_watch(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1395c1194
<     JSObject *callable;
---
>     JSFunction *fun;
1398d1196
<     JSObject *obj;
1401,1402c1199,1200
<     callable = js_ValueToCallableObject(cx, &vp[3], 0);
<     if (!callable)
---
>     fun = js_ValueToFunction(cx, &argv[1], JS_FALSE);
>     if (!fun)
1403a1202
>     argv[1] = OBJECT_TO_JSVAL(fun->object);
1406c1205
<     userid = vp[2];
---
>     userid = argv[0];
1410d1208
<     obj = JSVAL_TO_OBJECT(vp[1]);
1415,1416c1213
<     *vp = JSVAL_VOID;
<     return JS_SetWatchPoint(cx, obj, userid, obj_watch_handler, callable);
---
>     return JS_SetWatchPoint(cx, obj, userid, obj_watch_handler, fun->object);
1420c1217
< obj_unwatch(JSContext *cx, uintN argc, jsval *vp)
---
> obj_unwatch(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1422,1423c1219
<     *vp = JSVAL_VOID;
<     return JS_ClearWatchPoint(cx, JSVAL_TO_OBJECT(vp[1]), vp[2], NULL, NULL);
---
>     return JS_ClearWatchPoint(cx, obj, argv[0], NULL, NULL);
1427a1224
> #if JS_HAS_NEW_OBJ_METHODS
1435,1444c1232,1233
< obj_hasOwnProperty(JSContext *cx, uintN argc, jsval *vp)
< {
<     JSObject *obj;
< 
<     obj = JSVAL_TO_OBJECT(vp[1]);
<     return js_HasOwnPropertyHelper(cx, obj->map->ops->lookupProperty, vp);
< }
< 
< JSBool
< js_HasOwnPropertyHelper(JSContext *cx, JSLookupPropOp lookup, jsval *vp)
---
> obj_hasOwnProperty(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
>                    jsval *rval)
1447c1236
<     JSObject *obj, *obj2;
---
>     JSObject *obj2;
1451c1240
<     if (!JS_ValueToId(cx, vp[2], &id))
---
>     if (!JS_ValueToId(cx, argv[0], &id))
1453,1454c1242
<     obj = JSVAL_TO_OBJECT(vp[1]);
<     if (!lookup(cx, obj, id, &obj2, &prop))
---
>     if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop))
1457c1245
<         *vp = JSVAL_FALSE;
---
>         *rval = JSVAL_FALSE;
1459c1247,1250
<         *vp = JSVAL_TRUE;
---
>         *rval = JSVAL_TRUE;
>     } else if (OBJ_IS_NATIVE(obj2)) {
>         sprop = (JSScopeProperty *)prop;
>         *rval = BOOLEAN_TO_JSVAL(SPROP_IS_SHARED_PERMANENT(sprop));
1461,1496c1252
<         JSClass *clasp;
<         JSExtendedClass *xclasp;
<         JSObject *outer;
< 
<         clasp = OBJ_GET_CLASS(cx, obj2);
<         if (!(clasp->flags & JSCLASS_IS_EXTENDED) ||
<             !(xclasp = (JSExtendedClass *) clasp)->outerObject) {
<             outer = NULL;
<         } else {
<             outer = xclasp->outerObject(cx, obj2);
<             if (!outer)
<                 return JS_FALSE;
<         }
<         if (outer == obj) {
<             *vp = JSVAL_TRUE;
<         } else if (OBJ_IS_NATIVE(obj2) && OBJ_GET_CLASS(cx, obj) == clasp) {
<             /*
<              * The combination of JSPROP_SHARED and JSPROP_PERMANENT in a
<              * delegated property makes that property appear to be direct in
<              * all delegating instances of the same native class.  This hack
<              * avoids bloating every function instance with its own 'length'
<              * (AKA 'arity') property.  But it must not extend across class
<              * boundaries, to avoid making hasOwnProperty lie (bug 320854).
<              *
<              * It's not really a hack, of course: a permanent property can't
<              * be deleted, and JSPROP_SHARED means "don't allocate a slot in
<              * any instance, prototype or delegating".  Without a slot, and
<              * without the ability to remove and recreate (with differences)
<              * the property, there is no way to tell whether it is directly
<              * owned, or indirectly delegated.
<              */
<             sprop = (JSScopeProperty *)prop;
<             *vp = BOOLEAN_TO_JSVAL(SPROP_IS_SHARED_PERMANENT(sprop));
<         } else {
<             *vp = JSVAL_FALSE;
<         }
---
>         *rval = JSVAL_FALSE;
1505c1261,1262
< obj_isPrototypeOf(JSContext *cx, uintN argc, jsval *vp)
---
> obj_isPrototypeOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
>                   jsval *rval)
1509c1266
<     if (!js_IsDelegate(cx, JSVAL_TO_OBJECT(vp[1]), vp[2], &b))
---
>     if (!js_IsDelegate(cx, obj, *argv, &b))
1511c1268
<     *vp = BOOLEAN_TO_JSVAL(b);
---
>     *rval = BOOLEAN_TO_JSVAL(b);
1517c1274,1275
< obj_propertyIsEnumerable(JSContext *cx, uintN argc, jsval *vp)
---
> obj_propertyIsEnumerable(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
>                          jsval *rval)
1520d1277
<     JSObject *obj, *pobj;
1521a1279
>     JSObject *obj2;
1525c1283
<     if (!JS_ValueToId(cx, vp[2], &id))
---
>     if (!JS_ValueToId(cx, argv[0], &id))
1528,1529c1286
<     obj = JS_THIS_OBJECT(cx, vp);
<     if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &pobj, &prop))
---
>     if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop))
1533c1290
<         *vp = JSVAL_FALSE;
---
>         *rval = JSVAL_FALSE;
1548,1549c1305,1306
<     if (pobj != obj &&
<         !(OBJ_IS_NATIVE(pobj) &&
---
>     if (obj2 != obj &&
>         !(OBJ_IS_NATIVE(obj2) &&
1551,1552c1308,1309
<         OBJ_DROP_PROPERTY(cx, pobj, prop);
<         *vp = JSVAL_FALSE;
---
>         OBJ_DROP_PROPERTY(cx, obj2, prop);
>         *rval = JSVAL_FALSE;
1556,1557c1313,1314
<     ok = OBJ_GET_ATTRIBUTES(cx, pobj, id, prop, &attrs);
<     OBJ_DROP_PROPERTY(cx, pobj, prop);
---
>     ok = OBJ_GET_ATTRIBUTES(cx, obj2, id, prop, &attrs);
>     OBJ_DROP_PROPERTY(cx, obj2, prop);
1559c1316
<         *vp = BOOLEAN_TO_JSVAL((attrs & JSPROP_ENUMERATE) != 0);
---
>         *rval = BOOLEAN_TO_JSVAL((attrs & JSPROP_ENUMERATE) != 0);
1561a1319
> #endif /* JS_HAS_NEW_OBJ_METHODS */
1565c1323,1324
< obj_defineGetter(JSContext *cx, uintN argc, jsval *vp)
---
> obj_defineGetter(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
>                  jsval *rval)
1569c1328
<     JSObject *obj;
---
>     JSBool found;
1572c1331
<     fval = vp[3];
---
>     fval = argv[1];
1580c1339
<     if (!JS_ValueToId(cx, vp[2], &id))
---
>     if (!JS_ValueToId(cx, argv[0], &id))
1582,1583c1341
<     obj = JSVAL_TO_OBJECT(vp[1]);
<     if (!js_CheckRedeclaration(cx, obj, id, JSPROP_GETTER, NULL, NULL))
---
>     if (!js_CheckRedeclaration(cx, obj, id, JSPROP_GETTER, &found))
1591d1348
<     *vp = JSVAL_VOID;
1594,1595c1351
<                                JSPROP_ENUMERATE | JSPROP_GETTER | JSPROP_SHARED,
<                                NULL);
---
>                                JSPROP_GETTER | JSPROP_SHARED, NULL);
1599c1355,1356
< obj_defineSetter(JSContext *cx, uintN argc, jsval *vp)
---
> obj_defineSetter(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
>                  jsval *rval)
1603c1360
<     JSObject *obj;
---
>     JSBool found;
1606c1363
<     fval = vp[3];
---
>     fval = argv[1];
1614c1371
<     if (!JS_ValueToId(cx, vp[2], &id))
---
>     if (!JS_ValueToId(cx, argv[0], &id))
1616,1617c1373
<     obj = JSVAL_TO_OBJECT(vp[1]);
<     if (!js_CheckRedeclaration(cx, obj, id, JSPROP_SETTER, NULL, NULL))
---
>     if (!js_CheckRedeclaration(cx, obj, id, JSPROP_SETTER, &found))
1625d1380
<     *vp = JSVAL_VOID;
1628,1629c1383
<                                JSPROP_ENUMERATE | JSPROP_SETTER | JSPROP_SHARED,
<                                NULL);
---
>                                JSPROP_SETTER | JSPROP_SHARED, NULL);
1633c1387,1388
< obj_lookupGetter(JSContext *cx, uintN argc, jsval *vp)
---
> obj_lookupGetter(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
>                  jsval *rval)
1637d1391
<     JSProperty *prop;
1640c1394
<     if (!JS_ValueToId(cx, vp[2], &id))
---
>     if (!JS_ValueToId(cx, argv[0], &id))
1642c1396
<     if (!OBJ_LOOKUP_PROPERTY(cx, JSVAL_TO_OBJECT(vp[1]), id, &pobj, &prop))
---
>     if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &pobj, (JSProperty **) &sprop))
1644,1651c1398,1401
<     *vp = JSVAL_VOID;
<     if (prop) {
<         if (OBJ_IS_NATIVE(pobj)) {
<             sprop = (JSScopeProperty *) prop;
<             if (sprop->attrs & JSPROP_GETTER)
<                 *vp = OBJECT_TO_JSVAL(sprop->getter);
<         }
<         OBJ_DROP_PROPERTY(cx, pobj, prop);
---
>     if (sprop) {
>         if (sprop->attrs & JSPROP_GETTER)
>             *rval = OBJECT_TO_JSVAL(sprop->getter);
>         OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop);
1657c1407,1408
< obj_lookupSetter(JSContext *cx, uintN argc, jsval *vp)
---
> obj_lookupSetter(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
>                  jsval *rval)
1661d1411
<     JSProperty *prop;
1664c1414
<     if (!JS_ValueToId(cx, vp[2], &id))
---
>     if (!JS_ValueToId(cx, argv[0], &id))
1666c1416
<     if (!OBJ_LOOKUP_PROPERTY(cx, JSVAL_TO_OBJECT(vp[1]), id, &pobj, &prop))
---
>     if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &pobj, (JSProperty **) &sprop))
1668,1675c1418,1421
<     *vp = JSVAL_VOID;
<     if (prop) {
<         if (OBJ_IS_NATIVE(pobj)) {
<             sprop = (JSScopeProperty *) prop;
<             if (sprop->attrs & JSPROP_SETTER)
<                 *vp = OBJECT_TO_JSVAL(sprop->setter);
<         }
<         OBJ_DROP_PROPERTY(cx, pobj, prop);
---
>     if (sprop) {
>         if (sprop->attrs & JSPROP_SETTER)
>             *rval = OBJECT_TO_JSVAL(sprop->setter);
>         OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop);
1684a1431
> #if JS_HAS_NEW_OBJ_METHODS
1687a1435
> #endif
1697c1445
<     JS_FN(js_toSource_str,             obj_toSource, 0,0,0),
---
>     {js_toSource_str,             js_obj_toSource,    0, 0, OBJ_TOSTRING_EXTRA},
1699,1701c1447,1450
<     JS_FN(js_toString_str,             obj_toString,             0,0,0),
<     JS_FN(js_toLocaleString_str,       obj_toLocaleString,       0,0,0),
<     JS_FN(js_valueOf_str,              obj_valueOf,              0,0,0),
---
>     {js_toString_str,             js_obj_toString,    0, 0, OBJ_TOSTRING_EXTRA},
>     {js_toLocaleString_str,       js_obj_toString,    0, 0, OBJ_TOSTRING_EXTRA},
>     {js_valueOf_str,              obj_valueOf,        0,0,0},
>     {js_eval_str,                 obj_eval,           1,0,0},
1703,1704c1452,1458
<     JS_FN(js_watch_str,                obj_watch,                2,2,0),
<     JS_FN(js_unwatch_str,              obj_unwatch,              1,1,0),
---
>     {js_watch_str,                obj_watch,          2,0,0},
>     {js_unwatch_str,              obj_unwatch,        1,0,0},
> #endif
> #if JS_HAS_NEW_OBJ_METHODS
>     {js_hasOwnProperty_str,       obj_hasOwnProperty, 1,0,0},
>     {js_isPrototypeOf_str,        obj_isPrototypeOf,  1,0,0},
>     {js_propertyIsEnumerable_str, obj_propertyIsEnumerable, 1,0,0},
1706,1708d1459
<     JS_FN(js_hasOwnProperty_str,       obj_hasOwnProperty,       1,1,0),
<     JS_FN(js_isPrototypeOf_str,        obj_isPrototypeOf,        1,1,0),
<     JS_FN(js_propertyIsEnumerable_str, obj_propertyIsEnumerable, 1,1,0),
1710,1713c1461,1464
<     JS_FN(js_defineGetter_str,         obj_defineGetter,         2,2,0),
<     JS_FN(js_defineSetter_str,         obj_defineSetter,         2,2,0),
<     JS_FN(js_lookupGetter_str,         obj_lookupGetter,         1,1,0),
<     JS_FN(js_lookupSetter_str,         obj_lookupSetter,         1,1,0),
---
>     {js_defineGetter_str,         obj_defineGetter,   2,0,0},
>     {js_defineSetter_str,         obj_defineSetter,   2,0,0},
>     {js_lookupGetter_str,         obj_lookupGetter,   1,0,0},
>     {js_lookupSetter_str,         obj_lookupSetter,   1,0,0},
1715c1466
<     JS_FS_END
---
>     {0,0,0,0,0}
1746c1497,1501
<                     JSProperty **propp)
---
>                     JSProperty **propp
> #if defined JS_THREADSAFE && defined DEBUG
>                     , const char *file, uintN line
> #endif
>                     )
1850c1605
<     js_TraceObject,         js_Clear,
---
>     js_Mark,                js_Clear,
1862c1617
<     JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_IS_ANONYMOUS,
---
>     0,
1869,1870c1624,1626
< JSObject *
< js_NewWithObject(JSContext *cx, JSObject *proto, JSObject *parent, jsint depth)
---
> #if JS_HAS_OBJ_PROTO_PROP
> static JSBool
> With(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1872c1628,1629
<     JSObject *obj;
---
>     JSObject *parent, *proto;
>     jsval v;
1874,1880c1631,1637
<     obj = js_NewObject(cx, &js_WithClass, proto, parent);
<     if (!obj)
<         return NULL;
<     STOBJ_SET_SLOT(obj, JSSLOT_PRIVATE, PRIVATE_TO_JSVAL(cx->fp));
<     OBJ_SET_BLOCK_DEPTH(cx, obj, depth);
<     return obj;
< }
---
>     if (!JS_ReportErrorFlagsAndNumber(cx,
>                                       JSREPORT_WARNING | JSREPORT_STRICT,
>                                       js_GetErrorMessage, NULL,
>                                       JSMSG_DEPRECATED_USAGE,
>                                       js_WithClass.name)) {
>         return JS_FALSE;
>     }
1882,1886c1639,1644
< JSObject *
< js_NewBlockObject(JSContext *cx)
< {
<     JSObject *obj;
<     JSBool ok;
---
>     if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) {
>         obj = js_NewObject(cx, &js_WithClass, NULL, NULL);
>         if (!obj)
>             return JS_FALSE;
>         *rval = OBJECT_TO_JSVAL(obj);
>     }
1888,1902c1646,1659
<     /*
<      * Null obj's proto slot so that Object.prototype.* does not pollute block
<      * scopes.  Make sure obj has its own scope too, since clearing proto does
<      * not affect OBJ_SCOPE(obj).
<      */
<     obj = js_NewObject(cx, &js_BlockClass, NULL, NULL);
<     if (!obj)
<         return NULL;
<     JS_LOCK_OBJ(cx, obj);
<     ok = js_GetMutableScope(cx, obj) != NULL;
<     JS_UNLOCK_OBJ(cx, obj);
<     if (!ok)
<         return NULL;
<     OBJ_SET_PROTO(cx, obj, NULL);
<     return obj;
---
>     parent = cx->fp->scopeChain;
>     if (argc > 0) {
>         if (!js_ValueToObject(cx, argv[0], &proto))
>             return JS_FALSE;
>         v = OBJECT_TO_JSVAL(proto);
>         if (!obj_setSlot(cx, obj, INT_TO_JSVAL(JSSLOT_PROTO), &v))
>             return JS_FALSE;
>         if (argc > 1) {
>             if (!js_ValueToObject(cx, argv[1], &parent))
>                 return JS_FALSE;
>         }
>     }
>     v = OBJECT_TO_JSVAL(parent);
>     return obj_setSlot(cx, obj, INT_TO_JSVAL(JSSLOT_PARENT), &v);
1903a1661
> #endif
1906,1907c1664
< js_CloneBlockObject(JSContext *cx, JSObject *proto, JSObject *parent,
<                     JSStackFrame *fp)
---
> js_InitObjectClass(JSContext *cx, JSObject *obj)
1909c1666,1667
<     JSObject *clone;
---
>     JSObject *proto;
>     jsval eval;
1911,1912c1669,1675
<     clone = js_NewObject(cx, &js_BlockClass, proto, parent);
<     if (!clone)
---
> #if JS_HAS_SHARP_VARS
>     JS_ASSERT(sizeof(jsatomid) * JS_BITS_PER_BYTE >= ATOM_INDEX_LIMIT_LOG2 + 1);
> #endif
> 
>     proto = JS_InitClass(cx, obj, NULL, &js_ObjectClass, Object, 1,
>                          object_props, object_methods, NULL, NULL);
>     if (!proto)
1914,1918d1676
<     STOBJ_SET_SLOT(clone, JSSLOT_PRIVATE, PRIVATE_TO_JSVAL(fp));
<     STOBJ_SET_SLOT(clone, JSSLOT_BLOCK_DEPTH,
<                    OBJ_GET_SLOT(cx, proto, JSSLOT_BLOCK_DEPTH));
<     return clone;
< }
1920,2122c1678,1681
< /*
<  * XXXblock this reverses a path in the property tree -- try to share
<  *          the prototype's scope harder!
<  */
< JSBool
< js_PutBlockObject(JSContext *cx, JSObject *obj)
< {
<     JSStackFrame *fp;
<     uintN depth, slot;
<     JSScopeProperty *sprop;
< 
<     fp = (JSStackFrame *) JS_GetPrivate(cx, obj);
<     JS_ASSERT(fp);
<     depth = OBJ_BLOCK_DEPTH(cx, obj);
<     for (sprop = OBJ_SCOPE(obj)->lastProp; sprop; sprop = sprop->parent) {
<         if (sprop->getter != js_BlockClass.getProperty)
<             continue;
<         if (!(sprop->flags & SPROP_HAS_SHORTID))
<             continue;
<         slot = depth + (uintN)sprop->shortid;
<         JS_ASSERT(slot < fp->script->depth);
<         if (!js_DefineNativeProperty(cx, obj, sprop->id,
<                                      fp->spbase[slot], NULL, NULL,
<                                      JSPROP_ENUMERATE | JSPROP_PERMANENT,
<                                      SPROP_HAS_SHORTID, sprop->shortid,
<                                      NULL)) {
<             JS_SetPrivate(cx, obj, NULL);
<             return JS_FALSE;
<         }
<     }
< 
<     return JS_SetPrivate(cx, obj, NULL);
< }
< 
< static JSBool
< block_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
< {
<     JSStackFrame *fp;
<     jsint slot;
< 
<     JS_ASSERT(JS_InstanceOf(cx, obj, &js_BlockClass, NULL));
<     if (!JSVAL_IS_INT(id))
<         return JS_TRUE;
< 
<     fp = (JSStackFrame *) JS_GetPrivate(cx, obj);
<     if (!fp)
<         return JS_TRUE;
< 
<     slot = OBJ_BLOCK_DEPTH(cx, obj) + (uint16) JSVAL_TO_INT(id);
<     JS_ASSERT((uintN)slot < fp->script->depth);
<     *vp = fp->spbase[slot];
<     return JS_TRUE;
< }
< 
< static JSBool
< block_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
< {
<     JSStackFrame *fp;
<     jsint slot;
< 
<     JS_ASSERT(JS_InstanceOf(cx, obj, &js_BlockClass, NULL));
<     if (!JSVAL_IS_INT(id))
<         return JS_TRUE;
< 
<     fp = (JSStackFrame *) JS_GetPrivate(cx, obj);
<     if (!fp)
<         return JS_TRUE;
< 
<     slot = OBJ_BLOCK_DEPTH(cx, obj) + (uint16) JSVAL_TO_INT(id);
<     JS_ASSERT((uintN)slot < fp->script->depth);
<     fp->spbase[slot] = *vp;
<     return JS_TRUE;
< }
< 
< #if JS_HAS_XDR
< 
< #define NO_PARENT_INDEX ((uint32)-1)
< 
< uint32
< FindObjectIndex(JSObjectArray *array, JSObject *obj)
< {
<     size_t i;
< 
<     if (array) {
<         i = array->length;
<         do {
< 
<             if (array->vector[--i] == obj)
<                 return i;
<         } while (i != 0);
<     }
< 
<     return NO_PARENT_INDEX;
< }
< 
< static JSBool
< block_xdrObject(JSXDRState *xdr, JSObject **objp)
< {
<     JSContext *cx;
<     uint32 parentId;
<     JSObject *obj, *parent;
<     uint16 depth, count, i;
<     uint32 tmp;
<     JSTempValueRooter tvr;
<     JSScopeProperty *sprop;
<     jsid propid;
<     JSAtom *atom;
<     int16 shortid;
<     JSBool ok;
< 
<     cx = xdr->cx;
< #ifdef __GNUC__
<     obj = NULL;         /* quell GCC overwarning */
< #endif
< 
<     if (xdr->mode == JSXDR_ENCODE) {
<         obj = *objp;
<         parent = OBJ_GET_PARENT(cx, obj);
<         parentId = (xdr->script->objectsOffset == 0)
<                    ? NO_PARENT_INDEX
<                    : FindObjectIndex(JS_SCRIPT_OBJECTS(xdr->script), parent);
<         depth = (uint16)OBJ_BLOCK_DEPTH(cx, obj);
<         count = (uint16)OBJ_BLOCK_COUNT(cx, obj);
<         tmp = (uint32)(depth << 16) | count;
<     }
< #ifdef __GNUC__ /* suppress bogus gcc warnings */
<     else count = 0;
< #endif
< 
<     /* First, XDR the parent atomid. */
<     if (!JS_XDRUint32(xdr, &parentId))
<         return JS_FALSE;
< 
<     if (xdr->mode == JSXDR_DECODE) {
<         obj = js_NewBlockObject(cx);
<         if (!obj)
<             return JS_FALSE;
<         *objp = obj;
< 
<         /*
<          * If there's a parent id, then get the parent out of our script's
<          * object array. We know that we XDR block object in outer-to-inner
<          * order, which means that getting the parent now will work.
<          */
<         if (parentId == NO_PARENT_INDEX)
<             parent = NULL;
<         else
<             JS_GET_SCRIPT_OBJECT(xdr->script, parentId, parent);
<         STOBJ_SET_PARENT(obj, parent);
<     }
< 
<     JS_PUSH_SINGLE_TEMP_ROOT(cx, OBJECT_TO_JSVAL(obj), &tvr);
< 
<     if (!JS_XDRUint32(xdr, &tmp)) {
<         JS_POP_TEMP_ROOT(cx, &tvr);
<         return JS_FALSE;
<     }
< 
<     if (xdr->mode == JSXDR_DECODE) {
<         depth = (uint16)(tmp >> 16);
<         count = (uint16)tmp;
<         STOBJ_SET_SLOT(obj, JSSLOT_BLOCK_DEPTH, INT_TO_JSVAL(depth));
<     }
< 
<     /*
<      * XDR the block object's properties. We know that there are 'count'
<      * properties to XDR, stored as id/shortid pairs. We do not XDR any
<      * non-native properties, only those that the compiler created.
<      */
<     sprop = NULL;
<     ok = JS_TRUE;
<     for (i = 0; i < count; i++) {
<         if (xdr->mode == JSXDR_ENCODE) {
<             /* Find a property to XDR. */
<             do {
<                 /* If sprop is NULL, this is the first property. */
<                 sprop = sprop ? sprop->parent : OBJ_SCOPE(obj)->lastProp;
<             } while (!(sprop->flags & SPROP_HAS_SHORTID));
< 
<             JS_ASSERT(sprop->getter == js_BlockClass.getProperty);
<             propid = sprop->id;
<             JS_ASSERT(JSID_IS_ATOM(propid));
<             atom = JSID_TO_ATOM(propid);
<             shortid = sprop->shortid;
<             JS_ASSERT(shortid >= 0);
<         }
< 
<         /* XDR the real id, then the shortid. */
<         if (!js_XDRStringAtom(xdr, &atom) ||
<             !JS_XDRUint16(xdr, (uint16 *)&shortid)) {
<             ok = JS_FALSE;
<             break;
<         }
< 
<         if (xdr->mode == JSXDR_DECODE) {
<             if (!js_DefineNativeProperty(cx, obj, ATOM_TO_JSID(atom),
<                                          JSVAL_VOID, NULL, NULL,
<                                          JSPROP_ENUMERATE | JSPROP_PERMANENT,
<                                          SPROP_HAS_SHORTID, shortid, NULL)) {
<                 ok = JS_FALSE;
<                 break;
<             }
<         }
---
> #if JS_HAS_OBJ_PROTO_PROP
>     if (!JS_InitClass(cx, obj, NULL, &js_WithClass, With, 0,
>                       NULL, NULL, NULL, NULL)) {
>         return NULL;
2124,2130d1682
< 
<     JS_POP_TEMP_ROOT(cx, &tvr);
<     return ok;
< }
< 
< #else
< # define block_xdrObject NULL
2133,2163c1685,1687
< JSClass js_BlockClass = {
<     "Block",
<     JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(1) |
<     JSCLASS_IS_ANONYMOUS | JSCLASS_HAS_CACHED_PROTO(JSProto_Block),
<     JS_PropertyStub,  JS_PropertyStub,  block_getProperty, block_setProperty,
<     JS_EnumerateStub, JS_ResolveStub,   JS_ConvertStub,    JS_FinalizeStub,
<     NULL, NULL, NULL, NULL, block_xdrObject, NULL, NULL, NULL
< };
< 
< JSObject*
< js_InitBlockClass(JSContext *cx, JSObject* obj)
< {
<     JSObject *proto;
< 
<     proto = JS_InitClass(cx, obj, NULL, &js_BlockClass, NULL, 0, NULL,
<                          NULL, NULL, NULL);
<     if (!proto)
<         return NULL;
< 
<     OBJ_SET_PROTO(cx, proto, NULL);
<     return proto;
< }
< 
< JSObject *
< js_InitObjectClass(JSContext *cx, JSObject *obj)
< {
<     JSObject *proto;
< 
<     proto = JS_InitClass(cx, obj, NULL, &js_ObjectClass, Object, 1,
<                          object_props, object_methods, NULL, NULL);
<     if (!proto)
---
>     /* ECMA (15.1.2.1) says 'eval' is also a property of the global object. */
>     if (!OBJ_GET_PROPERTY(cx, proto, (jsid)cx->runtime->atomState.evalAtom,
>                           &eval)) {
2165,2168c1689,1691
< 
<     /* ECMA (15.1.2.1) says 'eval' is a property of the global object. */
<     if (!js_DefineFunction(cx, obj, cx->runtime->atomState.evalAtom,
<                            obj_eval, 1, 0)) {
---
>     }
>     if (!OBJ_DEFINE_PROPERTY(cx, obj, (jsid)cx->runtime->atomState.evalAtom,
>                              eval, NULL, NULL, 0, NULL)) {
2180a1704
>     map->nslots = JS_INITIAL_NSLOTS;
2219,2234d1742
< static void
< FreeSlots(JSContext *cx, JSObject *obj)
< {
<     if (obj->dslots) {
<         JS_ASSERT((uint32)obj->dslots[-1] > JS_INITIAL_NSLOTS);
<         JS_free(cx, obj->dslots - 1);
<         obj->dslots = NULL;
<     }
< }
< 
< #define SLOTS_TO_DYNAMIC_WORDS(nslots)                                        \
<   (JS_ASSERT((nslots) > JS_INITIAL_NSLOTS), (nslots) + 1 - JS_INITIAL_NSLOTS)
< 
< #define DYNAMIC_WORDS_TO_SLOTS(words)                                         \
<   (JS_ASSERT((words) > 1), (words) - 1 + JS_INITIAL_NSLOTS)
< 
2236,2374c1744,1745
< ReallocSlots(JSContext *cx, JSObject *obj, uint32 nslots,
<              JSBool exactAllocation)
< {
<     jsval *old, *slots;
<     uint32 oslots, nwords, owords, log, i;
< 
<     /*
<      * Minimal number of dynamic slots to allocate.
<      */
< #define MIN_DYNAMIC_WORDS 4
< 
<     /*
<      * The limit to switch to linear allocation strategy from the power of 2
<      * growth no to waste too much memory.
<      */
< #define LINEAR_GROWTH_STEP JS_BIT(16)
< 
<     old = obj->dslots;
<     if (nslots <= JS_INITIAL_NSLOTS) {
<         if (old &&
<             (exactAllocation ||
<              SLOTS_TO_DYNAMIC_WORDS((uint32)old[-1]) != MIN_DYNAMIC_WORDS ||
<              nslots <= (JS_INITIAL_NSLOTS +
<                         JSSLOT_FREE(STOBJ_GET_CLASS(obj))) / 2)) {
<             /*
<              * We do not want to free dynamic slots when allocation is a hint,
<              * we reached minimal allocation and almost all fixed slots are
<              * used. It avoids allocating dynamic slots again when properties
<              * are added to the object.
<              *
<              * If there were no private or reserved slots, the condition to
<              * free the slots would be
<              *
<              *   nslots <= JS_INITIAL_NSLOTS / 2
<              *
<              * but to account for never removed slots before JSSLOT_FREE(class)
<              * we need to subtract it from the slot counts which gives
<              *
<              *   nslots - JSSLOT_FREE <= (JS_INITIAL_NSLOTS - JSSLOT_FREE) / 2
<              *
<              * or
<              *
<              *   nslots <= (JS_INITIAL_NSLOTS + JSSLOT_FREE) / 2
<              */
<             FreeSlots(cx, obj);
<         }
<         return JS_TRUE;
<     }
< 
<     oslots = (old) ? (uint32)*--old : JS_INITIAL_NSLOTS;
<     nwords = SLOTS_TO_DYNAMIC_WORDS(nslots);
< 
<     if (nslots > oslots) {
<         if (!exactAllocation) {
<             /*
<              * Round up nslots so the number of bytes in dslots array is power
<              * of 2 to ensure exponential grouth.
<              */
<             if (nwords <= MIN_DYNAMIC_WORDS) {
<                 nwords = MIN_DYNAMIC_WORDS;
<             } else if (nwords < LINEAR_GROWTH_STEP) {
<                 JS_CEILING_LOG2(log, nwords);
<                 nwords = JS_BIT(log);
<             } else {
<                 nwords = JS_ROUNDUP(nwords, LINEAR_GROWTH_STEP);
<             }
<         }
<         slots = (jsval *)JS_realloc(cx, old, nwords * sizeof(jsval));
<         if (!slots)
<             return JS_FALSE;
<     } else {
<         JS_ASSERT(nslots < oslots);
<         if (!exactAllocation) {
<             owords = DYNAMIC_WORDS_TO_SLOTS(oslots);
<             if (owords <= MIN_DYNAMIC_WORDS)
<                 return JS_TRUE;
<             if (owords < LINEAR_GROWTH_STEP * 2) {
<                 /*
<                  * Shrink only if 1/4 of slots are left and we need to grow
<                  * the array at least twice to reach the current capacity. It
<                  * prevents frequent capacity growth/shrinking when slots are
<                  * often removed and added.
<                  */
<                 if (nwords > owords / 4)
<                     return JS_TRUE;
<                 JS_CEILING_LOG2(log, nwords);
<                 nwords = JS_BIT(log);
<                 if (nwords < MIN_DYNAMIC_WORDS)
<                     nwords = MIN_DYNAMIC_WORDS;
<             } else {
<                 /*
<                  * Shrink only if we free at least 2 linear allocation
<                  * segments, to prevent growth/shrinking resonance.
<                  */
<                 if (nwords > owords - LINEAR_GROWTH_STEP * 2)
<                     return JS_TRUE;
<                 nwords = JS_ROUNDUP(nwords, LINEAR_GROWTH_STEP);
<             }
<         }
< 
<         /* We avoid JS_realloc not to report a failed shrink attempt. */
<         slots = (jsval *)realloc(old, nwords * sizeof(jsval));
<         if (!slots)
<             slots = old;
<     }
< 
<     nslots = DYNAMIC_WORDS_TO_SLOTS(nwords);
<     *slots++ = (jsval)nslots;
<     obj->dslots = slots;
< 
<     /* If we're extending an allocation, initialize free slots. */
<     for (i = oslots; i < nslots; i++)
<         slots[i - JS_INITIAL_NSLOTS] = JSVAL_VOID;
< 
<     return JS_TRUE;
< 
< #undef LINEAR_GROWTH_STEP
< #undef MIN_DYNAMIC_WORDS
< }
< 
< extern JSBool
< js_GetClassId(JSContext *cx, JSClass *clasp, jsid *idp)
< {
<     JSProtoKey key;
<     JSAtom *atom;
< 
<     key = JSCLASS_CACHED_PROTO_KEY(clasp);
<     if (key != JSProto_Null) {
<         *idp = INT_TO_JSID(key);
<     } else if (clasp->flags & JSCLASS_IS_ANONYMOUS) {
<         *idp = INT_TO_JSID(JSProto_Object);
<     } else {
<         atom = js_Atomize(cx, clasp->name, strlen(clasp->name), 0);
<         if (!atom)
<             return JS_FALSE;
<         *idp = ATOM_TO_JSID(atom);
<     }
<     return JS_TRUE;
< }
---
> GetClassPrototype(JSContext *cx, JSObject *scope, const char *name,
>                   JSObject **protop);
2379,2401c1750
<     jsid id;
< 
<     /* Bootstrap the ur-object, and make it the default prototype object. */
<     if (!proto) {
<         if (!js_GetClassId(cx, clasp, &id))
<             return NULL;
<         if (!js_GetClassPrototype(cx, parent, id, &proto))
<             return NULL;
<         if (!proto &&
<             !js_GetClassPrototype(cx, parent, INT_TO_JSID(JSProto_Object),
<                                   &proto)) {
<             return NULL;
<         }
<     }
< 
<     return js_NewObjectWithGivenProto(cx, clasp, proto, parent);
< }
< 
< JSObject *
< js_NewObjectWithGivenProto(JSContext *cx, JSClass *clasp, JSObject *proto,
<                            JSObject *parent)
< {
<     JSObject *obj;
---
>     JSObject *obj, *ctor;
2404c1753
<     JSClass *protoclasp;
---
>     jsval cval;
2406c1755
<     JSTempValueRooter tvr;
---
>     jsval *newslots;
2408,2411c1757,1768
< #ifdef INCLUDE_MOZILLA_DTRACE
<     if (JAVASCRIPT_OBJECT_CREATE_START_ENABLED())
<         jsdtrace_object_create_start(cx->fp, clasp);
< #endif
---
>     /* Allocate an object from the GC heap and zero it. */
>     obj = (JSObject *) js_AllocGCThing(cx, GCX_OBJECT);
>     if (!obj)
>         return NULL;
> 
>     /* Bootstrap the ur-object, and make it the default prototype object. */
>     if (!proto) {
>         if (!GetClassPrototype(cx, parent, clasp->name, &proto))
>             goto bad;
>         if (!proto && !GetClassPrototype(cx, parent, js_Object_str, &proto))
>             goto bad;
>     }
2419,2457d1775
<      * Allocate a zeroed object from the GC heap.  Do this *after* any other
<      * GC-thing allocations under js_GetClassPrototype or clasp->getObjectOps,
<      * to avoid displacing the newborn root for obj.
<      */
<     obj = (JSObject *) js_NewGCThing(cx, GCX_OBJECT, sizeof(JSObject));
<     if (!obj)
<         goto earlybad;
< 
<     /*
<      * Initialize all JSObject fields before doing any operation that can
<      * potentially trigger GC.
<      */
<     obj->map = NULL;
<     obj->dslots = NULL;
< 
<     /* Set the proto and parent properties. */
<     STOBJ_SET_PROTO(obj, proto);
<     STOBJ_SET_PARENT(obj, parent);
< 
<     /*
<      * Set the class slot with the initial value of the system flag set to
<      * false.
<      */
<     JS_ASSERT(((jsuword) clasp & 3) == 0);
<     STOBJ_SET_SLOT(obj, JSSLOT_CLASS, PRIVATE_TO_JSVAL(clasp));
<     JS_ASSERT(!STOBJ_IS_SYSTEM(obj));
< 
<     /* Initialize the remaining fixed slots. */
<     for (i = JSSLOT_PRIVATE; i != JS_INITIAL_NSLOTS; ++i)
<         obj->fslots[i] = JSVAL_VOID;
< 
<     /*
<      * Root obj to prevent it from being collected out from under this call to
<      * js_NewObject. There's a possibilty of GC under the objectHook call-out
<      * further below.
<      */
<     JS_PUSH_TEMP_ROOT_OBJECT(cx, obj, &tvr);
< 
<     /*
2459,2463c1777,1778
<      * proto's class has the same private and reserved slots as obj's map
<      * and class have.  We assume that if prototype and object are of the
<      * same class, they always have the same number of computed reserved
<      * slots (returned via clasp->reserveSlots); otherwise, prototype and
<      * object classes must have the same (null or not) reserveSlots hook.
---
>      * proto's class has the same private and reserved slots, as obj's map
>      * and class have.
2467,2478c1782,1795
<         ((protoclasp = OBJ_GET_CLASS(cx, proto)) == clasp ||
<          (!((protoclasp->flags ^ clasp->flags) &
<             (JSCLASS_HAS_PRIVATE |
<              (JSCLASS_RESERVED_SLOTS_MASK << JSCLASS_RESERVED_SLOTS_SHIFT))) &&
<           protoclasp->reserveSlots == clasp->reserveSlots)))
<     {
<         /*
<          * Default parent to the parent of the prototype, which was set from
<          * the parent of the prototype's constructor.
<          */
<         if (!parent)
<             STOBJ_SET_PARENT(obj, OBJ_GET_PARENT(cx, proto));
---
>         ((clasp->flags ^ OBJ_GET_CLASS(cx, proto)->flags) &
>          (JSCLASS_HAS_PRIVATE |
>           (JSCLASS_RESERVED_SLOTS_MASK << JSCLASS_RESERVED_SLOTS_SHIFT)))
>         == 0) {
>         /* Default parent to the parent of the prototype's constructor. */
>         if (!parent) {
>             if (!OBJ_GET_PROPERTY(cx, proto,
>                                   (jsid)cx->runtime->atomState.constructorAtom,
>                                   &cval)) {
>                 goto bad;
>             }
>             if (JSVAL_IS_OBJECT(cval) && (ctor = JSVAL_TO_OBJECT(cval)) != NULL)
>                 parent = OBJ_GET_PARENT(cx, ctor);
>         }
2481a1799,1801
> 
>         /* Ensure that obj starts with the minimum slots for clasp. */
>         nslots = JS_INITIAL_NSLOTS;
2489,2497c1809,1810
<         /* Let ops->newObjectMap set freeslot so as to reserve slots. */
<         nslots = map->freeslot;
<         JS_ASSERT(nslots >= JSSLOT_PRIVATE);
<         if (nslots > JS_INITIAL_NSLOTS &&
<             !ReallocSlots(cx, obj, nslots, JS_TRUE)) {
<             js_DropObjectMap(cx, map, obj);
<             obj->map = NULL;
<             goto bad;
<         }
---
>         /* Let ops->newObjectMap set nslots so as to reserve slots. */
>         nslots = map->nslots;
2500,2504c1813,1819
<     if (cx->debugHooks->objectHook) {
<         JS_KEEP_ATOMS(cx->runtime);
<         cx->debugHooks->objectHook(cx, obj, JS_TRUE,
<                                    cx->debugHooks->objectHookData);
<         JS_UNKEEP_ATOMS(cx->runtime);
---
>     /* Allocate a slots vector, with a -1'st element telling its length. */
>     XMEMTAG("js_NewObject newslots ");
>     newslots = (jsval *) JS_malloc(cx, (nslots + 1) * sizeof(jsval));
>     if (!newslots) {
>         js_DropObjectMap(cx, obj->map, obj);
>         obj->map = NULL;
>         goto bad;
2505a1821,1822
>     newslots[0] = nslots;
>     newslots++;
2507,2516c1824,1831
< out:
<     JS_POP_TEMP_ROOT(cx, &tvr);
<     cx->weakRoots.newborn[GCX_OBJECT] = obj;
< #ifdef INCLUDE_MOZILLA_DTRACE
<     if (JAVASCRIPT_OBJECT_CREATE_ENABLED())
<         jsdtrace_object_create(cx, clasp, obj);
<     if (JAVASCRIPT_OBJECT_CREATE_DONE_ENABLED())
<         jsdtrace_object_create_done(cx->fp, clasp);
< #endif
<     return obj;
---
>     /* Set the proto, parent, and class properties. */
>     newslots[JSSLOT_PROTO] = OBJECT_TO_JSVAL(proto);
>     newslots[JSSLOT_PARENT] = OBJECT_TO_JSVAL(parent);
>     newslots[JSSLOT_CLASS] = PRIVATE_TO_JSVAL(clasp);
> 
>     /* Clear above JSSLOT_CLASS so the GC doesn't load uninitialized memory. */
>     for (i = JSSLOT_CLASS + 1; i < nslots; i++)
>         newslots[i] = JSVAL_VOID;
2518,2520c1833,1834
< bad:
<     obj = NULL;
<     goto out;
---
>     /* Store newslots after initializing all of 'em, just in case. */
>     obj->slots = newslots;
2522,2530c1836,1837
< earlybad:
< #ifdef INCLUDE_MOZILLA_DTRACE
<     if (JAVASCRIPT_OBJECT_CREATE_ENABLED())
<         jsdtrace_object_create(cx, clasp, NULL);
<     if (JAVASCRIPT_OBJECT_CREATE_DONE_ENABLED())
<         jsdtrace_object_create_done(cx->fp, clasp);
< #endif
<     return NULL;
< }
---
>     if (cx->runtime->objectHook)
>         cx->runtime->objectHook(cx, obj, JS_TRUE, cx->runtime->objectHookData);
2532c1839
< JS_BEGIN_EXTERN_C
---
>     return obj;
2534,2537c1841,1842
< JS_STATIC_DLL_CALLBACK(JSObject *)
< js_InitNullClass(JSContext *cx, JSObject *obj)
< {
<     JS_ASSERT(0);
---
> bad:
>     cx->newborn[GCX_OBJECT] = NULL;
2541,2555c1846,1847
< #define JS_PROTO(name,code,init) extern JSObject *init(JSContext *, JSObject *);
< #include "jsproto.tbl"
< #undef JS_PROTO
< 
< static JSObjectOp lazy_prototype_init[JSProto_LIMIT] = {
< #define JS_PROTO(name,code,init) init,
< #include "jsproto.tbl"
< #undef JS_PROTO
< };
< 
< JS_END_EXTERN_C
< 
< JSBool
< js_GetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key,
<                   JSObject **objp)
---
> static JSBool
> FindConstructor(JSContext *cx, JSObject *scope, const char *name, jsval *vp)
2557,2570c1849,1852
<     JSBool ok;
<     JSObject *tmp, *cobj;
<     JSResolvingKey rkey;
<     JSResolvingEntry *rentry;
<     uint32 generation;
<     JSObjectOp init;
<     jsval v;
< 
<     while ((tmp = OBJ_GET_PARENT(cx, obj)) != NULL)
<         obj = tmp;
<     if (!(OBJ_GET_CLASS(cx, obj)->flags & JSCLASS_IS_GLOBAL)) {
<         *objp = NULL;
<         return JS_TRUE;
<     }
---
>     JSAtom *atom;
>     JSObject *obj;
>     JSObject *pobj;
>     JSScopeProperty *sprop;
2572,2573c1854,1855
<     ok = JS_GetReservedSlot(cx, obj, key, &v);
<     if (!ok)
---
>     atom = js_Atomize(cx, name, strlen(name), 0);
>     if (!atom)
2575,2578d1856
<     if (!JSVAL_IS_PRIMITIVE(v)) {
<         *objp = JSVAL_TO_OBJECT(v);
<         return JS_TRUE;
<     }
2580,2627c1858
<     rkey.obj = obj;
<     rkey.id = ATOM_TO_JSID(cx->runtime->atomState.classAtoms[key]);
<     if (!js_StartResolving(cx, &rkey, JSRESFLAG_LOOKUP, &rentry))
<         return JS_FALSE;
<     if (!rentry) {
<         /* Already caching key in obj -- suppress recursion. */
<         *objp = NULL;
<         return JS_TRUE;
<     }
<     generation = cx->resolvingTable->generation;
< 
<     cobj = NULL;
<     init = lazy_prototype_init[key];
<     if (init) {
<         if (!init(cx, obj)) {
<             ok = JS_FALSE;
<         } else {
<             ok = JS_GetReservedSlot(cx, obj, key, &v);
<             if (ok && !JSVAL_IS_PRIMITIVE(v))
<                 cobj = JSVAL_TO_OBJECT(v);
<         }
<     }
< 
<     js_StopResolving(cx, &rkey, JSRESFLAG_LOOKUP, rentry, generation);
<     *objp = cobj;
<     return ok;
< }
< 
< JSBool
< js_SetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key, JSObject *cobj)
< {
<     JS_ASSERT(!OBJ_GET_PARENT(cx, obj));
<     if (!(OBJ_GET_CLASS(cx, obj)->flags & JSCLASS_IS_GLOBAL))
<         return JS_TRUE;
< 
<     return JS_SetReservedSlot(cx, obj, key, OBJECT_TO_JSVAL(cobj));
< }
< 
< JSBool
< js_FindClassObject(JSContext *cx, JSObject *start, jsid id, jsval *vp)
< {
<     JSObject *obj, *cobj, *pobj;
<     JSProtoKey key;
<     JSProperty *prop;
<     jsval v;
<     JSScopeProperty *sprop;
< 
<     if (start || (cx->fp && (start = cx->fp->scopeChain) != NULL)) {
---
>     if (scope || (cx->fp && (scope = cx->fp->scopeChain) != NULL)) {
2630,2632c1861,1863
<             obj = start;
<             start = OBJ_GET_PARENT(cx, obj);
<         } while (start);
---
>             obj = scope;
>             scope = OBJ_GET_PARENT(cx, obj);
>         } while (scope);
2641,2642c1872
<     OBJ_TO_INNER_OBJECT(cx, obj);
<     if (!obj)
---
>     if (!OBJ_LOOKUP_PROPERTY(cx, obj, (jsid)atom, &pobj, (JSProperty**)&sprop))
2644,2654c1874,1876
< 
<     if (JSID_IS_INT(id)) {
<         key = (JSProtoKey) JSID_TO_INT(id);
<         JS_ASSERT(key != JSProto_Null);
<         if (!js_GetClassObject(cx, obj, key, &cobj))
<             return JS_FALSE;
<         if (cobj) {
<             *vp = OBJECT_TO_JSVAL(cobj);
<             return JS_TRUE;
<         }
<         id = ATOM_TO_JSID(cx->runtime->atomState.classAtoms[key]);
---
>     if (!sprop)  {
>         *vp = JSVAL_VOID;
>         return JS_TRUE;
2657,2674c1879,1882
<     JS_ASSERT(OBJ_IS_NATIVE(obj));
<     if (js_LookupPropertyWithFlags(cx, obj, id, JSRESOLVE_CLASSNAME,
<                                    &pobj, &prop) < 0) {
<         return JS_FALSE;
<     }
<     v = JSVAL_VOID;
<     if (prop)  {
<         if (OBJ_IS_NATIVE(pobj)) {
<             sprop = (JSScopeProperty *) prop;
<             if (SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(pobj))) {
<                 v = LOCKED_OBJ_GET_SLOT(pobj, sprop->slot);
<                 if (JSVAL_IS_PRIMITIVE(v))
<                     v = JSVAL_VOID;
<             }
<         }
<         OBJ_DROP_PROPERTY(cx, pobj, prop);
<     }
<     *vp = v;
---
>     JS_ASSERT(OBJ_IS_NATIVE(pobj));
>     JS_ASSERT(SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(pobj)));
>     *vp = OBJ_GET_SLOT(cx, pobj, sprop->slot);
>     OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop);
2682d1889
<     jsid id;
2684d1890
<     JSTempValueRooter argtvr, tvr;
2687,2691c1893
<     JS_PUSH_TEMP_ROOT(cx, argc, argv, &argtvr);
< 
<     if (!js_GetClassId(cx, clasp, &id) ||
<         !js_FindClassObject(cx, parent, id, &cval)) {
<         JS_POP_TEMP_ROOT(cx, &argtvr);
---
>     if (!FindConstructor(cx, parent, clasp->name, &cval))
2693,2694d1894
<     }
< 
2696,2697c1896
<         js_ReportIsNotFunction(cx, &cval, JSV2F_CONSTRUCT | JSV2F_SEARCH_STACK);
<         JS_POP_TEMP_ROOT(cx, &argtvr);
---
>         js_ReportIsNotFunction(cx, &cval, JS_TRUE);
2702,2707d1900
<      * Protect cval in case a crazy getter for .prototype uproots it.  After
<      * this point, all control flow must exit through label out with obj set.
<      */
<     JS_PUSH_SINGLE_TEMP_ROOT(cx, cval, &tvr);
< 
<     /*
2716,2717c1909
<                               ATOM_TO_JSID(cx->runtime->atomState
<                                            .classPrototypeAtom),
---
>                               (jsid)cx->runtime->atomState.classPrototypeAtom,
2719,2720c1911
<             obj = NULL;
<             goto out;
---
>             return NULL;
2728c1919
<         goto out;
---
>         return NULL;
2732,2757c1923
< 
<     if (JSVAL_IS_PRIMITIVE(rval))
<         goto out;
<     obj = JSVAL_TO_OBJECT(rval);
< 
<     /*
<      * If the instance's class differs from what was requested, throw a type
<      * error.  If the given class has both the JSCLASS_HAS_PRIVATE and the
<      * JSCLASS_CONSTRUCT_PROTOTYPE flags, and the instance does not have its
<      * private data set at this point, then the constructor was replaced and
<      * we should throw a type error.
<      */
<     if (OBJ_GET_CLASS(cx, obj) != clasp ||
<         (!(~clasp->flags & (JSCLASS_HAS_PRIVATE |
<                             JSCLASS_CONSTRUCT_PROTOTYPE)) &&
<          !JS_GetPrivate(cx, obj))) {
<         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
<                              JSMSG_WRONG_CONSTRUCTOR, clasp->name);
<         goto bad;
<     }
< 
< out:
<     JS_POP_TEMP_ROOT(cx, &tvr);
<     JS_POP_TEMP_ROOT(cx, &argtvr);
<     return obj;
< 
---
>     return JSVAL_IS_OBJECT(rval) ? JSVAL_TO_OBJECT(rval) : obj;
2759,2761c1925,1926
<     cx->weakRoots.newborn[GCX_OBJECT] = NULL;
<     obj = NULL;
<     goto out;
---
>     cx->newborn[GCX_OBJECT] = NULL;
>     return NULL;
2772a1938
>     JS_ASSERT(obj->slots);
2774,2777c1940,1941
<     if (cx->debugHooks->objectHook) {
<         cx->debugHooks->objectHook(cx, obj, JS_FALSE,
<                                    cx->debugHooks->objectHookData);
<     }
---
>     if (cx->runtime->objectHook)
>         cx->runtime->objectHook(cx, obj, JS_FALSE, cx->runtime->objectHookData);
2779,2780c1943,1944
<     /* Finalize obj first, in case it needs map and slots. */
<     STOBJ_GET_CLASS(obj)->finalize(cx, obj);
---
>     /* Remove all watchpoints with weak links to obj. */
>     JS_ClearWatchPointsForObject(cx, obj);
2782,2785c1946,1954
< #ifdef INCLUDE_MOZILLA_DTRACE
<     if (JAVASCRIPT_OBJECT_FINALIZE_ENABLED())
<         jsdtrace_object_finalize(obj);
< #endif
---
>     /*
>      * Finalize obj first, in case it needs map and slots.  Optimized to use
>      * LOCKED_OBJ_GET_CLASS instead of OBJ_GET_CLASS, so we avoid "promoting"
>      * obj's scope from lock-free to lock-full (see jslock.c:ClaimScope) when
>      * we're called from the GC.  Only the GC should call js_FinalizeObject,
>      * and no other threads run JS (and possibly racing to update obj->slots)
>      * while the GC is running.
>      */
>     LOCKED_OBJ_GET_CLASS(obj)->finalize(cx, obj);
2789c1958,1960
<     FreeSlots(cx, obj);
---
>     obj->map = NULL;
>     JS_free(cx, obj->slots - 1);
>     obj->slots = NULL;
2798c1969,1971
<     JSClass *clasp;
---
>     uint32 nslots, i;
>     size_t nbytes;
>     jsval *newslots;
2802,2806c1975,1979
<     clasp = LOCKED_OBJ_GET_CLASS(obj);
<     if (map->freeslot == JSSLOT_FREE(clasp) && clasp->reserveSlots) {
<         /* Adjust map->freeslot to include computed reserved slots, if any. */
<         map->freeslot += clasp->reserveSlots(cx, obj);
<     }
---
>     nslots = map->nslots;
>     if (map->freeslot >= nslots) {
>         nslots = map->freeslot;
>         JS_ASSERT(nslots >= JS_INITIAL_NSLOTS);
>         nslots += (nslots + 1) / 2;
2808,2810c1981,1995
<     if (map->freeslot >= STOBJ_NSLOTS(obj) &&
<         !ReallocSlots(cx, obj, map->freeslot + 1, JS_FALSE)) {
<         return JS_FALSE;
---
>         nbytes = (nslots + 1) * sizeof(jsval);
> #if defined _MSC_VER && _MSC_VER <= 800
>         if (nbytes > 60000U) {
>             JS_ReportOutOfMemory(cx);
>             return JS_FALSE;
>         }
> #endif
> 		XMEMTAG("js_AllocSlot");
>         newslots = (jsval *) JS_realloc(cx, obj->slots - 1, nbytes);
>         if (!newslots)
>             return JS_FALSE;
>         for (i = 1 + newslots[0]; i <= nslots; i++)
>             newslots[i] = JSVAL_VOID;
>         newslots[0] = map->nslots = nslots;
>         obj->slots = newslots + 1;
2813,2814c1998,2000
<     /* ReallocSlots or js_FreeSlot should set the free slots to void. */
<     JS_ASSERT(STOBJ_GET_SLOT(obj, map->freeslot) == JSVAL_VOID);
---
> #ifdef TOO_MUCH_GC
>     obj->slots[map->freeslot] = JSVAL_VOID;
> #endif
2822a2009,2011
>     uint32 nslots;
>     size_t nbytes;
>     jsval *newslots;
2823a2013,2014
>     OBJ_CHECK_SLOT(obj, slot);
>     obj->slots[slot] = JSVAL_VOID;
2826,2827c2017
<     LOCKED_OBJ_SET_SLOT(obj, slot, JSVAL_VOID);
<     if (map->freeslot == slot + 1) {
---
>     if (map->freeslot == slot + 1)
2829,2831c2019,2031
< 
<         /* When shrinking ReallocSlots always returns true. */
<         ReallocSlots(cx, obj, slot, JS_FALSE);
---
>     nslots = map->nslots;
>     if (nslots > JS_INITIAL_NSLOTS && map->freeslot < nslots / 2) {
>         nslots = map->freeslot;
>         nslots += nslots / 2;
>         if (nslots < JS_INITIAL_NSLOTS)
>             nslots = JS_INITIAL_NSLOTS;
>         nbytes = (nslots + 1) * sizeof(jsval);
>        	XMEMTAG("js_FreeSlot");
>         newslots = (jsval *) JS_realloc(cx, obj->slots - 1, nbytes);
>         if (!newslots)
>             return;
>         newslots[0] = map->nslots = nslots;
>         obj->slots = newslots + 1;
2835,2860c2035,2043
< jsid
< js_CheckForStringIndex(jsid id, const jschar *cp, const jschar *end,
<                        JSBool negative)
< {
<     jsuint index = JS7_UNDEC(*cp++);
<     jsuint oldIndex = 0;
<     jsuint c = 0;
< 
<     if (index != 0) {
<         while (JS7_ISDEC(*cp)) {
<             oldIndex = index;
<             c = JS7_UNDEC(*cp);
<             index = 10 * index + c;
<             cp++;
<         }
<     }
<     if (cp == end &&
<         (oldIndex < (JSVAL_INT_MAX / 10) ||
<          (oldIndex == (JSVAL_INT_MAX / 10) &&
<           c <= (JSVAL_INT_MAX % 10)))) {
<         if (negative)
<             index = 0 - index;
<         id = INT_TO_JSID((jsint)index);
<     }
<     return id;
< }
---
> #if JS_BUG_EMPTY_INDEX_ZERO
> #define CHECK_FOR_EMPTY_INDEX(id)                                             \
>     JS_BEGIN_MACRO                                                            \
>         if (JSSTRING_LENGTH(_str) == 0)                                       \
>             id = JSVAL_ZERO;                                                  \
>     JS_END_MACRO
> #else
> #define CHECK_FOR_EMPTY_INDEX(id) /* nothing */
> #endif
2862,2866c2045,2046
< static JSBool
< PurgeProtoChain(JSContext *cx, JSObject *obj, jsid id)
< {
<     JSScope *scope;
<     JSScopeProperty *sprop;
---
> /* JSVAL_INT_MAX as a string */
> #define JSVAL_INT_MAX_STRING "1073741823"
2868,2895c2048,2081
<     while (obj) {
<         if (!OBJ_IS_NATIVE(obj)) {
<             obj = OBJ_GET_PROTO(cx, obj);
<             continue;
<         }
<         JS_LOCK_OBJ(cx, obj);
<         scope = OBJ_SCOPE(obj);
<         sprop = SCOPE_GET_PROPERTY(scope, id);
<         if (sprop) {
<             SCOPE_GENERATE_PCTYPE(cx, scope);
<             JS_UNLOCK_SCOPE(cx, scope);
<             return JS_TRUE;
<         }
<         obj = LOCKED_OBJ_GET_PROTO(scope->object);
<         JS_UNLOCK_SCOPE(cx, scope);
<     }
<     return JS_FALSE;
< }
< 
< static void
< PurgeScopeChain(JSContext *cx, JSObject *obj, jsid id)
< {
<     PurgeProtoChain(cx, OBJ_GET_PROTO(cx, obj), id);
<     while ((obj = OBJ_GET_PARENT(cx, obj)) != NULL) {
<         if (PurgeProtoChain(cx, obj, id))
<             return;
<     }
< }
---
> #define CHECK_FOR_FUNNY_INDEX(id)                                             \
>     JS_BEGIN_MACRO                                                            \
>         if (!JSVAL_IS_INT(id)) {                                              \
>             JSAtom *atom_ = (JSAtom *)id;                                     \
>             JSString *str_ = ATOM_TO_STRING(atom_);                           \
>             const jschar *cp_ = str_->chars;                                  \
>             JSBool negative_ = (*cp_ == '-');                                 \
>             if (negative_) cp_++;                                             \
>             if (JS7_ISDEC(*cp_) &&                                            \
>                 str_->length - negative_ <= sizeof(JSVAL_INT_MAX_STRING) - 1) \
>             {                                                                 \
>                 jsuint index_ = JS7_UNDEC(*cp_++);                            \
>                 jsuint oldIndex_ = 0;                                         \
>                 jsuint c_ = 0;                                                \
>                 if (index_ != 0) {                                            \
>                     while (JS7_ISDEC(*cp_)) {                                 \
>                         oldIndex_ = index_;                                   \
>                         c_ = JS7_UNDEC(*cp_);                                 \
>                         index_ = 10 * index_ + c_;                            \
>                         cp_++;                                                \
>                     }                                                         \
>                 }                                                             \
>                 if (*cp_ == 0 &&                                              \
>                     (oldIndex_ < (JSVAL_INT_MAX / 10) ||                      \
>                      (oldIndex_ == (JSVAL_INT_MAX / 10) &&                    \
>                       c_ <= (JSVAL_INT_MAX % 10)))) {                         \
>                     if (negative_) index_ = 0 - index_;                       \
>                     id = INT_TO_JSVAL((jsint)index_);                         \
>                 }                                                             \
>             } else {                                                          \
>                 CHECK_FOR_EMPTY_INDEX(id);                                    \
>             }                                                                 \
>         }                                                                     \
>     JS_END_MACRO
2905,2911d2090
<     /*
<      * Purge the property cache of now-shadowed id in obj's scope chain. Do
<      * this optimistically (assuming no failure below) before locking obj, so
<      * we can lock the shadowed scope.
<      */
<     PurgeScopeChain(cx, obj, id);
< 
2917,2918c2096,2100
<         /* Convert string indices to integers if appropriate. */
<         CHECK_FOR_STRING_INDEX(id);
---
>         /*
>          * Handle old bug that took empty string as zero index.  Also convert
>          * string indices to integers if appropriate.
>          */
>         CHECK_FOR_FUNNY_INDEX(id);
2939a2122,2125
>         if (sprop) {
>             PROPERTY_CACHE_FILL(&cx->runtime->propertyCache, obj, sprop->id,
>                                 sprop);
>         }
2954,2973d2139
< /*
<  * Backward compatibility requires allowing addProperty hooks to mutate the
<  * nominal initial value of a slot-full property, while GC safety wants that
<  * value to be stored before the call-out through the hook.  Optimize to do
<  * both while saving cycles for classes that stub their addProperty hook.
<  */
< #define ADD_PROPERTY_HELPER(cx,clasp,obj,scope,sprop,vp,cleanup)              \
<     JS_BEGIN_MACRO                                                            \
<         if ((clasp)->addProperty != JS_PropertyStub) {                        \
<             jsval nominal_ = *(vp);                                           \
<             if (!(clasp)->addProperty(cx, obj, SPROP_USERID(sprop), vp)) {    \
<                 cleanup;                                                      \
<             }                                                                 \
<             if (*(vp) != nominal_) {                                          \
<                 if (SPROP_HAS_VALID_SLOT(sprop, scope))                       \
<                     LOCKED_OBJ_WRITE_BARRIER(cx, obj, (sprop)->slot, *(vp));  \
<             }                                                                 \
<         }                                                                     \
<     JS_END_MACRO
< 
2983,2984c2149,2153
<     /* Convert string indices to integers if appropriate. */
<     CHECK_FOR_STRING_INDEX(id);
---
>     /*
>      * Handle old bug that took empty string as zero index.  Also convert
>      * string indices to integers if appropriate.
>      */
>     CHECK_FOR_FUNNY_INDEX(id);
2994d2162
<         JSProperty *prop;
3004c2172
<         if (!js_LookupProperty(cx, obj, id, &pobj, &prop))
---
>         if (!js_LookupProperty(cx, obj, id, &pobj, (JSProperty **)&sprop))
3006d2173
<         sprop = (JSScopeProperty *) prop;
3018a2186,2187
>             PROPERTY_CACHE_FILL(&cx->runtime->propertyCache, obj, id, sprop);
> 
3025c2194
<         if (prop) {
---
>         if (sprop) {
3027,3028c2196,2197
<             OBJ_DROP_PROPERTY(cx, pobj, prop);
<             prop = NULL;
---
>             OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop);
>             sprop = NULL;
3033,3038d2201
<     /*
<      * Purge the property cache of now-shadowed id in obj's scope chain.
<      * Do this early, before locking obj to avoid nesting locks.
<      */
<     PurgeScopeChain(cx, obj, id);
< 
3062,3065d2224
<     /* Store value before calling addProperty, in case the latter GC's. */
<     if (SPROP_HAS_VALID_SLOT(sprop, scope))
<         LOCKED_OBJ_WRITE_BARRIER(cx, obj, sprop->slot, value);
< 
3067,3069c2226,2233
<     ADD_PROPERTY_HELPER(cx, clasp, obj, scope, sprop, &value,
<                         js_RemoveScopeProperty(cx, scope, id);
<                         goto bad);
---
>     if (!clasp->addProperty(cx, obj, SPROP_USERID(sprop), &value)) {
>         (void) js_RemoveScopeProperty(cx, scope, id);
>         goto bad;
>     }
> 
>     PROPERTY_CACHE_FILL(&cx->runtime->propertyCache, obj, id, sprop);
>     if (SPROP_HAS_VALID_SLOT(sprop, scope))
>         LOCKED_OBJ_SET_SLOT(obj, sprop->slot, value);
3071d2234
< #if JS_HAS_GETTER_SETTER
3073d2235
< #endif
3085,3091c2247,2248
< /*
<  * Given pc pointing after a property accessing bytecode, return true if the
<  * access is "object-detecting" in the sense used by web scripts, e.g., when
<  * checking whether document.all is defined.
<  */
< static JSBool
< Detecting(JSContext *cx, jsbytecode *pc)
---
> JS_STATIC_DLL_CALLBACK(const void *)
> resolving_GetKey(JSDHashTable *table, JSDHashEntryHdr *hdr)
3093,3096c2250
<     JSScript *script;
<     jsbytecode *endpc;
<     JSOp op;
<     JSAtom *atom;
---
>     JSResolvingEntry *entry = (JSResolvingEntry *)hdr;
3098,3107c2252,2253
<     if (!cx->fp)
<         return JS_FALSE;
<     script = cx->fp->script;
<     for (endpc = script->code + script->length;
<          pc < endpc;
<          pc += js_CodeSpec[op].length) {
<         /* General case: a branch or equality op follows the access. */
<         op = (JSOp) *pc;
<         if (js_CodeSpec[op].format & JOF_DETECTING)
<             return JS_TRUE;
---
>     return &entry->key;
> }
3109,3117c2255,2258
<         switch (op) {
<           case JSOP_NULL:
<             /*
<              * Special case #1: handle (document.all == null).  Don't sweat
<              * about JS1.2's revision of the equality operators here.
<              */
<             if (++pc < endpc)
<                 return *pc == JSOP_EQ || *pc == JSOP_NE;
<             return JS_FALSE;
---
> JS_STATIC_DLL_CALLBACK(JSDHashNumber)
> resolving_HashKey(JSDHashTable *table, const void *ptr)
> {
>     const JSResolvingKey *key = (const JSResolvingKey *)ptr;
3119,3132c2260,2261
<           case JSOP_NAME:
<             /*
<              * Special case #2: handle (document.all == undefined).  Don't
<              * worry about someone redefining undefined, which was added by
<              * Edition 3, so is read/write for backward compatibility.
<              */
<             GET_ATOM_FROM_BYTECODE(script, pc, 0, atom);
<             if (atom == cx->runtime->atomState.typeAtoms[JSTYPE_VOID] &&
<                 (pc += js_CodeSpec[op].length) < endpc) {
<                 op = (JSOp) *pc;
<                 return op == JSOP_EQ || op == JSOP_NE ||
<                        op == JSOP_STRICTEQ || op == JSOP_STRICTNE;
<             }
<             return JS_FALSE;
---
>     return ((JSDHashNumber)key->obj >> JSVAL_TAGBITS) ^ key->id;
> }
3134,3135c2263,2275
<           case JSOP_GROUP:
<             break;
---
> // 2003.09.09 jht: swat no prototype warning
> JS_PUBLIC_API(JSBool)
> resolving_MatchEntry(JSDHashTable *table,
>                      const JSDHashEntryHdr *hdr,
>                      const void *ptr);
>                      
> JS_PUBLIC_API(JSBool)
> resolving_MatchEntry(JSDHashTable *table,
>                      const JSDHashEntryHdr *hdr,
>                      const void *ptr)
> {
>     const JSResolvingEntry *entry = (const JSResolvingEntry *)hdr;
>     const JSResolvingKey *key = (const JSResolvingKey *)ptr;
3137,3147c2277
<           default:
<             /*
<              * At this point, anything but an extended atom index prefix means
<              * we're not detecting.
<              */
<             if (!(js_CodeSpec[op].format & JOF_INDEXBASE))
<                 return JS_FALSE;
<             break;
<         }
<     }
<     return JS_FALSE;
---
>     return entry->key.obj == key->obj && entry->key.id == key->id;
3149a2280,2296
> static const JSDHashTableOps resolving_dhash_ops = {
>     JS_DHashAllocTable,
>     JS_DHashFreeTable,
>     resolving_GetKey,
>     resolving_HashKey,
>     resolving_MatchEntry,
>     JS_DHashMoveEntryStub,
>     JS_DHashClearEntryStub,
>     JS_DHashFinalizeStub,
>     NULL
> };
> 
> #if defined JS_THREADSAFE && defined DEBUG
> JS_FRIEND_API(JSBool)
> _js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
>                    JSProperty **propp, const char *file, uintN line)
> #else
3153,3160d2299
< {
<     return js_LookupPropertyWithFlags(cx, obj, id, 0, objp, propp) >= 0;
< }
< 
< #ifdef JS_SCOPE_DEPTH_METER
< # define SCOPE_DEPTH_ACCUM(bs,val) JS_BASIC_STATS_ACCUM(bs,val)
< #else
< # define SCOPE_DEPTH_ACCUM(bs,val) /* nothing */
3162,3165d2300
< 
< int
< js_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN flags,
<                            JSObject **objp, JSProperty **propp)
3168d2302
<     int protoIndex;
3174c2308,2309
<     JSResolvingEntry *entry;
---
>     JSDHashTable *table;
>     JSDHashEntryHdr *entry;
3177,3178c2312
<     jsbytecode *pc;
<     const JSCodeSpec *cs;
---
>     uintN flags;
3182,3184c2316,2320
<     /* Convert string indices to integers if appropriate. */
<     CHECK_FOR_STRING_INDEX(id);
<     JS_COUNT_OPERATION(cx, JSOW_LOOKUP_PROPERTY);
---
>     /*
>      * Handle old bug that took empty string as zero index.  Also convert
>      * string indices to integers if appropriate.
>      */
>     CHECK_FOR_FUNNY_INDEX(id);
3188c2324
<     for (protoIndex = 0; ; protoIndex++) {
---
>     for (;;) {
3189a2326
>         SET_OBJ_INFO(obj, file, line);
3205a2343,2361
>                 if (cx->resolving != 0) {
>                     table = cx->resolvingTable;
>                     entry = JS_DHashTableOperate(table, &key, JS_DHASH_LOOKUP);
>                     if (JS_DHASH_ENTRY_IS_BUSY(entry)) {
>                         JS_UNLOCK_OBJ(cx, obj);
>                         goto out;
>                     }
>                 } else if (!(table = cx->resolvingTable)) {
>                     table = JS_NewDHashTable(&resolving_dhash_ops,
>                                              NULL,
>                                              sizeof(JSResolvingEntry),
>                                              JS_DHASH_MIN_SIZE);
>                     if (!table)
>                         goto outofmem;
>                     cx->resolvingTable = table;
>                 } else {
>                     /* cx->resolving is 0, so the table had better be empty! */
>                     JS_ASSERT(table->entryCount == 0);
>                 }
3208,3211c2364,2366
<                  * Once we have successfully added an entry for (obj, key) to
<                  * cx->resolvingTable, control must go through cleanup: before
<                  * returning.  But note that JS_DHASH_ADD may find an existing
<                  * entry, in which case we bail to suppress runaway recursion.
---
>                  * Once we have successfully added an entry for key and bumped
>                  * cx->resolving, control flow must go through cleanup: before
>                  * returning.
3213,3216c2368
<                 if (!js_StartResolving(cx, &key, JSRESFLAG_LOOKUP, &entry)) {
<                     JS_UNLOCK_OBJ(cx, obj);
<                     return -1;
<                 }
---
>                 entry = JS_DHashTableOperate(table, &key, JS_DHASH_ADD);
3218c2370
<                     /* Already resolving id in obj -- suppress recursion. */
---
>             outofmem:
3220c2372,2373
<                     goto out;
---
>                     JS_ReportOutOfMemory(cx);
>                     return JS_FALSE;
3222c2375,2377
<                 generation = cx->resolvingTable->generation;
---
>                 ((JSResolvingEntry *)entry)->key = key;
>                 generation = table->generation;
>                 cx->resolving++;
3229,3234c2384,2387
<                     if (!(flags & JSRESOLVE_CLASSNAME) &&
<                         cx->fp &&
<                         (pc = cx->fp->pc)) {
<                         cs = &js_CodeSpec[*pc];
<                         format = cs->format;
<                         if (JOF_MODE(format) != JOF_NAME)
---
>                     flags = 0;
>                     if (cx->fp && cx->fp->pc) {
>                         format = js_CodeSpec[*cx->fp->pc].format;
>                         if ((format & JOF_MODEMASK) != JOF_NAME)
3239,3242d2391
<                         } else {
<                             pc += cs->length;
<                             if (Detecting(cx, pc))
<                                 flags |= JSRESOLVE_DETECTING;
3244,3245d2392
<                         if (format & JOF_DECLARING)
<                             flags |= JSRESOLVE_DECLARING;
3251,3253d2397
< 
<                     /* Protect id and all atoms from a GC nested in resolve. */
<                     JS_KEEP_ATOMS(cx->runtime);
3255d2398
<                     JS_UNKEEP_ATOMS(cx->runtime);
3258d2400
< 
3259a2402
>                     SET_OBJ_INFO(obj, file, line);
3266,3270d2408
<                         protoIndex = 0;
<                         for (proto = start; proto && proto != obj2;
<                              proto = OBJ_GET_PROTO(cx, proto)) {
<                             protoIndex++;
<                         }
3292,3295c2430
<                         if (sprop) {
<                             JS_ASSERT(obj2 == scope->object);
<                             obj = obj2;
<                         } else if (obj2 != obj) {
---
>                         if (obj2 != obj && !sprop) {
3309a2445
>                     SET_OBJ_INFO(obj, file, line);
3317,3321c2453,2468
<                 js_StopResolving(cx, &key, JSRESFLAG_LOOKUP, entry, generation);
<                 if (!ok)
<                     return -1;
<                 if (*propp)
<                     return protoIndex;
---
>                 /*
>                  * Do a raw remove only if the table hasn't changed since entry
>                  * was added, and only if fewer entries were removed than would
>                  * cause alpha to be  < .5 (alpha is at most .75).  Otherwise,
>                  * use JS_DHashTableOperate to re-lookup the key and remove its
>                  * entry, compressing or shrinking the table as needed.
>                  */
>                 if (table->generation == generation &&
>                     table->removedCount < JS_DHASH_TABLE_SIZE(table) >> 2) {
>                     JS_DHashTableRawRemove(table, entry);
>                 } else {
>                     JS_DHashTableOperate(table, &key, JS_DHASH_REMOVE);
>                 }
>                 cx->resolving--;
>                 if (!ok || *propp)
>                     return ok;
3326d2472
<             SCOPE_DEPTH_ACCUM(&cx->runtime->protoLookupDepthStats, protoIndex);
3331c2477
<             return protoIndex;
---
>             return JS_TRUE;
3338,3342c2484,2485
<         if (!OBJ_IS_NATIVE(proto)) {
<             if (!OBJ_LOOKUP_PROPERTY(cx, proto, id, objp, propp))
<                 return -1;
<             return protoIndex;
<         }
---
>         if (!OBJ_IS_NATIVE(proto))
>             return OBJ_LOOKUP_PROPERTY(cx, proto, id, objp, propp);
3349c2492
<     return protoIndex;
---
>     return JS_TRUE;
3352,3355c2495,2497
< int
< js_FindPropertyHelper(JSContext *cx, jsid id, JSObject **objp,
<                       JSObject **pobjp, JSProperty **propp,
<                       JSPropCacheEntry **entryp)
---
> JS_FRIEND_API(JSBool)
> js_FindProperty(JSContext *cx, jsid id, JSObject **objp, JSObject **pobjp,
>                 JSProperty **propp)
3356a2499
>     JSRuntime *rt;
3358,3360d2500
<     uint32 type;
<     int scopeIndex, protoIndex;
<     JSProperty *prop;
3361a2502
>     JSProperty *prop;
3362a2504
>     rt = cx->runtime;
3364,3372c2506,2518
<     type = OBJ_SCOPE(obj)->shape;
<     for (scopeIndex = 0; ; scopeIndex++) {
<         if (obj->map->ops->lookupProperty == js_LookupProperty) {
<             protoIndex =
<                 js_LookupPropertyWithFlags(cx, obj, id, 0, &pobj, &prop);
<         } else {
<             if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &pobj, &prop))
<                 return -1;
<             protoIndex = -1;
---
>     do {
>         /* Try the property cache and return immediately on cache hit. */
>         if (OBJ_IS_NATIVE(obj)) {
>             JS_LOCK_OBJ(cx, obj);
>             PROPERTY_CACHE_TEST(&rt->propertyCache, obj, id, sprop);
>             if (sprop) {
>                 JS_ASSERT(OBJ_IS_NATIVE(obj));
>                 *objp = obj;
>                 *pobjp = obj;
>                 *propp = (JSProperty *) sprop;
>                 return JS_TRUE;
>             }
>             JS_UNLOCK_OBJ(cx, obj);
3374a2521,2523
>         /* If cache miss, take the slow path. */
>         if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &pobj, &prop))
>             return JS_FALSE;
3376,3385c2525,2527
<             if (entryp) {
<                 if (protoIndex >= 0 && OBJ_IS_NATIVE(pobj)) {
<                     sprop = (JSScopeProperty *) prop;
<                     js_FillPropertyCache(cx, cx->fp->scopeChain, type,
<                                          scopeIndex, protoIndex, pobj, sprop,
<                                          entryp);
<                 } else {
<                     PCMETER(JS_PROPERTY_CACHE(cx).nofills++);
<                     *entryp = NULL;
<                 }
---
>             if (OBJ_IS_NATIVE(pobj)) {
>                 sprop = (JSScopeProperty *) prop;
>                 PROPERTY_CACHE_FILL(&rt->propertyCache, pobj, id, sprop);
3387d2528
<             SCOPE_DEPTH_ACCUM(&rt->scopeSearchDepthStats, scopeIndex);
3391c2532
<             return scopeIndex;
---
>             return JS_TRUE;
3393d2533
< 
3395,3398c2535
<         obj = OBJ_GET_PARENT(cx, obj);
<         if (!obj)
<             break;
<     }
---
>     } while ((obj = OBJ_GET_PARENT(cx, obj)) != NULL);
3403,3410c2540
<     return scopeIndex;
< }
< 
< JS_FRIEND_API(JSBool)
< js_FindProperty(JSContext *cx, jsid id, JSObject **objp, JSObject **pobjp,
<                 JSProperty **propp)
< {
<     return js_FindPropertyHelper(cx, id, objp, pobjp, propp, NULL) >= 0;
---
>     return JS_TRUE;
3414c2544
< js_FindIdentifierBase(JSContext *cx, jsid id, JSPropCacheEntry *entry)
---
> js_FindIdentifierBase(JSContext *cx, jsid id)
3423c2553
<     if (js_FindPropertyHelper(cx, id, &obj, &pobj, &prop, &entry) < 0)
---
>     if (!js_FindProperty(cx, id, &obj, &pobj, &prop))
3427,3431d2556
< 
<         JS_ASSERT(!entry ||
<                   entry->kpc == ((PCVCAP_TAG(entry->vcap) > 1)
<                                  ? (jsbytecode *) JSID_TO_ATOM(id)
<                                  : cx->fp->pc));
3447,3450c2572
<         const char *bytes = js_GetStringBytes(cx, str);
< 
<         if (!bytes ||
<             !JS_ReportErrorFlagsAndNumber(cx,
---
>         if (!JS_ReportErrorFlagsAndNumber(cx,
3453c2575,2576
<                                           JSMSG_UNDECLARED_VAR, bytes)) {
---
>                                           JSMSG_UNDECLARED_VAR,
>                                           JS_GetStringBytes(str))) {
3457d2579
< 
3462,3503c2584
< js_NativeGet(JSContext *cx, JSObject *obj, JSObject *pobj,
<              JSScopeProperty *sprop, jsval *vp)
< {
<     JSScope *scope;
<     uint32 slot;
<     int32 sample;
<     JSTempValueRooter tvr;
<     JSBool ok;
< 
<     JS_ASSERT(OBJ_IS_NATIVE(pobj));
<     JS_ASSERT(JS_IS_OBJ_LOCKED(cx, pobj));
<     scope = OBJ_SCOPE(pobj);
<     JS_ASSERT(scope->object == pobj);
< 
<     slot = sprop->slot;
<     *vp = (slot != SPROP_INVALID_SLOT)
<           ? LOCKED_OBJ_GET_SLOT(pobj, slot)
<           : JSVAL_VOID;
<     if (SPROP_HAS_STUB_GETTER(sprop))
<         return JS_TRUE;
< 
<     sample = cx->runtime->propertyRemovals;
<     JS_UNLOCK_SCOPE(cx, scope);
<     JS_PUSH_TEMP_ROOT_SPROP(cx, sprop, &tvr);
<     ok = SPROP_GET(cx, sprop, obj, pobj, vp);
<     JS_POP_TEMP_ROOT(cx, &tvr);
<     if (!ok)
<         return JS_FALSE;
< 
<     JS_LOCK_SCOPE(cx, scope);
<     JS_ASSERT(scope->object == pobj);
<     if (SLOT_IN_SCOPE(slot, scope) &&
<         (JS_LIKELY(cx->runtime->propertyRemovals == sample) ||
<          SCOPE_GET_PROPERTY(scope, sprop->id) == sprop)) {
<         LOCKED_OBJ_SET_SLOT(pobj, slot, *vp);
<     }
< 
<     return JS_TRUE;
< }
< 
< JSBool
< js_NativeSet(JSContext *cx, JSObject *obj, JSScopeProperty *sprop, jsval *vp)
---
> js_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
3504a2586,2587
>     JSObject *obj2;
>     JSScopeProperty *sprop;
3507,3553d2589
<     jsval pval;
<     int32 sample;
<     JSTempValueRooter tvr;
<     JSBool ok;
< 
<     JS_ASSERT(OBJ_IS_NATIVE(obj));
<     JS_ASSERT(JS_IS_OBJ_LOCKED(cx, obj));
<     scope = OBJ_SCOPE(obj);
<     JS_ASSERT(scope->object == obj);
< 
<     slot = sprop->slot;
<     if (slot != SPROP_INVALID_SLOT) {
<         pval = LOCKED_OBJ_GET_SLOT(obj, slot);
< 
<         /* If sprop has a stub setter, keep scope locked and just store *vp. */
<         if (SPROP_HAS_STUB_SETTER(sprop))
<             goto set_slot;
<     } else {
<         /*
<          * Allow API consumers to create shared properties with stub setters.
<          * Such properties lack value storage, so setting them is like writing
<          * to /dev/null.
<          */
<         if (SPROP_HAS_STUB_SETTER(sprop))
<             return JS_TRUE;
<         pval = JSVAL_VOID;
<     }
< 
<     sample = cx->runtime->propertyRemovals;
<     JS_UNLOCK_SCOPE(cx, scope);
<     JS_PUSH_TEMP_ROOT_SPROP(cx, sprop, &tvr);
<     ok = SPROP_SET(cx, sprop, obj, obj, vp);
<     JS_POP_TEMP_ROOT(cx, &tvr);
<     if (!ok)
<         return JS_FALSE;
< 
<     JS_LOCK_SCOPE(cx, scope);
<     JS_ASSERT(scope->object == obj);
<     if (SLOT_IN_SCOPE(slot, scope) &&
<         (JS_LIKELY(cx->runtime->propertyRemovals == sample) ||
<          SCOPE_GET_PROPERTY(scope, sprop->id) == sprop)) {
<   set_slot:
<         LOCKED_OBJ_WRITE_BARRIER(cx, obj, slot, *vp);
<     }
< 
<     return JS_TRUE;
< }
3555,3563c2591,2595
< JSBool
< js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
<                      JSPropCacheEntry **entryp)
< {
<     uint32 type;
<     int protoIndex;
<     JSObject *obj2;
<     JSProperty *prop;
<     JSScopeProperty *sprop;
---
>     /*
>      * Handle old bug that took empty string as zero index.  Also convert
>      * string indices to integers if appropriate.
>      */
>     CHECK_FOR_FUNNY_INDEX(id);
3565,3571c2597
<     /* Convert string indices to integers if appropriate. */
<     CHECK_FOR_STRING_INDEX(id);
<     JS_COUNT_OPERATION(cx, JSOW_GET_PROPERTY);
< 
<     type = OBJ_SCOPE(obj)->shape;
<     protoIndex = js_LookupPropertyWithFlags(cx, obj, id, 0, &obj2, &prop);
<     if (protoIndex < 0)
---
>     if (!js_LookupProperty(cx, obj, id, &obj2, (JSProperty **)&sprop))
3573,3574c2599,2600
<     if (!prop) {
<         jsbytecode *pc;
---
>     if (!sprop) {
>         jsval default_val;
3576c2602,2610
<         *vp = JSVAL_VOID;
---
> #if JS_BUG_NULL_INDEX_PROPS
>         /* Indexed properties defaulted to null in old versions. */
>         default_val = (JSVAL_IS_INT(id) && JSVAL_TO_INT(id) >= 0)
>                       ? JSVAL_NULL
>                       : JSVAL_VOID;
> #else
>         default_val = JSVAL_VOID;
> #endif
>         *vp = default_val;
3581,3585d2614
<         if (entryp) {
<             PCMETER(JS_PROPERTY_CACHE(cx).nofills++);
<             *entryp = NULL;
<         }
< 
3590,3613c2619,2633
<         if (JSVAL_IS_VOID(*vp) && cx->fp && (pc = cx->fp->pc)) {
<             JSOp op;
<             uintN flags;
< 
<             op = (JSOp) *pc;
<             if (op == JSOP_GETXPROP) {
<                 flags = JSREPORT_ERROR;
<             } else {
<                 if (!JS_HAS_STRICT_OPTION(cx) ||
<                     (op != JSOP_GETPROP && op != JSOP_GETELEM)) {
<                     return JS_TRUE;
<                 }
< 
<                 /*
<                  * XXX do not warn about missing __iterator__ as the function
<                  * may be called from JS_GetMethodById. See bug 355145.
<                  */
<                 if (id == ATOM_TO_JSID(cx->runtime->atomState.iteratorAtom))
<                     return JS_TRUE;
< 
<                 /* Kludge to allow (typeof foo == "undefined") tests. */
<                 JS_ASSERT(cx->fp->script);
<                 pc += js_CodeSpec[op].length;
<                 if (Detecting(cx, pc))
---
>         if (JS_HAS_STRICT_OPTION(cx) &&
>             *vp == default_val &&
>             cx->fp && cx->fp->pc &&
>             (*cx->fp->pc == JSOP_GETPROP || *cx->fp->pc == JSOP_GETELEM))
>         {
>             jsbytecode *pc, *endpc;
>             JSString *str;
> 
>             /* Kludge to allow (typeof foo == "undefined") tests. */
>             JS_ASSERT(cx->fp->script);
>             pc = cx->fp->pc;
>             pc += js_CodeSpec[*pc].length;
>             endpc = cx->fp->script->code + cx->fp->script->length;
>             while (pc < endpc) {
>                 if (*pc == JSOP_TYPEOF)
3615,3616c2635,2637
< 
<                 flags = JSREPORT_WARNING | JSREPORT_STRICT;
---
>                 if (*pc != JSOP_GROUP)
>                     break;
>                 pc++;
3620,3622c2641,2648
<             if (!js_ReportValueErrorFlags(cx, flags, JSMSG_UNDEFINED_PROP,
<                                           JSDVG_IGNORE_STACK, ID_TO_VALUE(id),
<                                           NULL, NULL, NULL)) {
---
>             str = js_DecompileValueGenerator(cx, JS_FALSE, ID_TO_VALUE(id),
>                                              NULL);
>             if (!str ||
>                 !JS_ReportErrorFlagsAndNumber(cx,
>                                               JSREPORT_WARNING|JSREPORT_STRICT,
>                                               js_GetErrorMessage, NULL,
>                                               JSMSG_UNDEFINED_PROP,
>                                               JS_GetStringBytes(str))) {
3630c2656
<         OBJ_DROP_PROPERTY(cx, obj2, prop);
---
>         OBJ_DROP_PROPERTY(cx, obj2, (JSProperty *)sprop);
3634,3635c2660,2667
<     sprop = (JSScopeProperty *) prop;
<     if (!js_NativeGet(cx, obj, obj2, sprop, vp))
---
>     /* Unlock obj2 before calling getter, relock after to avoid deadlock. */
>     scope = OBJ_SCOPE(obj2);
>     slot = sprop->slot;
>     *vp = (slot != SPROP_INVALID_SLOT)
>           ? LOCKED_OBJ_GET_SLOT(obj2, slot)
>           : JSVAL_VOID;
>     JS_UNLOCK_SCOPE(cx, scope);
>     if (!SPROP_GET(cx, sprop, obj, obj2, vp))
3636a2669
>     JS_LOCK_SCOPE(cx, scope);
3638,3640c2671,2673
<     if (entryp) {
<         js_FillPropertyCache(cx, obj, type, 0, protoIndex, obj2, sprop,
<                              entryp);
---
>     if (SPROP_HAS_VALID_SLOT(sprop, scope)) {
>         LOCKED_OBJ_SET_SLOT(obj2, slot, *vp);
>         PROPERTY_CACHE_FILL(&cx->runtime->propertyCache, obj2, id, sprop);
3642c2675
<     JS_UNLOCK_OBJ(cx, obj2);
---
>     JS_UNLOCK_SCOPE(cx, scope);
3647,3654c2680
< js_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
< {
<     return js_GetPropertyHelper(cx, obj, id, vp, NULL);
< }
< 
< JSBool
< js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
<                      JSPropCacheEntry **entryp)
---
> js_SetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
3656,3657d2681
<     uint32 type;
<     int protoIndex;
3659d2682
<     JSProperty *prop;
3665a2689,2690
>     jsval pval;
>     uint32 slot;
3667,3669c2692,2696
<     /* Convert string indices to integers if appropriate. */
<     CHECK_FOR_STRING_INDEX(id);
<     JS_COUNT_OPERATION(cx, JSOW_SET_PROPERTY);
---
>     /*
>      * Handle old bug that took empty string as zero index.  Also convert
>      * string indices to integers if appropriate.
>      */
>     CHECK_FOR_FUNNY_INDEX(id);
3671,3673c2698
<     type = OBJ_SCOPE(obj)->shape;
<     protoIndex = js_LookupPropertyWithFlags(cx, obj, id, 0, &pobj, &prop);
<     if (protoIndex < 0)
---
>     if (!js_LookupProperty(cx, obj, id, &pobj, (JSProperty **)&sprop))
3676,3678c2701,2703
<     if (prop && !OBJ_IS_NATIVE(pobj)) {
<         OBJ_DROP_PROPERTY(cx, pobj, prop);
<         prop = NULL;
---
>     if (sprop && !OBJ_IS_NATIVE(pobj)) {
>         OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop);
>         sprop = NULL;
3680d2704
<     sprop = (JSScopeProperty *) prop;
3706,3707c2730
<         if ((attrs & JSPROP_READONLY) ||
<             (SCOPE_IS_SEALED(scope) && pobj == obj)) {
---
>         if ((attrs & JSPROP_READONLY) || SCOPE_IS_SEALED(scope)) {
3709,3728c2732,2733
< 
<             /*
<              * Here, we'll either return true or goto read_only_error, which
<              * reports a strict warning or throws an error.  So we redefine
<              * the |flags| local variable to be JSREPORT_* flags to pass to
<              * JS_ReportErrorFlagsAndNumberUC at label read_only_error.  We
<              * must likewise re-task flags further below for the other 'goto
<              * read_only_error;' case.
<              */
<             flags = JSREPORT_ERROR;
<             if (attrs & JSPROP_READONLY) {
<                 if (!JS_HAS_STRICT_OPTION(cx)) {
<                     /* Just return true per ECMA if not in strict mode. */
<                     PCMETER(!entryp || JS_PROPERTY_CACHE(cx).rofills++);
<                     return JS_TRUE;
<                 }
< 
<                 /* Strict mode: report a read-only strict warning. */
<                 flags = JSREPORT_STRICT | JSREPORT_WARNING;
<             }
---
>             if ((attrs & JSPROP_READONLY) && JSVERSION_IS_ECMA(cx->version))
>                 return JS_TRUE;
3735d2739
<              *
3739,3745d2742
<              *
<              * But if we are shadowing (not sharing) the proto-property, then
<              * we need to regenerate the property cache shape id for scope, in
<              * case the cache contains the old type in an entry value that was
<              * filled by a get on obj that delegated up the prototype chain to
<              * pobj. Once we've shadowed the proto-property, that cache entry
<              * must not be hit.
3747,3748d2743
<             if (!(attrs & JSPROP_SHARED))
<                 SCOPE_GENERATE_PCTYPE(cx, scope);
3752,3765c2747
<             if (attrs & JSPROP_SHARED) {
<                 if (SPROP_HAS_STUB_SETTER(sprop) &&
<                     !(sprop->attrs & JSPROP_GETTER)) {
<                     if (entryp) {
<                         PCMETER(JS_PROPERTY_CACHE(cx).nofills++);
<                         *entryp = NULL;
<                     }
<                     return JS_TRUE;
<                 }
< 
<                 if (entryp) {
<                     js_FillPropertyCache(cx, obj, type, 0, protoIndex,
<                                          pobj, sprop, entryp);
<                 }
---
>             if (attrs & JSPROP_SHARED)
3767d2748
<             }
3792c2773
< #ifdef __GNUC__ /* suppress bogus gcc warnings */
---
> #ifdef __GNUC__         /* suppress bogus gcc warnings */
3799,3800c2780
<         if (SCOPE_IS_SEALED(OBJ_SCOPE(obj)) && OBJ_SCOPE(obj)->object == obj) {
<             flags = JSREPORT_ERROR;
---
>         if (SCOPE_IS_SEALED(OBJ_SCOPE(obj)))
3802,3808d2781
<         }
< 
<         /*
<          * Purge the property cache of now-shadowed id in obj's scope chain.
<          * Do this early, before locking obj to avoid nesting locks.
<          */
<         PurgeScopeChain(cx, obj, id);
3826,3830c2799,2806
<         /*
<          * Initialize the new property value (passed to setter) to undefined.
<          * Note that we store before calling addProperty, to match the order
<          * in js_DefineNativeProperty.
<          */
---
>         /* XXXbe called with obj locked */
>         if (!clasp->addProperty(cx, obj, SPROP_USERID(sprop), vp)) {
>             (void) js_RemoveScopeProperty(cx, scope, id);
>             JS_UNLOCK_SCOPE(cx, scope);
>             return JS_FALSE;
>         }
> 
>         /* Initialize new property value (passed to setter) to undefined. */
3834,3838c2810,2826
<         /* XXXbe called with obj locked */
<         ADD_PROPERTY_HELPER(cx, clasp, obj, scope, sprop, vp,
<                             js_RemoveScopeProperty(cx, scope, id);
<                             JS_UNLOCK_SCOPE(cx, scope);
<                             return JS_FALSE);
---
>         PROPERTY_CACHE_FILL(&cx->runtime->propertyCache, obj, id, sprop);
>     }
> 
>     /* Get the current property value from its slot. */
>     slot = sprop->slot;
>     if (slot != SPROP_INVALID_SLOT) {
>         JS_ASSERT(slot < obj->map->freeslot);
>         pval = LOCKED_OBJ_GET_SLOT(obj, slot);
> 
>         /* If sprop has a stub setter, keep scope locked and just store *vp. */
>         if (!sprop->setter) {
>             GC_POKE(cx, pval);
>             LOCKED_OBJ_SET_SLOT(obj, slot, *vp);
> 
>             JS_UNLOCK_SCOPE(cx, scope);
>             return JS_TRUE;
>         }
3841c2829,2833
<     if (!js_NativeSet(cx, obj, sprop, vp))
---
>     /* Avoid deadlock by unlocking obj's scope while calling sprop's setter. */
>     JS_UNLOCK_SCOPE(cx, scope);
> 
>     /* Let the setter modify vp before copying from it to obj->slots[slot]. */
>     if (!SPROP_SET(cx, sprop, obj, obj, vp))
3844,3845c2836,2847
<     if (entryp)
<         js_FillPropertyCache(cx, obj, type, 0, 0, obj, sprop, entryp);
---
>     /* Relock obj's scope until we are done with sprop. */
>     JS_LOCK_SCOPE(cx, scope);
> 
>     /*
>      * Check whether sprop is still around (was not deleted), and whether it
>      * has a slot (it may never have had one, or we may have lost a race with
>      * someone who cleared scope).
>      */
>     if (SPROP_HAS_VALID_SLOT(sprop, scope)) {
>         GC_POKE(cx, pval);
>         LOCKED_OBJ_SET_SLOT(obj, slot, *vp);
>     }
3849,3858c2851,2862
<   read_only_error:
<     return js_ReportValueErrorFlags(cx, flags, JSMSG_READ_ONLY,
<                                     JSDVG_IGNORE_STACK, ID_TO_VALUE(id), NULL,
<                                     NULL, NULL);
< }
< 
< JSBool
< js_SetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
< {
<     return js_SetPropertyHelper(cx, obj, id, vp, NULL);
---
>   read_only_error: {
>     JSString *str = js_DecompileValueGenerator(cx,
>                                                JSDVG_IGNORE_STACK,
>                                                ID_TO_VALUE(id),
>                                                NULL);
>     if (str) {
>         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
>                              JSMSG_READ_ONLY,
>                              JS_GetStringBytes(str));
>     }
>     return JS_FALSE;
>   }
3909c2913,2915
<     sprop = js_ChangeNativePropertyAttrs(cx, obj, sprop, *attrsp, 0,
---
>     sprop = js_ChangeNativePropertyAttrs(cx, obj, sprop,
>                                          *attrsp &
>                                          ~(JSPROP_GETTER | JSPROP_SETTER), 0,
3918a2925,2926
> #if JS_HAS_PROP_DELETE
> 
3921a2930
>     JSString *str;
3925c2934
<     *rval = JSVAL_TRUE;
---
>     *rval = JSVERSION_IS_ECMA(cx->version) ? JSVAL_TRUE : JSVAL_VOID;
3927,3929c2936,2940
<     /* Convert string indices to integers if appropriate. */
<     CHECK_FOR_STRING_INDEX(id);
<     JS_COUNT_OPERATION(cx, JSOW_DELETE_PROPERTY);
---
>     /*
>      * Handle old bug that took empty string as zero index.  Also convert
>      * string indices to integers if appropriate.
>      */
>     CHECK_FOR_FUNNY_INDEX(id);
3963,3964c2974,2984
<         *rval = JSVAL_FALSE;
<         return JS_TRUE;
---
>         if (JSVERSION_IS_ECMA(cx->version)) {
>             *rval = JSVAL_FALSE;
>             return JS_TRUE;
>         }
>         str = js_DecompileValueGenerator(cx, JSDVG_IGNORE_STACK,
>                                          ID_TO_VALUE(id), NULL);
>         if (str) {
>             JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
>                                  JSMSG_PERMANENT, JS_GetStringBytes(str));
>         }
>         return JS_FALSE;
3977a2998
>     PROPERTY_CACHE_FILL(&cx->runtime->propertyCache, obj, id, NULL);
3980a3002,3010
> 
> #else  /* !JS_HAS_PROP_DELETE */
> 
>     jsval null = JSVAL_NULL;
> 
>     *rval = JSVAL_VOID;
>     return js_SetProperty(cx, obj, id, &null);
> 
> #endif /* !JS_HAS_PROP_DELETE */
3986c3016
<     jsval v, save;
---
>     jsval v;
3989c3019
<     v = save = OBJECT_TO_JSVAL(obj);
---
>     v = OBJECT_TO_JSVAL(obj);
3997c3027
<                           &v)) {
---
>                           &v))
3999d3028
<         }
4003a3033,3051
> 
>             /*
>              * JS1.2 never failed (except for malloc failure) to convert an
>              * object to a string.  ECMA requires an error if both toString
>              * and valueOf fail to produce a primitive value.
>              */
>             if (!JSVAL_IS_PRIMITIVE(v) && cx->version == JSVERSION_1_2) {
>                 char *bytes = JS_smprintf("[object %s]",
>                                           OBJ_GET_CLASS(cx, obj)->name);
>                 if (!bytes)
>                     return JS_FALSE;
>                 str = JS_NewString(cx, bytes, strlen(bytes));
>                 if (!str) {
>                     xfree(bytes);
>                     return JS_FALSE;
>                 }
>                 v = STRING_TO_JSVAL(str);
>                 goto out;
>             }
4015a3064,3066
>             /* Don't convert to string (source object literal) for JS1.2. */
>             if (cx->version == JSVERSION_1_2 && hint == JSTYPE_BOOLEAN)
>                 goto out;
4017c3068
<                               NULL, &v)) {
---
>                               NULL, &v))
4019d3069
<             }
4024c3074
<         /* Avoid recursive death when decompiling in js_ReportValueError. */
---
>         /* Avoid recursive death through js_DecompileValueGenerator. */
4033,4037c3083,3091
<         js_ReportValueError2(cx, JSMSG_CANT_CONVERT_TO,
<                              JSDVG_SEARCH_STACK, save, str,
<                              (hint == JSTYPE_VOID)
<                              ? "primitive type"
<                              : JS_TYPE_STR(hint));
---
>         str = js_DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, str);
>         if (str) {
>             JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
>                                  JSMSG_CANT_CONVERT_TO,
>                                  JS_GetStringBytes(str),
>                                  (hint == JSTYPE_VOID)
>                                  ? "primitive type"
>                                  : js_type_str[hint]);
>         }
4049a3104
> 	XMEMTAG("js_NewIdArray");
4051c3106
<           JS_malloc(cx, sizeof(JSIdArray) + (length-1) * sizeof(jsval));
---
>         JS_malloc(cx, sizeof(JSIdArray) + (length - 1) * sizeof(jsval));
4058c3113
< js_SetIdArrayLength(JSContext *cx, JSIdArray *ida, jsint length)
---
> js_GrowIdArray(JSContext *cx, JSIdArray *ida, jsint length)
4060,4068c3115,3120
<     JSIdArray *rida;
< 
<     rida = (JSIdArray *)
<            JS_realloc(cx, ida, sizeof(JSIdArray) + (length-1) * sizeof(jsval));
<     if (!rida)
<         JS_DestroyIdArray(cx, ida);
<     else
<         rida->length = length;
<     return rida;
---
> 	XMEMTAG("js_GrowIdArray");
>     ida = (JSIdArray *)
>         JS_realloc(cx, ida, sizeof(JSIdArray) + (length - 1) * sizeof(jsval));
>     if (ida)
>         ida->length = length;
>     return ida;
4072,4077c3124,3127
< struct JSNativeIteratorState {
<     jsint                   next_index; /* index into jsid array */
<     JSIdArray               *ida;       /* all property ids in enumeration */
<     JSNativeIteratorState   *next;      /* double-linked list support */
<     JSNativeIteratorState   **prevp;
< };
---
> typedef struct JSNativeIteratorState {
>     jsint next_index;   /* index into jsid array */
>     JSIdArray *ida;     /* All property ids in enumeration */
> } JSNativeIteratorState;
4088,4089c3138
<     JSRuntime *rt;
<     JSObject *proto;
---
>     JSObject *proto_obj;
4098d3146
<     rt = cx->runtime;
4105c3153,3154
<       case JSENUMERATE_INIT:
---
> 
>     case JSENUMERATE_INIT:
4107c3156
<             return JS_FALSE;
---
>             goto init_error;
4123,4124c3172,3173
<         proto = OBJ_GET_PROTO(cx, obj);
<         if (proto && scope == OBJ_SCOPE(proto)) {
---
>         proto_obj = OBJ_GET_PROTO(cx, obj);
>         if (proto_obj && scope == OBJ_SCOPE(proto_obj)) {
4128c3177
<                 return JS_FALSE;
---
>                 goto init_error;
4144c3193
<                 return JS_FALSE;
---
>                 goto init_error;
4158a3208
> 		XMEMTAG("jsobj JSNativeIteratorState");
4163c3213
<             return JS_FALSE;
---
>             goto init_error;
4167,4175d3216
< 
<         JS_LOCK_RUNTIME(rt);
<         state->next = rt->nativeIteratorStates;
<         if (state->next)
<             state->next->prevp = &state->next;
<         state->prevp = &rt->nativeIteratorStates;
<         *state->prevp = state;
<         JS_UNLOCK_RUNTIME(rt);
< 
4179c3220
<         break;
---
>         return JS_TRUE;
4181c3222
<       case JSENUMERATE_NEXT:
---
>     case JSENUMERATE_NEXT:
4187,4199c3228
<             break;
<         }
<         /* FALL THROUGH */
< 
<       case JSENUMERATE_DESTROY:
<         state = (JSNativeIteratorState *) JSVAL_TO_PRIVATE(*statep);
< 
<         JS_LOCK_RUNTIME(rt);
<         JS_ASSERT(rt->nativeIteratorStates);
<         JS_ASSERT(*state->prevp == state);
<         if (state->next) {
<             JS_ASSERT(state->next->prevp == &state->next);
<             state->next->prevp = state->prevp;
---
>             return JS_TRUE;
4201,4202d3229
<         *state->prevp = state->next;
<         JS_UNLOCK_RUNTIME(rt);
4204,4210c3231
<         JS_DestroyIdArray(cx, state->ida);
<         JS_free(cx, state);
<         *statep = JSVAL_NULL;
<         break;
<     }
<     return JS_TRUE;
< }
---
>         /* Fall through ... */
4212,4216c3233,3238
< void
< js_TraceNativeIteratorStates(JSTracer *trc)
< {
<     JSNativeIteratorState *state;
<     jsid *cursor, *end, id;
---
>     case JSENUMERATE_DESTROY:
>         state = (JSNativeIteratorState *) JSVAL_TO_PRIVATE(*statep);
>         JS_DestroyIdArray(cx, state->ida);
>         JS_free(cx, state);
>         *statep = JSVAL_NULL;
>         return JS_TRUE;
4218,4220c3240,3243
<     state = trc->context->runtime->nativeIteratorStates;
<     if (!state)
<         return;
---
>     default:
>         JS_ASSERT(0);
>         return JS_FALSE;
>     }
4222,4230c3245,3247
<     do {
<         JS_ASSERT(*state->prevp == state);
<         cursor = state->ida->vector;
<         end = cursor + state->ida->length;
<         for (; cursor != end; ++cursor) {
<             id = *cursor;
<             TRACE_ID(trc, id);
<         }
<     } while ((state = state->next) != NULL);
---
> init_error:
>     *statep = JSVAL_NULL;
>     return JS_FALSE;
4237d3253
<     JSBool writing;
4240d3255
<     JSClass *clasp;
4242,4274c3257,3258
<     JSCheckAccessOp check;
< 
<     writing = (mode & JSACC_WRITE) != 0;
<     switch (mode & JSACC_TYPEMASK) {
<       case JSACC_PROTO:
<         pobj = obj;
<         if (!writing)
<             *vp = OBJECT_TO_JSVAL(OBJ_GET_PROTO(cx, obj));
<         *attrsp = JSPROP_PERMANENT;
<         break;
< 
<       case JSACC_PARENT:
<         JS_ASSERT(!writing);
<         pobj = obj;
<         *vp = OBJECT_TO_JSVAL(OBJ_GET_PARENT(cx, obj));
<         *attrsp = JSPROP_READONLY | JSPROP_PERMANENT;
<         break;
< 
<       default:
<         if (!js_LookupProperty(cx, obj, id, &pobj, &prop))
<             return JS_FALSE;
<         if (!prop) {
<             if (!writing)
<                 *vp = JSVAL_VOID;
<             *attrsp = 0;
<             clasp = OBJ_GET_CLASS(cx, obj);
<             return !clasp->checkAccess ||
<                    clasp->checkAccess(cx, obj, ID_TO_VALUE(id), mode, vp);
<         }
<         if (!OBJ_IS_NATIVE(pobj)) {
<             OBJ_DROP_PROPERTY(cx, pobj, prop);
<             return OBJ_CHECK_ACCESS(cx, pobj, id, mode, vp, attrsp);
<         }
---
>     JSClass *clasp;
>     JSBool ok;
4276,4282c3260,3269
<         sprop = (JSScopeProperty *)prop;
<         *attrsp = sprop->attrs;
<         if (!writing) {
<             *vp = (SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(pobj)))
<                   ? LOCKED_OBJ_GET_SLOT(pobj, sprop->slot)
<                   : JSVAL_VOID;
<         }
---
>     if (!js_LookupProperty(cx, obj, id, &pobj, &prop))
>         return JS_FALSE;
>     if (!prop) {
>         *vp = JSVAL_VOID;
>         *attrsp = 0;
>         clasp = OBJ_GET_CLASS(cx, obj);
>         return !clasp->checkAccess ||
>                clasp->checkAccess(cx, obj, ID_TO_VALUE(id), mode, vp);
>     }
>     if (!OBJ_IS_NATIVE(pobj)) {
4283a3271
>         return OBJ_CHECK_ACCESS(cx, pobj, id, mode, vp, attrsp);
4285,4302c3273,3287
< 
<     /*
<      * If obj's class has a stub (null) checkAccess hook, use the per-runtime
<      * checkObjectAccess callback, if configured.
<      *
<      * We don't want to require all classes to supply a checkAccess hook; we
<      * need that hook only for certain classes used when precompiling scripts
<      * and functions ("brutal sharing").  But for general safety of built-in
<      * magic properties such as __proto__ and __parent__, we route all access
<      * checks, even for classes that stub out checkAccess, through the global
<      * checkObjectAccess hook.  This covers precompilation-based sharing and
<      * (possibly unintended) runtime sharing across trust boundaries.
<      */
<     clasp = OBJ_GET_CLASS(cx, pobj);
<     check = clasp->checkAccess;
<     if (!check)
<         check = cx->runtime->checkObjectAccess;
<     return !check || check(cx, pobj, ID_TO_VALUE(id), mode, vp);
---
>     sprop = (JSScopeProperty *)prop;
>     *vp = (SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(pobj)))
>           ? LOCKED_OBJ_GET_SLOT(pobj, sprop->slot)
>           : JSVAL_VOID;
>     *attrsp = sprop->attrs;
>     clasp = LOCKED_OBJ_GET_CLASS(obj);
>     if (clasp->checkAccess) {
>         JS_UNLOCK_OBJ(cx, pobj);
>         ok = clasp->checkAccess(cx, obj, ID_TO_VALUE(id), mode, vp);
>         JS_LOCK_OBJ(cx, pobj);
>     } else {
>         ok = JS_TRUE;
>     }
>     OBJ_DROP_PROPERTY(cx, pobj, prop);
>     return ok;
4313,4315c3298,3299
< #ifdef NARCISSUS
< static JSBool
< GetCurrentExecutionContext(JSContext *cx, JSObject *obj, jsval *rval)
---
> static void
> ReportIsNotFunction(JSContext *cx, jsval *vp, JSBool constructing)
4317,4318c3301,3306
<     JSObject *tmp;
<     jsval xcval;
---
>     /*
>      * The decompiler may need to access the args of the function in
>      * progress rather than the one we had hoped to call.
>      * So we switch the cx->fp to the frame below us. We stick the
>      * current frame in the dormantFrameChain to protect it from gc.
>      */
4320,4330c3308,3313
<     while ((tmp = OBJ_GET_PARENT(cx, obj)) != NULL)
<         obj = tmp;
<     if (!OBJ_GET_PROPERTY(cx, obj,
<                           ATOM_TO_JSID(cx->runtime->atomState
<                                        .ExecutionContextAtom),
<                           &xcval)) {
<         return JS_FALSE;
<     }
<     if (JSVAL_IS_PRIMITIVE(xcval)) {
<         JS_ReportError(cx, "invalid ExecutionContext in global object");
<         return JS_FALSE;
---
>     JSStackFrame *fp = cx->fp;
>     if (fp->down) {
>         JS_ASSERT(!fp->dormantNext);
>         fp->dormantNext = cx->dormantFrameChain;
>         cx->dormantFrameChain = fp;
>         cx->fp = fp->down;
4332,4335c3315,3322
<     if (!OBJ_GET_PROPERTY(cx, JSVAL_TO_OBJECT(xcval),
<                           ATOM_TO_JSID(cx->runtime->atomState.currentAtom),
<                           rval)) {
<         return JS_FALSE;
---
> 
>     js_ReportIsNotFunction(cx, vp, constructing);
> 
>     if (fp->down) {
>         JS_ASSERT(cx->dormantFrameChain == fp);
>         cx->dormantFrameChain = fp->dormantNext;
>         fp->dormantNext = NULL;
>         cx->fp = fp;
4337d3323
<     return JS_TRUE;
4339d3324
< #endif
4348,4376c3333
< #ifdef NARCISSUS
<         JSObject *callee, *args;
<         jsval fval, nargv[3];
<         JSBool ok;
< 
<         callee = JSVAL_TO_OBJECT(argv[-2]);
<         if (!OBJ_GET_PROPERTY(cx, callee,
<                               ATOM_TO_JSID(cx->runtime->atomState.callAtom),
<                               &fval)) {
<             return JS_FALSE;
<         }
<         if (VALUE_IS_FUNCTION(cx, fval)) {
<             if (!GetCurrentExecutionContext(cx, obj, &nargv[2]))
<                 return JS_FALSE;
<             args = js_GetArgsObject(cx, cx->fp);
<             if (!args)
<                 return JS_FALSE;
<             nargv[0] = OBJECT_TO_JSVAL(obj);
<             nargv[1] = OBJECT_TO_JSVAL(args);
<             return js_InternalCall(cx, callee, fval, 3, nargv, rval);
<         }
<         if (JSVAL_IS_OBJECT(fval) && JSVAL_TO_OBJECT(fval) != callee) {
<             argv[-2] = fval;
<             ok = js_Call(cx, obj, argc, argv, rval);
<             argv[-2] = OBJECT_TO_JSVAL(callee);
<             return ok;
<         }
< #endif
<         js_ReportIsNotFunction(cx, &argv[-2], cx->fp->flags & JSFRAME_ITERATOR);
---
>         ReportIsNotFunction(cx, &argv[-2], JS_FALSE);
4390,4418c3347
< #ifdef NARCISSUS
<         JSObject *callee, *args;
<         jsval cval, nargv[2];
<         JSBool ok;
< 
<         callee = JSVAL_TO_OBJECT(argv[-2]);
<         if (!OBJ_GET_PROPERTY(cx, callee,
<                               ATOM_TO_JSID(cx->runtime->atomState
<                                            .constructAtom),
<                               &cval)) {
<             return JS_FALSE;
<         }
<         if (VALUE_IS_FUNCTION(cx, cval)) {
<             if (!GetCurrentExecutionContext(cx, obj, &nargv[1]))
<                 return JS_FALSE;
<             args = js_GetArgsObject(cx, cx->fp);
<             if (!args)
<                 return JS_FALSE;
<             nargv[0] = OBJECT_TO_JSVAL(args);
<             return js_InternalCall(cx, callee, cval, 2, nargv, rval);
<         }
<         if (JSVAL_IS_OBJECT(cval) && JSVAL_TO_OBJECT(cval) != callee) {
<             argv[-2] = cval;
<             ok = js_Call(cx, obj, argc, argv, rval);
<             argv[-2] = OBJECT_TO_JSVAL(callee);
<             return ok;
<         }
< #endif
<         js_ReportIsNotFunction(cx, &argv[-2], JSV2F_CONSTRUCT);
---
>         ReportIsNotFunction(cx, &argv[-2], JS_TRUE);
4432,4452c3361,3362
< #ifdef NARCISSUS
<     {
<         jsval fval, rval;
< 
<         if (!OBJ_GET_PROPERTY(cx, obj,
<                               ATOM_TO_JSID(cx->runtime->atomState
<                                            .hasInstanceAtom),
<                               &fval)) {
<             return JS_FALSE;
<         }
<         if (VALUE_IS_FUNCTION(cx, fval)) {
<             if (!js_InternalCall(cx, obj, fval, 1, &v, &rval))
<                 return JS_FALSE;
<             *bp = js_ValueToBoolean(rval);
<             return JS_TRUE;
<         }
<     }
< #endif
<     js_ReportValueError(cx, JSMSG_BAD_INSTANCEOF_RHS,
<                         JSDVG_SEARCH_STACK, OBJECT_TO_JSVAL(obj), NULL);
<     return JS_FALSE;
---
>     *bp = JS_FALSE;
>     return JS_TRUE;
4474,4475c3384,3391
< js_GetClassPrototype(JSContext *cx, JSObject *scope, jsid id,
<                      JSObject **protop)
---
> js_GetClassPrototype(JSContext *cx, const char *name, JSObject **protop)
> {
>     return GetClassPrototype(cx, NULL, name, protop);
> }
> 
> static JSBool
> GetClassPrototype(JSContext *cx, JSObject *scope, const char *name,
>                   JSObject **protop)
4480c3396
<     if (!js_FindClassObject(cx, scope, id, &v))
---
>     if (!FindConstructor(cx, scope, name, &v))
4482c3398
<     if (VALUE_IS_FUNCTION(cx, v)) {
---
>     if (JSVAL_IS_FUNCTION(cx, v)) {
4485,4486c3401
<                               ATOM_TO_JSID(cx->runtime->atomState
<                                            .classPrototypeAtom),
---
>                               (jsid)cx->runtime->atomState.classPrototypeAtom,
4490,4501d3404
<         if (!JSVAL_IS_PRIMITIVE(v)) {
<             /*
<              * Set the newborn root in case v is otherwise unreferenced.
<              * It's ok to overwrite newborn roots here, since the getter
<              * called just above could have.  Unlike the common GC rooting
<              * model, our callers do not have to protect protop thanks to
<              * this newborn root, since they all immediately create a new
<              * instance that delegates to this object, or just query the
<              * prototype for its class.
<              */
<             cx->weakRoots.newborn[GCX_OBJECT] = JSVAL_TO_GCTHING(v);
<         }
4507,4545d3409
< /*
<  * For shared precompilation of function objects, we support cloning on entry
<  * to an execution context in which the function declaration or expression
<  * should be processed as if it were not precompiled, where the precompiled
<  * function's scope chain does not match the execution context's.  The cloned
<  * function object carries its execution-context scope in its parent slot; it
<  * links to the precompiled function (the "clone-parent") via its proto slot.
<  *
<  * Note that this prototype-based delegation leaves an unchecked access path
<  * from the clone to the clone-parent's 'constructor' property.  If the clone
<  * lives in a less privileged or shared scope than the clone-parent, this is
<  * a security hole, a sharing hazard, or both.  Therefore we check all such
<  * accesses with the following getter/setter pair, which we use when defining
<  * 'constructor' in f.prototype for all function objects f.
<  */
< static JSBool
< CheckCtorGetAccess(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
< {
<     JSAtom *atom;
<     uintN attrs;
< 
<     atom = cx->runtime->atomState.constructorAtom;
<     JS_ASSERT(id == ATOM_TO_JSID(atom));
<     return OBJ_CHECK_ACCESS(cx, obj, ATOM_TO_JSID(atom), JSACC_READ,
<                             vp, &attrs);
< }
< 
< static JSBool
< CheckCtorSetAccess(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
< {
<     JSAtom *atom;
<     uintN attrs;
< 
<     atom = cx->runtime->atomState.constructorAtom;
<     JS_ASSERT(id == ATOM_TO_JSID(atom));
<     return OBJ_CHECK_ACCESS(cx, obj, ATOM_TO_JSID(atom), JSACC_WRITE,
<                             vp, &attrs);
< }
< 
4552,4554c3416,3418
<      * as user-defined constructors have a DontDelete prototype (which may be
<      * reset), while native or "system" constructors have DontEnum | ReadOnly |
<      * DontDelete.
---
>      * as user-defined constructors have a DontEnum | DontDelete prototype (it
>      * may be reset), while native or "system" constructors require DontEnum |
>      * ReadOnly | DontDelete.
4557,4560c3421,3422
<                              ATOM_TO_JSID(cx->runtime->atomState
<                                           .classPrototypeAtom),
<                              OBJECT_TO_JSVAL(proto),
<                              JS_PropertyStub, JS_PropertyStub,
---
>                              (jsid)cx->runtime->atomState.classPrototypeAtom,
>                              OBJECT_TO_JSVAL(proto), NULL, NULL,
4570,4573c3432,3433
<                                ATOM_TO_JSID(cx->runtime->atomState
<                                             .constructorAtom),
<                                OBJECT_TO_JSVAL(ctor),
<                                CheckCtorGetAccess, CheckCtorSetAccess,
---
>                                (jsid)cx->runtime->atomState.constructorAtom,
>                                OBJECT_TO_JSVAL(ctor), NULL, NULL,
4578,4609d3437
< js_PrimitiveToObject(JSContext *cx, jsval *vp)
< {
<     JSClass *clasp;
<     JSObject *obj;
< 
<     /* Table to map primitive value's tag into the corresponding class. */
<     JS_STATIC_ASSERT(JSVAL_INT == 1);
<     JS_STATIC_ASSERT(JSVAL_DOUBLE == 2);
<     JS_STATIC_ASSERT(JSVAL_STRING == 4);
<     JS_STATIC_ASSERT(JSVAL_BOOLEAN == 6);
<     static JSClass *const PrimitiveClasses[] = {
<         &js_NumberClass,    /* INT     */
<         &js_NumberClass,    /* DOUBLE  */
<         &js_NumberClass,    /* INT     */
<         &js_StringClass,    /* STRING  */
<         &js_NumberClass,    /* INT     */
<         &js_BooleanClass,   /* BOOLEAN */
<         &js_NumberClass     /* INT     */
<     };
< 
<     JS_ASSERT(!JSVAL_IS_OBJECT(*vp));
<     JS_ASSERT(*vp != JSVAL_VOID);
<     clasp = PrimitiveClasses[JSVAL_TAG(*vp) - 1];
<     obj = js_NewObject(cx, clasp, NULL, NULL);
<     if (!obj)
<         return JS_FALSE;
<     STOBJ_SET_SLOT(obj, JSSLOT_PRIVATE, *vp);
<     *vp = OBJECT_TO_JSVAL(obj);
<     return JS_TRUE;
< }
< 
< JSBool
4623c3451,3461
<         if (!js_PrimitiveToObject(cx, &v))
---
>         if (JSVAL_IS_STRING(v)) {
>             obj = js_StringToObject(cx, JSVAL_TO_STRING(v));
>         } else if (JSVAL_IS_INT(v)) {
>             obj = js_NumberToObject(cx, (jsdouble)JSVAL_TO_INT(v));
>         } else if (JSVAL_IS_DOUBLE(v)) {
>             obj = js_NumberToObject(cx, *JSVAL_TO_DOUBLE(v));
>         } else {
>             JS_ASSERT(JSVAL_IS_BOOLEAN(v));
>             obj = js_BooleanToObject(cx, JSVAL_TO_BOOLEAN(v));
>         }
>         if (!obj)
4625d3462
<         obj = JSVAL_TO_OBJECT(v);
4634a3472
>     JSString *str;
4638,4639c3476,3482
<     if (!obj)
<         js_ReportIsNullOrUndefined(cx, JSDVG_SEARCH_STACK, v, NULL);
---
>     if (!obj) {
>         str = js_DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, NULL);
>         if (str) {
>             JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
>                                  JSMSG_NO_PROPERTIES, JS_GetStringBytes(str));
>         }
>     }
4645a3489
> #if JS_HAS_VALUEOF_HINT
4650a3495,3498
> #else
>     return js_TryMethod(cx, obj, cx->runtime->atomState.valueOfAtom, 0, NULL,
>                         rval);
> #endif
4658d3505
<     jsid id;
4662,4663d3508
<     JS_CHECK_RECURSION(cx, return JS_FALSE);
< 
4670,4682c3515,3519
<     id = ATOM_TO_JSID(atom);
<     fval = JSVAL_VOID;
< #if JS_HAS_XML_SUPPORT
<     if (OBJECT_IS_XML(cx, obj)) {
<         JSXMLObjectOps *ops;
< 
<         ops = (JSXMLObjectOps *) obj->map->ops;
<         obj = ops->getMethod(cx, obj, id, &fval);
<         ok = (obj != NULL);
<     } else
< #endif
<     {
<         ok = OBJ_GET_PROPERTY(cx, obj, id, &fval);
---
>     if (OBJ_GET_PROPERTY(cx, obj, (jsid)atom, &fval) &&
>         !JSVAL_IS_PRIMITIVE(fval)) {
>         ok = js_InternalCall(cx, obj, fval, argc, argv, rval);
>     } else {
>         ok = JS_TRUE;
4684,4685d3520
<     if (!ok)
<         JS_ClearPendingException(cx);
4687,4689c3522
< 
<     return JSVAL_IS_PRIMITIVE(fval) ||
<            js_InternalCall(cx, obj, fval, argc, argv, rval);
---
>     return ok;
4693a3527,3528
> #include "jsxdrapi.h"
> 
4698d3532
<     JSAtom *atom;
4699a3534
>     const char *className;
4701,4702c3536
<     JSProtoKey protoKey;
<     jsid classKey;
---
>     JSBool ok;
4706d3539
<     atom = NULL;
4709c3542,3543
<         classId = JS_XDRFindClassIdByName(xdr, clasp->name);
---
>         className = clasp->name;
>         classId = JS_XDRFindClassIdByName(xdr, className);
4711,4722c3545,3546
<         if (classDef) {
<             if (!JS_XDRRegisterClass(xdr, clasp, &classId))
<                 return JS_FALSE;
<             protoKey = JSCLASS_CACHED_PROTO_KEY(clasp);
<             if (protoKey != JSProto_Null) {
<                 classDef |= (protoKey << 1);
<             } else {
<                 atom = js_Atomize(cx, clasp->name, strlen(clasp->name), 0);
<                 if (!atom)
<                     return JS_FALSE;
<             }
<         }
---
>         if (classDef && !JS_XDRRegisterClass(xdr, clasp, &classId))
>             return JS_FALSE;
4724d3547
<         clasp = NULL;           /* quell GCC overwarning */
4725a3549,3550
>         className = NULL;
>         clasp = NULL;           /* quell GCC overwarning */
4728,4735c3553
<     /*
<      * XDR a flag word, which could be 0 for a class use, in which case no
<      * name follows, only the id in xdr's class registry; 1 for a class def,
<      * in which case the flag word is followed by the class name transferred
<      * from or to atom; or a value greater than 1, an odd number that when
<      * divided by two yields the JSProtoKey for class.  In the last case, as
<      * in the 0 classDef case, no name is transferred via atom.
<      */
---
>     /* XDR a flag word followed (if true) by the class name. */
4738c3556
<     if (classDef == 1 && !js_XDRStringAtom(xdr, &atom))
---
>     if (classDef && !JS_XDRCString(xdr, (char **) &className))
4741,4742c3559,3562
<     if (!JS_XDRUint32(xdr, &classId))
<         return JS_FALSE;
---
>     /* From here on, return through out: to free className if it was set. */
>     ok = JS_XDRUint32(xdr, &classId);
>     if (!ok)
>         goto out;
4744c3564
<     if (xdr->mode == JSXDR_DECODE) {
---
>     if (xdr->mode != JSXDR_ENCODE) {
4746,4752c3566,3568
<             /* NB: we know that JSProto_Null is 0 here, for backward compat. */
<             protoKey = (JSProtoKey) (classDef >> 1);
<             classKey = (protoKey != JSProto_Null)
<                        ? INT_TO_JSID(protoKey)
<                        : ATOM_TO_JSID(atom);
<             if (!js_GetClassPrototype(cx, NULL, classKey, &proto))
<                 return JS_FALSE;
---
>             ok = js_GetClassPrototype(cx, className, &proto);
>             if (!ok)
>                 goto out;
4754,4755c3570,3572
<             if (!JS_XDRRegisterClass(xdr, clasp, &classId))
<                 return JS_FALSE;
---
>             ok = JS_XDRRegisterClass(xdr, clasp, &classId);
>             if (!ok)
>                 goto out;
4763c3580,3581
<                 return JS_FALSE;
---
>                 ok = JS_FALSE;
>                 goto out;
4771c3589,3591
<         return JS_FALSE;
---
>         ok = JS_FALSE;
>     } else {
>         ok = clasp->xdrObject(xdr, objp);
4773c3593,3596
<     return clasp->xdrObject(xdr, objp);
---
> out:
>     if (xdr->mode != JSXDR_ENCODE && className)
>         JS_free(cx, (void *)className);
>     return ok;
4778c3601
< #ifdef JS_DUMP_SCOPE_METERS
---
> #ifdef DEBUG_brendan
4780a3604
> #include <math.h>
4782c3606,3609
< JSBasicStats js_entry_count_bs = JS_INIT_STATIC_BASIC_STATS;
---
> uint32 js_entry_count_max;
> uint32 js_entry_count_sum;
> double js_entry_count_sqsum;
> uint32 js_entry_count_hist[11];
4787c3614,3620
<     JS_BASIC_STATS_ACCUM(&js_entry_count_bs, count);
---
>     if (count) {
>         js_entry_count_sum += count;
>         js_entry_count_sqsum += (double)count * count;
>         if (count > js_entry_count_max)
>             js_entry_count_max = count;
>     }
>     js_entry_count_hist[JS_MIN(count, 10)]++;
4798,4800c3631,3640
<         double mean, sigma;
< 
<         mean = JS_MeanAndStdDevBS(&js_entry_count_bs, &sigma);
---
>         double mean = 0., var = 0., sigma = 0.;
>         double nscopes = rt->liveScopes;
>         double nentrys = js_entry_count_sum;
>         if (nscopes > 0 && nentrys >= 0) {
>             mean = nentrys / nscopes;
>             var = nscopes * js_entry_count_sqsum - nentrys * nentrys;
>             if (var < 0.0 || nscopes <= 1)
>                 var = 0.0;
>             else
>                 var /= nscopes * (nscopes - 1);
4802,4805c3642,3644
<         fprintf(logfp, "scopes %u entries %g mean %g sigma %g max %u",
<                 js_entry_count_bs.num, js_entry_count_bs.sum, mean, sigma,
<                 js_entry_count_bs.max);
<     }
---
>             /* Windows says sqrt(0.0) is "-1.#J" (?!) so we must test. */
>             sigma = (var != 0.) ? sqrt(var) : 0.;
>         }
4807,4808c3646,3660
<     JS_DumpHistogram(&js_entry_count_bs, logfp);
<     JS_BASIC_STATS_INIT(&js_entry_count_bs);
---
>         fprintf(logfp,
>                 "scopes %g entries %g mean %g sigma %g max %u",
>                 nscopes, nentrys, mean, sigma, js_entry_count_max);
>     }
> 
>     fprintf(logfp, " histogram %u %u %u %u %u %u %u %u %u %u %u\n",
>             js_entry_count_hist[0], js_entry_count_hist[1],
>             js_entry_count_hist[2], js_entry_count_hist[3],
>             js_entry_count_hist[4], js_entry_count_hist[5],
>             js_entry_count_hist[6], js_entry_count_hist[7],
>             js_entry_count_hist[8], js_entry_count_hist[9],
>             js_entry_count_hist[10]);
>     js_entry_count_sum = js_entry_count_max = 0;
>     js_entry_count_sqsum = 0;
>     memset(js_entry_count_hist, 0, sizeof js_entry_count_hist);
4811,4828d3662
< #endif
< 
< #ifdef DEBUG
< static void
< PrintObjectSlotName(JSTracer *trc, char *buf, size_t bufsize)
< {
<     JSObject *obj;
<     uint32 slot;
<     JSScope *scope;
<     jsval nval;
<     JSScopeProperty *sprop;
<     JSClass *clasp;
<     uint32 key;
<     const char *slotname;
< 
<     JS_ASSERT(trc->debugPrinter == PrintObjectSlotName);
<     obj = (JSObject *)trc->debugPrintArg;
<     slot = (uint32)trc->debugPrintIndex;
4830,4871c3664
<     scope = OBJ_SCOPE(obj);
<     sprop = SCOPE_LAST_PROP(scope);
<     while (sprop && sprop->slot != slot)
<         sprop = sprop->parent;
< 
<     if (!sprop) {
<         switch (slot) {
<           case JSSLOT_PROTO:
<             JS_snprintf(buf, bufsize, "__proto__");
<             break;
<           case JSSLOT_PARENT:
<             JS_snprintf(buf, bufsize, "__parent__");
<             break;
<           default:
<             slotname = NULL;
<             clasp = LOCKED_OBJ_GET_CLASS(obj);
<             if (clasp->flags & JSCLASS_IS_GLOBAL) {
<                 key = slot - JSSLOT_START(clasp);
< #define JS_PROTO(name,code,init) \
<     if ((code) == key) { slotname = js_##name##_str; goto found; }
< #include "jsproto.tbl"
< #undef JS_PROTO
<             }
<           found:
<             if (slotname)
<                 JS_snprintf(buf, bufsize, "CLASS_OBJECT(%s)", slotname);
<             else
<                 JS_snprintf(buf, bufsize, "**UNKNOWN SLOT %ld**", (long)slot);
<             break;
<         }
<     } else {
<         nval = ID_TO_VALUE(sprop->id);
<         if (JSVAL_IS_INT(nval)) {
<             JS_snprintf(buf, bufsize, "%ld", (long)JSVAL_TO_INT(nval));
<         } else if (JSVAL_IS_STRING(nval)) {
<             js_PutEscapedString(buf, bufsize, JSVAL_TO_STRING(nval), 0);
<         } else {
<             JS_snprintf(buf, bufsize, "**FINALIZED ATOM KEY**");
<         }
<     }
< }
< #endif
---
> #endif /* DEBUG_brendan */
4873,4874c3666,3667
< void
< js_TraceObject(JSTracer *trc, JSObject *obj)
---
> uint32
> js_Mark(JSContext *cx, JSObject *obj, void *arg)
4876d3668
<     JSContext *cx;
4878d3669
<     JSBool traceScope;
4881,4882d3671
<     size_t nslots, i;
<     jsval v;
4885d3673
<     cx = trc->context;
4887,4908c3675,3676
< 
<     traceScope = (scope->object == obj);
<     if (!traceScope) {
<         JSObject *pobj = obj;
< 
<         /*
<          * Because obj does not own scope, we should be able to assert that an
<          * object on obj's prototype chain does -- or scope's properties might
<          * go untraced. It indeed turns out that you can disconnect an object
<          * from the prototype object whose scope it shares, so we may have to
<          * mark scope even though scope->object != obj.
<          */
<         while ((pobj = LOCKED_OBJ_GET_PROTO(pobj)) != NULL) {
<             if (pobj == scope->object)
<                 break;
<         }
<         JS_ASSERT_IF(pobj, OBJ_SCOPE(pobj) == scope);
<         traceScope = !pobj;
<     }
< 
<     if (traceScope) {
< #ifdef JS_DUMP_SCOPE_METERS
---
> #ifdef DEBUG_brendan
>     if (scope->object == obj)
4912,4914c3680,3681
<         sprop = SCOPE_LAST_PROP(scope);
<         if (sprop) {
<             JS_ASSERT(SCOPE_HAS_PROPERTY(scope, sprop));
---
>     JS_ASSERT(!SCOPE_LAST_PROP(scope) ||
>               SCOPE_HAS_PROPERTY(scope, SCOPE_LAST_PROP(scope)));
4916,4931c3683,3688
<             /* Regenerate property cache shape ids if GC'ing. */
<             if (IS_GC_MARKING_TRACER(trc)) {
<                 uint32 shape, oldshape;
< 
<                 shape = ++cx->runtime->shapeGen;
<                 JS_ASSERT(shape != 0);
< 
<                 if (!(sprop->flags & SPROP_MARK)) {
<                     oldshape = sprop->shape;
<                     sprop->shape = shape;
<                     sprop->flags |= SPROP_FLAG_SHAPE_REGEN;
<                     if (scope->shape != oldshape) {
<                         shape = ++cx->runtime->shapeGen;
<                         JS_ASSERT(shape != 0);
<                     }
<                 }
---
>     for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) {
>         if (SCOPE_HAD_MIDDLE_DELETE(scope) && !SCOPE_HAS_PROPERTY(scope, sprop))
>             continue;
>         MARK_SCOPE_PROPERTY(sprop);
>         if (!JSVAL_IS_INT(sprop->id))
>             GC_MARK_ATOM(cx, (JSAtom *)sprop->id, arg);
4933c3690,3718
<                 scope->shape = shape;
---
> #if JS_HAS_GETTER_SETTER
>         if (sprop->attrs & (JSPROP_GETTER | JSPROP_SETTER)) {
> #ifdef GC_MARK_DEBUG
>             char buf[64];
>             JSAtom *atom = (JSAtom *)sprop->id;
>             const char *id = (atom && ATOM_IS_STRING(atom))
>                              ? JS_GetStringBytes(ATOM_TO_STRING(atom))
>                              : "unknown";
> #endif
> 
>             if (sprop->attrs & JSPROP_GETTER) {
> #ifdef GC_MARK_DEBUG
>                 JS_snprintf(buf, sizeof buf, "%s %s",
>                             id, js_getter_str);
> #endif
>                 GC_MARK(cx,
>                         JSVAL_TO_GCTHING((jsval) sprop->getter),
>                         buf,
>                         arg);
>             }
>             if (sprop->attrs & JSPROP_SETTER) {
> #ifdef GC_MARK_DEBUG
>                 JS_snprintf(buf, sizeof buf, "%s %s",
>                             id, js_setter_str);
> #endif
>                 GC_MARK(cx,
>                         JSVAL_TO_GCTHING((jsval) sprop->setter),
>                         buf,
>                         arg);
4935,4943d3719
< 
<             /* Trace scope's property tree ancestor line. */
<             do {
<                 if (SCOPE_HAD_MIDDLE_DELETE(scope) &&
<                     !SCOPE_HAS_PROPERTY(scope, sprop)) {
<                     continue;
<                 }
<                 TRACE_SCOPE_PROPERTY(trc, sprop);
<             } while ((sprop = sprop->parent) != NULL);
4944a3721
> #endif /* JS_HAS_GETTER_SETTER */
4947,4949d3723
<     if (!JS_CLIST_IS_EMPTY(&cx->runtime->watchPointList))
<         js_TraceWatchPoints(trc, obj);
< 
4952,4957c3726,3727
<     if (clasp->mark) {
<         if (clasp->flags & JSCLASS_MARK_IS_TRACE)
<             ((JSTraceOp) clasp->mark)(trc, obj);
<         else if (IS_GC_MARKING_TRACER(trc))
<             (void) clasp->mark(cx, obj, trc);
<     }
---
>     if (clasp->mark)
>         (void) clasp->mark(cx, obj, arg);
4959,4977c3729,3735
<     /*
<      * An unmutated object that shares a prototype object's scope. We can't
<      * tell how many slots are in use in obj by looking at its scope, so we
<      * use STOBJ_NSLOTS(obj).
<      *
<      * NB: In case clasp->mark mutates something, leave this code here --
<      * don't move it up and unify it with the |if (!traceScope)| section
<      * above.
<      */
<     nslots = (scope->object != obj)
<              ? STOBJ_NSLOTS(obj)
<              : LOCKED_OBJ_NSLOTS(obj);
< 
<     for (i = 0; i != nslots; ++i) {
<         v = STOBJ_GET_SLOT(obj, i);
<         if (JSVAL_IS_TRACEABLE(v)) {
<             JS_SET_TRACING_DETAILS(trc, PrintObjectSlotName, obj, i);
<             JS_CallTracer(trc, JSVAL_TO_TRACEABLE(v), JSVAL_TRACE_KIND(v));
<         }
---
>     if (scope->object != obj) {
>         /*
>          * An unmutated object that shares a prototype's scope.  We can't tell
>          * how many slots are allocated and in use at obj->slots by looking at
>          * scope, so we get obj->slots' length from its -1'st element.
>          */
>         return (uint32) obj->slots[-1];
4978a3737
>     return JS_MIN(obj->map->freeslot, obj->map->nslots);
4984a3744,3745
>     JSRuntime *rt;
>     JSScopeProperty *sprop;
4995a3757,3765
>         /* Clear the property cache before we clear the scope. */
>         rt = cx->runtime;
>         for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) {
>             if (!SCOPE_HAD_MIDDLE_DELETE(scope) ||
>                 SCOPE_HAS_PROPERTY(scope, sprop)) {
>                 PROPERTY_CACHE_FILL(&rt->propertyCache, obj, sprop->id, NULL);
>             }
>         }
> 
5000c3770
<         i = STOBJ_NSLOTS(obj);
---
>         i = scope->map.nslots;
5003c3773
<             STOBJ_SET_SLOT(obj, i, JSVAL_VOID);
---
>             obj->slots[i] = JSVAL_VOID;
5015c3785
<     v = (slot < STOBJ_NSLOTS(obj)) ? STOBJ_GET_SLOT(obj, slot) : JSVAL_VOID;
---
>     v = (slot < (uint32) obj->slots[-1]) ? obj->slots[slot] : JSVAL_VOID;
5020c3790
< JSBool
---
> void
5023,5024c3793
<     JSScope *scope;
<     uint32 nslots;
---
>     uint32 nslots, rlimit, i;
5025a3795
>     jsval *newslots;
5028,5040c3798,3799
<     scope = OBJ_SCOPE(obj);
<     if (slot >= JS_INITIAL_NSLOTS && !obj->dslots) {
<         /*
<          * At this point, obj may or may not own scope.  If some path calls
<          * js_GetMutableScope but does not add a slot-owning property, then
<          * scope->object == obj but obj->dslots will be null. If obj shares a
<          * prototype's scope, then we cannot update scope->map here. Instead
<          * we rely on STOBJ_NSLOTS(obj) to get the number of available slots
<          * in obj after we allocate dynamic slots.
<          *
<          * See js_TraceObject, before the slot tracing, where we make a special
<          * case for unmutated (scope->object != obj) objects.
<          */
---
>     nslots = (uint32) obj->slots[-1];
>     if (slot >= nslots) {
5042,5048c3801,3810
<         nslots = JSSLOT_FREE(clasp);
<         if (clasp->reserveSlots)
<             nslots += clasp->reserveSlots(cx, obj);
<         JS_ASSERT(slot < nslots);
<         if (!ReallocSlots(cx, obj, nslots, JS_TRUE)) {
<             JS_UNLOCK_SCOPE(cx, scope);
<             return JS_FALSE;
---
>         rlimit = JSSLOT_START(clasp) + JSCLASS_RESERVED_SLOTS(clasp);
>         JS_ASSERT(slot < rlimit);
>         if (rlimit > nslots)
>             nslots = rlimit;
> 		XMEMTAG("js_SetRequiredSlot");
>         newslots = (jsval *)
>             JS_realloc(cx, obj->slots - 1, (nslots + 1) * sizeof(jsval));
>         if (!newslots) {
>             JS_UNLOCK_OBJ(cx, obj);
>             return;
5049a3812,3817
>         for (i = 1 + newslots[0]; i <= rlimit; i++)
>             newslots[i] = JSVAL_VOID;
>         newslots[0] = nslots;
>         if (OBJ_SCOPE(obj)->object == obj)
>             obj->map->nslots = nslots;
>         obj->slots = newslots + 1;
5052,5058c3820,3821
<     /* Whether or not we grew nslots, we may need to advance freeslot. */
<     if (scope->object == obj && slot >= scope->map.freeslot)
<         scope->map.freeslot = slot + 1;
< 
<     STOBJ_SET_SLOT(obj, slot, v);
<     JS_UNLOCK_SCOPE(cx, scope);
<     return JS_TRUE;
---
>     obj->slots[slot] = v;
>     JS_UNLOCK_OBJ(cx, obj);
5062a3826,3832
> void printChar(jschar *cp);
> void printString(JSString *str);
> void printObj(JSContext *cx, JSObject *jsobj);
> void printId(JSContext *cx, jsid id);
> void printAtom(JSAtom *atom);
> void printVal(JSContext *cx, jsval val);
> 
5066c3836
<     fprintf(stderr, "jschar* (%p) \"", (void *)cp);
---
>     fprintf(stderr, "jschar* (0x%p) \"", (void *)cp);
5076,5078c3846,3848
<     fprintf(stderr, "string (%p) \"", (void *)str);
<     JSSTRING_CHARS_AND_LENGTH(str, s, n);
<     for (i=0; i < n; i++)
---
>     fprintf(stderr, "string (0x%p) \"", (void *)str);
>     s = JSSTRING_CHARS(str);
>     for (i=0, n=JSSTRING_LENGTH(str); i < n; i++)
5084,5085d3853
< void printVal(JSContext *cx, jsval val);
< 
5091c3859
<     fprintf(stderr, "object %p\n", (void *)jsobj);
---
>     fprintf(stderr, "object 0x%p\n", (void *)jsobj);
5093,5094c3861,3862
<     fprintf(stderr, "class %p %s\n", (void *)clasp, clasp->name);
<     for (i=0; i < STOBJ_NSLOTS(jsobj); i++) {
---
>     fprintf(stderr, "class 0x%p %s\n", (void *)clasp, clasp->name);
>     for (i=0; i < jsobj->map->nslots; i++) {
5096c3864
<         val = STOBJ_GET_SLOT(jsobj, i);
---
>         val = jsobj->slots[i];
5098c3866
<             fprintf(stderr, "object %p\n", (void *)JSVAL_TO_OBJECT(val));
---
>             fprintf(stderr, "object 0x%p\n", (void *)JSVAL_TO_OBJECT(val));
5105c3873
<     fprintf(stderr, "val %d (%p) = ", (int)val, (void *)val);
---
>     fprintf(stderr, "val %d (0x%p) = ", (int)val, (void *)val);
5127c3895
<     fprintf(stderr, "id %d (%p) is ", (int)id, (void *)id);
---
>     fprintf(stderr, "id %d (0x%p) is ", (int)id, (void *)id);
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsobj.h /Volumes/Swap/js_D11/src/jsobj.h
2d1
<  * vim: set ts=8 sw=4 et tw=78:
4,15c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
20,39c16,33
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
60c54,55
<     uint32      freeslot;       /* index of next free slot in object */
---
>     uint32      nslots;         /* length of obj->slots vector */
>     uint32      freeslot;       /* index of next free obj->slots element */
63a59,62
> #if defined JS_THREADSAFE && defined DEBUG
> #define OBJ_LOOKUP_PROPERTY(cx,obj,id,objp,propp)                             \
>     (obj)->map->ops->lookupProperty(cx,obj,id,objp,propp,__FILE__,__LINE__)
> #else
65a65
> #endif
101,113c101
<      : JS_TRUE)
< 
< #define OBJ_TO_INNER_OBJECT(cx,obj)                                           \
<     JS_BEGIN_MACRO                                                            \
<         JSClass *clasp_ = OBJ_GET_CLASS(cx, obj);                             \
<         if (clasp_->flags & JSCLASS_IS_EXTENDED) {                            \
<             JSExtendedClass *xclasp_ = (JSExtendedClass*)clasp_;              \
<             if (xclasp_->innerObject)                                         \
<                 obj = xclasp_->innerObject(cx, obj);                          \
<         }                                                                     \
<     JS_END_MACRO
< 
< #define JS_INITIAL_NSLOTS   6
---
>      : (void)0)
116,117c104,117
<  * When JSObject.dslots is not null, JSObject.dslots[-1] records the number of
<  * available slots.
---
>  * In the original JS engine design, obj->slots pointed to a vector of length
>  * JS_INITIAL_NSLOTS words if obj->map was shared with a prototype object,
>  * else of length obj->map->nslots.  With the advent of JS_GetReservedSlot,
>  * JS_SetReservedSlot, and JSCLASS_HAS_RESERVED_SLOTS (see jsapi.h), the size
>  * of the minimum length slots vector in the case where map is shared cannot
>  * be constant.  This length starts at JS_INITIAL_NSLOTS, but may advance to
>  * include all the reserved slots.
>  *
>  * Therefore slots must be self-describing.  Rather than tag its low order bit
>  * (a bit is all we need) to distinguish initial length from reserved length,
>  * we do "the BSTR thing": over-allocate slots by one jsval, and store the
>  * *net* length (counting usable slots, which have non-negative obj->slots[]
>  * indices) in obj->slots[-1].  All code that sets obj->slots must be aware of
>  * this hack -- you have been warned, and jsobj.c has been updated!
121,122c121
<     jsval       fslots[JS_INITIAL_NSLOTS];
<     jsval       *dslots;        /* dynamically allocated slots */
---
>     jsval       *slots;
136,210c135
< /*
<  * STOBJ prefix means Single Threaded Object. Use the following fast macros to
<  * directly manipulate slots in obj when only one thread can access obj and
<  * when obj->map->freeslot can be inconsistent with slots.
<  */
< 
< #define STOBJ_NSLOTS(obj)                                                     \
<     ((obj)->dslots ? (uint32)(obj)->dslots[-1] : (uint32)JS_INITIAL_NSLOTS)
< 
< #define STOBJ_GET_SLOT(obj,slot)                                              \
<     ((slot) < JS_INITIAL_NSLOTS                                               \
<      ? (obj)->fslots[(slot)]                                                  \
<      : (JS_ASSERT((slot) < (uint32)(obj)->dslots[-1]),                        \
<         (obj)->dslots[(slot) - JS_INITIAL_NSLOTS]))
< 
< #define STOBJ_SET_SLOT(obj,slot,value)                                        \
<     ((slot) < JS_INITIAL_NSLOTS                                               \
<      ? (obj)->fslots[(slot)] = (value)                                        \
<      : (JS_ASSERT((slot) < (uint32)(obj)->dslots[-1]),                        \
<         (obj)->dslots[(slot) - JS_INITIAL_NSLOTS] = (value)))
< 
< #define STOBJ_GET_PROTO(obj)                                                  \
<     JSVAL_TO_OBJECT((obj)->fslots[JSSLOT_PROTO])
< #define STOBJ_SET_PROTO(obj,proto)                                            \
<     ((obj)->fslots[JSSLOT_PROTO] = OBJECT_TO_JSVAL(proto))
< 
< #define STOBJ_GET_PARENT(obj)                                                 \
<     JSVAL_TO_OBJECT((obj)->fslots[JSSLOT_PARENT])
< #define STOBJ_SET_PARENT(obj,parent)                                          \
<     ((obj)->fslots[JSSLOT_PARENT] = OBJECT_TO_JSVAL(parent))
< 
< /*
<  * We use JSSLOT_CLASS to store both JSClass* and the system flag as an int-
<  * tagged value (see jsapi.h for details) with the system flag stored in the
<  * second lowest bit.
<  */
< #define STOBJ_GET_CLASS(obj)    ((JSClass *)((obj)->fslots[JSSLOT_CLASS] & ~3))
< #define STOBJ_IS_SYSTEM(obj)    (((obj)->fslots[JSSLOT_CLASS] & 2) != 0)
< 
< #define STOBJ_SET_SYSTEM(obj)   ((void)((obj)->fslots[JSSLOT_CLASS] |= 2))
< 
< #define STOBJ_GET_PRIVATE(obj)                                                \
<     (JS_ASSERT(JSVAL_IS_INT(STOBJ_GET_SLOT(obj, JSSLOT_PRIVATE))),            \
<      JSVAL_TO_PRIVATE(STOBJ_GET_SLOT(obj, JSSLOT_PRIVATE)))
< 
< #define OBJ_CHECK_SLOT(obj,slot)                                              \
<     JS_ASSERT(slot < (obj)->map->freeslot)
< 
< /*
<  * Macros for accessing slots in obj while obj is locked (if thread-safe) and
<  * when slot must be bounded by the map->freeslot.
<  */
< #define LOCKED_OBJ_NSLOTS(obj)                                                \
<    JS_MIN((obj)->map->freeslot, STOBJ_NSLOTS(obj))
< 
< #define LOCKED_OBJ_GET_SLOT(obj,slot)                                         \
<     (OBJ_CHECK_SLOT(obj, slot), STOBJ_GET_SLOT(obj, slot))
< #define LOCKED_OBJ_SET_SLOT(obj,slot,value)                                   \
<     (OBJ_CHECK_SLOT(obj, slot), STOBJ_SET_SLOT(obj, slot, value))
< 
< /*
<  * NB: Don't call LOCKED_OBJ_SET_SLOT or STOBJ_SET_SLOT for a write to a slot
<  * that may contain a function reference already, or where the new value is a
<  * function ref, and the object's scope may be branded with a property cache
<  * structural type capability that distinguishes versions of the object with
<  * and without the function property. Instead use LOCKED_OBJ_WRITE_BARRIER or
<  * a fast inline equivalent (JSOP_SETNAME/JSOP_SETPROP cases in jsinterp.c).
<  */
< #define LOCKED_OBJ_WRITE_BARRIER(cx,obj,slot,newval)                          \
<     JS_BEGIN_MACRO                                                            \
<         JSScope *scope_ = OBJ_SCOPE(obj);                                     \
<         JS_ASSERT(scope_->object == (obj));                                   \
<         GC_WRITE_BARRIER(cx, scope_, LOCKED_OBJ_GET_SLOT(obj, slot), newval); \
<         LOCKED_OBJ_SET_SLOT(obj, slot, newval);                               \
<     JS_END_MACRO
---
> #define JS_INITIAL_NSLOTS   5
211a137,150
> #ifdef DEBUG
> #define MAP_CHECK_SLOT(map,slot) \
>     JS_ASSERT((uint32)slot < JS_MIN((map)->freeslot, (map)->nslots))
> #define OBJ_CHECK_SLOT(obj,slot) \
>     MAP_CHECK_SLOT((obj)->map, slot)
> #else
> #define OBJ_CHECK_SLOT(obj,slot) ((void)0)
> #endif
> 
> /* Fast macros for accessing obj->slots while obj is locked (if thread-safe). */
> #define LOCKED_OBJ_GET_SLOT(obj,slot) \
>     (OBJ_CHECK_SLOT(obj, slot), (obj)->slots[slot])
> #define LOCKED_OBJ_SET_SLOT(obj,slot,value) \
>     (OBJ_CHECK_SLOT(obj, slot), (obj)->slots[slot] = (value))
213,221c152
<     (OBJ_CHECK_SLOT(obj, JSSLOT_PROTO), STOBJ_GET_PROTO(obj))
< #define LOCKED_OBJ_SET_PROTO(obj,proto) \
<     (OBJ_CHECK_SLOT(obj, JSSLOT_PROTO), STOBJ_SET_PROTO(obj, proto))
< 
< #define LOCKED_OBJ_GET_PARENT(obj) \
<     (OBJ_CHECK_SLOT(obj, JSSLOT_PARENT), STOBJ_GET_PARENT(obj))
< #define LOCKED_OBJ_SET_PARENT(obj,parent) \
<     (OBJ_CHECK_SLOT(obj, JSSLOT_PARENT), STOBJ_SET_PARENT(obj, parent))
< 
---
>     JSVAL_TO_OBJECT(LOCKED_OBJ_GET_SLOT(obj, JSSLOT_PROTO))
223,226c154
<     (OBJ_CHECK_SLOT(obj, JSSLOT_CLASS), STOBJ_GET_CLASS(obj))
< 
< #define LOCKED_OBJ_GET_PRIVATE(obj) \
<     (OBJ_CHECK_SLOT(obj, JSSLOT_PRIVATE), STOBJ_GET_PRIVATE(obj))
---
>     ((JSClass *)JSVAL_TO_PRIVATE(LOCKED_OBJ_GET_SLOT(obj, JSSLOT_CLASS)))
230c158
< /* Thread-safe functions and wrapper macros for accessing slots in obj. */
---
> /* Thread-safe functions and wrapper macros for accessing obj->slots. */
238,244c166,169
<     JS_BEGIN_MACRO                                                            \
<         OBJ_CHECK_SLOT(obj, slot);                                            \
<         if (OBJ_IS_NATIVE(obj) && OBJ_SCOPE(obj)->ownercx == cx)              \
<             LOCKED_OBJ_WRITE_BARRIER(cx, obj, slot, value);                   \
<         else                                                                  \
<             js_SetSlotThreadSafe(cx, obj, slot, value);                       \
<     JS_END_MACRO
---
>     (OBJ_CHECK_SLOT(obj, slot),                                               \
>      (OBJ_IS_NATIVE(obj) && OBJ_SCOPE(obj)->ownercx == cx)                    \
>      ? (void) LOCKED_OBJ_SET_SLOT(obj, slot, value)                           \
>      : js_SetSlotThreadSafe(cx, obj, slot, value))
255,256c180,182
<  * are suspended at GC-safe points, so calling STOBJ_GET_SLOT from the GC's
<  * thread is safe when rt->gcRunning is set. See jsgc.c for details.
---
>  * are suspended at GC-safe points, so there is no hazard in directly accessing
>  * obj->slots[slot] from the GC's thread, once rt->gcRunning has been set.  See
>  * jsgc.c for details.
263a190,194
> #define GC_AWARE_GET_SLOT(cx, obj, slot)                                      \
>     ((OBJ_IS_NATIVE(obj) && CX_THREAD_IS_RUNNING_GC(cx))                      \
>      ? (obj)->slots[slot]                                                     \
>      : OBJ_GET_SLOT(cx, obj, slot))
> 
267,268c198,199
< #define OBJ_SET_SLOT(cx,obj,slot,value) LOCKED_OBJ_WRITE_BARRIER(cx,obj,slot, \
<                                                                  value)
---
> #define OBJ_SET_SLOT(cx,obj,slot,value) LOCKED_OBJ_SET_SLOT(obj,slot,value)
> #define GC_AWARE_GET_SLOT(cx,obj,slot)  LOCKED_OBJ_GET_SLOT(obj,slot)
274c205
<     STOBJ_GET_PROTO(obj)
---
>     JSVAL_TO_OBJECT(OBJ_GET_SLOT(cx, obj, JSSLOT_PROTO))
276c207
<     STOBJ_SET_SLOT(obj, JSSLOT_PROTO, OBJECT_TO_JSVAL(proto))
---
>     OBJ_SET_SLOT(cx, obj, JSSLOT_PROTO, OBJECT_TO_JSVAL(proto))
279c210
<     STOBJ_GET_PARENT(obj)
---
>     JSVAL_TO_OBJECT(OBJ_GET_SLOT(cx, obj, JSSLOT_PARENT))
281c212
<     STOBJ_SET_SLOT(obj, JSSLOT_PARENT, OBJECT_TO_JSVAL(parent))
---
>     OBJ_SET_SLOT(cx, obj, JSSLOT_PARENT, OBJECT_TO_JSVAL(parent))
283,288c214,215
< /*
<  * Class is invariant and comes from the fixed JSSLOT_CLASS. Thus no locking
<  * is necessary to read it. Same for the private slot.
<  */
< #define OBJ_GET_CLASS(cx,obj)           STOBJ_GET_CLASS(obj)
< #define OBJ_GET_PRIVATE(cx,obj)         STOBJ_GET_PRIVATE(obj)
---
> #define OBJ_GET_CLASS(cx,obj) \
>     ((JSClass *)JSVAL_TO_PRIVATE(OBJ_GET_SLOT(cx, obj, JSSLOT_CLASS)))
292,293c219,220
<     JS_LIKELY((map)->ops == &js_ObjectOps ||                                  \
<               (map)->ops->newObjectMap == js_ObjectOps.newObjectMap)
---
>     ((map)->ops == &js_ObjectOps ||                                           \
>      ((map)->ops && (map)->ops->newObjectMap == js_ObjectOps.newObjectMap))
301,353d227
< extern JSClass  js_BlockClass;
< 
< /*
<  * Block scope object macros.  The slots reserved by js_BlockClass are:
<  *
<  *   JSSLOT_PRIVATE       JSStackFrame *    active frame pointer or null
<  *   JSSLOT_BLOCK_DEPTH   int               depth of block slots in frame
<  *
<  * After JSSLOT_BLOCK_DEPTH come one or more slots for the block locals.
<  * OBJ_BLOCK_COUNT depends on this arrangement.
<  *
<  * A With object is like a Block object, in that both have one reserved slot
<  * telling the stack depth of the relevant slots (the slot whose value is the
<  * object named in the with statement, the slots containing the block's local
<  * variables); and both have a private slot referring to the JSStackFrame in
<  * whose activation they were created (or null if the with or block object
<  * outlives the frame).
<  */
< #define JSSLOT_BLOCK_DEPTH      (JSSLOT_PRIVATE + 1)
< 
< #define OBJ_BLOCK_COUNT(cx,obj)                                               \
<     ((obj)->map->freeslot - (JSSLOT_BLOCK_DEPTH + 1))
< #define OBJ_BLOCK_DEPTH(cx,obj)                                               \
<     JSVAL_TO_INT(STOBJ_GET_SLOT(obj, JSSLOT_BLOCK_DEPTH))
< #define OBJ_SET_BLOCK_DEPTH(cx,obj,depth)                                     \
<     STOBJ_SET_SLOT(obj, JSSLOT_BLOCK_DEPTH, INT_TO_JSVAL(depth))
< 
< /*
<  * To make sure this slot is well-defined, always call js_NewWithObject to
<  * create a With object, don't call js_NewObject directly.  When creating a
<  * With object that does not correspond to a stack slot, pass -1 for depth.
<  *
<  * When popping the stack across this object's "with" statement, client code
<  * must call JS_SetPrivate(cx, withobj, NULL).
<  */
< extern JSObject *
< js_NewWithObject(JSContext *cx, JSObject *proto, JSObject *parent, jsint depth);
< 
< /*
<  * Create a new block scope object not linked to any proto or parent object.
<  * Blocks are created by the compiler to reify let blocks and comprehensions.
<  * Only when dynamic scope is captured do they need to be cloned and spliced
<  * into an active scope chain.
<  */
< extern JSObject *
< js_NewBlockObject(JSContext *cx);
< 
< extern JSObject *
< js_CloneBlockObject(JSContext *cx, JSObject *proto, JSObject *parent,
<                     JSStackFrame *fp);
< 
< extern JSBool
< js_PutBlockObject(JSContext *cx, JSObject *obj);
364,368c238,242
< #define IS_SHARP(he)    (JS_PTR_TO_UINT32((he)->value) & SHARP_BIT)
< #define MAKE_SHARP(he)  ((he)->value = JS_UINT32_TO_PTR(JS_PTR_TO_UINT32((he)->value)|SHARP_BIT))
< #define IS_BUSY(he)     (JS_PTR_TO_UINT32((he)->value) & BUSY_BIT)
< #define MAKE_BUSY(he)   ((he)->value = JS_UINT32_TO_PTR(JS_PTR_TO_UINT32((he)->value)|BUSY_BIT))
< #define CLEAR_BUSY(he)  ((he)->value = JS_UINT32_TO_PTR(JS_PTR_TO_UINT32((he)->value)&~BUSY_BIT))
---
> #define IS_SHARP(he)    ((jsatomid)(he)->value & SHARP_BIT)
> #define MAKE_SHARP(he)  ((he)->value = (void*)((jsatomid)(he)->value|SHARP_BIT))
> #define IS_BUSY(he)     ((jsatomid)(he)->value & BUSY_BIT)
> #define MAKE_BUSY(he)   ((he)->value = (void*)((jsatomid)(he)->value|BUSY_BIT))
> #define CLEAR_BUSY(he)  ((he)->value = (void*)((jsatomid)(he)->value&~BUSY_BIT))
372c246
<                     jschar **sp);
---
> 		    jschar **sp);
377,383d250
< /*
<  * Mark objects stored in map if GC happens between js_EnterSharpObject
<  * and js_LeaveSharpObject. GC calls this when map->depth > 0.
<  */
< extern void
< js_TraceSharpMap(JSTracer *trc, JSSharpObjectMap *map);
< 
385c252,253
< js_HasOwnPropertyHelper(JSContext *cx, JSLookupPropOp lookup, jsval *vp);
---
> js_obj_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
> 		jsval *rval);
387,388c255,257
< extern JSObject*
< js_InitBlockClass(JSContext *cx, JSObject* obj);
---
> extern JSBool
> js_obj_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
> 		jsval *rval);
406c275
<                  JSClass *clasp);
---
> 		 JSClass *clasp);
410c279
<                 JSClass *clasp, JSObject *obj);
---
> 		JSClass *clasp, JSObject *obj);
421,423d289
< extern JSBool
< js_GetClassId(JSContext *cx, JSClass *clasp, jsid *idp);
< 
427,446d292
< /*
<  * See jsapi.h, JS_NewObjectWithGivenProto.
<  */
< extern JSObject *
< js_NewObjectWithGivenProto(JSContext *cx, JSClass *clasp, JSObject *proto,
<                            JSObject *parent);
< 
< /*
<  * Fast access to immutable standard objects (constructors and prototypes).
<  */
< extern JSBool
< js_GetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key,
<                   JSObject **objp);
< 
< extern JSBool
< js_SetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key, JSObject *cobj);
< 
< extern JSBool
< js_FindClassObject(JSContext *cx, JSObject *start, jsid id, jsval *vp);
< 
460,482d305
< /* JSVAL_INT_MAX as a string */
< #define JSVAL_INT_MAX_STRING "1073741823"
< 
< #define CHECK_FOR_STRING_INDEX(id)                                            \
<     JS_BEGIN_MACRO                                                            \
<         if (JSID_IS_ATOM(id)) {                                               \
<             JSAtom *atom_ = JSID_TO_ATOM(id);                                 \
<             JSString *str_ = ATOM_TO_STRING(atom_);                           \
<             const jschar *s_ = JSFLATSTR_CHARS(str_);                         \
<             JSBool negative_ = (*s_ == '-');                                  \
<             if (negative_) s_++;                                              \
<             if (JS7_ISDEC(*s_)) {                                             \
<                 size_t n_ = JSFLATSTR_LENGTH(str_) - negative_;               \
<                 if (n_ <= sizeof(JSVAL_INT_MAX_STRING) - 1)                   \
<                     id = js_CheckForStringIndex(id, s_, s_ + n_, negative_);  \
<             }                                                                 \
<         }                                                                     \
<     JS_END_MACRO
< 
< extern jsid
< js_CheckForStringIndex(jsid id, const jschar *cp, const jschar *end,
<                        JSBool negative);
< 
511,512c334,335
<                   JSPropertyOp getter, JSPropertyOp setter, uintN attrs,
<                   JSProperty **propp);
---
> 		  JSPropertyOp getter, JSPropertyOp setter, uintN attrs,
> 		  JSProperty **propp);
520c343
<  * Unlike js_DefineProperty, propp must be non-null. On success, and if id was
---
>  * Unlike js_DefineProperty, propp must be non-null.  On success, and if id was
522,523c345,346
<  * stored in *propp. If successful but id was not found, return true with both
<  * *objp and *propp null. Therefore all callers who receive a non-null *propp
---
>  * stored in *propp.  If successful but id was not found, return true with both
>  * *objp and *propp null.  Therefore all callers who receive a non-null *propp
525a349
> #if defined JS_THREADSAFE && defined DEBUG
527,528c351,352
< js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
<                   JSProperty **propp);
---
> _js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
> 		   JSProperty **propp, const char *file, uintN line);
530,542c354,360
< /*
<  * Specialized subroutine that allows caller to preset JSRESOLVE_* flags and
<  * returns the index along the prototype chain in which *propp was found, or
<  * the last index if not found, or -1 on error.
<  */
< extern int
< js_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN flags,
<                            JSObject **objp, JSProperty **propp);
< 
< extern int
< js_FindPropertyHelper(JSContext *cx, jsid id, JSObject **objp,
<                       JSObject **pobjp, JSProperty **propp,
<                       JSPropCacheEntry **entryp);
---
> #define js_LookupProperty(cx,obj,id,objp,propp) \
>     _js_LookupProperty(cx,obj,id,objp,propp,__FILE__,__LINE__)
> #else
> extern JS_FRIEND_API(JSBool)
> js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
> 		  JSProperty **propp);
> #endif
544,547d361
< /*
<  * Return the index along the scope chain in which id was found, or the last
<  * index if not found, or -1 on error.
<  */
550c364
<                 JSProperty **propp);
---
> 		JSProperty **propp);
553c367
< js_FindIdentifierBase(JSContext *cx, jsid id, JSPropCacheEntry *entry);
---
> js_FindIdentifierBase(JSContext *cx, jsid id);
558,574d371
< /*
<  * NB: js_NativeGet and js_NativeSet are called with the scope containing sprop
<  * (pobj's scope for Get, obj's for Set) locked, and on successful return, that
<  * scope is again locked.  But on failure, both functions return false with the
<  * scope containing sprop unlocked.
<  */
< extern JSBool
< js_NativeGet(JSContext *cx, JSObject *obj, JSObject *pobj,
<              JSScopeProperty *sprop, jsval *vp);
< 
< extern JSBool
< js_NativeSet(JSContext *cx, JSObject *obj, JSScopeProperty *sprop, jsval *vp);
< 
< extern JSBool
< js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
<                      JSPropCacheEntry **entryp);
< 
579,582d375
< js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
<                      JSPropCacheEntry **entryp);
< 
< extern JSBool
587c380
<                  uintN *attrsp);
---
> 		 uintN *attrsp);
591c384
<                  uintN *attrsp);
---
> 		 uintN *attrsp);
602,604d394
< /*
<  * Unlike realloc(3), this function frees ida on failure.
<  */
606c396
< js_SetIdArrayLength(JSContext *cx, JSIdArray *ida, jsint length);
---
> js_GrowIdArray(JSContext *cx, JSIdArray *ida, jsint length);
610,613c400
<              jsval *statep, jsid *idp);
< 
< extern void
< js_TraceNativeIteratorStates(JSTracer *trc);
---
> 	     jsval *statep, jsid *idp);
617c404
<                jsval *vp, uintN *attrsp);
---
> 	       jsval *vp, uintN *attrsp);
624c411
<              jsval *rval);
---
> 	     jsval *rval);
636,637c423
< js_GetClassPrototype(JSContext *cx, JSObject *scope, jsid id,
<                      JSObject **protop);
---
> js_GetClassPrototype(JSContext *cx, const char *name, JSObject **protop);
641,648c427
<                      uintN attrs);
< 
< /*
<  * Wrap boolean, number or string as Boolean, Number or String object.
<  * *vp must not be an object, null or undefined.
<  */
< extern JSBool
< js_PrimitiveToObject(JSContext *cx, jsval *vp);
---
> 		     uintN attrs);
661c440
<              uintN argc, jsval *argv, jsval *rval);
---
> 	     uintN argc, jsval *argv, jsval *rval);
666,667c445,446
< extern void
< js_TraceObject(JSTracer *trc, JSObject *obj);
---
> extern uint32
> js_Mark(JSContext *cx, JSObject *obj, void *arg);
675c454
< extern JSBool
---
> extern void
678,684d456
< extern JSObject *
< js_CheckScopeChainValidity(JSContext *cx, JSObject *scopeobj, const char *caller);
< 
< extern JSBool
< js_CheckPrincipalsAccess(JSContext *cx, JSObject *scopeobj,
<                          JSPrincipals *principals, JSAtom *caller);
< 
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsopcode.c /Volumes/Swap/js_D11/src/jsopcode.c
2d1
<  * vim: set sw=4 ts=8 et tw=78:
4,5c3,6
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
7,15c8,11
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
20,23c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
27,39c23,33
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
50c44
< #include <stdlib.h>
---
> #include "xstdlib.h"
68,69d61
< #include "jsregexp.h"
< #include "jsscan.h"
74,85c66
< #if JS_HAS_DESTRUCTURING
< # include "jsnum.h"
< #endif
< 
< static const char js_incop_strs[][3] = {"++", "--"};
< 
< const JSCodeSpec js_CodeSpec[] = {
< #define OPDEF(op,val,name,token,length,nuses,ndefs,prec,format) \
<     {length,nuses,ndefs,prec,format},
< #include "jsopcode.tbl"
< #undef OPDEF
< };
---
> //#include "_optimize.h"
87c68,93
< uintN js_NumCodeSpecs = JS_ARRAY_LENGTH(js_CodeSpec);
---
> char js_const_str[]         = "const";
> char js_var_str[]           = "var";
> char js_function_str[]      = "function";
> char js_in_str[]            = "in";
> char js_instanceof_str[]    = "instanceof";
> char js_new_str[]           = "new";
> char js_delete_str[]        = "delete";
> char js_typeof_str[]        = "typeof";
> char js_void_str[]          = "void";
> char js_null_str[]          = "null";
> char js_this_str[]          = "this";
> char js_false_str[]         = "false";
> char js_true_str[]          = "true";
> 
> char *js_incop_str[]        = {"++", "--"};
> 
> /* Pollute the namespace locally for MSVC Win16, but not for WatCom.  */
> #ifdef __WINDOWS_386__
>     #ifdef FAR
> 	#undef FAR
>     #endif
> #else  /* !__WINDOWS_386__ */
> #ifndef FAR
> #define FAR
> #endif
> #endif /* !__WINDOWS_386__ */
89,93c95
< /*
<  * Each element of the array is either a source literal associated with JS
<  * bytecode or null.
<  */
< static const char *CodeToken[] = {
---
> JSCodeSpec FAR js_CodeSpec[] = {
95c97
<     token,
---
>     {name,token,length,nuses,ndefs,prec,format},
100,110c102
< #ifdef DEBUG
< /*
<  * Array of JS bytecode names used by DEBUG-only js_Disassemble.
<  */
< static const char *CodeName[] = {
< #define OPDEF(op,val,name,token,length,nuses,ndefs,prec,format) \
<     name,
< #include "jsopcode.tbl"
< #undef OPDEF
< };
< #endif
---
> uintN js_NumCodeSpecs = sizeof (js_CodeSpec) / sizeof js_CodeSpec[0];
118,119c110,111
< 
<     type = JOF_OPTYPE(*pc);
---
>     
>     type = (js_CodeSpec[*pc].format & JOF_TYPEMASK);
125,126c117,146
< uintN
< js_GetIndexFromBytecode(JSScript *script, jsbytecode *pc, ptrdiff_t pcoff)
---
> #if 1 // !!dp
> // ------------------------------------------------------------------------------------------------------
> JS_FRIEND_API(void)
> js_Disassemble_OutputProc(JSContext *cx, JSScript *script, JSBool lines, 
> 	LGenericOutProc outProc, void *outParam)
> {
>     jsbytecode *pc, *end;
>     uintN len;
> 
>     pc = script->code;
>     end = pc + script->length;
>     while (pc < end) {
> 	if (pc == script->main)
> 	    (*outProc)(outParam, "main:\n" );
> 	len = js_Disassemble1_OutputProc(cx, script, pc,
>                               PTRDIFF(pc, script->code, jsbytecode), lines, 
>                               outProc, outParam);
> 	if (!len)
> 	    return;
> 	pc += len;
>     }
> 
> }
> 
> // ------------------------------------------------------------------------------------------------------
> 
> #ifdef _UTF8
> extern JS_FRIEND_API(uintN)
> js_Disassemble1_OutputProc(JSContext *cx, JSScript *script, jsbytecode *pc, uintN loc, JSBool lines, 
> 	LGenericOutProc outProc, void *outParam)
129c149,154
<     uintN span, base;
---
>     JSCodeSpec *cs;
>     intN len, off;
>     JSAtom *atom;
>     JSString *str;
>     char *cstr;
> 	size_t mbLength;
132c157,179
<     JS_ASSERT(js_CodeSpec[op].length >= 1 + pcoff + UINT16_LEN);
---
>     if (op >= JSOP_LIMIT) {
> 		char numBuf1[12], numBuf2[12];
> 		JS_snprintf(numBuf1, sizeof numBuf1, "%d", op);
> 		JS_snprintf(numBuf2, sizeof numBuf2, "%d", JSOP_LIMIT);
> 		JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
> 				     JSMSG_BYTECODE_TOO_BIG, numBuf1, numBuf2);
> 		return 0;
>     }
>     cs = &js_CodeSpec[op];
>     len = (intN)cs->length;
>     (*outProc)(outParam, "%05u:", loc);
>     if (lines)
> 		(*outProc)(outParam, "%4u", JS_PCToLineNumber(cx, script, pc));
>     (*outProc)(outParam, "  %s", cs->name);
>     switch (cs->format & JOF_TYPEMASK) {
>       case JOF_BYTE:
> 	if (op == JSOP_TRAP) {
> 	    op = JS_GetTrapOpcode(cx, script, pc);
> 	    if (op == JSOP_LIMIT)
> 		return 0;
> 	    len = (intN)js_CodeSpec[op].length;
> 	}
> 	break;
134,145c181,371
<     /*
<      * We need to detect index base prefix. It presents when resetbase
<      * follows the bytecode.
<      */
<     span = js_CodeSpec[op].length;
<     base = 0;
<     if (pc - script->code + span < script->length) {
<         if (pc[span] == JSOP_RESETBASE) {
<             base = GET_INDEXBASE(pc - JSOP_INDEXBASE_LENGTH);
<         } else if (pc[span] == JSOP_RESETBASE0) {
<             JS_ASSERT(JSOP_INDEXBASE1 <= pc[-1] || pc[-1] <= JSOP_INDEXBASE3);
<             base = (pc[-1] - JSOP_INDEXBASE1 + 1) << 16;
---
>       case JOF_JUMP:
>       case JOF_JUMPX:
> 	off = GetJumpOffset(pc, pc);
> 	(*outProc)(outParam, " %u (%d)", loc + off, off);
> 	break;
> 
>       case JOF_CONST:
> 	atom = GET_ATOM(cx, script, pc);
> 	str = js_ValueToSource(cx, ATOM_KEY(atom));
> 	if (!str)
> 	    return 0;
>         cstr = js_DeflateString(cx, JSSTRING_CHARS(str), JSSTRING_LENGTH(str),&mbLength);
>         if (!cstr)
>             return 0;
> 	(*outProc)(outParam, " %s", cstr);
> 	JS_free(cx, cstr);
> 	break;
> 
>       case JOF_UINT16:
> 	(*outProc)(outParam, " %u", GET_ARGC(pc));
> 	break;
> 
> #if JS_HAS_SWITCH_STATEMENT
>       case JOF_TABLESWITCH:
>       {
> 	jsbytecode *pc2;
> 	jsint i, low, high;
> 
> 	pc2 = pc;
> 	off = GetJumpOffset(pc, pc2);
> 	pc2 += JUMP_OFFSET_LEN;
> 	low = GetJumpOffset(pc, pc2);
> 	pc2 += JUMP_OFFSET_LEN;
> 	high = GetJumpOffset(pc, pc2);
> 	pc2 += JUMP_OFFSET_LEN;
> 	(*outProc)(outParam, " defaultOffset %d low %d high %d", off, low, high);
>         for (i = low; i <= high; i++) {
>             off = GetJumpOffset(pc, pc2);
>             (*outProc)(outParam, "\n\t%d: %d", i, off);
>             pc2 += JUMP_OFFSET_LEN;
>         }
> 	len = 1 + pc2 - pc;
> 	break;
>       }
> 
>       case JOF_LOOKUPSWITCH:
>       {
> 	jsbytecode *pc2;
> 	jsint npairs;
> 
>         pc2 = pc;
> 	off = GetJumpOffset(pc, pc2);
> 	pc2 += JUMP_OFFSET_LEN;
> 	npairs = (jsint) GET_ATOM_INDEX(pc2);
> 	pc2 += ATOM_INDEX_LEN;
> 	(*outProc)(outParam, " offset %d npairs %u", off, (uintN) npairs);
> 	while (npairs) {
> 	    atom = GET_ATOM(cx, script, pc2);
> 	    pc2 += ATOM_INDEX_LEN;
> 	    off = GetJumpOffset(pc, pc2);
> 	    pc2 += JUMP_OFFSET_LEN;
> 
> 	    str = js_ValueToSource(cx, ATOM_KEY(atom));
> 	    if (!str)
> 		return 0;
>             cstr = js_DeflateString(cx, JSSTRING_CHARS(str),
>                                     JSSTRING_LENGTH(str),&mbLength);
>             if (!cstr)
>                 return 0;
> 	    (*outProc)(outParam, "\n\t%s: %d", cstr, off);
> 	    JS_free(cx, cstr);
> 	    npairs--;
> 	}
> 	len = 1 + pc2 - pc;
> 	break;
>       }
> #endif /* JS_HAS_SWITCH_STATEMENT */
> 
>       case JOF_QARG:
> 	(*outProc)(outParam, " %u", GET_ARGNO(pc));
> 	break;
> 
>       case JOF_QVAR:
> 	(*outProc)(outParam, " %u", GET_VARNO(pc));
> 	break;
> 
> #if JS_HAS_LEXICAL_CLOSURE
>       case JOF_DEFLOCALVAR:
>         (*outProc)(outParam, " %u", GET_VARNO(pc));
>         pc += VARNO_LEN;
>         atom = GET_ATOM(cx, script, pc);
>         str = js_ValueToSource(cx, ATOM_KEY(atom));
>         if (!str)
>             return 0;
>         cstr = js_DeflateString(cx, JSSTRING_CHARS(str), JSSTRING_LENGTH(str),&mbLength);
>         if (!cstr)
>             return 0;
>         (*outProc)(outParam, " %s", cstr);
>         JS_free(cx, cstr);
>         break;
> #endif
> 
>       default: {
> 	char numBuf[12];
> 	JS_snprintf(numBuf, sizeof numBuf, "%lx", (unsigned long) cs->format);
> 	JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
> 			     JSMSG_UNKNOWN_FORMAT, numBuf);
> 	return 0;
>       }
>     }
>     (*outProc)(outParam, "\n" );
>     return len;
> 
> }
> #else //#ifdef _UTF8
> extern JS_FRIEND_API(uintN)
> js_Disassemble1_OutputProc(JSContext *cx, JSScript *script, jsbytecode *pc, uintN loc, JSBool lines, 
> 	LGenericOutProc outProc, void *outParam)
> {
>     JSOp op;
>     JSCodeSpec *cs;
>     intN len, off;
>     JSAtom *atom;
>     JSString *str;
>     char *cstr;
> 	
>     op = (JSOp)*pc;
>     if (op >= JSOP_LIMIT) {
> 		char numBuf1[12], numBuf2[12];
> 		JS_snprintf(numBuf1, sizeof numBuf1, "%d", op);
> 		JS_snprintf(numBuf2, sizeof numBuf2, "%d", JSOP_LIMIT);
> 		JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
> 				     JSMSG_BYTECODE_TOO_BIG, numBuf1, numBuf2);
> 		return 0;
>     }
>     cs = &js_CodeSpec[op];
>     len = (intN)cs->length;
>     (*outProc)(outParam, "%05u:", loc);
>     if (lines)
> 		(*outProc)(outParam, "%4u", JS_PCToLineNumber(cx, script, pc));
>     (*outProc)(outParam, "  %s", cs->name);
>     switch (cs->format & JOF_TYPEMASK) {
>       case JOF_BYTE:
> 	if (op == JSOP_TRAP) {
> 	    op = JS_GetTrapOpcode(cx, script, pc);
> 	    if (op == JSOP_LIMIT)
> 		return 0;
> 	    len = (intN)js_CodeSpec[op].length;
> 	}
> 	break;
> 
>       case JOF_JUMP:
>       case JOF_JUMPX:
> 	off = GetJumpOffset(pc, pc);
> 	(*outProc)(outParam, " %u (%d)", loc + off, off);
> 	break;
> 
>       case JOF_CONST:
> 	atom = GET_ATOM(cx, script, pc);
> 	str = js_ValueToSource(cx, ATOM_KEY(atom));
> 	if (!str)
> 	    return 0;
>         cstr = js_DeflateString(cx, JSSTRING_CHARS(str), JSSTRING_LENGTH(str));
>         if (!cstr)
>             return 0;
> 	(*outProc)(outParam, " %s", cstr);
> 	JS_free(cx, cstr);
> 	break;
> 
>       case JOF_UINT16:
> 	(*outProc)(outParam, " %u", GET_ARGC(pc));
> 	break;
> 
> #if JS_HAS_SWITCH_STATEMENT
>       case JOF_TABLESWITCH:
>       {
> 	jsbytecode *pc2;
> 	jsint i, low, high;
> 
> 	pc2 = pc;
> 	off = GetJumpOffset(pc, pc2);
> 	pc2 += JUMP_OFFSET_LEN;
> 	low = GetJumpOffset(pc, pc2);
> 	pc2 += JUMP_OFFSET_LEN;
> 	high = GetJumpOffset(pc, pc2);
> 	pc2 += JUMP_OFFSET_LEN;
> 	(*outProc)(outParam, " defaultOffset %d low %d high %d", off, low, high);
>         for (i = low; i <= high; i++) {
>             off = GetJumpOffset(pc, pc2);
>             (*outProc)(outParam, "\n\t%d: %d", i, off);
>             pc2 += JUMP_OFFSET_LEN;
146a373,440
> 	len = 1 + pc2 - pc;
> 	break;
>       }
> 
>       case JOF_LOOKUPSWITCH:
>       {
> 	jsbytecode *pc2;
> 	jsint npairs;
> 
>         pc2 = pc;
> 	off = GetJumpOffset(pc, pc2);
> 	pc2 += JUMP_OFFSET_LEN;
> 	npairs = (jsint) GET_ATOM_INDEX(pc2);
> 	pc2 += ATOM_INDEX_LEN;
> 	(*outProc)(outParam, " offset %d npairs %u", off, (uintN) npairs);
> 	while (npairs) {
> 	    atom = GET_ATOM(cx, script, pc2);
> 	    pc2 += ATOM_INDEX_LEN;
> 	    off = GetJumpOffset(pc, pc2);
> 	    pc2 += JUMP_OFFSET_LEN;
> 
> 	    str = js_ValueToSource(cx, ATOM_KEY(atom));
> 	    if (!str)
> 		return 0;
>             cstr = js_DeflateString(cx, JSSTRING_CHARS(str),
>                                     JSSTRING_LENGTH(str));
>             if (!cstr)
>                 return 0;
> 	    (*outProc)(outParam, "\n\t%s: %d", cstr, off);
> 	    JS_free(cx, cstr);
> 	    npairs--;
> 	}
> 	len = 1 + pc2 - pc;
> 	break;
>       }
> #endif /* JS_HAS_SWITCH_STATEMENT */
> 
>       case JOF_QARG:
> 	(*outProc)(outParam, " %u", GET_ARGNO(pc));
> 	break;
> 
>       case JOF_QVAR:
> 	(*outProc)(outParam, " %u", GET_VARNO(pc));
> 	break;
> 
> #if JS_HAS_LEXICAL_CLOSURE
>       case JOF_DEFLOCALVAR:
>         (*outProc)(outParam, " %u", GET_VARNO(pc));
>         pc += VARNO_LEN;
>         atom = GET_ATOM(cx, script, pc);
>         str = js_ValueToSource(cx, ATOM_KEY(atom));
>         if (!str)
>             return 0;
>         cstr = js_DeflateString(cx, JSSTRING_CHARS(str), JSSTRING_LENGTH(str));
>         if (!cstr)
>             return 0;
>         (*outProc)(outParam, " %s", cstr);
>         JS_free(cx, cstr);
>         break;
> #endif
> 
>       default: {
> 	char numBuf[12];
> 	JS_snprintf(numBuf, sizeof numBuf, "%lx", (unsigned long) cs->format);
> 	JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
> 			     JSMSG_UNKNOWN_FORMAT, numBuf);
> 	return 0;
>       }
148c442,444
<     return base + GET_UINT16(pc + pcoff);
---
>     (*outProc)(outParam, "\n" );
>     return len;
> 
149a446,452
> #endif //#ifdef _UTF8
> 
> 
> #endif // !!dp
> 
> // ------------------------------------------------------------------------------------------------------
> // ------------------------------------------------------------------------------------------------------
153c456
< JS_FRIEND_API(JSBool)
---
> JS_FRIEND_API(void)
162,164c465,467
<         if (pc == script->main)
<             fputs("main:\n", fp);
<         len = js_Disassemble1(cx, script, pc,
---
> 	if (pc == script->main)
> 	    fputs("main:\n", fp);
> 	len = js_Disassemble1(cx, script, pc,
167,169c470,472
<         if (!len)
<             return JS_FALSE;
<         pc += len;
---
> 	if (!len)
> 	    return;
> 	pc += len;
171d473
<     return JS_TRUE;
174,175c476,479
< const char *
< ToDisassemblySource(JSContext *cx, jsval v)
---
> #ifdef _UTF8
> JS_FRIEND_API(uintN)
> js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc, uintN loc,
> 		JSBool lines, FILE *fp)
177,180c481,484
<     JSObject *obj;
<     JSScopeProperty *sprop;
<     char *source;
<     const char *bytes;
---
>     JSOp op;
>     JSCodeSpec *cs;
>     intN len, off;
>     JSAtom *atom;
181a486,487
>     char *cstr;
> 	size_t mbLength;
183,203c489,553
<     if (!JSVAL_IS_PRIMITIVE(v)) {
<         obj = JSVAL_TO_OBJECT(v);
<         if (OBJ_GET_CLASS(cx, obj) == &js_BlockClass) {
<             source = JS_sprintf_append(NULL, "depth %d {",
<                                        OBJ_BLOCK_DEPTH(cx, obj));
<             for (sprop = OBJ_SCOPE(obj)->lastProp; sprop;
<                  sprop = sprop->parent) {
<                 bytes = js_AtomToPrintableString(cx, JSID_TO_ATOM(sprop->id));
<                 if (!bytes)
<                     return NULL;
<                 source = JS_sprintf_append(source, "%s: %d%s",
<                                            bytes, sprop->shortid,
<                                            sprop->parent ? ", " : "");
<             }
<             source = JS_sprintf_append(source, "}");
<             if (!source)
<                 return NULL;
<             str = JS_NewString(cx, source, strlen(source));
<             if (!str)
<                 return NULL;
<             return js_GetStringBytes(cx, str);
---
>     op = (JSOp)*pc;
>     if (op >= JSOP_LIMIT) {
> 	char numBuf1[12], numBuf2[12];
> 	JS_snprintf(numBuf1, sizeof numBuf1, "%d", op);
> 	JS_snprintf(numBuf2, sizeof numBuf2, "%d", JSOP_LIMIT);
> 	JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
> 			     JSMSG_BYTECODE_TOO_BIG, numBuf1, numBuf2);
> 	return 0;
>     }
>     cs = &js_CodeSpec[op];
>     len = (intN)cs->length;
>     fprintf(fp, "%05u:", loc);
>     if (lines)
> 	fprintf(fp, "%4u", JS_PCToLineNumber(cx, script, pc));
>     fprintf(fp, "  %s", cs->name);
>     switch (cs->format & JOF_TYPEMASK) {
>       case JOF_BYTE:
> 	if (op == JSOP_TRAP) {
> 	    op = JS_GetTrapOpcode(cx, script, pc);
> 	    if (op == JSOP_LIMIT)
> 		return 0;
> 	    len = (intN)js_CodeSpec[op].length;
> 	}
> 	break;
> 
>       case JOF_JUMP:
>       case JOF_JUMPX:
> 	off = GetJumpOffset(pc, pc);
> 	fprintf(fp, " %u (%d)", loc + off, off);
> 	break;
> 
>       case JOF_CONST:
> 	atom = GET_ATOM(cx, script, pc);
> 	str = js_ValueToSource(cx, ATOM_KEY(atom));
> 	if (!str)
> 	    return 0;
>         cstr = js_DeflateString(cx, JSSTRING_CHARS(str), JSSTRING_LENGTH(str),&mbLength);
>         if (!cstr)
>             return 0;
> 	fprintf(fp, " %s", cstr);
> 	JS_free(cx, cstr);
> 	break;
> 
>       case JOF_UINT16:
> 	fprintf(fp, " %u", GET_ARGC(pc));
> 	break;
> 
> #if JS_HAS_SWITCH_STATEMENT
>       case JOF_TABLESWITCH:
>       {
> 	jsbytecode *pc2;
> 	jsint i, low, high;
> 
> 	pc2 = pc;
> 	off = GetJumpOffset(pc, pc2);
> 	pc2 += JUMP_OFFSET_LEN;
> 	low = GetJumpOffset(pc, pc2);
> 	pc2 += JUMP_OFFSET_LEN;
> 	high = GetJumpOffset(pc, pc2);
> 	pc2 += JUMP_OFFSET_LEN;
> 	fprintf(fp, " defaultOffset %d low %d high %d", off, low, high);
>         for (i = low; i <= high; i++) {
>             off = GetJumpOffset(pc, pc2);
>             fprintf(fp, "\n\t%d: %d", i, off);
>             pc2 += JUMP_OFFSET_LEN;
204a555,622
> 	len = 1 + pc2 - pc;
> 	break;
>       }
> 
>       case JOF_LOOKUPSWITCH:
>       {
> 	jsbytecode *pc2;
> 	jsint npairs;
> 
>         pc2 = pc;
> 	off = GetJumpOffset(pc, pc2);
> 	pc2 += JUMP_OFFSET_LEN;
> 	npairs = (jsint) GET_ATOM_INDEX(pc2);
> 	pc2 += ATOM_INDEX_LEN;
> 	fprintf(fp, " offset %d npairs %u", off, (uintN) npairs);
> 	while (npairs) {
> 	    atom = GET_ATOM(cx, script, pc2);
> 	    pc2 += ATOM_INDEX_LEN;
> 	    off = GetJumpOffset(pc, pc2);
> 	    pc2 += JUMP_OFFSET_LEN;
> 
> 	    str = js_ValueToSource(cx, ATOM_KEY(atom));
> 	    if (!str)
> 		return 0;
>             cstr = js_DeflateString(cx, JSSTRING_CHARS(str),
>                                     JSSTRING_LENGTH(str),&mbLength);
>             if (!cstr)
>                 return 0;
> 	    fprintf(fp, "\n\t%s: %d", cstr, off);
> 	    JS_free(cx, cstr);
> 	    npairs--;
> 	}
> 	len = 1 + pc2 - pc;
> 	break;
>       }
> #endif /* JS_HAS_SWITCH_STATEMENT */
> 
>       case JOF_QARG:
> 	fprintf(fp, " %u", GET_ARGNO(pc));
> 	break;
> 
>       case JOF_QVAR:
> 	fprintf(fp, " %u", GET_VARNO(pc));
> 	break;
> 
> #if JS_HAS_LEXICAL_CLOSURE
>       case JOF_DEFLOCALVAR:
>         fprintf(fp, " %u", GET_VARNO(pc));
>         pc += VARNO_LEN;
>         atom = GET_ATOM(cx, script, pc);
>         str = js_ValueToSource(cx, ATOM_KEY(atom));
>         if (!str)
>             return 0;
>         cstr = js_DeflateString(cx, JSSTRING_CHARS(str), JSSTRING_LENGTH(str),&mbLength);
>         if (!cstr)
>             return 0;
>         fprintf(fp, " %s", cstr);
>         JS_free(cx, cstr);
>         break;
> #endif
> 
>       default: {
> 	char numBuf[12];
> 	JS_snprintf(numBuf, sizeof numBuf, "%lx", (unsigned long) cs->format);
> 	JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
> 			     JSMSG_UNKNOWN_FORMAT, numBuf);
> 	return 0;
>       }
206c624,625
<     return js_ValueToPrintableSource(cx, v);
---
>     fputs("\n", fp);
>     return len;
208c627
< 
---
> #else //#ifdef _UTF8
210,211c629,630
< js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
<                 uintN loc, JSBool lines, FILE *fp)
---
> js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc, uintN loc,
> 		JSBool lines, FILE *fp)
214,216c633,634
<     const JSCodeSpec *cs;
<     ptrdiff_t len, off, jmplen;
<     uint32 type;
---
>     JSCodeSpec *cs;
>     intN len, off;
218,223c636,638
<     uintN index;
<     JSObject *obj;
<     jsval v;
<     const char *bytes;
<     jsint i;
< 
---
>     JSString *str;
>     char *cstr;
> 	
226,231c641,646
<         char numBuf1[12], numBuf2[12];
<         JS_snprintf(numBuf1, sizeof numBuf1, "%d", op);
<         JS_snprintf(numBuf2, sizeof numBuf2, "%d", JSOP_LIMIT);
<         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
<                              JSMSG_BYTECODE_TOO_BIG, numBuf1, numBuf2);
<         return 0;
---
> 	char numBuf1[12], numBuf2[12];
> 	JS_snprintf(numBuf1, sizeof numBuf1, "%d", op);
> 	JS_snprintf(numBuf2, sizeof numBuf2, "%d", JSOP_LIMIT);
> 	JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
> 			     JSMSG_BYTECODE_TOO_BIG, numBuf1, numBuf2);
> 	return 0;
234c649
<     len = (ptrdiff_t) cs->length;
---
>     len = (intN)cs->length;
237,240c652,654
<         fprintf(fp, "%4u", JS_PCToLineNumber(cx, script, pc));
<     fprintf(fp, "  %s", CodeName[op]);
<     type = JOF_TYPE(cs->format);
<     switch (type) {
---
> 	fprintf(fp, "%4u", JS_PCToLineNumber(cx, script, pc));
>     fprintf(fp, "  %s", cs->name);
>     switch (cs->format & JOF_TYPEMASK) {
242,248c656,662
<         if (op == JSOP_TRAP) {
<             op = JS_GetTrapOpcode(cx, script, pc);
<             if (op == JSOP_LIMIT)
<                 return 0;
<             len = (ptrdiff_t) js_CodeSpec[op].length;
<         }
<         break;
---
> 	if (op == JSOP_TRAP) {
> 	    op = JS_GetTrapOpcode(cx, script, pc);
> 	    if (op == JSOP_LIMIT)
> 		return 0;
> 	    len = (intN)js_CodeSpec[op].length;
> 	}
> 	break;
252,271c666,676
<         off = GetJumpOffset(pc, pc);
<         fprintf(fp, " %u (%d)", loc + off, off);
<         break;
< 
<       case JOF_ATOM:
<       case JOF_OBJECT:
<       case JOF_REGEXP:
<         index = js_GetIndexFromBytecode(script, pc, 0);
<         if (type == JOF_ATOM) {
<             JS_GET_SCRIPT_ATOM(script, index, atom);
<             v = ATOM_KEY(atom);
<         } else {
<             if (type == JOF_OBJECT)
<                 JS_GET_SCRIPT_OBJECT(script, index, obj);
<             else
<                 JS_GET_SCRIPT_REGEXP(script, index, obj);
<             v = OBJECT_TO_JSVAL(obj);
<         }
<         bytes = ToDisassemblySource(cx, v);
<         if (!bytes)
---
> 	off = GetJumpOffset(pc, pc);
> 	fprintf(fp, " %u (%d)", loc + off, off);
> 	break;
> 
>       case JOF_CONST:
> 	atom = GET_ATOM(cx, script, pc);
> 	str = js_ValueToSource(cx, ATOM_KEY(atom));
> 	if (!str)
> 	    return 0;
>         cstr = js_DeflateString(cx, JSSTRING_CHARS(str), JSSTRING_LENGTH(str));
>         if (!cstr)
273,274c678,680
<         fprintf(fp, " %s", bytes);
<         break;
---
> 	fprintf(fp, " %s", cstr);
> 	JS_free(cx, cstr);
> 	break;
277,283c683,684
<       case JOF_LOCAL:
<         i = (jsint)GET_UINT16(pc);
<         goto print_int;
< 
<       case JOF_2BYTE:
<         fprintf(fp, " %u", (uintN)pc[1]);
<         break;
---
> 	fprintf(fp, " %u", GET_ARGC(pc));
> 	break;
284a686
> #if JS_HAS_SWITCH_STATEMENT
286d687
<       case JOF_TABLESWITCHX:
288,289c689,690
<         jsbytecode *pc2;
<         jsint i, low, high;
---
> 	jsbytecode *pc2;
> 	jsint i, low, high;
291,300c692,699
<         jmplen = (type == JOF_TABLESWITCH) ? JUMP_OFFSET_LEN
<                                            : JUMPX_OFFSET_LEN;
<         pc2 = pc;
<         off = GetJumpOffset(pc, pc2);
<         pc2 += jmplen;
<         low = GET_JUMP_OFFSET(pc2);
<         pc2 += JUMP_OFFSET_LEN;
<         high = GET_JUMP_OFFSET(pc2);
<         pc2 += JUMP_OFFSET_LEN;
<         fprintf(fp, " defaultOffset %d low %d high %d", off, low, high);
---
> 	pc2 = pc;
> 	off = GetJumpOffset(pc, pc2);
> 	pc2 += JUMP_OFFSET_LEN;
> 	low = GetJumpOffset(pc, pc2);
> 	pc2 += JUMP_OFFSET_LEN;
> 	high = GetJumpOffset(pc, pc2);
> 	pc2 += JUMP_OFFSET_LEN;
> 	fprintf(fp, " defaultOffset %d low %d high %d", off, low, high);
304c703
<             pc2 += jmplen;
---
>             pc2 += JUMP_OFFSET_LEN;
306,307c705,706
<         len = 1 + pc2 - pc;
<         break;
---
> 	len = 1 + pc2 - pc;
> 	break;
311d709
<       case JOF_LOOKUPSWITCHX:
313,314c711,712
<         jsbytecode *pc2;
<         jsatomid npairs;
---
> 	jsbytecode *pc2;
> 	jsint npairs;
316,317d713
<         jmplen = (type == JOF_LOOKUPSWITCH) ? JUMP_OFFSET_LEN
<                                             : JUMPX_OFFSET_LEN;
319,331c715,731
<         off = GetJumpOffset(pc, pc2);
<         pc2 += jmplen;
<         npairs = GET_UINT16(pc2);
<         pc2 += UINT16_LEN;
<         fprintf(fp, " offset %d npairs %u", off, (uintN) npairs);
<         while (npairs) {
<             JS_GET_SCRIPT_ATOM(script, GET_INDEX(pc2), atom);
<             pc2 += INDEX_LEN;
<             off = GetJumpOffset(pc, pc2);
<             pc2 += jmplen;
< 
<             bytes = ToDisassemblySource(cx, ATOM_KEY(atom));
<             if (!bytes)
---
> 	off = GetJumpOffset(pc, pc2);
> 	pc2 += JUMP_OFFSET_LEN;
> 	npairs = (jsint) GET_ATOM_INDEX(pc2);
> 	pc2 += ATOM_INDEX_LEN;
> 	fprintf(fp, " offset %d npairs %u", off, (uintN) npairs);
> 	while (npairs) {
> 	    atom = GET_ATOM(cx, script, pc2);
> 	    pc2 += ATOM_INDEX_LEN;
> 	    off = GetJumpOffset(pc, pc2);
> 	    pc2 += JUMP_OFFSET_LEN;
> 
> 	    str = js_ValueToSource(cx, ATOM_KEY(atom));
> 	    if (!str)
> 		return 0;
>             cstr = js_DeflateString(cx, JSSTRING_CHARS(str),
>                                     JSSTRING_LENGTH(str));
>             if (!cstr)
333,337c733,738
<             fprintf(fp, "\n\t%s: %d", bytes, off);
<             npairs--;
<         }
<         len = 1 + pc2 - pc;
<         break;
---
> 	    fprintf(fp, "\n\t%s: %d", cstr, off);
> 	    JS_free(cx, cstr);
> 	    npairs--;
> 	}
> 	len = 1 + pc2 - pc;
> 	break;
338a740
> #endif /* JS_HAS_SWITCH_STATEMENT */
341,342c743,744
<         fprintf(fp, " %u", GET_ARGNO(pc));
<         break;
---
> 	fprintf(fp, " %u", GET_ARGNO(pc));
> 	break;
345,346c747,748
<         fprintf(fp, " %u", GET_VARNO(pc));
<         break;
---
> 	fprintf(fp, " %u", GET_VARNO(pc));
> 	break;
348,349c750,751
<       case JOF_SLOTATOM:
<       case JOF_SLOTOBJECT:
---
> #if JS_HAS_LEXICAL_CLOSURE
>       case JOF_DEFLOCALVAR:
351,360c753,756
<         index = js_GetIndexFromBytecode(script, pc, VARNO_LEN);
<         if (type == JOF_SLOTATOM) {
<             JS_GET_SCRIPT_ATOM(script, index, atom);
<             v = ATOM_KEY(atom);
<         } else {
<             JS_GET_SCRIPT_OBJECT(script, index, obj);
<             v = OBJECT_TO_JSVAL(obj);
<         }
<         bytes = ToDisassemblySource(cx, v);
<         if (!bytes)
---
>         pc += VARNO_LEN;
>         atom = GET_ATOM(cx, script, pc);
>         str = js_ValueToSource(cx, ATOM_KEY(atom));
>         if (!str)
362,378c758,762
<         fprintf(fp, " %s", bytes);
<         break;
< 
<       case JOF_UINT24:
<         JS_ASSERT(op == JSOP_UINT24);
<         i = (jsint)GET_UINT24(pc);
<         goto print_int;
< 
<       case JOF_INT8:
<         i = GET_INT8(pc);
<         goto print_int;
< 
<       case JOF_INT32:
<         JS_ASSERT(op == JSOP_INT32);
<         i = GET_INT32(pc);
<       print_int:
<         fprintf(fp, " %d", i);
---
>         cstr = js_DeflateString(cx, JSSTRING_CHARS(str), JSSTRING_LENGTH(str));
>         if (!cstr)
>             return 0;
>         fprintf(fp, " %s", cstr);
>         JS_free(cx, cstr);
379a764
> #endif
382,386c767,771
<         char numBuf[12];
<         JS_snprintf(numBuf, sizeof numBuf, "%lx", (unsigned long) cs->format);
<         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
<                              JSMSG_UNKNOWN_FORMAT, numBuf);
<         return 0;
---
> 	char numBuf[12];
> 	JS_snprintf(numBuf, sizeof numBuf, "%lx", (unsigned long) cs->format);
> 	JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
> 			     JSMSG_UNKNOWN_FORMAT, numBuf);
> 	return 0;
392c777
< 
---
> #endif //#ifdef _UTF8
417c802
< SprintEnsureBuffer(Sprinter *sp, size_t len)
---
> SprintAlloc(Sprinter *sp, size_t nb)
419,427c804,805
<     ptrdiff_t nb;
<     char *base;
< 
<     nb = (sp->offset + len + 1) - sp->size;
<     if (nb < 0)
<         return JS_TRUE;
<     base = sp->base;
<     if (!base) {
<         JS_ARENA_ALLOCATE_CAST(base, char *, sp->pool, nb);
---
>     if (!sp->base) {
> 	JS_ARENA_ALLOCATE_CAST(sp->base, char *, sp->pool, nb);
429c807
<         JS_ARENA_GROW_CAST(base, char *, sp->pool, sp->size, nb);
---
> 	JS_ARENA_GROW_CAST(sp->base, char *, sp->pool, sp->size, nb);
431,433c809,811
<     if (!base) {
<         js_ReportOutOfScriptQuota(sp->context);
<         return JS_FALSE;
---
>     if (!sp->base) {
> 	JS_ReportOutOfMemory(sp->context);
> 	return JS_FALSE;
435d812
<     sp->base = base;
443c820
<     ptrdiff_t offset;
---
>     ptrdiff_t nb, offset;
447,448c824,826
<     if (!SprintEnsureBuffer(sp, len))
<         return -1;
---
>     nb = (sp->offset + len + 1) - sp->size;
>     if (nb > 0 && !SprintAlloc(sp, nb))
> 	return -1;
460,489d837
< SprintCString(Sprinter *sp, const char *s)
< {
<     return SprintPut(sp, s, strlen(s));
< }
< 
< static ptrdiff_t
< SprintString(Sprinter *sp, JSString *str)
< {
<     jschar *chars;
<     size_t length, size;
<     ptrdiff_t offset;
< 
<     JSSTRING_CHARS_AND_LENGTH(str, chars, length);
<     if (length == 0)
<         return sp->offset;
< 
<     size = js_GetDeflatedStringLength(sp->context, chars, length);
<     if (size == (size_t)-1 || !SprintEnsureBuffer(sp, size))
<         return -1;
< 
<     offset = sp->offset;
<     sp->offset += size;
<     js_DeflateStringToBuffer(sp->context, chars, length, sp->base + offset,
<                              &size);
<     sp->base[sp->offset] = 0;
<     return offset;
< }
< 
< 
< static ptrdiff_t
497c845
<     bp = JS_vsmprintf(format, ap);      /* XXX vsaprintf */
---
>     bp = JS_vsmprintf(format, ap);	/* XXX vsaprintf */
500,501c848,849
<         JS_ReportOutOfMemory(sp->context);
<         return -1;
---
> 	JS_ReportOutOfMemory(sp->context);
> 	return -1;
503,504c851,852
<     offset = SprintCString(sp, bp);
<     free(bp);
---
>     offset = SprintPut(sp, bp, strlen(bp));
>     xfree(bp);
508c856
< const char js_EscapeMap[] = {
---
> jschar js_EscapeMap[] = {
518c866
<     '\0', '0'
---
>     0
521,522d868
< #define DONT_ESCAPE     0x10000
< 
524c870
< QuoteString(Sprinter *sp, JSString *str, uint32 quote)
---
> QuoteString(Sprinter *sp, JSString *str, jschar quote)
526,530c872,873
<     JSBool dontEscape, ok;
<     jschar qc, c;
<     ptrdiff_t off, len;
<     const jschar *s, *t, *z;
<     const char *e;
---
>     ptrdiff_t off, len, nb;
>     const jschar *s, *t, *u, *z;
531a875,876
>     jschar c;
>     JSBool ok;
534,535d878
<     dontEscape = (quote & DONT_ESCAPE) != 0;
<     qc = (jschar) quote;
537,538c880,881
<     if (qc && Sprint(sp, "%c", (char)qc) < 0)
<         return NULL;
---
>     if (quote && Sprint(sp, "%c", (char)quote) < 0)
> 	return NULL;
541c884,885
<     JSSTRING_CHARS_AND_END(str, s, z);
---
>     s = JSSTRING_CHARS(str);
>     z = s + JSSTRING_LENGTH(str);
543,576c887,917
<         /* Move t forward from s past un-quote-worthy characters. */
<         c = *t;
<         while (JS_ISPRINT(c) && c != qc && c != '\\' && c != '\t' &&
<                !(c >> 8)) {
<             c = *++t;
<             if (t == z)
<                 break;
<         }
<         len = PTRDIFF(t, s, jschar);
< 
<         /* Allocate space for s, including the '\0' at the end. */
<         if (!SprintEnsureBuffer(sp, len))
<             return NULL;
< 
<         /* Advance sp->offset and copy s into sp's buffer. */
<         bp = sp->base + sp->offset;
<         sp->offset += len;
<         while (--len >= 0)
<             *bp++ = (char) *s++;
<         *bp = '\0';
< 
<         if (t == z)
<             break;
< 
<         /* Use js_EscapeMap, \u, or \x only if necessary. */
<         if (!(c >> 8) && (e = strchr(js_EscapeMap, (int)c)) != NULL) {
<             ok = dontEscape
<                  ? Sprint(sp, "%c", (char)c) >= 0
<                  : Sprint(sp, "\\%c", e[1]) >= 0;
<         } else {
<             ok = Sprint(sp, (c >> 8) ? "\\u%04X" : "\\x%02X", c) >= 0;
<         }
<         if (!ok)
<             return NULL;
---
> 	/* Move t forward from s past un-quote-worthy characters. */
> 	c = *t;
> 	while (JS_ISPRINT(c) && c != quote && c != '\\' && !(c >> 8)) {
> 	    c = *++t;
> 	    if (t == z)
> 		break;
> 	}
> 	len = PTRDIFF(t, s, jschar);
> 
> 	/* Allocate space for s, including the '\0' at the end. */
> 	nb = (sp->offset + len + 1) - sp->size;
> 	if (nb > 0 && !SprintAlloc(sp, nb))
> 	    return NULL;
> 
> 	/* Advance sp->offset and copy s into sp's buffer. */
> 	bp = sp->base + sp->offset;
> 	sp->offset += len;
> 	while (--len >= 0)
> 	    *bp++ = (char) *s++;
> 	*bp = '\0';
> 
> 	if (t == z)
> 	    break;
> 
> 	/* Use js_EscapeMap, \u, or \x only if necessary. */
> 	if ((u = js_strchr(js_EscapeMap, c)) != NULL)
> 	    ok = Sprint(sp, "\\%c", (char)u[1]) >= 0;
> 	else
> 	    ok = Sprint(sp, (c >> 8) ? "\\u%04X" : "\\x%02X", c) >= 0;
> 	if (!ok)
> 	    return NULL;
580,588c921,922
<     if (qc && Sprint(sp, "%c", (char)qc) < 0)
<         return NULL;
< 
<     /*
<      * If we haven't Sprint'd anything yet, Sprint an empty string so that
<      * the OFF2STR below gives a valid result.
<      */
<     if (off == sp->offset && Sprint(sp, "") < 0)
<         return NULL;
---
>     if (quote && Sprint(sp, "%c", (char)quote) < 0)
> 	return NULL;
614,615c948
<     JSPackedBool    pretty;         /* pretty-print: indent, use newlines */
<     JSPackedBool    grouped;        /* in parenthesized expression context */
---
>     JSBool          pretty;         /* pretty-print: indent, use newlines */
617,619c950
<     jsbytecode      *dvgfence;      /* js_DecompileValueGenerator fencepost */
<     JSFunction      *fun;           /* interpreted function */
<     jsuword         *localNames;    /* argument and variable names */
---
>     JSScope         *scope;         /* script function scope */
622,629d952
< /*
<  * Hack another flag, a la JS_DONT_PRETTY_PRINT, into uintN indent parameters
<  * to functions such as js_DecompileFunction and js_NewPrinter.  This time, as
<  * opposed to JS_DONT_PRETTY_PRINT back in the dark ages, we can assume that a
<  * uintN is at least 32 bits.
<  */
< #define JS_IN_GROUP_CONTEXT 0x10000
< 
631,632c954
< JS_NEW_PRINTER(JSContext *cx, const char *name,  JSFunction *fun,
<                uintN indent, JSBool pretty)
---
> js_NewPrinter(JSContext *cx, const char *name, uintN indent, JSBool pretty)
634a957,958
>     JSStackFrame *fp;
>     JSObjectMap *map;
635a960
> 	XMEMTAG("js_NewPrinter");
638c963
<         return NULL;
---
> 	return NULL;
640,641c965,966
<     JS_INIT_ARENA_POOL(&jp->pool, name, 256, 1, &cx->scriptStackQuota);
<     jp->indent = indent & ~JS_IN_GROUP_CONTEXT;
---
>     JS_InitArenaPool(&jp->pool, name, 256, 1);
>     jp->indent = indent;
643d967
<     jp->grouped = (indent & JS_IN_GROUP_CONTEXT) != 0;
645,653c969,974
<     jp->dvgfence = NULL;
<     jp->fun = fun;
<     jp->localNames = NULL;
<     if (fun && FUN_INTERPRETED(fun) && JS_GET_LOCAL_NAME_COUNT(fun)) {
<         jp->localNames = js_GetLocalNameArray(cx, fun, &jp->pool);
<         if (!jp->localNames) {
<             js_DestroyPrinter(jp);
<             return NULL;
<         }
---
>     jp->scope = NULL;
>     fp = cx->fp;
>     if (fp && fp->fun && fp->fun->object) {
> 	map = fp->fun->object->map;
> 	if (MAP_IS_NATIVE(map))
> 	    jp->scope = (JSScope *)map;
673c994
<         return cx->runtime->emptyString;
---
> 	return cx->runtime->emptyString;
676c997
<         return NULL;
---
> 	return NULL;
682,697d1002
< /*
<  * NB: Indexed by SRC_DECL_* defines from jsemit.h.
<  */
< static const char * const var_prefix[] = {"var ", "const ", "let "};
< 
< static const char *
< VarPrefix(jssrcnote *sn)
< {
<     if (sn && (SN_TYPE(sn) == SRC_DECL || SN_TYPE(sn) == SRC_GROUPASSIGN)) {
<         ptrdiff_t type = js_GetSrcNoteOffset(sn, 0);
<         if ((uintN)type <= SRC_DECL_LET)
<             return var_prefix[type];
<     }
<     return "";
< }
< 
712d1016
<         format++;
714c1018,1019
<             return -1;
---
> 	    return -1;
> 	format++;
719c1024
<     if (!jp->pretty && format[cc = strlen(format) - 1] == '\n') {
---
>     if (!jp->pretty && format[cc = strlen(format)-1] == '\n') {
728c1033
<     bp = JS_vsmprintf(format, ap);      /* XXX vsaprintf */
---
>     bp = JS_vsmprintf(format, ap);	/* XXX vsaprintf */
734,735c1039,1040
<         JS_ReportOutOfMemory(jp->sprinter.context);
<         return -1;
---
> 	JS_ReportOutOfMemory(jp->sprinter.context);
> 	return -1;
740,741c1045,1046
<         cc = -1;
<     free(bp);
---
> 	cc = -1;
>     xfree(bp);
750c1055
<     return SprintCString(&jp->sprinter, s) >= 0;
---
>     return SprintPut(&jp->sprinter, s, strlen(s)) >= 0;
760,761d1064
<     uintN       inArrayInit;    /* array initialiser/comprehension level */
<     JSBool      inGenExp;       /* in generator expression */
765,818d1067
< /*
<  * Get a stacked offset from ss->sprinter.base, or if the stacked value |off|
<  * is negative, lazily fetch the generating pc at |spindex = 1 + off| and try
<  * to decompile the code that generated the missing value.  This is used when
<  * reporting errors, where the model stack will lack |pcdepth| non-negative
<  * offsets (see js_DecompileValueGenerator and js_DecompileCode).
<  *
<  * If the stacked offset is -1, return 0 to index the NUL padding at the start
<  * of ss->sprinter.base.  If this happens, it means there is a decompiler bug
<  * to fix, but it won't violate memory safety.
<  */
< static ptrdiff_t
< GetOff(SprintStack *ss, uintN i)
< {
<     ptrdiff_t off;
<     char *bytes;
< 
<     off = ss->offsets[i];
<     if (off < 0) {
< #if defined DEBUG_brendan || defined DEBUG_mrbkap || defined DEBUG_crowder
<         JS_ASSERT(off < -1);
< #endif
<         if (++off == 0) {
<             if (!ss->sprinter.base && SprintPut(&ss->sprinter, "", 0) >= 0)
<                 memset(ss->sprinter.base, 0, ss->sprinter.offset);
<             return 0;
<         }
< 
<         bytes = js_DecompileValueGenerator(ss->sprinter.context, off,
<                                            JSVAL_NULL, NULL);
<         if (!bytes)
<             return 0;
<         off = SprintCString(&ss->sprinter, bytes);
<         if (off < 0)
<             off = 0;
<         ss->offsets[i] = off;
<         JS_free(ss->sprinter.context, bytes);
<     }
<     return off;
< }
< 
< static const char *
< GetStr(SprintStack *ss, uintN i)
< {
<     ptrdiff_t off;
< 
<     /*
<      * Must call GetOff before using ss->sprinter.base, since it may be null
<      * until bootstrapped by GetOff.
<      */
<     off = GetOff(ss, i);
<     return OFF2STR(&ss->sprinter, off);
< }
< 
820c1069
< #define PAREN_SLOP      (2 + 1)
---
> #define PAREN_SLOP	(2 + 1)
824,825c1073,1074
<  * JSOP_SETPROP, and JSOP_SETELEM, respectively.  They are never stored in
<  * bytecode, so they don't preempt valid opcodes.
---
>  * JSOP_SETPROP, and JSOP_SETELEM, respectively.  See the first assertion in
>  * PushOff.
827,835c1076,1077
< #define JSOP_GETPROP2   256
< #define JSOP_GETELEM2   257
< 
< static void
< AddParenSlop(SprintStack *ss)
< {
<     memset(OFF2STR(&ss->sprinter, ss->sprinter.offset), 0, PAREN_SLOP);
<     ss->sprinter.offset += PAREN_SLOP;
< }
---
> #define JSOP_GETPROP2   254
> #define JSOP_GETELEM2   255
842,843c1084,1088
<     if (!SprintEnsureBuffer(&ss->sprinter, PAREN_SLOP))
<         return JS_FALSE;
---
> #if JSOP_LIMIT > JSOP_GETPROP2
> #error JSOP_LIMIT must be <= JSOP_GETPROP2
> #endif
>     if (!SprintAlloc(&ss->sprinter, PAREN_SLOP))
> 	return JS_FALSE;
849,850c1094,1095
<         JS_ReportOutOfMemory(ss->sprinter.context);
<         return JS_FALSE;
---
> 	JS_ReportOutOfMemory(ss->sprinter.context);
> 	return JS_FALSE;
856,857c1101,1102
<                      : (op == JSOP_GETELEM2) ? JSOP_GETELEM
<                      : (jsbytecode) op;
---
> 		     : (op == JSOP_GETELEM2) ? JSOP_GETELEM
> 		     : (jsbytecode) op;
859c1104
<     AddParenSlop(ss);
---
>     ss->sprinter.offset += PAREN_SLOP;
867c1112
<     const JSCodeSpec *cs, *topcs;
---
>     JSCodeSpec *cs, *topcs;
874c1119
<         return 0;
---
> 	return 0;
877d1121
<     off = GetOff(ss, top);
881,882c1125,1128
<         ss->sprinter.offset = ss->offsets[top] = off - 2;
<         off = Sprint(&ss->sprinter, "(%s)", OFF2STR(&ss->sprinter, off));
---
> 	ss->offsets[top] -= 2;
> 	ss->sprinter.offset = ss->offsets[top];
> 	off = Sprint(&ss->sprinter, "(%s)",
> 		     OFF2STR(&ss->sprinter, ss->sprinter.offset + 2));
884c1130
<         ss->sprinter.offset = off;
---
> 	off = ss->sprinter.offset = ss->offsets[top];
889,897c1135
< static const char *
< PopStr(SprintStack *ss, JSOp op)
< {
<     ptrdiff_t off;
< 
<     off = PopOff(ss, op);
<     return OFF2STR(&ss->sprinter, off);
< }
< 
---
> #if JS_HAS_SWITCH_STATEMENT
901,902d1138
<     JSAtom      *label;
<     jsint       order;          /* source order for stable tableswitch sort */
905,906c1141,1142
< static JSBool
< CompareOffsets(void *arg, const void *v1, const void *v2, int *result)
---
> static int
> CompareOffsets(const void *v1, const void *v2, void *arg)
908d1143
<     ptrdiff_t offset_diff;
912,952c1147
<     offset_diff = te1->offset - te2->offset;
<     *result = (offset_diff == 0 ? te1->order - te2->order
<                : offset_diff < 0 ? -1
<                : 1);
<     return JS_TRUE;
< }
< 
< static ptrdiff_t
< SprintDoubleValue(Sprinter *sp, jsval v, JSOp *opp)
< {
<     jsdouble d;
<     ptrdiff_t todo;
<     char *s, buf[DTOSTR_STANDARD_BUFFER_SIZE];
< 
<     JS_ASSERT(JSVAL_IS_DOUBLE(v));
<     d = *JSVAL_TO_DOUBLE(v);
<     if (JSDOUBLE_IS_NEGZERO(d)) {
<         todo = SprintCString(sp, "-0");
<         *opp = JSOP_NEG;
<     } else if (!JSDOUBLE_IS_FINITE(d)) {
<         /* Don't use Infinity and NaN, they're mutable. */
<         todo = SprintCString(sp,
<                              JSDOUBLE_IS_NaN(d)
<                              ? "0 / 0"
<                              : (d < 0)
<                              ? "1 / -0"
<                              : "1 / 0");
<         *opp = JSOP_DIV;
<     } else {
<         s = JS_dtostr(buf, sizeof buf, DTOSTR_STANDARD, 0, d);
<         if (!s) {
<             JS_ReportOutOfMemory(sp->context);
<             return -1;
<         }
<         JS_ASSERT(strcmp(s, js_Infinity_str) &&
<                   (*s != '-' ||
<                    strcmp(s + 1, js_Infinity_str)) &&
<                   strcmp(s, js_NaN_str));
<         todo = Sprint(sp, s);
<     }
<     return todo;
---
>     return te1->offset - te2->offset;
955,956c1150,1151
< static jsbytecode *
< Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop);
---
> static JSBool
> Decompile(SprintStack *ss, jsbytecode *pc, intN nb);
960,961c1155,1156
<                 jsbytecode *pc, ptrdiff_t switchLength,
<                 ptrdiff_t defaultOffset, JSBool isCondSwitch)
---
> 		jsbytecode *pc, ptrdiff_t switchLength,
> 		ptrdiff_t defaultOffset, JSBool isCondSwitch)
965d1159
<     ptrdiff_t off, off2, diff, caseExprOff, todo;
967a1162
>     ptrdiff_t diff, off, off2, caseExprOff;
974,977c1169
<     /* JSOP_CONDSWITCH doesn't pop, unlike JSOP_{LOOKUP,TABLE}SWITCH. */
<     off = isCondSwitch ? GetOff(ss, ss->top-1) : PopOff(ss, JSOP_NOP);
<     lval = OFF2STR(&ss->sprinter, off);
< 
---
>     lval = OFF2STR(&ss->sprinter, PopOff(ss, JSOP_NOP));
981,1006c1173,1203
<         diff = table[0].offset - defaultOffset;
<         if (diff > 0) {
<             jp->indent += 2;
<             js_printf(jp, "\t%s:\n", js_default_str);
<             jp->indent += 2;
<             if (!Decompile(ss, pc + defaultOffset, diff, JSOP_NOP))
<                 return JS_FALSE;
<             jp->indent -= 4;
<         }
< 
<         caseExprOff = isCondSwitch ? JSOP_CONDSWITCH_LENGTH : 0;
< 
<         for (i = 0; i < tableLength; i++) {
<             off = table[i].offset;
<             off2 = (i + 1 < tableLength) ? table[i + 1].offset : switchLength;
< 
<             key = table[i].key;
<             if (isCondSwitch) {
<                 ptrdiff_t nextCaseExprOff;
< 
<                 /*
<                  * key encodes the JSOP_CASE bytecode's offset from switchtop.
<                  * The next case expression follows immediately, unless we are
<                  * at the last case.
<                  */
<                 nextCaseExprOff = (ptrdiff_t)JSVAL_TO_INT(key);
---
> 	diff = table[0].offset - defaultOffset;
> 	if (diff > 0) {
> 	    jp->indent += 2;
> 	    js_printf(jp, "\tdefault:\n");
> 	    jp->indent += 2;
> 	    if (!Decompile(ss, pc + defaultOffset, diff))
> 		return JS_FALSE;
> 	    jp->indent -= 4;
> 	}
> 
> 	caseExprOff = isCondSwitch
>                       ? (ptrdiff_t) js_CodeSpec[JSOP_CONDSWITCH].length
>                       : 0;
> 
> 	for (i = 0; i < tableLength; i++) {
> 	    off = table[i].offset;
> 	    if (i + 1 < tableLength)
> 		off2 = table[i + 1].offset;
> 	    else
> 		off2 = switchLength;
> 
> 	    key = table[i].key;
> 	    if (isCondSwitch) {
> 		ptrdiff_t nextCaseExprOff;
> 
> 		/*
> 		 * key encodes the JSOP_CASE bytecode's offset from switchtop.
> 		 * The next case expression follows immediately, unless we are
> 		 * at the last case.
> 		 */
> 		nextCaseExprOff = (ptrdiff_t)JSVAL_TO_INT(key);
1008,1072c1205,1246
<                 jp->indent += 2;
<                 if (!Decompile(ss, pc + caseExprOff,
<                                nextCaseExprOff - caseExprOff, JSOP_NOP)) {
<                     return JS_FALSE;
<                 }
<                 caseExprOff = nextCaseExprOff;
< 
<                 /* Balance the stack as if this JSOP_CASE matched. */
<                 --ss->top;
<             } else {
<                 /*
<                  * key comes from an atom, not the decompiler, so we need to
<                  * quote it if it's a string literal.  But if table[i].label
<                  * is non-null, key was constant-propagated and label is the
<                  * name of the const we should show as the case label.  We set
<                  * key to undefined so this identifier is escaped, if required
<                  * by non-ASCII characters, but not quoted, by QuoteString.
<                  */
<                 todo = -1;
<                 if (table[i].label) {
<                     str = ATOM_TO_STRING(table[i].label);
<                     key = JSVAL_VOID;
<                 } else if (JSVAL_IS_DOUBLE(key)) {
<                     JSOp junk;
< 
<                     todo = SprintDoubleValue(&ss->sprinter, key, &junk);
<                     str = NULL;
<                 } else {
<                     str = js_ValueToString(cx, key);
<                     if (!str)
<                         return JS_FALSE;
<                 }
<                 if (todo >= 0) {
<                     rval = OFF2STR(&ss->sprinter, todo);
<                 } else {
<                     rval = QuoteString(&ss->sprinter, str, (jschar)
<                                        (JSVAL_IS_STRING(key) ? '"' : 0));
<                     if (!rval)
<                         return JS_FALSE;
<                 }
<                 RETRACT(&ss->sprinter, rval);
<                 jp->indent += 2;
<                 js_printf(jp, "\tcase %s:\n", rval);
<             }
< 
<             jp->indent += 2;
<             if (off <= defaultOffset && defaultOffset < off2) {
<                 diff = defaultOffset - off;
<                 if (diff != 0) {
<                     if (!Decompile(ss, pc + off, diff, JSOP_NOP))
<                         return JS_FALSE;
<                     off = defaultOffset;
<                 }
<                 jp->indent -= 2;
<                 js_printf(jp, "\t%s:\n", js_default_str);
<                 jp->indent += 2;
<             }
<             if (!Decompile(ss, pc + off, off2 - off, JSOP_NOP))
<                 return JS_FALSE;
<             jp->indent -= 4;
< 
<             /* Re-balance as if last JSOP_CASE or JSOP_DEFAULT mismatched. */
<             if (isCondSwitch)
<                 ++ss->top;
<         }
---
> 		jp->indent += 2;
> 		if (!Decompile(ss, pc + caseExprOff,
> 			       nextCaseExprOff - caseExprOff)) {
> 		    return JS_FALSE;
> 		}
> 		caseExprOff = nextCaseExprOff;
> 	   } else {
> 		/*
> 		 * key comes from an atom, not the decompiler, so we need to
> 		 * quote it if it's a string literal.
> 		 */
> 		str = js_ValueToString(cx, key);
> 		if (!str)
> 		    return JS_FALSE;
> 		jp->indent += 2;
> 		if (JSVAL_IS_STRING(key)) {
> 		    rval = QuoteString(&ss->sprinter, str, (jschar)'"');
> 		    if (!rval)
> 			return JS_FALSE;
>                     RETRACT(&ss->sprinter, rval);
> 		} else {
> 		    rval = JS_GetStringBytes(str);
> 		}
> 		js_printf(jp, "\tcase %s:\n", rval);
> 	    }
> 
> 	    jp->indent += 2;
> 	    if (off <= defaultOffset && defaultOffset < off2) {
> 		diff = defaultOffset - off;
> 		if (diff != 0) {
> 		    if (!Decompile(ss, pc + off, diff))
> 			return JS_FALSE;
> 		    off = defaultOffset;
> 		}
> 		jp->indent -= 2;
> 		js_printf(jp, "\tdefault:\n");
> 		jp->indent += 2;
> 	    }
> 	    if (!Decompile(ss, pc + off, off2 - off))
> 		return JS_FALSE;
> 	    jp->indent -= 4;
> 	}
1076,1078c1250,1252
<         jp->indent += 2;
<         js_printf(jp, "\t%s:;\n", js_default_str);
<         jp->indent -= 2;
---
> 	jp->indent += 2;
> 	js_printf(jp, "\tdefault:\n");
> 	jp->indent -= 2;
1081,1084d1254
< 
<     /* By the end of a JSOP_CONDSWITCH, the discriminant has been popped. */
<     if (isCondSwitch)
<         --ss->top;
1087,1111d1256
< 
< #define LOCAL_ASSERT_RV(expr, rv)                                             \
<     JS_BEGIN_MACRO                                                            \
<         JS_ASSERT(expr);                                                      \
<         if (!(expr)) return (rv);                                             \
<     JS_END_MACRO
< 
< static JSAtom *
< GetSlotAtom(JSPrinter *jp, JSBool argument, uintN slot)
< {
<     JSFunction *fun;
<     JSAtom *name;
< 
<     fun = jp->fun;
<     LOCAL_ASSERT_RV(jp->fun, NULL);
<     LOCAL_ASSERT_RV(jp->localNames, NULL);
<     if (argument) {
<         LOCAL_ASSERT_RV(slot < fun->nargs, NULL);
<     } else {
<         LOCAL_ASSERT_RV(slot < fun->u.i.nvars, NULL);
<         slot += fun->nargs;
<     }
<     name = JS_LOCAL_NAME_TO_ATOM(jp->localNames[slot]);
< #if !JS_HAS_DESTRUCTURING
<     LOCAL_ASSERT_RV(name, NULL);
1113,1114d1257
<     return name;
< }
1116,1117c1259,1260
< const char *
< GetLocal(SprintStack *ss, jsint i)
---
> static JSAtom *
> GetSlotAtom(JSPrinter *jp, JSPropertyOp getter, uintN slot)
1119,1125c1262
<     ptrdiff_t off;
<     JSContext *cx;
<     JSScript *script;
<     jsatomid j, n;
<     JSAtom *atom;
<     JSObject *obj;
<     jsint depth, count;
---
>     JSScope *scope;
1127,1133c1264
<     const char *rval;
< 
< #define LOCAL_ASSERT(expr)      LOCAL_ASSERT_RV(expr, "")
< 
<     off = ss->offsets[i];
<     if (off >= 0)
<         return OFF2STR(&ss->sprinter, off);
---
>     JSObject *obj, *proto;
1135,1149c1266,1274
<     /*
<      * We must be called from js_DecompileValueGenerator (via Decompile) when
<      * dereferencing a local that's undefined or null. Search script->objects
<      * for the block containing this local by its stack index, i.
<      */
<     cx = ss->sprinter.context;
<     script = ss->printer->script;
<     LOCAL_ASSERT(script->objectsOffset != 0);
<     for (j = 0, n = JS_SCRIPT_OBJECTS(script)->length; j < n; j++) {
<         JS_GET_SCRIPT_OBJECT(script, j, obj);
<         if (OBJ_GET_CLASS(cx, obj) == &js_BlockClass) {
<             depth = OBJ_BLOCK_DEPTH(cx, obj);
<             count = OBJ_BLOCK_COUNT(cx, obj);
<             if ((jsuint)(i - depth) < (jsuint)count)
<                 break;
---
>     scope = jp->scope;
>     while (scope) {
>         for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) {
>             if (sprop->getter != getter)
>                 continue;
>             JS_ASSERT(sprop->flags & SPROP_HAS_SHORTID);
>             JS_ASSERT(!JSVAL_IS_INT(sprop->id));
>             if ((uintN) sprop->shortid == slot)
>                 return (JSAtom *) sprop->id;
1151,1156c1276,1280
<     }
< 
<     LOCAL_ASSERT(j < n);
<     i -= depth;
<     for (sprop = OBJ_SCOPE(obj)->lastProp; sprop; sprop = sprop->parent) {
<         if (sprop->shortid == i)
---
>         obj = scope->object;
>         if (!obj)
>             break;
>         proto = OBJ_GET_PROTO(jp->sprinter.context, obj);
>         if (!proto)
1157a1282
>         scope = OBJ_SCOPE(proto);
1159,1168c1284
< 
<     LOCAL_ASSERT(sprop && JSID_IS_ATOM(sprop->id));
<     atom = JSID_TO_ATOM(sprop->id);
<     rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
<     if (!rval)
<         return NULL;
<     RETRACT(&ss->sprinter, rval);
<     return rval;
< 
< #undef LOCAL_ASSERT
---
>     return NULL;
1171,1181c1287,1288
< #if JS_HAS_DESTRUCTURING
< 
< #define LOCAL_ASSERT(expr)  LOCAL_ASSERT_RV(expr, NULL)
< #define LOAD_OP_DATA(pc)    (oplen = (cs = &js_CodeSpec[op=(JSOp)*pc])->length)
< 
< static jsbytecode *
< DecompileDestructuring(SprintStack *ss, jsbytecode *pc, jsbytecode *endpc);
< 
< static jsbytecode *
< DecompileDestructuringLHS(SprintStack *ss, jsbytecode *pc, jsbytecode *endpc,
<                           JSBool *hole)
---
> static const char *
> VarPrefix(jssrcnote *sn)
1183,1201c1290,1291
<     JSContext *cx;
<     JSPrinter *jp;
<     JSOp op;
<     const JSCodeSpec *cs;
<     uintN oplen, i;
<     const char *lval, *xval;
<     ptrdiff_t todo;
<     JSAtom *atom;
< 
<     *hole = JS_FALSE;
<     cx = ss->sprinter.context;
<     jp = ss->printer;
<     LOAD_OP_DATA(pc);
< 
<     switch (op) {
<       case JSOP_POP:
<         *hole = JS_TRUE;
<         todo = SprintPut(&ss->sprinter, ", ", 2);
<         break;
---
>     char *kw;
>     static char buf[8];
1203,1215c1293,1304
<       case JSOP_DUP:
<         pc = DecompileDestructuring(ss, pc, endpc);
<         if (!pc)
<             return NULL;
<         if (pc == endpc)
<             return pc;
<         LOAD_OP_DATA(pc);
<         lval = PopStr(ss, JSOP_NOP);
<         todo = SprintCString(&ss->sprinter, lval);
<         if (op == JSOP_POPN)
<             return pc;
<         LOCAL_ASSERT(*pc == JSOP_POP);
<         break;
---
>     kw = NULL;
>     if (sn) {
>         if (SN_TYPE(sn) == SRC_VAR)
>             kw = js_var_str;
>         else if (SN_TYPE(sn) == SRC_CONST)
>             kw = js_const_str;
>     }
>     if (!kw)
>         return "";
>     JS_snprintf(buf, sizeof buf, "%s ", kw);
>     return buf;
> }
1217,1249c1306,1310
<       case JSOP_SETARG:
<       case JSOP_SETVAR:
<       case JSOP_SETGVAR:
<       case JSOP_SETLOCAL:
<         LOCAL_ASSERT(pc[oplen] == JSOP_POP || pc[oplen] == JSOP_POPN);
<         /* FALL THROUGH */
< 
<       case JSOP_SETLOCALPOP:
<         i = GET_UINT16(pc);
<         atom = NULL;
<         lval = NULL;
<         if (op == JSOP_SETARG || op == JSOP_SETVAR) {
<             atom = GetSlotAtom(jp, op == JSOP_SETARG, i);
<             LOCAL_ASSERT(atom);
<         } else if (op == JSOP_SETGVAR) {
<             GET_ATOM_FROM_BYTECODE(jp->script, pc, 0, atom);
<         } else {
<             lval = GetLocal(ss, i);
<         }
<         if (atom)
<             lval = js_AtomToPrintableString(cx, atom);
<         LOCAL_ASSERT(lval);
<         todo = SprintCString(&ss->sprinter, lval);
<         if (op != JSOP_SETLOCALPOP) {
<             pc += oplen;
<             if (pc == endpc)
<                 return pc;
<             LOAD_OP_DATA(pc);
<             if (op == JSOP_POPN)
<                 return pc;
<             LOCAL_ASSERT(op == JSOP_POP);
<         }
<         break;
---
> static JSBool
> IsASCIIIdentifier(JSString *str)
> {
>     size_t n;
>     jschar *s, c;
1251,1284c1312,1320
<       default:
<         /*
<          * We may need to auto-parenthesize the left-most value decompiled
<          * here, so add back PAREN_SLOP temporarily.  Then decompile until the
<          * opcode that would reduce the stack depth to (ss->top-1), which we
<          * pass to Decompile encoded as -(ss->top-1) - 1 or just -ss->top for
<          * the nb parameter.
<          */
<         todo = ss->sprinter.offset;
<         ss->sprinter.offset = todo + PAREN_SLOP;
<         pc = Decompile(ss, pc, -((intN)ss->top), JSOP_NOP);
<         if (!pc)
<             return NULL;
<         if (pc == endpc)
<             return pc;
<         LOAD_OP_DATA(pc);
<         LOCAL_ASSERT(op == JSOP_ENUMELEM || op == JSOP_ENUMCONSTELEM);
<         xval = PopStr(ss, JSOP_NOP);
<         lval = PopStr(ss, JSOP_GETPROP);
<         ss->sprinter.offset = todo;
<         if (*lval == '\0') {
<             /* lval is from JSOP_BINDNAME, so just print xval. */
<             todo = SprintCString(&ss->sprinter, xval);
<         } else if (*xval == '\0') {
<             /* xval is from JSOP_SETCALL or JSOP_BINDXMLNAME, print lval. */
<             todo = SprintCString(&ss->sprinter, lval);
<         } else {
<             todo = Sprint(&ss->sprinter,
<                           (JOF_OPMODE(ss->opcodes[ss->top+1]) == JOF_XMLNAME)
<                           ? "%s.%s"
<                           : "%s[%s]",
<                           lval, xval);
<         }
<         break;
---
>     n = JSSTRING_LENGTH(str);
>     s = JSSTRING_CHARS(str);
>     c = *s;
>     if (n == 0 || !JS_ISIDENT_START(c) || !JS_ISPRINT(c))
>         return JS_FALSE;
>     for (n--; n != 0; n--) {
>         c = *++s;
>         if (!JS_ISIDENT(c) || !JS_ISPRINT(c))
>             return JS_FALSE;
1286,1292c1322
< 
<     if (todo < 0)
<         return NULL;
< 
<     LOCAL_ASSERT(pc < endpc);
<     pc += oplen;
<     return pc;
---
>     return JS_TRUE;
1295,1306c1325,1326
< /*
<  * Starting with a SRC_DESTRUCT-annotated JSOP_DUP, decompile a destructuring
<  * left-hand side object or array initialiser, including nested destructuring
<  * initialisers.  On successful return, the decompilation will be pushed on ss
<  * and the return value will point to the POP or GROUP bytecode following the
<  * destructuring expression.
<  *
<  * At any point, if pc is equal to endpc and would otherwise advance, we stop
<  * immediately and return endpc.
<  */
< static jsbytecode *
< DecompileDestructuring(SprintStack *ss, jsbytecode *pc, jsbytecode *endpc)
---
> static JSBool
> Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
1308d1327
<     ptrdiff_t head;
1310,1317c1329,1333
<     JSPrinter *jp;
<     JSOp op, saveop;
<     const JSCodeSpec *cs;
<     uintN oplen;
<     jsint i, lasti;
<     jsdouble d;
<     const char *lval;
<     JSAtom *atom;
---
>     JSPrinter *jp, *jp2;
>     jsbytecode *endpc, *done, *forelem_done;
>     ptrdiff_t len, todo, oplen, cond, next, tail;
>     JSOp op, lastop, saveop;
>     JSCodeSpec *cs, *topcs;
1318a1335,1340
>     const char *lval, *rval, *xval;
>     jsint i, argc;
>     char **argv;
>     JSAtom *atom;
>     JSObject *obj;
>     JSFunction *fun;
1320,1323c1342,1343
<     JSBool hole;
< 
<     LOCAL_ASSERT(*pc == JSOP_DUP);
<     pc += JSOP_DUP_LENGTH;
---
>     JSBool ok;
>     jsval val;
1325,1335c1345,1350
<     /*
<      * Set head so we can rewrite '[' to '{' as needed.  Back up PAREN_SLOP
<      * chars so the destructuring decompilation accumulates contiguously in
<      * ss->sprinter starting with "[".
<      */
<     head = SprintPut(&ss->sprinter, "[", 1);
<     if (head < 0 || !PushOff(ss, head, JSOP_NOP))
<         return NULL;
<     ss->sprinter.offset -= PAREN_SLOP;
<     LOCAL_ASSERT(head == ss->sprinter.offset - 1);
<     LOCAL_ASSERT(*OFF2STR(&ss->sprinter, head) == '[');
---
> /*
>  * Local macros
>  */
> #define DECOMPILE_CODE(pc,nb)	if (!Decompile(ss, pc, nb)) return JS_FALSE
> #define POP_STR()		OFF2STR(&ss->sprinter, PopOff(ss, op))
> #define LOCAL_ASSERT(expr)	JS_ASSERT(expr); if (!(expr)) return JS_FALSE
1339c1354,1360
<     lasti = -1;
---
>     endpc = pc + nb;
>     forelem_done = NULL;
>     todo = -2;			/* NB: different from Sprint() error return. */
>     tail = -1;
>     op = JSOP_NOP;
>     sn = NULL;
>     rval = NULL;
1342,1344c1363,1397
< #if JS_HAS_DESTRUCTURING_SHORTHAND
<         ptrdiff_t nameoff = -1;
< #endif
---
> 	lastop = op;
> 	op = saveop = (JSOp) *pc;
> 	if (op >= JSOP_LIMIT) {
> 	    switch (op) {
> 	      case JSOP_GETPROP2:
> 		saveop = JSOP_GETPROP;
> 		break;
> 	      case JSOP_GETELEM2:
> 		saveop = JSOP_GETELEM;
> 		break;
> 	      default:;
> 	    }
> 	}
> 	cs = &js_CodeSpec[saveop];
> 	len = oplen = cs->length;
> 
> 	if (cs->token) {
> 	    switch (cs->nuses) {
> 	      case 2:
> 		rval = POP_STR();
> 		lval = POP_STR();
> 		if ((sn = js_GetSrcNote(jp->script, pc)) != NULL &&
> 		    SN_TYPE(sn) == SRC_ASSIGNOP) {
> 		    /* Print only the right operand of the assignment-op. */
> 		    todo = SprintPut(&ss->sprinter, rval, strlen(rval));
> 		} else {
> 		    todo = Sprint(&ss->sprinter, "%s %s %s",
> 				  lval, cs->token, rval);
> 		}
> 		break;
> 
> 	      case 1:
> 		rval = POP_STR();
> 		todo = Sprint(&ss->sprinter, "%s%s", cs->token, rval);
> 		break;
1346,1388c1399,1403
<         LOAD_OP_DATA(pc);
<         saveop = op;
< 
<         switch (op) {
<           case JSOP_POP:
<             pc += oplen;
<             goto out;
< 
<           /* Handle the optimized number-pushing opcodes. */
<           case JSOP_ZERO:   d = i = 0; goto do_getelem;
<           case JSOP_ONE:    d = i = 1; goto do_getelem;
<           case JSOP_UINT16: d = i = GET_UINT16(pc); goto do_getelem;
<           case JSOP_UINT24: d = i = GET_UINT24(pc); goto do_getelem;
<           case JSOP_INT8:   d = i = GET_INT8(pc);   goto do_getelem;
<           case JSOP_INT32:  d = i = GET_INT32(pc);  goto do_getelem;
< 
<           case JSOP_DOUBLE:
<             GET_ATOM_FROM_BYTECODE(jp->script, pc, 0, atom);
<             d = *ATOM_TO_DOUBLE(atom);
<             LOCAL_ASSERT(JSDOUBLE_IS_FINITE(d) && !JSDOUBLE_IS_NEGZERO(d));
<             i = (jsint)d;
< 
<           do_getelem:
<             sn = js_GetSrcNote(jp->script, pc);
<             pc += oplen;
<             if (pc == endpc)
<                 return pc;
<             LOAD_OP_DATA(pc);
<             LOCAL_ASSERT(op == JSOP_GETELEM);
< 
<             /* Distinguish object from array by opcode or source note. */
<             if (sn && SN_TYPE(sn) == SRC_INITPROP) {
<                 *OFF2STR(&ss->sprinter, head) = '{';
<                 if (Sprint(&ss->sprinter, "%g: ", d) < 0)
<                     return NULL;
<             } else {
<                 /* Sanity check for the gnarly control flow above. */
<                 LOCAL_ASSERT(i == d);
< 
<                 /* Fill in any holes (holes at the end don't matter). */
<                 while (++lasti < i) {
<                     if (SprintPut(&ss->sprinter, ", ", 2) < 0)
<                         return NULL;
---
> 	      case 0:
> #if JS_HAS_GETTER_SETTER
>                 if (op == JSOP_GETTER || op == JSOP_SETTER) {
>                     todo = -2;
>                     break;
1390,1404d1404
<             }
<             break;
< 
<           case JSOP_LENGTH:
<             atom = cx->runtime->atomState.lengthAtom;
<             goto do_destructure_atom;
< 
<           case JSOP_CALLPROP:
<           case JSOP_GETPROP:
<             GET_ATOM_FROM_BYTECODE(jp->script, pc, 0, atom);
<           do_destructure_atom:
<             *OFF2STR(&ss->sprinter, head) = '{';
<             str = ATOM_TO_STRING(atom);
< #if JS_HAS_DESTRUCTURING_SHORTHAND
<             nameoff = ss->sprinter.offset;
1406,1412c1406,1407
<             if (!QuoteString(&ss->sprinter, str,
<                              js_IsIdentifier(str) ? 0 : (jschar)'\'')) {
<                 return NULL;
<             }
<             if (SprintPut(&ss->sprinter, ": ", 2) < 0)
<                 return NULL;
<             break;
---
> 		todo = SprintPut(&ss->sprinter, cs->token, strlen(cs->token));
> 		break;
1414,1416c1409,1484
<           default:
<             LOCAL_ASSERT(0);
<         }
---
> 	      default:
> 		todo = -2;
> 		break;
> 	    }
> 	} else {
> 	    switch (op) {
> 	      case JSOP_NOP:
> 		/*
>                  * Check for a do-while loop, a for-loop with an empty
>                  * initializer part, a labeled statement, a function
>                  * definition, or try/finally.
> 		 */
> 		sn = js_GetSrcNote(jp->script, pc);
> 		todo = -2;
> 		switch (sn ? SN_TYPE(sn) : SRC_NULL) {
> #if JS_HAS_DO_WHILE_LOOP
> 		  case SRC_WHILE:
> 		    js_printf(jp, "\tdo {\n");
> 		    jp->indent += 4;
> 		    break;
> #endif /* JS_HAS_DO_WHILE_LOOP */
> 
> 		  case SRC_FOR:
> 		    rval = "";
> 
> 		  do_forloop:
> 		    /* Skip the JSOP_NOP or JSOP_POP bytecode. */
> 		    pc++;
> 
> 		    /* Get the cond, next, and loop-closing tail offsets. */
> 		    cond = js_GetSrcNoteOffset(sn, 0);
> 		    next = js_GetSrcNoteOffset(sn, 1);
> 		    tail = js_GetSrcNoteOffset(sn, 2);
> 		    LOCAL_ASSERT(tail + GetJumpOffset(pc+tail, pc+tail) == 0);
> 
> 		    /* Print the keyword and the possibly empty init-part. */
> 		    js_printf(jp, "\tfor (%s;", rval);
> 
> 		    if (pc[cond] == JSOP_IFEQ || pc[cond] == JSOP_IFEQX) {
> 			/* Decompile the loop condition. */
> 			DECOMPILE_CODE(pc, cond);
> 			js_printf(jp, " %s", POP_STR());
> 		    }
> 
> 		    /* Need a semicolon whether or not there was a cond. */
> 		    js_puts(jp, ";");
> 
> 		    if (pc[next] != JSOP_GOTO && pc[next] != JSOP_GOTOX) {
> 			/* Decompile the loop updater. */
> 			DECOMPILE_CODE(pc + next, tail - next - 1);
> 			js_printf(jp, " %s", POP_STR());
> 		    }
> 
> 		    /* Do the loop body. */
> 		    js_puts(jp, ") {\n");
> 		    jp->indent += 4;
> 		    oplen = (cond) ? js_CodeSpec[pc[cond]].length : 0;
> 		    DECOMPILE_CODE(pc + cond + oplen, next - cond - oplen);
> 		    jp->indent -= 4;
> 		    js_printf(jp, "\t}\n");
> 
> 		    /* Set len so pc skips over the entire loop. */
> 		    len = tail + js_CodeSpec[pc[tail]].length;
> 		    break;
> 
> 		  case SRC_LABEL:
> 		    atom = js_GetAtom(cx, &jp->script->atomMap,
> 				      (jsatomid) js_GetSrcNoteOffset(sn, 0));
> 		    jp->indent -= 4;
>                     rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
>                     if (!rval)
>                         return JS_FALSE;
>                     RETRACT(&ss->sprinter, rval);
>                     js_printf(jp, "\t%s:\n", rval);
> 		    jp->indent += 4;
> 		    break;
1418,1420c1486,1535
<         pc += oplen;
<         if (pc == endpc)
<             return pc;
---
> 		  case SRC_LABELBRACE:
> 		    atom = js_GetAtom(cx, &jp->script->atomMap,
> 				      (jsatomid) js_GetSrcNoteOffset(sn, 0));
>                     rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
>                     if (!rval)
>                         return JS_FALSE;
>                     RETRACT(&ss->sprinter, rval);
> 		    js_printf(jp, "\t%s: {\n", rval);
> 		    jp->indent += 4;
> 		    break;
> 
> 		  case SRC_ENDBRACE:
> 		    jp->indent -= 4;
> 		    js_printf(jp, "\t}\n");
> 		    break;
> 
> 		  case SRC_CATCH:
> 		    jp->indent -= 4;
> 		    sn = js_GetSrcNote(jp->script, pc);
> 		    pc += oplen;
> 		    js_printf(jp, "\t} catch (");
> 
>                     LOCAL_ASSERT(*pc == JSOP_NAME);
>                     pc += js_CodeSpec[JSOP_NAME].length;
>                     LOCAL_ASSERT(*pc == JSOP_PUSHOBJ);
>                     pc += js_CodeSpec[JSOP_PUSHOBJ].length;
>                     LOCAL_ASSERT(*pc == JSOP_NEWINIT);
>                     pc += js_CodeSpec[JSOP_NEWINIT].length;
>                     LOCAL_ASSERT(*pc == JSOP_EXCEPTION);
>                     pc += js_CodeSpec[JSOP_EXCEPTION].length;
>                     LOCAL_ASSERT(*pc == JSOP_INITCATCHVAR);
>                     atom = GET_ATOM(cx, jp->script, pc);
>                     rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
>                     if (!rval)
>                         return JS_FALSE;
>                     RETRACT(&ss->sprinter, rval);
>                     js_printf(jp, "%s", rval);
>                     pc += js_CodeSpec[JSOP_INITCATCHVAR].length;
>                     LOCAL_ASSERT(*pc == JSOP_ENTERWITH);
>                     pc += js_CodeSpec[JSOP_ENTERWITH].length;
> 
> 		    len = js_GetSrcNoteOffset(sn, 0);
> 		    if (len) {
> 			js_printf(jp, " if ");
> 			DECOMPILE_CODE(pc, len);
> 			js_printf(jp, "%s", POP_STR());
> 			pc += len;
>                         LOCAL_ASSERT(*pc == JSOP_IFEQ || *pc == JSOP_IFEQX);
>                         pc += js_CodeSpec[*pc].length;
> 		    }
1422,1429c1537,1560
<         /*
<          * Decompile the left-hand side expression whose bytecode starts at pc
<          * and continues for a bounded number of bytecodes or stack operations
<          * (and which in any event stops before endpc).
<          */
<         pc = DecompileDestructuringLHS(ss, pc, endpc, &hole);
<         if (!pc)
<             return NULL;
---
> 		    js_printf(jp, ") {\n");
> 		    jp->indent += 4;
> 		    len = 0;
> 		    break;
> 
> 		  case SRC_FUNCDEF:
> 		    atom = js_GetAtom(cx, &jp->script->atomMap,
> 				      (jsatomid) js_GetSrcNoteOffset(sn, 0));
> 		    JS_ASSERT(ATOM_IS_OBJECT(atom));
>                   do_function:
> 		    obj = ATOM_TO_OBJECT(atom);
> 		    fun = (JSFunction *) JS_GetPrivate(cx, obj);
> 		    jp2 = js_NewPrinter(cx, JS_GetFunctionName(fun),
> 					jp->indent, jp->pretty);
> 		    if (!jp2)
> 			return JS_FALSE;
> 		    jp2->scope = jp->scope;
> 		    if (js_DecompileFunction(jp2, fun)) {
> 			str = js_GetPrinterOutput(jp2);
> 			if (str)
> 			    js_printf(jp, "%s\n", JS_GetStringBytes(str));
> 		    }
> 		    js_DestroyPrinter(jp2);
> 		    break;
1431,1443c1562,1565
< #if JS_HAS_DESTRUCTURING_SHORTHAND
<         if (nameoff >= 0) {
<             ptrdiff_t offset, initlen;
< 
<             offset = ss->sprinter.offset;
<             LOCAL_ASSERT(*OFF2STR(&ss->sprinter, offset) == '\0');
<             initlen = offset - nameoff;
<             LOCAL_ASSERT(initlen >= 4);
< 
<             /* Early check to rule out odd "name: lval" length. */
<             if (((size_t)initlen & 1) == 0) {
<                 size_t namelen;
<                 const char *name;
---
> 		  default:;
> 		}
>               case JSOP_RETRVAL:
> 		break;
1445,1459c1567,1569
<                 /*
<                  * Even "name: lval" string length: check for "x: x" and the
<                  * like, and apply the shorthand if we can.
<                  */
<                 namelen = (size_t)(initlen - 2) >> 1;
<                 name = OFF2STR(&ss->sprinter, nameoff);
<                 if (!strncmp(name + namelen, ": ", 2) &&
<                     !strncmp(name, name + namelen + 2, namelen)) {
<                     offset -= namelen + 2;
<                     *OFF2STR(&ss->sprinter, offset) = '\0';
<                     ss->sprinter.offset = offset;
<                 }
<             }
<         }
< #endif
---
>               case JSOP_GROUP:
>                 /* Use last real op so PopOff adds parens if needed. */
>                 todo = PopOff(ss, lastop);
1461,1462c1571,1578
<         if (pc == endpc || *pc != JSOP_DUP)
<             break;
---
>                 /* Now add user-supplied parens only if PopOff did not. */
>                 cs    = &js_CodeSpec[lastop];
>                 topcs = &js_CodeSpec[ss->opcodes[ss->top]];
>                 if (topcs->prec >= cs->prec) {
>                     todo = Sprint(&ss->sprinter, "(%s)",
>                                   OFF2STR(&ss->sprinter, todo));
>                 }
>                 break;
1464,1471c1580,1584
<         /*
<          * Check for SRC_DESTRUCT on this JSOP_DUP, which would mean another
<          * destructuring initialiser abuts this one, and we should stop.  This
<          * happens with source of the form '[a] = [b] = c'.
<          */
<         sn = js_GetSrcNote(jp->script, pc);
<         if (sn && SN_TYPE(sn) == SRC_DESTRUCT)
<             break;
---
> 	      case JSOP_PUSH:
> 	      case JSOP_PUSHOBJ:
> 	      case JSOP_BINDNAME:
> 		todo = Sprint(&ss->sprinter, "");
> 		break;
1473,1474c1586,1591
<         if (!hole && SprintPut(&ss->sprinter, ", ", 2) < 0)
<             return NULL;
---
> #if JS_HAS_EXCEPTIONS
>               case JSOP_TRY:
>                 js_printf(jp, "\ttry {\n");
>                 jp->indent += 4;
> 		todo = -2;
>                 break;
1476,1477c1593,1594
<         pc += JSOP_DUP_LENGTH;
<     }
---
>             {
>               static const char finally_cookie[] = "finally-cookie";
1479,1484c1596,1599
< out:
<     lval = OFF2STR(&ss->sprinter, head);
<     if (SprintPut(&ss->sprinter, (*lval == '[') ? "]" : "}", 1) < 0)
<         return NULL;
<     return pc;
< }
---
>               case JSOP_FINALLY:
>                 jp->indent -= 4;
>                 js_printf(jp, "\t} finally {\n");
>                 jp->indent += 4;
1486,2091c1601,1607
< static jsbytecode *
< DecompileGroupAssignment(SprintStack *ss, jsbytecode *pc, jsbytecode *endpc,
<                          jssrcnote *sn, ptrdiff_t *todop)
< {
<     JSOp op;
<     const JSCodeSpec *cs;
<     uintN oplen, start, end, i;
<     ptrdiff_t todo;
<     JSBool hole;
<     const char *rval;
< 
<     LOAD_OP_DATA(pc);
<     LOCAL_ASSERT(op == JSOP_PUSH || op == JSOP_GETLOCAL);
< 
<     todo = Sprint(&ss->sprinter, "%s[", VarPrefix(sn));
<     if (todo < 0 || !PushOff(ss, todo, JSOP_NOP))
<         return NULL;
<     ss->sprinter.offset -= PAREN_SLOP;
< 
<     for (;;) {
<         pc += oplen;
<         if (pc == endpc)
<             return pc;
<         pc = DecompileDestructuringLHS(ss, pc, endpc, &hole);
<         if (!pc)
<             return NULL;
<         if (pc == endpc)
<             return pc;
<         LOAD_OP_DATA(pc);
<         if (op != JSOP_PUSH && op != JSOP_GETLOCAL)
<             break;
<         if (!hole && SprintPut(&ss->sprinter, ", ", 2) < 0)
<             return NULL;
<     }
< 
<     LOCAL_ASSERT(op == JSOP_POPN);
<     if (SprintPut(&ss->sprinter, "] = [", 5) < 0)
<         return NULL;
< 
<     end = ss->top - 1;
<     start = end - GET_UINT16(pc);
<     for (i = start; i < end; i++) {
<         rval = GetStr(ss, i);
<         if (Sprint(&ss->sprinter,
<                    (i == start) ? "%s" : ", %s",
<                    (i == end - 1 && *rval == '\0') ? ", " : rval) < 0) {
<             return NULL;
<         }
<     }
< 
<     if (SprintPut(&ss->sprinter, "]", 1) < 0)
<         return NULL;
<     ss->sprinter.offset = ss->offsets[i];
<     ss->top = start;
<     *todop = todo;
<     return pc;
< }
< 
< #undef LOCAL_ASSERT
< #undef LOAD_OP_DATA
< 
< #endif /* JS_HAS_DESTRUCTURING */
< 
< static JSBool
< InitSprintStack(JSContext *cx, SprintStack *ss, JSPrinter *jp, uintN depth)
< {
<     size_t offsetsz, opcodesz;
<     void *space;
< 
<     INIT_SPRINTER(cx, &ss->sprinter, &cx->tempPool, PAREN_SLOP);
< 
<     /* Allocate the parallel (to avoid padding) offset and opcode stacks. */
<     offsetsz = depth * sizeof(ptrdiff_t);
<     opcodesz = depth * sizeof(jsbytecode);
<     JS_ARENA_ALLOCATE(space, &cx->tempPool, offsetsz + opcodesz);
<     if (!space) {
<         js_ReportOutOfScriptQuota(cx);
<         return JS_FALSE;
<     }
<     ss->offsets = (ptrdiff_t *) space;
<     ss->opcodes = (jsbytecode *) ((char *)space + offsetsz);
< 
<     ss->top = ss->inArrayInit = 0;
<     ss->inGenExp = JS_FALSE;
<     ss->printer = jp;
<     return JS_TRUE;
< }
< 
< /*
<  * If nb is non-negative, decompile nb bytecodes starting at pc.  Otherwise
<  * the decompiler starts at pc and continues until it reaches an opcode for
<  * which decompiling would result in the stack depth equaling -(nb + 1).
<  *
<  * The nextop parameter is either JSOP_NOP or the "next" opcode in order of
<  * abstract interpretation (not necessarily physically next in a bytecode
<  * vector). So nextop is JSOP_POP for the last operand in a comma expression,
<  * or JSOP_AND for the right operand of &&.
<  */
< static jsbytecode *
< Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
< {
<     JSContext *cx;
<     JSPrinter *jp, *jp2;
<     jsbytecode *startpc, *endpc, *pc2, *done, *forelem_tail, *forelem_done;
<     ptrdiff_t tail, todo, len, oplen, cond, next;
<     JSOp op, lastop, saveop;
<     const JSCodeSpec *cs;
<     jssrcnote *sn, *sn2;
<     const char *lval, *rval, *xval, *fmt, *token;
<     jsint i, argc;
<     char **argv;
<     JSAtom *atom;
<     JSObject *obj;
<     JSFunction *fun;
<     JSString *str;
<     JSBool ok;
< #if JS_HAS_XML_SUPPORT
<     JSBool foreach, inXML, quoteAttr;
< #else
< #define inXML JS_FALSE
< #endif
<     jsval val;
< 
<     static const char exception_cookie[] = "/*EXCEPTION*/";
<     static const char retsub_pc_cookie[] = "/*RETSUB_PC*/";
<     static const char forelem_cookie[]   = "/*FORELEM*/";
<     static const char with_cookie[]      = "/*WITH*/";
<     static const char dot_format[]       = "%s.%s";
<     static const char index_format[]     = "%s[%s]";
<     static const char predot_format[]    = "%s%s.%s";
<     static const char postdot_format[]   = "%s.%s%s";
<     static const char preindex_format[]  = "%s%s[%s]";
<     static const char postindex_format[] = "%s[%s]%s";
<     static const char ss_format[]        = "%s%s";
< 
<     /* Argument and variables decompilation uses the following to share code. */
<     JS_STATIC_ASSERT(ARGNO_LEN == VARNO_LEN);
< 
< /*
<  * Local macros
<  */
< #define DECOMPILE_CODE(pc,nb) if (!Decompile(ss, pc, nb, JSOP_NOP)) return NULL
< #define NEXT_OP(pc)           (((pc) + (len) == endpc) ? nextop : pc[len])
< #define POP_STR()             PopStr(ss, op)
< #define LOCAL_ASSERT(expr)    LOCAL_ASSERT_RV(expr, NULL)
< 
< /*
<  * Callers know that ATOM_IS_STRING(atom), and we leave it to the optimizer to
<  * common ATOM_TO_STRING(atom) here and near the call sites.
<  */
< #define ATOM_IS_IDENTIFIER(atom) js_IsIdentifier(ATOM_TO_STRING(atom))
< #define ATOM_IS_KEYWORD(atom)                                                 \
<     (js_CheckKeyword(JSSTRING_CHARS(ATOM_TO_STRING(atom)),                    \
<                      JSSTRING_LENGTH(ATOM_TO_STRING(atom))) != TOK_EOF)
< 
< /*
<  * Given an atom already fetched from jp->script's atom map, quote/escape its
<  * string appropriately into rval, and select fmt from the quoted and unquoted
<  * alternatives.
<  */
< #define GET_QUOTE_AND_FMT(qfmt, ufmt, rval)                                   \
<     JS_BEGIN_MACRO                                                            \
<         jschar quote_;                                                        \
<         if (!ATOM_IS_IDENTIFIER(atom)) {                                      \
<             quote_ = '\'';                                                    \
<             fmt = qfmt;                                                       \
<         } else {                                                              \
<             quote_ = 0;                                                       \
<             fmt = ufmt;                                                       \
<         }                                                                     \
<         rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), quote_);      \
<         if (!rval)                                                            \
<             return NULL;                                                      \
<     JS_END_MACRO
< 
< #define LOAD_ATOM(PCOFF)                                                      \
<     GET_ATOM_FROM_BYTECODE(jp->script, pc, PCOFF, atom)
< 
< #define LOAD_OBJECT(PCOFF)                                                    \
<     GET_OBJECT_FROM_BYTECODE(jp->script, pc, PCOFF, obj)
< 
< #define LOAD_FUNCTION(PCOFF)                                                  \
<     GET_FUNCTION_FROM_BYTECODE(jp->script, pc, PCOFF, obj)
< 
< #define LOAD_REGEXP(PCOFF)                                                    \
<     GET_REGEXP_FROM_BYTECODE(jp->script, pc, PCOFF, obj)
< 
< #define GET_SOURCE_NOTE_ATOM(sn, atom)                                        \
<     JS_BEGIN_MACRO                                                            \
<         jsatomid atomIndex_ = (jsatomid) js_GetSrcNoteOffset((sn), 0);        \
<                                                                               \
<         LOCAL_ASSERT(atomIndex_ < jp->script->atomMap.length);                \
<         (atom) = jp->script->atomMap.vector[atomIndex_];                      \
<     JS_END_MACRO
< 
< /*
<  * Get atom from jp->script's atom map, quote/escape its string appropriately
<  * into rval, and select fmt from the quoted and unquoted alternatives.
<  */
< #define GET_ATOM_QUOTE_AND_FMT(qfmt, ufmt, rval)                              \
<     JS_BEGIN_MACRO                                                            \
<         LOAD_ATOM(0);                                                         \
<         GET_QUOTE_AND_FMT(qfmt, ufmt, rval);                                  \
<     JS_END_MACRO
< 
<     cx = ss->sprinter.context;
<     JS_CHECK_RECURSION(cx, return NULL);
< 
<     jp = ss->printer;
<     startpc = pc;
<     endpc = (nb < 0) ? jp->script->code + jp->script->length : pc + nb;
<     forelem_tail = forelem_done = NULL;
<     tail = -1;
<     todo = -2;                  /* NB: different from Sprint() error return. */
<     saveop = JSOP_NOP;
<     sn = NULL;
<     rval = NULL;
< #if JS_HAS_XML_SUPPORT
<     foreach = inXML = quoteAttr = JS_FALSE;
< #endif
< 
<     while (nb < 0 || pc < endpc) {
<         /*
<          * Move saveop to lastop so prefixed bytecodes can take special action
<          * while sharing maximal code.  Set op and saveop to the new bytecode,
<          * use op in POP_STR to trigger automatic parenthesization, but push
<          * saveop at the bottom of the loop if this op pushes.  Thus op may be
<          * set to nop or otherwise mutated to suppress auto-parens.
<          */
<         lastop = saveop;
<         op = (JSOp) *pc;
<         cs = &js_CodeSpec[op];
<         if (cs->format & JOF_INDEXBASE) {
<             /*
<              * The decompiler uses js_GetIndexFromBytecode to get atoms and
<              * objects and ignores these suffix/prefix bytecodes, thus
<              * simplifying code that must process JSOP_GETTER/JSOP_SETTER
<              * prefixes.
<              */
<             pc += cs->length;
<             if (pc >= endpc)
<                 break;
<             op = (JSOp) *pc;
<             cs = &js_CodeSpec[op];
<         }
<         saveop = op;
<         len = oplen = cs->length;
< 
<         if (nb < 0 && -(nb + 1) == (intN)ss->top - cs->nuses + cs->ndefs)
<             return pc;
< 
<         /*
<          * Save source literal associated with JS now before the following
<          * rewrite changes op. See bug 380197.
<          */
<         token = CodeToken[op];
< 
<         if (pc + oplen == jp->dvgfence) {
<             JSStackFrame *fp;
<             uint32 format, mode, type;
< 
<             /*
<              * Rewrite non-get ops to their "get" format if the error is in
<              * the bytecode at pc, so we don't decompile more than the error
<              * expression.
<              */
<             for (fp = cx->fp; fp && !fp->script; fp = fp->down)
<                 continue;
<             format = cs->format;
<             if (((fp && pc == fp->pc) ||
<                  (pc == startpc && cs->nuses != 0)) &&
<                 format & (JOF_SET|JOF_DEL|JOF_INCDEC|JOF_IMPORT|JOF_FOR|
<                           JOF_VARPROP)) {
<                 mode = JOF_MODE(format);
<                 if (mode == JOF_NAME) {
<                     /*
<                      * JOF_NAME does not imply JOF_ATOM, so we must check for
<                      * the QARG and QVAR format types, and translate those to
<                      * JSOP_GETARG or JSOP_GETVAR appropriately, instead of to
<                      * JSOP_NAME.
<                      */
<                     type = JOF_TYPE(format);
<                     op = (type == JOF_QARG)
<                          ? JSOP_GETARG
<                          : (type == JOF_QVAR)
<                          ? JSOP_GETVAR
<                          : (type == JOF_LOCAL)
<                          ? JSOP_GETLOCAL
<                          : JSOP_NAME;
< 
<                     i = cs->nuses - js_CodeSpec[op].nuses;
<                     while (--i >= 0)
<                         PopOff(ss, JSOP_NOP);
<                 } else {
<                     /*
<                      * We must replace the faulting pc's bytecode with a
<                      * corresponding JSOP_GET* code.  For JSOP_SET{PROP,ELEM},
<                      * we must use the "2nd" form of JSOP_GET{PROP,ELEM}, to
<                      * throw away the assignment op's right-hand operand and
<                      * decompile it as if it were a GET of its left-hand
<                      * operand.
<                      */
<                     if (mode == JOF_PROP) {
<                         op = (JSOp) ((format & JOF_SET)
<                                      ? JSOP_GETPROP2
<                                      : JSOP_GETPROP);
<                     } else if (mode == JOF_ELEM) {
<                         op = (JSOp) ((format & JOF_SET)
<                                      ? JSOP_GETELEM2
<                                      : JSOP_GETELEM);
<                     } else {
<                         /*
<                          * Zero mode means precisely that op is uncategorized
<                          * for our purposes, so we must write per-op special
<                          * case code here.
<                          */
<                         switch (op) {
<                           case JSOP_ENUMELEM:
<                           case JSOP_ENUMCONSTELEM:
<                             op = JSOP_GETELEM;
<                             break;
< #if JS_HAS_LVALUE_RETURN
<                           case JSOP_SETCALL:
<                             op = JSOP_CALL;
<                             break;
< #endif
<                           case JSOP_GETARGPROP:
<                             op = JSOP_GETARG;
<                             break;
<                           case JSOP_GETVARPROP:
<                             op = JSOP_GETVAR;
<                             break;
<                           case JSOP_GETLOCALPROP:
<                             op = JSOP_GETLOCAL;
<                             break;
<                           default:
<                             LOCAL_ASSERT(0);
<                         }
<                     }
<                 }
<             }
< 
<             saveop = op;
<             if (op >= JSOP_LIMIT) {
<                 switch (op) {
<                   case JSOP_GETPROP2:
<                     saveop = JSOP_GETPROP;
<                     break;
<                   case JSOP_GETELEM2:
<                     saveop = JSOP_GETELEM;
<                     break;
<                   default:;
<                 }
<             }
<             LOCAL_ASSERT(js_CodeSpec[saveop].length == oplen ||
<                          JOF_TYPE(format) == JOF_SLOTATOM);
< 
<             jp->dvgfence = NULL;
<         }
< 
<         if (token) {
<             switch (cs->nuses) {
<               case 2:
<                 sn = js_GetSrcNote(jp->script, pc);
<                 if (sn && SN_TYPE(sn) == SRC_ASSIGNOP) {
<                     /*
<                      * Avoid over-parenthesizing y in x op= y based on its
<                      * expansion: x = x op y (replace y by z = w to see the
<                      * problem).
<                      */
<                     op = (JSOp) pc[oplen];
<                     LOCAL_ASSERT(op != saveop);
<                 }
<                 rval = POP_STR();
<                 lval = POP_STR();
<                 if (op != saveop) {
<                     /* Print only the right operand of the assignment-op. */
<                     todo = SprintCString(&ss->sprinter, rval);
<                     op = saveop;
<                 } else if (!inXML) {
<                     todo = Sprint(&ss->sprinter, "%s %s %s",
<                                   lval, token, rval);
<                 } else {
<                     /* In XML, just concatenate the two operands. */
<                     LOCAL_ASSERT(op == JSOP_ADD);
<                     todo = Sprint(&ss->sprinter, ss_format, lval, rval);
<                 }
<                 break;
< 
<               case 1:
<                 rval = POP_STR();
<                 todo = Sprint(&ss->sprinter, ss_format, token, rval);
<                 break;
< 
<               case 0:
<                 todo = SprintCString(&ss->sprinter, token);
<                 break;
< 
<               default:
<                 todo = -2;
<                 break;
<             }
<         } else {
<             switch (op) {
<               case JSOP_NOP:
<                 /*
<                  * Check for a do-while loop, a for-loop with an empty
<                  * initializer part, a labeled statement, a function
<                  * definition, or try/finally.
<                  */
<                 sn = js_GetSrcNote(jp->script, pc);
<                 todo = -2;
<                 switch (sn ? SN_TYPE(sn) : SRC_NULL) {
<                   case SRC_WHILE:
<                     ++pc;
<                     tail = js_GetSrcNoteOffset(sn, 0) - 1;
<                     LOCAL_ASSERT(pc[tail] == JSOP_IFNE ||
<                                  pc[tail] == JSOP_IFNEX);
<                     js_printf(jp, "\tdo {\n");
<                     jp->indent += 4;
<                     DECOMPILE_CODE(pc, tail);
<                     jp->indent -= 4;
<                     js_printf(jp, "\t} while (%s);\n", POP_STR());
<                     pc += tail;
<                     len = js_CodeSpec[*pc].length;
<                     todo = -2;
<                     break;
< 
<                   case SRC_FOR:
<                     rval = "";
< 
<                   do_forloop:
<                     /* Skip the JSOP_NOP or JSOP_POP bytecode. */
<                     pc++;
< 
<                     /* Get the cond, next, and loop-closing tail offsets. */
<                     cond = js_GetSrcNoteOffset(sn, 0);
<                     next = js_GetSrcNoteOffset(sn, 1);
<                     tail = js_GetSrcNoteOffset(sn, 2);
<                     LOCAL_ASSERT(tail + GetJumpOffset(pc+tail, pc+tail) == 0);
< 
<                     /* Print the keyword and the possibly empty init-part. */
<                     js_printf(jp, "\tfor (%s;", rval);
< 
<                     if (pc[cond] == JSOP_IFEQ || pc[cond] == JSOP_IFEQX) {
<                         /* Decompile the loop condition. */
<                         DECOMPILE_CODE(pc, cond);
<                         js_printf(jp, " %s", POP_STR());
<                     }
< 
<                     /* Need a semicolon whether or not there was a cond. */
<                     js_puts(jp, ";");
< 
<                     if (pc[next] != JSOP_GOTO && pc[next] != JSOP_GOTOX) {
<                         /* Decompile the loop updater. */
<                         DECOMPILE_CODE(pc + next, tail - next - 1);
<                         js_printf(jp, " %s", POP_STR());
<                     }
< 
<                     /* Do the loop body. */
<                     js_printf(jp, ") {\n");
<                     jp->indent += 4;
<                     oplen = (cond) ? js_CodeSpec[pc[cond]].length : 0;
<                     DECOMPILE_CODE(pc + cond + oplen, next - cond - oplen);
<                     jp->indent -= 4;
<                     js_printf(jp, "\t}\n");
< 
<                     /* Set len so pc skips over the entire loop. */
<                     len = tail + js_CodeSpec[pc[tail]].length;
<                     break;
< 
<                   case SRC_LABEL:
<                     GET_SOURCE_NOTE_ATOM(sn, atom);
<                     jp->indent -= 4;
<                     rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
<                     if (!rval)
<                         return NULL;
<                     RETRACT(&ss->sprinter, rval);
<                     js_printf(jp, "\t%s:\n", rval);
<                     jp->indent += 4;
<                     break;
< 
<                   case SRC_LABELBRACE:
<                     GET_SOURCE_NOTE_ATOM(sn, atom);
<                     rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
<                     if (!rval)
<                         return NULL;
<                     RETRACT(&ss->sprinter, rval);
<                     js_printf(jp, "\t%s: {\n", rval);
<                     jp->indent += 4;
<                     break;
< 
<                   case SRC_ENDBRACE:
<                     jp->indent -= 4;
<                     js_printf(jp, "\t}\n");
<                     break;
< 
<                   case SRC_FUNCDEF:
<                     JS_GET_SCRIPT_OBJECT(jp->script, js_GetSrcNoteOffset(sn, 0),
<                                          obj);
<                   do_function:
<                     js_puts(jp, "\n");
<                     fun = GET_FUNCTION_PRIVATE(cx, obj);
<                     jp2 = JS_NEW_PRINTER(cx, "nested_function", fun,
<                                          jp->indent, jp->pretty);
<                     if (!jp2)
<                         return NULL;
<                     ok = js_DecompileFunction(jp2);
<                     if (ok && jp2->sprinter.base)
<                         js_puts(jp, jp2->sprinter.base);
<                     js_DestroyPrinter(jp2);
<                     if (!ok)
<                         return NULL;
<                     js_puts(jp, "\n\n");
<                     break;
< 
<                   case SRC_BRACE:
<                     js_printf(jp, "\t{\n");
<                     jp->indent += 4;
<                     len = js_GetSrcNoteOffset(sn, 0);
<                     DECOMPILE_CODE(pc + oplen, len - oplen);
<                     jp->indent -= 4;
<                     js_printf(jp, "\t}\n");
<                     break;
< 
<                   default:;
<                 }
<                 break;
< 
<               case JSOP_GROUP:
<                 cs = &js_CodeSpec[lastop];
<                 if ((cs->prec != 0 &&
<                      cs->prec <= js_CodeSpec[NEXT_OP(pc)].prec) ||
<                     pc[JSOP_GROUP_LENGTH] == JSOP_NULL ||
<                     pc[JSOP_GROUP_LENGTH] == JSOP_GLOBALTHIS ||
<                     pc[JSOP_GROUP_LENGTH] == JSOP_DUP ||
<                     pc[JSOP_GROUP_LENGTH] == JSOP_IFEQ ||
<                     pc[JSOP_GROUP_LENGTH] == JSOP_IFNE) {
<                     /*
<                      * Force parens if this JSOP_GROUP forced re-association
<                      * against precedence, or if this is a call or constructor
<                      * expression, or if it is destructured (JSOP_DUP), or if
<                      * it is an if or loop condition test.
<                      *
<                      * This is necessary to handle the operator new grammar,
<                      * by which new x(y).z means (new x(y))).z.  For example
<                      * new (x(y).z) must decompile with the constructor
<                      * parenthesized, but normal precedence has JSOP_GETPROP
<                      * (for the final .z) higher than JSOP_NEW.  In general,
<                      * if the call or constructor expression is parenthesized,
<                      * we preserve parens.
<                      */
<                     op = JSOP_NAME;
<                     rval = POP_STR();
<                     todo = SprintCString(&ss->sprinter, rval);
<                 } else {
<                     /*
<                      * Don't explicitly parenthesize -- just fix the top
<                      * opcode so that the auto-parens magic in PopOff can do
<                      * its thing.
<                      */
<                     LOCAL_ASSERT(ss->top != 0);
<                     ss->opcodes[ss->top-1] = saveop = lastop;
<                     todo = -2;
<                 }
<                 break;
< 
<               case JSOP_PUSH:
< #if JS_HAS_DESTRUCTURING
<                 sn = js_GetSrcNote(jp->script, pc);
<                 if (sn && SN_TYPE(sn) == SRC_GROUPASSIGN) {
<                     pc = DecompileGroupAssignment(ss, pc, endpc, sn, &todo);
<                     if (!pc)
<                         return NULL;
<                     LOCAL_ASSERT(*pc == JSOP_POPN);
<                     len = oplen = JSOP_POPN_LENGTH;
<                     goto end_groupassignment;
<                 }
< #endif
<                 /* FALL THROUGH */
< 
<               case JSOP_BINDNAME:
<                 todo = Sprint(&ss->sprinter, "");
<                 break;
< 
<               case JSOP_TRY:
<                 js_printf(jp, "\ttry {\n");
<                 jp->indent += 4;
<                 todo = -2;
<                 break;
< 
<               case JSOP_FINALLY:
<                 jp->indent -= 4;
<                 js_printf(jp, "\t} finally {\n");
<                 jp->indent += 4;
< 
<                 /*
<                  * We push push the pair of exception/restsub cookies to
<                  * simulate the effects [gosub] or control transfer during
<                  * exception capturing on the stack.
<                  */
<                 todo = Sprint(&ss->sprinter, exception_cookie);
<                 if (todo < 0 || !PushOff(ss, todo, op))
<                     return NULL;
<                 todo = Sprint(&ss->sprinter, retsub_pc_cookie);
<                 break;
---
>                 /*
>                  * We must push an empty string placeholder for gosub's return
>                  * address, popped by JSOP_RETSUB and counted by script->depth
>                  * but not by ss->top (see JSOP_SETSP, below).
>                  */
>                 todo = Sprint(&ss->sprinter, finally_cookie);
>                 break;
2095,2097c1611
<                 LOCAL_ASSERT(strcmp(rval, retsub_pc_cookie) == 0);
<                 lval = POP_STR();
<                 LOCAL_ASSERT(strcmp(lval, exception_cookie) == 0);
---
>                 LOCAL_ASSERT(strcmp(rval, finally_cookie) == 0);
2099a1614
>             }
2109,2110c1624,1625
<               case JSOP_GOSUB:
<               case JSOP_GOSUBX:
---
> 	      case JSOP_GOSUB:
> 	      case JSOP_GOSUBX:
2116,2121c1631,1632
<                 todo = -2;
<                 break;
< 
<               case JSOP_POPN:
<               {
<                 uintN newtop, oldtop, i;
---
> 		todo = -2;
> 		break;
2122a1634
> 	      case JSOP_SETSP:
2129,2246c1641,1642
<                 oldtop = ss->top;
<                 newtop = oldtop - GET_UINT16(pc);
<                 LOCAL_ASSERT(newtop <= oldtop);
<                 todo = -2;
< 
<                 sn = js_GetSrcNote(jp->script, pc);
<                 if (sn && SN_TYPE(sn) == SRC_HIDDEN)
<                     break;
< #if JS_HAS_DESTRUCTURING
<                 if (sn && SN_TYPE(sn) == SRC_GROUPASSIGN) {
<                     todo = Sprint(&ss->sprinter, "%s[] = [",
<                                   VarPrefix(sn));
<                     if (todo < 0)
<                         return NULL;
<                     for (i = newtop; i < oldtop; i++) {
<                         rval = OFF2STR(&ss->sprinter, ss->offsets[i]);
<                         if (Sprint(&ss->sprinter, ss_format,
<                                    (i == newtop) ? "" : ", ",
<                                    (i == oldtop - 1 && *rval == '\0')
<                                    ? ", " : rval) < 0) {
<                             return NULL;
<                         }
<                     }
<                     if (SprintPut(&ss->sprinter, "]", 1) < 0)
<                         return NULL;
< 
<                     /*
<                      * Kill newtop before the end_groupassignment: label by
<                      * retracting/popping early.  Control will either jump to
<                      * do_forloop: or do_letheadbody: or else break from our
<                      * case JSOP_POPN: after the switch (*pc2) below.
<                      */
<                     if (newtop < oldtop) {
<                         ss->sprinter.offset = GetOff(ss, newtop);
<                         ss->top = newtop;
<                     }
< 
<                   end_groupassignment:
<                     /*
<                      * Thread directly to the next opcode if we can, to handle
<                      * the special cases of a group assignment in the first or
<                      * last part of a for(;;) loop head, or in a let block or
<                      * expression head.
<                      *
<                      * NB: todo at this point indexes space in ss->sprinter
<                      * that is liable to be overwritten.  The code below knows
<                      * exactly how long rval lives, or else copies it down via
<                      * SprintCString.
<                      */
<                     rval = OFF2STR(&ss->sprinter, todo);
<                     todo = -2;
<                     pc2 = pc + oplen;
<                     switch (*pc2) {
<                       case JSOP_NOP:
<                         /* First part of for(;;) or let block/expr head. */
<                         sn = js_GetSrcNote(jp->script, pc2);
<                         if (sn) {
<                             if (SN_TYPE(sn) == SRC_FOR) {
<                                 pc = pc2;
<                                 goto do_forloop;
<                             }
<                             if (SN_TYPE(sn) == SRC_DECL) {
<                                 if (ss->top == jp->script->depth) {
<                                     /*
<                                      * This must be an empty destructuring
<                                      * in the head of a let whose body block
<                                      * is also empty.
<                                      */
<                                     pc = pc2 + 1;
<                                     len = js_GetSrcNoteOffset(sn, 0);
<                                     LOCAL_ASSERT(pc[len] == JSOP_LEAVEBLOCK);
<                                     js_printf(jp, "\tlet (%s) {\n", rval);
<                                     js_printf(jp, "\t}\n");
<                                     goto end_popn;
<                                 }
<                                 todo = SprintCString(&ss->sprinter, rval);
<                                 if (todo < 0 || !PushOff(ss, todo, JSOP_NOP))
<                                     return NULL;
<                                 op = JSOP_POP;
<                                 pc = pc2 + 1;
<                                 goto do_letheadbody;
<                             }
<                         }
<                         break;
< 
<                       case JSOP_GOTO:
<                       case JSOP_GOTOX:
<                         /* Third part of for(;;) loop head. */
<                         cond = GetJumpOffset(pc2, pc2);
<                         sn = js_GetSrcNote(jp->script, pc2 + cond - 1);
<                         if (sn && SN_TYPE(sn) == SRC_FOR) {
<                             todo = SprintCString(&ss->sprinter, rval);
<                             saveop = JSOP_NOP;
<                         }
<                         break;
<                     }
< 
<                     /*
<                      * If control flow reaches this point with todo still -2,
<                      * just print rval as an expression statement.
<                      */
<                     if (todo == -2)
<                         js_printf(jp, "\t%s;\n", rval);
<                   end_popn:
<                     break;
<                 }
< #endif
<                 if (newtop < oldtop) {
<                     ss->sprinter.offset = GetOff(ss, newtop);
<                     ss->top = newtop;
<                 }
<                 break;
<               }
< 
<               case JSOP_EXCEPTION:
<                 /* The catch decompiler handles this op itself. */
<                 LOCAL_ASSERT(JS_FALSE);
<                 break;
---
>                 ss->top = (uintN) GET_ATOM_INDEX(pc);
> 		break;
2248c1644
<               case JSOP_POP:
---
> 	      case JSOP_EXCEPTION:
2250,2253c1646,1647
<                  * By default, do not automatically parenthesize when popping
<                  * a stacked expression decompilation.  We auto-parenthesize
<                  * only when JSOP_POP is annotated with SRC_PCDELTA, meaning
<                  * comma operator.
---
>                  * The only other JSOP_EXCEPTION case occurs as part of a code
>                  * sequence that follows a SRC_CATCH-annotated JSOP_NOP.
2255,2258d1648
<                 op = JSOP_POPV;
<                 /* FALL THROUGH */
< 
<               case JSOP_POPV:
2260,2267c1650,1653
<                 switch (sn ? SN_TYPE(sn) : SRC_NULL) {
<                   case SRC_FOR:
<                     /* Force parens around 'in' expression at 'for' front. */
<                     if (ss->opcodes[ss->top-1] == JSOP_IN)
<                         op = JSOP_LSH;
<                     rval = POP_STR();
<                     todo = -2;
<                     goto do_forloop;
---
>                 LOCAL_ASSERT(sn && SN_TYPE(sn) == SRC_HIDDEN);
>                 todo = -2;
> 		break;
> #endif /* JS_HAS_EXCEPTIONS */
2269,2271c1655,1662
<                   case SRC_PCDELTA:
<                     /* Comma operator: use JSOP_POP for correct precedence. */
<                     op = JSOP_POP;
---
> 	      case JSOP_POP:
> 	      case JSOP_POPV:
> 		sn = js_GetSrcNote(jp->script, pc);
> 		switch (sn ? SN_TYPE(sn) : SRC_NULL) {
> 		  case SRC_FOR:
> 		    rval = POP_STR();
> 		    todo = -2;
> 		    goto do_forloop;
2273,2276c1664,1668
<                     /* Pop and save to avoid blowing stack depth budget. */
<                     lval = JS_strdup(cx, POP_STR());
<                     if (!lval)
<                         return NULL;
---
> 		  case SRC_PCDELTA:
> 		    /* Pop and save to avoid blowing stack depth budget. */
> 		    lval = JS_strdup(cx, POP_STR());
> 		    if (!lval)
> 			return JS_FALSE;
2278c1670
<                     /*
---
> 		    /*
2282,2363c1674,1714
<                     done = pc + len;
<                     pc += js_GetSrcNoteOffset(sn, 0);
<                     len = 0;
< 
<                     if (!Decompile(ss, done, pc - done, JSOP_POP)) {
<                         JS_free(cx, (char *)lval);
<                         return NULL;
<                     }
< 
<                     /* Pop Decompile result and print comma expression. */
<                     rval = POP_STR();
<                     todo = Sprint(&ss->sprinter, "%s, %s", lval, rval);
<                     JS_free(cx, (char *)lval);
<                     break;
< 
<                   case SRC_HIDDEN:
<                     /* Hide this pop, it's from a goto in a with or for/in. */
<                     todo = -2;
<                     break;
< 
<                   case SRC_DECL:
<                     /* This pop is at the end of the let block/expr head. */
<                     pc += JSOP_POP_LENGTH;
< #if JS_HAS_DESTRUCTURING
<                   do_letheadbody:
< #endif
<                     len = js_GetSrcNoteOffset(sn, 0);
<                     if (pc[len] == JSOP_LEAVEBLOCK) {
<                         js_printf(jp, "\tlet (%s) {\n", POP_STR());
<                         jp->indent += 4;
<                         DECOMPILE_CODE(pc, len);
<                         jp->indent -= 4;
<                         js_printf(jp, "\t}\n");
<                         todo = -2;
<                     } else {
<                         LOCAL_ASSERT(pc[len] == JSOP_LEAVEBLOCKEXPR);
< 
<                         lval = JS_strdup(cx, POP_STR());
<                         if (!lval)
<                             return NULL;
< 
<                         /* Set saveop to reflect what we will push. */
<                         saveop = JSOP_LEAVEBLOCKEXPR;
<                         if (!Decompile(ss, pc, len, saveop)) {
<                             JS_free(cx, (char *)lval);
<                             return NULL;
<                         }
<                         rval = POP_STR();
<                         todo = Sprint(&ss->sprinter,
<                                       (*rval == '{')
<                                       ? "let (%s) (%s)"
<                                       : "let (%s) %s",
<                                       lval, rval);
<                         JS_free(cx, (char *)lval);
<                     }
<                     break;
< 
<                   default:
<                     /* Turn off parens around a yield statement. */
<                     if (ss->opcodes[ss->top-1] == JSOP_YIELD)
<                         op = JSOP_NOP;
< 
<                     rval = POP_STR();
< 
<                     /*
<                      * Don't emit decompiler-pushed strings that are not
<                      * handled by other opcodes. They are pushed onto the
<                      * stack to help model the interpreter stack and should
<                      * not appear in the decompiler's output.
<                      */
<                     if (*rval != '\0' && (rval[0] != '/' || rval[1] != '*')) {
<                         js_printf(jp,
<                                   (*rval == '{' ||
<                                    (strncmp(rval, js_function_str, 8) == 0 &&
<                                     rval[8] == ' '))
<                                   ? "\t(%s);\n"
<                                   : "\t%s;\n",
<                                   rval);
<                     } else {
<                         LOCAL_ASSERT(*rval == '\0' ||
<                                      strcmp(rval, exception_cookie) == 0);
<                     }
---
> 		    done = pc + len;
> 		    pc += js_GetSrcNoteOffset(sn, 0);
> 		    len = 0;
> 
> 		    if (!Decompile(ss, done, pc - done)) {
> 			JS_free(cx, (char *)lval);
> 			return JS_FALSE;
> 		    }
> 
> 		    /* Pop Decompile result and print comma expression. */
> 		    rval = POP_STR();
> 		    todo = Sprint(&ss->sprinter, "%s, %s", lval, rval);
> 		    JS_free(cx, (char *)lval);
> 		    break;
> 
> 		  case SRC_HIDDEN:
> 		    /* Hide this pop, it's from a goto in a with or for/in. */
> 		    todo = -2;
> 		    break;
> 
> 		  default:
> 		    rval = POP_STR();
> 		    if (*rval != '\0')
> 			js_printf(jp, "\t%s;\n", rval);
> 		    todo = -2;
> 		    break;
> 		}
> 		break;
> 
> 	      case JSOP_POP2:
> 		(void) PopOff(ss, op);
> 		(void) PopOff(ss, op);
> 		todo = -2;
> 		break;
> 
>             {
>               static const char with_cookie[] = "with-cookie";
> 
> 	      case JSOP_ENTERWITH:
> 		sn = js_GetSrcNote(jp->script, pc);
> 		if (sn && SN_TYPE(sn) == SRC_HIDDEN) {
2367,2379d1717
<                 sn = NULL;
<                 break;
< 
<               case JSOP_ENDITER:
<                 sn = js_GetSrcNote(jp->script, pc);
<                 todo = -2;
<                 if (sn && SN_TYPE(sn) == SRC_HIDDEN)
<                     break;
<                 (void) PopOff(ss, op);
<                 break;
< 
<               case JSOP_ENTERWITH:
<                 LOCAL_ASSERT(!js_GetSrcNote(jp->script, pc));
2384c1722
<                 break;
---
> 		break;
2386,2387c1724,1725
<               case JSOP_LEAVEWITH:
<                 sn = js_GetSrcNote(jp->script, pc);
---
> 	      case JSOP_LEAVEWITH:
> 		sn = js_GetSrcNote(jp->script, pc);
2389c1727
<                 if (sn && SN_TYPE(sn) == SRC_HIDDEN)
---
> 		if (sn && SN_TYPE(sn) == SRC_HIDDEN)
2395,2410c1733,1734
<                 break;
< 
<               case JSOP_ENTERBLOCK:
<               {
<                 JSAtom **atomv, *smallv[5];
<                 JSScopeProperty *sprop;
< 
<                 LOAD_OBJECT(0);
<                 argc = OBJ_BLOCK_COUNT(cx, obj);
<                 if ((size_t)argc <= JS_ARRAY_LENGTH(smallv)) {
<                     atomv = smallv;
<                 } else {
<                     atomv = (JSAtom **) JS_malloc(cx, argc * sizeof(JSAtom *));
<                     if (!atomv)
<                         return NULL;
<                 }
---
> 		break;
>             }
2412,2804c1736,1763
<                 /* From here on, control must flow through enterblock_out. */
<                 for (sprop = OBJ_SCOPE(obj)->lastProp; sprop;
<                      sprop = sprop->parent) {
<                     if (!(sprop->flags & SPROP_HAS_SHORTID))
<                         continue;
<                     LOCAL_ASSERT(sprop->shortid < argc);
<                     atomv[sprop->shortid] = JSID_TO_ATOM(sprop->id);
<                 }
<                 ok = JS_TRUE;
<                 for (i = 0; i < argc; i++) {
<                     atom = atomv[i];
<                     rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
<                     if (!rval ||
<                         !PushOff(ss, STR2OFF(&ss->sprinter, rval), op)) {
<                         ok = JS_FALSE;
<                         goto enterblock_out;
<                     }
<                 }
< 
<                 sn = js_GetSrcNote(jp->script, pc);
<                 switch (sn ? SN_TYPE(sn) : SRC_NULL) {
< #if JS_HAS_BLOCK_SCOPE
<                   case SRC_BRACE:
<                     js_printf(jp, "\t{\n");
<                     jp->indent += 4;
<                     len = js_GetSrcNoteOffset(sn, 0);
<                     ok = Decompile(ss, pc + oplen, len - oplen, JSOP_NOP)
<                          != NULL;
<                     if (!ok)
<                         goto enterblock_out;
<                     jp->indent -= 4;
<                     js_printf(jp, "\t}\n");
<                     break;
< #endif
< 
<                   case SRC_CATCH:
<                     jp->indent -= 4;
<                     js_printf(jp, "\t} catch (");
< 
<                     pc2 = pc;
<                     pc += oplen;
<                     LOCAL_ASSERT(*pc == JSOP_EXCEPTION);
<                     pc += JSOP_EXCEPTION_LENGTH;
<                     todo = Sprint(&ss->sprinter, exception_cookie);
<                     if (todo < 0 || !PushOff(ss, todo, JSOP_EXCEPTION)) {
<                         ok = JS_FALSE;
<                         goto enterblock_out;
<                     }
< 
<                     if (*pc == JSOP_DUP) {
<                         sn2 = js_GetSrcNote(jp->script, pc);
<                         if (!sn2 || SN_TYPE(sn2) != SRC_DESTRUCT) {
<                             /*
<                              * This is a dup to save the exception for later.
<                              * It is emitted only when the catch head contains
<                              * an exception guard.
<                              */
<                             LOCAL_ASSERT(js_GetSrcNoteOffset(sn, 0) != 0);
<                             pc += JSOP_DUP_LENGTH;
<                             todo = Sprint(&ss->sprinter, exception_cookie);
<                             if (todo < 0 ||
<                                 !PushOff(ss, todo, JSOP_EXCEPTION)) {
<                                 ok = JS_FALSE;
<                                 goto enterblock_out;
<                             }
<                         }
<                     }
< 
< #if JS_HAS_DESTRUCTURING
<                     if (*pc == JSOP_DUP) {
<                         pc = DecompileDestructuring(ss, pc, endpc);
<                         if (!pc) {
<                             ok = JS_FALSE;
<                             goto enterblock_out;
<                         }
<                         LOCAL_ASSERT(*pc == JSOP_POP);
<                         pc += JSOP_POP_LENGTH;
<                         lval = PopStr(ss, JSOP_NOP);
<                         js_puts(jp, lval);
<                     } else {
< #endif
<                         LOCAL_ASSERT(*pc == JSOP_SETLOCALPOP);
<                         i = GET_UINT16(pc);
<                         pc += JSOP_SETLOCALPOP_LENGTH;
<                         atom = atomv[i - OBJ_BLOCK_DEPTH(cx, obj)];
<                         str = ATOM_TO_STRING(atom);
<                         if (!QuoteString(&jp->sprinter, str, 0)) {
<                             ok = JS_FALSE;
<                             goto enterblock_out;
<                         }
< #if JS_HAS_DESTRUCTURING
<                     }
< #endif
< 
<                     /*
<                      * Pop the exception_cookie (or its dup in the case of a
<                      * guarded catch head) off the stack now.
<                      */
<                     rval = PopStr(ss, JSOP_NOP);
<                     LOCAL_ASSERT(strcmp(rval, exception_cookie) == 0);
< 
<                     len = js_GetSrcNoteOffset(sn, 0);
<                     if (len) {
<                         len -= PTRDIFF(pc, pc2, jsbytecode);
<                         LOCAL_ASSERT(len > 0);
<                         js_printf(jp, " if ");
<                         ok = Decompile(ss, pc, len, JSOP_NOP) != NULL;
<                         if (!ok)
<                             goto enterblock_out;
<                         js_printf(jp, "%s", POP_STR());
<                         pc += len;
<                         LOCAL_ASSERT(*pc == JSOP_IFEQ || *pc == JSOP_IFEQX);
<                         pc += js_CodeSpec[*pc].length;
<                     }
< 
<                     js_printf(jp, ") {\n");
<                     jp->indent += 4;
<                     len = 0;
<                     break;
<                   default:
<                     break;
<                 }
< 
<                 todo = -2;
< 
<               enterblock_out:
<                 if (atomv != smallv)
<                     JS_free(cx, atomv);
<                 if (!ok)
<                     return NULL;
<               }
<               break;
< 
<               case JSOP_LEAVEBLOCK:
<               case JSOP_LEAVEBLOCKEXPR:
<               {
<                 uintN top, depth;
< 
<                 sn = js_GetSrcNote(jp->script, pc);
<                 todo = -2;
<                 if (op == JSOP_LEAVEBLOCKEXPR) {
<                     LOCAL_ASSERT(SN_TYPE(sn) == SRC_PCBASE);
<                     rval = POP_STR();
<                 } else if (sn) {
<                     LOCAL_ASSERT(op == JSOP_LEAVEBLOCK);
<                     if (SN_TYPE(sn) == SRC_HIDDEN)
<                         break;
< 
<                     /*
<                      * This JSOP_LEAVEBLOCK must be for a catch block. If sn's
<                      * offset does not equal the model stack depth, there must
<                      * be a copy of the exception value on the stack due to a
<                      * catch guard (see above, the JSOP_ENTERBLOCK + SRC_CATCH
<                      * case code).
<                      */
<                     LOCAL_ASSERT(SN_TYPE(sn) == SRC_CATCH);
<                     if ((uintN)js_GetSrcNoteOffset(sn, 0) != ss->top) {
<                         LOCAL_ASSERT((uintN)js_GetSrcNoteOffset(sn, 0)
<                                      == ss->top - 1);
<                         rval = POP_STR();
<                         LOCAL_ASSERT(strcmp(rval, exception_cookie) == 0);
<                     }
<                 }
<                 top = ss->top;
<                 depth = GET_UINT16(pc);
<                 LOCAL_ASSERT(top >= depth);
<                 top -= depth;
<                 ss->top = top;
<                 ss->sprinter.offset = GetOff(ss, top);
<                 if (op == JSOP_LEAVEBLOCKEXPR)
<                     todo = SprintCString(&ss->sprinter, rval);
<                 break;
<               }
< 
<               case JSOP_CALLLOCAL:
<               case JSOP_GETLOCAL:
<                 i = GET_UINT16(pc);
<                 LOCAL_ASSERT((uintN)i < ss->top);
<                 sn = js_GetSrcNote(jp->script, pc);
< 
< #if JS_HAS_DESTRUCTURING
<                 if (sn && SN_TYPE(sn) == SRC_GROUPASSIGN) {
<                     pc = DecompileGroupAssignment(ss, pc, endpc, sn, &todo);
<                     if (!pc)
<                         return NULL;
<                     LOCAL_ASSERT(*pc == JSOP_POPN);
<                     len = oplen = JSOP_POPN_LENGTH;
<                     goto end_groupassignment;
<                 }
< #endif
< 
<                 rval = GetLocal(ss, i);
<                 todo = Sprint(&ss->sprinter, ss_format, VarPrefix(sn), rval);
<                 break;
< 
<               case JSOP_SETLOCAL:
<               case JSOP_SETLOCALPOP:
<                 i = GET_UINT16(pc);
<                 lval = GetStr(ss, i);
<                 rval = POP_STR();
<                 goto do_setlval;
< 
<               case JSOP_INCLOCAL:
<               case JSOP_DECLOCAL:
<                 i = GET_UINT16(pc);
<                 lval = GetLocal(ss, i);
<                 goto do_inclval;
< 
<               case JSOP_LOCALINC:
<               case JSOP_LOCALDEC:
<                 i = GET_UINT16(pc);
<                 lval = GetLocal(ss, i);
<                 goto do_lvalinc;
< 
<               case JSOP_FORLOCAL:
<                 i = GET_UINT16(pc);
<                 lval = GetStr(ss, i);
<                 atom = NULL;
<                 goto do_forlvalinloop;
< 
<               case JSOP_RETRVAL:
<                 todo = -2;
<                 break;
< 
<               case JSOP_RETURN:
<                 LOCAL_ASSERT(jp->fun);
<                 fun = jp->fun;
<                 if (fun->flags & JSFUN_EXPR_CLOSURE) {
<                     rval = POP_STR();
<                     js_printf(jp, (*rval == '{') ? "(%s)%s" : ss_format,
<                               rval,
<                               ((fun->flags & JSFUN_LAMBDA) || !fun->atom)
<                               ? ""
<                               : ";");
<                     todo = -2;
<                     break;
<                 }
<                 /* FALL THROUGH */
< 
<               case JSOP_SETRVAL:
<                 rval = POP_STR();
<                 if (*rval != '\0')
<                     js_printf(jp, "\t%s %s;\n", js_return_str, rval);
<                 else
<                     js_printf(jp, "\t%s;\n", js_return_str);
<                 todo = -2;
<                 break;
< 
< #if JS_HAS_GENERATORS
<               case JSOP_YIELD:
< #if JS_HAS_GENERATOR_EXPRS
<                 if (!ss->inGenExp || !(sn = js_GetSrcNote(jp->script, pc)))
< #endif
<                 {
<                     /* Turn off most parens. */
<                     op = JSOP_SETNAME;
<                     rval = POP_STR();
<                     todo = (*rval != '\0')
<                            ? Sprint(&ss->sprinter,
<                                     (strncmp(rval, js_yield_str, 5) == 0 &&
<                                      (rval[5] == ' ' || rval[5] == '\0'))
<                                     ? "%s (%s)"
<                                     : "%s %s",
<                                     js_yield_str, rval)
<                            : SprintCString(&ss->sprinter, js_yield_str);
<                     break;
<                 }
< #if JS_HAS_GENERATOR_EXPRS
<                 LOCAL_ASSERT(SN_TYPE(sn) == SRC_HIDDEN);
<                 /* FALL THROUGH */
< #endif
< 
<               case JSOP_ARRAYPUSH:
<               {
<                 uintN pos, forpos;
<                 ptrdiff_t start;
< 
<                 /* Turn off most parens. */
<                 op = JSOP_SETNAME;
< 
<                 /* Pop the expression being pushed or yielded. */
<                 rval = POP_STR();
< 
<                 /*
<                  * Skip down over iterables left stacked by JSOP_FOR* until
<                  * we hit a block-local or the new Array initialiser (empty
<                  * destructuring patterns yield zero-count blocks).
<                  */
<                 pos = ss->top;
<                 while ((op = (JSOp) ss->opcodes[--pos]) != JSOP_ENTERBLOCK &&
<                        op != JSOP_NEWINIT) {
<                     if (pos == 0)
<                         break;
<                 }
< 
<                 /*
<                  * Make forpos index the space before the left-most |for| in
<                  * the single string of accumulated |for| heads and optional
<                  * final |if (condition)|.
<                  */
<                 forpos = pos + (op == JSOP_ENTERBLOCK || op == JSOP_NEWINIT);
<                 LOCAL_ASSERT(forpos < ss->top);
< 
<                 /*
<                  * Now skip down over the block's local slots, if any. There
<                  * may be no locals for an empty destructuring pattern.
<                  */
<                 while (ss->opcodes[pos] == JSOP_ENTERBLOCK) {
<                     if (pos == 0)
<                         break;
<                     --pos;
<                 }
< 
< #if JS_HAS_GENERATOR_EXPRS
<                 if (saveop == JSOP_YIELD) {
<                     /*
<                      * Generator expression: decompile just rval followed by
<                      * the string starting at forpos. Leave the result string
<                      * in ss->offsets[0] so it can be recovered by our caller
<                      * (the JSOP_ANONFUNOBJ with SRC_GENEXP case). Bump the
<                      * top of stack to balance yield, which is an expression
<                      * (so has neutral stack balance).
<                      */
<                     LOCAL_ASSERT(pos == 0);
<                     xval = OFF2STR(&ss->sprinter, ss->offsets[forpos]);
<                     ss->sprinter.offset = PAREN_SLOP;
<                     todo = Sprint(&ss->sprinter, ss_format, rval, xval);
<                     if (todo < 0)
<                         return NULL;
<                     ss->offsets[0] = todo;
<                     ++ss->top;
<                     return pc;
<                 }
< #endif /* JS_HAS_GENERATOR_EXPRS */
< 
<                 /*
<                  * Array comprehension: retract the sprinter to the beginning
<                  * of the array initialiser and decompile "[<rval> for ...]".
<                  */
<                 LOCAL_ASSERT(ss->opcodes[pos] == JSOP_NEWINIT);
<                 start = ss->offsets[pos];
<                 LOCAL_ASSERT(ss->sprinter.base[start] == '[' ||
<                              ss->sprinter.base[start] == '#');
<                 LOCAL_ASSERT(forpos < ss->top);
<                 xval = OFF2STR(&ss->sprinter, ss->offsets[forpos]);
<                 lval = OFF2STR(&ss->sprinter, start);
<                 RETRACT(&ss->sprinter, lval);
< 
<                 todo = Sprint(&ss->sprinter, "%s%s%.*s",
<                               lval, rval, rval - xval, xval);
<                 if (todo < 0)
<                     return NULL;
<                 ss->offsets[pos] = todo;
<                 todo = -2;
<                 break;
<               }
< #endif
< 
<               case JSOP_THROWING:
<                 todo = -2;
<                 break;
< 
<               case JSOP_THROW:
<                 sn = js_GetSrcNote(jp->script, pc);
<                 todo = -2;
<                 if (sn && SN_TYPE(sn) == SRC_HIDDEN)
<                     break;
<                 rval = POP_STR();
<                 js_printf(jp, "\t%s %s;\n", js_throw_str, rval);
<                 break;
< 
<               case JSOP_GOTO:
<               case JSOP_GOTOX:
<                 sn = js_GetSrcNote(jp->script, pc);
<                 switch (sn ? SN_TYPE(sn) : SRC_NULL) {
<                   case SRC_WHILE:
<                     cond = GetJumpOffset(pc, pc);
<                     tail = js_GetSrcNoteOffset(sn, 0);
<                     DECOMPILE_CODE(pc + cond, tail - cond);
<                     rval = POP_STR();
<                     js_printf(jp, "\twhile (%s) {\n", rval);
<                     jp->indent += 4;
<                     DECOMPILE_CODE(pc + oplen, cond - oplen);
<                     jp->indent -= 4;
<                     js_printf(jp, "\t}\n");
<                     pc += tail;
<                     LOCAL_ASSERT(*pc == JSOP_IFNE || *pc == JSOP_IFNEX);
<                     len = js_CodeSpec[*pc].length;
<                     todo = -2;
<                     break;
< 
<                   case SRC_CONT2LABEL:
<                     GET_SOURCE_NOTE_ATOM(sn, atom);
---
>               case JSOP_SETRVAL:
> 	      case JSOP_RETURN:
> 		rval = POP_STR();
> 		if (*rval != '\0')
> 		    js_printf(jp, "\t%s %s;\n", cs->name, rval);
> 		else
> 		    js_printf(jp, "\t%s;\n", cs->name);
>                 todo = -2;
> 		break;
> 
> #if JS_HAS_EXCEPTIONS
> 	      case JSOP_THROW:
> 		sn = js_GetSrcNote(jp->script, pc);
> 		todo = -2;
> 		if (sn && SN_TYPE(sn) == SRC_HIDDEN)
> 		    break;
> 		rval = POP_STR();
> 		js_printf(jp, "\t%s %s;\n", cs->name, rval);
> 		break;
> #endif /* JS_HAS_EXCEPTIONS */
> 
> 	      case JSOP_GOTO:
> 	      case JSOP_GOTOX:
> 		sn = js_GetSrcNote(jp->script, pc);
> 		switch (sn ? SN_TYPE(sn) : SRC_NULL) {
> 		  case SRC_CONT2LABEL:
> 		    atom = js_GetAtom(cx, &jp->script->atomMap,
> 				      (jsatomid) js_GetSrcNoteOffset(sn, 0));
2807c1766
<                         return NULL;
---
>                         return JS_FALSE;
2809,2817c1768,1775
<                     js_printf(jp, "\tcontinue %s;\n", rval);
<                     break;
< 
<                   case SRC_CONTINUE:
<                     js_printf(jp, "\tcontinue;\n");
<                     break;
< 
<                   case SRC_BREAK2LABEL:
<                     GET_SOURCE_NOTE_ATOM(sn, atom);
---
> 		    js_printf(jp, "\tcontinue %s;\n", rval);
> 		    break;
> 		  case SRC_CONTINUE:
> 		    js_printf(jp, "\tcontinue;\n");
> 		    break;
> 		  case SRC_BREAK2LABEL:
> 		    atom = js_GetAtom(cx, &jp->script->atomMap,
> 				      (jsatomid) js_GetSrcNoteOffset(sn, 0));
2820c1778
<                         return NULL;
---
>                         return JS_FALSE;
2822,2906c1780,1835
<                     js_printf(jp, "\tbreak %s;\n", rval);
<                     break;
< 
<                   case SRC_HIDDEN:
<                     break;
< 
<                   default:
<                     js_printf(jp, "\tbreak;\n");
<                     break;
<                 }
<                 todo = -2;
<                 break;
< 
<               case JSOP_IFEQ:
<               case JSOP_IFEQX:
<               {
<                 JSBool elseif = JS_FALSE;
< 
<               if_again:
<                 len = GetJumpOffset(pc, pc);
<                 sn = js_GetSrcNote(jp->script, pc);
< 
<                 switch (sn ? SN_TYPE(sn) : SRC_NULL) {
<                   case SRC_IF:
<                   case SRC_IF_ELSE:
<                     op = JSOP_NOP;              /* turn off parens */
<                     rval = POP_STR();
<                     if (ss->inArrayInit || ss->inGenExp) {
<                         LOCAL_ASSERT(SN_TYPE(sn) == SRC_IF);
<                         ss->sprinter.offset -= PAREN_SLOP;
<                         if (Sprint(&ss->sprinter, " if (%s)", rval) < 0)
<                             return NULL;
<                         AddParenSlop(ss);
<                     } else {
<                         js_printf(jp,
<                                   elseif ? " if (%s) {\n" : "\tif (%s) {\n",
<                                   rval);
<                         jp->indent += 4;
<                     }
< 
<                     if (SN_TYPE(sn) == SRC_IF) {
<                         DECOMPILE_CODE(pc + oplen, len - oplen);
<                     } else {
<                         LOCAL_ASSERT(!ss->inArrayInit && !ss->inGenExp);
<                         tail = js_GetSrcNoteOffset(sn, 0);
<                         DECOMPILE_CODE(pc + oplen, tail - oplen);
<                         jp->indent -= 4;
<                         pc += tail;
<                         LOCAL_ASSERT(*pc == JSOP_GOTO || *pc == JSOP_GOTOX);
<                         oplen = js_CodeSpec[*pc].length;
<                         len = GetJumpOffset(pc, pc);
<                         js_printf(jp, "\t} else");
< 
<                         /*
<                          * If the second offset for sn is non-zero, it tells
<                          * the distance from the goto around the else, to the
<                          * ifeq for the if inside the else that forms an "if
<                          * else if" chain.  Thus cond spans the condition of
<                          * the second if, so we simply decompile it and start
<                          * over at label if_again.
<                          */
<                         cond = js_GetSrcNoteOffset(sn, 1);
<                         if (cond != 0) {
<                             DECOMPILE_CODE(pc + oplen, cond - oplen);
<                             pc += cond;
<                             elseif = JS_TRUE;
<                             goto if_again;
<                         }
< 
<                         js_printf(jp, " {\n");
<                         jp->indent += 4;
<                         DECOMPILE_CODE(pc + oplen, len - oplen);
<                     }
< 
<                     if (!ss->inArrayInit && !ss->inGenExp) {
<                         jp->indent -= 4;
<                         js_printf(jp, "\t}\n");
<                     }
<                     todo = -2;
<                     break;
< 
<                   case SRC_COND:
<                     xval = JS_strdup(cx, POP_STR());
<                     if (!xval)
<                         return NULL;
---
> 		    js_printf(jp, "\tbreak %s;\n", rval);
> 		    break;
> 		  case SRC_HIDDEN:
> 		    break;
> 		  default:
> 		    js_printf(jp, "\tbreak;\n");
> 		    break;
> 		}
> 		todo = -2;
> 		break;
> 
> 	      case JSOP_IFEQ:
> 	      case JSOP_IFEQX:
> 		len = GetJumpOffset(pc, pc);
> 		sn = js_GetSrcNote(jp->script, pc);
> 
> 		switch (sn ? SN_TYPE(sn) : SRC_NULL) {
> 		  case SRC_IF:
> 		  case SRC_IF_ELSE:
> 		    rval = POP_STR();
> 		    js_printf(jp, "\tif (%s) {\n", rval);
> 		    jp->indent += 4;
> 		    if (SN_TYPE(sn) == SRC_IF) {
> 			DECOMPILE_CODE(pc + oplen, len - oplen);
> 		    } else {
>                         len = js_GetSrcNoteOffset(sn, 0);
> 			DECOMPILE_CODE(pc + oplen, len - oplen);
> 			jp->indent -= 4;
> 			pc += len;
> 			LOCAL_ASSERT(*pc == JSOP_GOTO || *pc == JSOP_GOTOX);
> 			oplen = js_CodeSpec[*pc].length;
> 			len = GetJumpOffset(pc, pc);
> 			js_printf(jp, "\t} else {\n");
> 			jp->indent += 4;
> 			DECOMPILE_CODE(pc + oplen, len - oplen);
> 		    }
> 		    jp->indent -= 4;
> 		    js_printf(jp, "\t}\n");
> 		    todo = -2;
> 		    break;
> 
> 		  case SRC_WHILE:
> 		    rval = POP_STR();
> 		    js_printf(jp, "\twhile (%s) {\n", rval);
> 		    jp->indent += 4;
>                     tail = js_GetSrcNoteOffset(sn, 0);
> 		    DECOMPILE_CODE(pc + oplen, tail - oplen);
> 		    jp->indent -= 4;
> 		    js_printf(jp, "\t}\n");
> 		    todo = -2;
> 		    break;
> 
> 		  case SRC_COND:
> 		    xval = JS_strdup(cx, POP_STR());
> 		    if (!xval)
> 			return JS_FALSE;
2908,2935c1837,1870
<                     DECOMPILE_CODE(pc + oplen, len - oplen);
<                     lval = JS_strdup(cx, POP_STR());
<                     if (!lval) {
<                         JS_free(cx, (void *)xval);
<                         return NULL;
<                     }
<                     pc += len;
<                     LOCAL_ASSERT(*pc == JSOP_GOTO || *pc == JSOP_GOTOX);
<                     oplen = js_CodeSpec[*pc].length;
<                     len = GetJumpOffset(pc, pc);
<                     DECOMPILE_CODE(pc + oplen, len - oplen);
<                     rval = POP_STR();
<                     todo = Sprint(&ss->sprinter, "%s ? %s : %s",
<                                   xval, lval, rval);
<                     JS_free(cx, (void *)xval);
<                     JS_free(cx, (void *)lval);
<                     break;
< 
<                   default:
<                     break;
<                 }
<                 break;
<               }
< 
<               case JSOP_IFNE:
<               case JSOP_IFNEX:
<                 LOCAL_ASSERT(0);
<                 break;
---
> 		    DECOMPILE_CODE(pc + oplen, len - oplen);
> 		    lval = JS_strdup(cx, POP_STR());
> 		    if (!lval) {
> 			JS_free(cx, (void *)xval);
> 			return JS_FALSE;
> 		    }
> 		    pc += len;
> 		    LOCAL_ASSERT(*pc == JSOP_GOTO || *pc == JSOP_GOTOX);
> 		    oplen = js_CodeSpec[*pc].length;
> 		    len = GetJumpOffset(pc, pc);
> 		    DECOMPILE_CODE(pc + oplen, len - oplen);
> 		    rval = POP_STR();
> 		    todo = Sprint(&ss->sprinter, "%s ? %s : %s",
> 				  xval, lval, rval);
> 		    JS_free(cx, (void *)xval);
> 		    JS_free(cx, (void *)lval);
> 		    break;
> 
> 		  default:
> 		    break;
> 		}
> 		break;
> 
> 	      case JSOP_IFNE:
> 	      case JSOP_IFNEX:
> #if JS_HAS_DO_WHILE_LOOP
> 		/* Currently, this must be a do-while loop's upward branch. */
>                 jp->indent -= 4;
>                 js_printf(jp, "\t} while (%s);\n", POP_STR());
>                 todo = -2;
> #else
>                 JS_ASSERT(0);
> #endif /* JS_HAS_DO_WHILE_LOOP */
> 		break;
2937,2938c1872,1873
<               case JSOP_OR:
<               case JSOP_ORX:
---
> 	      case JSOP_OR:
> 	      case JSOP_ORX:
2942,2953c1877,1885
<                 /* Top of stack is the first clause in a disjunction (||). */
<                 lval = JS_strdup(cx, POP_STR());
<                 if (!lval)
<                     return NULL;
<                 done = pc + GetJumpOffset(pc, pc);
<                 pc += len;
<                 len = PTRDIFF(done, pc, jsbytecode);
<                 if (!Decompile(ss, pc, len, op)) {
<                     JS_free(cx, (char *)lval);
<                     return NULL;
<                 }
<                 rval = POP_STR();
---
> 		/* Top of stack is the first clause in a disjunction (||). */
> 		lval = JS_strdup(cx, POP_STR());
> 		if (!lval)
> 		    return JS_FALSE;
> 		done = pc + GetJumpOffset(pc, pc);
> 		pc += len;
> 		len = PTRDIFF(done, pc, jsbytecode);
> 		DECOMPILE_CODE(pc, len);
> 		rval = POP_STR();
2970,2971c1902,1903
<                 JS_free(cx, (char *)lval);
<                 break;
---
> 		JS_free(cx, (char *)lval);
> 		break;
2973,2974c1905,1906
<               case JSOP_AND:
<               case JSOP_ANDX:
---
> 	      case JSOP_AND:
> 	      case JSOP_ANDX:
2978,2990c1910,1917
<               case JSOP_FORARG:
<                 atom = GetSlotAtom(jp, JS_TRUE, GET_ARGNO(pc));
<                 LOCAL_ASSERT(atom);
<                 goto do_fornameinloop;
< 
<               case JSOP_FORVAR:
<               case JSOP_FORCONST:
<                 atom = GetSlotAtom(jp, JS_FALSE, GET_VARNO(pc));
<                 LOCAL_ASSERT(atom);
<                 goto do_fornameinloop;
< 
<               case JSOP_FORNAME:
<                 LOAD_ATOM(0);
---
> 	      case JSOP_FORARG:
> 		atom = GetSlotAtom(jp, js_GetArgument, GET_ARGNO(pc));
> 		LOCAL_ASSERT(atom);
>                 lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
>                 if (!lval)
>                     return JS_FALSE;
>                 RETRACT(&ss->sprinter, lval);
> 		goto do_fornameinloop;
2992,2997c1919,1926
<               do_fornameinloop:
<                 lval = "";
<               do_forlvalinloop:
<                 sn = js_GetSrcNote(jp->script, pc);
<                 xval = NULL;
<                 goto do_forinloop;
---
> 	      case JSOP_FORVAR:
> 		atom = GetSlotAtom(jp, js_GetLocalVariable, GET_VARNO(pc));
> 		LOCAL_ASSERT(atom);
>                 lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
>                 if (!lval)
>                     return JS_FALSE;
>                 RETRACT(&ss->sprinter, lval);
> 		goto do_fornameinloop;
2999,3010c1928,1933
<               case JSOP_FORPROP:
<                 xval = NULL;
<                 LOAD_ATOM(0);
<                 if (!ATOM_IS_IDENTIFIER(atom)) {
<                     xval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom),
<                                        (jschar)'\'');
<                     if (!xval)
<                         return NULL;
<                     atom = NULL;
<                 }
<                 lval = POP_STR();
<                 sn = NULL;
---
> 	      case JSOP_FORNAME:
>                 atom = GET_ATOM(cx, jp->script, pc);
>                 lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
>                 if (!lval)
>                     return JS_FALSE;
>                 RETRACT(&ss->sprinter, lval);
3012,3034c1935,1953
<               do_forinloop:
<                 pc += oplen;
<                 LOCAL_ASSERT(*pc == JSOP_IFEQ || *pc == JSOP_IFEQX);
<                 oplen = js_CodeSpec[*pc].length;
<                 len = GetJumpOffset(pc, pc);
<                 sn2 = js_GetSrcNote(jp->script, pc);
<                 tail = js_GetSrcNoteOffset(sn2, 0);
< 
<               do_forinhead:
<                 if (!atom && xval) {
<                     /*
<                      * If xval is not a dummy empty string, we have to strdup
<                      * it to save it from being clobbered by the first Sprint
<                      * below.  Standard dumb decompiler operating procedure!
<                      */
<                     if (*xval == '\0') {
<                         xval = NULL;
<                     } else {
<                         xval = JS_strdup(cx, xval);
<                         if (!xval)
<                             return NULL;
<                     }
<                 }
---
>               do_fornameinloop:
> 		sn = js_GetSrcNote(jp->script, pc);
> 		xval = NULL;
> 		atom = NULL;
> 		goto do_forinloop;
> 
> 	      case JSOP_FORPROP:
> 		xval = NULL;
> 		atom = GET_ATOM(cx, jp->script, pc);
> 		lval = POP_STR();
> 		sn = NULL;
> 
> 	      do_forinloop:
> 		pc += oplen;
> 		LOCAL_ASSERT(*pc == JSOP_IFEQ || *pc == JSOP_IFEQX);
> 		oplen = js_CodeSpec[*pc].length;
> 		len = GetJumpOffset(pc, pc);
> 		sn = js_GetSrcNote(jp->script, pc);
>                 tail = js_GetSrcNoteOffset(sn, 0);
3036,3046c1955,1956
< #if JS_HAS_XML_SUPPORT
<                 if (foreach) {
<                     foreach = JS_FALSE;
<                     todo = Sprint(&ss->sprinter, "for %s (%s%s",
<                                   js_each_str, VarPrefix(sn), lval);
<                 } else
< #endif
<                 {
<                     todo = Sprint(&ss->sprinter, "for (%s%s",
<                                   VarPrefix(sn), lval);
<                 }
---
>               do_forinbody:
> 		js_printf(jp, "\tfor (%s%s", VarPrefix(sn), lval);
3048,3052c1958,1962
<                     if (*lval && SprintPut(&ss->sprinter, ".", 1) < 0)
<                         return NULL;
<                     xval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
<                     if (!xval)
<                         return NULL;
---
>                     lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
>                     if (!lval)
>                         return JS_FALSE;
>                     RETRACT(&ss->sprinter, lval);
>                     js_printf(jp, ".%s", lval);
3054,3089c1964
<                     LOCAL_ASSERT(*xval != '\0');
<                     ok = (Sprint(&ss->sprinter,
<                                  (JOF_OPMODE(lastop) == JOF_XMLNAME)
<                                  ? ".%s"
<                                  : "[%s]",
<                                  xval)
<                           >= 0);
<                     JS_free(cx, (char *)xval);
<                     if (!ok)
<                         return NULL;
<                 }
<                 if (todo < 0)
<                     return NULL;
< 
<                 lval = OFF2STR(&ss->sprinter, todo);
<                 rval = GetStr(ss, ss->top-1);
<                 RETRACT(&ss->sprinter, rval);
<                 if (ss->inArrayInit || ss->inGenExp) {
<                     if (ss->top > 1 &&
<                         (js_CodeSpec[ss->opcodes[ss->top-2]].format &
<                          JOF_FOR)) {
<                         ss->sprinter.offset -= PAREN_SLOP;
<                     }
<                     todo = Sprint(&ss->sprinter, " %s in %s)", lval, rval);
<                     if (todo < 0)
<                         return NULL;
<                     ss->offsets[ss->top-1] = todo;
<                     ss->opcodes[ss->top-1] = op;
<                     AddParenSlop(ss);
<                     DECOMPILE_CODE(pc + oplen, tail - oplen);
<                 } else {
<                     js_printf(jp, "\t%s in %s) {\n", lval, rval);
<                     jp->indent += 4;
<                     DECOMPILE_CODE(pc + oplen, tail - oplen);
<                     jp->indent -= 4;
<                     js_printf(jp, "\t}\n");
---
>                     js_printf(jp, "[%s]", xval);
3091,3092c1966,1973
<                 todo = -2;
<                 break;
---
>                 rval = OFF2STR(&ss->sprinter, ss->offsets[ss->top-1]);
> 		js_printf(jp, " in %s) {\n", rval);
> 		jp->indent += 4;
> 		DECOMPILE_CODE(pc + oplen, tail - oplen);
> 		jp->indent -= 4;
> 		js_printf(jp, "\t}\n");
> 		todo = -2;
> 		break;
3095,3097c1976,1978
<                 pc++;
<                 LOCAL_ASSERT(*pc == JSOP_IFEQ || *pc == JSOP_IFEQX);
<                 len = js_CodeSpec[*pc].length;
---
> 		pc++;
> 		LOCAL_ASSERT(*pc == JSOP_IFEQ || *pc == JSOP_IFEQX);
> 		len = js_CodeSpec[*pc].length;
3100,3103c1981,1983
<                  * Arrange for the JSOP_ENUMELEM case to set tail for use by
<                  * do_forinhead: code that uses on it to find the loop-closing
<                  * jump (whatever its format, normal or extended), in order to
<                  * bound the recursively decompiled loop body.
---
>                  * Set tail for use by do_forinbody: code that uses it to find
>                  * the loop-closing jump (whatever its format, short or long),
>                  * in order to bound the recursively decompiled loop body.
3105,3107c1985,1986
<                 sn = js_GetSrcNote(jp->script, pc);
<                 LOCAL_ASSERT(!forelem_tail);
<                 forelem_tail = pc + js_GetSrcNoteOffset(sn, 0);
---
> 		sn = js_GetSrcNote(jp->script, pc);
>                 tail = js_GetSrcNoteOffset(sn, 0) - oplen;
3115,3119d1993
<                  *
<                  * Since a for..in loop can't nest in the head of another for
<                  * loop, we can use forelem_{tail,done} singletons to remember
<                  * state from JSOP_FORELEM to JSOP_ENUMELEM, thence (via goto)
<                  * to label do_forinhead.
3121,3125c1995,1996
<                 LOCAL_ASSERT(!forelem_done);
<                 forelem_done = pc + GetJumpOffset(pc, pc);
< 
<                 /* Our net stack balance after forelem;ifeq is +1. */
<                 todo = SprintCString(&ss->sprinter, forelem_cookie);
---
>                 JS_ASSERT(!forelem_done);
> 		forelem_done = pc + GetJumpOffset(pc, pc);
3128,3149c1999,2011
<               case JSOP_ENUMELEM:
<               case JSOP_ENUMCONSTELEM:
<                 /*
<                  * The stack has the object under the (top) index expression.
<                  * The "rval" property id is underneath those two on the stack.
<                  * The for loop body net and gross lengths can now be adjusted
<                  * to account for the length of the indexing expression that
<                  * came after JSOP_FORELEM and before JSOP_ENUMELEM.
<                  */
<                 atom = NULL;
<                 op = JSOP_NOP;          /* turn off parens around xval */
<                 xval = POP_STR();
<                 op = JSOP_GETELEM;      /* lval must have high precedence */
<                 lval = POP_STR();
<                 op = saveop;
<                 rval = POP_STR();
<                 LOCAL_ASSERT(strcmp(rval, forelem_cookie) == 0);
<                 LOCAL_ASSERT(forelem_tail > pc);
<                 tail = forelem_tail - pc;
<                 forelem_tail = NULL;
<                 LOCAL_ASSERT(forelem_done > pc);
<                 len = forelem_done - pc;
---
> 	      case JSOP_ENUMELEM:
> 		/*
> 		 * The stack has the object under the (top) index expression.
> 		 * The "rval" property id is underneath those two on the stack.
> 		 * The for loop body length can now be adjusted to account for
> 		 * the length of the indexing expression.
> 		 */
> 		atom = NULL;
> 		xval = POP_STR();
> 		lval = POP_STR();
> 		rval = OFF2STR(&ss->sprinter, ss->offsets[ss->top-1]);
>                 JS_ASSERT(forelem_done > pc);
> 		len = forelem_done - pc;
3151,3226c2013
<                 goto do_forinhead;
< 
< #if JS_HAS_GETTER_SETTER
<               case JSOP_GETTER:
<               case JSOP_SETTER:
<                 todo = -2;
<                 break;
< #endif
< 
<               case JSOP_DUP2:
<                 rval = GetStr(ss, ss->top-2);
<                 todo = SprintCString(&ss->sprinter, rval);
<                 if (todo < 0 || !PushOff(ss, todo,
<                                          (JSOp) ss->opcodes[ss->top-2])) {
<                     return NULL;
<                 }
<                 /* FALL THROUGH */
< 
<               case JSOP_DUP:
< #if JS_HAS_DESTRUCTURING
<                 sn = js_GetSrcNote(jp->script, pc);
<                 if (sn) {
<                     LOCAL_ASSERT(SN_TYPE(sn) == SRC_DESTRUCT);
<                     pc = DecompileDestructuring(ss, pc, endpc);
<                     if (!pc)
<                         return NULL;
<                     len = 0;
<                     lval = POP_STR();
<                     op = saveop = JSOP_ENUMELEM;
<                     rval = POP_STR();
< 
<                     if (strcmp(rval, forelem_cookie) == 0) {
<                         LOCAL_ASSERT(forelem_tail > pc);
<                         tail = forelem_tail - pc;
<                         forelem_tail = NULL;
<                         LOCAL_ASSERT(forelem_done > pc);
<                         len = forelem_done - pc;
<                         forelem_done = NULL;
<                         xval = NULL;
<                         atom = NULL;
< 
<                         /*
<                          * Null sn if this is a 'for (var [k, v] = i in o)'
<                          * loop, because 'var [k, v = i;' has already been
<                          * hoisted.
<                          */
<                         if (js_GetSrcNoteOffset(sn, 0) == SRC_DECL_VAR)
<                             sn = NULL;
<                         goto do_forinhead;
<                     }
< 
<                     todo = Sprint(&ss->sprinter, "%s%s = %s",
<                                   VarPrefix(sn), lval, rval);
<                     break;
<                 }
< #endif
< 
<                 rval = GetStr(ss, ss->top-1);
<                 saveop = (JSOp) ss->opcodes[ss->top-1];
<                 todo = SprintCString(&ss->sprinter, rval);
<                 break;
< 
<               case JSOP_SETARG:
<                 atom = GetSlotAtom(jp, JS_TRUE, GET_ARGNO(pc));
<                 LOCAL_ASSERT(atom);
<                 goto do_setname;
< 
<               case JSOP_SETVAR:
<                 atom = GetSlotAtom(jp, JS_FALSE, GET_VARNO(pc));
<                 LOCAL_ASSERT(atom);
<                 goto do_setname;
< 
<               case JSOP_SETCONST:
<               case JSOP_SETNAME:
<               case JSOP_SETGVAR:
<                 LOAD_ATOM(0);
---
> 		goto do_forinbody;
3228c2015,2041
<               do_setname:
---
> 	      case JSOP_DUP2:
> 		rval = OFF2STR(&ss->sprinter, ss->offsets[ss->top-2]);
> 		todo = SprintPut(&ss->sprinter, rval, strlen(rval));
> 		if (todo < 0 || !PushOff(ss, todo, (JSOp)ss->opcodes[ss->top-2]))
> 		    return JS_FALSE;
> 		/* FALL THROUGH */
> 
> 	      case JSOP_DUP:
> 		rval = OFF2STR(&ss->sprinter, ss->offsets[ss->top-1]);
>                 op = (JSOp)ss->opcodes[ss->top-1];
> 		todo = SprintPut(&ss->sprinter, rval, strlen(rval));
> 		break;
> 
> 	      case JSOP_SETARG:
> 		atom = GetSlotAtom(jp, js_GetArgument, GET_ARGNO(pc));
> 		LOCAL_ASSERT(atom);
> 		goto do_setname;
> 
> 	      case JSOP_SETVAR:
> 		atom = GetSlotAtom(jp, js_GetLocalVariable, GET_VARNO(pc));
> 		LOCAL_ASSERT(atom);
> 		goto do_setname;
> 
> 	      case JSOP_SETCONST:
> 	      case JSOP_SETNAME:
> 		atom = GET_ATOM(cx, jp->script, pc);
> 	      do_setname:
3231,3235c2044,2047
<                     return NULL;
<                 rval = POP_STR();
<                 if (op == JSOP_SETNAME)
<                     (void) PopOff(ss, op);
< 
---
>                     return JS_FALSE;
> 		rval = POP_STR();
> 		if (op == JSOP_SETNAME)
> 		    (void) PopOff(ss, op);
3237,3264c2049,2062
<                 sn = js_GetSrcNote(jp->script, pc - 1);
<                 if (sn && SN_TYPE(sn) == SRC_ASSIGNOP) {
<                     todo = Sprint(&ss->sprinter, "%s %s= %s",
<                                   lval,
<                                   (lastop == JSOP_GETTER)
<                                   ? js_getter_str
<                                   : (lastop == JSOP_SETTER)
<                                   ? js_setter_str
<                                   : CodeToken[lastop],
<                                   rval);
<                 } else {
<                     sn = js_GetSrcNote(jp->script, pc);
<                     todo = Sprint(&ss->sprinter, "%s%s = %s",
<                                   VarPrefix(sn), lval, rval);
<                 }
<                 if (op == JSOP_SETLOCALPOP) {
<                     if (!PushOff(ss, todo, saveop))
<                         return NULL;
<                     rval = POP_STR();
<                     LOCAL_ASSERT(*rval != '\0');
<                     js_printf(jp, "\t%s;\n", rval);
<                     todo = -2;
<                 }
<                 break;
< 
<               case JSOP_NEW:
<               case JSOP_CALL:
<               case JSOP_EVAL:
---
> 		if ((sn = js_GetSrcNote(jp->script, pc - 1)) != NULL &&
> 		    SN_TYPE(sn) == SRC_ASSIGNOP) {
> 		    todo = Sprint(&ss->sprinter, "%s %s= %s",
> 				  lval, js_CodeSpec[lastop].token, rval);
> 		} else {
> 		    sn = js_GetSrcNote(jp->script, pc);
> 		    todo = Sprint(&ss->sprinter, "%s%s = %s",
> 				  VarPrefix(sn), lval, rval);
> 		}
> 		break;
> 
> 	      case JSOP_NEW:
> 	      case JSOP_CALL:
> 	      case JSOP_EVAL:
3266c2064
<               case JSOP_SETCALL:
---
> 	      case JSOP_SETCALL:
3268,3271c2066,2070
<                 /* Turn off most parens (all if there's only one argument). */
<                 argc = GET_ARGC(pc);
<                 op = (argc == 1) ? JSOP_NOP : JSOP_SETNAME;
<                 argv = (char **)
---
> 		saveop = op;
> 		op = JSOP_NOP;           /* turn off parens */
> 		argc = GET_ARGC(pc);
> 		XMEMTAG("jsopcode JSOP_NOP");
> 		argv = (char **)
3273,3281c2072,2073
<                 if (!argv)
<                     return NULL;
< 
<                 ok = JS_TRUE;
<                 for (i = argc; i > 0; i--) {
<                     argv[i] = JS_strdup(cx, POP_STR());
<                     if (!argv[i])
<                         ok = JS_FALSE;
<                 }
---
> 		if (!argv)
> 		    return JS_FALSE;
3283,3334c2075,2122
<                 /* Skip the JSOP_PUSHOBJ-created empty string. */
<                 LOCAL_ASSERT(ss->top >= 2);
<                 (void) PopOff(ss, op);
< 
<                 /*
<                  * Special case: new (x(y)(z)) must be parenthesized like so.
<                  * Same for new (x(y).z) -- contrast with new x(y).z.
<                  */
<                 op = (JSOp) ss->opcodes[ss->top-1];
<                 lval = PopStr(ss,
<                               (saveop == JSOP_NEW &&
<                                (op == JSOP_CALL || op == JSOP_EVAL ||
<                                 (js_CodeSpec[op].format & JOF_CALLOP)))
<                               ? JSOP_NAME
<                               : saveop);
<                 op = saveop;
< 
<                 argv[0] = JS_strdup(cx, lval);
<                 if (!argv[i])
<                     ok = JS_FALSE;
< 
<                 lval = "(", rval = ")";
<                 if (op == JSOP_NEW) {
<                     if (argc == 0)
<                         lval = rval = "";
<                     todo = Sprint(&ss->sprinter, "%s %s%s",
<                                   js_new_str, argv[0], lval);
<                 } else {
<                     todo = Sprint(&ss->sprinter, ss_format,
<                                   argv[0], lval);
<                 }
<                 if (todo < 0)
<                     ok = JS_FALSE;
< 
<                 for (i = 1; i <= argc; i++) {
<                     if (!argv[i] ||
<                         Sprint(&ss->sprinter, ss_format,
<                                argv[i], (i < argc) ? ", " : "") < 0) {
<                         ok = JS_FALSE;
<                         break;
<                     }
<                 }
<                 if (Sprint(&ss->sprinter, rval) < 0)
<                     ok = JS_FALSE;
< 
<                 for (i = 0; i <= argc; i++) {
<                     if (argv[i])
<                         JS_free(cx, argv[i]);
<                 }
<                 JS_free(cx, argv);
<                 if (!ok)
<                     return NULL;
---
> 		ok = JS_TRUE;
> 		for (i = argc; i > 0; i--) {
> 		    argv[i] = JS_strdup(cx, POP_STR());
> 		    if (!argv[i]) {
> 			ok = JS_FALSE;
> 			break;
> 		    }
> 		}
> 
> 		/* Skip the JSOP_PUSHOBJ-created empty string. */
> 		LOCAL_ASSERT(ss->top >= 2);
> 		(void) PopOff(ss, op);
> 
> 		/* Get the callee's decompiled image in argv[0]. */
> 		argv[0] = JS_strdup(cx, POP_STR());
> 		if (!argv[i])
> 		    ok = JS_FALSE;
> 
> 		lval = "(", rval = ")";
> 		if (saveop == JSOP_NEW) {
> 		    todo = Sprint(&ss->sprinter, "%s %s%s",
> 				  js_new_str, argv[0], lval);
> 		} else {
> 		    todo = Sprint(&ss->sprinter, "%s%s",
> 				  argv[0], lval);
> 		}
> 		if (todo < 0)
> 		    ok = JS_FALSE;
> 
> 		for (i = 1; i <= argc; i++) {
> 		    if (!argv[i] ||
> 			Sprint(&ss->sprinter, "%s%s",
> 			       argv[i], (i < argc) ? ", " : "") < 0) {
> 			ok = JS_FALSE;
> 			break;
> 		    }
> 		}
> 		if (Sprint(&ss->sprinter, rval) < 0)
> 		    ok = JS_FALSE;
> 
> 		for (i = 0; i <= argc; i++) {
> 		    if (argv[i])
> 			JS_free(cx, argv[i]);
> 		}
> 		JS_free(cx, argv);
> 		if (!ok)
> 		    return JS_FALSE;
> 		op = saveop;
3338c2126
<                         return NULL;
---
>                         return JS_FALSE;
3342c2130
<                 break;
---
> 		break;
3344,3345c2132,2133
<               case JSOP_DELNAME:
<                 LOAD_ATOM(0);
---
> 	      case JSOP_DELNAME:
> 		atom = GET_ATOM(cx, jp->script, pc);
3348c2136
<                     return NULL;
---
>                     return JS_FALSE;
3350,3358c2138,2139
<               do_delete_lval:
<                 todo = Sprint(&ss->sprinter, "%s %s", js_delete_str, lval);
<                 break;
< 
<               case JSOP_DELPROP:
<                 GET_ATOM_QUOTE_AND_FMT("%s %s[%s]", "%s %s.%s", rval);
<                 lval = POP_STR();
<                 todo = Sprint(&ss->sprinter, fmt, js_delete_str, lval, rval);
<                 break;
---
> 		todo = Sprint(&ss->sprinter, "%s %s", js_delete_str, lval);
> 		break;
3360,3471c2141,2179
<               case JSOP_DELELEM:
<                 op = JSOP_NOP;          /* turn off parens */
<                 xval = POP_STR();
<                 op = saveop;
<                 lval = POP_STR();
<                 if (*xval == '\0')
<                     goto do_delete_lval;
<                 todo = Sprint(&ss->sprinter,
<                               (JOF_OPMODE(lastop) == JOF_XMLNAME)
<                               ? "%s %s.%s"
<                               : "%s %s[%s]",
<                               js_delete_str, lval, xval);
<                 break;
< 
< #if JS_HAS_XML_SUPPORT
<               case JSOP_DELDESC:
<                 xval = POP_STR();
<                 lval = POP_STR();
<                 todo = Sprint(&ss->sprinter, "%s %s..%s",
<                               js_delete_str, lval, xval);
<                 break;
< #endif
< 
<               case JSOP_TYPEOFEXPR:
<               case JSOP_TYPEOF:
<               case JSOP_VOID:
<                 rval = POP_STR();
<                 todo = Sprint(&ss->sprinter, "%s %s",
<                               (op == JSOP_VOID) ? js_void_str : js_typeof_str,
<                               rval);
<                 break;
< 
<               case JSOP_INCARG:
<               case JSOP_DECARG:
<                 atom = GetSlotAtom(jp, JS_TRUE, GET_ARGNO(pc));
<                 LOCAL_ASSERT(atom);
<                 goto do_incatom;
< 
<               case JSOP_INCVAR:
<               case JSOP_DECVAR:
<                 atom = GetSlotAtom(jp, JS_FALSE, GET_VARNO(pc));
<                 LOCAL_ASSERT(atom);
<                 goto do_incatom;
< 
<               case JSOP_INCNAME:
<               case JSOP_DECNAME:
<               case JSOP_INCGVAR:
<               case JSOP_DECGVAR:
<                 LOAD_ATOM(0);
<               do_incatom:
<                 lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
<                 if (!lval)
<                     return NULL;
<                 RETRACT(&ss->sprinter, lval);
<               do_inclval:
<                 todo = Sprint(&ss->sprinter, ss_format,
<                               js_incop_strs[!(cs->format & JOF_INC)], lval);
<                 break;
< 
<               case JSOP_INCPROP:
<               case JSOP_DECPROP:
<                 GET_ATOM_QUOTE_AND_FMT(preindex_format, predot_format, rval);
< 
<                 /*
<                  * Force precedence below the numeric literal opcodes, so that
<                  * 42..foo or 10000..toString(16), e.g., decompile with parens
<                  * around the left-hand side of dot.
<                  */
<                 op = JSOP_GETPROP;
<                 lval = POP_STR();
<                 todo = Sprint(&ss->sprinter, fmt,
<                               js_incop_strs[!(cs->format & JOF_INC)],
<                               lval, rval);
<                 break;
< 
<               case JSOP_INCELEM:
<               case JSOP_DECELEM:
<                 op = JSOP_NOP;          /* turn off parens */
<                 xval = POP_STR();
<                 op = JSOP_GETELEM;
<                 lval = POP_STR();
<                 if (*xval != '\0') {
<                     todo = Sprint(&ss->sprinter,
<                                   (JOF_OPMODE(lastop) == JOF_XMLNAME)
<                                   ? predot_format
<                                   : preindex_format,
<                                   js_incop_strs[!(cs->format & JOF_INC)],
<                                   lval, xval);
<                 } else {
<                     todo = Sprint(&ss->sprinter, ss_format,
<                                   js_incop_strs[!(cs->format & JOF_INC)], lval);
<                 }
<                 break;
< 
<               case JSOP_ARGINC:
<               case JSOP_ARGDEC:
<                 atom = GetSlotAtom(jp, JS_TRUE, GET_ARGNO(pc));
<                 LOCAL_ASSERT(atom);
<                 goto do_atominc;
< 
<               case JSOP_VARINC:
<               case JSOP_VARDEC:
<                 atom = GetSlotAtom(jp, JS_FALSE, GET_VARNO(pc));
<                 LOCAL_ASSERT(atom);
<                 goto do_atominc;
< 
<               case JSOP_NAMEINC:
<               case JSOP_NAMEDEC:
<               case JSOP_GVARINC:
<               case JSOP_GVARDEC:
<                 LOAD_ATOM(0);
<               do_atominc:
---
> 	      case JSOP_DELPROP:
> 		atom = GET_ATOM(cx, jp->script, pc);
>                 rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
>                 if (!rval)
>                     return JS_FALSE;
> 		lval = POP_STR();
> 		todo = Sprint(&ss->sprinter, "%s %s.%s",
> 			      js_delete_str, lval, rval);
> 		break;
> 
> 	      case JSOP_DELELEM:
> 		xval = POP_STR();
> 		lval = POP_STR();
> 		todo = Sprint(&ss->sprinter, "%s %s[%s]",
> 			      js_delete_str, lval, xval);
> 		break;
> 
> 	      case JSOP_TYPEOF:
> 	      case JSOP_VOID:
> 		rval = POP_STR();
> 		todo = Sprint(&ss->sprinter, "%s %s", cs->name, rval);
> 		break;
> 
> 	      case JSOP_INCARG:
> 	      case JSOP_DECARG:
> 		atom = GetSlotAtom(jp, js_GetArgument, GET_ARGNO(pc));
> 		LOCAL_ASSERT(atom);
> 		goto do_incatom;
> 
> 	      case JSOP_INCVAR:
> 	      case JSOP_DECVAR:
> 		atom = GetSlotAtom(jp, js_GetLocalVariable, GET_VARNO(pc));
> 		LOCAL_ASSERT(atom);
> 		goto do_incatom;
> 
> 	      case JSOP_INCNAME:
> 	      case JSOP_DECNAME:
> 		atom = GET_ATOM(cx, jp->script, pc);
> 	      do_incatom:
3474c2182
<                     return NULL;
---
>                     return JS_FALSE;
3476,3549c2184,2224
<               do_lvalinc:
<                 todo = Sprint(&ss->sprinter, ss_format,
<                               lval, js_incop_strs[!(cs->format & JOF_INC)]);
<                 break;
< 
<               case JSOP_PROPINC:
<               case JSOP_PROPDEC:
<                 GET_ATOM_QUOTE_AND_FMT(postindex_format, postdot_format, rval);
< 
<                 /*
<                  * Force precedence below the numeric literal opcodes, so that
<                  * 42..foo or 10000..toString(16), e.g., decompile with parens
<                  * around the left-hand side of dot.
<                  */
<                 op = JSOP_GETPROP;
<                 lval = POP_STR();
<                 todo = Sprint(&ss->sprinter, fmt, lval, rval,
<                               js_incop_strs[!(cs->format & JOF_INC)]);
<                 break;
< 
<               case JSOP_ELEMINC:
<               case JSOP_ELEMDEC:
<                 op = JSOP_NOP;          /* turn off parens */
<                 xval = POP_STR();
<                 op = JSOP_GETELEM;
<                 lval = POP_STR();
<                 if (*xval != '\0') {
<                     todo = Sprint(&ss->sprinter,
<                                   (JOF_OPMODE(lastop) == JOF_XMLNAME)
<                                   ? postdot_format
<                                   : postindex_format,
<                                   lval, xval,
<                                   js_incop_strs[!(cs->format & JOF_INC)]);
<                 } else {
<                     todo = Sprint(&ss->sprinter, ss_format,
<                                   lval, js_incop_strs[!(cs->format & JOF_INC)]);
<                 }
<                 break;
< 
<               case JSOP_LENGTH:
<                 fmt = dot_format;
<                 rval = js_length_str;
<                 goto do_getprop_lval;
< 
<               case JSOP_GETPROP2:
<                 op = JSOP_GETPROP;
<                 (void) PopOff(ss, lastop);
<                 /* FALL THROUGH */
< 
<               case JSOP_CALLPROP:
<               case JSOP_GETPROP:
<               case JSOP_GETXPROP:
<                 LOAD_ATOM(0);
< 
<               do_getprop:
<                 GET_QUOTE_AND_FMT(index_format, dot_format, rval);
<               do_getprop_lval:
<                 lval = POP_STR();
<                 todo = Sprint(&ss->sprinter, fmt, lval, rval);
<                 break;
< 
<               case JSOP_GETTHISPROP:
<                 LOAD_ATOM(0);
<                 GET_QUOTE_AND_FMT(index_format, dot_format, rval);
<                 todo = Sprint(&ss->sprinter, fmt, js_this_str, rval);
<                 break;
< 
<               case JSOP_GETARGPROP:
<               case JSOP_GETVARPROP:
<                 /* Get the name of the argument or variable. */
<                 atom = GetSlotAtom(ss->printer, op == JSOP_GETARGPROP,
<                                    GET_UINT16(pc));
<                 LOCAL_ASSERT(atom);
<                 LOCAL_ASSERT(ATOM_IS_STRING(atom));
---
> 		todo = Sprint(&ss->sprinter, "%s%s",
> 			      js_incop_str[!(cs->format & JOF_INC)], lval);
> 		break;
> 
> 	      case JSOP_INCPROP:
> 	      case JSOP_DECPROP:
> 		atom = GET_ATOM(cx, jp->script, pc);
>                 rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
>                 if (!rval)
>                     return JS_FALSE;
> 		lval = POP_STR();
> 		todo = Sprint(&ss->sprinter, "%s%s.%s",
> 			      js_incop_str[!(cs->format & JOF_INC)],
> 			      lval, rval);
> 		break;
> 
> 	      case JSOP_INCELEM:
> 	      case JSOP_DECELEM:
> 		xval = POP_STR();
> 		lval = POP_STR();
> 		todo = Sprint(&ss->sprinter, "%s%s[%s]",
> 			      js_incop_str[!(cs->format & JOF_INC)],
> 			      lval, xval);
> 		break;
> 
> 	      case JSOP_ARGINC:
> 	      case JSOP_ARGDEC:
> 		atom = GetSlotAtom(jp, js_GetArgument, GET_ARGNO(pc));
> 		LOCAL_ASSERT(atom);
> 		goto do_atominc;
> 
> 	      case JSOP_VARINC:
> 	      case JSOP_VARDEC:
> 		atom = GetSlotAtom(jp, js_GetLocalVariable, GET_VARNO(pc));
> 		LOCAL_ASSERT(atom);
> 		goto do_atominc;
> 
> 	      case JSOP_NAMEINC:
> 	      case JSOP_NAMEDEC:
> 		atom = GET_ATOM(cx, jp->script, pc);
> 	      do_atominc:
3551,3562d2225
<                 if (!lval || !PushOff(ss, STR2OFF(&ss->sprinter, lval), op))
<                     return NULL;
< 
<                 /* Get the name of the property. */
<                 LOAD_ATOM(ARGNO_LEN);
<                 goto do_getprop;
< 
<               case JSOP_GETLOCALPROP:
<                 LOAD_ATOM(2);
<                 i = GET_UINT16(pc);
<                 LOCAL_ASSERT((uintN)i < ss->top);
<                 lval = GetLocal(ss, i);
3564,3721c2227,2237
<                     return NULL;
<                 todo = SprintCString(&ss->sprinter, lval);
<                 if (todo < 0 || !PushOff(ss, todo, op))
<                     return NULL;
<                 goto do_getprop;
< 
<               case JSOP_SETPROP:
<                 LOAD_ATOM(0);
<                 GET_QUOTE_AND_FMT("%s[%s] %s= %s", "%s.%s %s= %s", xval);
<                 rval = POP_STR();
< 
<                 /*
<                  * Force precedence below the numeric literal opcodes, so that
<                  * 42..foo or 10000..toString(16), e.g., decompile with parens
<                  * around the left-hand side of dot.
<                  */
<                 op = JSOP_GETPROP;
<                 lval = POP_STR();
<                 sn = js_GetSrcNote(jp->script, pc - 1);
<                 todo = Sprint(&ss->sprinter, fmt, lval, xval,
<                               (sn && SN_TYPE(sn) == SRC_ASSIGNOP)
<                               ? (lastop == JSOP_GETTER)
<                                 ? js_getter_str
<                                 : (lastop == JSOP_SETTER)
<                                 ? js_setter_str
<                                 : CodeToken[lastop]
<                               : "",
<                               rval);
<                 break;
< 
<               case JSOP_GETELEM2:
<                 op = JSOP_GETELEM;
<                 (void) PopOff(ss, lastop);
<                 /* FALL THROUGH */
< 
<               case JSOP_CALLELEM:
<               case JSOP_GETELEM:
<                 op = JSOP_NOP;          /* turn off parens */
<                 xval = POP_STR();
<                 op = saveop;
<                 lval = POP_STR();
<                 if (*xval == '\0') {
<                     todo = Sprint(&ss->sprinter, "%s", lval);
<                 } else {
<                     todo = Sprint(&ss->sprinter,
<                                   (JOF_OPMODE(lastop) == JOF_XMLNAME)
<                                   ? dot_format
<                                   : index_format,
<                                   lval, xval);
<                 }
<                 break;
< 
<               case JSOP_SETELEM:
<                 rval = POP_STR();
<                 op = JSOP_NOP;          /* turn off parens */
<                 xval = POP_STR();
<                 cs = &js_CodeSpec[ss->opcodes[ss->top]];
<                 op = JSOP_GETELEM;      /* lval must have high precedence */
<                 lval = POP_STR();
<                 op = saveop;
<                 if (*xval == '\0')
<                     goto do_setlval;
<                 sn = js_GetSrcNote(jp->script, pc - 1);
<                 todo = Sprint(&ss->sprinter,
<                               (JOF_MODE(cs->format) == JOF_XMLNAME)
<                               ? "%s.%s %s= %s"
<                               : "%s[%s] %s= %s",
<                               lval, xval,
<                               (sn && SN_TYPE(sn) == SRC_ASSIGNOP)
<                               ? (lastop == JSOP_GETTER)
<                                 ? js_getter_str
<                                 : (lastop == JSOP_SETTER)
<                                 ? js_setter_str
<                                 : CodeToken[lastop]
<                               : "",
<                               rval);
<                 break;
< 
<               case JSOP_ARGSUB:
<                 i = (jsint) GET_ARGNO(pc);
<                 todo = Sprint(&ss->sprinter, "%s[%d]",
<                               js_arguments_str, (int) i);
<                 break;
< 
<               case JSOP_ARGCNT:
<                 todo = Sprint(&ss->sprinter, dot_format,
<                               js_arguments_str, js_length_str);
<                 break;
< 
<               case JSOP_CALLARG:
<               case JSOP_GETARG:
<                 i = GET_ARGNO(pc);
<                 atom = GetSlotAtom(jp, JS_TRUE, i);
< #if JS_HAS_DESTRUCTURING
<                 if (!atom) {
<                     todo = Sprint(&ss->sprinter, "%s[%d]", js_arguments_str, i);
<                     break;
<                 }
< #else
<                 LOCAL_ASSERT(atom);
< #endif
<                 goto do_name;
< 
<               case JSOP_CALLVAR:
<               case JSOP_GETVAR:
<                 atom = GetSlotAtom(jp, JS_FALSE, GET_VARNO(pc));
<                 LOCAL_ASSERT(atom);
<                 goto do_name;
< 
<               case JSOP_CALLNAME:
<               case JSOP_NAME:
<               case JSOP_GETGVAR:
<               case JSOP_CALLGVAR:
<                 LOAD_ATOM(0);
<               do_name:
<                 lval = "";
< #if JS_HAS_XML_SUPPORT
<               do_qname:
< #endif
<                 sn = js_GetSrcNote(jp->script, pc);
<                 rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom),
<                                    inXML ? DONT_ESCAPE : 0);
<                 if (!rval)
<                     return NULL;
<                 RETRACT(&ss->sprinter, rval);
<                 todo = Sprint(&ss->sprinter, "%s%s%s",
<                               VarPrefix(sn), lval, rval);
<                 break;
< 
<               case JSOP_UINT16:
<                 i = (jsint) GET_UINT16(pc);
<                 goto do_sprint_int;
< 
<               case JSOP_UINT24:
<                 i = (jsint) GET_UINT24(pc);
<                 goto do_sprint_int;
< 
<               case JSOP_INT8:
<                 i = GET_INT8(pc);
<                 goto do_sprint_int;
< 
<               case JSOP_INT32:
<                 i = GET_INT32(pc);
<               do_sprint_int:
<                 todo = Sprint(&ss->sprinter, "%d", i);
<                 break;
< 
<               case JSOP_DOUBLE:
<                 LOAD_ATOM(0);
<                 val = ATOM_KEY(atom);
<                 LOCAL_ASSERT(JSVAL_IS_DOUBLE(val));
<                 todo = SprintDoubleValue(&ss->sprinter, val, &saveop);
<                 break;
< 
<               case JSOP_STRING:
<                 LOAD_ATOM(0);
<                 rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom),
<                                    inXML ? DONT_ESCAPE : '"');
---
>                     return JS_FALSE;
> 		todo = STR2OFF(&ss->sprinter, lval);
>                 SprintPut(&ss->sprinter,
>                           js_incop_str[!(cs->format & JOF_INC)],
>                           2);
> 		break;
> 
> 	      case JSOP_PROPINC:
> 	      case JSOP_PROPDEC:
> 		atom = GET_ATOM(cx, jp->script, pc);
>                 rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
3723,3900c2239,2266
<                     return NULL;
<                 todo = STR2OFF(&ss->sprinter, rval);
<                 break;
< 
<               case JSOP_ANONFUNOBJ:
< #if JS_HAS_GENERATOR_EXPRS
<                 sn = js_GetSrcNote(jp->script, pc);
<                 if (sn && SN_TYPE(sn) == SRC_GENEXP) {
<                     JSScript *inner, *outer;
<                     void *mark;
<                     SprintStack ss2;
< 
<                     LOAD_FUNCTION(0);
<                     fun = GET_FUNCTION_PRIVATE(cx, obj);
<                     LOCAL_ASSERT(FUN_INTERPRETED(fun));
<                     inner = fun->u.i.script;
< 
<                     /*
<                      * All allocation when decompiling is LIFO, using malloc
<                      * or, more commonly, arena-alloocating from cx->tempPool.
<                      * After InitSprintStack succeeds, we must release to mark
<                      * before returning.
<                      */
<                     mark = JS_ARENA_MARK(&cx->tempPool);
<                     if (!InitSprintStack(cx, &ss2, jp, inner->depth))
<                         return NULL;
<                     ss2.inGenExp = JS_TRUE;
< 
<                     /*
<                      * Recursively decompile this generator function as an
<                      * un-parenthesized generator expression. The ss->inGenExp
<                      * special case of JSOP_YIELD shares array comprehension
<                      * decompilation code that leaves the result as the single
<                      * string pushed on ss2.
<                      */
<                     outer = jp->script;
<                     LOCAL_ASSERT(JS_UPTRDIFF(pc, outer->code) <= outer->length);
<                     jp->script = inner;
<                     if (!Decompile(&ss2, inner->code, inner->length,
<                                    JSOP_NOP)) {
<                         JS_ARENA_RELEASE(&cx->tempPool, mark);
<                         return NULL;
<                     }
<                     jp->script = outer;
< 
<                     /*
<                      * Advance over this op and its global |this| push, and
<                      * arrange to advance over the call to this lambda.
<                      */
<                     pc += len;
<                     LOCAL_ASSERT(*pc == JSOP_GLOBALTHIS);
<                     pc += JSOP_NULL_LENGTH;
<                     LOCAL_ASSERT(*pc == JSOP_CALL);
<                     LOCAL_ASSERT(GET_ARGC(pc) == 0);
<                     len = JSOP_CALL_LENGTH;
< 
<                     /*
<                      * Arrange to parenthesize this genexp unless:
<                      *
<                      *  1. It is the complete expression consumed by a control
<                      *     flow bytecode such as JSOP_TABLESWITCH whose syntax
<                      *     always parenthesizes the controlling expression.
<                      *  2. It is the sole argument to a function call.
<                      *  3. It is the condition of an if statement and not of a
<                      *     ?: expression.
<                      *
<                      * But (first, before anything else) always parenthesize
<                      * if this genexp runs up against endpc and the next op is
<                      * not a while or do-while loop JSOP_IFNE* opcode. In such
<                      * cases, this Decompile activation has been recursively
<                      * called by a comma operator, &&, or || bytecode.
<                      */
<                     LOCAL_ASSERT(pc + len < endpc ||
<                                  endpc < outer->code + outer->length);
<                     LOCAL_ASSERT(ss2.top == 1);
<                     ss2.opcodes[0] = JSOP_POP;
<                     if (pc + len == endpc &&
<                         ((JSOp) *endpc != JSOP_IFNE &&
<                          (JSOp) *endpc != JSOP_IFNEX)) {
<                         op = JSOP_SETNAME;
<                     } else {
<                         op = (JSOp) pc[len];
<                         op = ((js_CodeSpec[op].format & JOF_PARENHEAD) ||
<                               ((js_CodeSpec[op].format & JOF_INVOKE) &&
<                                GET_ARGC(pc + len) == 1) ||
<                               (((op == JSOP_IFEQ || op == JSOP_IFEQX) &&
<                                (sn2 = js_GetSrcNote(outer, pc + len)) &&
<                                SN_TYPE(sn2) != SRC_COND)))
<                              ? JSOP_POP
<                              : JSOP_SETNAME;
< 
<                     /*
<                      * Stack this result as if it's a name, not an anonymous
<                      * function, so it doesn't get decompiled as a generator
<                      * function in a getter or setter context. The precedence
<                      * level is the same for JSOP_NAME and JSOP_ANONFUNOBJ.
<                      */
<                     LOCAL_ASSERT(js_CodeSpec[JSOP_NAME].prec ==
<                                  js_CodeSpec[saveop].prec);
<                     saveop = JSOP_NAME;
<                     }
< 
<                     /*
<                      * Alas, we have to malloc a copy of the result left on
<                      * the top of ss2 because both ss and ss2 arena-allocate
<                      * from cx's tempPool.
<                      */
<                     rval = JS_strdup(cx, PopStr(&ss2, op));
<                     JS_ARENA_RELEASE(&cx->tempPool, mark);
<                     if (!rval)
<                         return NULL;
<                     todo = SprintCString(&ss->sprinter, rval);
<                     JS_free(cx, (void *)rval);
<                     break;
<                 }
< #endif /* JS_HAS_GENERATOR_EXPRS */
<                 /* FALL THROUGH */
< 
<               case JSOP_NAMEDFUNOBJ:
<                 LOAD_FUNCTION(0);
<                 {
<                     uintN indent = JS_DONT_PRETTY_PRINT;
< 
<                     /*
<                      * Always parenthesize expression closures. We can't force
<                      * saveop to a low-precedence op to arrange for auto-magic
<                      * parenthesization without confusing getter/setter code
<                      * that checks for JSOP_ANONFUNOBJ and JSOP_NAMEDFUNOBJ.
<                      */
<                     fun = GET_FUNCTION_PRIVATE(cx, obj);
<                     if (!(fun->flags & JSFUN_EXPR_CLOSURE))
<                         indent |= JS_IN_GROUP_CONTEXT;
<                     str = JS_DecompileFunction(cx, fun, indent);
<                     if (!str)
<                         return NULL;
<                 }
<               sprint_string:
<                 todo = SprintString(&ss->sprinter, str);
<                 break;
< 
<               case JSOP_OBJECT:
<                 LOAD_OBJECT(0);
<                 LOCAL_ASSERT(OBJ_GET_CLASS(cx, obj) == &js_RegExpClass);
<                 goto do_regexp;
< 
<               case JSOP_REGEXP:
<                 GET_REGEXP_FROM_BYTECODE(jp->script, pc, 0, obj);
<               do_regexp:
<                 if (!js_regexp_toString(cx, obj, &val))
<                     return NULL;
<                 str = JSVAL_TO_STRING(val);
<                 goto sprint_string;
< 
<               case JSOP_TABLESWITCH:
<               case JSOP_TABLESWITCHX:
<               {
<                 ptrdiff_t jmplen, off, off2;
<                 jsint j, n, low, high;
<                 TableEntry *table, *tmp;
< 
<                 sn = js_GetSrcNote(jp->script, pc);
<                 LOCAL_ASSERT(sn && SN_TYPE(sn) == SRC_SWITCH);
<                 len = js_GetSrcNoteOffset(sn, 0);
<                 jmplen = (op == JSOP_TABLESWITCH) ? JUMP_OFFSET_LEN
<                                                   : JUMPX_OFFSET_LEN;
<                 pc2 = pc;
<                 off = GetJumpOffset(pc, pc2);
<                 pc2 += jmplen;
<                 low = GET_JUMP_OFFSET(pc2);
<                 pc2 += JUMP_OFFSET_LEN;
<                 high = GET_JUMP_OFFSET(pc2);
<                 pc2 += JUMP_OFFSET_LEN;
< 
<                 n = high - low + 1;
<                 if (n == 0) {
<                     table = NULL;
<                     j = 0;
<                     ok = JS_TRUE;
---
>                     return JS_FALSE;
> 		lval = POP_STR();
> 		todo = Sprint(&ss->sprinter, "%s.%s%s",
> 			      lval, rval,
> 			      js_incop_str[!(cs->format & JOF_INC)]);
> 		break;
> 
> 	      case JSOP_ELEMINC:
> 	      case JSOP_ELEMDEC:
> 		xval = POP_STR();
> 		lval = POP_STR();
> 		todo = Sprint(&ss->sprinter, "%s[%s]%s",
> 			      lval, xval,
> 			      js_incop_str[!(cs->format & JOF_INC)]);
> 		break;
> 
> 	      case JSOP_GETPROP2:
> 		op = JSOP_GETPROP;
> 		(void) PopOff(ss, lastop);
> 		/* FALL THROUGH */
> 
> 	      case JSOP_GETPROP:
> 		atom = GET_ATOM(cx, jp->script, pc);
>                 str = ATOM_TO_STRING(atom);
>                 if (IsASCIIIdentifier(str)) {
>                     lval = POP_STR();
>                     todo = Sprint(&ss->sprinter, "%s.%s",
>                                   lval, JS_GetStringBytes(str));
3902,3979c2268,2270
<                     table = (TableEntry *)
<                             JS_malloc(cx, (size_t)n * sizeof *table);
<                     if (!table)
<                         return NULL;
<                     for (i = j = 0; i < n; i++) {
<                         table[j].label = NULL;
<                         off2 = GetJumpOffset(pc, pc2);
<                         if (off2) {
<                             sn = js_GetSrcNote(jp->script, pc2);
<                             if (sn) {
<                                 LOCAL_ASSERT(SN_TYPE(sn) == SRC_LABEL);
<                                 GET_SOURCE_NOTE_ATOM(sn, table[j].label);
<                             }
<                             table[j].key = INT_TO_JSVAL(low + i);
<                             table[j].offset = off2;
<                             table[j].order = j;
<                             j++;
<                         }
<                         pc2 += jmplen;
<                     }
<                     tmp = (TableEntry *)
<                           JS_malloc(cx, (size_t)j * sizeof *table);
<                     if (tmp) {
<                         ok = js_MergeSort(table, (size_t)j, sizeof(TableEntry),
<                                           CompareOffsets, NULL, tmp);
<                         JS_free(cx, tmp);
<                     } else {
<                         ok = JS_FALSE;
<                     }
<                 }
< 
<                 if (ok) {
<                     ok = DecompileSwitch(ss, table, (uintN)j, pc, len, off,
<                                          JS_FALSE);
<                 }
<                 JS_free(cx, table);
<                 if (!ok)
<                     return NULL;
<                 todo = -2;
<                 break;
<               }
< 
<               case JSOP_LOOKUPSWITCH:
<               case JSOP_LOOKUPSWITCHX:
<               {
<                 ptrdiff_t jmplen, off, off2;
<                 jsatomid npairs, k;
<                 TableEntry *table;
< 
<                 sn = js_GetSrcNote(jp->script, pc);
<                 LOCAL_ASSERT(sn && SN_TYPE(sn) == SRC_SWITCH);
<                 len = js_GetSrcNoteOffset(sn, 0);
<                 jmplen = (op == JSOP_LOOKUPSWITCH) ? JUMP_OFFSET_LEN
<                                                    : JUMPX_OFFSET_LEN;
<                 pc2 = pc;
<                 off = GetJumpOffset(pc, pc2);
<                 pc2 += jmplen;
<                 npairs = GET_UINT16(pc2);
<                 pc2 += UINT16_LEN;
< 
<                 table = (TableEntry *)
<                     JS_malloc(cx, (size_t)npairs * sizeof *table);
<                 if (!table)
<                     return NULL;
<                 for (k = 0; k < npairs; k++) {
<                     sn = js_GetSrcNote(jp->script, pc2);
<                     if (sn) {
<                         LOCAL_ASSERT(SN_TYPE(sn) == SRC_LABEL);
<                         GET_SOURCE_NOTE_ATOM(sn, table[k].label);
<                     } else {
<                         table[k].label = NULL;
<                     }
<                     JS_GET_SCRIPT_ATOM(jp->script, GET_INDEX(pc2), atom);
<                     pc2 += INDEX_LEN;
<                     off2 = GetJumpOffset(pc, pc2);
<                     pc2 += jmplen;
<                     table[k].key = ATOM_KEY(atom);
<                     table[k].offset = off2;
---
>                     xval = QuoteString(&ss->sprinter, str, (jschar)'\'');
>                     lval = POP_STR();
>                     todo = Sprint(&ss->sprinter, "%s[%s]", lval, xval);
3980a2272
> 		break;
3982,4014c2274,2285
<                 ok = DecompileSwitch(ss, table, (uintN)npairs, pc, len, off,
<                                      JS_FALSE);
<                 JS_free(cx, table);
<                 if (!ok)
<                     return NULL;
<                 todo = -2;
<                 break;
<               }
< 
<               case JSOP_CONDSWITCH:
<               {
<                 ptrdiff_t off, off2, caseOff;
<                 jsint ncases;
<                 TableEntry *table;
< 
<                 sn = js_GetSrcNote(jp->script, pc);
<                 LOCAL_ASSERT(sn && SN_TYPE(sn) == SRC_SWITCH);
<                 len = js_GetSrcNoteOffset(sn, 0);
<                 off = js_GetSrcNoteOffset(sn, 1);
< 
<                 /*
<                  * Count the cases using offsets from switch to first case,
<                  * and case to case, stored in srcnote immediates.
<                  */
<                 pc2 = pc;
<                 off2 = off;
<                 for (ncases = 0; off2 != 0; ncases++) {
<                     pc2 += off2;
<                     LOCAL_ASSERT(*pc2 == JSOP_CASE || *pc2 == JSOP_DEFAULT ||
<                                  *pc2 == JSOP_CASEX || *pc2 == JSOP_DEFAULTX);
<                     if (*pc2 == JSOP_DEFAULT || *pc2 == JSOP_DEFAULTX) {
<                         /* End of cases, but count default as a case. */
<                         off2 = 0;
---
> 	      case JSOP_SETPROP:
>                 sn = js_GetSrcNote(jp->script, pc - 1);
>                 atom = GET_ATOM(cx, jp->script, pc);
>                 str = ATOM_TO_STRING(atom);
>                 if (IsASCIIIdentifier(str)) {
>                     rval = POP_STR();
>                     lval = POP_STR();
>                     xval = JS_GetStringBytes(str);
>                     if (sn && SN_TYPE(sn) == SRC_ASSIGNOP) {
>                         todo = Sprint(&ss->sprinter, "%s.%s %s= %s",
>                                       lval, xval,
>                                       js_CodeSpec[lastop].token, rval);
4016,4018c2287,2288
<                         sn = js_GetSrcNote(jp->script, pc2);
<                         LOCAL_ASSERT(sn && SN_TYPE(sn) == SRC_PCDELTA);
<                         off2 = js_GetSrcNoteOffset(sn, 0);
---
>                         todo = Sprint(&ss->sprinter, "%s.%s = %s",
>                                       lval, xval, rval);
4020,4166d2289
<                 }
< 
<                 /*
<                  * Allocate table and rescan the cases using their srcnotes,
<                  * stashing each case's delta from switch top in table[i].key,
<                  * and the distance to its statements in table[i].offset.
<                  */
<                 table = (TableEntry *)
<                     JS_malloc(cx, (size_t)ncases * sizeof *table);
<                 if (!table)
<                     return NULL;
<                 pc2 = pc;
<                 off2 = off;
<                 for (i = 0; i < ncases; i++) {
<                     pc2 += off2;
<                     LOCAL_ASSERT(*pc2 == JSOP_CASE || *pc2 == JSOP_DEFAULT ||
<                                  *pc2 == JSOP_CASEX || *pc2 == JSOP_DEFAULTX);
<                     caseOff = pc2 - pc;
<                     table[i].key = INT_TO_JSVAL((jsint) caseOff);
<                     table[i].offset = caseOff + GetJumpOffset(pc2, pc2);
<                     if (*pc2 == JSOP_CASE || *pc2 == JSOP_CASEX) {
<                         sn = js_GetSrcNote(jp->script, pc2);
<                         LOCAL_ASSERT(sn && SN_TYPE(sn) == SRC_PCDELTA);
<                         off2 = js_GetSrcNoteOffset(sn, 0);
<                     }
<                 }
< 
<                 /*
<                  * Find offset of default code by fetching the default offset
<                  * from the end of table.  JSOP_CONDSWITCH always has a default
<                  * case at the end.
<                  */
<                 off = JSVAL_TO_INT(table[ncases-1].key);
<                 pc2 = pc + off;
<                 off += GetJumpOffset(pc2, pc2);
< 
<                 ok = DecompileSwitch(ss, table, (uintN)ncases, pc, len, off,
<                                      JS_TRUE);
<                 JS_free(cx, table);
<                 if (!ok)
<                     return NULL;
<                 todo = -2;
<                 break;
<               }
< 
<               case JSOP_CASE:
<               case JSOP_CASEX:
<               {
<                 lval = POP_STR();
<                 if (!lval)
<                     return NULL;
<                 js_printf(jp, "\tcase %s:\n", lval);
<                 todo = -2;
<                 break;
<               }
< 
<               case JSOP_STRICTEQ:
<               case JSOP_STRICTNE:
<                 rval = POP_STR();
<                 lval = POP_STR();
<                 todo = Sprint(&ss->sprinter, "%s %c== %s",
<                               lval, (op == JSOP_STRICTEQ) ? '=' : '!', rval);
<                 break;
< 
<               case JSOP_CLOSURE:
<                 LOAD_FUNCTION(0);
<                 todo = -2;
<                 goto do_function;
<                 break;
< 
< #if JS_HAS_EXPORT_IMPORT
<               case JSOP_EXPORTALL:
<                 js_printf(jp, "\texport *;\n");
<                 todo = -2;
<                 break;
< 
<               case JSOP_EXPORTNAME:
<                 LOAD_ATOM(0);
<                 rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
<                 if (!rval)
<                     return NULL;
<                 RETRACT(&ss->sprinter, rval);
<                 js_printf(jp, "\texport %s;\n", rval);
<                 todo = -2;
<                 break;
< 
<               case JSOP_IMPORTALL:
<                 lval = POP_STR();
<                 js_printf(jp, "\timport %s.*;\n", lval);
<                 todo = -2;
<                 break;
< 
<               case JSOP_IMPORTPROP:
<               do_importprop:
<                 GET_ATOM_QUOTE_AND_FMT("\timport %s[%s];\n",
<                                        "\timport %s.%s;\n",
<                                        rval);
<                 lval = POP_STR();
<                 js_printf(jp, fmt, lval, rval);
<                 todo = -2;
<                 break;
< 
<               case JSOP_IMPORTELEM:
<                 xval = POP_STR();
<                 op = JSOP_GETELEM;
<                 if (JOF_OPMODE(lastop) == JOF_XMLNAME)
<                     goto do_importprop;
<                 lval = POP_STR();
<                 js_printf(jp, "\timport %s[%s];\n", lval, xval);
<                 todo = -2;
<                 break;
< #endif /* JS_HAS_EXPORT_IMPORT */
< 
<               case JSOP_TRAP:
<                 op = JS_GetTrapOpcode(cx, jp->script, pc);
<                 if (op == JSOP_LIMIT)
<                     return NULL;
<                 saveop = op;
<                 *pc = op;
<                 cs = &js_CodeSpec[op];
<                 len = cs->length;
<                 DECOMPILE_CODE(pc, len);
<                 *pc = JSOP_TRAP;
<                 todo = -2;
<                 break;
< 
<               case JSOP_NEWINIT:
<               {
<                 i = GET_INT8(pc);
<                 LOCAL_ASSERT(i == JSProto_Array || i == JSProto_Object);
< 
<                 todo = ss->sprinter.offset;
< #if JS_HAS_SHARP_VARS
<                 op = (JSOp)pc[len];
<                 if (op == JSOP_DEFSHARP) {
<                     pc += len;
<                     cs = &js_CodeSpec[op];
<                     len = cs->length;
<                     if (Sprint(&ss->sprinter, "#%u=",
<                                (unsigned) (jsint) GET_UINT16(pc)) < 0)
<                         return NULL;
<                 }
< #endif /* JS_HAS_SHARP_VARS */
<                 if (i == JSProto_Array) {
<                     ++ss->inArrayInit;
<                     if (SprintCString(&ss->sprinter, "[") < 0)
<                         return NULL;
4168,4267c2291,2297
<                     if (SprintCString(&ss->sprinter, "{") < 0)
<                         return NULL;
<                 }
<                 break;
<               }
< 
<               case JSOP_ENDINIT:
<               {
<                 JSBool inArray;
< 
<                 op = JSOP_NOP;           /* turn off parens */
<                 rval = POP_STR();
<                 sn = js_GetSrcNote(jp->script, pc);
< 
<                 /* Skip any #n= prefix to find the opening bracket. */
<                 for (xval = rval; *xval != '[' && *xval != '{'; xval++)
<                     continue;
<                 inArray = (*xval == '[');
<                 if (inArray)
<                     --ss->inArrayInit;
<                 todo = Sprint(&ss->sprinter, "%s%s%c",
<                               rval,
<                               (sn && SN_TYPE(sn) == SRC_CONTINUE) ? ", " : "",
<                               inArray ? ']' : '}');
<                 break;
<               }
< 
<               {
<                 JSBool isFirst;
<                 const char *maybeComma;
< 
<               case JSOP_INITELEM:
<                 /* Turn off most parens (all if there's only one initialiser). */
<                 LOCAL_ASSERT(pc + len < endpc);
<                 isFirst = (ss->opcodes[ss->top - 3] == JSOP_NEWINIT);
<                 op = (isFirst &&
<                       GetStr(ss, ss->top - 2)[0] == '0' &&
<                       (JSOp) pc[len] == JSOP_ENDINIT)
<                      ? JSOP_NOP
<                      : JSOP_SETNAME;
<                 rval = POP_STR();
< 
<                 /* Turn off all parens for xval and lval, which we control. */
<                 op = JSOP_NOP;
<                 xval = POP_STR();
<                 lval = POP_STR();
<                 sn = js_GetSrcNote(jp->script, pc);
< 
<                 if (sn && SN_TYPE(sn) == SRC_INITPROP) {
<                     atom = NULL;
<                     goto do_initprop;
<                 }
<                 maybeComma = isFirst ? "" : ", ";
<                 todo = Sprint(&ss->sprinter, "%s%s%s",
<                               lval,
<                               maybeComma,
<                               rval);
<                 break;
< 
<               case JSOP_INITPROP:
<                 LOAD_ATOM(0);
<                 xval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom),
<                                    (jschar)
<                                    (ATOM_IS_IDENTIFIER(atom) ? 0 : '\''));
<                 if (!xval)
<                     return NULL;
<                 isFirst = (ss->opcodes[ss->top - 2] == JSOP_NEWINIT);
<                 rval = POP_STR();
<                 lval = POP_STR();
<                 /* fall through */
< 
<               do_initprop:
<                 maybeComma = isFirst ? "" : ", ";
< #ifdef OLD_GETTER_SETTER
<                 todo = Sprint(&ss->sprinter, "%s%s%s%s%s%s%s:%s",
<                               lval,
<                               maybeComma,
<                               xval,
<                               (lastop == JSOP_GETTER || lastop == JSOP_SETTER)
<                               ? " " : "",
<                               (lastop == JSOP_GETTER) ? js_getter_str :
<                               (lastop == JSOP_SETTER) ? js_setter_str :
<                               "",
<                               rval);
< #else
<                 if (lastop == JSOP_GETTER || lastop == JSOP_SETTER) {
<                     if (!atom ||
<                         !ATOM_IS_STRING(atom) ||
<                         !ATOM_IS_IDENTIFIER(atom) ||
<                         ATOM_IS_KEYWORD(atom) ||
<                         (ss->opcodes[ss->top+1] != JSOP_ANONFUNOBJ &&
<                          ss->opcodes[ss->top+1] != JSOP_NAMEDFUNOBJ)) {
<                         todo = Sprint(&ss->sprinter, "%s%s%s %s: %s",
<                                       lval,
<                                       maybeComma,
<                                       xval,
<                                       (lastop == JSOP_GETTER) ? js_getter_str :
<                                       (lastop == JSOP_SETTER) ? js_setter_str :
<                                       "",
<                                       rval);
---
>                     xval = QuoteString(&ss->sprinter, str, (jschar)'\'');
>                     rval = POP_STR();
>                     lval = POP_STR();
>                     if (sn && SN_TYPE(sn) == SRC_ASSIGNOP) {
>                         todo = Sprint(&ss->sprinter, "%s[%s] %s= %s",
>                                       lval, xval,
>                                       js_CodeSpec[lastop].token, rval);
4269,4284c2299,2300
<                         const char *end = rval + strlen(rval);
< 
<                         if (*rval == '(')
<                             ++rval, --end;
<                         LOCAL_ASSERT(strncmp(rval, js_function_str, 8) == 0);
<                         LOCAL_ASSERT(rval[8] == ' ');
<                         rval += 8 + 1;
<                         LOCAL_ASSERT(*end ? *end == ')' : end[-1] == '}');
<                         todo = Sprint(&ss->sprinter, "%s%s%s %s%s%.*s",
<                                       lval,
<                                       maybeComma,
<                                       (lastop == JSOP_GETTER)
<                                       ? js_get_str : js_set_str,
<                                       xval,
<                                       (rval[0] != '(') ? " " : "",
<                                       end - rval, rval);
---
>                         todo = Sprint(&ss->sprinter, "%s[%s] = %s",
>                                       lval, xval, rval);
4286,4288d2301
<                 } else {
<                     todo = Sprint(&ss->sprinter, "%s%s%s: %s",
<                                   lval, maybeComma, xval, rval);
4290,4305c2303
< #endif
<                 break;
<               }
< 
< #if JS_HAS_SHARP_VARS
<               case JSOP_DEFSHARP:
<                 i = (jsint) GET_UINT16(pc);
<                 rval = POP_STR();
<                 todo = Sprint(&ss->sprinter, "#%u=%s", (unsigned) i, rval);
<                 break;
< 
<               case JSOP_USESHARP:
<                 i = (jsint) GET_UINT16(pc);
<                 todo = Sprint(&ss->sprinter, "#%u#", (unsigned) i);
<                 break;
< #endif /* JS_HAS_SHARP_VARS */
---
> 		break;
4307,4326c2305,2319
< #if JS_HAS_DEBUGGER_KEYWORD
<               case JSOP_DEBUGGER:
<                 js_printf(jp, "\tdebugger;\n");
<                 todo = -2;
<                 break;
< #endif /* JS_HAS_DEBUGGER_KEYWORD */
< 
< #if JS_HAS_XML_SUPPORT
<               case JSOP_STARTXML:
<               case JSOP_STARTXMLEXPR:
<                 inXML = op == JSOP_STARTXML;
<                 todo = -2;
<                 break;
< 
<               case JSOP_DEFXMLNS:
<                 rval = POP_STR();
<                 js_printf(jp, "\t%s %s %s = %s;\n",
<                           js_default_str, js_xml_str, js_namespace_str, rval);
<                 todo = -2;
<                 break;
---
> 	      case JSOP_GETELEM2:
> 		op = JSOP_GETELEM;
> 		(void) PopOff(ss, lastop);
> 		/* FALL THROUGH */
> 
> 	      case JSOP_GETELEM:
> 		op = JSOP_NOP;           /* turn off parens */
> 		xval = POP_STR();
> 		op = JSOP_GETELEM;
> 		lval = POP_STR();
>                 if (*xval == '\0')
>                     todo = Sprint(&ss->sprinter, "%s", lval);
>                 else
>                     todo = Sprint(&ss->sprinter, "%s[%s]", lval, xval);
> 		break;
4328,4331c2321,2333
<               case JSOP_ANYNAME:
<                 if (pc[JSOP_ANYNAME_LENGTH] == JSOP_TOATTRNAME) {
<                     len += JSOP_TOATTRNAME_LENGTH;
<                     todo = SprintPut(&ss->sprinter, "@*", 2);
---
> 	      case JSOP_SETELEM:
> 		op = JSOP_NOP;           /* turn off parens */
> 		rval = POP_STR();
> 		xval = POP_STR();
> 		op = JSOP_SETELEM;
> 		lval = POP_STR();
>                 if (*xval == '\0')
>                     goto do_setlval;
>                 if ((sn = js_GetSrcNote(jp->script, pc - 1)) != NULL &&
>                     SN_TYPE(sn) == SRC_ASSIGNOP) {
>                     todo = Sprint(&ss->sprinter, "%s[%s] %s= %s",
>                                   lval, xval,
>                                   js_CodeSpec[lastop].token, rval);
4333c2335,2336
<                     todo = SprintPut(&ss->sprinter, "*", 1);
---
>                     todo = Sprint(&ss->sprinter, "%s[%s] = %s",
>                                   lval, xval, rval);
4334a2338,2343
> 		break;
> 
>               case JSOP_ARGSUB:
>                 i = (jsint) GET_ATOM_INDEX(pc);
>                 todo = Sprint(&ss->sprinter, "%s[%d]",
>                               js_arguments_str, (int) i);
4337,4345c2346,2349
<               case JSOP_QNAMEPART:
<                 LOAD_ATOM(0);
<                 if (pc[JSOP_QNAMEPART_LENGTH] == JSOP_TOATTRNAME) {
<                     saveop = JSOP_TOATTRNAME;
<                     len += JSOP_TOATTRNAME_LENGTH;
<                     lval = "@";
<                     goto do_qname;
<                 }
<                 goto do_name;
---
>               case JSOP_ARGCNT:
>                 todo = Sprint(&ss->sprinter, "%s.%s",
>                               js_arguments_str, js_length_str);
>                 break;
4347,4348c2351,2364
<               case JSOP_QNAMECONST:
<                 LOAD_ATOM(0);
---
> 	      case JSOP_GETARG:
> 		atom = GetSlotAtom(jp, js_GetArgument, GET_ARGNO(pc));
> 		LOCAL_ASSERT(atom);
> 		goto do_name;
> 
> 	      case JSOP_GETVAR:
> 		atom = GetSlotAtom(jp, js_GetLocalVariable, GET_VARNO(pc));
> 		LOCAL_ASSERT(atom);
> 		goto do_name;
> 
> 	      case JSOP_NAME:
> 		atom = GET_ATOM(cx, jp->script, pc);
> 	      do_name:
> 		sn = js_GetSrcNote(jp->script, pc);
4351c2367
<                     return NULL;
---
>                     return JS_FALSE;
4353,4367c2369,2370
<                 lval = POP_STR();
<                 todo = Sprint(&ss->sprinter, "%s::%s", lval, rval);
<                 break;
< 
<               case JSOP_QNAME:
<                 rval = POP_STR();
<                 lval = POP_STR();
<                 todo = Sprint(&ss->sprinter, "%s::[%s]", lval, rval);
<                 break;
< 
<               case JSOP_TOATTRNAME:
<                 op = JSOP_NOP;           /* turn off parens */
<                 rval = POP_STR();
<                 todo = Sprint(&ss->sprinter, "@[%s]", rval);
<                 break;
---
> 		todo = Sprint(&ss->sprinter, "%s%s", VarPrefix(sn), rval);
> 		break;
4369,4414c2372,2375
<               case JSOP_TOATTRVAL:
<                 todo = -2;
<                 break;
< 
<               case JSOP_ADDATTRNAME:
<                 rval = POP_STR();
<                 lval = POP_STR();
<                 todo = Sprint(&ss->sprinter, "%s %s", lval, rval);
<                 /* This gets reset by all XML tag expressions. */
<                 quoteAttr = JS_TRUE;
<                 break;
< 
<               case JSOP_ADDATTRVAL:
<                 rval = POP_STR();
<                 lval = POP_STR();
<                 if (quoteAttr)
<                     todo = Sprint(&ss->sprinter, "%s=\"%s\"", lval, rval);
<                 else
<                     todo = Sprint(&ss->sprinter, "%s=%s", lval, rval);
<                 break;
< 
<               case JSOP_BINDXMLNAME:
<                 /* Leave the name stacked and push a dummy string. */
<                 todo = Sprint(&ss->sprinter, "");
<                 break;
< 
<               case JSOP_SETXMLNAME:
<                 /* Pop the r.h.s., the dummy string, and the name. */
<                 rval = POP_STR();
<                 (void) PopOff(ss, op);
<                 lval = POP_STR();
<                 goto do_setlval;
< 
<               case JSOP_XMLELTEXPR:
<               case JSOP_XMLTAGEXPR:
<                 todo = Sprint(&ss->sprinter, "{%s}", POP_STR());
<                 inXML = JS_TRUE;
<                 /* If we're an attribute value, we shouldn't quote this. */
<                 quoteAttr = JS_FALSE;
<                 break;
< 
<               case JSOP_TOXMLLIST:
<                 op = JSOP_NOP;           /* turn off parens */
<                 todo = Sprint(&ss->sprinter, "<>%s</>", POP_STR());
<                 inXML = JS_FALSE;
<                 break;
---
> 	      case JSOP_UINT16:
> 		i = (jsint) GET_ATOM_INDEX(pc);
> 		todo = Sprint(&ss->sprinter, "%u", (unsigned) i);
> 		break;
4416,4418c2377,2392
<               case JSOP_FOREACH:
<                 foreach = JS_TRUE;
<                 todo = -2;
---
>               case JSOP_NUMBER:
>                 atom = GET_ATOM(cx, jp->script, pc);
>                 val = ATOM_KEY(atom);
>                 if (JSVAL_IS_INT(val)) {
>                     long ival = (long)JSVAL_TO_INT(val);
>                     todo = Sprint(&ss->sprinter, "%ld", ival);
>                 } else {
>                     char buf[DTOSTR_STANDARD_BUFFER_SIZE];
>                     char *numStr = JS_dtostr(buf, sizeof buf, DTOSTR_STANDARD,
>                                              0, *JSVAL_TO_DOUBLE(val));
>                     if (!numStr) {
>                         JS_ReportOutOfMemory(cx);
>                         return JS_FALSE;
>                     }
>                     todo = Sprint(&ss->sprinter, numStr);
>                 }
4421,4427c2395,2401
<               case JSOP_TOXML:
<               case JSOP_CALLXMLNAME:
<               case JSOP_XMLNAME:
<               case JSOP_FILTER:
<                 /* These ops indicate the end of XML expressions. */
<                 inXML = JS_FALSE;
<                 todo = -2;
---
>               case JSOP_STRING:
>                 atom = GET_ATOM(cx, jp->script, pc);
>                 rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom),
>                                    (jschar)'"');
>                 if (!rval)
>                     return JS_FALSE;
>                 todo = STR2OFF(&ss->sprinter, rval);
4430,4433c2404,2421
<               case JSOP_ENDFILTER:
<                 rval = POP_STR();
<                 lval = POP_STR();
<                 todo = Sprint(&ss->sprinter, "%s.(%s)", lval, rval);
---
>               case JSOP_OBJECT:
>               case JSOP_ANONFUNOBJ:
>               case JSOP_NAMEDFUNOBJ:
>                 atom = GET_ATOM(cx, jp->script, pc);
>                 if (op == JSOP_OBJECT) {
>                     str = js_ValueToSource(cx, ATOM_KEY(atom));
>                     if (!str)
>                         return JS_FALSE;
>                 } else {
>                     if (!js_fun_toString(cx, ATOM_TO_OBJECT(atom),
>                                          JS_DONT_PRETTY_PRINT, 0, NULL,
>                                          &val)) {
>                         return JS_FALSE;
>                     }
>                     str = JSVAL_TO_STRING(val);
>                 }
>                 todo = SprintPut(&ss->sprinter, JS_GetStringBytes(str),
>                                  JSSTRING_LENGTH(str));
4436,4440c2424,2441
<               case JSOP_DESCENDANTS:
<                 rval = POP_STR();
<                 lval = POP_STR();
<                 todo = Sprint(&ss->sprinter, "%s..%s", lval, rval);
<                 break;
---
> #if JS_HAS_SWITCH_STATEMENT
> 	      case JSOP_TABLESWITCH:
> 	      case JSOP_TABLESWITCHX:
> 	      {
> 		jsbytecode *pc2;
> 		ptrdiff_t off, off2;
> 		jsint j, n, low, high;
> 		TableEntry *table;
> 
> 		sn = js_GetSrcNote(jp->script, pc);
> 		JS_ASSERT(sn && SN_TYPE(sn) == SRC_SWITCH);
> 		len = js_GetSrcNoteOffset(sn, 0);
> 		pc2 = pc;
> 		off = GetJumpOffset(pc, pc2);
> 		pc2 += JUMP_OFFSET_LEN;
> 		low = GetJumpOffset(pc, pc2);
> 		pc2 += JUMP_OFFSET_LEN;
> 		high = GetJumpOffset(pc, pc2);
4442,4445c2443,2624
<               case JSOP_XMLOBJECT:
<                 LOAD_OBJECT(0);
<                 todo = Sprint(&ss->sprinter, "<xml address='%p'>", obj);
<                 break;
---
> 		n = high - low + 1;
>                 if (n == 0) {
>                     table = NULL;
> 		    j = 0;
>                 } else {
>                 	XMEMTAG("jsopcode TableEntry");
>                     table = (TableEntry *)
>                             JS_malloc(cx, (size_t)n * sizeof *table);
>                     if (!table)
>                         return JS_FALSE;
> 		    for (i = j = 0; i < n; i++) {
> 			pc2 += JUMP_OFFSET_LEN;
> 			off2 = GetJumpOffset(pc, pc2);
> 			if (off2) {
> 			    table[j].key = INT_TO_JSVAL(low + i);
> 			    table[j++].offset = off2;
> 			}
> 		    }
>                     js_HeapSort(table, (size_t) j, sizeof *table,
>                                 CompareOffsets, NULL);
> 		}
> 
> 		ok = DecompileSwitch(ss, table, (uintN)j, pc, len, off,
> 				     JS_FALSE);
> 		JS_free(cx, table);
> 		if (!ok)
> 		    return ok;
> 		todo = -2;
> 		break;
> 	      }
> 
> 	      case JSOP_LOOKUPSWITCH:
> 	      case JSOP_LOOKUPSWITCHX:
> 	      {
> 		jsbytecode *pc2;
> 		ptrdiff_t off, off2;
> 		jsint npairs;
> 		TableEntry *table;
> 
> 		sn = js_GetSrcNote(jp->script, pc);
> 		JS_ASSERT(sn && SN_TYPE(sn) == SRC_SWITCH);
> 		len = js_GetSrcNoteOffset(sn, 0);
> 		pc2 = pc;
> 		off = GetJumpOffset(pc, pc2);
> 		pc2 += JUMP_OFFSET_LEN;
> 		npairs = (jsint) GET_ATOM_INDEX(pc2);
> 		pc2 += ATOM_INDEX_LEN;
> 		
> 		XMEMTAG("jsopcode TableEntry");
> 		table = (TableEntry *)
>                     JS_malloc(cx, (size_t)npairs * sizeof *table);
> 		if (!table)
> 		    return JS_FALSE;
> 		for (i = 0; i < npairs; i++) {
> 		    atom = GET_ATOM(cx, jp->script, pc2);
> 		    pc2 += ATOM_INDEX_LEN;
> 		    off2 = GetJumpOffset(pc, pc2);
> 		    pc2 += JUMP_OFFSET_LEN;
> 		    table[i].key = ATOM_KEY(atom);
> 		    table[i].offset = off2;
> 		}
> 
> 		ok = DecompileSwitch(ss, table, (uintN)npairs, pc, len, off,
> 				     JS_FALSE);
> 		JS_free(cx, table);
> 		if (!ok)
> 		    return ok;
> 		todo = -2;
> 		break;
> 	      }
> 
> 	      case JSOP_CONDSWITCH:
> 	      {
> 		jsbytecode *pc2;
> 		ptrdiff_t off, off2, caseOff;
> 		jsint ncases;
> 		TableEntry *table;
> 
> 		sn = js_GetSrcNote(jp->script, pc);
> 		JS_ASSERT(sn && SN_TYPE(sn) == SRC_SWITCH);
> 		len = js_GetSrcNoteOffset(sn, 0);
> 		off = js_GetSrcNoteOffset(sn, 1);
> 
> 		/*
> 		 * Count the cases using offsets from switch to first case,
> 		 * and case to case, stored in srcnote immediates.
> 		 */
> 		pc2 = pc;
> 		off2 = off;
> 		for (ncases = 0; off2 != 0; ncases++) {
> 		    pc2 += off2;
> 		    JS_ASSERT(*pc2 == JSOP_CASE || *pc2 == JSOP_DEFAULT ||
>                               *pc2 == JSOP_CASEX || *pc2 == JSOP_DEFAULTX);
> 		    if (*pc2 == JSOP_DEFAULT || *pc2 == JSOP_DEFAULTX) {
> 			/* End of cases, but count default as a case. */
> 			off2 = 0;
> 		    } else {
> 			sn = js_GetSrcNote(jp->script, pc2);
> 			JS_ASSERT(sn && SN_TYPE(sn) == SRC_PCDELTA);
> 			off2 = js_GetSrcNoteOffset(sn, 0);
> 		    }
> 		}
> 
> 		/*
> 		 * Allocate table and rescan the cases using their srcnotes,
> 		 * stashing each case's delta from switch top in table[i].key,
> 		 * and the distance to its statements in table[i].offset.
> 		 */
> 		XMEMTAG("jsopcode TableEntry");
> 		table = (TableEntry *)
>                     JS_malloc(cx, (size_t)ncases * sizeof *table);
> 		if (!table)
> 		    return JS_FALSE;
> 		pc2 = pc;
> 		off2 = off;
> 		for (i = 0; i < ncases; i++) {
> 		    pc2 += off2;
> 		    JS_ASSERT(*pc2 == JSOP_CASE || *pc2 == JSOP_DEFAULT ||
>                               *pc2 == JSOP_CASEX || *pc2 == JSOP_DEFAULTX);
> 		    caseOff = pc2 - pc;
> 		    table[i].key = INT_TO_JSVAL((jsint) caseOff);
> 		    table[i].offset = caseOff + GetJumpOffset(pc2, pc2);
> 		    if (*pc2 == JSOP_CASE || *pc2 == JSOP_CASEX) {
> 			sn = js_GetSrcNote(jp->script, pc2);
> 			JS_ASSERT(sn && SN_TYPE(sn) == SRC_PCDELTA);
> 			off2 = js_GetSrcNoteOffset(sn, 0);
> 		    }
> 		}
> 
> 		/*
> 		 * Find offset of default code by fetching the default offset
> 		 * from the end of table.  JSOP_CONDSWITCH always has a default
> 		 * case at the end.
> 		 */
> 		off = JSVAL_TO_INT(table[ncases-1].key);
> 		pc2 = pc + off;
> 		off += GetJumpOffset(pc2, pc2);
> 
> 		ok = DecompileSwitch(ss, table, (uintN)ncases, pc, len, off,
> 				     JS_TRUE);
> 		JS_free(cx, table);
> 		if (!ok)
> 		    return ok;
> 		todo = -2;
> 		break;
> 	      }
> 
> 	      case JSOP_CASE:
> 	      case JSOP_CASEX:
> 	      {
> 		lval = POP_STR();
> 		if (!lval)
> 		    return JS_FALSE;
> 		js_printf(jp, "\tcase %s:\n", lval);
> 		todo = -2;
> 		break;
> 	      }
> 
> #endif /* JS_HAS_SWITCH_STATEMENT */
> 
> #if !JS_BUG_FALLIBLE_EQOPS
> 	      case JSOP_NEW_EQ:
> 	      case JSOP_NEW_NE:
> 		rval = POP_STR();
> 		lval = POP_STR();
> 		todo = Sprint(&ss->sprinter, "%s %c%s %s",
> 			      lval,
> 			      (op == JSOP_NEW_EQ) ? '=' : '!',
> #if JS_HAS_TRIPLE_EQOPS
> 			      JSVERSION_IS_ECMA(cx->version) ? "==" :
> #endif
> 			      "=",
> 			      rval);
> 		break;
> #endif /* !JS_BUG_FALLIBLE_EQOPS */
> 
> #if JS_HAS_LEXICAL_CLOSURE
> 	      case JSOP_CLOSURE:
> 		atom = GET_ATOM(cx, jp->script, pc);
> 		JS_ASSERT(ATOM_IS_OBJECT(atom));
>                 goto do_function;
> #endif /* JS_HAS_LEXICAL_CLOSURE */
4447,4454c2626,2630
<               case JSOP_XMLCDATA:
<                 LOAD_ATOM(0);
<                 todo = SprintPut(&ss->sprinter, "<![CDATA[", 9);
<                 if (!QuoteString(&ss->sprinter, ATOM_TO_STRING(atom),
<                                  DONT_ESCAPE))
<                     return NULL;
<                 SprintPut(&ss->sprinter, "]]>", 3);
<                 break;
---
> #if JS_HAS_EXPORT_IMPORT
> 	      case JSOP_EXPORTALL:
> 		js_printf(jp, "\texport *\n");
> 		todo = -2;
> 		break;
4456,4463c2632,2646
<               case JSOP_XMLCOMMENT:
<                 LOAD_ATOM(0);
<                 todo = SprintPut(&ss->sprinter, "<!--", 4);
<                 if (!QuoteString(&ss->sprinter, ATOM_TO_STRING(atom),
<                                  DONT_ESCAPE))
<                     return NULL;
<                 SprintPut(&ss->sprinter, "-->", 3);
<                 break;
---
> 	      case JSOP_EXPORTNAME:
> 		atom = GET_ATOM(cx, jp->script, pc);
>                 rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
>                 if (!rval)
>                     return JS_FALSE;
>                 RETRACT(&ss->sprinter, rval);
>                 js_printf(jp, "\texport %s\n", rval);
> 		todo = -2;
> 		break;
> 
> 	      case JSOP_IMPORTALL:
> 		lval = POP_STR();
> 		js_printf(jp, "\timport %s.*\n", lval);
> 		todo = -2;
> 		break;
4465,4467c2648,2650
<               case JSOP_XMLPI:
<                 LOAD_ATOM(0);
<                 rval = JS_strdup(cx, POP_STR());
---
> 	      case JSOP_IMPORTPROP:
> 		atom = GET_ATOM(cx, jp->script, pc);
>                 rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
4469,4479c2652,2665
<                     return NULL;
<                 todo = SprintPut(&ss->sprinter, "<?", 2);
<                 ok = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0) &&
<                      (*rval == '\0' ||
<                       (SprintPut(&ss->sprinter, " ", 1) >= 0 &&
<                        SprintCString(&ss->sprinter, rval)));
<                 JS_free(cx, (char *)rval);
<                 if (!ok)
<                     return NULL;
<                 SprintPut(&ss->sprinter, "?>", 2);
<                 break;
---
>                     return JS_FALSE;
> 		lval = POP_STR();
>                 js_printf(jp, "\timport %s.%s\n", lval, rval);
> 		todo = -2;
> 		break;
> 
> 	      case JSOP_IMPORTELEM:
> 		xval = POP_STR();
> 		op = JSOP_GETELEM;
> 		lval = POP_STR();
> 		js_printf(jp, "\timport %s[%s]\n", lval, xval);
> 		todo = -2;
> 		break;
> #endif /* JS_HAS_EXPORT_IMPORT */
4481,4484c2667,2747
<               case JSOP_GETFUNNS:
<                 todo = SprintPut(&ss->sprinter, js_function_str, 8);
<                 break;
< #endif /* JS_HAS_XML_SUPPORT */
---
> 	      case JSOP_TRAP:
> 		op = JS_GetTrapOpcode(cx, jp->script, pc);
> 		if (op == JSOP_LIMIT)
> 		    return JS_FALSE;
> 		*pc = op;
> 		cs = &js_CodeSpec[op];
> 		len = cs->length;
> 		DECOMPILE_CODE(pc, len);
> 		*pc = JSOP_TRAP;
> 		todo = -2;
> 		break;
> 
> #if JS_HAS_INITIALIZERS
> 	      case JSOP_NEWINIT:
> 		LOCAL_ASSERT(ss->top >= 2);
> 		(void) PopOff(ss, op);
> 		lval = POP_STR();
> #if JS_HAS_SHARP_VARS
> 		op = (JSOp)pc[len];
> 		if (op == JSOP_DEFSHARP) {
> 		    pc += len;
> 		    cs = &js_CodeSpec[op];
> 		    len = cs->length;
> 		    i = (jsint) GET_ATOM_INDEX(pc);
> 		    todo = Sprint(&ss->sprinter, "#%u=%c",
> 				  (unsigned) i,
> 				  (*lval == 'O') ? '{' : '[');
> 		} else
> #endif /* JS_HAS_SHARP_VARS */
> 		{
> 		    todo = Sprint(&ss->sprinter, (*lval == 'O') ? "{" : "[");
> 		}
> 		break;
> 
> 	      case JSOP_ENDINIT:
> 		rval = POP_STR();
> 		sn = js_GetSrcNote(jp->script, pc);
> 		todo = Sprint(&ss->sprinter, "%s%s%c",
> 			      rval,
> 			      (sn && SN_TYPE(sn) == SRC_CONTINUE) ? ", " : "",
> 			      (*rval == '{') ? '}' : ']');
> 		break;
> 
> 	      case JSOP_INITPROP:
>               case JSOP_INITCATCHVAR:
> 		atom = GET_ATOM(cx, jp->script, pc);
>                 xval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
>                 if (!xval)
>                     return JS_FALSE;
> 		rval = POP_STR();
> 		lval = POP_STR();
> 	      do_initprop:
> #ifdef OLD_GETTER_SETTER
>                 todo = Sprint(&ss->sprinter, "%s%s%s%s%s:%s",
>                               lval,
>                               (lval[1] != '\0') ? ", " : "",
>                               xval,
>                               (lastop == JSOP_GETTER || lastop == JSOP_SETTER)
>                               ? " " : "",
>                               (lastop == JSOP_GETTER) ? js_getter_str :
>                               (lastop == JSOP_SETTER) ? js_setter_str :
>                               "",
>                               rval);
> #else
>                 if (lastop == JSOP_GETTER || lastop == JSOP_SETTER) {
>                     todo = Sprint(&ss->sprinter, "%s%s%s %s%s",
>                                   lval,
>                                   (lval[1] != '\0') ? ", " : "",
>                                   (lastop == JSOP_GETTER)
>                                   ? js_get_str : js_set_str,
>                                   xval,
>                                   rval + strlen(js_function_str) + 1);
>                 } else {
>                     todo = Sprint(&ss->sprinter, "%s%s%s:%s",
>                                   lval,
>                                   (lval[1] != '\0') ? ", " : "",
>                                   xval,
>                                   rval);
>                 }
> #endif
> 		break;
4486,4490c2749,2760
<               default:
<                 todo = -2;
<                 break;
<             }
<         }
---
> 	      case JSOP_INITELEM:
> 		rval = POP_STR();
> 		xval = POP_STR();
> 		lval = POP_STR();
> 		sn = js_GetSrcNote(jp->script, pc);
> 		if (sn && SN_TYPE(sn) == SRC_LABEL)
> 		    goto do_initprop;
> 		todo = Sprint(&ss->sprinter, "%s%s%s",
> 			      lval,
> 			      (lval[1] != '\0' || *xval != '0') ? ", " : "",
> 			      rval);
> 		break;
4492,4499c2762,2774
<         if (todo < 0) {
<             /* -2 means "don't push", -1 means reported error. */
<             if (todo == -1)
<                 return NULL;
<         } else {
<             if (!PushOff(ss, todo, saveop))
<                 return NULL;
<         }
---
> #if JS_HAS_SHARP_VARS
> 	      case JSOP_DEFSHARP:
> 		i = (jsint) GET_ATOM_INDEX(pc);
> 		rval = POP_STR();
> 		todo = Sprint(&ss->sprinter, "#%u=%s", (unsigned) i, rval);
> 		break;
> 
> 	      case JSOP_USESHARP:
> 		i = (jsint) GET_ATOM_INDEX(pc);
> 		todo = Sprint(&ss->sprinter, "#%u#", (unsigned) i);
> 		break;
> #endif /* JS_HAS_SHARP_VARS */
> #endif /* JS_HAS_INITIALIZERS */
4501,4505c2776,2781
<         if (cs->format & JOF_CALLOP) {
<             todo = Sprint(&ss->sprinter, "");
<             if (todo < 0 || !PushOff(ss, todo, saveop))
<                 return NULL;
<         }
---
> #if JS_HAS_DEBUGGER_KEYWORD
> 	      case JSOP_DEBUGGER:
> 		js_printf(jp, "\tdebugger;\n");
> 		todo = -2;
> 		break;
> #endif /* JS_HAS_DEBUGGER_KEYWORD */
4507c2783,2797
<         pc += len;
---
> 	      default:
> 		todo = -2;
> 		break;
> 	    }
> 	}
> 
> 	if (todo < 0) {
> 	    /* -2 means "don't push", -1 means reported error. */
> 	    if (todo == -1)
> 		return JS_FALSE;
> 	} else {
> 	    if (!PushOff(ss, todo, op))
> 		return JS_FALSE;
> 	}
> 	pc += len;
4513d2802
< #undef inXML
4515d2803
< #undef NEXT_OP
4518,4520d2805
< #undef ATOM_IS_IDENTIFIER
< #undef GET_QUOTE_AND_FMT
< #undef GET_ATOM_QUOTE_AND_FMT
4522c2807
<     return pc;
---
>     return JS_TRUE;
4524a2810
> 
4526,4527c2812
< js_DecompileCode(JSPrinter *jp, JSScript *script, jsbytecode *pc, uintN len,
<                  uintN pcdepth)
---
> js_DecompileCode(JSPrinter *jp, JSScript *script, jsbytecode *pc, uintN len)
4529d2813
<     uintN depth, i;
4532c2816,2817
<     void *mark;
---
>     void *mark, *space;
>     size_t offsetsz, opcodesz;
4537,4539d2821
<     depth = script->depth;
<     JS_ASSERT(pcdepth <= depth);
< 
4540a2823
>     ss.printer = jp;
4543,4545c2826
<     ok = InitSprintStack(cx, &ss, jp, depth);
<     if (!ok)
<         goto out;
---
>     INIT_SPRINTER(cx, &ss.sprinter, &cx->tempPool, PAREN_SLOP);
4547,4582c2828,2834
<     /*
<      * If we are called from js_DecompileValueGenerator with a portion of
<      * script's bytecode that starts with a non-zero model stack depth given
<      * by pcdepth, attempt to initialize the missing string offsets in ss to
<      * |spindex| negative indexes from fp->sp for the activation fp in which
<      * the error arose.
<      *
<      * See js_DecompileValueGenerator for how its |spindex| parameter is used,
<      * and see also GetOff, which makes use of the ss.offsets[i] < -1 that are
<      * potentially stored below.
<      */
<     ss.top = pcdepth;
<     if (pcdepth != 0) {
<         JSStackFrame *fp;
<         ptrdiff_t top;
< 
<         for (fp = cx->fp; fp && !fp->script; fp = fp->down)
<             continue;
<         top = fp ? fp->sp - fp->spbase : 0;
<         for (i = 0; i < pcdepth; i++) {
<             ss.offsets[i] = -1;
<             ss.opcodes[i] = JSOP_NOP;
<         }
<         if (fp && fp->pc == pc && (uintN)top == pcdepth) {
<             for (i = 0; i < pcdepth; i++) {
<                 ptrdiff_t off;
<                 jsbytecode *genpc;
< 
<                 off = (intN)i - (intN)depth;
<                 genpc = (jsbytecode *) fp->spbase[off];
<                 if (JS_UPTRDIFF(genpc, script->code) < script->length) {
<                     ss.offsets[i] += (ptrdiff_t)i - top;
<                     ss.opcodes[i] = *genpc;
<                 }
<             }
<         }
---
>     /* Allocate the parallel (to avoid padding) offset and opcode stacks. */
>     offsetsz = script->depth * sizeof(ptrdiff_t);
>     opcodesz = script->depth * sizeof(jsbytecode);
>     JS_ARENA_ALLOCATE(space, &cx->tempPool, offsetsz + opcodesz);
>     if (!space) {
> 	ok = JS_FALSE;
>         goto out;
4583a2836,2838
>     ss.offsets = (ptrdiff_t *) space;
>     ss.opcodes = (jsbytecode *) ((char *)space + offsetsz);
>     ss.top = 0;
4588c2843
<     ok = Decompile(&ss, pc, len, JSOP_NOP) != NULL;
---
>     ok = Decompile(&ss, pc, len);
4593,4596c2848,2851
<         do {
<             last = OFF2STR(&ss.sprinter, PopOff(&ss, JSOP_POP));
<         } while (ss.top > pcdepth);
<         js_printf(jp, "%s", last);
---
> 	do {
> 	    last = OFF2STR(&ss.sprinter, PopOff(&ss, JSOP_NOP));
> 	} while (ss.top);
> 	js_printf(jp, "%s", last);
4608c2863
<     return js_DecompileCode(jp, script, script->code, (uintN)script->length, 0);
---
>     return js_DecompileCode(jp, script, script->code, (uintN)script->length);
4614c2869
< js_DecompileFunctionBody(JSPrinter *jp)
---
> js_DecompileFunctionBody(JSPrinter *jp, JSFunction *fun)
4616a2872,2873
>     JSScope *scope, *save;
>     JSBool ok;
4618,4621c2875,2877
<     JS_ASSERT(jp->fun);
<     JS_ASSERT(!jp->script);
<     if (!FUN_INTERPRETED(jp->fun)) {
<         js_printf(jp, native_code_str);
---
>     script = fun->script;
>     if (!script) {
> 	js_printf(jp, native_code_str);
4624,4626c2880,2885
< 
<     script = jp->fun->u.i.script;
<     return js_DecompileCode(jp, script, script->code, (uintN)script->length, 0);
---
>     scope = fun->object ? OBJ_SCOPE(fun->object) : NULL;
>     save = jp->scope;
>     jp->scope = scope;
>     ok = js_DecompileCode(jp, script, script->code, (uintN)script->length);
>     jp->scope = save;
>     return ok;
4630c2889
< js_DecompileFunction(JSPrinter *jp)
---
> js_DecompileFunction(JSPrinter *jp, JSFunction *fun)
4632,4636c2891,2907
<     JSFunction *fun;
<     uintN i;
<     JSAtom *param;
<     jsbytecode *pc, *endpc;
<     ptrdiff_t len;
---
> 	// !!DP 2004.01.20 jht: Protect JS source, return [function %name]
> 	#if 1
>     js_printf(jp, "[%s ", js_function_str);
>     if (fun->atom && !QuoteString(&jp->sprinter, ATOM_TO_STRING(fun->atom), 0))
>         return JS_FALSE;
>     #ifdef DEBUG
>     js_printf(jp, " 0x%lx]", fun);	// Include function address for debugging
>    	#else
>     js_printf(jp, "]");
>     #endif
> 	#else
>     JSContext *cx;
>     uintN i, nargs, indent;
>     void *mark;
>     JSAtom **params;
>     JSScope *scope, *oldscope;
>     JSScopeProperty *sprop;
4639,4642d2909
<     fun = jp->fun;
<     JS_ASSERT(fun);
<     JS_ASSERT(!jp->script);
< 
4648a2916
>         js_puts(jp, "\n");
4651c2919
<         if (!jp->grouped && (fun->flags & JSFUN_LAMBDA))
---
>         if (fun->flags & JSFUN_LAMBDA)
4654c2922
<     if (JSFUN_GETTER_TEST(fun->flags))
---
>     if (fun->flags & JSFUN_GETTER)
4656c2924
<     else if (JSFUN_SETTER_TEST(fun->flags))
---
>     else if (fun->flags & JSFUN_SETTER)
4664,4691c2932,2961
<     if (!FUN_INTERPRETED(fun)) {
<         js_printf(jp, ") {\n");
<         jp->indent += 4;
<         js_printf(jp, native_code_str);
<         jp->indent -= 4;
<         js_printf(jp, "\t}");
<     } else {
< #ifdef JS_HAS_DESTRUCTURING
<         SprintStack ss;
<         void *mark;
< #endif
< 
<         /* Print the parameters. */
<         pc = fun->u.i.script->main;
<         endpc = pc + fun->u.i.script->length;
<         ok = JS_TRUE;
< 
< #ifdef JS_HAS_DESTRUCTURING
<         /* Skip JSOP_GENERATOR in case of destructuring parameters. */
<         if (*pc == JSOP_GENERATOR)
<             pc += JSOP_GENERATOR_LENGTH;
< 
<         ss.printer = NULL;
<         jp->script = fun->u.i.script;
<         mark = JS_ARENA_MARK(&jp->sprinter.context->tempPool);
< #endif
< 
<         for (i = 0; i < fun->nargs; i++) {
---
>     if (fun->script && fun->object) {
>         /*
>          * Print the parameters.
>          *
>          * This code is complicated by the need to handle duplicate parameter
>          * names, as required by ECMA (bah!).  A duplicate parameter is stored
>          * as another node with the same id (the parameter name) but different
>          * shortid (the argument index) along the property tree ancestor line
>          * starting at SCOPE_LAST_PROP(scope).  Only the last duplicate param
>          * is mapped by the scope's hash table.
>          */
>         cx = jp->sprinter.context;
>         nargs = fun->nargs;
>         mark = JS_ARENA_MARK(&cx->tempPool);
>         JS_ARENA_ALLOCATE_CAST(params, JSAtom **, &cx->tempPool,
>                                nargs * sizeof(JSAtom *));
>         if (!params) {
>             JS_ReportOutOfMemory(cx);
>             return JS_FALSE;
>         }
>         scope = OBJ_SCOPE(fun->object);
>         for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) {
>             if (sprop->getter != js_GetArgument)
>                 continue;
>             JS_ASSERT(sprop->flags & SPROP_HAS_SHORTID);
>             JS_ASSERT((uintN) sprop->shortid < nargs);
>             JS_ASSERT(!JSVAL_IS_INT(sprop->id));
>             params[(uintN) sprop->shortid] = (JSAtom *) sprop->id;
>         }
>         for (i = 0; i < nargs; i++) {
4694,4735c2964,2965
< 
<             param = GetSlotAtom(jp, JS_TRUE, i);
< 
< #if JS_HAS_DESTRUCTURING
< #define LOCAL_ASSERT(expr)      LOCAL_ASSERT_RV(expr, JS_FALSE)
< 
<             if (!param) {
<                 ptrdiff_t todo;
<                 const char *lval;
< 
<                 LOCAL_ASSERT(*pc == JSOP_GETARG);
<                 pc += JSOP_GETARG_LENGTH;
<                 LOCAL_ASSERT(*pc == JSOP_DUP);
<                 if (!ss.printer) {
<                     ok = InitSprintStack(jp->sprinter.context, &ss, jp,
<                                          fun->u.i.script->depth);
<                     if (!ok)
<                         break;
<                 }
<                 pc = DecompileDestructuring(&ss, pc, endpc);
<                 if (!pc) {
<                     ok = JS_FALSE;
<                     break;
<                 }
<                 LOCAL_ASSERT(*pc == JSOP_POP);
<                 pc += JSOP_POP_LENGTH;
<                 lval = PopStr(&ss, JSOP_NOP);
<                 todo = SprintCString(&jp->sprinter, lval);
<                 if (todo < 0) {
<                     ok = JS_FALSE;
<                     break;
<                 }
<                 continue;
<             }
< 
< #undef LOCAL_ASSERT
< #endif
< 
<             if (!QuoteString(&jp->sprinter, ATOM_TO_STRING(param), 0)) {
<                 ok = JS_FALSE;
<                 break;
<             }
---
>             if (!QuoteString(&jp->sprinter, ATOM_TO_STRING(params[i]), 0))
>                 return JS_FALSE;
4737,4740c2967,2970
< 
< #ifdef JS_HAS_DESTRUCTURING
<         jp->script = NULL;
<         JS_ARENA_RELEASE(&jp->sprinter.context->tempPool, mark);
---
>         JS_ARENA_RELEASE(&cx->tempPool, mark);
> #ifdef __GNUC__
>     } else {
>         scope = NULL;
4742,4759d2971
<         if (!ok)
<             return JS_FALSE;
<         if (fun->flags & JSFUN_EXPR_CLOSURE) {
<             js_printf(jp, ") ");
<         } else {
<             js_printf(jp, ") {\n");
<             jp->indent += 4;
<         }
< 
<         len = fun->u.i.script->code + fun->u.i.script->length - pc;
<         ok = js_DecompileCode(jp, fun->u.i.script, pc, (uintN)len, 0);
<         if (!ok)
<             return JS_FALSE;
< 
<         if (!(fun->flags & JSFUN_EXPR_CLOSURE)) {
<             jp->indent -= 4;
<             js_printf(jp, "\t}");
<         }
4762,4763c2974,2990
<     if (!jp->pretty && !jp->grouped && (fun->flags & JSFUN_LAMBDA))
<         js_puts(jp, ")");
---
>     js_printf(jp, ") {\n");
>     indent = jp->indent;
>     jp->indent += 4;
>     if (fun->script && fun->object) {
> 	oldscope = jp->scope;
> 	jp->scope = scope;
> 	ok = js_DecompileScript(jp, fun->script);
> 	jp->scope = oldscope;
> 	if (!ok) {
> 	    jp->indent = indent;
> 	    return JS_FALSE;
> 	}
>     } else {
> 	js_printf(jp, native_code_str);
>     }
>     jp->indent -= 4;
>     js_printf(jp, "\t}");
4764a2992,2998
>     if (jp->pretty) {
>         js_puts(jp, "\n");
>     } else {
>         if (fun->flags & JSFUN_LAMBDA)
>             js_puts(jp, ")");
>     }
>     #endif
4768,4770c3002
< #undef LOCAL_ASSERT_RV
< 
< char *
---
> JSString *
4772c3004
<                            JSString *fallback)
---
> 			   JSString *fallback)
4775,4777c3007,3008
<     jsbytecode *pc, *begin, *end;
<     jsval *sp, *spbase, *base, *limit;
<     intN depth, pcdepth;
---
>     jsbytecode *pc, *begin, *end, *tmp;
>     jsval *sp, *base, *limit;
4780c3011,3013
<     const JSCodeSpec *cs;
---
>     JSCodeSpec *cs;
>     uint32 format, mode;
>     intN depth;
4782c3015
<     ptrdiff_t len, oplen;
---
>     uintN len, off;
4784c3017
<     char *name;
---
>     JSString *name;
4786,4791c3019
<     JS_ASSERT(spindex < 0 ||
<               spindex == JSDVG_IGNORE_STACK ||
<               spindex == JSDVG_SEARCH_STACK);
< 
<     for (fp = cx->fp; fp && !fp->script; fp = fp->down)
<         continue;
---
>     fp = cx->fp;
4797,4807d3024
<     sp = fp->sp;
<     spbase = fp->spbase;
<     if ((uintN)(sp - spbase) > fp->script->depth) {
<         /*
<          * Preparing to make an internal invocation, using an argv stack
<          * segment pushed just above fp's operand stack space.  Such an argv
<          * stack has no generating pc "basement", so we must fall back.
<          */
<         goto do_fallback;
<     }
< 
4815c3032
<             JS_ASSERT(!fp->script && !(fp->fun && FUN_INTERPRETED(fp->fun)));
---
>             JS_ASSERT(!fp->script && fp->fun && fp->fun->native);
4820d3036
<             spbase = down->spbase;
4831c3047
<             spbase = base = fp->spbase;
---
>             base = fp->spbase;
4853,4856d3068
<          *
<          * We search from limit to base to find the most recently calculated
<          * value matching v under assumption that it is it that caused
<          * exception, see bug 328664.
4858,4861c3070
<         for (sp = limit;;) {
<             if (sp <= base)
<                 goto do_fallback;
<             --sp;
---
>         for (sp = base; sp < limit; sp++) {
4864,4865c3073
<                 sp -= depth;
<                 pc = (jsbytecode *) *sp;
---
>                 pc = (jsbytecode *) sp[-depth];
4882d3089
<             JS_ASSERT(spindex < 0);
4884,4886c3091,3095
< #if !JS_HAS_NO_SUCH_METHOD
<             JS_ASSERT(-depth <= spindex);
< #endif
---
>             JS_ASSERT(-depth <= spindex && spindex < 0);
>             spindex -= depth;
> 
>             base = (jsval *) cx->stackPool.current->base;
>             limit = (jsval *) cx->stackPool.current->avail;
4888,4889c3097,3098
<             if ((jsuword) (sp - fp->spbase) < (jsuword) depth)
<                 pc = (jsbytecode *) *(sp - depth);
---
>             if (JS_UPTRDIFF(sp, base) < JS_UPTRDIFF(limit, base))
>                 pc = (jsbytecode *) *sp;
4895c3104
<      * from fp->sp[spindex - script->depth)].
---
>      * from sp[-(1+depth)].
4905,4927d3113
< 
<     /* None of these stack-writing ops generates novel values. */
<     JS_ASSERT(op != JSOP_CASE && op != JSOP_CASEX &&
<               op != JSOP_DUP && op != JSOP_DUP2 &&
<               op != JSOP_SWAP);
< 
<     /*
<      * |this| could convert to a very long object initialiser, so cite it by
<      * its keyword name instead.
<      */
<     if (op == JSOP_THIS)
<         return JS_strdup(cx, js_this_str);
< 
<     /*
<      * JSOP_BINDNAME is special: it generates a value, the base object of a
<      * reference.  But if it is the generating op for a diagnostic produced by
<      * js_DecompileValueGenerator, the name being bound is irrelevant.  Just
<      * fall back to the base object.
<      */
<     if (op == JSOP_BINDNAME)
<         goto do_fallback;
< 
<     /* NAME ops are self-contained, others require left or right context. */
4929,4935c3115,3121
<     begin = pc;
<     end = pc + cs->length;
<     switch (JOF_MODE(cs->format)) {
<       case JOF_PROP:
<       case JOF_ELEM:
<       case JOF_XMLNAME:
<       case 0:
---
>     format = cs->format;
>     mode = (format & JOF_MODEMASK);
> 
>     /* NAME ops are self-contained, but others require left context. */
>     if (mode == JOF_NAME) {
>         begin = pc;
>     } else {
4937c3123
<         if (!sn)
---
>         if (!sn || SN_TYPE(sn) != SRC_PCBASE)
4939,4951c3125
<         switch (SN_TYPE(sn)) {
<           case SRC_PCBASE:
<             begin -= js_GetSrcNoteOffset(sn, 0);
<             break;
<           case SRC_PCDELTA:
<             end = begin + js_GetSrcNoteOffset(sn, 0);
<             begin += cs->length;
<             break;
<           default:
<             goto do_fallback;
<         }
<         break;
<       default:;
---
>         begin = pc - js_GetSrcNoteOffset(sn, 0);
4952a3127
>     end = pc + cs->length;
4954,5000d3128
<     if (len <= 0)
<         goto do_fallback;
< 
<     /*
<      * Walk forward from script->main and compute starting stack depth.
<      * FIXME: Code to compute oplen copied from js_Disassemble1 and reduced.
<      * FIXME: Optimize to use last empty-stack sequence point.
<      */
<     pcdepth = 0;
<     for (pc = script->main; pc < begin; pc += oplen) {
<         uint32 type;
<         intN nuses, ndefs;
< 
<         op = (JSOp) *pc;
<         if (op == JSOP_TRAP)
<             op = JS_GetTrapOpcode(cx, script, pc);
<         cs = &js_CodeSpec[op];
<         oplen = cs->length;
< 
<         if (op == JSOP_POPN) {
<             pcdepth -= GET_UINT16(pc);
<             continue;
<         }
< 
<         /*
<          * A (C ? T : E) expression requires skipping either T (if begin is in
<          * E) or both T and E (if begin is after the whole expression) before
<          * adjusting pcdepth based on the JSOP_IFEQ or JSOP_IFEQX at pc that
<          * tests condition C.  We know that the stack depth can't change from
<          * what it was with C on top of stack.
<          */
<         sn = js_GetSrcNote(script, pc);
<         if (sn && SN_TYPE(sn) == SRC_COND) {
<             ptrdiff_t jmpoff, jmplen;
< 
<             jmpoff = js_GetSrcNoteOffset(sn, 0);
<             if (pc + jmpoff < begin) {
<                 pc += jmpoff;
<                 op = (JSOp) *pc;
<                 JS_ASSERT(op == JSOP_GOTO || op == JSOP_GOTOX);
<                 cs = &js_CodeSpec[op];
<                 oplen = cs->length;
<                 jmplen = GetJumpOffset(pc, pc);
<                 if (pc + jmplen < begin) {
<                     oplen = (uintN) jmplen;
<                     continue;
<                 }
5001a3130,3152
>     if (format & (JOF_SET | JOF_DEL | JOF_INCDEC | JOF_IMPORT | JOF_FOR)) {
> 		XMEMTAG("jsopcode tmp jsbytecode");
>         tmp = (jsbytecode *) JS_malloc(cx, len * sizeof(jsbytecode));
>         if (!tmp)
>             return NULL;
>         memcpy(tmp, begin, len * sizeof(jsbytecode));
>         if (mode == JOF_NAME) {
>             tmp[0] = JSOP_NAME;
>         } else {
>             /*
>              * We must replace the faulting pc's bytecode with a corresponding
>              * JSOP_GET* code.  For JSOP_SET{PROP,ELEM}, we must use the "2nd"
>              * form of JSOP_GET{PROP,ELEM}, to throw away the assignment op's
>              * right-hand operand and decompile it as if it were a GET of its
>              * left-hand operand.
>              */
>             off = len - cs->length;
>             JS_ASSERT(off == (uintN) PTRDIFF(pc, begin, jsbytecode));
>             if (mode == JOF_PROP) {
>                 tmp[off] = (format & JOF_SET) ? JSOP_GETPROP2 : JSOP_GETPROP;
>             } else if (mode == JOF_ELEM) {
>                 tmp[off] = (format & JOF_SET) ? JSOP_GETELEM2 : JSOP_GETELEM;
>             } else {
5003,5004c3154,3155
<                  * Ok, begin lies in E.  Manually pop C off the model stack,
<                  * since we have moved beyond the IFEQ now.
---
>                  * A zero mode means precisely that op is uncategorized for our
>                  * purposes, so we must write per-op special case code here.
5006,5048c3157,3168
<                 --pcdepth;
<             }
<         }
< 
<         type = JOF_TYPE(cs->format);
<         switch (type) {
<           case JOF_TABLESWITCH:
<           case JOF_TABLESWITCHX:
<           {
<             jsint jmplen, i, low, high;
<             jsbytecode *pc2;
< 
<             jmplen = (type == JOF_TABLESWITCH) ? JUMP_OFFSET_LEN
<                                                : JUMPX_OFFSET_LEN;
<             pc2 = pc;
<             pc2 += jmplen;
<             low = GET_JUMP_OFFSET(pc2);
<             pc2 += JUMP_OFFSET_LEN;
<             high = GET_JUMP_OFFSET(pc2);
<             pc2 += JUMP_OFFSET_LEN;
<             for (i = low; i <= high; i++)
<                 pc2 += jmplen;
<             oplen = 1 + pc2 - pc;
<             break;
<           }
< 
<           case JOF_LOOKUPSWITCH:
<           case JOF_LOOKUPSWITCHX:
<           {
<             jsint jmplen;
<             jsbytecode *pc2;
<             jsatomid npairs;
< 
<             jmplen = (type == JOF_LOOKUPSWITCH) ? JUMP_OFFSET_LEN
<                                                 : JUMPX_OFFSET_LEN;
<             pc2 = pc;
<             pc2 += jmplen;
<             npairs = GET_UINT16(pc2);
<             pc2 += INDEX_LEN;
<             while (npairs) {
<                 pc2 += INDEX_LEN;
<                 pc2 += jmplen;
<                 npairs--;
---
>                 switch (op) {
>                   case JSOP_ENUMELEM:
>                     tmp[off] = JSOP_GETELEM;
>                     break;
> #if JS_HAS_LVALUE_RETURN
>                   case JSOP_SETCALL:
>                     tmp[off] = JSOP_CALL;
>                     break;
> #endif
>                   default:
>                     JS_ASSERT(0);
>                 }
5050,5086d3169
<             oplen = 1 + pc2 - pc;
<             break;
<           }
< 
<           default:;
<         }
< 
<         if (sn && SN_TYPE(sn) == SRC_HIDDEN)
<             continue;
< 
<         nuses = cs->nuses;
<         if (nuses < 0) {
<             /* Call opcode pushes [callee, this, argv...]. */
<             nuses = 2 + GET_ARGC(pc);
<         } else if (op == JSOP_RETSUB) {
<             /* Pop [exception or hole, retsub pc-index]. */
<             JS_ASSERT(nuses == 0);
<             nuses = 2;
<         } else if (op == JSOP_LEAVEBLOCK || op == JSOP_LEAVEBLOCKEXPR) {
<             JS_ASSERT(nuses == 0);
<             nuses = GET_UINT16(pc);
<         }
<         pcdepth -= nuses;
<         JS_ASSERT(pcdepth >= 0);
< 
<         ndefs = cs->ndefs;
<         if (op == JSOP_FINALLY) {
<             /* Push [exception or hole, retsub pc-index]. */
<             JS_ASSERT(ndefs == 0);
<             ndefs = 2;
<         } else if (op == JSOP_ENTERBLOCK) {
<             JSObject *obj;
< 
<             JS_ASSERT(ndefs == 0);
<             GET_OBJECT_FROM_BYTECODE(script, pc, 0, obj);
<             JS_ASSERT(OBJ_BLOCK_DEPTH(cx, obj) == pcdepth);
<             ndefs = OBJ_BLOCK_COUNT(cx, obj);
5088c3171,3174
<         pcdepth += ndefs;
---
>         begin = tmp;
>     } else {
>         /* No need to revise script bytecode. */
>         tmp = NULL;
5091,5100c3177,3184
<     name = NULL;
<     jp = JS_NEW_PRINTER(cx, "js_DecompileValueGenerator", fp->fun, 0, JS_FALSE);
<     if (jp) {
<         jp->dvgfence = end;
<         if (js_DecompileCode(jp, script, begin, (uintN)len, (uintN)pcdepth)) {
<             name = (jp->sprinter.base) ? jp->sprinter.base : (char *) "";
<             name = JS_strdup(cx, name);
<         }
<         js_DestroyPrinter(jp);
<     }
---
>     jp = js_NewPrinter(cx, "js_DecompileValueGenerator", 0, JS_FALSE);
>     if (jp && js_DecompileCode(jp, script, begin, len))
>         name = js_GetPrinterOutput(jp);
>     else
>         name = NULL;
>     js_DestroyPrinter(jp);
>     if (tmp)
>         JS_free(cx, tmp);
5104,5110c3188
<     if (!fallback) {
<         fallback = js_ValueToSource(cx, v);
<         if (!fallback)
<             return NULL;
<     }
<     return js_DeflateString(cx, JSSTRING_CHARS(fallback),
<                             JSSTRING_LENGTH(fallback));
---
>     return fallback ? fallback : js_ValueToString(cx, v);
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsopcode.h /Volumes/Swap/js_D11/src/jsopcode.h
3,4c3,6
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
6,14c8,11
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,22c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
26,38c23,33
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
48d42
< #include "jsutil.h"
63,70d56
< typedef enum JSOpLength {
< #define OPDEF(op,val,name,token,length,nuses,ndefs,prec,format) \
<     op##_LENGTH = length,
< #include "jsopcode.tbl"
< #undef OPDEF
<     JSOP_LIMIT_LENGTH
< } JSOpLength;
< 
76c62
< #define JOF_ATOM          2       /* unsigned 16-bit constant pool index */
---
> #define JOF_CONST         2       /* unsigned 16-bit constant pool index */
82c68
< #define JOF_SLOTATOM      8       /* uint16 slot index + constant pool index */
---
> #define JOF_DEFLOCALVAR   8       /* define local var with initial value */
86,110c72,84
< #define JOF_UINT24        12      /* extended unsigned 24-bit literal (index) */
< #define JOF_2BYTE         13      /* 2-byte opcode, e.g., upper 8 bits of 24-bit
<                                      atom index */
< #define JOF_LOCAL         14      /* block-local operand stack variable */
< #define JOF_OBJECT        15      /* unsigned 16-bit object pool index */
< #define JOF_SLOTOBJECT    16      /* uint16 slot index + object pool index */
< #define JOF_REGEXP        17      /* unsigned 16-bit regexp pool index */
< #define JOF_INT8          18      /* int8 immediate operand */
< #define JOF_INT32         19      /* int32 immediate operand */
< #define JOF_TYPEMASK      0x001f  /* mask for above immediate types */
< 
< #define JOF_NAME          (1U<<5) /* name operation */
< #define JOF_PROP          (2U<<5) /* obj.prop operation */
< #define JOF_ELEM          (3U<<5) /* obj[index] operation */
< #define JOF_XMLNAME       (4U<<5) /* XML name: *, a::b, @a, @a::b, etc. */
< #define JOF_VARPROP       (5U<<5) /* x.prop for arg, var, or local x */
< #define JOF_MODEMASK      (7U<<5) /* mask for above addressing modes */
< #define JOF_SET           (1U<<8) /* set (i.e., assignment) operation */
< #define JOF_DEL           (1U<<9) /* delete operation */
< #define JOF_DEC          (1U<<10) /* decrement (--, not ++) opcode */
< #define JOF_INC          (2U<<10) /* increment (++, not --) opcode */
< #define JOF_INCDEC       (3U<<10) /* increment or decrement opcode */
< #define JOF_POST         (1U<<12) /* postorder increment or decrement */
< #define JOF_IMPORT       (1U<<13) /* import property op */
< #define JOF_FOR          (1U<<14) /* for-in property op */
---
> #define JOF_TYPEMASK      0x000f  /* mask for above immediate types */
> #define JOF_NAME          0x0010  /* name operation */
> #define JOF_PROP          0x0020  /* obj.prop operation */
> #define JOF_ELEM          0x0030  /* obj[index] operation */
> #define JOF_MODEMASK      0x0030  /* mask for above addressing modes */
> #define JOF_SET           0x0040  /* set (i.e., assignment) operation */
> #define JOF_DEL           0x0080  /* delete operation */
> #define JOF_DEC           0x0100  /* decrement (--, not ++) opcode */
> #define JOF_INC           0x0200  /* increment (++, not --) opcode */
> #define JOF_INCDEC        0x0300  /* increment or decrement opcode */
> #define JOF_POST          0x0400  /* postorder increment or decrement */
> #define JOF_IMPORT        0x0800  /* import property op */
> #define JOF_FOR           0x1000  /* for-in property op */
113,133c87,88
< #define JOF_DETECTING    (1U<<15) /* object detection for JSNewResolveOp */
< #define JOF_BACKPATCH    (1U<<16) /* backpatch placeholder during codegen */
< #define JOF_LEFTASSOC    (1U<<17) /* left-associative operator */
< #define JOF_DECLARING    (1U<<18) /* var, const, or function declaration op */
< #define JOF_INDEXBASE    (1U<<19) /* atom segment base setting prefix op */
< #define JOF_CALLOP       (1U<<20) /* call operation that pushes function and
<                                      this */
< #define JOF_PARENHEAD    (1U<<21) /* opcode consumes value of expression in
<                                      parenthesized statement head */
< #define JOF_INVOKE       (1U<<22) /* JSOP_CALL, JSOP_NEW, JSOP_EVAL */
< #define JOF_TMPSLOT      (1U<<23) /* interpreter uses extra temporary slot
<                                      to root intermediate objects */
< #define JOF_TMPSLOT_SHIFT 23
< 
< /* Shorthands for type from format and type from opcode. */
< #define JOF_TYPE(fmt)   ((fmt) & JOF_TYPEMASK)
< #define JOF_OPTYPE(op)  JOF_TYPE(js_CodeSpec[op].format)
< 
< /* Shorthands for mode from format and mode from opcode. */
< #define JOF_MODE(fmt)   ((fmt) & JOF_MODEMASK)
< #define JOF_OPMODE(op)  JOF_MODE(js_CodeSpec[op].format)
---
> #define JOF_BACKPATCH     0x4000  /* backpatch placeholder during codegen */
> #define JOF_LEFTASSOC     0x8000  /* left-associative operator */
142,149d96
< /* Common uint16 immediate format helpers. */
< #define UINT16_LEN              2
< #define UINT16_HI(i)            ((jsbytecode)((i) >> 8))
< #define UINT16_LO(i)            ((jsbytecode)(i))
< #define GET_UINT16(pc)          ((uintN)(((pc)[1] << 8) | (pc)[2]))
< #define SET_UINT16(pc,i)        ((pc)[1] = UINT16_HI(i), (pc)[2] = UINT16_LO(i))
< #define UINT16_LIMIT            ((uintN)1 << 16)
< 
154c101
< #define GET_JUMP_OFFSET(pc)     ((int16)GET_UINT16(pc))
---
> #define GET_JUMP_OFFSET(pc)     ((int16)(((pc)[1] << 8) | (pc)[2]))
156c103
<                                  (pc)[2] = JUMP_OFFSET_LO(off))
---
> 				 (pc)[2] = JUMP_OFFSET_LO(off))
171c118
< #define GET_SPANDEP_INDEX(pc)   ((uint16)GET_UINT16(pc))
---
> #define GET_SPANDEP_INDEX(pc)   ((uint16)(((pc)[1] << 8) | (pc)[2]))
173c120
<                                  (pc)[2] = JUMP_OFFSET_LO(i))
---
> 				 (pc)[2] = JUMP_OFFSET_LO(i))
192,234c139,149
< /*
<  * A literal is indexed by a per-script atom or object maps. Most scripts
<  * have relatively few literals, so the standard JOF_ATOM, JOF_OBJECT and
<  * JOF_REGEXP formats specifies a fixed 16 bits of immediate operand index.
<  * A script with more than 64K literals must wrap the bytecode into
<  * JSOP_INDEXBASE and JSOP_RESETBASE pair.
<  */
< #define INDEX_LEN               2
< #define INDEX_HI(i)             ((jsbytecode)((i) >> 8))
< #define INDEX_LO(i)             ((jsbytecode)(i))
< #define GET_INDEX(pc)           GET_UINT16(pc)
< #define SET_INDEX(pc,i)         ((pc)[1] = INDEX_HI(i), (pc)[2] = INDEX_LO(i))
< 
< #define GET_INDEXBASE(pc)       (JS_ASSERT(*(pc) == JSOP_INDEXBASE),          \
<                                  ((uintN)((pc)[1])) << 16)
< #define INDEXBASE_LEN           1
< 
< #define UINT24_HI(i)            ((jsbytecode)((i) >> 16))
< #define UINT24_MID(i)           ((jsbytecode)((i) >> 8))
< #define UINT24_LO(i)            ((jsbytecode)(i))
< #define GET_UINT24(pc)          ((jsatomid)(((pc)[1] << 16) |                 \
<                                             ((pc)[2] << 8) |                  \
<                                             (pc)[3]))
< #define SET_UINT24(pc,i)        ((pc)[1] = UINT24_HI(i),                      \
<                                  (pc)[2] = UINT24_MID(i),                     \
<                                  (pc)[3] = UINT24_LO(i))
< 
< #define GET_INT8(pc)            ((jsint)(int8)(pc)[1])
< 
< #define GET_INT32(pc)           ((jsint)(((uint32)((pc)[1]) << 24) |          \
<                                          ((uint32)((pc)[2]) << 16) |          \
<                                          ((uint32)((pc)[3]) << 8)  |          \
<                                          (uint32)(pc)[4]))
< #define SET_INT32(pc,i)         ((pc)[1] = (jsbytecode)((uint32)(i) >> 24),   \
<                                  (pc)[2] = (jsbytecode)((uint32)(i) >> 16),   \
<                                  (pc)[3] = (jsbytecode)((uint32)(i) >> 8),    \
<                                  (pc)[4] = (jsbytecode)(uint32)(i))
< 
< /* Index limit is determined by SN_3BYTE_OFFSET_FLAG, see jsemit.h. */
< #define INDEX_LIMIT_LOG2        23
< #define INDEX_LIMIT             ((uint32)1 << INDEX_LIMIT_LOG2)
< 
< JS_STATIC_ASSERT(sizeof(uint32) * JS_BITS_PER_BYTE >= INDEX_LIMIT_LOG2 + 1);
---
> /* A literal is indexed by a per-script atom map. */
> #define ATOM_INDEX_LEN          2
> #define ATOM_INDEX_HI(index)    ((jsbytecode)((index) >> 8))
> #define ATOM_INDEX_LO(index)    ((jsbytecode)(index))
> #define GET_ATOM_INDEX(pc)      ((jsatomid)(((pc)[1] << 8) | (pc)[2]))
> #define SET_ATOM_INDEX(pc,index)((pc)[1] = ATOM_INDEX_HI(index),              \
> 				 (pc)[2] = ATOM_INDEX_LO(index))
> #define GET_ATOM(cx,script,pc)  js_GetAtom((cx), &(script)->atomMap,          \
> 					   GET_ATOM_INDEX(pc))
> #define ATOM_INDEX_LIMIT_LOG2   16
> #define ATOM_INDEX_LIMIT        ((uint32)1 << ATOM_INDEX_LIMIT_LOG2)
237,240c152,155
< #define ARGC_HI(argc)           UINT16_HI(argc)
< #define ARGC_LO(argc)           UINT16_LO(argc)
< #define GET_ARGC(pc)            GET_UINT16(pc)
< #define ARGC_LIMIT              UINT16_LIMIT
---
> #define ARGC_HI(argc)           ((jsbytecode)((argc) >> 8))
> #define ARGC_LO(argc)           ((jsbytecode)(argc))
> #define GET_ARGC(pc)            ((uintN)(((pc)[1] << 8) | (pc)[2]))
> #define ARGC_LIMIT              ((uint32)1 << 16)
243,251c158,163
< #define GET_ARGNO(pc)           GET_UINT16(pc)
< #define SET_ARGNO(pc,argno)     SET_UINT16(pc,argno)
< #define ARGNO_LEN               2
< #define ARGNO_LIMIT             UINT16_LIMIT
< 
< #define GET_VARNO(pc)           GET_UINT16(pc)
< #define SET_VARNO(pc,varno)     SET_UINT16(pc,varno)
< #define VARNO_LEN               2
< #define VARNO_LIMIT             UINT16_LIMIT
---
> #define GET_ARGNO(pc)           GET_ARGC(pc)
> #define SET_ARGNO(pc,argno)     SET_JUMP_OFFSET(pc,argno)
> #define ARGNO_LEN               JUMP_OFFSET_LEN
> #define GET_VARNO(pc)           GET_ARGC(pc)
> #define SET_VARNO(pc,varno)     SET_JUMP_OFFSET(pc,varno)
> #define VARNO_LEN               JUMP_OFFSET_LEN
253a166,167
>     const char          *name;          /* JS bytecode name */
>     const char          *token;         /* JS source literal or null */
261c175,188
< extern const JSCodeSpec js_CodeSpec[];
---
> extern char             js_const_str[];
> extern char             js_var_str[];
> extern char             js_function_str[];
> extern char             js_in_str[];
> extern char             js_instanceof_str[];
> extern char             js_new_str[];
> extern char             js_delete_str[];
> extern char             js_typeof_str[];
> extern char             js_void_str[];
> extern char             js_null_str[];
> extern char             js_this_str[];
> extern char             js_false_str[];
> extern char             js_true_str[];
> extern JSCodeSpec       js_CodeSpec[];
263c190
< extern const char       js_EscapeMap[];
---
> extern jschar           js_EscapeMap[];
278,286d204
< 
< #ifdef JS_ARENAMETER
< # define JS_NEW_PRINTER(cx, name, fun, indent, pretty)                        \
<     js_NewPrinter(cx, name, fun, indent, pretty)
< #else
< # define JS_NEW_PRINTER(cx, name, fun, indent, pretty)                        \
<     js_NewPrinter(cx, fun, indent, pretty)
< #endif
< 
288,289c206
< JS_NEW_PRINTER(JSContext *cx, const char *name, JSFunction *fun,
<                uintN indent, JSBool pretty);
---
> js_NewPrinter(JSContext *cx, const char *name, uintN indent, JSBool pretty);
303,336d219
< /*
<  * Get index operand from the bytecode using a bytecode analysis to deduce the
<  * the index register.
<  */
< uintN
< js_GetIndexFromBytecode(JSScript *script, jsbytecode *pc, ptrdiff_t pcoff);
< 
< /*
<  * A slower version of GET_ATOM when the caller does not want to maintain
<  * the index segment register itself.
<  */
< #define GET_ATOM_FROM_BYTECODE(script, pc, pcoff, atom)                       \
<     JS_BEGIN_MACRO                                                            \
<         uintN index_ = js_GetIndexFromBytecode((script), (pc), (pcoff));      \
<         JS_GET_SCRIPT_ATOM((script), index_, atom);                           \
<     JS_END_MACRO
< 
< #define GET_OBJECT_FROM_BYTECODE(script, pc, pcoff, obj)                      \
<     JS_BEGIN_MACRO                                                            \
<         uintN index_ = js_GetIndexFromBytecode((script), (pc), (pcoff));      \
<         JS_GET_SCRIPT_OBJECT((script), index_, obj);                          \
<     JS_END_MACRO
< 
< #define GET_FUNCTION_FROM_BYTECODE(script, pc, pcoff, obj)                    \
<     JS_BEGIN_MACRO                                                            \
<         GET_OBJECT_FROM_BYTECODE(script, pc, pcoff, obj);                     \
<         JS_ASSERT(OBJ_GET_CLASS(cx, obj) == &js_FunctionClass);               \
<     JS_END_MACRO
< 
< #define GET_REGEXP_FROM_BYTECODE(script, pc, pcoff, obj)                      \
<     JS_BEGIN_MACRO                                                            \
<         uintN index_ = js_GetIndexFromBytecode((script), (pc), (pcoff));      \
<         JS_GET_SCRIPT_REGEXP((script), index_, obj);                          \
<     JS_END_MACRO
344c227
< extern JS_FRIEND_API(JSBool)
---
> extern JS_FRIEND_API(void)
349c232
<                 JSBool lines, FILE *fp);
---
> 		JSBool lines, FILE *fp);
351a235,245
> #if 1 // !!dp
> extern JS_FRIEND_API(void)
> js_Disassemble_OutputProc(JSContext *cx, JSScript *script, JSBool lines, 
> 	LGenericOutProc outProc, void *outParam);
> 
> extern JS_FRIEND_API(uintN)
> js_Disassemble1_OutputProc(JSContext *cx, JSScript *script, jsbytecode *pc, uintN loc,
> 		JSBool lines, 
> 		LGenericOutProc outProc, void *outParam);
> #endif
> 
356,357c250
< js_DecompileCode(JSPrinter *jp, JSScript *script, jsbytecode *pc, uintN len,
<                  uintN pcdepth);
---
> js_DecompileCode(JSPrinter *jp, JSScript *script, jsbytecode *pc, uintN len);
363c256
< js_DecompileFunctionBody(JSPrinter *jp);
---
> js_DecompileFunctionBody(JSPrinter *jp, JSFunction *fun);
366c259
< js_DecompileFunction(JSPrinter *jp);
---
> js_DecompileFunction(JSPrinter *jp, JSFunction *fun);
369,371c262,264
<  * Find the source expression that resulted in v, and return a newly allocated
<  * C-string containing it.  Fall back on v's string conversion (fallback) if we
<  * can't find the bytecode that generated and pushed v on the operand stack.
---
>  * Find the source expression that resulted in v, and return a new string
>  * containing it.  Fall back on v's string conversion (fallback) if we can't
>  * find the bytecode that generated and pushed v on the operand stack.
377,378d269
<  *
<  * The caller must call JS_free on the result after a succsesful call.
380c271
< extern char *
---
> extern JSString *
382c273
<                            JSString *fallback);
---
> 			   JSString *fallback);
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsopcode.tbl /Volumes/Swap/js_D11/src/jsopcode.tbl
2d1
<  * vim: set ts=8 sw=4 et tw=0 ft=C:
4,15c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
20,39c16,33
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
66,94c60,61
<  * Precedence   Operators               Opcodes
<  *  1           let (x = y) z, yield w  JSOP_LEAVEBLOCKEXPR, JSOP_YIELD
<  *  2           ,                       JSOP_POP with SRC_PCDELTA, JSOP_RETURN
<  *  3           =, +=, etc.             JSOP_SETNAME, etc. (all JOF_ASSIGNING)
<  *  4           ?:                      JSOP_IFEQ, JSOP_IFEQX
<  *  5           ||                      JSOP_OR, JSOP_ORX
<  *  6           &&                      JSOP_AND, JSOP_ANDX
<  *  7           |                       JSOP_BITOR
<  *  8           ^                       JSOP_BITXOR
<  *  9           &                       JSOP_BITAND
<  * 10           ==, !=, etc.            JSOP_EQ, JSOP_NE, etc.
<  * 11           <, in, etc.             JSOP_LT, JSOP_IN, etc.
<  * 12           <<, >>, >>>             JSOP_LSH, JSOP_RSH, JSOP_URSH
<  * 13           +, -, etc.              JSOP_ADD, JSOP_SUB, etc.
<  * 14           *, /, %                 JSOP_MUL, JSOP_DIV, JSOP_MOD
<  * 15           !, ~, etc.              JSOP_NOT, JSOP_BITNOT, etc.
<  * 16           3.14, 0, etc.           JSOP_DOUBLE, JSOP_ZERO, etc.
<  * 17           delete, new             JSOP_DEL*, JSOP_NEW
<  * 18           x.y, f(), etc.          JSOP_GETPROP, JSOP_CALL, etc.
<  * 19           x, null, etc.           JSOP_NAME, JSOP_NULL, etc.
<  *
<  * The push-numeric-constant operators, JSOP_ZERO, JSOP_DOUBLE, etc., have
<  * lower precedence than the member operators emitted for the . operator, to
<  * cause the decompiler to parenthesize the . left operand, e.g. (0).foo.
<  * Otherwise the . could be taken as a decimal point.  We use the same level
<  * 16 for function expressions too, to force parenthesization.
<  *
<  * This file is best viewed with 128 columns:
< 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
---
>  * This file is best viewed with 116 columns:
> 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345
102,103c69,70
< OPDEF(JSOP_POPV,      2,  "popv",       NULL,         1,  1,  0,  2,  JOF_BYTE)
< OPDEF(JSOP_ENTERWITH, 3,  "enterwith",  NULL,         1,  1,  1,  0,  JOF_BYTE|JOF_PARENHEAD)
---
> OPDEF(JSOP_POPV,      2,  "popv",       NULL,         1,  1,  0,  0,  JOF_BYTE)
> OPDEF(JSOP_ENTERWITH, 3,  "enterwith",  NULL,         1,  1,  1,  0,  JOF_BYTE)
105c72
< OPDEF(JSOP_RETURN,    5,  "return",     NULL,         1,  1,  0,  2,  JOF_BYTE)
---
> OPDEF(JSOP_RETURN,    5,  "return",     NULL,         1,  1,  0,  0,  JOF_BYTE)
107,108c74,75
< OPDEF(JSOP_IFEQ,      7,  "ifeq",       NULL,         3,  1,  0,  4,  JOF_JUMP|JOF_DETECTING)
< OPDEF(JSOP_IFNE,      8,  "ifne",       NULL,         3,  1,  0,  0,  JOF_JUMP|JOF_PARENHEAD)
---
> OPDEF(JSOP_IFEQ,      7,  "ifeq",       NULL,         3,  1,  0,  0,  JOF_JUMP)
> OPDEF(JSOP_IFNE,      8,  "ifne",       NULL,         3,  1,  0,  0,  JOF_JUMP)
111c78
< OPDEF(JSOP_ARGUMENTS, 9, js_arguments_str, js_arguments_str, 1, 0, 1, 18, JOF_BYTE)
---
> OPDEF(JSOP_ARGUMENTS, 9, js_arguments_str, js_arguments_str, 1, 0, 1, 12, JOF_BYTE)
114,115c81,82
< OPDEF(JSOP_FORARG,    10, "forarg",     NULL,         3,  0,  1, 19,  JOF_QARG|JOF_NAME|JOF_FOR)
< OPDEF(JSOP_FORVAR,    11, "forvar",     NULL,         3,  0,  1, 19,  JOF_QVAR|JOF_NAME|JOF_FOR)
---
> OPDEF(JSOP_FORARG,    10, "forarg",     NULL,         3,  0,  1,  0,  JOF_QARG|JOF_NAME|JOF_FOR)
> OPDEF(JSOP_FORVAR,    11, "forvar",     NULL,         3,  0,  1,  0,  JOF_QVAR|JOF_NAME|JOF_FOR)
120,175c87,142
< OPDEF(JSOP_SETCONST,  14, "setconst",   NULL,         3,  1,  1,  3,  JOF_ATOM|JOF_NAME|JOF_SET)
< OPDEF(JSOP_BITOR,     15, "bitor",      "|",          1,  2,  1,  7,  JOF_BYTE|JOF_LEFTASSOC)
< OPDEF(JSOP_BITXOR,    16, "bitxor",     "^",          1,  2,  1,  8,  JOF_BYTE|JOF_LEFTASSOC)
< OPDEF(JSOP_BITAND,    17, "bitand",     "&",          1,  2,  1,  9,  JOF_BYTE|JOF_LEFTASSOC)
< OPDEF(JSOP_EQ,        18, "eq",         "==",         1,  2,  1,  10,  JOF_BYTE|JOF_LEFTASSOC|JOF_DETECTING)
< OPDEF(JSOP_NE,        19, "ne",         "!=",         1,  2,  1,  10,  JOF_BYTE|JOF_LEFTASSOC|JOF_DETECTING)
< OPDEF(JSOP_LT,        20, "lt",         "<",          1,  2,  1, 11,  JOF_BYTE|JOF_LEFTASSOC)
< OPDEF(JSOP_LE,        21, "le",         "<=",         1,  2,  1, 11,  JOF_BYTE|JOF_LEFTASSOC)
< OPDEF(JSOP_GT,        22, "gt",         ">",          1,  2,  1, 11,  JOF_BYTE|JOF_LEFTASSOC)
< OPDEF(JSOP_GE,        23, "ge",         ">=",         1,  2,  1, 11,  JOF_BYTE|JOF_LEFTASSOC)
< OPDEF(JSOP_LSH,       24, "lsh",        "<<",         1,  2,  1, 12,  JOF_BYTE|JOF_LEFTASSOC)
< OPDEF(JSOP_RSH,       25, "rsh",        ">>",         1,  2,  1, 12,  JOF_BYTE|JOF_LEFTASSOC)
< OPDEF(JSOP_URSH,      26, "ursh",       ">>>",        1,  2,  1, 12,  JOF_BYTE|JOF_LEFTASSOC)
< OPDEF(JSOP_ADD,       27, "add",        "+",          1,  2,  1, 13,  JOF_BYTE|JOF_LEFTASSOC)
< OPDEF(JSOP_SUB,       28, "sub",        "-",          1,  2,  1, 13,  JOF_BYTE|JOF_LEFTASSOC)
< OPDEF(JSOP_MUL,       29, "mul",        "*",          1,  2,  1, 14,  JOF_BYTE|JOF_LEFTASSOC)
< OPDEF(JSOP_DIV,       30, "div",        "/",          1,  2,  1, 14,  JOF_BYTE|JOF_LEFTASSOC)
< OPDEF(JSOP_MOD,       31, "mod",        "%",          1,  2,  1, 14,  JOF_BYTE|JOF_LEFTASSOC)
< OPDEF(JSOP_NOT,       32, "not",        "!",          1,  1,  1, 15,  JOF_BYTE|JOF_DETECTING)
< OPDEF(JSOP_BITNOT,    33, "bitnot",     "~",          1,  1,  1, 15,  JOF_BYTE)
< OPDEF(JSOP_NEG,       34, "neg",        "- ",         1,  1,  1, 15,  JOF_BYTE)
< OPDEF(JSOP_NEW,       35, js_new_str,   NULL,         3, -1,  1, 17,  JOF_UINT16|JOF_INVOKE)
< OPDEF(JSOP_DELNAME,   36, "delname",    NULL,         3,  0,  1, 17,  JOF_ATOM|JOF_NAME|JOF_DEL)
< OPDEF(JSOP_DELPROP,   37, "delprop",    NULL,         3,  1,  1, 17,  JOF_ATOM|JOF_PROP|JOF_DEL)
< OPDEF(JSOP_DELELEM,   38, "delelem",    NULL,         1,  2,  1, 17,  JOF_BYTE |JOF_ELEM|JOF_DEL)
< OPDEF(JSOP_TYPEOF,    39, js_typeof_str,NULL,         1,  1,  1, 15,  JOF_BYTE|JOF_DETECTING)
< OPDEF(JSOP_VOID,      40, js_void_str,  NULL,         1,  1,  1, 15,  JOF_BYTE)
< OPDEF(JSOP_INCNAME,   41, "incname",    NULL,         3,  0,  1, 15,  JOF_ATOM|JOF_NAME|JOF_INC)
< OPDEF(JSOP_INCPROP,   42, "incprop",    NULL,         3,  1,  1, 15,  JOF_ATOM|JOF_PROP|JOF_INC)
< OPDEF(JSOP_INCELEM,   43, "incelem",    NULL,         1,  2,  1, 15,  JOF_BYTE |JOF_ELEM|JOF_INC)
< OPDEF(JSOP_DECNAME,   44, "decname",    NULL,         3,  0,  1, 15,  JOF_ATOM|JOF_NAME|JOF_DEC)
< OPDEF(JSOP_DECPROP,   45, "decprop",    NULL,         3,  1,  1, 15,  JOF_ATOM|JOF_PROP|JOF_DEC)
< OPDEF(JSOP_DECELEM,   46, "decelem",    NULL,         1,  2,  1, 15,  JOF_BYTE |JOF_ELEM|JOF_DEC)
< OPDEF(JSOP_NAMEINC,   47, "nameinc",    NULL,         3,  0,  1, 15,  JOF_ATOM|JOF_NAME|JOF_INC|JOF_POST)
< OPDEF(JSOP_PROPINC,   48, "propinc",    NULL,         3,  1,  1, 15,  JOF_ATOM|JOF_PROP|JOF_INC|JOF_POST|JOF_TMPSLOT)
< OPDEF(JSOP_ELEMINC,   49, "eleminc",    NULL,         1,  2,  1, 15,  JOF_BYTE |JOF_ELEM|JOF_INC|JOF_POST|JOF_TMPSLOT)
< OPDEF(JSOP_NAMEDEC,   50, "namedec",    NULL,         3,  0,  1, 15,  JOF_ATOM|JOF_NAME|JOF_DEC|JOF_POST)
< OPDEF(JSOP_PROPDEC,   51, "propdec",    NULL,         3,  1,  1, 15,  JOF_ATOM|JOF_PROP|JOF_DEC|JOF_POST|JOF_TMPSLOT)
< OPDEF(JSOP_ELEMDEC,   52, "elemdec",    NULL,         1,  2,  1, 15,  JOF_BYTE |JOF_ELEM|JOF_DEC|JOF_POST|JOF_TMPSLOT)
< OPDEF(JSOP_GETPROP,   53, "getprop",    NULL,         3,  1,  1, 18,  JOF_ATOM|JOF_PROP)
< OPDEF(JSOP_SETPROP,   54, "setprop",    NULL,         3,  2,  1,  3,  JOF_ATOM|JOF_PROP|JOF_SET|JOF_DETECTING)
< OPDEF(JSOP_GETELEM,   55, "getelem",    NULL,         1,  2,  1, 18,  JOF_BYTE |JOF_ELEM|JOF_LEFTASSOC)
< OPDEF(JSOP_SETELEM,   56, "setelem",    NULL,         1,  3,  1,  3,  JOF_BYTE |JOF_ELEM|JOF_SET|JOF_DETECTING)
< OPDEF(JSOP_CALLNAME,  57, "callname",   NULL,         3,  0,  2, 19,  JOF_ATOM|JOF_NAME|JOF_CALLOP)
< OPDEF(JSOP_CALL,      58, "call",       NULL,         3, -1,  1, 18,  JOF_UINT16|JOF_INVOKE)
< OPDEF(JSOP_NAME,      59, "name",       NULL,         3,  0,  1, 19,  JOF_ATOM|JOF_NAME)
< OPDEF(JSOP_DOUBLE,    60, "double",     NULL,         3,  0,  1, 16,  JOF_ATOM)
< OPDEF(JSOP_STRING,    61, "string",     NULL,         3,  0,  1, 19,  JOF_ATOM)
< OPDEF(JSOP_ZERO,      62, "zero",       "0",          1,  0,  1, 16,  JOF_BYTE)
< OPDEF(JSOP_ONE,       63, "one",        "1",          1,  0,  1, 16,  JOF_BYTE)
< OPDEF(JSOP_NULL,      64, js_null_str,  js_null_str,  1,  0,  1, 19,  JOF_BYTE)
< OPDEF(JSOP_THIS,      65, js_this_str,  js_this_str,  1,  0,  1, 19,  JOF_BYTE)
< OPDEF(JSOP_FALSE,     66, js_false_str, js_false_str, 1,  0,  1, 19,  JOF_BYTE)
< OPDEF(JSOP_TRUE,      67, js_true_str,  js_true_str,  1,  0,  1, 19,  JOF_BYTE)
< OPDEF(JSOP_OR,        68, "or",         NULL,         3,  1,  0,  5,  JOF_JUMP|JOF_DETECTING|JOF_LEFTASSOC)
< OPDEF(JSOP_AND,       69, "and",        NULL,         3,  1,  0,  6,  JOF_JUMP|JOF_DETECTING|JOF_LEFTASSOC)
---
> OPDEF(JSOP_SETCONST,  14, "setconst",   NULL,         3,  1,  1,  1,  JOF_CONST|JOF_NAME|JOF_SET|JOF_ASSIGNING)
> OPDEF(JSOP_BITOR,     15, "bitor",      "|",          1,  2,  1,  2,  JOF_BYTE|JOF_LEFTASSOC)
> OPDEF(JSOP_BITXOR,    16, "bitxor",     "^",          1,  2,  1,  3,  JOF_BYTE|JOF_LEFTASSOC)
> OPDEF(JSOP_BITAND,    17, "bitand",     "&",          1,  2,  1,  4,  JOF_BYTE|JOF_LEFTASSOC)
> OPDEF(JSOP_EQ,        18, "eq",         "==",         1,  2,  1,  5,  JOF_BYTE|JOF_LEFTASSOC)
> OPDEF(JSOP_NE,        19, "ne",         "!=",         1,  2,  1,  5,  JOF_BYTE|JOF_LEFTASSOC)
> OPDEF(JSOP_LT,        20, "lt",         "<",          1,  2,  1,  6,  JOF_BYTE|JOF_LEFTASSOC)
> OPDEF(JSOP_LE,        21, "le",         "<=",         1,  2,  1,  6,  JOF_BYTE|JOF_LEFTASSOC)
> OPDEF(JSOP_GT,        22, "gt",         ">",          1,  2,  1,  6,  JOF_BYTE|JOF_LEFTASSOC)
> OPDEF(JSOP_GE,        23, "ge",         ">=",         1,  2,  1,  6,  JOF_BYTE|JOF_LEFTASSOC)
> OPDEF(JSOP_LSH,       24, "lsh",        "<<",         1,  2,  1,  7,  JOF_BYTE|JOF_LEFTASSOC)
> OPDEF(JSOP_RSH,       25, "rsh",        ">>",         1,  2,  1,  7,  JOF_BYTE|JOF_LEFTASSOC)
> OPDEF(JSOP_URSH,      26, "ursh",       ">>>",        1,  2,  1,  7,  JOF_BYTE|JOF_LEFTASSOC)
> OPDEF(JSOP_ADD,       27, "add",        "+",          1,  2,  1,  8,  JOF_BYTE|JOF_LEFTASSOC)
> OPDEF(JSOP_SUB,       28, "sub",        "-",          1,  2,  1,  8,  JOF_BYTE|JOF_LEFTASSOC)
> OPDEF(JSOP_MUL,       29, "mul",        "*",          1,  2,  1,  9,  JOF_BYTE|JOF_LEFTASSOC)
> OPDEF(JSOP_DIV,       30, "div",        "/",          1,  2,  1,  9,  JOF_BYTE|JOF_LEFTASSOC)
> OPDEF(JSOP_MOD,       31, "mod",        "%",          1,  2,  1,  9,  JOF_BYTE|JOF_LEFTASSOC)
> OPDEF(JSOP_NOT,       32, "not",        "!",          1,  1,  1, 10,  JOF_BYTE)
> OPDEF(JSOP_BITNOT,    33, "bitnot",     "~",          1,  1,  1, 10,  JOF_BYTE)
> OPDEF(JSOP_NEG,       34, "neg",        "-",          1,  1,  1, 10,  JOF_BYTE)
> OPDEF(JSOP_NEW,       35, js_new_str,   NULL,         3, -1,  1, 10,  JOF_UINT16)
> OPDEF(JSOP_DELNAME,   36, "delname",    NULL,         3,  0,  1, 10,  JOF_CONST|JOF_NAME|JOF_DEL)
> OPDEF(JSOP_DELPROP,   37, "delprop",    NULL,         3,  1,  1, 10,  JOF_CONST|JOF_PROP|JOF_DEL)
> OPDEF(JSOP_DELELEM,   38, "delelem",    NULL,         1,  2,  1, 10,  JOF_BYTE |JOF_ELEM|JOF_DEL)
> OPDEF(JSOP_TYPEOF,    39, js_typeof_str,NULL,         1,  1,  1, 10,  JOF_BYTE)
> OPDEF(JSOP_VOID,      40, js_void_str,  NULL,         1,  1,  1, 10,  JOF_BYTE)
> OPDEF(JSOP_INCNAME,   41, "incname",    NULL,         3,  0,  1, 10,  JOF_CONST|JOF_NAME|JOF_INC)
> OPDEF(JSOP_INCPROP,   42, "incprop",    NULL,         3,  1,  1, 10,  JOF_CONST|JOF_PROP|JOF_INC)
> OPDEF(JSOP_INCELEM,   43, "incelem",    NULL,         1,  2,  1, 10,  JOF_BYTE |JOF_ELEM|JOF_INC)
> OPDEF(JSOP_DECNAME,   44, "decname",    NULL,         3,  0,  1, 10,  JOF_CONST|JOF_NAME|JOF_DEC)
> OPDEF(JSOP_DECPROP,   45, "decprop",    NULL,         3,  1,  1, 10,  JOF_CONST|JOF_PROP|JOF_DEC)
> OPDEF(JSOP_DECELEM,   46, "decelem",    NULL,         1,  2,  1, 10,  JOF_BYTE |JOF_ELEM|JOF_DEC)
> OPDEF(JSOP_NAMEINC,   47, "nameinc",    NULL,         3,  0,  1, 10,  JOF_CONST|JOF_NAME|JOF_INC|JOF_POST)
> OPDEF(JSOP_PROPINC,   48, "propinc",    NULL,         3,  1,  1, 10,  JOF_CONST|JOF_PROP|JOF_INC|JOF_POST)
> OPDEF(JSOP_ELEMINC,   49, "eleminc",    NULL,         1,  2,  1, 10,  JOF_BYTE |JOF_ELEM|JOF_INC|JOF_POST)
> OPDEF(JSOP_NAMEDEC,   50, "namedec",    NULL,         3,  0,  1, 10,  JOF_CONST|JOF_NAME|JOF_DEC|JOF_POST)
> OPDEF(JSOP_PROPDEC,   51, "propdec",    NULL,         3,  1,  1, 10,  JOF_CONST|JOF_PROP|JOF_DEC|JOF_POST)
> OPDEF(JSOP_ELEMDEC,   52, "elemdec",    NULL,         1,  2,  1, 10,  JOF_BYTE |JOF_ELEM|JOF_DEC|JOF_POST)
> OPDEF(JSOP_GETPROP,   53, "getprop",    NULL,         3,  1,  1, 11,  JOF_CONST|JOF_PROP)
> OPDEF(JSOP_SETPROP,   54, "setprop",    NULL,         3,  2,  1,  1,  JOF_CONST|JOF_PROP|JOF_SET|JOF_ASSIGNING)
> OPDEF(JSOP_GETELEM,   55, "getelem",    NULL,         1,  2,  1, 11,  JOF_BYTE |JOF_ELEM|JOF_LEFTASSOC)
> OPDEF(JSOP_SETELEM,   56, "setelem",    NULL,         1,  3,  1,  1,  JOF_BYTE |JOF_ELEM|JOF_SET|JOF_ASSIGNING)
> OPDEF(JSOP_PUSHOBJ,   57, "pushobj",    NULL,         1,  0,  1,  0,  JOF_BYTE)
> OPDEF(JSOP_CALL,      58, "call",       NULL,         3, -1,  1, 11,  JOF_UINT16)
> OPDEF(JSOP_NAME,      59, "name",       NULL,         3,  0,  1, 12,  JOF_CONST|JOF_NAME)
> OPDEF(JSOP_NUMBER,    60, "number",     NULL,         3,  0,  1, 12,  JOF_CONST)
> OPDEF(JSOP_STRING,    61, "string",     NULL,         3,  0,  1, 12,  JOF_CONST)
> OPDEF(JSOP_ZERO,      62, "zero",       "0",          1,  0,  1, 12,  JOF_BYTE)
> OPDEF(JSOP_ONE,       63, "one",        "1",          1,  0,  1, 12,  JOF_BYTE)
> OPDEF(JSOP_NULL,      64, js_null_str,  js_null_str,  1,  0,  1, 12,  JOF_BYTE)
> OPDEF(JSOP_THIS,      65, js_this_str,  js_this_str,  1,  0,  1, 12,  JOF_BYTE)
> OPDEF(JSOP_FALSE,     66, js_false_str, js_false_str, 1,  0,  1, 12,  JOF_BYTE)
> OPDEF(JSOP_TRUE,      67, js_true_str,  js_true_str,  1,  0,  1, 12,  JOF_BYTE)
> OPDEF(JSOP_OR,        68, "or",         NULL,         3,  1,  0,  0,  JOF_JUMP)
> OPDEF(JSOP_AND,       69, "and",        NULL,         3,  1,  0,  0,  JOF_JUMP)
178,179c145,146
< OPDEF(JSOP_TABLESWITCH,  70, "tableswitch",  NULL,   -1,  1,  0,  0,  JOF_TABLESWITCH|JOF_DETECTING|JOF_PARENHEAD)
< OPDEF(JSOP_LOOKUPSWITCH, 71, "lookupswitch", NULL,   -1,  1,  0,  0,  JOF_LOOKUPSWITCH|JOF_DETECTING|JOF_PARENHEAD)
---
> OPDEF(JSOP_TABLESWITCH,  70, "tableswitch",  NULL,   -1,  1,  0,  0,  JOF_TABLESWITCH)
> OPDEF(JSOP_LOOKUPSWITCH, 71, "lookupswitch", NULL,   -1,  1,  0,  0,  JOF_LOOKUPSWITCH)
182,183c149,150
< OPDEF(JSOP_STRICTEQ,  72, "stricteq",   NULL,         1,  2,  1,  10,  JOF_BYTE|JOF_DETECTING)
< OPDEF(JSOP_STRICTNE,  73, "strictne",   NULL,         1,  2,  1,  10,  JOF_BYTE|JOF_DETECTING)
---
> OPDEF(JSOP_NEW_EQ,    72, "eq",         NULL,         1,  2,  1,  5,  JOF_BYTE)
> OPDEF(JSOP_NEW_NE,    73, "ne",         NULL,         1,  2,  1,  5,  JOF_BYTE)
186c153
< OPDEF(JSOP_CLOSURE,   74, "closure",    NULL,         3,  0,  0,  0,  JOF_OBJECT)
---
> OPDEF(JSOP_CLOSURE,   74, "closure",    NULL,         3,  0,  0,  0,  JOF_CONST)
190c157
< OPDEF(JSOP_EXPORTNAME,76, "exportname", NULL,         3,  0,  0,  0,  JOF_ATOM|JOF_NAME)
---
> OPDEF(JSOP_EXPORTNAME,76, "exportname", NULL,         3,  0,  0,  0,  JOF_CONST|JOF_NAME)
192c159
< OPDEF(JSOP_IMPORTPROP,78, "importprop", NULL,         3,  1,  0,  0,  JOF_ATOM|JOF_PROP|JOF_IMPORT)
---
> OPDEF(JSOP_IMPORTPROP,78, "importprop", NULL,         3,  1,  0,  0,  JOF_CONST|JOF_PROP|JOF_IMPORT)
196c163
< OPDEF(JSOP_OBJECT,    80, "object",     NULL,         3,  0,  1, 19,  JOF_OBJECT)
---
> OPDEF(JSOP_OBJECT,    80, "object",     NULL,         3,  0,  1, 12,  JOF_CONST)
199c166
< OPDEF(JSOP_POP,       81, "pop",        NULL,         1,  1,  0,  2,  JOF_BYTE)
---
> OPDEF(JSOP_POP,       81, "pop",        NULL,         1,  1,  0,  0,  JOF_BYTE)
202c169
< OPDEF(JSOP_POS,       82, "pos",        "+ ",         1,  1,  1, 15,  JOF_BYTE)
---
> OPDEF(JSOP_POS,       82, "pos",        "+",          1,  1,  1, 10,  JOF_BYTE)
208,211c175,178
< OPDEF(JSOP_GETARG,    84, "getarg",     NULL,         3,  0,  1, 19,  JOF_QARG |JOF_NAME)
< OPDEF(JSOP_SETARG,    85, "setarg",     NULL,         3,  1,  1,  3,  JOF_QARG |JOF_NAME|JOF_SET)
< OPDEF(JSOP_GETVAR,    86, "getvar",     NULL,         3,  0,  1, 19,  JOF_QVAR |JOF_NAME)
< OPDEF(JSOP_SETVAR,    87, "setvar",     NULL,         3,  1,  1,  3,  JOF_QVAR |JOF_NAME|JOF_SET|JOF_DETECTING)
---
> OPDEF(JSOP_GETARG,    84, "getarg",     NULL,         3,  0,  1, 12,  JOF_QARG |JOF_NAME)
> OPDEF(JSOP_SETARG,    85, "setarg",     NULL,         3,  1,  1,  1,  JOF_QARG |JOF_NAME|JOF_SET|JOF_ASSIGNING)
> OPDEF(JSOP_GETVAR,    86, "getvar",     NULL,         3,  0,  1, 12,  JOF_QVAR |JOF_NAME)
> OPDEF(JSOP_SETVAR,    87, "setvar",     NULL,         3,  1,  1,  1,  JOF_QVAR |JOF_NAME|JOF_SET|JOF_ASSIGNING)
214c181
< OPDEF(JSOP_UINT16,    88, "uint16",     NULL,         3,  0,  1, 16,  JOF_UINT16)
---
> OPDEF(JSOP_UINT16,    88, "uint16",     NULL,         3,  0,  1, 12,  JOF_UINT16)
217,220c184,187
< OPDEF(JSOP_NEWINIT,   89, "newinit",    NULL,         2,  0,  1, 19,  JOF_INT8)
< OPDEF(JSOP_ENDINIT,   90, "endinit",    NULL,         1,  0,  0, 19,  JOF_BYTE)
< OPDEF(JSOP_INITPROP,  91, "initprop",   NULL,         3,  1,  0,  3,  JOF_ATOM|JOF_PROP|JOF_DETECTING)
< OPDEF(JSOP_INITELEM,  92, "initelem",   NULL,         1,  2,  0,  3,  JOF_BYTE |JOF_ELEM|JOF_DETECTING)
---
> OPDEF(JSOP_NEWINIT,   89, "newinit",    NULL,         1,  2,  1, 10,  JOF_BYTE)
> OPDEF(JSOP_ENDINIT,   90, "endinit",    NULL,         1,  0,  0,  0,  JOF_BYTE)
> OPDEF(JSOP_INITPROP,  91, "initprop",   NULL,         3,  1,  0,  0,  JOF_CONST|JOF_PROP)
> OPDEF(JSOP_INITELEM,  92, "initelem",   NULL,         1,  2,  0,  0,  JOF_BYTE |JOF_ELEM)
225,237c192,199
< OPDEF(JSOP_INCARG,    95, "incarg",     NULL,         3,  0,  1, 15,  JOF_QARG |JOF_NAME|JOF_INC)
< OPDEF(JSOP_INCVAR,    96, "incvar",     NULL,         3,  0,  1, 15,  JOF_QVAR |JOF_NAME|JOF_INC)
< OPDEF(JSOP_DECARG,    97, "decarg",     NULL,         3,  0,  1, 15,  JOF_QARG |JOF_NAME|JOF_DEC)
< OPDEF(JSOP_DECVAR,    98, "decvar",     NULL,         3,  0,  1, 15,  JOF_QVAR |JOF_NAME|JOF_DEC)
< OPDEF(JSOP_ARGINC,    99, "arginc",     NULL,         3,  0,  1, 15,  JOF_QARG |JOF_NAME|JOF_INC|JOF_POST)
< OPDEF(JSOP_VARINC,    100,"varinc",     NULL,         3,  0,  1, 15,  JOF_QVAR |JOF_NAME|JOF_INC|JOF_POST)
< OPDEF(JSOP_ARGDEC,    101,"argdec",     NULL,         3,  0,  1, 15,  JOF_QARG |JOF_NAME|JOF_DEC|JOF_POST)
< OPDEF(JSOP_VARDEC,    102,"vardec",     NULL,         3,  0,  1, 15,  JOF_QVAR |JOF_NAME|JOF_DEC|JOF_POST)
< 
< /*
<  * Initialize for-in iterator. See also JSOP_FOREACH and JSOP_FOREACHKEYVAL.
<  */
< OPDEF(JSOP_FORIN,     103,"forin",      NULL,         1,  1,  1,  0,  JOF_BYTE)
---
> OPDEF(JSOP_INCARG,    95, "incarg",     NULL,         3,  0,  1, 10,  JOF_QARG |JOF_NAME|JOF_INC)
> OPDEF(JSOP_INCVAR,    96, "incvar",     NULL,         3,  0,  1, 10,  JOF_QVAR |JOF_NAME|JOF_INC)
> OPDEF(JSOP_DECARG,    97, "decarg",     NULL,         3,  0,  1, 10,  JOF_QARG |JOF_NAME|JOF_DEC)
> OPDEF(JSOP_DECVAR,    98, "decvar",     NULL,         3,  0,  1, 10,  JOF_QVAR |JOF_NAME|JOF_DEC)
> OPDEF(JSOP_ARGINC,    99, "arginc",     NULL,         3,  0,  1, 10,  JOF_QARG |JOF_NAME|JOF_INC|JOF_POST)
> OPDEF(JSOP_VARINC,    100,"varinc",     NULL,         3,  0,  1, 10,  JOF_QVAR |JOF_NAME|JOF_INC|JOF_POST)
> OPDEF(JSOP_ARGDEC,    101,"argdec",     NULL,         3,  0,  1, 10,  JOF_QARG |JOF_NAME|JOF_DEC|JOF_POST)
> OPDEF(JSOP_VARDEC,    102,"vardec",     NULL,         3,  0,  1, 10,  JOF_QVAR |JOF_NAME|JOF_DEC|JOF_POST)
240,243c202,206
< OPDEF(JSOP_FORNAME,   104,"forname",    NULL,         3,  0,  1, 19,  JOF_ATOM|JOF_NAME|JOF_FOR)
< OPDEF(JSOP_FORPROP,   105,"forprop",    NULL,         3,  1,  1, 18,  JOF_ATOM|JOF_PROP|JOF_FOR)
< OPDEF(JSOP_FORELEM,   106,"forelem",    NULL,         1,  1,  3, 18,  JOF_BYTE |JOF_ELEM|JOF_FOR)
< OPDEF(JSOP_POPN,      107,"popn",       NULL,         3, -1,  0,  0,  JOF_UINT16)
---
> OPDEF(JSOP_TOOBJECT,  103,"toobject",   NULL,         1,  1,  1,  0,  JOF_BYTE)
> OPDEF(JSOP_FORNAME,   104,"forname",    NULL,         3,  0,  1,  0,  JOF_CONST|JOF_NAME|JOF_FOR)
> OPDEF(JSOP_FORPROP,   105,"forprop",    NULL,         3,  1,  1,  0,  JOF_CONST|JOF_PROP|JOF_FOR)
> OPDEF(JSOP_FORELEM,   106,"forelem",    NULL,         1,  2,  4,  0,  JOF_BYTE |JOF_ELEM|JOF_FOR)
> OPDEF(JSOP_POP2,      107,"pop2",       NULL,         1,  2,  0,  0,  JOF_BYTE)
246,247c209,210
< OPDEF(JSOP_BINDNAME,  108,"bindname",   NULL,         3,  0,  1,  0,  JOF_ATOM|JOF_NAME|JOF_SET)
< OPDEF(JSOP_SETNAME,   109,"setname",    NULL,         3,  2,  1,  3,  JOF_ATOM|JOF_NAME|JOF_SET|JOF_DETECTING)
---
> OPDEF(JSOP_BINDNAME,  108,"bindname",   NULL,         3,  0,  1,  0,  JOF_CONST|JOF_NAME|JOF_SET|JOF_ASSIGNING)
> OPDEF(JSOP_SETNAME,   109,"setname",    NULL,         3,  2,  1,  1,  JOF_CONST|JOF_NAME|JOF_SET|JOF_ASSIGNING)
250c213
< OPDEF(JSOP_THROW,     110,js_throw_str, NULL,         1,  1,  0,  0,  JOF_BYTE)
---
> OPDEF(JSOP_THROW,     110,"throw",      NULL,         1,  1,  0,  0,  JOF_BYTE)
253,254c216,217
< OPDEF(JSOP_IN,        111,js_in_str,    js_in_str,    1,  2,  1, 11,  JOF_BYTE|JOF_LEFTASSOC)
< OPDEF(JSOP_INSTANCEOF,112,js_instanceof_str,js_instanceof_str,1,2,1,11,JOF_BYTE|JOF_LEFTASSOC)
---
> OPDEF(JSOP_IN,        111,js_in_str,    js_in_str,    1,  2,  1,  6,  JOF_BYTE|JOF_LEFTASSOC)
> OPDEF(JSOP_INSTANCEOF,112,js_instanceof_str,js_instanceof_str,1,2,1,6,JOF_BYTE|JOF_LEFTASSOC)
260,261c223,224
< OPDEF(JSOP_GOSUB,     114,"gosub",      NULL,         3,  0,  0,  0,  JOF_JUMP)
< OPDEF(JSOP_RETSUB,    115,"retsub",     NULL,         1,  0,  0,  0,  JOF_BYTE)
---
> OPDEF(JSOP_GOSUB,     114,"gosub",      NULL,         3,  0,  1,  0,  JOF_JUMP)
> OPDEF(JSOP_RETSUB,    115,"retsub",     NULL,         1,  1,  0,  0,  JOF_BYTE)
265,267c228
< 
< /* Push the global object as |this| for a non-reference-type callable. */
< OPDEF(JSOP_GLOBALTHIS,117,"globalthis", js_null_str,  1,  0,  1,  0,  JOF_BYTE)
---
> OPDEF(JSOP_SETSP,     117,"setsp",      NULL,         3,  0,  0,  0,  JOF_UINT16)
274c235
< OPDEF(JSOP_CONDSWITCH,118,"condswitch", NULL,         1,  0,  0,  0,  JOF_BYTE|JOF_PARENHEAD)
---
> OPDEF(JSOP_CONDSWITCH,118,"condswitch", NULL,         1,  0,  0,  0,  JOF_BYTE)
281c242
< OPDEF(JSOP_EVAL,      121,"eval",       NULL,         3, -1,  1, 18,  JOF_UINT16|JOF_INVOKE)
---
> OPDEF(JSOP_EVAL,      121,"eval",       NULL,         3, -1,  1, 11,  JOF_UINT16)
286c247
< OPDEF(JSOP_ENUMELEM,  122,"enumelem",   NULL,         1,  3,  0,  3,  JOF_BYTE |JOF_SET)
---
> OPDEF(JSOP_ENUMELEM,  122,"enumelem",   NULL,         1,  3,  0,  1,  JOF_BYTE |JOF_SET|JOF_ASSIGNING)
293,294c254,255
< OPDEF(JSOP_GETTER,    123,js_getter_str,NULL,         1,  0,  0,  0,  JOF_BYTE)
< OPDEF(JSOP_SETTER,    124,js_setter_str,NULL,         1,  0,  0,  0,  JOF_BYTE)
---
> OPDEF(JSOP_GETTER,    123,js_getter_str,js_getter_str,1,  0,  0,  0,  JOF_BYTE)
> OPDEF(JSOP_SETTER,    124,js_setter_str,js_setter_str,1,  0,  0,  0,  JOF_BYTE)
299,301c260,262
< OPDEF(JSOP_DEFFUN,    125,"deffun",     NULL,         3,  0,  0,  0,  JOF_OBJECT|JOF_DECLARING)
< OPDEF(JSOP_DEFCONST,  126,"defconst",   NULL,         3,  0,  0,  0,  JOF_ATOM|JOF_DECLARING)
< OPDEF(JSOP_DEFVAR,    127,"defvar",     NULL,         3,  0,  0,  0,  JOF_ATOM|JOF_DECLARING)
---
> OPDEF(JSOP_DEFFUN,    125,"deffun",     NULL,         3,  0,  0,  0,  JOF_CONST)
> OPDEF(JSOP_DEFCONST,  126,"defconst",   NULL,         3,  0,  0,  0,  JOF_CONST|JOF_NAME)
> OPDEF(JSOP_DEFVAR,    127,"defvar",     NULL,         3,  0,  0,  0,  JOF_CONST|JOF_NAME)
304c265
< OPDEF(JSOP_ANONFUNOBJ,  128, "anonfunobj",  NULL,     3,  0,  1, 19,  JOF_OBJECT)
---
> OPDEF(JSOP_ANONFUNOBJ,  128, "anonfunobj",  NULL,     3,  0,  1, 12,  JOF_CONST)
307c268
< OPDEF(JSOP_NAMEDFUNOBJ, 129, "namedfunobj", NULL,     3,  0,  1, 19,  JOF_OBJECT)
---
> OPDEF(JSOP_NAMEDFUNOBJ, 129, "namedfunobj", NULL,     3,  0,  1, 12,  JOF_CONST)
309,313c270,271
< /*
<  * Like JSOP_SETLOCAL, but specialized to avoid requiring JSOP_POP immediately
<  * after to throw away the exception value.
<  */
< OPDEF(JSOP_SETLOCALPOP, 130, "setlocalpop", NULL,     3,  1,  0,  3,  JOF_LOCAL|JOF_NAME|JOF_SET)
---
> /* Like JSOP_INITPROP, but specialized to make a DontDelete property for ECMA ed. 3 catch variables. */
> OPDEF(JSOP_INITCATCHVAR,130, "initcatchvar",NULL,     3,  1,  0,  0,  JOF_CONST|JOF_PROP)
315,316c273,274
< /* Parenthesization opcode to help the decompiler. */
< OPDEF(JSOP_GROUP,       131, "group",       NULL,     1,  0,  0, 19,  JOF_BYTE)
---
> /* ECMA-mandated parenthesization opcode, which nulls the reference base register, obj; see jsinterp.c. */
> OPDEF(JSOP_GROUP,       131, "group",       NULL,     1,  0,  0,  0,  JOF_BYTE)
318,322c276,277
< /*
<  * Host object extension: given 'o.item(i) = j', the left-hand side compiles
<  * JSOP_SETCALL, rather than JSOP_CALL.
<  */
< OPDEF(JSOP_SETCALL,     132, "setcall",     NULL,     3, -1,  2, 18,  JOF_UINT16|JOF_SET)
---
> /* Host object extension: given 'o.item(i) = j', the left-hand side compiles JSOP_SETCALL, rather than JSOP_CALL. */
> OPDEF(JSOP_SETCALL,     132, "setcall",     NULL,     3, -1,  2, 11,  JOF_UINT16|JOF_SET|JOF_ASSIGNING)
332a288,290
>  * N.B. JSOP_SWAP doesn't swap the corresponding pc stack generating pcs, as
>  * they're not needed for the current use of preserving the top-of-stack return
>  * value when popping scopes while returning from catch blocks.
341,342c299,300
< OPDEF(JSOP_ARGSUB,      136,"argsub",     NULL,       3,  0,  1, 18,  JOF_QARG |JOF_NAME)
< OPDEF(JSOP_ARGCNT,      137,"argcnt",     NULL,       1,  0,  1, 18,  JOF_BYTE)
---
> OPDEF(JSOP_ARGSUB,      136,"argsub",     NULL,       3,  0,  1, 12,  JOF_QARG |JOF_NAME)
> OPDEF(JSOP_ARGCNT,      137,"argcnt",     NULL,       1,  0,  1, 12,  JOF_BYTE)
349c307
< OPDEF(JSOP_DEFLOCALFUN, 138,"deflocalfun",NULL,       5,  0,  0,  0,  JOF_SLOTOBJECT|JOF_DECLARING)
---
> OPDEF(JSOP_DEFLOCALFUN, 138,"deflocalfun",NULL,       5,  0,  0,  0,  JOF_DEFLOCALVAR)
353,357c311,315
< OPDEF(JSOP_IFEQX,         140,"ifeqx",    NULL,       5,  1,  0,  4,  JOF_JUMPX|JOF_DETECTING)
< OPDEF(JSOP_IFNEX,         141,"ifnex",    NULL,       5,  1,  0,  0,  JOF_JUMPX|JOF_PARENHEAD)
< OPDEF(JSOP_ORX,           142,"orx",      NULL,       5,  1,  0,  5,  JOF_JUMPX|JOF_DETECTING)
< OPDEF(JSOP_ANDX,          143,"andx",     NULL,       5,  1,  0,  6,  JOF_JUMPX|JOF_DETECTING)
< OPDEF(JSOP_GOSUBX,        144,"gosubx",   NULL,       5,  0,  0,  0,  JOF_JUMPX)
---
> OPDEF(JSOP_IFEQX,         140,"ifeqx",    NULL,       5,  1,  0,  0,  JOF_JUMPX)
> OPDEF(JSOP_IFNEX,         141,"ifnex",    NULL,       5,  1,  0,  0,  JOF_JUMPX)
> OPDEF(JSOP_ORX,           142,"orx",      NULL,       5,  1,  0,  0,  JOF_JUMPX)
> OPDEF(JSOP_ANDX,          143,"andx",     NULL,       5,  1,  0,  0,  JOF_JUMPX)
> OPDEF(JSOP_GOSUBX,        144,"gosubx",   NULL,       5,  0,  1,  0,  JOF_JUMPX)
360,361c318,319
< OPDEF(JSOP_TABLESWITCHX,  147,"tableswitchx",NULL,   -1,  1,  0,  0,  JOF_TABLESWITCHX|JOF_DETECTING|JOF_PARENHEAD)
< OPDEF(JSOP_LOOKUPSWITCHX, 148,"lookupswitchx",NULL,  -1,  1,  0,  0,  JOF_LOOKUPSWITCHX|JOF_DETECTING|JOF_PARENHEAD)
---
> OPDEF(JSOP_TABLESWITCHX,  147,"tableswitchx",NULL,   -1,  1,  0,  0,  JOF_TABLESWITCHX)
> OPDEF(JSOP_LOOKUPSWITCHX, 148,"lookupswitchx",NULL,  -1,  1,  0,  0,  JOF_LOOKUPSWITCHX)
366,368c324
< 
< /* Set pending exception from the stack, to trigger rethrow. */
< OPDEF(JSOP_THROWING,      151,"throwing", NULL,       1,  1,  0,  0,  JOF_BYTE)
---
> OPDEF(JSOP_BACKPATCH_PUSH,151,"backpatch_push",NULL,  3,  0,  1,  0,  JOF_JUMP|JOF_BACKPATCH)
371c327
< OPDEF(JSOP_SETRVAL,       152,"setrval",  NULL,       1,  1,  0,  2,  JOF_BYTE)
---
> OPDEF(JSOP_SETRVAL,       152,"setrval",  NULL,       1,  1,  0,  0,  JOF_BYTE)
373,521d328
< 
< /* Optimized global variable ops (we don't bother doing a JSOP_FORGVAR op). */
< OPDEF(JSOP_GETGVAR,       154,"getgvar",  NULL,       3,  0,  1, 19,  JOF_ATOM|JOF_NAME)
< OPDEF(JSOP_SETGVAR,       155,"setgvar",  NULL,       3,  1,  1,  3,  JOF_ATOM|JOF_NAME|JOF_SET|JOF_DETECTING)
< OPDEF(JSOP_INCGVAR,       156,"incgvar",  NULL,       3,  0,  1, 15,  JOF_ATOM|JOF_NAME|JOF_INC)
< OPDEF(JSOP_DECGVAR,       157,"decgvar",  NULL,       3,  0,  1, 15,  JOF_ATOM|JOF_NAME|JOF_DEC)
< OPDEF(JSOP_GVARINC,       158,"gvarinc",  NULL,       3,  0,  1, 15,  JOF_ATOM|JOF_NAME|JOF_INC|JOF_POST)
< OPDEF(JSOP_GVARDEC,       159,"gvardec",  NULL,       3,  0,  1, 15,  JOF_ATOM|JOF_NAME|JOF_DEC|JOF_POST)
< 
< /* Regular expression literal requiring special "fork on exec" handling. */
< OPDEF(JSOP_REGEXP,        160,"regexp",   NULL,       3,  0,  1, 19,  JOF_REGEXP)
< 
< /* XML (ECMA-357, a.k.a. "E4X") support. */
< OPDEF(JSOP_DEFXMLNS,      161,"defxmlns",   NULL,     1,  1,  0,  0,  JOF_BYTE)
< OPDEF(JSOP_ANYNAME,       162,"anyname",    NULL,     1,  0,  1, 19,  JOF_BYTE|JOF_XMLNAME)
< OPDEF(JSOP_QNAMEPART,     163,"qnamepart",  NULL,     3,  0,  1, 19,  JOF_ATOM|JOF_XMLNAME)
< OPDEF(JSOP_QNAMECONST,    164,"qnameconst", NULL,     3,  1,  1, 19,  JOF_ATOM|JOF_XMLNAME)
< OPDEF(JSOP_QNAME,         165,"qname",      NULL,     1,  2,  1,  0,  JOF_BYTE|JOF_XMLNAME)
< OPDEF(JSOP_TOATTRNAME,    166,"toattrname", NULL,     1,  1,  1, 19,  JOF_BYTE|JOF_XMLNAME)
< OPDEF(JSOP_TOATTRVAL,     167,"toattrval",  NULL,     1,  1,  1, 19,  JOF_BYTE)
< OPDEF(JSOP_ADDATTRNAME,   168,"addattrname",NULL,     1,  2,  1, 13,  JOF_BYTE)
< OPDEF(JSOP_ADDATTRVAL,    169,"addattrval", NULL,     1,  2,  1, 13,  JOF_BYTE)
< OPDEF(JSOP_BINDXMLNAME,   170,"bindxmlname",NULL,     1,  1,  2,  3,  JOF_BYTE|JOF_SET)
< OPDEF(JSOP_SETXMLNAME,    171,"setxmlname", NULL,     1,  3,  1,  3,  JOF_BYTE|JOF_SET|JOF_DETECTING)
< OPDEF(JSOP_XMLNAME,       172,"xmlname",    NULL,     1,  1,  1, 19,  JOF_BYTE)
< OPDEF(JSOP_DESCENDANTS,   173,"descendants",NULL,     1,  2,  1, 18,  JOF_BYTE)
< OPDEF(JSOP_FILTER,        174,"filter",     NULL,     3,  1,  1,  0,  JOF_JUMP)
< OPDEF(JSOP_ENDFILTER,     175,"endfilter",  NULL,     3,  2,  1, 18,  JOF_JUMP)
< OPDEF(JSOP_TOXML,         176,"toxml",      NULL,     1,  1,  1, 19,  JOF_BYTE)
< OPDEF(JSOP_TOXMLLIST,     177,"toxmllist",  NULL,     1,  1,  1, 19,  JOF_BYTE)
< OPDEF(JSOP_XMLTAGEXPR,    178,"xmltagexpr", NULL,     1,  1,  1,  0,  JOF_BYTE)
< OPDEF(JSOP_XMLELTEXPR,    179,"xmleltexpr", NULL,     1,  1,  1,  0,  JOF_BYTE)
< OPDEF(JSOP_XMLOBJECT,     180,"xmlobject",  NULL,     3,  0,  1, 19,  JOF_OBJECT)
< OPDEF(JSOP_XMLCDATA,      181,"xmlcdata",   NULL,     3,  0,  1, 19,  JOF_ATOM)
< OPDEF(JSOP_XMLCOMMENT,    182,"xmlcomment", NULL,     3,  0,  1, 19,  JOF_ATOM)
< OPDEF(JSOP_XMLPI,         183,"xmlpi",      NULL,     3,  1,  1, 19,  JOF_ATOM)
< OPDEF(JSOP_CALLPROP,      184,"callprop",   NULL,     3,  1,  2, 18,  JOF_ATOM|JOF_PROP|JOF_CALLOP)
< OPDEF(JSOP_GETFUNNS,      185,"getfunns",   NULL,     1,  0,  1, 19,  JOF_BYTE)
< OPDEF(JSOP_FOREACH,       186,"foreach",    NULL,     1,  1,  1,  0,  JOF_BYTE)
< OPDEF(JSOP_DELDESC,       187,"deldesc",    NULL,     1,  2,  1, 17,  JOF_BYTE |JOF_ELEM|JOF_DEL)
< 
< /*
<  * Opcode to hold 24-bit immediate integer operands.
<  */
< OPDEF(JSOP_UINT24,        188,"uint24",     NULL,     4,  0,  1, 16,  JOF_UINT24)
< 
< /*
<  * Opcodes to allow 24-bit atom or object indexes. Whenever an index exceeds
<  * the 16-bit limit, the index-accessing bytecode must be bracketed by
<  * JSOP_INDEXBASE and JSOP_RESETBASE to provide the upper bits of the index.
<  * See jsemit.c, EmitIndexOp.
<  */
< OPDEF(JSOP_INDEXBASE,     189,"atombase",   NULL,     2,  0,  0,  0,  JOF_2BYTE|JOF_INDEXBASE)
< OPDEF(JSOP_RESETBASE,     190,"resetbase",  NULL,     1,  0,  0,  0,  JOF_BYTE)
< OPDEF(JSOP_RESETBASE0,    191,"resetbase0", NULL,     1,  0,  0,  0,  JOF_BYTE)
< 
< /*
<  * Opcodes to help the decompiler deal with XML.
<  */
< OPDEF(JSOP_STARTXML,      192,"startxml",    NULL,    1,  0,  0,  0,  JOF_BYTE)
< OPDEF(JSOP_STARTXMLEXPR,  193,"startxmlexpr",NULL,    1,  0,  0,  0,  JOF_BYTE)
< 
< OPDEF(JSOP_CALLELEM,      194, "callelem",   NULL,    1,  2,  2, 18,  JOF_BYTE |JOF_ELEM|JOF_LEFTASSOC|JOF_CALLOP)
< 
< /*
<  * Stop interpretation, emitted at end of script to save the threaded bytecode
<  * interpreter an extra branch test on every DO_NEXT_OP (see jsinterp.c).
<  */
< OPDEF(JSOP_STOP,          195,"stop",        NULL,    1,  0,  0,  0,  JOF_BYTE)
< 
< /*
<  * Get an extant property value, throwing ReferenceError if the identified
<  * property does not exist.
<  */
< OPDEF(JSOP_GETXPROP,      196,"getxprop",    NULL,    3,  1,  1, 18,  JOF_ATOM|JOF_PROP)
< 
< OPDEF(JSOP_CALLXMLNAME,   197, "callxmlname",  NULL,  1,  1,  2, 19,  JOF_BYTE|JOF_CALLOP)
< 
< /*
<  * Specialized JSOP_TYPEOF to avoid reporting undefined for typeof(0, undef).
<  */
< OPDEF(JSOP_TYPEOFEXPR,    198,"typeofexpr",  NULL,    1,  1,  1, 15,  JOF_BYTE|JOF_DETECTING)
< 
< /*
<  * Block-local scope support.
<  */
< OPDEF(JSOP_ENTERBLOCK,    199,"enterblock",  NULL,    3,  0,  0,  0,  JOF_OBJECT)
< OPDEF(JSOP_LEAVEBLOCK,    200,"leaveblock",  NULL,    3,  0,  0,  0,  JOF_UINT16)
< OPDEF(JSOP_GETLOCAL,      201,"getlocal",    NULL,    3,  0,  1, 19,  JOF_LOCAL|JOF_NAME)
< OPDEF(JSOP_SETLOCAL,      202,"setlocal",    NULL,    3,  1,  1,  3,  JOF_LOCAL|JOF_NAME|JOF_SET)
< OPDEF(JSOP_INCLOCAL,      203,"inclocal",    NULL,    3,  0,  1, 15,  JOF_LOCAL|JOF_NAME|JOF_INC)
< OPDEF(JSOP_DECLOCAL,      204,"declocal",    NULL,    3,  0,  1, 15,  JOF_LOCAL|JOF_NAME|JOF_DEC)
< OPDEF(JSOP_LOCALINC,      205,"localinc",    NULL,    3,  0,  1, 15,  JOF_LOCAL|JOF_NAME|JOF_INC|JOF_POST)
< OPDEF(JSOP_LOCALDEC,      206,"localdec",    NULL,    3,  0,  1, 15,  JOF_LOCAL|JOF_NAME|JOF_DEC|JOF_POST)
< OPDEF(JSOP_FORLOCAL,      207,"forlocal",    NULL,    3,  0,  1, 19,  JOF_LOCAL|JOF_NAME|JOF_FOR)
< 
< /*
<  * Iterator, generator, and array comprehension support.
<  */
< OPDEF(JSOP_FORCONST,      208,"forconst",    NULL,    3,  0,  1, 19,  JOF_QVAR|JOF_NAME|JOF_FOR)
< OPDEF(JSOP_ENDITER,       209,"enditer",     NULL,    1,  1,  0,  0,  JOF_BYTE|JOF_TMPSLOT)
< OPDEF(JSOP_GENERATOR,     210,"generator",   NULL,    1,  0,  0,  0,  JOF_BYTE)
< OPDEF(JSOP_YIELD,         211,"yield",       NULL,    1,  1,  1,  1,  JOF_BYTE)
< OPDEF(JSOP_ARRAYPUSH,     212,"arraypush",   NULL,    3,  1,  0,  3,  JOF_LOCAL)
< 
< OPDEF(JSOP_FOREACHKEYVAL, 213,"foreachkeyval",NULL,   1,  1,  1,  0,  JOF_BYTE)
< 
< /*
<  * Variant of JSOP_ENUMELEM for destructuring const (const [a, b] = ...).
<  */
< OPDEF(JSOP_ENUMCONSTELEM, 214,"enumconstelem",NULL,   1,  3,  0,  3,  JOF_BYTE|JOF_SET)
< 
< /*
<  * Variant of JSOP_LEAVEBLOCK has a result on the stack above the locals,
<  * which must be moved down when the block pops.
<  */
< OPDEF(JSOP_LEAVEBLOCKEXPR,215,"leaveblockexpr",NULL,  3,  0,  0,  1,  JOF_UINT16)
< 
< /*
<  * Optimize common JSOP_{THIS,GET{ARG,VAR,LOCAL}} -> JSOP_GETPROP cliches.
<  */
< OPDEF(JSOP_GETTHISPROP,   216,"getthisprop",   NULL,  3,  0,  1, 18,  JOF_ATOM)
< OPDEF(JSOP_GETARGPROP,    217,"getargprop",    NULL,  5,  0,  1, 18,  JOF_SLOTATOM|JOF_VARPROP)
< OPDEF(JSOP_GETVARPROP,    218,"getvarprop",    NULL,  5,  0,  1, 18,  JOF_SLOTATOM|JOF_VARPROP)
< OPDEF(JSOP_GETLOCALPROP,  219,"getlocalprop",  NULL,  5,  0,  1, 18,  JOF_SLOTATOM|JOF_VARPROP)
< 
< /*
<  * Optimize atom segments 1-3.  These must be followed by JSOP_RESETBASE0 after
<  * the opcode that they prefix.
<  */
< OPDEF(JSOP_INDEXBASE1,    220,"atombase1",     NULL,  1,  0,  0,  0,  JOF_BYTE |JOF_INDEXBASE)
< OPDEF(JSOP_INDEXBASE2,    221,"atombase2",     NULL,  1,  0,  0,  0,  JOF_BYTE |JOF_INDEXBASE)
< OPDEF(JSOP_INDEXBASE3,    222,"atombase3",     NULL,  1,  0,  0,  0,  JOF_BYTE |JOF_INDEXBASE)
< 
< OPDEF(JSOP_CALLGVAR,      223, "callgvar",     NULL,  3,  0,  2, 19,  JOF_ATOM|JOF_NAME|JOF_CALLOP)
< OPDEF(JSOP_CALLVAR,       224, "callvar",      NULL,  3,  0,  2, 19,  JOF_QVAR |JOF_NAME|JOF_CALLOP)
< OPDEF(JSOP_CALLARG,       225, "callarg",      NULL,  3,  0,  2, 19,  JOF_QARG |JOF_NAME|JOF_CALLOP)
< OPDEF(JSOP_CALLLOCAL,     226, "calllocal",    NULL,  3,  0,  2, 19,  JOF_LOCAL|JOF_NAME|JOF_CALLOP)
< 
< /*
<  * Opcodes to hold 8-bit and 32-bit immediate integer operands.
<  */
< OPDEF(JSOP_INT8,          227, "int8",         NULL,  2,  0,  1, 16,  JOF_INT8)
< OPDEF(JSOP_INT32,         228, "int32",        NULL,  5,  0,  1, 16,  JOF_INT32)
< 
< /*
<  * Get the value of the 'length' property from a stacked object.
<  */
< OPDEF(JSOP_LENGTH,        229, "length",       NULL,  1,  1,  1, 18,  JOF_BYTE|JOF_PROP)
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsosdep.h /Volumes/Swap/js_D11/src/jsosdep.h
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
54a50,64
> #ifdef XP_MAC
> #define JS_HAVE_LONG_LONG
> 
> JS_BEGIN_EXTERN_C
> 
> #include <stddef.h>
> 
> extern void* reallocSmaller(void* block, size_t newSize);
> 
> extern char* strdup(const char* str);
> 
> JS_END_EXTERN_C
> 
> #endif /* XP_MAC */
> 
65,68c75
< #if defined(XP_MACOSX) || defined(DARWIN)
< #define JS_HAVE_LONG_LONG
< 
< #elif defined(AIXV3) || defined(AIX)
---
> #if defined(AIXV3) || defined(AIX)
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsotypes.h /Volumes/Swap/js_D11/src/jsotypes.h
2,13c2,11
< /* ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
> /*
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
18,37c16,33
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
78c74
< #if !defined(_WIN32) && !defined(XP_OS2)
---
> #if !defined(XP_MAC) && !defined(_WIN32) && !defined(XP_OS2)
96c92
< #if defined(AIX) && defined(HAVE_SYS_INTTYPES_H)
---
> #ifdef AIX4_3
105c101
< #if !defined(_WIN32) && !defined(XP_OS2)
---
> #if !defined(XP_MAC) && !defined(_WIN32) && !defined(XP_OS2)
113c109
< #endif /* AIX && HAVE_SYS_INTTYPES_H */
---
> #endif /* AIX4_3 */
115c111
< #endif  /* XP_BEOS */
---
> #endif	/* XP_BEOS */
120,122c116,118
< #define TEST_BIT        JS_TEST_BIT
< #define SET_BIT         JS_SET_BIT
< #define CLEAR_BIT       JS_CLEAR_BIT
---
> #define TEST_BIT	JS_TEST_BIT
> #define SET_BIT		JS_SET_BIT
> #define CLEAR_BIT	JS_CLEAR_BIT
201a198,206
> #ifdef XP_MAC
> #ifndef TRUE				/* Mac standard is lower case true */
> 	#define TRUE 1
> #endif
> #ifndef FALSE				/* Mac standard is lower case false */
> 	#define FALSE 0
> #endif
> #endif
> 
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsparse.c /Volumes/Swap/js_D11/src/jsparse.c
2d1
<  * vim: set ts=8 sw=4 et tw=78:
4,15c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
20,23c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
27,39c23,33
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
52c46,48
<  * This parser attempts no error recovery.
---
>  * This parser attempts no error recovery.  The dense JSTokenType enumeration
>  * was designed with error recovery built on 64-bit first and follow bitsets
>  * in mind, however.
55c51
< #include <stdlib.h>
---
> #include "xstdlib.h"
62d57
< #include "jsarray.h"
79,93c74
< #if JS_HAS_XML_SUPPORT
< #include "jsxml.h"
< #endif
< 
< #if JS_HAS_DESTRUCTURING
< #include "jsdhash.h"
< #endif
< 
< /*
<  * Asserts to verify assumptions behind pn_ macros.
<  */
< JS_STATIC_ASSERT(offsetof(JSParseNode, pn_u.name.atom) ==
<                  offsetof(JSParseNode, pn_u.apair.atom));
< JS_STATIC_ASSERT(offsetof(JSParseNode, pn_u.name.slot) ==
<                  offsetof(JSParseNode, pn_u.lexical.slot));
---
> //#include "_optimize.h"
98,99c79,80
<  * Each parser takes a context, a token stream, and a tree context struct.
<  * Each returns a parse node tree or null on error.
---
>  * Each parser takes a context and a token stream, and emits bytecode using
>  * a code generator.
109,116d89
< typedef JSParseNode *
< JSPrimaryParser(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
<                 JSTokenType tt, JSBool afterDot);
< 
< typedef JSParseNode *
< JSParenParser(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
<               JSParseNode *pn1, JSBool *genexp);
< 
117a91
> #if JS_HAS_LEXICAL_CLOSURE
118a93
> #endif
136,138c111,112
< static JSMemberParser  MemberExpr;
< static JSPrimaryParser PrimaryExpr;
< static JSParenParser   ParenExpr;
---
> static JSMemberParser MemberExpr;
> static JSParser PrimaryExpr;
158,240c132
< JSBool
< js_InitParseContext(JSContext *cx, JSParseContext *pc, JSPrincipals *principals,
<                     const jschar *base, size_t length,
<                     FILE *fp, const char *filename, uintN lineno)
< {
<     pc->tempPoolMark = JS_ARENA_MARK(&cx->tempPool);
<     if (!js_InitTokenStream(cx, TS(pc), base, length, fp, filename, lineno)) {
<         JS_ARENA_RELEASE(&cx->tempPool, pc->tempPoolMark);
<         return JS_FALSE;
<     }
<     if (principals)
<         JSPRINCIPALS_HOLD(cx, principals);
<     pc->principals = principals;
<     pc->nodeList = NULL;
<     pc->traceListHead = NULL;
< 
<     /* Root atoms and objects allocated for the parsed tree. */
<     JS_KEEP_ATOMS(cx->runtime);
<     JS_PUSH_TEMP_ROOT_PARSE_CONTEXT(cx, pc, &pc->tempRoot);
<     return JS_TRUE;
< }
< 
< void
< js_FinishParseContext(JSContext *cx, JSParseContext *pc)
< {
<     if (pc->principals)
<         JSPRINCIPALS_DROP(cx, pc->principals);
<     JS_ASSERT(pc->tempRoot.u.parseContext == pc);
<     JS_POP_TEMP_ROOT(cx, &pc->tempRoot);
<     JS_UNKEEP_ATOMS(cx->runtime);
<     js_CloseTokenStream(cx, TS(pc));
<     JS_ARENA_RELEASE(&cx->tempPool, pc->tempPoolMark);
< }
< 
< void
< js_InitCompilePrincipals(JSContext *cx, JSParseContext *pc,
<                          JSPrincipals *principals)
< {
<     JS_ASSERT(!pc->principals);
<     if (principals)
<         JSPRINCIPALS_HOLD(cx, principals);
<     pc->principals = principals;
< }
< 
< JSParsedObjectBox *
< js_NewParsedObjectBox(JSContext *cx, JSParseContext *pc, JSObject *obj)
< {
<     JSParsedObjectBox *pob;
< 
<     /*
<      * We use JSContext.tempPool to allocate parsed objects and place them on
<      * a list in JSTokenStream to ensure GC safety. Thus the tempPool arenas
<      * containing the entries must be alive until we are done with scanning,
<      * parsing and code generation for the whole script or top-level function.
<      */
<     JS_ASSERT(obj);
<     JS_ARENA_ALLOCATE_TYPE(pob, JSParsedObjectBox, &cx->tempPool);
<     if (!pob) {
<         js_ReportOutOfScriptQuota(cx);
<         return NULL;
<     }
<     pob->traceLink = pc->traceListHead;
<     pob->emitLink = NULL;
<     pob->object = obj;
<     pc->traceListHead = pob;
<     return pob;
< }
< 
< 
< void
< js_TraceParseContext(JSTracer *trc, JSParseContext *pc)
< {
<     JSParsedObjectBox *pob;
< 
<     JS_ASSERT(pc->tempRoot.u.parseContext == pc);
<     pob = pc->traceListHead;
<     while (pob) {
<         JS_CALL_OBJECT_TRACER(trc, pob->object, "parser.object");
<         pob = pob->traceLink;
<     }
< }
< 
< static JSParseNode *
---
> static void
243,244d134
<     JSParseNode *next;
< 
246,252c136,139
<         return NULL;
< 
<     /* Catch back-to-back dup recycles. */
<     JS_ASSERT(pn != tc->parseContext->nodeList);
<     next = pn->pn_next;
<     pn->pn_next = tc->parseContext->nodeList;
<     tc->parseContext->nodeList = pn;
---
>         return;
>     JS_ASSERT(pn != tc->nodeList);      /* catch back-to-back dup recycles */
>     pn->pn_next = tc->nodeList;
>     tc->nodeList = pn;
256d142
<     return next;
264c150
<     pn = tc->parseContext->nodeList;
---
>     pn = tc->nodeList;
268c154
<             js_ReportOutOfScriptQuota(cx);
---
>             JS_ReportOutOfMemory(cx);
270c156
<         tc->parseContext->nodeList = pn->pn_next;
---
>         tc->nodeList = pn->pn_next;
280,281c166,167
<                 *pn->pn_tail = tc->parseContext->nodeList;
<                 tc->parseContext->nodeList = pn->pn_head;
---
>                 *pn->pn_tail = tc->nodeList;
>                 tc->nodeList = pn->pn_head;
306,314d191
<     if (pn) {
< #ifdef METER_PARSENODES
<         parsenodes++;
<         if (parsenodes - recyclednodes > maxparsenodes)
<             maxparsenodes = parsenodes - recyclednodes;
< #endif
<         memset(&pn->pn_u, 0, sizeof pn->pn_u);
<         pn->pn_next = NULL;
<     }
322c199
< NewParseNode(JSContext *cx, JSTokenStream *ts, JSParseNodeArity arity,
---
> NewParseNode(JSContext *cx, JSToken *tok, JSParseNodeArity arity,
326d202
<     JSToken *tp;
331,333c207,208
<     tp = &CURRENT_TOKEN(ts);
<     pn->pn_type = tp->type;
<     pn->pn_pos = tp->pos;
---
>     pn->pn_type = tok->type;
>     pn->pn_pos = tok->pos;
335a211,216
>     pn->pn_next = NULL;
> #ifdef METER_PARSENODES
>     parsenodes++;
>     if (parsenodes - recyclednodes > maxparsenodes)
>         maxparsenodes = parsenodes - recyclednodes;
> #endif
360a242
>             left->pn_extra = 0;
394d275
<         left->pn_pos.end = right->pn_pos.end;
408a290,295
>     pn->pn_next = NULL;
> #ifdef METER_PARSENODES
>     parsenodes++;
>     if (parsenodes - recyclednodes > maxparsenodes)
>         maxparsenodes = parsenodes - recyclednodes;
> #endif
411a299,325
> static JSBool
> WellTerminated(JSContext *cx, JSTokenStream *ts, JSTokenType lastExprType)
> {
>     JSTokenType tt;
> 
>     tt = js_PeekTokenSameLine(cx, ts);
>     if (tt == TOK_ERROR)
>         return JS_FALSE;
>     if (tt != TOK_EOF && tt != TOK_EOL && tt != TOK_SEMI && tt != TOK_RC) {
> #if JS_HAS_LEXICAL_CLOSURE
>         if ((tt == TOK_FUNCTION || lastExprType == TOK_FUNCTION) &&
>             cx->version < JSVERSION_1_2) {
>             /*
>              * Checking against version < 1.2 and version >= 1.0
>              * in the above line breaks old javascript, so we keep it
>              * this way for now... XXX warning needed?
>              */
>             return JS_TRUE;
>         }
> #endif
>         js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
>                                     JSMSG_SEMI_BEFORE_STMNT);
>         return JS_FALSE;
>     }
>     return JS_TRUE;
> }
> 
419d332
<     const char *name;
442,450c355,360
<     if (JS_HAS_STRICT_OPTION(cx)) {
<         name = js_AtomToPrintableString(cx, atom);
<         if (!name ||
<             !js_ReportCompileErrorNumber(cx, ts, NULL,
<                                          JSREPORT_WARNING | JSREPORT_STRICT,
<                                          JSMSG_DEPRECATED_USAGE,
<                                          name)) {
<             return TOK_ERROR;
<         }
---
>     if (!js_ReportCompileErrorNumber(cx, ts, NULL,
>                                      JSREPORT_WARNING |
>                                      JSREPORT_STRICT,
>                                      JSMSG_DEPRECATED_USAGE,
>                                      ATOM_BYTES(atom))) {
>         return TOK_ERROR;
456,502d365
< static void
< MaybeSetupFrame(JSContext *cx, JSObject *chain, JSStackFrame *oldfp,
<                 JSStackFrame *newfp)
< {
<     /*
<      * Always push a new frame if the current frame is special, so that
<      * Variables gets the correct variables object: the one from the special
<      * frame's caller.
<      */
<     if (oldfp &&
<         oldfp->varobj &&
<         oldfp->scopeChain == chain &&
<         !(oldfp->flags & JSFRAME_SPECIAL)) {
<         return;
<     }
< 
<     memset(newfp, 0, sizeof *newfp);
< 
<     /* Default to sharing the same variables object and scope chain. */
<     newfp->varobj = newfp->scopeChain = chain;
<     if (cx->options & JSOPTION_VAROBJFIX) {
<         while ((chain = JS_GetParent(cx, chain)) != NULL)
<             newfp->varobj = chain;
<     }
<     newfp->down = oldfp;
<     if (oldfp) {
<         /*
<          * In the case of eval and debugger frames, we need to dig down and find
<          * the real variables objects and function that our new stack frame is
<          * going to use.
<          */
<         newfp->flags = oldfp->flags & (JSFRAME_SPECIAL | JSFRAME_SCRIPT_OBJECT);
<         while (oldfp->flags & JSFRAME_SPECIAL) {
<             oldfp = oldfp->down;
<             if (!oldfp)
<                 break;
<         }
<         if (oldfp && (newfp->flags & JSFRAME_SPECIAL)) {
<             newfp->varobj = oldfp->varobj;
<             newfp->vars = oldfp->vars;
<             newfp->callee = oldfp->callee;
<             newfp->fun = oldfp->fun;
<         }
<     }
<     cx->fp = newfp;
< }
< 
506,507c369,370
< JSParseNode *
< js_ParseScript(JSContext *cx, JSObject *chain, JSParseContext *pc)
---
> JS_FRIEND_API(JSParseNode *)
> js_ParseTokenStream(JSContext *cx, JSObject *chain, JSTokenStream *ts)
519c382,391
<     MaybeSetupFrame(cx, chain, fp, &frame);
---
>     if (!fp || !fp->varobj || fp->scopeChain != chain) {
>         memset(&frame, 0, sizeof frame);
>         frame.varobj = frame.scopeChain = chain;
>         if (cx->options & JSOPTION_VAROBJFIX) {
>             while ((chain = JS_GetParent(cx, chain)) != NULL)
>                 frame.varobj = chain;
>         }
>         frame.down = fp;
>         cx->fp = &frame;
>     }
522,530c394,401
<      * Protect atoms from being collected by a GC activation, which might
<      * - nest on this thread due to out of memory (the so-called "last ditch"
<      *   GC attempted within js_NewGCThing), or
<      * - run for any reason on another thread if this thread is suspended on
<      *   an object lock before it finishes generating bytecode into a script
<      *   protected from the GC by a root or a stack frame reference.
<      */
<     TREE_CONTEXT_INIT(&tc, pc);
<     pn = Statements(cx, TS(pc), &tc);
---
>      * Prevent GC activation (possible if out of memory when atomizing,
>      * or from pre-ECMAv2 switch case expr eval in the unlikely case of a
>      * branch-callback -- unlikely because it means the switch case must
>      * have called a function).
>      */
>     JS_DISABLE_GC(cx->runtime);
>     TREE_CONTEXT_INIT(&tc);
>     pn = Statements(cx, ts, &tc);
532,533c403,404
<         if (!js_MatchToken(cx, TS(pc), TOK_EOF)) {
<             js_ReportCompileErrorNumber(cx, TS(pc), NULL, JSREPORT_ERROR,
---
>         if (!js_MatchToken(cx, ts, TOK_EOF)) {
>             js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
543a415
>     JS_ENABLE_GC(cx->runtime);
551,554c423,425
< JSScript *
< js_CompileScript(JSContext *cx, JSObject *obj, JSPrincipals *principals,
<                  uint32 tcflags, const jschar *chars, size_t length,
<                  FILE *file, const char *filename, uintN lineno)
---
> JS_FRIEND_API(JSBool)
> js_CompileTokenStream(JSContext *cx, JSObject *chain, JSTokenStream *ts,
>                       JSCodeGenerator *cg)
556d426
<     JSParseContext pc;
558,560d427
<     JSArenaPool codePool, notePool;
<     JSCodeGenerator cg;
<     JSTokenType tt;
562c429
<     JSScript *script;
---
>     JSBool ok;
567,573d433
<     JS_ASSERT(!(tcflags & ~TCF_COMPILE_N_GO));
< 
<     if (!js_InitParseContext(cx, &pc, principals, chars, length, file,
<                              filename, lineno)) {
<         return NULL;
<     }
< 
575,576d434
<      * From this point the control must flow through the label out.
<      *
582,606c440,445
<     MaybeSetupFrame(cx, obj, fp, &frame);
< 
<     JS_INIT_ARENA_POOL(&codePool, "code", 1024, sizeof(jsbytecode),
<                        &cx->scriptStackQuota);
<     JS_INIT_ARENA_POOL(&notePool, "note", 1024, sizeof(jssrcnote),
<                        &cx->scriptStackQuota);
<     js_InitCodeGenerator(cx, &cg, &pc, &codePool, &notePool,
<                          pc.tokenStream.lineno);
< 
<     /* From this point the control must flow via the label out. */
<     cg.treeContext.flags |= tcflags;
< 
<     /*
<      * Inline Statements() to emit as we go to save space.
<      */
<     for (;;) {
<         pc.tokenStream.flags |= TSF_OPERAND;
<         tt = js_PeekToken(cx, &pc.tokenStream);
<         pc.tokenStream.flags &= ~TSF_OPERAND;
<         if (tt <= TOK_EOF) {
<             if (tt == TOK_EOF)
<                 break;
<             JS_ASSERT(tt == TOK_ERROR);
<             script = NULL;
<             goto out;
---
>     if (!fp || !fp->varobj || fp->scopeChain != chain) {
>         memset(&frame, 0, sizeof frame);
>         frame.varobj = frame.scopeChain = chain;
>         if (cx->options & JSOPTION_VAROBJFIX) {
>             while ((chain = JS_GetParent(cx, chain)) != NULL)
>                 frame.varobj = chain;
608,626c447,448
< 
<         pn = Statement(cx, &pc.tokenStream, &cg.treeContext);
<         if (!pn) {
<             script = NULL;
<             goto out;
<         }
< 
<         /*
<          * FIXME bug 346749: let declarations at the top level in a script are
<          * turned into var declarations and do not introduce block nodes.
<          */
<         JS_ASSERT(!cg.treeContext.blockNode);
< 
<         if (!js_FoldConstants(cx, pn, &cg.treeContext) ||
<             !js_EmitTree(cx, &cg, pn)) {
<             script = NULL;
<             goto out;
<         }
<         RecycleTree(pn, &cg.treeContext);
---
>         frame.down = fp;
>         cx->fp = &frame;
628a451,461
>     /* Prevent GC activation while compiling. */
>     JS_DISABLE_GC(cx->runtime);
> 
>     pn = Statements(cx, ts, &cg->treeContext);
>     if (!pn) {
>         ok = JS_FALSE;
>     } else if (!js_MatchToken(cx, ts, TOK_EOF)) {
>         js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
>                                     JSMSG_SYNTAX_ERROR);
>         ok = JS_FALSE;
>     } else {
630,635c463,468
<     printf("Parser growth: %d (%u nodes, %u max, %u unrecycled)\n",
<            (char *)sbrk(0) - (char *)before,
<            parsenodes,
<            maxparsenodes,
<            parsenodes - recyclednodes);
<     before = sbrk(0);
---
>         printf("Parser growth: %d (%u nodes, %u max, %u unrecycled)\n",
>                (char *)sbrk(0) - (char *)before,
>                parsenodes,
>                maxparsenodes,
>                parsenodes - recyclednodes);
>         before = sbrk(0);
638,644c471,479
<     /*
<      * Nowadays the threaded interpreter needs a stop instruction, so we
<      * do have to emit that here.
<      */
<     if (js_Emit1(cx, &cg, JSOP_STOP) < 0) {
<         script = NULL;
<         goto out;
---
>         /*
>          * No need to emit code here -- Statements already has, for each
>          * statement in turn.  Search for TCF_COMPILING in Statements, below.
>          * That flag is set for every tc == &cg->treeContext, and it implies
>          * that the tc can be downcast to a cg and used to emit code during
>          * parsing, rather than at the end of the parse phase.
>          */
>         JS_ASSERT(cg->treeContext.flags & TCF_COMPILING);
>         ok = JS_TRUE;
645a481
> 
653,668c489
<     script = js_NewScriptFromCG(cx, &cg);
< 
< #ifdef JS_SCOPE_DEPTH_METER
<     if (script) {
<         JSObject *pobj = obj;
<         uintN depth = 1;
<         while ((pobj = OBJ_GET_PARENT(cx, pobj)) != NULL)
<             ++depth;
<         JS_BASIC_STATS_ACCUM(&cx->runtime->hostenvScopeDepthStats, depth);
<     }
< #endif
< 
<   out:
<     js_FinishCodeGenerator(cx, &cg);
<     JS_FinishArenaPool(&codePool);
<     JS_FinishArenaPool(&notePool);
---
>     JS_ENABLE_GC(cx->runtime);
670,671c491
<     js_FinishParseContext(cx, &pc);
<     return script;
---
>     return ok;
675,678c495,497
<  * Insist on a final return before control flows out of pn.  Try to be a bit
<  * smart about loops: do {...; return e2;} while(0) at the end of a function
<  * that contains an early return e1 will get a strict warning.  Similarly for
<  * iloops: while (true){...} is treated as though ... returns.
---
>  * Insist on a final return before control flows out of pn, but don't be too
>  * smart about loops (do {...; return e2;} while(0) at the end of a function
>  * that contains an early return e1 will get a strict-option-only warning).
680,684c499
< #define ENDS_IN_OTHER   0
< #define ENDS_IN_RETURN  1
< #define ENDS_IN_BREAK   2
< 
< static int
---
> static JSBool
686a502
>     JSBool ok, hasDefault;
688d503
<     uintN rv, rv2, hasDefault;
693c508
<             return ENDS_IN_OTHER;
---
>             return JS_FALSE;
697,728c512,514
<         if (!pn->pn_kid3)
<             return ENDS_IN_OTHER;
<         return HasFinalReturn(pn->pn_kid2) & HasFinalReturn(pn->pn_kid3);
< 
<       case TOK_WHILE:
<         pn2 = pn->pn_left;
<         if (pn2->pn_type == TOK_PRIMARY && pn2->pn_op == JSOP_TRUE)
<             return ENDS_IN_RETURN;
<         if (pn2->pn_type == TOK_NUMBER && pn2->pn_dval)
<             return ENDS_IN_RETURN;
<         return ENDS_IN_OTHER;
< 
<       case TOK_DO:
<         pn2 = pn->pn_right;
<         if (pn2->pn_type == TOK_PRIMARY) {
<             if (pn2->pn_op == JSOP_FALSE)
<                 return HasFinalReturn(pn->pn_left);
<             if (pn2->pn_op == JSOP_TRUE)
<                 return ENDS_IN_RETURN;
<         }
<         if (pn2->pn_type == TOK_NUMBER) {
<             if (pn2->pn_dval == 0)
<                 return HasFinalReturn(pn->pn_left);
<             return ENDS_IN_RETURN;
<         }
<         return ENDS_IN_OTHER;
< 
<       case TOK_FOR:
<         pn2 = pn->pn_left;
<         if (pn2->pn_arity == PN_TERNARY && !pn2->pn_kid2)
<             return ENDS_IN_RETURN;
<         return ENDS_IN_OTHER;
---
>         ok = HasFinalReturn(pn->pn_kid2);
>         ok &= pn->pn_kid3 && HasFinalReturn(pn->pn_kid3);
>         return ok;
729a516
> #if JS_HAS_SWITCH_STATEMENT
731,736c518,520
<         rv = ENDS_IN_RETURN;
<         hasDefault = ENDS_IN_OTHER;
<         pn2 = pn->pn_right;
<         if (pn2->pn_type == TOK_LEXICALSCOPE)
<             pn2 = pn2->pn_expr;
<         for (pn2 = pn2->pn_head; rv && pn2; pn2 = pn2->pn_next) {
---
>         ok = JS_TRUE;
>         hasDefault = JS_FALSE;
>         for (pn2 = pn->pn_kid2->pn_head; ok && pn2; pn2 = pn2->pn_next) {
738c522
<                 hasDefault = ENDS_IN_RETURN;
---
>                 hasDefault = JS_TRUE;
741,747c525,526
<             if (pn3->pn_head) {
<                 rv2 = HasFinalReturn(PN_LAST(pn3));
<                 if (rv2 == ENDS_IN_OTHER && pn2->pn_next)
<                     /* Falling through to next case or default. */;
<                 else
<                     rv &= rv2;
<             }
---
>             if (pn3->pn_head)
>                 ok &= HasFinalReturn(PN_LAST(pn3));
750,754c529,531
<         rv &= hasDefault;
<         return rv;
< 
<       case TOK_BREAK:
<         return ENDS_IN_BREAK;
---
>         ok &= hasDefault;
>         return ok;
> #endif /* JS_HAS_SWITCH_STATEMENT */
760,764c537
<         return ENDS_IN_RETURN;
< 
<       case TOK_COLON:
<       case TOK_LEXICALSCOPE:
<         return HasFinalReturn(pn->pn_expr);
---
>         return JS_TRUE;
765a539
> #if JS_HAS_EXCEPTIONS
767c541
<         return ENDS_IN_RETURN;
---
>         return JS_TRUE;
771,775c545,546
<         if (pn->pn_kid3) {
<             rv = HasFinalReturn(pn->pn_kid3);
<             if (rv == ENDS_IN_RETURN)
<                 return rv;
<         }
---
>         if (pn->pn_kid3 && HasFinalReturn(pn->pn_kid3))
>             return JS_TRUE;
778,784c549,552
<         rv = HasFinalReturn(pn->pn_kid1);
<         if (pn->pn_kid2) {
<             JS_ASSERT(pn->pn_kid2->pn_arity == PN_LIST);
<             for (pn2 = pn->pn_kid2->pn_head; pn2; pn2 = pn2->pn_next)
<                 rv &= HasFinalReturn(pn2);
<         }
<         return rv;
---
>         ok = HasFinalReturn(pn->pn_kid1);
>         if (pn->pn_kid2)
>             ok &= HasFinalReturn(pn->pn_kid2);
>         return ok;
787,794c555,560
<         /* Check this catch block's body. */
<         return HasFinalReturn(pn->pn_kid3);
< 
<       case TOK_LET:
<         /* Non-binary let statements are let declarations. */
<         if (pn->pn_arity != PN_BINARY)
<             return ENDS_IN_OTHER;
<         return HasFinalReturn(pn->pn_right);
---
>         /* Check this block's code and iterate over further catch blocks. */
>         ok = HasFinalReturn(pn->pn_kid3);
>         for (pn2 = pn->pn_kid2; pn2; pn2 = pn2->pn_kid2)
>             ok &= HasFinalReturn(pn2->pn_kid3);
>         return ok;
> #endif
797c563
<         return ENDS_IN_OTHER;
---
>         return JS_FALSE;
802,803c568
< ReportBadReturn(JSContext *cx, JSTreeContext *tc, uintN flags, uintN errnum,
<                 uintN anonerrnum)
---
> ReportNoReturnValue(JSContext *cx, JSTokenStream *ts)
805c570,571
<     const char *name;
---
>     JSFunction *fun;
>     JSBool ok;
807,809c573,579
<     JS_ASSERT(tc->flags & TCF_IN_FUNCTION);
<     if (tc->fun->atom) {
<         name = js_AtomToPrintableString(cx, tc->fun->atom);
---
>     fun = cx->fp->fun;
>     if (fun->atom) {
>         char *name = js_GetStringBytes(ATOM_TO_STRING(fun->atom));
>         ok = js_ReportCompileErrorNumber(cx, ts, NULL,
>                                          JSREPORT_WARNING |
>                                          JSREPORT_STRICT,
>                                          JSMSG_NO_RETURN_VALUE, name);
811,812c581,584
<         errnum = anonerrnum;
<         name = NULL;
---
>         ok = js_ReportCompileErrorNumber(cx, ts, NULL,
>                                          JSREPORT_WARNING |
>                                          JSREPORT_STRICT,
>                                          JSMSG_ANON_NO_RETURN_VALUE);
814,815c586
<     return js_ReportCompileErrorNumber(cx, TS(tc->parseContext), NULL, flags,
<                                        errnum, name);
---
>     return ok;
819c590
< CheckFinalReturn(JSContext *cx, JSTreeContext *tc, JSParseNode *pn)
---
> CheckFinalReturn(JSContext *cx, JSTokenStream *ts, JSParseNode *pn)
821,824c592
<     JS_ASSERT(tc->flags & TCF_IN_FUNCTION);
<     return HasFinalReturn(pn) == ENDS_IN_RETURN ||
<            ReportBadReturn(cx, tc, JSREPORT_WARNING | JSREPORT_STRICT,
<                            JSMSG_NO_RETURN_VALUE, JSMSG_ANON_NO_RETURN_VALUE);
---
>     return HasFinalReturn(pn) || ReportNoReturnValue(cx, ts);
828c596,597
< FunctionBody(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
---
> FunctionBody(JSContext *cx, JSTokenStream *ts, JSFunction *fun,
>              JSTreeContext *tc)
830,831c599,601
<     JSStmtInfo stmtInfo;
<     uintN oldflags, firstLine;
---
>     JSStackFrame *fp, frame;
>     JSObject *funobj;
>     uintN oldflags;
834,836c604,613
<     JS_ASSERT(tc->flags & TCF_IN_FUNCTION);
<     js_PushStatement(tc, &stmtInfo, STMT_BLOCK, -1);
<     stmtInfo.flags = SIF_BODY_BLOCK;
---
>     fp = cx->fp;
>     funobj = fun->object;
>     if (!fp || fp->fun != fun || fp->varobj != funobj ||
>         fp->scopeChain != funobj) {
>         memset(&frame, 0, sizeof frame);
>         frame.fun = fun;
>         frame.varobj = frame.scopeChain = funobj;
>         frame.down = fp;
>         cx->fp = &frame;
>     }
840,870c617
< 
<     /*
<      * Save the body's first line, and store it in pn->pn_pos.begin.lineno
<      * later, because we may have not peeked in ts yet, so Statements won't
<      * acquire a valid pn->pn_pos.begin from the current token.
<      */
<     firstLine = ts->lineno;
< #if JS_HAS_EXPR_CLOSURES
<     if (CURRENT_TOKEN(ts).type == TOK_LC) {
<         pn = Statements(cx, ts, tc);
<     } else {
<         pn = NewParseNode(cx, ts, PN_UNARY, tc);
<         if (pn) {
<             pn->pn_kid = AssignExpr(cx, ts, tc);
<             if (!pn->pn_kid) {
<                 pn = NULL;
<             } else {
<                 if (tc->flags & TCF_FUN_IS_GENERATOR) {
<                     ReportBadReturn(cx, tc, JSREPORT_ERROR,
<                                     JSMSG_BAD_GENERATOR_RETURN,
<                                     JSMSG_BAD_ANON_GENERATOR_RETURN);
<                     pn = NULL;
<                 } else {
<                     pn->pn_type = TOK_RETURN;
<                     pn->pn_op = JSOP_RETURN;
<                     pn->pn_pos.end = pn->pn_kid->pn_pos.end;
<                 }
<             }
<         }
<     }
< #else
---
>     tc->flags |= TCF_IN_FUNCTION;
872,876d618
< #endif
< 
<     if (pn) {
<         js_PopStatement(tc);
<         pn->pn_pos.begin.lineno = firstLine;
878,880c620,622
<         /* Check for falling off the end of a function that returns a value. */
<         if (JS_HAS_STRICT_OPTION(cx) && (tc->flags & TCF_RETURN_EXPR) &&
<             !CheckFinalReturn(cx, tc, pn)) {
---
>     /* Check for falling off the end of a function that returns a value. */
>     if (pn && JS_HAS_STRICT_OPTION(cx) && (tc->flags & TCF_RETURN_EXPR)) {
>         if (!CheckFinalReturn(cx, ts, pn))
882d623
<         }
885c626,627
<     tc->flags = oldflags | (tc->flags & (TCF_FUN_FLAGS | TCF_HAS_DEFXMLNS));
---
>     cx->fp = fp;
>     tc->flags = oldflags | (tc->flags & TCF_FUN_FLAGS);
894,896c636
< js_CompileFunctionBody(JSContext *cx, JSFunction *fun, JSPrincipals *principals,
<                        const jschar *chars, size_t length,
<                        const char *filename, uintN lineno)
---
> js_CompileFunctionBody(JSContext *cx, JSTokenStream *ts, JSFunction *fun)
898,899d637
<     JSParseContext pc;
<     JSArenaPool codePool, notePool;
900a639,640
>     JSStackFrame *fp, frame;
>     JSObject *funobj;
901a642
>     JSBool ok;
903,904c644,645
<     if (!js_InitParseContext(cx, &pc, principals, chars, length, NULL,
<                              filename, lineno)) {
---
>     if (!js_InitCodeGenerator(cx, &funcg, ts->filename, ts->lineno,
>                               ts->principals)) {
908,916c649,650
<     /* No early return from this point until js_FinishParseContext call. */
<     JS_INIT_ARENA_POOL(&codePool, "code", 1024, sizeof(jsbytecode),
<                        &cx->scriptStackQuota);
<     JS_INIT_ARENA_POOL(&notePool, "note", 1024, sizeof(jssrcnote),
<                        &cx->scriptStackQuota);
<     js_InitCodeGenerator(cx, &funcg, &pc, &codePool, &notePool,
<                          pc.tokenStream.lineno);
<     funcg.treeContext.flags |= TCF_IN_FUNCTION;
<     funcg.treeContext.fun = fun;
---
>     /* Prevent GC activation while compiling. */
>     JS_DISABLE_GC(cx->runtime);
918,940c652,679
<     /*
<      * Farble the body so that it looks like a block statement to js_EmitTree,
<      * which is called beneath FunctionBody; see Statements, further below in
<      * this file.  FunctionBody pushes a STMT_BLOCK record around its call to
<      * Statements, so Statements will not compile each statement as it loops
<      * to save JSParseNode space -- it will not compile at all, only build a
<      * JSParseNode tree.
<      *
<      * Therefore we must fold constants, allocate try notes, and generate code
<      * for this function, including a stop opcode at the end.
<      */
<     CURRENT_TOKEN(&pc.tokenStream).type = TOK_LC;
<     pn = FunctionBody(cx, &pc.tokenStream, &funcg.treeContext);
<     if (pn) {
<         if (!js_MatchToken(cx, &pc.tokenStream, TOK_EOF)) {
<             js_ReportCompileErrorNumber(cx, &pc.tokenStream, NULL,
<                                         JSREPORT_ERROR, JSMSG_SYNTAX_ERROR);
<             pn = NULL;
<         } else {
<             if (!js_FoldConstants(cx, pn, &funcg.treeContext) ||
<                 !js_EmitFunctionScript(cx, &funcg, pn)) {
<                 pn = NULL;
<             }
---
>     /* Push a JSStackFrame for use by FunctionBody and js_EmitFunctionBody. */
>     fp = cx->fp;
>     funobj = fun->object;
>     JS_ASSERT(!fp || fp->fun != fun || fp->varobj != funobj ||
>               fp->scopeChain != funobj);
>     memset(&frame, 0, sizeof frame);
>     frame.fun = fun;
>     frame.varobj = frame.scopeChain = funobj;
>     frame.down = fp;
>     cx->fp = &frame;
> 
>     /* Ensure that the body looks like a block statement to js_EmitTree. */
>     CURRENT_TOKEN(ts).type = TOK_LC;
>     pn = FunctionBody(cx, ts, fun, &funcg.treeContext);
>     if (!pn) {
>         ok = JS_FALSE;
>     } else {
>         /*
>          * No need to emit code here -- Statements (via FunctionBody) already
>          * has.  See similar comment in js_CompileTokenStream, and bug 108257.
>          */
>         fun->script = js_NewScriptFromCG(cx, &funcg, fun);
>         if (!fun->script) {
>             ok = JS_FALSE;
>         } else {
>             if (funcg.treeContext.flags & TCF_FUN_HEAVYWEIGHT)
>                 fun->flags |= JSFUN_HEAVYWEIGHT;
>             ok = JS_TRUE;
944a684,685
>     cx->fp = fp;
>     JS_ENABLE_GC(cx->runtime);
946,949c687
<     JS_FinishArenaPool(&codePool);
<     JS_FinishArenaPool(&notePool);
<     js_FinishParseContext(cx, &pc);
<     return pn != NULL;
---
>     return ok;
952,977c690,692
< /*
<  * Parameter block types for the several Binder functions.  We use a common
<  * helper function signature in order to share code among destructuring and
<  * simple variable declaration parsers.  In the destructuring case, the binder
<  * function is called indirectly from the variable declaration parser by way
<  * of CheckDestructuring and its friends.
<  */
< typedef struct BindData BindData;
< 
< typedef JSBool
< (*Binder)(JSContext *cx, BindData *data, JSAtom *atom, JSTreeContext *tc);
< 
< struct BindData {
<     JSParseNode             *pn;                /* error source coordinate */
<     JSOp                    op;                 /* prolog bytecode or nop */
<     Binder                  binder;             /* binder, discriminates u */
<     union {
<         struct {
<             jsuint          index;
<             uintN           overflow;
<         } let;
<     } u;
< };
< 
< static JSBool
< BindArg(JSContext *cx, JSAtom *atom, JSTreeContext *tc)
---
> static JSParseNode *
> FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
>             JSBool lambda)
979c694,704
<     const char *name;
---
>     JSParseNode *pn, *body;
>     JSOp op, prevop;
>     JSAtom *funAtom, *argAtom;
>     JSFunction *fun;
>     JSObject *parent;
>     JSObject *pobj;
>     JSScopeProperty *sprop;
>     uintN dupflag;
>     JSBool ok;
>     JSTreeContext funtc;
>     JSAtomListElement *ale;
981,994c706,710
<     /*
<      * Check for a duplicate parameter name, a "feature" required by ECMA-262.
<      */
<     JS_ASSERT(tc->flags & TCF_IN_FUNCTION);
<     if (js_LookupLocal(cx, tc->fun, atom, NULL) != JSLOCAL_NONE) {
<         name = js_AtomToPrintableString(cx, atom);
<         if (!name ||
<             !js_ReportCompileErrorNumber(cx, TS(tc->parseContext), NULL,
<                                          JSREPORT_WARNING | JSREPORT_STRICT,
<                                          JSMSG_DUPLICATE_FORMAL,
<                                          name)) {
<             return JS_FALSE;
<         }
<     }
---
>     /* Make a TOK_FUNCTION node. */
>     pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_FUNC, tc);
>     if (!pn)
>         return NULL;
>     op = CURRENT_TOKEN(ts).t_op;
996,997c712,716
<     return js_AddLocal(cx, tc->fun, atom, JSLOCAL_ARG);
< }
---
>     /* Scan the optional function name into funAtom. */
>     if (js_MatchToken(cx, ts, TOK_NAME))
>         funAtom = CURRENT_TOKEN(ts).t_atom;
>     else
>         funAtom = NULL;
999,1003c718,723
< static JSBool
< BindLocalVariable(JSContext *cx, JSFunction *fun, JSAtom *atom,
<                   JSLocalKind localKind)
< {
<     JS_ASSERT(localKind == JSLOCAL_VAR || localKind == JSLOCAL_CONST);
---
>     /* Find the nearest variable-declaring scope and use it as our parent. */
>     parent = cx->fp->varobj;
>     fun = js_NewFunction(cx, NULL, NULL, 0, lambda ? JSFUN_LAMBDA : 0, parent,
>                          funAtom);
>     if (!fun)
>         return NULL;
1005,1012c725,728
<     /*
<      * Don't bind a variable with the hidden name 'arguments', per ECMA-262.
<      * Instead 'var arguments' always restates the predefined property of the
<      * activation objects with unhidden name 'arguments'.  Assignment to such
<      * a variable must be handled specially.
<      */
<     if (atom == cx->runtime->atomState.argumentsAtom)
<         return JS_TRUE;
---
> #if JS_HAS_GETTER_SETTER
>     if (op != JSOP_NOP)
>         fun->flags |= (op == JSOP_GETTER) ? JSPROP_GETTER : JSPROP_SETTER;
> #endif
1014,1015c730,756
<     return js_AddLocal(cx, fun, atom, localKind);
< }
---
>     /* Now parse formal argument list and compute fun->nargs. */
>     MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_FORMAL);
>     if (!js_MatchToken(cx, ts, TOK_RP)) {
>         do {
>             MUST_MATCH_TOKEN(TOK_NAME, JSMSG_MISSING_FORMAL);
>             argAtom = CURRENT_TOKEN(ts).t_atom;
>             pobj = NULL;
>             if (!js_LookupProperty(cx, fun->object, (jsid)argAtom, &pobj,
>                                    (JSProperty **)&sprop)) {
>                 return NULL;
>             }
>             dupflag = 0;
>             if (sprop) {
>                 ok = JS_TRUE;
>                 if (pobj == fun->object &&
>                     sprop->getter == js_GetArgument) {
>                     /*
>                      * A duplicate parameter name. We force a duplicate node
>                      * on the SCOPE_LAST_PROP(scope) list with the same id,
>                      * distinguished by the SPROP_IS_DUPLICATE flag, and not
>                      * mapped by an entry in scope.
>                      */
>                     ok = js_ReportCompileErrorNumber(cx, ts, NULL,
>                                                      JSREPORT_WARNING |
>                                                      JSREPORT_STRICT,
>                                                      JSMSG_DUPLICATE_FORMAL,
>                                                      ATOM_BYTES(argAtom));
1017,1063c758,775
< #if JS_HAS_DESTRUCTURING
< /*
<  * Forward declaration to maintain top-down presentation.
<  */
< static JSParseNode *
< DestructuringExpr(JSContext *cx, BindData *data, JSTreeContext *tc,
<                   JSTokenType tt);
< 
< static JSBool
< BindDestructuringArg(JSContext *cx, BindData *data, JSAtom *atom,
<                      JSTreeContext *tc)
< {
<     JSAtomListElement *ale;
<     const char *name;
< 
<     JS_ASSERT(tc->flags & TCF_IN_FUNCTION);
<     ATOM_LIST_SEARCH(ale, &tc->decls, atom);
<     if (!ale) {
<         ale = js_IndexAtom(cx, atom, &tc->decls);
<         if (!ale)
<             return JS_FALSE;
<         ALE_SET_JSOP(ale, data->op);
<     }
< 
<     if (js_LookupLocal(cx, tc->fun, atom, NULL) != JSLOCAL_NONE) {
<         name = js_AtomToPrintableString(cx, atom);
<         if (!name ||
<             !js_ReportCompileErrorNumber(cx, TS(tc->parseContext), data->pn,
<                                          JSREPORT_WARNING | JSREPORT_STRICT,
<                                          JSMSG_DUPLICATE_FORMAL,
<                                          name)) {
<             return JS_FALSE;
<         }
<     } else {
<         if (!BindLocalVariable(cx, tc->fun, atom, JSLOCAL_VAR))
<             return JS_FALSE;
<     }
<     return JS_TRUE;
< }
< #endif /* JS_HAS_DESTRUCTURING */
< 
< static JSFunction *
< NewCompilerFunction(JSContext *cx, JSTreeContext *tc, JSAtom *atom,
<                     uintN lambda)
< {
<     JSObject *parent;
<     JSFunction *fun;
---
>                     dupflag = SPROP_IS_DUPLICATE;
>                 }
>                 OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop);
>                 if (!ok)
>                     return NULL;
>                 sprop = NULL;
>             }
>             if (!js_AddNativeProperty(cx, fun->object, (jsid)argAtom,
>                                       js_GetArgument, js_SetArgument,
>                                       SPROP_INVALID_SLOT,
>                                       JSPROP_ENUMERATE | JSPROP_PERMANENT |
>                                       JSPROP_SHARED,
>                                       SPROP_HAS_SHORTID | dupflag,
>                                       fun->nargs)) {
>                 return NULL;
>             }
>             fun->nargs++;
>         } while (js_MatchToken(cx, ts, TOK_COMMA));
1065,1071c777
<     JS_ASSERT((lambda & ~JSFUN_LAMBDA) == 0);
<     parent = (tc->flags & TCF_IN_FUNCTION) ? tc->fun->object : cx->fp->varobj;
<     fun = js_NewFunction(cx, NULL, NULL, 0, JSFUN_INTERPRETED | lambda,
<                          parent, atom);
<     if (fun && !(tc->flags & TCF_COMPILE_N_GO)) {
<         STOBJ_SET_PARENT(fun->object, NULL);
<         STOBJ_SET_PROTO(fun->object, NULL);
---
>         MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_FORMAL);
1073,1074d778
<     return fun;
< }
1076,1090c780,781
< static JSParseNode *
< FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
<             uintN lambda)
< {
<     JSOp op, prevop;
<     JSParseNode *pn, *body, *result;
<     JSTokenType tt;
<     JSAtom *funAtom;
<     JSParsedObjectBox *funpob;
<     JSAtomListElement *ale;
<     JSFunction *fun;
<     JSTreeContext funtc;
< #if JS_HAS_DESTRUCTURING
<     JSParseNode *item, *list = NULL;
< #endif
---
>     MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_BODY);
>     pn->pn_pos.begin = CURRENT_TOKEN(ts).pos.begin;
1092,1097c783,785
<     /* Make a TOK_FUNCTION node. */
< #if JS_HAS_GETTER_SETTER
<     op = CURRENT_TOKEN(ts).t_op;
< #endif
<     pn = NewParseNode(cx, ts, PN_FUNC, tc);
<     if (!pn)
---
>     TREE_CONTEXT_INIT(&funtc);
>     body = FunctionBody(cx, ts, fun, &funtc);
>     if (!body)
1099,1101d786
< #ifdef DEBUG
<     pn->pn_index = (uint32) -1;
< #endif
1103,1108c788,801
<     /* Scan the optional function name into funAtom. */
<     ts->flags |= TSF_KEYWORD_IS_NAME;
<     tt = js_GetToken(cx, ts);
<     ts->flags &= ~TSF_KEYWORD_IS_NAME;
<     if (tt == TOK_NAME) {
<         funAtom = CURRENT_TOKEN(ts).t_atom;
---
>     MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_BODY);
>     pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
> 
> #if JS_HAS_LEXICAL_CLOSURE
>     /*
>      * If we collected flags that indicate nested heavyweight functions, or
>      * this function contains heavyweight-making statements (references to
>      * __parent__ or __proto__; use of with, eval, import, or export; and
>      * assignment to arguments), flag the function as heavyweight (requiring
>      * a call object per invocation).
>      */
>     if (funtc.flags & TCF_FUN_HEAVYWEIGHT) {
>         fun->flags |= JSFUN_HEAVYWEIGHT;
>         tc->flags |= TCF_FUN_HEAVYWEIGHT;
1110,1113c803,811
<         if (lambda == 0 && (cx->options & JSOPTION_ANONFUNFIX)) {
<             js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                         JSMSG_SYNTAX_ERROR);
<             return NULL;
---
>         /*
>          * If this function is a named statement function not at top-level
>          * (i.e. a JSOP_CLOSURE), or if it refers to unqualified names that
>          * are not local args or vars (TCF_FUN_USES_NONLOCALS), then our
>          * enclosing function, if any, must be heavyweight.
>          */
>         if ((!lambda && funAtom && tc->topStmt) ||
>             (funtc.flags & TCF_FUN_USES_NONLOCALS)) {
>             tc->flags |= TCF_FUN_HEAVYWEIGHT;
1115,1116d812
<         funAtom = NULL;
<         js_UngetToken(ts);
1117a814
> #endif
1123c820
<     if (lambda == 0 && funAtom) {
---
>     if (!lambda && funAtom) {
1127,1144c824,837
<             if (JS_HAS_STRICT_OPTION(cx) || prevop == JSOP_DEFCONST) {
<                 const char *name = js_AtomToPrintableString(cx, funAtom);
<                 if (!name ||
<                     !js_ReportCompileErrorNumber(cx, ts, NULL,
<                                                  (prevop != JSOP_DEFCONST)
<                                                  ? JSREPORT_WARNING |
<                                                    JSREPORT_STRICT
<                                                  : JSREPORT_ERROR,
<                                                  JSMSG_REDECLARED_VAR,
<                                                  (prevop == JSOP_DEFFUN ||
<                                                   prevop == JSOP_CLOSURE)
<                                                  ? js_function_str
<                                                  : (prevop == JSOP_DEFCONST)
<                                                  ? js_const_str
<                                                  : js_var_str,
<                                                  name)) {
<                     return NULL;
<                 }
---
>             if ((JS_HAS_STRICT_OPTION(cx) || prevop == JSOP_DEFCONST) &&
>                 !js_ReportCompileErrorNumber(cx, ts, NULL,
>                                              (prevop != JSOP_DEFCONST)
>                                              ? JSREPORT_WARNING|JSREPORT_STRICT
>                                              : JSREPORT_ERROR,
>                                              JSMSG_REDECLARED_VAR,
>                                              (prevop == JSOP_DEFFUN ||
>                                               prevop == JSOP_CLOSURE)
>                                              ? js_function_str
>                                              : (prevop == JSOP_DEFCONST)
>                                              ? js_const_str
>                                              : js_var_str,
>                                              ATOM_BYTES(funAtom))) {
>                 return NULL;
1146c839
<             if (!AT_TOP_LEVEL(tc) && prevop == JSOP_DEFVAR)
---
>             if (tc->topStmt && prevop == JSOP_DEFVAR)
1153c846
<         ALE_SET_JSOP(ale, AT_TOP_LEVEL(tc) ? JSOP_DEFFUN : JSOP_CLOSURE);
---
>         ALE_SET_JSOP(ale, tc->topStmt ? JSOP_CLOSURE : JSOP_DEFFUN);
1154a848
> #if JS_HAS_LEXICAL_CLOSURE
1160c854
<          * wins when jsemit.c's BindNameToSlot can optimize a JSOP_NAME into a
---
>          * wins when jsemit.c's LookupArgOrVar can optimize a JSOP_NAME into a
1163,1164c857,859
<         if (AT_TOP_LEVEL(tc) && (tc->flags & TCF_IN_FUNCTION)) {
<             JSLocalKind localKind;
---
>         if (!tc->topStmt && (tc->flags & TCF_IN_FUNCTION)) {
>             JSStackFrame *fp;
>             JSObject *varobj;
1167,1171c862,867
<              * Define a property on the outer function so that BindNameToSlot
<              * can properly optimize accesses. Note that we need a variable,
<              * not an argument, for the function statement. Thus we add a
<              * variable even if the parameter with the given name already
<              * exists.
---
>              * Define a property on the outer function so that LookupArgOrVar
>              * can properly optimize accesses.
>              *
>              * XXX Here and in Variables, we use the function object's scope,
>              * XXX arguably polluting it, when we could use a compiler-private
>              * XXX scope structure.  Tradition!
1173,1273c869,879
<             localKind = js_LookupLocal(cx, tc->fun, funAtom, NULL);
<             if (localKind == JSLOCAL_NONE || localKind == JSLOCAL_ARG) {
<                 if (!js_AddLocal(cx, tc->fun, funAtom, JSLOCAL_VAR))
<                     return NULL;
<             }
<         }
<     }
< 
<     fun = NewCompilerFunction(cx, tc, funAtom, lambda);
<     if (!fun)
<         return NULL;
< 
< #if JS_HAS_GETTER_SETTER
<     if (op != JSOP_NOP)
<         fun->flags |= (op == JSOP_GETTER) ? JSPROP_GETTER : JSPROP_SETTER;
< #endif
< 
<     /*
<      * Create wrapping box for fun->object early to protect against a
<      * last-ditch GC.
<      */
<     funpob = js_NewParsedObjectBox(cx, tc->parseContext, fun->object);
<     if (!funpob)
<         return NULL;
< 
<     /* Initialize early for possible flags mutation via DestructuringExpr. */
<     TREE_CONTEXT_INIT(&funtc, tc->parseContext);
<     funtc.flags |= TCF_IN_FUNCTION;
<     funtc.fun = fun;
< 
<     /* Now parse formal argument list and compute fun->nargs. */
<     MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_FORMAL);
<     if (!js_MatchToken(cx, ts, TOK_RP)) {
<         do {
<             tt = js_GetToken(cx, ts);
<             switch (tt) {
< #if JS_HAS_DESTRUCTURING
<               case TOK_LB:
<               case TOK_LC:
<               {
<                 BindData data;
<                 JSParseNode *lhs, *rhs;
<                 jsint slot;
< 
<                 /*
<                  * A destructuring formal parameter turns into one or more
<                  * local variables initialized from properties of a single
<                  * anonymous positional parameter, so here we must tweak our
<                  * binder and its data.
<                  */
<                 data.pn = NULL;
<                 data.op = JSOP_DEFVAR;
<                 data.binder = BindDestructuringArg;
<                 lhs = DestructuringExpr(cx, &data, &funtc, tt);
<                 if (!lhs)
<                     return NULL;
< 
<                 /*
<                  * Adjust fun->nargs to count the single anonymous positional
<                  * parameter that is to be destructured.
<                  */
<                 slot = fun->nargs;
<                 if (!js_AddLocal(cx, fun, NULL, JSLOCAL_ARG))
<                     return NULL;
< 
<                 /*
<                  * Synthesize a destructuring assignment from the single
<                  * anonymous positional parameter into the destructuring
<                  * left-hand-side expression and accumulate it in list.
<                  */
<                 rhs = NewParseNode(cx, ts, PN_NAME, tc);
<                 if (!rhs)
<                     return NULL;
<                 rhs->pn_type = TOK_NAME;
<                 rhs->pn_op = JSOP_GETARG;
<                 rhs->pn_atom = cx->runtime->atomState.emptyAtom;
<                 rhs->pn_slot = slot;
< 
<                 item = NewBinary(cx, TOK_ASSIGN, JSOP_NOP, lhs, rhs, tc);
<                 if (!item)
<                     return NULL;
<                 if (!list) {
<                     list = NewParseNode(cx, ts, PN_LIST, tc);
<                     if (!list)
<                         return NULL;
<                     list->pn_type = TOK_COMMA;
<                     PN_INIT_LIST(list);
<                 }
<                 PN_APPEND(list, item);
<                 break;
<               }
< #endif /* JS_HAS_DESTRUCTURING */
< 
<               case TOK_NAME:
<                 if (!BindArg(cx, CURRENT_TOKEN(ts).t_atom, &funtc))
<                     return NULL;
<                 break;
< 
<               default:
<                 js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                             JSMSG_MISSING_FORMAL);
---
>             fp = cx->fp;
>             varobj = fp->varobj;
>             JS_ASSERT(OBJ_GET_CLASS(cx, varobj) == &js_FunctionClass);
>             JS_ASSERT(fp->fun == (JSFunction *) JS_GetPrivate(cx, varobj));
>             if (!js_DefineNativeProperty(cx, varobj, (jsid)funAtom,
>                                          OBJECT_TO_JSVAL(fun->object),
>                                          js_GetLocalVariable,
>                                          js_SetLocalVariable,
>                                          JSPROP_ENUMERATE,
>                                          SPROP_HAS_SHORTID, fp->fun->nvars,
>                                          NULL)) {
1276,1327c882
<         } while (js_MatchToken(cx, ts, TOK_COMMA));
< 
<         MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_FORMAL);
<     }
< 
< #if JS_HAS_EXPR_CLOSURES
<     ts->flags |= TSF_OPERAND;
<     tt = js_GetToken(cx, ts);
<     ts->flags &= ~TSF_OPERAND;
<     if (tt != TOK_LC) {
<         js_UngetToken(ts);
<         fun->flags |= JSFUN_EXPR_CLOSURE;
<     }
< #else
<     MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_BODY);
< #endif
<     pn->pn_pos.begin = CURRENT_TOKEN(ts).pos.begin;
< 
<     body = FunctionBody(cx, ts, &funtc);
<     if (!body)
<         return NULL;
< 
< #if JS_HAS_EXPR_CLOSURES
<     if (tt == TOK_LC)
<         MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_BODY);
<     else if (lambda == 0)
<         js_MatchToken(cx, ts, TOK_SEMI);
< #else
<     MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_BODY);
< #endif
<     pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
< 
< #if JS_HAS_DESTRUCTURING
<     /*
<      * If there were destructuring formal parameters, prepend the initializing
<      * comma expression that we synthesized to body.  If the body is a lexical
<      * scope node, we must make a special TOK_BODY node, to prepend the formal
<      * parameter destructuring code without bracing the decompilation of the
<      * function body's lexical scope.
<      */
<     if (list) {
<         if (body->pn_arity != PN_LIST) {
<             JSParseNode *block;
< 
<             block = NewParseNode(cx, ts, PN_LIST, tc);
<             if (!block)
<                 return NULL;
<             block->pn_type = TOK_BODY;
<             block->pn_pos = body->pn_pos;
<             PN_INIT_LIST_1(block, body);
< 
<             body = block;
---
>             fp->fun->nvars++;
1329,1342d883
< 
<         item = NewParseNode(cx, ts, PN_UNARY, tc);
<         if (!item)
<             return NULL;
< 
<         item->pn_type = TOK_SEMI;
<         item->pn_pos.begin = item->pn_pos.end = body->pn_pos.begin;
<         item->pn_kid = list;
<         item->pn_next = body->pn_head;
<         body->pn_head = item;
<         if (body->pn_tail == &body->pn_head)
<             body->pn_tail = &item->pn_next;
<         ++body->pn_count;
<     }
1344,1368d884
< 
<     /*
<      * If we collected flags that indicate nested heavyweight functions, or
<      * this function contains heavyweight-making statements (references to
<      * __parent__ or __proto__; use of with, eval, import, or export; and
<      * assignment to arguments), flag the function as heavyweight (requiring
<      * a call object per invocation).
<      */
<     if (funtc.flags & TCF_FUN_HEAVYWEIGHT) {
<         fun->flags |= JSFUN_HEAVYWEIGHT;
<         tc->flags |= TCF_FUN_HEAVYWEIGHT;
<     } else {
<         /*
<          * If this function is a named statement function not at top-level
<          * (i.e. a JSOP_CLOSURE, not a function definiton or expression), then
<          * our enclosing function, if any, must be heavyweight.
<          *
<          * The TCF_FUN_USES_NONLOCALS flag is set only by the code generator,
<          * so it won't be set here.  Assert that it's not.  We have to check
<          * it later, in js_EmitTree, after js_EmitFunctionScript has traversed
<          * the function's body.
<          */
<         JS_ASSERT(!(funtc.flags & TCF_FUN_USES_NONLOCALS));
<         if (lambda == 0 && funAtom && !AT_TOP_LEVEL(tc))
<             tc->flags |= TCF_FUN_HEAVYWEIGHT;
1371,1372c887,888
<     result = pn;
<     if (lambda != 0) {
---
> #if JS_HAS_LEXICAL_CLOSURE
>     if (lambda || !funAtom) {
1374c890,892
<          * ECMA ed. 3 standard: function expression, possibly anonymous.
---
>          * ECMA ed. 3 standard: function expression, possibly anonymous (even
>          * if at top-level, an unnamed function is an expression statement, not
>          * a function declaration).
1376,1392c894,895
<         op = funAtom ? JSOP_NAMEDFUNOBJ : JSOP_ANONFUNOBJ;
<     } else if (!funAtom) {
<         /*
<          * If this anonymous function definition is *not* embedded within a
<          * larger expression, we treat it as an expression statement, not as
<          * a function declaration -- and not as a syntax error (as ECMA-262
<          * Edition 3 would have it).  Backward compatibility must trump all,
<          * unless JSOPTION_ANONFUNFIX is set.
<          */
<         result = NewParseNode(cx, ts, PN_UNARY, tc);
<         if (!result)
<             return NULL;
<         result->pn_type = TOK_SEMI;
<         result->pn_pos = pn->pn_pos;
<         result->pn_kid = pn;
<         op = JSOP_ANONFUNOBJ;
<     } else if (!AT_TOP_LEVEL(tc)) {
---
>         op = fun->atom ? JSOP_NAMEDFUNOBJ : JSOP_ANONFUNOBJ;
>     } else if (tc->topStmt) {
1400c903,904
<     } else {
---
>     } else
> #endif
1402d905
<     }
1404d906
<     pn->pn_funpob = funpob;
1405a908
>     pn->pn_fun = fun;
1407,1408c910,911
<     pn->pn_flags = funtc.flags & (TCF_FUN_FLAGS | TCF_HAS_DEFXMLNS);
<     pn->pn_sclen = funtc.maxScopeDepth;
---
>     pn->pn_flags = funtc.flags & TCF_FUN_FLAGS;
>     pn->pn_tryCount = funtc.tryCount;
1410c913
<     return result;
---
>     return pn;
1416c919
<     return FunctionDef(cx, ts, tc, 0);
---
>     return FunctionDef(cx, ts, tc, JS_FALSE);
1418a922
> #if JS_HAS_LEXICAL_CLOSURE
1422c926
<     return FunctionDef(cx, ts, tc, JSFUN_LAMBDA);
---
>     return FunctionDef(cx, ts, tc, JS_TRUE);
1423a928
> #endif
1433c938
<     JSParseNode *pn, *pn2, *saveBlock;
---
>     JSParseNode *pn, *pn2;
1436,1438c941
<     JS_CHECK_RECURSION(cx, return NULL);
< 
<     pn = NewParseNode(cx, ts, PN_LIST, tc);
---
>     pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc);
1441,1442d943
<     saveBlock = tc->blockNode;
<     tc->blockNode = pn;
1445,1453c946,948
<     for (;;) {
<         ts->flags |= TSF_OPERAND;
<         tt = js_PeekToken(cx, ts);
<         ts->flags &= ~TSF_OPERAND;
<         if (tt <= TOK_EOF || tt == TOK_RC) {
<             if (tt == TOK_ERROR)
<                 return NULL;
<             break;
<         }
---
>     ts->flags |= TSF_REGEXP;
>     while ((tt = js_PeekToken(cx, ts)) > TOK_EOF && tt != TOK_RC) {
>         ts->flags &= ~TSF_REGEXP;
1455,1457c950
<         if (!pn2) {
<             if (ts->flags & TSF_EOF)
<                 ts->flags |= TSF_UNEXPECTED_EOF;
---
>         if (!pn2)
1459c952
<         }
---
>         ts->flags |= TSF_REGEXP;
1461,1474c954,984
<         if (pn2->pn_type == TOK_FUNCTION) {
<             /*
<              * PNX_FUNCDEFS notifies the emitter that the block contains top-
<              * level function definitions that should be processed before the
<              * rest of nodes.
<              *
<              * TCF_HAS_FUNCTION_STMT is for the TOK_LC case in Statement. It
<              * is relevant only for function definitions not at top-level,
<              * which we call function statements.
<              */
<             if (AT_TOP_LEVEL(tc))
<                 pn->pn_extra |= PNX_FUNCDEFS;
<             else
<                 tc->flags |= TCF_HAS_FUNCTION_STMT;
---
>         /* If compiling top-level statements, emit as we go to save space. */
>         if (!tc->topStmt && (tc->flags & TCF_COMPILING)) {
>             if (cx->fp->fun &&
>                 JS_HAS_STRICT_OPTION(cx) &&
>                 (tc->flags & TCF_RETURN_EXPR)) {
>                 /*
>                  * Check pn2 for lack of a final return statement if it is the
>                  * last statement in the block.
>                  */
>                 tt = js_PeekToken(cx, ts);
>                 if ((tt == TOK_EOF || tt == TOK_RC) &&
>                     !CheckFinalReturn(cx, ts, pn2)) {
>                     tt = TOK_ERROR;
>                     break;
>                 }
> 
>                 /*
>                  * Clear TCF_RETURN_EXPR so FunctionBody doesn't try to
>                  * CheckFinalReturn again.
>                  */
>                 tc->flags &= ~TCF_RETURN_EXPR;
>             }
>             if (!js_FoldConstants(cx, pn2, tc) ||
>                 !js_AllocTryNotes(cx, (JSCodeGenerator *)tc) ||
>                 !js_EmitTree(cx, (JSCodeGenerator *)tc, pn2)) {
>                 tt = TOK_ERROR;
>                 break;
>             }
>             RecycleTree(pn2, tc);
>         } else {
>             PN_APPEND(pn, pn2);
1476d985
<         PN_APPEND(pn, pn2);
1478,1486c987,989
< 
<     /*
<      * Handle the case where there was a let declaration under this block.  If
<      * it replaced tc->blockNode with a new block node then we must refresh pn
<      * and then restore tc->blockNode.
<      */
<     if (tc->blockNode != pn)
<         pn = tc->blockNode;
<     tc->blockNode = saveBlock;
---
>     ts->flags &= ~TSF_REGEXP;
>     if (tt == TOK_ERROR)
>         return NULL;
1495c998
<     JSParseNode *pn;
---
>     JSParseNode *pn, *pn2;
1498c1001
<     pn = ParenExpr(cx, ts, tc, NULL, NULL);
---
>     pn = Expr(cx, ts, tc);
1504,1505c1007,1009
<      * Check for (a = b) and warn about possible (a == b) mistype iff b's
<      * operator has greater precedence than ==.
---
>      * Check for (a = b) and "correct" it to (a == b) iff b's operator has
>      * greater precedence than ==.
>      * XXX not ECMA, but documented in several books -- now a strict warning.
1510a1015
>         JSBool rewrite = !JSVERSION_IS_ECMA(cx->version);
1514c1019,1021
<                                          "")) {
---
>                                          rewrite
>                                          ? "\nAssuming equality test"
>                                          : "")) {
1516a1024,1041
>         if (rewrite) {
>             pn->pn_type = TOK_EQOP;
>             pn->pn_op = (JSOp)cx->jsop_eq;
>             pn2 = pn->pn_left;
>             switch (pn2->pn_op) {
>               case JSOP_SETNAME:
>                 pn2->pn_op = JSOP_NAME;
>                 break;
>               case JSOP_SETPROP:
>                 pn2->pn_op = JSOP_GETPROP;
>                 break;
>               case JSOP_SETELEM:
>                 pn2->pn_op = JSOP_GETELEM;
>                 break;
>               default:
>                 JS_ASSERT(0);
>             }
>         }
1524a1050
> #if JS_HAS_LABEL_STATEMENT
1535a1062,1064
> #else
>     label = NULL;
> #endif
1536a1066,1067
>     if (pn->pn_pos.end.lineno == ts->lineno)
>         return WellTerminated(cx, ts, TOK_ERROR);
1544c1075
<     JSParseNode *pn, *pn2;
---
>     JSParseNode *pn, *pn2, *pn3;
1548c1079
<     pn = NewParseNode(cx, ts, PN_NAME, tc);
---
>     pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NAME, tc);
1552a1084
>     pn->pn_expr = NULL;
1553a1086
>     pn->pn_attrs = 0;
1555c1088
<     ts->flags |= TSF_OPERAND;
---
>     ts->flags |= TSF_REGEXP;
1557c1090
<         ts->flags &= ~TSF_OPERAND;
---
>         ts->flags &= ~TSF_REGEXP;
1562c1095
<             pn2 = NewParseNode(cx, ts, PN_NAME, tc);
---
>             pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NAME, tc);
1565d1097
<             ts->flags |= TSF_KEYWORD_IS_NAME;
1568c1100
<                 pn2->pn_slot = -1;
---
>                 pn2->pn_atom = NULL;
1573a1106
>                 pn2->pn_attrs = 0;
1575d1107
<             ts->flags &= ~TSF_KEYWORD_IS_NAME;
1580,1581c1112,1113
<             /* Make a TOK_LB binary node. */
<             pn2 = NewBinary(cx, tt, JSOP_GETELEM, pn, Expr(cx, ts, tc), tc);
---
>             /* Make a TOK_LB node. */
>             pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_BINARY, tc);
1583a1116,1118
>             pn3 = Expr(cx, ts, tc);
>             if (!pn3)
>                 return NULL;
1585a1121,1126
>             pn2->pn_pos.begin = pn->pn_pos.begin;
>             pn2->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
> 
>             pn2->pn_op = JSOP_GETELEM;
>             pn2->pn_left = pn;
>             pn2->pn_right = pn3;
1589c1130
<         ts->flags |= TSF_OPERAND;
---
>         ts->flags |= TSF_REGEXP;
1591c1132
<     ts->flags &= ~TSF_OPERAND;
---
>     ts->flags &= ~TSF_REGEXP;
1616,1617c1157,1160
< static JSBool
< BindLet(JSContext *cx, BindData *data, JSAtom *atom, JSTreeContext *tc)
---
> extern const char js_with_statement_str[];
> 
> static JSParseNode *
> Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
1619,1621c1162,1165
<     JSObject *blockObj;
<     JSScopeProperty *sprop;
<     JSAtomListElement *ale;
---
>     JSTokenType tt, lastExprType;
>     JSParseNode *pn, *pn1, *pn2, *pn3, *pn4;
>     JSStmtInfo stmtInfo, *stmt, *stmt2;
>     JSAtom *label;
1623,1644c1167,1169
<     blockObj = tc->blockChain;
<     sprop = SCOPE_GET_PROPERTY(OBJ_SCOPE(blockObj), ATOM_TO_JSID(atom));
<     ATOM_LIST_SEARCH(ale, &tc->decls, atom);
<     if (sprop || (ale && ALE_JSOP(ale) == JSOP_DEFCONST)) {
<         const char *name;
< 
<         if (sprop) {
<             JS_ASSERT(sprop->flags & SPROP_HAS_SHORTID);
<             JS_ASSERT((uint16)sprop->shortid < data->u.let.index);
<         }
< 
<         name = js_AtomToPrintableString(cx, atom);
<         if (name) {
<             js_ReportCompileErrorNumber(cx, TS(tc->parseContext), data->pn,
<                                         JSREPORT_ERROR, JSMSG_REDECLARED_VAR,
<                                         (ale && ALE_JSOP(ale) == JSOP_DEFCONST)
<                                         ? js_const_str
<                                         : "variable",
<                                         name);
<         }
<         return JS_FALSE;
<     }
---
>     ts->flags |= TSF_REGEXP;
>     tt = js_GetToken(cx, ts);
>     ts->flags &= ~TSF_REGEXP;
1646,1649c1171,1175
<     if (data->u.let.index == JS_BIT(16)) {
<         js_ReportCompileErrorNumber(cx, TS(tc->parseContext), data->pn,
<                                     JSREPORT_ERROR, data->u.let.overflow);
<         return JS_FALSE;
---
> #if JS_HAS_GETTER_SETTER
>     if (tt == TOK_NAME) {
>         tt = CheckGetterOrSetter(cx, ts, TOK_FUNCTION);
>         if (tt == TOK_ERROR)
>             return NULL;
1650a1177
> #endif
1652,1695c1179,1203
<     /* Use JSPROP_ENUMERATE to aid the disassembler. */
<     return js_DefineNativeProperty(cx, blockObj, ATOM_TO_JSID(atom),
<                                    JSVAL_VOID, NULL, NULL,
<                                    JSPROP_ENUMERATE | JSPROP_PERMANENT,
<                                    SPROP_HAS_SHORTID,
<                                    (intN)data->u.let.index++,
<                                    NULL);
< }
< 
< static JSBool
< BindVarOrConst(JSContext *cx, BindData *data, JSAtom *atom, JSTreeContext *tc)
< {
<     JSStmtInfo *stmt;
<     JSAtomListElement *ale;
<     JSOp op, prevop;
<     const char *name;
<     JSLocalKind localKind;
< 
<     stmt = js_LexicalLookup(tc, atom, NULL, 0);
<     ATOM_LIST_SEARCH(ale, &tc->decls, atom);
<     op = data->op;
<     if ((stmt && stmt->type != STMT_WITH) || ale) {
<         prevop = ale ? ALE_JSOP(ale) : JSOP_DEFVAR;
<         if (JS_HAS_STRICT_OPTION(cx)
<             ? op != JSOP_DEFVAR || prevop != JSOP_DEFVAR
<             : op == JSOP_DEFCONST || prevop == JSOP_DEFCONST) {
<             name = js_AtomToPrintableString(cx, atom);
<             if (!name ||
<                 !js_ReportCompileErrorNumber(cx, TS(tc->parseContext), data->pn,
<                                              (op != JSOP_DEFCONST &&
<                                               prevop != JSOP_DEFCONST)
<                                              ? JSREPORT_WARNING |
<                                                JSREPORT_STRICT
<                                              : JSREPORT_ERROR,
<                                              JSMSG_REDECLARED_VAR,
<                                              (prevop == JSOP_DEFFUN ||
<                                               prevop == JSOP_CLOSURE)
<                                              ? js_function_str
<                                              : (prevop == JSOP_DEFCONST)
<                                              ? js_const_str
<                                              : js_var_str,
<                                              name)) {
<                 return JS_FALSE;
<             }
---
>     switch (tt) {
> #if JS_HAS_EXPORT_IMPORT
>       case TOK_EXPORT:
>         pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc);
>         if (!pn)
>             return NULL;
>         PN_INIT_LIST(pn);
>         if (js_MatchToken(cx, ts, TOK_STAR)) {
>             pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc);
>             if (!pn2)
>                 return NULL;
>             PN_APPEND(pn, pn2);
>         } else {
>             do {
>                 MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NO_EXPORT_NAME);
>                 pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NAME, tc);
>                 if (!pn2)
>                     return NULL;
>                 pn2->pn_op = JSOP_NAME;
>                 pn2->pn_atom = CURRENT_TOKEN(ts).t_atom;
>                 pn2->pn_expr = NULL;
>                 pn2->pn_slot = -1;
>                 pn2->pn_attrs = 0;
>                 PN_APPEND(pn, pn2);
>             } while (js_MatchToken(cx, ts, TOK_COMMA));
1697,1728c1205,1208
<         if (op == JSOP_DEFVAR && prevop == JSOP_CLOSURE)
<             tc->flags |= TCF_FUN_CLOSURE_VS_VAR;
<     }
<     if (!ale) {
<         ale = js_IndexAtom(cx, atom, &tc->decls);
<         if (!ale)
<             return JS_FALSE;
<     }
<     ALE_SET_JSOP(ale, op);
< 
<     if (!(tc->flags & TCF_IN_FUNCTION)) {
<         /*
<          * Don't lookup global variables or variables in an active frame at
<          * compile time.
<          */
<         return JS_TRUE;
<     }
< 
<     localKind = js_LookupLocal(cx, tc->fun, atom, NULL);
<     if (localKind == JSLOCAL_NONE) {
<         /*
<          * Property not found in current variable scope: we have not seen this
<          * variable before.  Define a new local variable by adding a property
<          * to the function's scope, allocating one slot in the function's vars
<          * frame. Any locals declared in with statement bodies are handled at
<          * runtime, by script prolog JSOP_DEFVAR opcodes generated for
<          * slot-less vars.
<          */
<         localKind = (data->op == JSOP_DEFCONST) ? JSLOCAL_CONST : JSLOCAL_VAR;
<         if (!js_InWithStatement(tc) &&
<             !BindLocalVariable(cx, tc->fun, atom, localKind)) {
<             return JS_FALSE;
---
>         pn->pn_pos.end = PN_LAST(pn)->pn_pos.end;
>         if (pn->pn_pos.end.lineno == ts->lineno &&
>             !WellTerminated(cx, ts, TOK_ERROR)) {
>             return NULL;
1730,1733c1210,1211
<     } else if (localKind == JSLOCAL_ARG) {
<         name = js_AtomToPrintableString(cx, atom);
<         if (!name)
<             return JS_FALSE;
---
>         tc->flags |= TCF_FUN_HEAVYWEIGHT;
>         break;
1735,1744c1213,1227
<         if (op == JSOP_DEFCONST) {
<             js_ReportCompileErrorNumber(cx, TS(tc->parseContext), data->pn,
<                                         JSREPORT_ERROR, JSMSG_REDECLARED_PARAM,
<                                         name);
<             return JS_FALSE;
<         }
<         if (!js_ReportCompileErrorNumber(cx, TS(tc->parseContext), data->pn,
<                                          JSREPORT_WARNING | JSREPORT_STRICT,
<                                          JSMSG_VAR_HIDES_ARG, name)) {
<             return JS_FALSE;
---
>       case TOK_IMPORT:
>         pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc);
>         if (!pn)
>             return NULL;
>         PN_INIT_LIST(pn);
>         do {
>             pn2 = ImportExpr(cx, ts, tc);
>             if (!pn2)
>                 return NULL;
>             PN_APPEND(pn, pn2);
>         } while (js_MatchToken(cx, ts, TOK_COMMA));
>         pn->pn_pos.end = PN_LAST(pn)->pn_pos.end;
>         if (pn->pn_pos.end.lineno == ts->lineno &&
>             !WellTerminated(cx, ts, TOK_ERROR)) {
>             return NULL;
1746,1768d1228
<     } else {
<         /* Not an argument, must be a redeclared local var. */
<         JS_ASSERT(localKind == JSLOCAL_VAR || localKind == JSLOCAL_CONST);
<     }
<     return JS_TRUE;
< }
< 
< #if JS_HAS_DESTRUCTURING
< 
< static JSBool
< BindDestructuringVar(JSContext *cx, BindData *data, JSParseNode *pn,
<                      JSTreeContext *tc)
< {
<     JSAtom *atom;
< 
<     /*
<      * Destructuring is a form of assignment, so just as for an initialized
<      * simple variable, we must check for assignment to 'arguments' and flag
<      * the enclosing function (if any) as heavyweight.
<      */
<     JS_ASSERT(pn->pn_type == TOK_NAME);
<     atom = pn->pn_atom;
<     if (atom == cx->runtime->atomState.argumentsAtom)
1770,1840d1229
< 
<     data->pn = pn;
<     if (!data->binder(cx, data, atom, tc))
<         return JS_FALSE;
<     data->pn = NULL;
< 
<     /*
<      * Select the appropriate name-setting opcode, which may be specialized
<      * further for local variable and argument slot optimizations.  At this
<      * point, we can't select the optimal final opcode, yet we must preserve
<      * the CONST bit and convey "set", not "get".
<      */
<     if (data->op == JSOP_DEFCONST) {
<         pn->pn_op = JSOP_SETCONST;
<         pn->pn_const = JS_TRUE;
<     } else {
<         pn->pn_op = JSOP_SETNAME;
<         pn->pn_const = JS_FALSE;
<     }
<     return JS_TRUE;
< }
< 
< static JSBool
< MakeSetCall(JSContext *cx, JSParseNode *pn, JSTreeContext *tc, uintN msg)
< {
<     JSParseNode *pn2;
< 
<     JS_ASSERT(pn->pn_arity == PN_LIST);
<     JS_ASSERT(pn->pn_op == JSOP_CALL || pn->pn_op == JSOP_EVAL);
<     pn2 = pn->pn_head;
<     if (pn2->pn_type == TOK_FUNCTION && (pn2->pn_flags & TCF_GENEXP_LAMBDA)) {
<         js_ReportCompileErrorNumber(cx, TS(tc->parseContext), pn,
<                                     JSREPORT_ERROR, msg);
<         return JS_FALSE;
<     }
<     pn->pn_op = JSOP_SETCALL;
<     return JS_TRUE;
< }
< 
< /*
<  * Here, we are destructuring {... P: Q, ...} = R, where P is any id, Q is any
<  * LHS expression except a destructuring initialiser, and R is on the stack.
<  * Because R is already evaluated, the usual LHS-specialized bytecodes won't
<  * work.  After pushing R[P] we need to evaluate Q's "reference base" QB and
<  * then push its property name QN.  At this point the stack looks like
<  *
<  *   [... R, R[P], QB, QN]
<  *
<  * We need to set QB[QN] = R[P].  This is a job for JSOP_ENUMELEM, which takes
<  * its operands with left-hand side above right-hand side:
<  *
<  *   [rval, lval, xval]
<  *
<  * and pops all three values, setting lval[xval] = rval.  But we cannot select
<  * JSOP_ENUMELEM yet, because the LHS may turn out to be an arg or local var,
<  * which can be optimized further.  So we select JSOP_SETNAME.
<  */
< static JSBool
< BindDestructuringLHS(JSContext *cx, JSParseNode *pn, JSTreeContext *tc)
< {
<     while (pn->pn_type == TOK_RP)
<         pn = pn->pn_kid;
< 
<     switch (pn->pn_type) {
<       case TOK_NAME:
<         if (pn->pn_atom == cx->runtime->atomState.argumentsAtom)
<             tc->flags |= TCF_FUN_HEAVYWEIGHT;
<         /* FALL THROUGH */
<       case TOK_DOT:
<       case TOK_LB:
<         pn->pn_op = JSOP_SETNAME;
1841a1231
> #endif /* JS_HAS_EXPORT_IMPORT */
1843,1846c1233,1240
< #if JS_HAS_LVALUE_RETURN
<       case TOK_LP:
<         if (!MakeSetCall(cx, pn, tc, JSMSG_BAD_LEFTSIDE_OF_ASS))
<             return JS_FALSE;
---
>       case TOK_FUNCTION:
>         pn = FunctionStmt(cx, ts, tc);
>         if (!pn)
>             return NULL;
>         if (pn->pn_pos.end.lineno == ts->lineno &&
>             !WellTerminated(cx, ts, TOK_FUNCTION)) {
>             return NULL;
>         }
1848d1241
< #endif
1850,1854c1243,1263
< #if JS_HAS_XML_SUPPORT
<       case TOK_UNARYOP:
<         if (pn->pn_op == JSOP_XMLNAME) {
<             pn->pn_op = JSOP_BINDXMLNAME;
<             break;
---
>       case TOK_IF:
>         /* An IF node has three kids: condition, then, and optional else. */
>         pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_TERNARY, tc);
>         if (!pn)
>             return NULL;
>         pn1 = Condition(cx, ts, tc);
>         if (!pn1)
>             return NULL;
>         js_PushStatement(tc, &stmtInfo, STMT_IF, -1);
>         pn2 = Statement(cx, ts, tc);
>         if (!pn2)
>             return NULL;
>         if (js_MatchToken(cx, ts, TOK_ELSE)) {
>             stmtInfo.type = STMT_ELSE;
>             pn3 = Statement(cx, ts, tc);
>             if (!pn3)
>                 return NULL;
>             pn->pn_pos.end = pn3->pn_pos.end;
>         } else {
>             pn3 = NULL;
>             pn->pn_pos.end = pn2->pn_pos.end;
1856,1933c1265,1269
<         /* FALL THROUGH */
< #endif
< 
<       default:
<         js_ReportCompileErrorNumber(cx, TS(tc->parseContext), pn,
<                                     JSREPORT_ERROR, JSMSG_BAD_LEFTSIDE_OF_ASS);
<         return JS_FALSE;
<     }
< 
<     return JS_TRUE;
< }
< 
< typedef struct FindPropValData {
<     uint32          numvars;    /* # of destructuring vars in left side */
<     uint32          maxstep;    /* max # of steps searching right side */
<     JSDHashTable    table;      /* hash table for O(1) right side search */
< } FindPropValData;
< 
< typedef struct FindPropValEntry {
<     JSDHashEntryHdr hdr;
<     JSParseNode     *pnkey;
<     JSParseNode     *pnval;
< } FindPropValEntry;
< 
< #define ASSERT_VALID_PROPERTY_KEY(pnkey)                                      \
<     JS_ASSERT((pnkey)->pn_arity == PN_NULLARY &&                              \
<               ((pnkey)->pn_type == TOK_NUMBER ||                              \
<                (pnkey)->pn_type == TOK_STRING ||                              \
<                (pnkey)->pn_type == TOK_NAME))
< 
< JS_STATIC_DLL_CALLBACK(JSDHashNumber)
< HashFindPropValKey(JSDHashTable *table, const void *key)
< {
<     const JSParseNode *pnkey = (const JSParseNode *)key;
< 
<     ASSERT_VALID_PROPERTY_KEY(pnkey);
<     return (pnkey->pn_type == TOK_NUMBER)
<            ? (JSDHashNumber) (JSDOUBLE_HI32(pnkey->pn_dval) ^
<                               JSDOUBLE_LO32(pnkey->pn_dval))
<            : ATOM_HASH(pnkey->pn_atom);
< }
< 
< JS_STATIC_DLL_CALLBACK(JSBool)
< MatchFindPropValEntry(JSDHashTable *table,
<                       const JSDHashEntryHdr *entry,
<                       const void *key)
< {
<     const FindPropValEntry *fpve = (const FindPropValEntry *)entry;
<     const JSParseNode *pnkey = (const JSParseNode *)key;
< 
<     ASSERT_VALID_PROPERTY_KEY(pnkey);
<     return pnkey->pn_type == fpve->pnkey->pn_type &&
<            ((pnkey->pn_type == TOK_NUMBER)
<             ? pnkey->pn_dval == fpve->pnkey->pn_dval
<             : pnkey->pn_atom == fpve->pnkey->pn_atom);
< }
< 
< static const JSDHashTableOps FindPropValOps = {
<     JS_DHashAllocTable,
<     JS_DHashFreeTable,
<     HashFindPropValKey,
<     MatchFindPropValEntry,
<     JS_DHashMoveEntryStub,
<     JS_DHashClearEntryStub,
<     JS_DHashFinalizeStub,
<     NULL
< };
< 
< #define STEP_HASH_THRESHOLD     10
< #define BIG_DESTRUCTURING        5
< #define BIG_OBJECT_INIT         20
< 
< static JSParseNode *
< FindPropertyValue(JSParseNode *pn, JSParseNode *pnid, FindPropValData *data)
< {
<     FindPropValEntry *entry;
<     JSParseNode *pnhit, *pnhead, *pnprop, *pnkey;
<     uint32 step;
---
>         js_PopStatement(tc);
>         pn->pn_kid1 = pn1;
>         pn->pn_kid2 = pn2;
>         pn->pn_kid3 = pn3;
>         return pn;
1935,1940c1271,1275
<     /* If we have a hash table, use it as the sole source of truth. */
<     if (data->table.ops) {
<         entry = (FindPropValEntry *)
<                 JS_DHashTableOperate(&data->table, pnid, JS_DHASH_LOOKUP);
<         return JS_DHASH_ENTRY_IS_BUSY(&entry->hdr) ? entry->pnval : NULL;
<     }
---
> #if JS_HAS_SWITCH_STATEMENT
>       case TOK_SWITCH:
>       {
>         JSParseNode *pn5;
>         JSBool seenDefault = JS_FALSE;
1942,1944c1277,1280
<     /* If pn is not an object initialiser node, we can't do anything here. */
<     if (pn->pn_type != TOK_RC)
<         return NULL;
---
>         pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_BINARY, tc);
>         if (!pn)
>             return NULL;
>         MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_SWITCH);
1946,1984c1282,1285
<     /*
<      * We must search all the way through pn's list, to handle the case of an
<      * id duplicated for two or more property initialisers.
<      */
<     pnhit = NULL;
<     step = 0;
<     ASSERT_VALID_PROPERTY_KEY(pnid);
<     pnhead = pn->pn_head;
<     if (pnhead && pnhead->pn_type == TOK_DEFSHARP)
<         pnhead = pnhead->pn_next;
<     if (pnid->pn_type == TOK_NUMBER) {
<         for (pnprop = pnhead; pnprop; pnprop = pnprop->pn_next) {
<             JS_ASSERT(pnprop->pn_type == TOK_COLON);
<             if (pnprop->pn_op == JSOP_NOP) {
<                 pnkey = pnprop->pn_left;
<                 ASSERT_VALID_PROPERTY_KEY(pnkey);
<                 if (pnkey->pn_type == TOK_NUMBER &&
<                     pnkey->pn_dval == pnid->pn_dval) {
<                     pnhit = pnprop;
<                 }
<                 ++step;
<             }
<         }
<     } else {
<         for (pnprop = pnhead; pnprop; pnprop = pnprop->pn_next) {
<             JS_ASSERT(pnprop->pn_type == TOK_COLON);
<             if (pnprop->pn_op == JSOP_NOP) {
<                 pnkey = pnprop->pn_left;
<                 ASSERT_VALID_PROPERTY_KEY(pnkey);
<                 if (pnkey->pn_type == pnid->pn_type &&
<                     pnkey->pn_atom == pnid->pn_atom) {
<                     pnhit = pnprop;
<                 }
<                 ++step;
<             }
<         }
<     }
<     if (!pnhit)
<         return NULL;
---
>         /* pn1 points to the switch's discriminant. */
>         pn1 = Expr(cx, ts, tc);
>         if (!pn1)
>             return NULL;
1986,2008c1287,1288
<     /* Hit via full search -- see whether it's time to create the hash table. */
<     JS_ASSERT(!data->table.ops);
<     if (step > data->maxstep) {
<         data->maxstep = step;
<         if (step >= STEP_HASH_THRESHOLD &&
<             data->numvars >= BIG_DESTRUCTURING &&
<             pn->pn_count >= BIG_OBJECT_INIT &&
<             JS_DHashTableInit(&data->table, &FindPropValOps, pn,
<                               sizeof(FindPropValEntry),
<                               JS_DHASH_DEFAULT_CAPACITY(pn->pn_count)))
<         {
<             for (pn = pnhead; pn; pn = pn->pn_next) {
<                 JS_ASSERT(pnprop->pn_type == TOK_COLON);
<                 ASSERT_VALID_PROPERTY_KEY(pn->pn_left);
<                 entry = (FindPropValEntry *)
<                         JS_DHashTableOperate(&data->table, pn->pn_left,
<                                              JS_DHASH_ADD);
<                 entry->pnval = pn->pn_right;
<             }
<         }
<     }
<     return pnhit->pn_right;
< }
---
>         MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_SWITCH);
>         MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_SWITCH);
2010,2022c1290,1294
< /*
<  * If data is null, the caller is AssignExpr and instead of binding variables,
<  * we specialize lvalues in the propery value positions of the left-hand side.
<  * If right is null, just check for well-formed lvalues.
<  */
< static JSBool
< CheckDestructuring(JSContext *cx, BindData *data,
<                    JSParseNode *left, JSParseNode *right,
<                    JSTreeContext *tc)
< {
<     JSBool ok;
<     FindPropValData fpvd;
<     JSParseNode *lhs, *rhs, *pn, *pn2;
---
>         /* pn2 is a list of case nodes. The default case has pn_left == NULL */
>         pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc);
>         if (!pn2)
>             return NULL;
>         PN_INIT_LIST(pn2);
2024,2028c1296
<     if (left->pn_type == TOK_ARRAYCOMP) {
<         js_ReportCompileErrorNumber(cx, TS(tc->parseContext), left,
<                                     JSREPORT_ERROR, JSMSG_ARRAY_COMP_LEFTSIDE);
<         return JS_FALSE;
<     }
---
>         js_PushStatement(tc, &stmtInfo, STMT_SWITCH, -1);
2030,2051c1298,1304
<     ok = JS_TRUE;
<     fpvd.table.ops = NULL;
<     lhs = left->pn_head;
<     if (lhs && lhs->pn_type == TOK_DEFSHARP) {
<         pn = lhs;
<         goto no_var_name;
<     }
< 
<     if (left->pn_type == TOK_RB) {
<         rhs = (right && right->pn_type == left->pn_type)
<               ? right->pn_head
<               : NULL;
< 
<         while (lhs) {
<             pn = lhs, pn2 = rhs;
<             if (!data) {
<                 /* Skip parenthesization if not in a variable declaration. */
<                 while (pn->pn_type == TOK_RP)
<                     pn = pn->pn_kid;
<                 if (pn2) {
<                     while (pn2->pn_type == TOK_RP)
<                         pn2 = pn2->pn_kid;
---
>         while ((tt = js_GetToken(cx, ts)) != TOK_RC) {
>             switch (tt) {
>               case TOK_DEFAULT:
>                 if (seenDefault) {
>                     js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
>                                                 JSMSG_TOO_MANY_DEFAULTS);
>                     return NULL;
2053c1306,1307
<             }
---
>                 seenDefault = JS_TRUE;
>                 /* fall through */
2055,2058c1309,1314
<             /* Nullary comma is an elision; binary comma is an expression.*/
<             if (pn->pn_type != TOK_COMMA || pn->pn_arity != PN_NULLARY) {
<                 if (pn->pn_type == TOK_RB || pn->pn_type == TOK_RC) {
<                     ok = CheckDestructuring(cx, data, pn, pn2, tc);
---
>               case TOK_CASE:
>                 pn3 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_BINARY, tc);
>                 if (!pn3)
>                     return NULL;
>                 if (tt == TOK_DEFAULT) {
>                     pn3->pn_left = NULL;
2060,2067c1316,1318
<                     if (data) {
<                         if (pn->pn_type != TOK_NAME)
<                             goto no_var_name;
< 
<                         ok = BindDestructuringVar(cx, data, pn, tc);
<                     } else {
<                         ok = BindDestructuringLHS(cx, pn, tc);
<                     }
---
>                     pn3->pn_left = Expr(cx, ts, tc);
>                     if (!pn3->pn_left)
>                         return NULL;
2069,2098c1320,1324
<                 if (!ok)
<                     goto out;
<             }
< 
<             lhs = lhs->pn_next;
<             if (rhs)
<                 rhs = rhs->pn_next;
<         }
<     } else {
<         JS_ASSERT(left->pn_type == TOK_RC);
<         fpvd.numvars = left->pn_count;
<         fpvd.maxstep = 0;
<         rhs = NULL;
< 
<         while (lhs) {
<             JS_ASSERT(lhs->pn_type == TOK_COLON);
<             pn = lhs->pn_right;
<             if (!data) {
<                 /* Skip parenthesization if not in a variable declaration. */
<                 while (pn->pn_type == TOK_RP)
<                     pn = pn->pn_kid;
<             }
< 
<             if (pn->pn_type == TOK_RB || pn->pn_type == TOK_RC) {
<                 if (right) {
<                     rhs = FindPropertyValue(right, lhs->pn_left, &fpvd);
<                     if (rhs && !data) {
<                         while (rhs->pn_type == TOK_RP)
<                             rhs = rhs->pn_kid;
<                     }
---
>                 PN_APPEND(pn2, pn3);
>                 if (pn2->pn_count == JS_BIT(16)) {
>                     js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
>                                                 JSMSG_TOO_MANY_CASES);
>                     return NULL;
2099a1326
>                 break;
2101,2104c1328,1329
<                 ok = CheckDestructuring(cx, data, pn, rhs, tc);
<             } else if (data) {
<                 if (pn->pn_type != TOK_NAME)
<                     goto no_var_name;
---
>               case TOK_ERROR:
>                 return NULL;
2106,2108c1331,1334
<                 ok = BindDestructuringVar(cx, data, pn, tc);
<             } else {
<                 ok = BindDestructuringLHS(cx, pn, tc);
---
>               default:
>                 js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
>                                             JSMSG_BAD_SWITCH);
>                 return NULL;
2110,2111c1336
<             if (!ok)
<                 goto out;
---
>             MUST_MATCH_TOKEN(TOK_COLON, JSMSG_COLON_AFTER_CASE);
2113,2120c1338,1352
<             lhs = lhs->pn_next;
<         }
<     }
< 
< out:
<     if (fpvd.table.ops)
<         JS_DHashTableFinish(&fpvd.table);
<     return ok;
---
>             pn4 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc);
>             if (!pn4)
>                 return NULL;
>             pn4->pn_type = TOK_LC;
>             PN_INIT_LIST(pn4);
>             while ((tt = js_PeekToken(cx, ts)) != TOK_RC &&
>                     tt != TOK_CASE && tt != TOK_DEFAULT) {
>                 if (tt == TOK_ERROR)
>                     return NULL;
>                 pn5 = Statement(cx, ts, tc);
>                 if (!pn5)
>                     return NULL;
>                 pn4->pn_pos.end = pn5->pn_pos.end;
>                 PN_APPEND(pn4, pn5);
>             }
2122,2127c1354,1359
< no_var_name:
<     js_ReportCompileErrorNumber(cx, TS(tc->parseContext), pn, JSREPORT_ERROR,
<                                 JSMSG_NO_VARIABLE_NAME);
<     ok = JS_FALSE;
<     goto out;
< }
---
>             /* Fix the PN_LIST so it doesn't begin at the TOK_COLON. */
>             if (pn4->pn_head)
>                 pn4->pn_pos.begin = pn4->pn_head->pn_pos.begin;
>             pn3->pn_pos.end = pn4->pn_pos.end;
>             pn3->pn_right = pn4;
>         }
2129,2133c1361
< static JSParseNode *
< DestructuringExpr(JSContext *cx, BindData *data, JSTreeContext *tc,
<                   JSTokenType tt)
< {
<     JSParseNode *pn;
---
>         js_PopStatement(tc);
2135,2141c1363,1368
<     pn = PrimaryExpr(cx, TS(tc->parseContext), tc, tt, JS_FALSE);
<     if (!pn)
<         return NULL;
<     if (!CheckDestructuring(cx, data, pn, NULL, tc))
<         return NULL;
<     return pn;
< }
---
>         pn->pn_pos.end = pn2->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
>         pn->pn_kid1 = pn1;
>         pn->pn_kid2 = pn2;
>         return pn;
>       }
> #endif /* JS_HAS_SWITCH_STATEMENT */
2143c1370,1385
< #endif /* JS_HAS_DESTRUCTURING */
---
>       case TOK_WHILE:
>         pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_BINARY, tc);
>         if (!pn)
>             return NULL;
>         js_PushStatement(tc, &stmtInfo, STMT_WHILE_LOOP, -1);
>         pn2 = Condition(cx, ts, tc);
>         if (!pn2)
>             return NULL;
>         pn->pn_left = pn2;
>         pn2 = Statement(cx, ts, tc);
>         if (!pn2)
>             return NULL;
>         js_PopStatement(tc);
>         pn->pn_pos.end = pn2->pn_pos.end;
>         pn->pn_right = pn2;
>         return pn;
2145c1387,1405
< extern const char js_with_statement_str[];
---
> #if JS_HAS_DO_WHILE_LOOP
>       case TOK_DO:
>         pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_BINARY, tc);
>         if (!pn)
>             return NULL;
>         js_PushStatement(tc, &stmtInfo, STMT_DO_LOOP, -1);
>         pn2 = Statement(cx, ts, tc);
>         if (!pn2)
>             return NULL;
>         pn->pn_left = pn2;
>         MUST_MATCH_TOKEN(TOK_WHILE, JSMSG_WHILE_AFTER_DO);
>         pn2 = Condition(cx, ts, tc);
>         if (!pn2)
>             return NULL;
>         js_PopStatement(tc);
>         pn->pn_pos.end = pn2->pn_pos.end;
>         pn->pn_right = pn2;
>         break;
> #endif /* JS_HAS_DO_WHILE_LOOP */
2147,2150c1407,1412
< static JSParseNode *
< ContainsStmt(JSParseNode *pn, JSTokenType tt)
< {
<     JSParseNode *pn2, *pnt;
---
>       case TOK_FOR:
>         /* A FOR node is binary, left is loop control and right is the body. */
>         pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_BINARY, tc);
>         if (!pn)
>             return NULL;
>         js_PushStatement(tc, &stmtInfo, STMT_FOR_LOOP, -1);
2152,2161c1414,1443
<     if (!pn)
<         return NULL;
<     if (pn->pn_type == tt)
<         return pn;
<     switch (pn->pn_arity) {
<       case PN_LIST:
<         for (pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) {
<             pnt = ContainsStmt(pn2, tt);
<             if (pnt)
<                 return pnt;
---
>         MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_AFTER_FOR);
>         tt = js_PeekToken(cx, ts);
>         if (tt == TOK_SEMI) {
>             /* No initializer -- set first kid of left sub-node to null. */
>             pn1 = NULL;
>         } else {
>             /* Set pn1 to a var list or an initializing expression. */
> #if JS_HAS_IN_OPERATOR
>             /*
>              * Set the TCF_IN_FOR_INIT flag during parsing of the first clause
>              * of the for statement.  This flag will be used by the RelExpr
>              * production; if it is set, then the 'in' keyword will not be
>              * recognized as an operator, leaving it available to be parsed as
>              * part of a for/in loop.  A side effect of this restriction is
>              * that (unparenthesized) expressions involving an 'in' operator
>              * are illegal in the init clause of an ordinary for loop.
>              */
>             tc->flags |= TCF_IN_FOR_INIT;
> #endif /* JS_HAS_IN_OPERATOR */
>             if (tt == TOK_VAR) {
>                 (void) js_GetToken(cx, ts);
>                 pn1 = Variables(cx, ts, tc);
>             } else {
>                 pn1 = Expr(cx, ts, tc);
>             }
> #if JS_HAS_IN_OPERATOR
>             tc->flags &= ~TCF_IN_FOR_INIT;
> #endif /* JS_HAS_IN_OPERATOR */
>             if (!pn1)
>                 return NULL;
2163,2172c1445
<         break;
<       case PN_TERNARY:
<         pnt = ContainsStmt(pn->pn_kid1, tt);
<         if (pnt)
<             return pnt;
<         pnt = ContainsStmt(pn->pn_kid2, tt);
<         if (pnt)
<             return pnt;
<         return ContainsStmt(pn->pn_kid3, tt);
<       case PN_BINARY:
---
> 
2174,2175c1447,1450
<          * Limit recursion if pn is a binary expression, which can't contain a
<          * var statement.
---
>          * We can be sure that it's a for/in loop if there's still an 'in'
>          * keyword here, even if JavaScript recognizes 'in' as an operator,
>          * as we've excluded 'in' from being parsed in RelExpr by setting
>          * the TCF_IN_FOR_INIT flag in our JSTreeContext.
2177,2192c1452,1453
<         if (pn->pn_op != JSOP_NOP)
<             return NULL;
<         pnt = ContainsStmt(pn->pn_left, tt);
<         if (pnt)
<             return pnt;
<         return ContainsStmt(pn->pn_right, tt);
<       case PN_UNARY:
<         if (pn->pn_op != JSOP_NOP)
<             return NULL;
<         return ContainsStmt(pn->pn_kid, tt);
<       case PN_NAME:
<         return ContainsStmt(pn->pn_expr, tt);
<       default:;
<     }
<     return NULL;
< }
---
>         if (pn1 && js_MatchToken(cx, ts, TOK_IN)) {
>             stmtInfo.type = STMT_FOR_IN_LOOP;
2194,2199c1455,1464
< static JSParseNode *
< ReturnOrYield(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
<               JSParser operandParser)
< {
<     JSTokenType tt, tt2;
<     JSParseNode *pn, *pn2;
---
>             /* Check that the left side of the 'in' is valid. */
>             if ((pn1->pn_type == TOK_VAR)
>                 ? (pn1->pn_count > 1 || pn1->pn_op == JSOP_DEFCONST)
>                 : (pn1->pn_type != TOK_NAME &&
>                    pn1->pn_type != TOK_DOT &&
>                    pn1->pn_type != TOK_LB)) {
>                 js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
>                                             JSMSG_BAD_FOR_LEFTSIDE);
>                 return NULL;
>             }
2201,2206c1466,1471
<     tt = CURRENT_TOKEN(ts).type;
<     if (tt == TOK_RETURN && !(tc->flags & TCF_IN_FUNCTION)) {
<         js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                     JSMSG_BAD_RETURN_OR_YIELD, js_return_str);
<         return NULL;
<     }
---
>             /* Beware 'for (arguments in ...)' with or without a 'var'. */
>             pn2 = (pn1->pn_type == TOK_VAR) ? pn1->pn_head : pn1;
>             if (pn2->pn_type == TOK_NAME &&
>                 pn2->pn_atom == cx->runtime->atomState.argumentsAtom) {
>                 tc->flags |= TCF_FUN_HEAVYWEIGHT;
>             }
2208,2210c1473,1487
<     pn = NewParseNode(cx, ts, PN_UNARY, tc);
<     if (!pn)
<         return NULL;
---
>             /* Parse the object expression as the right operand of 'in'. */
>             pn2 = NewBinary(cx, TOK_IN, JSOP_NOP, pn1, Expr(cx, ts, tc), tc);
>             if (!pn2)
>                 return NULL;
>             pn->pn_left = pn2;
>         } else {
>             /* Parse the loop condition or null into pn2. */
>             MUST_MATCH_TOKEN(TOK_SEMI, JSMSG_SEMI_AFTER_FOR_INIT);
>             if (js_PeekToken(cx, ts) == TOK_SEMI) {
>                 pn2 = NULL;
>             } else {
>                 pn2 = Expr(cx, ts, tc);
>                 if (!pn2)
>                     return NULL;
>             }
2212,2215c1489,1497
< #if JS_HAS_GENERATORS
<     if (tt == TOK_YIELD)
<         tc->flags |= TCF_FUN_IS_GENERATOR;
< #endif
---
>             /* Parse the update expression or null into pn3. */
>             MUST_MATCH_TOKEN(TOK_SEMI, JSMSG_SEMI_AFTER_FOR_COND);
>             if (js_PeekToken(cx, ts) == TOK_RP) {
>                 pn3 = NULL;
>             } else {
>                 pn3 = Expr(cx, ts, tc);
>                 if (!pn3)
>                     return NULL;
>             }
2217,2222c1499,1509
<     /* This is ugly, but we don't want to require a semicolon. */
<     ts->flags |= TSF_OPERAND;
<     tt2 = js_PeekTokenSameLine(cx, ts);
<     ts->flags &= ~TSF_OPERAND;
<     if (tt2 == TOK_ERROR)
<         return NULL;
---
>             /* Build the RESERVED node to use as the left kid of pn. */
>             pn4 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_TERNARY, tc);
>             if (!pn4)
>                 return NULL;
>             pn4->pn_type = TOK_RESERVED;
>             pn4->pn_op = JSOP_NOP;
>             pn4->pn_kid1 = pn1;
>             pn4->pn_kid2 = pn2;
>             pn4->pn_kid3 = pn3;
>             pn->pn_left = pn4;
>         }
2224,2230c1511,1514
<     if (tt2 != TOK_EOF && tt2 != TOK_EOL && tt2 != TOK_SEMI && tt2 != TOK_RC
< #if JS_HAS_GENERATORS
<         && (tt != TOK_YIELD ||
<             (tt2 != tt && tt2 != TOK_RB && tt2 != TOK_RP && tt2 != TOK_COLON))
< #endif
<         ) {
<         pn2 = operandParser(cx, ts, tc);
---
>         MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_FOR_CTRL);
> 
>         /* Parse the loop body into pn->pn_right. */
>         pn2 = Statement(cx, ts, tc);
2233,2263c1517,1518
< #if JS_HAS_GENERATORS
<         if (tt == TOK_RETURN)
< #endif
<             tc->flags |= TCF_RETURN_EXPR;
<         pn->pn_pos.end = pn2->pn_pos.end;
<         pn->pn_kid = pn2;
<     } else {
< #if JS_HAS_GENERATORS
<         if (tt == TOK_RETURN)
< #endif
<             tc->flags |= TCF_RETURN_VOID;
<     }
< 
<     if ((~tc->flags & (TCF_RETURN_EXPR | TCF_FUN_IS_GENERATOR)) == 0) {
<         /* As in Python (see PEP-255), disallow return v; in generators. */
<         ReportBadReturn(cx, tc, JSREPORT_ERROR,
<                         JSMSG_BAD_GENERATOR_RETURN,
<                         JSMSG_BAD_ANON_GENERATOR_RETURN);
<         return NULL;
<     }
< 
<     if (JS_HAS_STRICT_OPTION(cx) &&
<         (~tc->flags & (TCF_RETURN_EXPR | TCF_RETURN_VOID)) == 0 &&
<         !ReportBadReturn(cx, tc, JSREPORT_WARNING | JSREPORT_STRICT,
<                          JSMSG_NO_RETURN_VALUE,
<                          JSMSG_ANON_NO_RETURN_VALUE)) {
<         return NULL;
<     }
< 
<     return pn;
< }
---
>         pn->pn_right = pn2;
>         js_PopStatement(tc);
2265,2271c1520,1522
< static JSParseNode *
< PushLexicalScope(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
<                  JSStmtInfo *stmtInfo)
< {
<     JSParseNode *pn;
<     JSObject *obj;
<     JSParsedObjectBox *blockpob;
---
>         /* Record the absolute line number for source note emission. */
>         pn->pn_pos.end = pn2->pn_pos.end;
>         return pn;
2273,2275c1524,1546
<     pn = NewParseNode(cx, ts, PN_NAME, tc);
<     if (!pn)
<         return NULL;
---
> #if JS_HAS_EXCEPTIONS
>       case TOK_TRY: {
>         JSParseNode *catchtail = NULL;
>         /*
>          * try nodes are ternary.
>          * kid1 is the try Statement
>          * kid2 is the catch node
>          * kid3 is the finally Statement
>          *
>          * catch nodes are ternary.
>          * kid1 is the discriminant
>          * kid2 is the next catch node, or NULL
>          * kid3 is the catch block (on kid3 so that we can always append a
>          *                          new catch pn on catchtail->kid2)
>          *
>          * catch discriminant nodes are binary
>          * atom is the receptacle
>          * expr is the discriminant code
>          *
>          * finally nodes are unary (just the finally expression)
>          */
>         pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_TERNARY, tc);
>         pn->pn_op = JSOP_NOP;
2277,2279c1548,1554
<     obj = js_NewBlockObject(cx);
<     if (!obj)
<         return NULL;
---
>         MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_TRY);
>         js_PushStatement(tc, &stmtInfo, STMT_TRY, -1);
>         pn->pn_kid1 = Statements(cx, ts, tc);
>         if (!pn->pn_kid1)
>             return NULL;
>         MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_TRY);
>         js_PopStatement(tc);
2281,2283c1556,1563
<     blockpob = js_NewParsedObjectBox(cx, tc->parseContext, obj);
<     if (!blockpob)
<         return NULL;
---
>         catchtail = pn;
>         while (js_PeekToken(cx, ts) == TOK_CATCH) {
>             /* check for another catch after unconditional catch */
>             if (catchtail != pn && !catchtail->pn_kid1->pn_expr) {
>                 js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
>                                             JSMSG_CATCH_AFTER_GENERAL);
>                 return NULL;
>             }
2285,2291c1565,1574
<     js_PushBlockScope(tc, stmtInfo, obj, -1);
<     pn->pn_type = TOK_LEXICALSCOPE;
<     pn->pn_op = JSOP_LEAVEBLOCK;
<     pn->pn_pob = blockpob;
<     pn->pn_slot = -1;
<     return pn;
< }
---
>             /*
>              * legal catch forms are:
>              * catch (v)
>              * catch (v if <boolean_expression>)
>              * (the latter is legal only #ifdef JS_HAS_CATCH_GUARD)
>              */
>             (void) js_GetToken(cx, ts); /* eat `catch' */
>             pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_TERNARY, tc);
>             if (!pn2)
>                 return NULL;
2293c1576,1584
< #if JS_HAS_BLOCK_SCOPE
---
>             /*
>              * We use a PN_NAME for the discriminant (catchguard) node
>              * with the actual discriminant code in the initializer spot
>              */
>             MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_CATCH);
>             MUST_MATCH_TOKEN(TOK_NAME, JSMSG_CATCH_IDENTIFIER);
>             pn3 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NAME, tc);
>             if (!pn3)
>                 return NULL;
2295,2299c1586,1600
< static JSParseNode *
< LetBlock(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc, JSBool statement)
< {
<     JSParseNode *pn, *pnblock, *pnlet;
<     JSStmtInfo stmtInfo;
---
>             pn3->pn_atom = CURRENT_TOKEN(ts).t_atom;
>             pn3->pn_expr = NULL;
> #if JS_HAS_CATCH_GUARD
>             /*
>              * We use `catch (x if x === 5)' (not `catch (x : x === 5)') to
>              * avoid conflicting with the JS2/ECMA2 proposed catchguard syntax.
>              */
>             if (js_PeekToken(cx, ts) == TOK_IF) {
>                 (void)js_GetToken(cx, ts); /* eat `if' */
>                 pn3->pn_expr = Expr(cx, ts, tc);
>                 if (!pn3->pn_expr)
>                     return NULL;
>             }
> #endif
>             pn2->pn_kid1 = pn3;
2301c1602
<     JS_ASSERT(CURRENT_TOKEN(ts).type == TOK_LET);
---
>             MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_CATCH);
2303,2306c1604,1611
<     /* Create the let binary node. */
<     pnlet = NewParseNode(cx, ts, PN_BINARY, tc);
<     if (!pnlet)
<         return NULL;
---
>             MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_CATCH);
>             js_PushStatement(tc, &stmtInfo, STMT_CATCH, -1);
>             stmtInfo.label = pn3->pn_atom;
>             pn2->pn_kid3 = Statements(cx, ts, tc);
>             if (!pn2->pn_kid3)
>                 return NULL;
>             MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_CATCH);
>             js_PopStatement(tc);
2308c1613,1615
<     MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_LET);
---
>             catchtail = catchtail->pn_kid2 = pn2;
>         }
>         catchtail->pn_kid2 = NULL;
2310,2322c1617,1636
<     /* This is a let block or expression of the form: let (a, b, c) .... */
<     pnblock = PushLexicalScope(cx, ts, tc, &stmtInfo);
<     if (!pnblock)
<         return NULL;
<     pn = pnblock;
<     pn->pn_expr = pnlet;
< 
<     pnlet->pn_left = Variables(cx, ts, tc);
<     if (!pnlet->pn_left)
<         return NULL;
<     pnlet->pn_left->pn_extra = PNX_POPVAR;
< 
<     MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_LET);
---
>         if (js_MatchToken(cx, ts, TOK_FINALLY)) {
>             tc->tryCount++;
>             MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_FINALLY);
>             js_PushStatement(tc, &stmtInfo, STMT_FINALLY, -1);
>             pn->pn_kid3 = Statements(cx, ts, tc);
>             if (!pn->pn_kid3)
>                 return NULL;
>             MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_FINALLY);
>             js_PopStatement(tc);
>         } else {
>             pn->pn_kid3 = NULL;
>         }
>         if (!pn->pn_kid2 && !pn->pn_kid3) {
>             js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
>                                         JSMSG_CATCH_OR_FINALLY);
>             return NULL;
>         }
>         tc->tryCount++;
>         return pn;
>       }
2324,2331c1638,1639
<     ts->flags |= TSF_OPERAND;
<     if (statement && !js_MatchToken(cx, ts, TOK_LC)) {
<         /*
<          * If this is really an expression in let statement guise, then we
<          * need to wrap the TOK_LET node in a TOK_SEMI node so that we pop
<          * the return value of the expression.
<          */
<         pn = NewParseNode(cx, ts, PN_UNARY, tc);
---
>       case TOK_THROW:
>         pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc);
2334,2344c1642,1643
<         pn->pn_type = TOK_SEMI;
<         pn->pn_num = -1;
<         pn->pn_kid = pnblock;
< 
<         statement = JS_FALSE;
<     }
<     ts->flags &= ~TSF_OPERAND;
< 
<     if (statement) {
<         pnlet->pn_right = Statements(cx, ts, tc);
<         if (!pnlet->pn_right)
---
>         pn2 = Expr(cx, ts, tc);
>         if (!pn2)
2346,2354c1645,1647
<         MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_LET);
<     } else {
<         /*
<          * Change pnblock's opcode to the variant that propagates the last
<          * result down after popping the block, and clear statement.
<          */
<         pnblock->pn_op = JSOP_LEAVEBLOCKEXPR;
<         pnlet->pn_right = AssignExpr(cx, ts, tc);
<         if (!pnlet->pn_right)
---
>         pn->pn_pos.end = pn2->pn_pos.end;
>         if (pn->pn_pos.end.lineno == ts->lineno &&
>             !WellTerminated(cx, ts, TOK_ERROR)) {
2356,2370c1649,1652
<     }
< 
<     js_PopStatement(tc);
<     return pn;
< }
< 
< #endif /* JS_HAS_BLOCK_SCOPE */
< 
< static JSParseNode *
< Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
< {
<     JSTokenType tt;
<     JSParseNode *pn, *pn1, *pn2, *pn3, *pn4;
<     JSStmtInfo stmtInfo, *stmt, *stmt2;
<     JSAtom *label;
---
>         }
>         pn->pn_op = JSOP_THROW;
>         pn->pn_kid = pn2;
>         break;
2372c1654,1658
<     JS_CHECK_RECURSION(cx, return NULL);
---
>       /* TOK_CATCH and TOK_FINALLY are both handled in the TOK_TRY case */
>       case TOK_CATCH:
>         js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
>                                     JSMSG_CATCH_WITHOUT_TRY);
>         return NULL;
2374,2376c1660,1663
<     ts->flags |= TSF_OPERAND;
<     tt = js_GetToken(cx, ts);
<     ts->flags &= ~TSF_OPERAND;
---
>       case TOK_FINALLY:
>         js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
>                                     JSMSG_FINALLY_WITHOUT_TRY);
>         return NULL;
2378,2384c1665
< #if JS_HAS_GETTER_SETTER
<     if (tt == TOK_NAME) {
<         tt = CheckGetterOrSetter(cx, ts, TOK_FUNCTION);
<         if (tt == TOK_ERROR)
<             return NULL;
<     }
< #endif
---
> #endif /* JS_HAS_EXCEPTIONS */
2386,2389c1667,1668
<     switch (tt) {
< #if JS_HAS_EXPORT_IMPORT
<       case TOK_EXPORT:
<         pn = NewParseNode(cx, ts, PN_LIST, tc);
---
>       case TOK_BREAK:
>         pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc);
2392,2397c1671,1684
<         PN_INIT_LIST(pn);
<         if (js_MatchToken(cx, ts, TOK_STAR)) {
<             pn2 = NewParseNode(cx, ts, PN_NULLARY, tc);
<             if (!pn2)
<                 return NULL;
<             PN_APPEND(pn, pn2);
---
>         if (!MatchLabel(cx, ts, pn))
>             return NULL;
>         stmt = tc->topStmt;
>         label = pn->pn_atom;
>         if (label) {
>             for (; ; stmt = stmt->down) {
>                 if (!stmt) {
>                     js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
>                                                 JSMSG_LABEL_NOT_FOUND);
>                     return NULL;
>                 }
>                 if (stmt->type == STMT_LABEL && stmt->label == label)
>                     break;
>             }
2399,2402c1686,1689
<             do {
<                 MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NO_EXPORT_NAME);
<                 pn2 = NewParseNode(cx, ts, PN_NAME, tc);
<                 if (!pn2)
---
>             for (; ; stmt = stmt->down) {
>                 if (!stmt) {
>                     js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
>                                                 JSMSG_TOUGH_BREAK);
2404,2408c1691,1694
<                 pn2->pn_op = JSOP_NAME;
<                 pn2->pn_atom = CURRENT_TOKEN(ts).t_atom;
<                 pn2->pn_slot = -1;
<                 PN_APPEND(pn, pn2);
<             } while (js_MatchToken(cx, ts, TOK_COMMA));
---
>                 }
>                 if (STMT_IS_LOOP(stmt) || stmt->type == STMT_SWITCH)
>                     break;
>             }
2410,2411c1696,1697
<         pn->pn_pos.end = PN_LAST(pn)->pn_pos.end;
<         tc->flags |= TCF_FUN_HEAVYWEIGHT;
---
>         if (label)
>             pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
2414,2415c1700,1701
<       case TOK_IMPORT:
<         pn = NewParseNode(cx, ts, PN_LIST, tc);
---
>       case TOK_CONTINUE:
>         pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc);
2418,2426c1704,1741
<         PN_INIT_LIST(pn);
<         do {
<             pn2 = ImportExpr(cx, ts, tc);
<             if (!pn2)
<                 return NULL;
<             PN_APPEND(pn, pn2);
<         } while (js_MatchToken(cx, ts, TOK_COMMA));
<         pn->pn_pos.end = PN_LAST(pn)->pn_pos.end;
<         tc->flags |= TCF_FUN_HEAVYWEIGHT;
---
>         if (!MatchLabel(cx, ts, pn))
>             return NULL;
>         stmt = tc->topStmt;
>         label = pn->pn_atom;
>         if (label) {
>             for (stmt2 = NULL; ; stmt = stmt->down) {
>                 if (!stmt) {
>                     js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
>                                                 JSMSG_LABEL_NOT_FOUND);
>                     return NULL;
>                 }
>                 if (stmt->type == STMT_LABEL) {
>                     if (stmt->label == label) {
>                         if (!stmt2 || !STMT_IS_LOOP(stmt2)) {
>                             js_ReportCompileErrorNumber(cx, ts, NULL,
>                                                         JSREPORT_ERROR,
>                                                         JSMSG_BAD_CONTINUE);
>                             return NULL;
>                         }
>                         break;
>                     }
>                 } else {
>                     stmt2 = stmt;
>                 }
>             }
>         } else {
>             for (; ; stmt = stmt->down) {
>                 if (!stmt) {
>                     js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
>                                                 JSMSG_BAD_CONTINUE);
>                     return NULL;
>                 }
>                 if (STMT_IS_LOOP(stmt))
>                     break;
>             }
>         }
>         if (label)
>             pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
2428,2438d1742
< #endif /* JS_HAS_EXPORT_IMPORT */
< 
<       case TOK_FUNCTION:
< #if JS_HAS_XML_SUPPORT
<         ts->flags |= TSF_KEYWORD_IS_NAME;
<         tt = js_PeekToken(cx, ts);
<         ts->flags &= ~TSF_KEYWORD_IS_NAME;
<         if (tt == TOK_DBLCOLON)
<             goto expression;
< #endif
<         return FunctionStmt(cx, ts, tc);
2440,2442c1744,1745
<       case TOK_IF:
<         /* An IF node has three kids: condition, then, and optional else. */
<         pn = NewParseNode(cx, ts, PN_TERNARY, tc);
---
>       case TOK_WITH:
>         pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_BINARY, tc);
2445,2446c1748,1750
<         pn1 = Condition(cx, ts, tc);
<         if (!pn1)
---
>         MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_WITH);
>         pn2 = Expr(cx, ts, tc);
>         if (!pn2)
2448c1752,1755
<         js_PushStatement(tc, &stmtInfo, STMT_IF, -1);
---
>         MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_WITH);
>         pn->pn_left = pn2;
> 
>         js_PushStatement(tc, &stmtInfo, STMT_WITH, -1);
2452,2464d1758
<         ts->flags |= TSF_OPERAND;
<         if (js_MatchToken(cx, ts, TOK_ELSE)) {
<             ts->flags &= ~TSF_OPERAND;
<             stmtInfo.type = STMT_ELSE;
<             pn3 = Statement(cx, ts, tc);
<             if (!pn3)
<                 return NULL;
<             pn->pn_pos.end = pn3->pn_pos.end;
<         } else {
<             ts->flags &= ~TSF_OPERAND;
<             pn3 = NULL;
<             pn->pn_pos.end = pn2->pn_pos.end;
<         }
2466,2469d1759
<         pn->pn_kid1 = pn1;
<         pn->pn_kid2 = pn2;
<         pn->pn_kid3 = pn3;
<         return pn;
2471,2474c1761,1772
<       case TOK_SWITCH:
<       {
<         JSParseNode *pn5, *saveBlock;
<         JSBool seenDefault = JS_FALSE;
---
>         /* Deprecate after parsing, in case of WERROR option. */
>         if (!js_ReportCompileErrorNumber(cx, ts, NULL,
>                                          JSREPORT_WARNING | JSREPORT_STRICT,
>                                          JSMSG_DEPRECATED_USAGE,
>                                          js_with_statement_str)) {
>             return NULL;
>         }
> 
>         pn->pn_pos.end = pn2->pn_pos.end;
>         pn->pn_right = pn2;
>         tc->flags |= TCF_FUN_HEAVYWEIGHT;
>         return pn;
2476c1774,1775
<         pn = NewParseNode(cx, ts, PN_BINARY, tc);
---
>       case TOK_VAR:
>         pn = Variables(cx, ts, tc);
2479,2483c1778,1779
<         MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_SWITCH);
< 
<         /* pn1 points to the switch's discriminant. */
<         pn1 = ParenExpr(cx, ts, tc, NULL, NULL);
<         if (!pn1)
---
>         if (pn->pn_pos.end.lineno == ts->lineno &&
>             !WellTerminated(cx, ts, TOK_ERROR)) {
2484a1781,1784
>         }
>         /* Tell js_EmitTree to generate a final POP. */
>         pn->pn_extra = JS_TRUE;
>         break;
2486,2491c1786,1793
<         MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_SWITCH);
<         MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_SWITCH);
< 
<         /* pn2 is a list of case nodes. The default case has pn_left == NULL */
<         pn2 = NewParseNode(cx, ts, PN_LIST, tc);
<         if (!pn2)
---
>       case TOK_RETURN:
>         if (!(tc->flags & TCF_IN_FUNCTION)) {
>             js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
>                                         JSMSG_BAD_RETURN);
>             return NULL;
>         }
>         pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc);
>         if (!pn)
2493,2508d1794
<         saveBlock = tc->blockNode;
<         tc->blockNode = pn2;
<         PN_INIT_LIST(pn2);
< 
<         js_PushStatement(tc, &stmtInfo, STMT_SWITCH, -1);
< 
<         while ((tt = js_GetToken(cx, ts)) != TOK_RC) {
<             switch (tt) {
<               case TOK_DEFAULT:
<                 if (seenDefault) {
<                     js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                                 JSMSG_TOO_MANY_DEFAULTS);
<                     return NULL;
<                 }
<                 seenDefault = JS_TRUE;
<                 /* FALL THROUGH */
2510,2525c1796,1801
<               case TOK_CASE:
<                 pn3 = NewParseNode(cx, ts, PN_BINARY, tc);
<                 if (!pn3)
<                     return NULL;
<                 if (tt == TOK_CASE) {
<                     pn3->pn_left = Expr(cx, ts, tc);
<                     if (!pn3->pn_left)
<                         return NULL;
<                 }
<                 PN_APPEND(pn2, pn3);
<                 if (pn2->pn_count == JS_BIT(16)) {
<                     js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                                 JSMSG_TOO_MANY_CASES);
<                     return NULL;
<                 }
<                 break;
---
>         /* This is ugly, but we don't want to require a semicolon. */
>         ts->flags |= TSF_REGEXP;
>         tt = js_PeekTokenSameLine(cx, ts);
>         ts->flags &= ~TSF_REGEXP;
>         if (tt == TOK_ERROR)
>             return NULL;
2527c1803,1805
<               case TOK_ERROR:
---
>         if (tt != TOK_EOF && tt != TOK_EOL && tt != TOK_SEMI && tt != TOK_RC) {
>             pn2 = Expr(cx, ts, tc);
>             if (!pn2)
2529,2807c1807,1808
< 
<               default:
<                 js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                             JSMSG_BAD_SWITCH);
<                 return NULL;
<             }
<             MUST_MATCH_TOKEN(TOK_COLON, JSMSG_COLON_AFTER_CASE);
< 
<             pn4 = NewParseNode(cx, ts, PN_LIST, tc);
<             if (!pn4)
<                 return NULL;
<             pn4->pn_type = TOK_LC;
<             PN_INIT_LIST(pn4);
<             ts->flags |= TSF_OPERAND;
<             while ((tt = js_PeekToken(cx, ts)) != TOK_RC &&
<                    tt != TOK_CASE && tt != TOK_DEFAULT) {
<                 ts->flags &= ~TSF_OPERAND;
<                 if (tt == TOK_ERROR)
<                     return NULL;
<                 pn5 = Statement(cx, ts, tc);
<                 if (!pn5)
<                     return NULL;
<                 pn4->pn_pos.end = pn5->pn_pos.end;
<                 PN_APPEND(pn4, pn5);
<                 ts->flags |= TSF_OPERAND;
<             }
<             ts->flags &= ~TSF_OPERAND;
< 
<             /* Fix the PN_LIST so it doesn't begin at the TOK_COLON. */
<             if (pn4->pn_head)
<                 pn4->pn_pos.begin = pn4->pn_head->pn_pos.begin;
<             pn3->pn_pos.end = pn4->pn_pos.end;
<             pn3->pn_right = pn4;
<         }
< 
<         /*
<          * Handle the case where there was a let declaration in any case in
<          * the switch body, but not within an inner block.  If it replaced
<          * tc->blockNode with a new block node then we must refresh pn2 and
<          * then restore tc->blockNode.
<          */
<         if (tc->blockNode != pn2)
<             pn2 = tc->blockNode;
<         tc->blockNode = saveBlock;
<         js_PopStatement(tc);
< 
<         pn->pn_pos.end = pn2->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
<         pn->pn_left = pn1;
<         pn->pn_right = pn2;
<         return pn;
<       }
< 
<       case TOK_WHILE:
<         pn = NewParseNode(cx, ts, PN_BINARY, tc);
<         if (!pn)
<             return NULL;
<         js_PushStatement(tc, &stmtInfo, STMT_WHILE_LOOP, -1);
<         pn2 = Condition(cx, ts, tc);
<         if (!pn2)
<             return NULL;
<         pn->pn_left = pn2;
<         pn2 = Statement(cx, ts, tc);
<         if (!pn2)
<             return NULL;
<         js_PopStatement(tc);
<         pn->pn_pos.end = pn2->pn_pos.end;
<         pn->pn_right = pn2;
<         return pn;
< 
<       case TOK_DO:
<         pn = NewParseNode(cx, ts, PN_BINARY, tc);
<         if (!pn)
<             return NULL;
<         js_PushStatement(tc, &stmtInfo, STMT_DO_LOOP, -1);
<         pn2 = Statement(cx, ts, tc);
<         if (!pn2)
<             return NULL;
<         pn->pn_left = pn2;
<         MUST_MATCH_TOKEN(TOK_WHILE, JSMSG_WHILE_AFTER_DO);
<         pn2 = Condition(cx, ts, tc);
<         if (!pn2)
<             return NULL;
<         js_PopStatement(tc);
<         pn->pn_pos.end = pn2->pn_pos.end;
<         pn->pn_right = pn2;
<         if (JSVERSION_NUMBER(cx) != JSVERSION_ECMA_3) {
<             /*
<              * All legacy and extended versions must do automatic semicolon
<              * insertion after do-while.  See the testcase and discussion in
<              * http://bugzilla.mozilla.org/show_bug.cgi?id=238945.
<              */
<             (void) js_MatchToken(cx, ts, TOK_SEMI);
<             return pn;
<         }
<         break;
< 
<       case TOK_FOR:
<       {
< #if JS_HAS_BLOCK_SCOPE
<         JSParseNode *pnlet;
<         JSStmtInfo blockInfo;
< 
<         pnlet = NULL;
< #endif
< 
<         /* A FOR node is binary, left is loop control and right is the body. */
<         pn = NewParseNode(cx, ts, PN_BINARY, tc);
<         if (!pn)
<             return NULL;
<         js_PushStatement(tc, &stmtInfo, STMT_FOR_LOOP, -1);
< 
<         pn->pn_op = JSOP_FORIN;
<         if (js_MatchToken(cx, ts, TOK_NAME)) {
<             if (CURRENT_TOKEN(ts).t_atom == cx->runtime->atomState.eachAtom)
<                 pn->pn_op = JSOP_FOREACH;
<             else
<                 js_UngetToken(ts);
<         }
< 
<         MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_AFTER_FOR);
<         ts->flags |= TSF_OPERAND;
<         tt = js_PeekToken(cx, ts);
<         ts->flags &= ~TSF_OPERAND;
<         if (tt == TOK_SEMI) {
<             if (pn->pn_op == JSOP_FOREACH)
<                 goto bad_for_each;
< 
<             /* No initializer -- set first kid of left sub-node to null. */
<             pn1 = NULL;
<         } else {
<             /*
<              * Set pn1 to a var list or an initializing expression.
<              *
<              * Set the TCF_IN_FOR_INIT flag during parsing of the first clause
<              * of the for statement.  This flag will be used by the RelExpr
<              * production; if it is set, then the 'in' keyword will not be
<              * recognized as an operator, leaving it available to be parsed as
<              * part of a for/in loop.
<              *
<              * A side effect of this restriction is that (unparenthesized)
<              * expressions involving an 'in' operator are illegal in the init
<              * clause of an ordinary for loop.
<              */
<             tc->flags |= TCF_IN_FOR_INIT;
<             if (tt == TOK_VAR) {
<                 (void) js_GetToken(cx, ts);
<                 pn1 = Variables(cx, ts, tc);
< #if JS_HAS_BLOCK_SCOPE
<             } else if (tt == TOK_LET) {
<                 (void) js_GetToken(cx, ts);
<                 if (js_PeekToken(cx, ts) == TOK_LP) {
<                     pn1 = LetBlock(cx, ts, tc, JS_FALSE);
<                     tt = TOK_LEXICALSCOPE;
<                 } else {
<                     pnlet = PushLexicalScope(cx, ts, tc, &blockInfo);
<                     if (!pnlet)
<                         return NULL;
<                     blockInfo.flags |= SIF_FOR_BLOCK;
<                     pn1 = Variables(cx, ts, tc);
<                 }
< #endif
<             } else {
<                 pn1 = Expr(cx, ts, tc);
<                 if (pn1) {
<                     while (pn1->pn_type == TOK_RP)
<                         pn1 = pn1->pn_kid;
<                 }
<             }
<             tc->flags &= ~TCF_IN_FOR_INIT;
<             if (!pn1)
<                 return NULL;
<         }
< 
<         /*
<          * We can be sure that it's a for/in loop if there's still an 'in'
<          * keyword here, even if JavaScript recognizes 'in' as an operator,
<          * as we've excluded 'in' from being parsed in RelExpr by setting
<          * the TCF_IN_FOR_INIT flag in our JSTreeContext.
<          */
<         if (pn1 && js_MatchToken(cx, ts, TOK_IN)) {
<             stmtInfo.type = STMT_FOR_IN_LOOP;
< 
<             /* Check that the left side of the 'in' is valid. */
<             JS_ASSERT(!TOKEN_TYPE_IS_DECL(tt) || pn1->pn_type == tt);
<             if (TOKEN_TYPE_IS_DECL(tt)
<                 ? (pn1->pn_count > 1 || pn1->pn_op == JSOP_DEFCONST
< #if JS_HAS_DESTRUCTURING
<                    || (JSVERSION_NUMBER(cx) == JSVERSION_1_7 &&
<                        pn->pn_op == JSOP_FORIN &&
<                        (pn1->pn_head->pn_type == TOK_RC ||
<                         (pn1->pn_head->pn_type == TOK_RB &&
<                          pn1->pn_head->pn_count != 2) ||
<                         (pn1->pn_head->pn_type == TOK_ASSIGN &&
<                          (pn1->pn_head->pn_left->pn_type != TOK_RB ||
<                           pn1->pn_head->pn_left->pn_count != 2))))
< #endif
<                   )
<                 : (pn1->pn_type != TOK_NAME &&
<                    pn1->pn_type != TOK_DOT &&
< #if JS_HAS_DESTRUCTURING
<                    ((JSVERSION_NUMBER(cx) == JSVERSION_1_7 &&
<                      pn->pn_op == JSOP_FORIN)
<                     ? (pn1->pn_type != TOK_RB || pn1->pn_count != 2)
<                     : (pn1->pn_type != TOK_RB && pn1->pn_type != TOK_RC)) &&
< #endif
< #if JS_HAS_LVALUE_RETURN
<                    pn1->pn_type != TOK_LP &&
< #endif
< #if JS_HAS_XML_SUPPORT
<                    (pn1->pn_type != TOK_UNARYOP ||
<                     pn1->pn_op != JSOP_XMLNAME) &&
< #endif
<                    pn1->pn_type != TOK_LB)) {
<                 js_ReportCompileErrorNumber(cx, ts, pn1, JSREPORT_ERROR,
<                                             JSMSG_BAD_FOR_LEFTSIDE);
<                 return NULL;
<             }
< 
<             if (TOKEN_TYPE_IS_DECL(tt)) {
<                 /* Tell js_EmitTree(TOK_VAR) that pn1 is part of a for/in. */
<                 pn1->pn_extra |= PNX_FORINVAR;
< 
<                 /*
<                  * Generate a final POP only if the variable is a simple name
<                  * (which means it is not a destructuring left-hand side) and
<                  * it has an initializer.
<                  */
<                 pn2 = pn1->pn_head;
<                 if (pn2->pn_type == TOK_NAME && pn2->pn_expr)
<                     pn1->pn_extra |= PNX_POPVAR;
<             } else {
<                 pn2 = pn1;
< #if JS_HAS_LVALUE_RETURN
<                 if (pn2->pn_type == TOK_LP &&
<                     !MakeSetCall(cx, pn2, tc, JSMSG_BAD_LEFTSIDE_OF_ASS)) {
<                     return NULL;
<                 }
< #endif
< #if JS_HAS_XML_SUPPORT
<                 if (pn2->pn_type == TOK_UNARYOP)
<                     pn2->pn_op = JSOP_BINDXMLNAME;
< #endif
<             }
< 
<             switch (pn2->pn_type) {
<               case TOK_NAME:
<                 /* Beware 'for (arguments in ...)' with or without a 'var'. */
<                 if (pn2->pn_atom == cx->runtime->atomState.argumentsAtom)
<                     tc->flags |= TCF_FUN_HEAVYWEIGHT;
<                 break;
< 
< #if JS_HAS_DESTRUCTURING
<               case TOK_ASSIGN:
<                 pn2 = pn2->pn_left;
<                 JS_ASSERT(pn2->pn_type == TOK_RB || pn2->pn_type == TOK_RC);
<                 /* FALL THROUGH */
<               case TOK_RB:
<               case TOK_RC:
<                 /* Check for valid lvalues in var-less destructuring for-in. */
<                 if (pn1 == pn2 && !CheckDestructuring(cx, NULL, pn2, NULL, tc))
<                     return NULL;
< 
<                 if (JSVERSION_NUMBER(cx) == JSVERSION_1_7) {
<                     /*
<                      * Destructuring for-in requires [key, value] enumeration
<                      * in JS1.7.
<                      */
<                     if (pn->pn_op != JSOP_FOREACH)
<                         pn->pn_op = JSOP_FOREACHKEYVAL;
<                 }
<                 break;
< #endif
< 
<               default:;
<             }
< 
<             /* Parse the object expression as the right operand of 'in'. */
<             pn2 = NewBinary(cx, TOK_IN, JSOP_NOP, pn1, Expr(cx, ts, tc), tc);
<             if (!pn2)
---
>             if (pn2->pn_pos.end.lineno == ts->lineno &&
>                 !WellTerminated(cx, ts, TOK_ERROR)) {
2809,2838d1809
<             pn->pn_left = pn2;
<         } else {
<             if (pn->pn_op == JSOP_FOREACH)
<                 goto bad_for_each;
<             pn->pn_op = JSOP_NOP;
< 
<             /* Parse the loop condition or null into pn2. */
<             MUST_MATCH_TOKEN(TOK_SEMI, JSMSG_SEMI_AFTER_FOR_INIT);
<             ts->flags |= TSF_OPERAND;
<             tt = js_PeekToken(cx, ts);
<             ts->flags &= ~TSF_OPERAND;
<             if (tt == TOK_SEMI) {
<                 pn2 = NULL;
<             } else {
<                 pn2 = Expr(cx, ts, tc);
<                 if (!pn2)
<                     return NULL;
<             }
< 
<             /* Parse the update expression or null into pn3. */
<             MUST_MATCH_TOKEN(TOK_SEMI, JSMSG_SEMI_AFTER_FOR_COND);
<             ts->flags |= TSF_OPERAND;
<             tt = js_PeekToken(cx, ts);
<             ts->flags &= ~TSF_OPERAND;
<             if (tt == TOK_RP) {
<                 pn3 = NULL;
<             } else {
<                 pn3 = Expr(cx, ts, tc);
<                 if (!pn3)
<                     return NULL;
2840,4014c1811,1827
< 
<             /* Build the RESERVED node to use as the left kid of pn. */
<             pn4 = NewParseNode(cx, ts, PN_TERNARY, tc);
<             if (!pn4)
<                 return NULL;
<             pn4->pn_type = TOK_RESERVED;
<             pn4->pn_op = JSOP_NOP;
<             pn4->pn_kid1 = pn1;
<             pn4->pn_kid2 = pn2;
<             pn4->pn_kid3 = pn3;
<             pn->pn_left = pn4;
<         }
< 
<         MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_FOR_CTRL);
< 
<         /* Parse the loop body into pn->pn_right. */
<         pn2 = Statement(cx, ts, tc);
<         if (!pn2)
<             return NULL;
<         pn->pn_right = pn2;
< 
<         /* Record the absolute line number for source note emission. */
<         pn->pn_pos.end = pn2->pn_pos.end;
< 
< #if JS_HAS_BLOCK_SCOPE
<         if (pnlet) {
<             js_PopStatement(tc);
<             pnlet->pn_expr = pn;
<             pn = pnlet;
<         }
< #endif
<         js_PopStatement(tc);
<         return pn;
< 
<       bad_for_each:
<         js_ReportCompileErrorNumber(cx, ts, pn, JSREPORT_ERROR,
<                                     JSMSG_BAD_FOR_EACH_LOOP);
<         return NULL;
<       }
< 
<       case TOK_TRY: {
<         JSParseNode *catchList, *lastCatch;
< 
<         /*
<          * try nodes are ternary.
<          * kid1 is the try Statement
<          * kid2 is the catch node list or null
<          * kid3 is the finally Statement
<          *
<          * catch nodes are ternary.
<          * kid1 is the lvalue (TOK_NAME, TOK_LB, or TOK_LC)
<          * kid2 is the catch guard or null if no guard
<          * kid3 is the catch block
<          *
<          * catch lvalue nodes are either:
<          *   TOK_NAME for a single identifier
<          *   TOK_RB or TOK_RC for a destructuring left-hand side
<          *
<          * finally nodes are TOK_LC Statement lists.
<          */
<         pn = NewParseNode(cx, ts, PN_TERNARY, tc);
<         if (!pn)
<             return NULL;
<         pn->pn_op = JSOP_NOP;
< 
<         MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_TRY);
<         js_PushStatement(tc, &stmtInfo, STMT_TRY, -1);
<         pn->pn_kid1 = Statements(cx, ts, tc);
<         if (!pn->pn_kid1)
<             return NULL;
<         MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_TRY);
<         js_PopStatement(tc);
< 
<         catchList = NULL;
<         tt = js_GetToken(cx, ts);
<         if (tt == TOK_CATCH) {
<             catchList = NewParseNode(cx, ts, PN_LIST, tc);
<             if (!catchList)
<                 return NULL;
<             catchList->pn_type = TOK_RESERVED;
<             PN_INIT_LIST(catchList);
<             lastCatch = NULL;
< 
<             do {
<                 JSParseNode *pnblock;
<                 BindData data;
< 
<                 /* Check for another catch after unconditional catch. */
<                 if (lastCatch && !lastCatch->pn_kid2) {
<                     js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                                 JSMSG_CATCH_AFTER_GENERAL);
<                     return NULL;
<                 }
< 
<                 /*
<                  * Create a lexical scope node around the whole catch clause,
<                  * including the head.
<                  */
<                 pnblock = PushLexicalScope(cx, ts, tc, &stmtInfo);
<                 if (!pnblock)
<                     return NULL;
<                 stmtInfo.type = STMT_CATCH;
< 
<                 /*
<                  * Legal catch forms are:
<                  *   catch (lhs)
<                  *   catch (lhs if <boolean_expression>)
<                  * where lhs is a name or a destructuring left-hand side.
<                  * (the latter is legal only #ifdef JS_HAS_CATCH_GUARD)
<                  */
<                 pn2 = NewParseNode(cx, ts, PN_TERNARY, tc);
<                 if (!pn2)
<                     return NULL;
<                 pnblock->pn_expr = pn2;
<                 MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_CATCH);
< 
<                 /*
<                  * Contrary to ECMA Ed. 3, the catch variable is lexically
<                  * scoped, not a property of a new Object instance.  This is
<                  * an intentional change that anticipates ECMA Ed. 4.
<                  */
<                 data.pn = NULL;
<                 data.op = JSOP_NOP;
<                 data.binder = BindLet;
<                 data.u.let.index = 0;
<                 data.u.let.overflow = JSMSG_TOO_MANY_CATCH_VARS;
< 
<                 tt = js_GetToken(cx, ts);
<                 switch (tt) {
< #if JS_HAS_DESTRUCTURING
<                   case TOK_LB:
<                   case TOK_LC:
<                     pn3 = DestructuringExpr(cx, &data, tc, tt);
<                     if (!pn3)
<                         return NULL;
<                     break;
< #endif
< 
<                   case TOK_NAME:
<                     label = CURRENT_TOKEN(ts).t_atom;
<                     if (!data.binder(cx, &data, label, tc))
<                         return NULL;
< 
<                     pn3 = NewParseNode(cx, ts, PN_NAME, tc);
<                     if (!pn3)
<                         return NULL;
<                     pn3->pn_atom = label;
<                     break;
< 
<                   default:
<                     js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                                 JSMSG_CATCH_IDENTIFIER);
<                     return NULL;
<                 }
< 
<                 pn2->pn_kid1 = pn3;
< #if JS_HAS_CATCH_GUARD
<                 /*
<                  * We use 'catch (x if x === 5)' (not 'catch (x : x === 5)')
<                  * to avoid conflicting with the JS2/ECMAv4 type annotation
<                  * catchguard syntax.
<                  */
<                 if (js_MatchToken(cx, ts, TOK_IF)) {
<                     pn2->pn_kid2 = Expr(cx, ts, tc);
<                     if (!pn2->pn_kid2)
<                         return NULL;
<                 }
< #endif
<                 MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_CATCH);
< 
<                 MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_CATCH);
<                 pn2->pn_kid3 = Statements(cx, ts, tc);
<                 if (!pn2->pn_kid3)
<                     return NULL;
<                 MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_CATCH);
<                 js_PopStatement(tc);
< 
<                 PN_APPEND(catchList, pnblock);
<                 lastCatch = pn2;
<                 ts->flags |= TSF_OPERAND;
<                 tt = js_GetToken(cx, ts);
<                 ts->flags &= ~TSF_OPERAND;
<             } while (tt == TOK_CATCH);
<         }
<         pn->pn_kid2 = catchList;
< 
<         if (tt == TOK_FINALLY) {
<             MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_FINALLY);
<             js_PushStatement(tc, &stmtInfo, STMT_FINALLY, -1);
<             pn->pn_kid3 = Statements(cx, ts, tc);
<             if (!pn->pn_kid3)
<                 return NULL;
<             MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_FINALLY);
<             js_PopStatement(tc);
<         } else {
<             js_UngetToken(ts);
<         }
<         if (!catchList && !pn->pn_kid3) {
<             js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                         JSMSG_CATCH_OR_FINALLY);
<             return NULL;
<         }
<         return pn;
<       }
< 
<       case TOK_THROW:
<         pn = NewParseNode(cx, ts, PN_UNARY, tc);
<         if (!pn)
<             return NULL;
< 
<         /* ECMA-262 Edition 3 says 'throw [no LineTerminator here] Expr'. */
<         ts->flags |= TSF_OPERAND;
<         tt = js_PeekTokenSameLine(cx, ts);
<         ts->flags &= ~TSF_OPERAND;
<         if (tt == TOK_ERROR)
<             return NULL;
<         if (tt == TOK_EOF || tt == TOK_EOL || tt == TOK_SEMI || tt == TOK_RC) {
<             js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                         JSMSG_SYNTAX_ERROR);
<             return NULL;
<         }
< 
<         pn2 = Expr(cx, ts, tc);
<         if (!pn2)
<             return NULL;
<         pn->pn_pos.end = pn2->pn_pos.end;
<         pn->pn_op = JSOP_THROW;
<         pn->pn_kid = pn2;
<         break;
< 
<       /* TOK_CATCH and TOK_FINALLY are both handled in the TOK_TRY case */
<       case TOK_CATCH:
<         js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                     JSMSG_CATCH_WITHOUT_TRY);
<         return NULL;
< 
<       case TOK_FINALLY:
<         js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                     JSMSG_FINALLY_WITHOUT_TRY);
<         return NULL;
< 
<       case TOK_BREAK:
<         pn = NewParseNode(cx, ts, PN_NULLARY, tc);
<         if (!pn)
<             return NULL;
<         if (!MatchLabel(cx, ts, pn))
<             return NULL;
<         stmt = tc->topStmt;
<         label = pn->pn_atom;
<         if (label) {
<             for (; ; stmt = stmt->down) {
<                 if (!stmt) {
<                     js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                                 JSMSG_LABEL_NOT_FOUND);
<                     return NULL;
<                 }
<                 if (stmt->type == STMT_LABEL && stmt->u.label == label)
<                     break;
<             }
<         } else {
<             for (; ; stmt = stmt->down) {
<                 if (!stmt) {
<                     js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                                 JSMSG_TOUGH_BREAK);
<                     return NULL;
<                 }
<                 if (STMT_IS_LOOP(stmt) || stmt->type == STMT_SWITCH)
<                     break;
<             }
<         }
<         if (label)
<             pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
<         break;
< 
<       case TOK_CONTINUE:
<         pn = NewParseNode(cx, ts, PN_NULLARY, tc);
<         if (!pn)
<             return NULL;
<         if (!MatchLabel(cx, ts, pn))
<             return NULL;
<         stmt = tc->topStmt;
<         label = pn->pn_atom;
<         if (label) {
<             for (stmt2 = NULL; ; stmt = stmt->down) {
<                 if (!stmt) {
<                     js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                                 JSMSG_LABEL_NOT_FOUND);
<                     return NULL;
<                 }
<                 if (stmt->type == STMT_LABEL) {
<                     if (stmt->u.label == label) {
<                         if (!stmt2 || !STMT_IS_LOOP(stmt2)) {
<                             js_ReportCompileErrorNumber(cx, ts, NULL,
<                                                         JSREPORT_ERROR,
<                                                         JSMSG_BAD_CONTINUE);
<                             return NULL;
<                         }
<                         break;
<                     }
<                 } else {
<                     stmt2 = stmt;
<                 }
<             }
<         } else {
<             for (; ; stmt = stmt->down) {
<                 if (!stmt) {
<                     js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                                 JSMSG_BAD_CONTINUE);
<                     return NULL;
<                 }
<                 if (STMT_IS_LOOP(stmt))
<                     break;
<             }
<         }
<         if (label)
<             pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
<         break;
< 
<       case TOK_WITH:
<         pn = NewParseNode(cx, ts, PN_BINARY, tc);
<         if (!pn)
<             return NULL;
<         MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_WITH);
<         pn2 = ParenExpr(cx, ts, tc, NULL, NULL);
<         if (!pn2)
<             return NULL;
<         MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_WITH);
<         pn->pn_left = pn2;
< 
<         js_PushStatement(tc, &stmtInfo, STMT_WITH, -1);
<         pn2 = Statement(cx, ts, tc);
<         if (!pn2)
<             return NULL;
<         js_PopStatement(tc);
< 
<         pn->pn_pos.end = pn2->pn_pos.end;
<         pn->pn_right = pn2;
<         tc->flags |= TCF_FUN_HEAVYWEIGHT;
<         return pn;
< 
<       case TOK_VAR:
<         pn = Variables(cx, ts, tc);
<         if (!pn)
<             return NULL;
< 
<         /* Tell js_EmitTree to generate a final POP. */
<         pn->pn_extra |= PNX_POPVAR;
<         break;
< 
< #if JS_HAS_BLOCK_SCOPE
<       case TOK_LET:
<       {
<         JSObject *obj;
<         JSParsedObjectBox *blockpob;
< 
<         /* Check for a let statement or let expression. */
<         if (js_PeekToken(cx, ts) == TOK_LP) {
<             pn = LetBlock(cx, ts, tc, JS_TRUE);
<             if (!pn || pn->pn_op == JSOP_LEAVEBLOCK)
<                 return pn;
< 
<             /* Let expressions require automatic semicolon insertion. */
<             JS_ASSERT(pn->pn_type == TOK_SEMI ||
<                       pn->pn_op == JSOP_LEAVEBLOCKEXPR);
<             break;
<         }
< 
<         /*
<          * This is a let declaration. We must be directly under a block per
<          * the proposed ES4 specs, but not an implicit block created due to
<          * 'for (let ...)'. If we pass this error test, make the enclosing
<          * JSStmtInfo be our scope. Further let declarations in this block
<          * will find this scope statement and use the same block object.
<          *
<          * If we are the first let declaration in this block (i.e., when the
<          * enclosing maybe-scope JSStmtInfo isn't yet a scope statement) then
<          * we also need to set tc->blockNode to be our TOK_LEXICALSCOPE.
<          */
<         stmt = tc->topStmt;
<         if (stmt &&
<             (!STMT_MAYBE_SCOPE(stmt) || (stmt->flags & SIF_FOR_BLOCK))) {
<             js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                         JSMSG_LET_DECL_NOT_IN_BLOCK);
<             return NULL;
<         }
< 
<         if (stmt && (stmt->flags & SIF_SCOPE)) {
<             JS_ASSERT(tc->blockChain == stmt->u.blockObj);
<             obj = tc->blockChain;
<         } else {
<             if (!stmt) {
<                 /*
<                  * FIXME: https://bugzilla.mozilla.org/show_bug.cgi?id=346749
<                  *
<                  * This is a hard case that requires more work. In particular,
<                  * in many cases, we're trying to emit code as we go. However,
<                  * this means that we haven't necessarily finished processing
<                  * all let declarations in the implicit top-level block when
<                  * we emit a reference to one of them.  For now, punt on this
<                  * and pretend this is a var declaration.
<                  */
<                 CURRENT_TOKEN(ts).type = TOK_VAR;
<                 CURRENT_TOKEN(ts).t_op = JSOP_DEFVAR;
< 
<                 pn = Variables(cx, ts, tc);
<                 if (!pn)
<                     return NULL;
<                 pn->pn_extra |= PNX_POPVAR;
<                 break;
<             }
< 
<             /* Convert the block statement into a scope statement. */
<             obj = js_NewBlockObject(cx);
<             if (!obj)
<                 return NULL;
<             blockpob = js_NewParsedObjectBox(cx, tc->parseContext, obj);
<             if (!blockpob)
<                 return NULL;
< 
<             /*
<              * Insert stmt on the tc->topScopeStmt/stmtInfo.downScope linked
<              * list stack, if it isn't already there.  If it is there, but it
<              * lacks the SIF_SCOPE flag, it must be a try, catch, or finally
<              * block.
<              */
<             JS_ASSERT(!(stmt->flags & SIF_SCOPE));
<             stmt->flags |= SIF_SCOPE;
<             if (stmt != tc->topScopeStmt) {
<                 JS_ASSERT(!stmt->downScope);
<                 JS_ASSERT(stmt->type == STMT_BLOCK ||
<                           stmt->type == STMT_SWITCH ||
<                           stmt->type == STMT_TRY ||
<                           stmt->type == STMT_FINALLY);
<                 stmt->downScope = tc->topScopeStmt;
<                 tc->topScopeStmt = stmt;
<                 if (++tc->scopeDepth > tc->maxScopeDepth)
<                     tc->maxScopeDepth = tc->scopeDepth;
<             } else {
<                 JS_ASSERT(stmt->type == STMT_CATCH);
<                 JS_ASSERT(stmt->downScope);
<             }
< 
<             STOBJ_SET_PARENT(obj, tc->blockChain);
<             tc->blockChain = obj;
<             stmt->u.blockObj = obj;
< 
< #ifdef DEBUG
<             pn1 = tc->blockNode;
<             JS_ASSERT(!pn1 || pn1->pn_type != TOK_LEXICALSCOPE);
< #endif
< 
<             /* Create a new lexical scope node for these statements. */
<             pn1 = NewParseNode(cx, ts, PN_NAME, tc);
<             if (!pn1)
<                 return NULL;
< 
<             pn1->pn_type = TOK_LEXICALSCOPE;
<             pn1->pn_op = JSOP_LEAVEBLOCK;
<             pn1->pn_pos = tc->blockNode->pn_pos;
<             pn1->pn_pob = blockpob;
<             pn1->pn_expr = tc->blockNode;
<             pn1->pn_slot = -1;
<             tc->blockNode = pn1;
<         }
< 
<         pn = Variables(cx, ts, tc);
<         if (!pn)
<             return NULL;
<         pn->pn_extra = PNX_POPVAR;
<         break;
<       }
< #endif /* JS_HAS_BLOCK_SCOPE */
< 
<       case TOK_RETURN:
<         pn = ReturnOrYield(cx, ts, tc, Expr);
<         if (!pn)
<             return NULL;
<         break;
< 
<       case TOK_LC:
<       {
<         uintN oldflags;
< 
<         oldflags = tc->flags;
<         tc->flags = oldflags & ~TCF_HAS_FUNCTION_STMT;
<         js_PushStatement(tc, &stmtInfo, STMT_BLOCK, -1);
<         pn = Statements(cx, ts, tc);
<         if (!pn)
<             return NULL;
< 
<         MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_IN_COMPOUND);
<         js_PopStatement(tc);
< 
<         /*
<          * If we contain a function statement and our container is top-level
<          * or another block, flag pn to preserve braces when decompiling.
<          */
<         if ((tc->flags & TCF_HAS_FUNCTION_STMT) &&
<             (!tc->topStmt || tc->topStmt->type == STMT_BLOCK)) {
<             pn->pn_extra |= PNX_NEEDBRACES;
<         }
<         tc->flags = oldflags | (tc->flags & (TCF_FUN_FLAGS | TCF_RETURN_FLAGS));
<         return pn;
<       }
< 
<       case TOK_EOL:
<       case TOK_SEMI:
<         pn = NewParseNode(cx, ts, PN_UNARY, tc);
<         if (!pn)
<             return NULL;
<         pn->pn_type = TOK_SEMI;
<         return pn;
< 
< #if JS_HAS_DEBUGGER_KEYWORD
<       case TOK_DEBUGGER:
<         pn = NewParseNode(cx, ts, PN_NULLARY, tc);
<         if (!pn)
<             return NULL;
<         pn->pn_type = TOK_DEBUGGER;
<         tc->flags |= TCF_FUN_HEAVYWEIGHT;
<         break;
< #endif /* JS_HAS_DEBUGGER_KEYWORD */
< 
< #if JS_HAS_XML_SUPPORT
<       case TOK_DEFAULT:
<         pn = NewParseNode(cx, ts, PN_UNARY, tc);
<         if (!pn)
<             return NULL;
<         if (!js_MatchToken(cx, ts, TOK_NAME) ||
<             CURRENT_TOKEN(ts).t_atom != cx->runtime->atomState.xmlAtom ||
<             !js_MatchToken(cx, ts, TOK_NAME) ||
<             CURRENT_TOKEN(ts).t_atom != cx->runtime->atomState.namespaceAtom ||
<             !js_MatchToken(cx, ts, TOK_ASSIGN) ||
<             CURRENT_TOKEN(ts).t_op != JSOP_NOP) {
<             js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                         JSMSG_BAD_DEFAULT_XML_NAMESPACE);
<             return NULL;
<         }
<         pn2 = Expr(cx, ts, tc);
<         if (!pn2)
<             return NULL;
<         pn->pn_op = JSOP_DEFXMLNS;
<         pn->pn_pos.end = pn2->pn_pos.end;
<         pn->pn_kid = pn2;
<         tc->flags |= TCF_HAS_DEFXMLNS;
<         break;
< #endif
< 
<       case TOK_ERROR:
<         return NULL;
< 
<       default:
< #if JS_HAS_XML_SUPPORT
<       expression:
< #endif
<         js_UngetToken(ts);
<         pn2 = Expr(cx, ts, tc);
<         if (!pn2)
<             return NULL;
< 
<         if (js_PeekToken(cx, ts) == TOK_COLON) {
<             if (pn2->pn_type != TOK_NAME) {
<                 js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                             JSMSG_BAD_LABEL);
<                 return NULL;
<             }
<             label = pn2->pn_atom;
<             for (stmt = tc->topStmt; stmt; stmt = stmt->down) {
<                 if (stmt->type == STMT_LABEL && stmt->u.label == label) {
<                     js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                                 JSMSG_DUPLICATE_LABEL);
<                     return NULL;
<                 }
<             }
<             (void) js_GetToken(cx, ts);
< 
<             /* Push a label struct and parse the statement. */
<             js_PushStatement(tc, &stmtInfo, STMT_LABEL, -1);
<             stmtInfo.u.label = label;
<             pn = Statement(cx, ts, tc);
<             if (!pn)
<                 return NULL;
< 
<             /* Normalize empty statement to empty block for the decompiler. */
<             if (pn->pn_type == TOK_SEMI && !pn->pn_kid) {
<                 pn->pn_type = TOK_LC;
<                 pn->pn_arity = PN_LIST;
<                 PN_INIT_LIST(pn);
<             }
< 
<             /* Pop the label, set pn_expr, and return early. */
<             js_PopStatement(tc);
<             pn2->pn_type = TOK_COLON;
<             pn2->pn_pos.end = pn->pn_pos.end;
<             pn2->pn_expr = pn;
<             return pn2;
<         }
< 
<         pn = NewParseNode(cx, ts, PN_UNARY, tc);
<         if (!pn)
<             return NULL;
<         pn->pn_type = TOK_SEMI;
<         pn->pn_pos = pn2->pn_pos;
<         pn->pn_kid = pn2;
<         break;
<     }
< 
<     /* Check termination of this primitive statement. */
<     if (ON_CURRENT_LINE(ts, pn->pn_pos)) {
<         ts->flags |= TSF_OPERAND;
<         tt = js_PeekTokenSameLine(cx, ts);
<         ts->flags &= ~TSF_OPERAND;
<         if (tt == TOK_ERROR)
<             return NULL;
<         if (tt != TOK_EOF && tt != TOK_EOL && tt != TOK_SEMI && tt != TOK_RC) {
<             js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                         JSMSG_SEMI_BEFORE_STMNT);
<             return NULL;
<         }
<     }
< 
<     (void) js_MatchToken(cx, ts, TOK_SEMI);
<     return pn;
< }
< 
< static JSParseNode *
< Variables(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
< {
<     JSTokenType tt;
<     JSBool let;
<     JSStmtInfo *scopeStmt;
<     BindData data;
<     JSParseNode *pn, *pn2;
<     JSStackFrame *fp;
<     JSAtom *atom;
< 
<     /*
<      * The three options here are:
<      * - TOK_LET: We are parsing a let declaration.
<      * - TOK_LP: We are parsing the head of a let block.
<      * - Otherwise, we're parsing var declarations.
<      */
<     tt = CURRENT_TOKEN(ts).type;
<     let = (tt == TOK_LET || tt == TOK_LP);
<     JS_ASSERT(let || tt == TOK_VAR);
< 
<     /* Make sure that Statement set the tree context up correctly. */
<     scopeStmt = tc->topScopeStmt;
<     if (let) {
<         while (scopeStmt && !(scopeStmt->flags & SIF_SCOPE)) {
<             JS_ASSERT(!STMT_MAYBE_SCOPE(scopeStmt));
<             scopeStmt = scopeStmt->downScope;
<         }
<         JS_ASSERT(scopeStmt);
<     }
< 
<     data.pn = NULL;
<     data.op = let ? JSOP_NOP : CURRENT_TOKEN(ts).t_op;
<     pn = NewParseNode(cx, ts, PN_LIST, tc);
<     if (!pn)
<         return NULL;
<     pn->pn_op = data.op;
<     PN_INIT_LIST(pn);
< 
<     /*
<      * The tricky part of this code is to create special parsenode opcodes for
<      * getting and setting variables (which will be stored as special slots in
<      * the frame).  The most complicated case is an eval() inside a function.
<      * If the evaluated string references variables in the enclosing function,
<      * then we need to generate the special variable opcodes.  We determine
<      * this by looking up the variable's id in the current variable object.
<      * Fortunately, we can avoid doing this for let declared variables.
<      */
<     fp = cx->fp;
<     if (let) {
<         JS_ASSERT(tc->blockChain == scopeStmt->u.blockObj);
<         data.binder = BindLet;
<         data.u.let.index = OBJ_BLOCK_COUNT(cx, tc->blockChain);
<         data.u.let.overflow = JSMSG_TOO_MANY_FUN_VARS;
<     } else {
<         data.binder = BindVarOrConst;
<     }
< 
<     do {
<         tt = js_GetToken(cx, ts);
< #if JS_HAS_DESTRUCTURING
<         if (tt == TOK_LB || tt == TOK_LC) {
<             pn2 = PrimaryExpr(cx, ts, tc, tt, JS_FALSE);
<             if (!pn2)
<                 return NULL;
< 
<             if ((tc->flags & TCF_IN_FOR_INIT) &&
<                 js_PeekToken(cx, ts) == TOK_IN) {
<                 if (!CheckDestructuring(cx, &data, pn2, NULL, tc))
<                     return NULL;
<                 PN_APPEND(pn, pn2);
<                 continue;
<             }
< 
<             MUST_MATCH_TOKEN(TOK_ASSIGN, JSMSG_BAD_DESTRUCT_DECL);
<             if (CURRENT_TOKEN(ts).t_op != JSOP_NOP)
<                 goto bad_var_init;
< 
<             pn2 = NewBinary(cx, TOK_ASSIGN, JSOP_NOP,
<                             pn2, AssignExpr(cx, ts, tc),
<                             tc);
<             if (!pn2 ||
<                 !CheckDestructuring(cx, &data,
<                                     pn2->pn_left, pn2->pn_right,
<                                     tc)) {
<                 return NULL;
<             }
<             PN_APPEND(pn, pn2);
<             continue;
<         }
< #endif
< 
<         if (tt != TOK_NAME) {
<             js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                         JSMSG_NO_VARIABLE_NAME);
<             return NULL;
<         }
<         atom = CURRENT_TOKEN(ts).t_atom;
<         if (!data.binder(cx, &data, atom, tc))
<             return NULL;
< 
<         pn2 = NewParseNode(cx, ts, PN_NAME, tc);
<         if (!pn2)
<             return NULL;
<         pn2->pn_op = JSOP_NAME;
<         pn2->pn_atom = atom;
<         pn2->pn_slot = -1;
<         if (!let)
<             pn2->pn_const = (data.op == JSOP_DEFCONST);
<         PN_APPEND(pn, pn2);
< 
<         if (js_MatchToken(cx, ts, TOK_ASSIGN)) {
<             if (CURRENT_TOKEN(ts).t_op != JSOP_NOP)
<                 goto bad_var_init;
< 
<             pn2->pn_expr = AssignExpr(cx, ts, tc);
<             if (!pn2->pn_expr)
<                 return NULL;
<             pn2->pn_op = (!let && data.op == JSOP_DEFCONST)
<                          ? JSOP_SETCONST
<                          : JSOP_SETNAME;
<             if (!let && atom == cx->runtime->atomState.argumentsAtom)
<                 tc->flags |= TCF_FUN_HEAVYWEIGHT;
<         }
<     } while (js_MatchToken(cx, ts, TOK_COMMA));
< 
<     pn->pn_pos.end = PN_LAST(pn)->pn_pos.end;
<     return pn;
< 
< bad_var_init:
<     js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                 JSMSG_BAD_VAR_INIT);
<     return NULL;
< }
< 
< static JSParseNode *
< Expr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
< {
<     JSParseNode *pn, *pn2;
< 
<     pn = AssignExpr(cx, ts, tc);
<     if (pn && js_MatchToken(cx, ts, TOK_COMMA)) {
<         pn2 = NewParseNode(cx, ts, PN_LIST, tc);
<         if (!pn2)
<             return NULL;
<         pn2->pn_pos.begin = pn->pn_pos.begin;
<         PN_INIT_LIST_1(pn2, pn);
<         pn = pn2;
<         do {
< #if JS_HAS_GENERATORS
<             pn2 = PN_LAST(pn);
<             if (pn2->pn_type == TOK_YIELD) {
<                 js_ReportCompileErrorNumber(cx, ts, pn2, JSREPORT_ERROR,
<                                             JSMSG_BAD_GENERATOR_SYNTAX,
<                                             js_yield_str);
<                 return NULL;
<             }
< #endif
<             pn2 = AssignExpr(cx, ts, tc);
<             if (!pn2)
<                 return NULL;
<             PN_APPEND(pn, pn2);
<         } while (js_MatchToken(cx, ts, TOK_COMMA));
<         pn->pn_pos.end = PN_LAST(pn)->pn_pos.end;
<     }
<     return pn;
< }
< 
< static JSParseNode *
< AssignExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
< {
<     JSParseNode *pn, *pn2;
<     JSTokenType tt;
<     JSOp op;
< 
<     JS_CHECK_RECURSION(cx, return NULL);
< 
< #if JS_HAS_GENERATORS
<     ts->flags |= TSF_OPERAND;
<     if (js_MatchToken(cx, ts, TOK_YIELD)) {
<         ts->flags &= ~TSF_OPERAND;
<         return ReturnOrYield(cx, ts, tc, AssignExpr);
<     }
<     ts->flags &= ~TSF_OPERAND;
< #endif
< 
<     pn = CondExpr(cx, ts, tc);
<     if (!pn)
<         return NULL;
< 
<     tt = js_GetToken(cx, ts);
< #if JS_HAS_GETTER_SETTER
<     if (tt == TOK_NAME) {
<         tt = CheckGetterOrSetter(cx, ts, TOK_ASSIGN);
<         if (tt == TOK_ERROR)
<             return NULL;
<     }
< #endif
<     if (tt != TOK_ASSIGN) {
<         js_UngetToken(ts);
<         return pn;
<     }
< 
<     op = CURRENT_TOKEN(ts).t_op;
<     for (pn2 = pn; pn2->pn_type == TOK_RP; pn2 = pn2->pn_kid)
<         continue;
<     switch (pn2->pn_type) {
<       case TOK_NAME:
<         pn2->pn_op = JSOP_SETNAME;
<         if (pn2->pn_atom == cx->runtime->atomState.argumentsAtom)
<             tc->flags |= TCF_FUN_HEAVYWEIGHT;
<         break;
<       case TOK_DOT:
<         pn2->pn_op = JSOP_SETPROP;
<         break;
<       case TOK_LB:
<         pn2->pn_op = JSOP_SETELEM;
<         break;
< #if JS_HAS_DESTRUCTURING
<       case TOK_RB:
<       case TOK_RC:
<         if (op != JSOP_NOP) {
<             js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                         JSMSG_BAD_DESTRUCT_ASS);
<             return NULL;
<         }
<         pn = AssignExpr(cx, ts, tc);
<         if (!pn || !CheckDestructuring(cx, NULL, pn2, pn, tc))
<             return NULL;
<         return NewBinary(cx, TOK_ASSIGN, op, pn2, pn, tc);
< #endif
< #if JS_HAS_LVALUE_RETURN
<       case TOK_LP:
<         if (!MakeSetCall(cx, pn2, tc, JSMSG_BAD_LEFTSIDE_OF_ASS))
<             return NULL;
<         break;
< #endif
< #if JS_HAS_XML_SUPPORT
<       case TOK_UNARYOP:
<         if (pn2->pn_op == JSOP_XMLNAME) {
<             pn2->pn_op = JSOP_SETXMLNAME;
<             break;
<         }
<         /* FALL THROUGH */
< #endif
<       default:
<         js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                     JSMSG_BAD_LEFTSIDE_OF_ASS);
<         return NULL;
<     }
< 
<     return NewBinary(cx, TOK_ASSIGN, op, pn2, AssignExpr(cx, ts, tc), tc);
< }
< 
< static JSParseNode *
< CondExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
< {
<     JSParseNode *pn, *pn1, *pn2, *pn3;
<     uintN oldflags;
< 
<     pn = OrExpr(cx, ts, tc);
<     if (pn && js_MatchToken(cx, ts, TOK_HOOK)) {
<         pn1 = pn;
<         pn = NewParseNode(cx, ts, PN_TERNARY, tc);
<         if (!pn)
<             return NULL;
<         /*
<          * Always accept the 'in' operator in the middle clause of a ternary,
<          * where it's unambiguous, even if we might be parsing the init of a
<          * for statement.
<          */
<         oldflags = tc->flags;
<         tc->flags &= ~TCF_IN_FOR_INIT;
<         pn2 = AssignExpr(cx, ts, tc);
<         tc->flags = oldflags | (tc->flags & TCF_FUN_FLAGS);
< 
<         if (!pn2)
<             return NULL;
<         MUST_MATCH_TOKEN(TOK_COLON, JSMSG_COLON_IN_COND);
<         pn3 = AssignExpr(cx, ts, tc);
<         if (!pn3)
<             return NULL;
<         pn->pn_pos.begin = pn1->pn_pos.begin;
<         pn->pn_pos.end = pn3->pn_pos.end;
<         pn->pn_kid1 = pn1;
<         pn->pn_kid2 = pn2;
<         pn->pn_kid3 = pn3;
<     }
<     return pn;
< }
< 
< static JSParseNode *
< OrExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
< {
<     JSParseNode *pn;
< 
<     pn = AndExpr(cx, ts, tc);
<     while (pn && js_MatchToken(cx, ts, TOK_OR))
<         pn = NewBinary(cx, TOK_OR, JSOP_OR, pn, AndExpr(cx, ts, tc), tc);
<     return pn;
< }
< 
< static JSParseNode *
< AndExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
< {
<     JSParseNode *pn;
< 
<     pn = BitOrExpr(cx, ts, tc);
<     while (pn && js_MatchToken(cx, ts, TOK_AND))
<         pn = NewBinary(cx, TOK_AND, JSOP_AND, pn, BitOrExpr(cx, ts, tc), tc);
<     return pn;
< }
< 
< static JSParseNode *
< BitOrExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
< {
<     JSParseNode *pn;
< 
<     pn = BitXorExpr(cx, ts, tc);
<     while (pn && js_MatchToken(cx, ts, TOK_BITOR)) {
<         pn = NewBinary(cx, TOK_BITOR, JSOP_BITOR, pn, BitXorExpr(cx, ts, tc),
<                        tc);
<     }
<     return pn;
< }
< 
< static JSParseNode *
< BitXorExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
< {
<     JSParseNode *pn;
< 
<     pn = BitAndExpr(cx, ts, tc);
<     while (pn && js_MatchToken(cx, ts, TOK_BITXOR)) {
<         pn = NewBinary(cx, TOK_BITXOR, JSOP_BITXOR, pn, BitAndExpr(cx, ts, tc),
<                        tc);
<     }
<     return pn;
< }
< 
< static JSParseNode *
< BitAndExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
< {
<     JSParseNode *pn;
< 
<     pn = EqExpr(cx, ts, tc);
<     while (pn && js_MatchToken(cx, ts, TOK_BITAND))
<         pn = NewBinary(cx, TOK_BITAND, JSOP_BITAND, pn, EqExpr(cx, ts, tc), tc);
<     return pn;
< }
< 
< static JSParseNode *
< EqExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
< {
<     JSParseNode *pn;
<     JSOp op;
< 
<     pn = RelExpr(cx, ts, tc);
<     while (pn && js_MatchToken(cx, ts, TOK_EQOP)) {
<         op = CURRENT_TOKEN(ts).t_op;
<         pn = NewBinary(cx, TOK_EQOP, op, pn, RelExpr(cx, ts, tc), tc);
<     }
<     return pn;
< }
< 
< static JSParseNode *
< RelExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
< {
<     JSParseNode *pn;
<     JSTokenType tt;
<     JSOp op;
<     uintN inForInitFlag = tc->flags & TCF_IN_FOR_INIT;
< 
<     /*
<      * Uses of the in operator in ShiftExprs are always unambiguous,
<      * so unset the flag that prohibits recognizing it.
<      */
<     tc->flags &= ~TCF_IN_FOR_INIT;
< 
<     pn = ShiftExpr(cx, ts, tc);
<     while (pn &&
<            (js_MatchToken(cx, ts, TOK_RELOP) ||
<             /*
<              * Recognize the 'in' token as an operator only if we're not
<              * currently in the init expr of a for loop.
<              */
<             (inForInitFlag == 0 && js_MatchToken(cx, ts, TOK_IN)) ||
<             js_MatchToken(cx, ts, TOK_INSTANCEOF))) {
<         tt = CURRENT_TOKEN(ts).type;
<         op = CURRENT_TOKEN(ts).t_op;
<         pn = NewBinary(cx, tt, op, pn, ShiftExpr(cx, ts, tc), tc);
<     }
<     /* Restore previous state of inForInit flag. */
<     tc->flags |= inForInitFlag;
< 
<     return pn;
< }
< 
< static JSParseNode *
< ShiftExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
< {
<     JSParseNode *pn;
<     JSOp op;
< 
<     pn = AddExpr(cx, ts, tc);
<     while (pn && js_MatchToken(cx, ts, TOK_SHOP)) {
<         op = CURRENT_TOKEN(ts).t_op;
<         pn = NewBinary(cx, TOK_SHOP, op, pn, AddExpr(cx, ts, tc), tc);
<     }
<     return pn;
< }
< 
< static JSParseNode *
< AddExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
< {
<     JSParseNode *pn;
<     JSTokenType tt;
<     JSOp op;
< 
<     pn = MulExpr(cx, ts, tc);
<     while (pn &&
<            (js_MatchToken(cx, ts, TOK_PLUS) ||
<             js_MatchToken(cx, ts, TOK_MINUS))) {
<         tt = CURRENT_TOKEN(ts).type;
<         op = (tt == TOK_PLUS) ? JSOP_ADD : JSOP_SUB;
<         pn = NewBinary(cx, tt, op, pn, MulExpr(cx, ts, tc), tc);
<     }
<     return pn;
< }
< 
< static JSParseNode *
< MulExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
< {
<     JSParseNode *pn;
<     JSTokenType tt;
<     JSOp op;
< 
<     pn = UnaryExpr(cx, ts, tc);
<     while (pn &&
<            (js_MatchToken(cx, ts, TOK_STAR) ||
<             js_MatchToken(cx, ts, TOK_DIVOP))) {
<         tt = CURRENT_TOKEN(ts).type;
<         op = CURRENT_TOKEN(ts).t_op;
<         pn = NewBinary(cx, tt, op, pn, UnaryExpr(cx, ts, tc), tc);
<     }
<     return pn;
< }
< 
< static JSParseNode *
< SetLvalKid(JSContext *cx, JSTokenStream *ts, JSParseNode *pn, JSParseNode *kid,
<            const char *name)
< {
<     while (kid->pn_type == TOK_RP)
<         kid = kid->pn_kid;
<     if (kid->pn_type != TOK_NAME &&
<         kid->pn_type != TOK_DOT &&
< #if JS_HAS_LVALUE_RETURN
<         (kid->pn_type != TOK_LP ||
<          (kid->pn_op != JSOP_CALL && kid->pn_op != JSOP_EVAL)) &&
< #endif
< #if JS_HAS_XML_SUPPORT
<         (kid->pn_type != TOK_UNARYOP || kid->pn_op != JSOP_XMLNAME) &&
< #endif
<         kid->pn_type != TOK_LB) {
<         js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                     JSMSG_BAD_OPERAND, name);
<         return NULL;
<     }
<     pn->pn_kid = kid;
<     return kid;
< }
< 
< static const char incop_name_str[][10] = {"increment", "decrement"};
< 
< static JSBool
< SetIncOpKid(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
<             JSParseNode *pn, JSParseNode *kid,
<             JSTokenType tt, JSBool preorder)
< {
<     JSOp op;
< 
<     kid = SetLvalKid(cx, ts, pn, kid, incop_name_str[tt == TOK_DEC]);
<     if (!kid)
<         return JS_FALSE;
<     switch (kid->pn_type) {
<       case TOK_NAME:
<         op = (tt == TOK_INC)
<              ? (preorder ? JSOP_INCNAME : JSOP_NAMEINC)
<              : (preorder ? JSOP_DECNAME : JSOP_NAMEDEC);
<         if (kid->pn_atom == cx->runtime->atomState.argumentsAtom)
<             tc->flags |= TCF_FUN_HEAVYWEIGHT;
<         break;
< 
<       case TOK_DOT:
<         op = (tt == TOK_INC)
<              ? (preorder ? JSOP_INCPROP : JSOP_PROPINC)
<              : (preorder ? JSOP_DECPROP : JSOP_PROPDEC);
<         break;
< 
< #if JS_HAS_LVALUE_RETURN
<       case TOK_LP:
<         if (!MakeSetCall(cx, kid, tc, JSMSG_BAD_INCOP_OPERAND))
<             return JS_FALSE;
<         /* FALL THROUGH */
< #endif
< #if JS_HAS_XML_SUPPORT
<       case TOK_UNARYOP:
<         if (kid->pn_op == JSOP_XMLNAME)
<             kid->pn_op = JSOP_SETXMLNAME;
<         /* FALL THROUGH */
< #endif
<       case TOK_LB:
<         op = (tt == TOK_INC)
<              ? (preorder ? JSOP_INCELEM : JSOP_ELEMINC)
<              : (preorder ? JSOP_DECELEM : JSOP_ELEMDEC);
<         break;
< 
<       default:
<         JS_ASSERT(0);
<         op = JSOP_NOP;
<     }
<     pn->pn_op = op;
<     return JS_TRUE;
< }
< 
< static JSParseNode *
< UnaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
< {
<     JSTokenType tt;
<     JSParseNode *pn, *pn2;
< 
<     JS_CHECK_RECURSION(cx, return NULL);
< 
<     ts->flags |= TSF_OPERAND;
<     tt = js_GetToken(cx, ts);
<     ts->flags &= ~TSF_OPERAND;
< 
<     switch (tt) {
<       case TOK_UNARYOP:
<       case TOK_PLUS:
<       case TOK_MINUS:
<         pn = NewParseNode(cx, ts, PN_UNARY, tc);
<         if (!pn)
<             return NULL;
<         pn->pn_type = TOK_UNARYOP;      /* PLUS and MINUS are binary */
<         pn->pn_op = CURRENT_TOKEN(ts).t_op;
<         pn2 = UnaryExpr(cx, ts, tc);
<         if (!pn2)
<             return NULL;
<         pn->pn_pos.end = pn2->pn_pos.end;
<         pn->pn_kid = pn2;
---
>             tc->flags |= TCF_RETURN_EXPR;
>             pn->pn_pos.end = pn2->pn_pos.end;
>             pn->pn_kid = pn2;
>         } else {
>             tc->flags |= TCF_RETURN_VOID;
>             pn->pn_kid = NULL;
>         }
> 
>         if (JS_HAS_STRICT_OPTION(cx) &&
>             (~tc->flags & (TCF_RETURN_EXPR | TCF_RETURN_VOID)) == 0) {
>             /*
>              * We must be in a frame with a non-native function, because
>              * we're compiling one.
>              */
>             if (!ReportNoReturnValue(cx, ts))
>                 return NULL;
>         }
4017,4019c1830,1832
<       case TOK_INC:
<       case TOK_DEC:
<         pn = NewParseNode(cx, ts, PN_UNARY, tc);
---
>       case TOK_LC:
>         js_PushStatement(tc, &stmtInfo, STMT_BLOCK, -1);
>         pn = Statements(cx, ts, tc);
4022,4028d1834
<         pn2 = MemberExpr(cx, ts, tc, JS_TRUE);
<         if (!pn2)
<             return NULL;
<         if (!SetIncOpKid(cx, ts, tc, pn, pn2, tt, JS_TRUE))
<             return NULL;
<         pn->pn_pos.end = pn2->pn_pos.end;
<         break;
4030,4031c1836,1842
<       case TOK_DELETE:
<         pn = NewParseNode(cx, ts, PN_UNARY, tc);
---
>         MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_IN_COMPOUND);
>         js_PopStatement(tc);
>         return pn;
> 
>       case TOK_EOL:
>       case TOK_SEMI:
>         pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc);
4034,4037c1845,1847
<         pn2 = UnaryExpr(cx, ts, tc);
<         if (!pn2)
<             return NULL;
<         pn->pn_pos.end = pn2->pn_pos.end;
---
>         pn->pn_type = TOK_SEMI;
>         pn->pn_kid = NULL;
>         return pn;
4039,4047c1849,1851
<         /*
<          * Under ECMA3, deleting any unary expression is valid -- it simply
<          * returns true. Here we strip off any parentheses and fold constants
<          * before checking for a call expression, in order to rule out delete
<          * of a generator expression.
<          */
<         while (pn2->pn_type == TOK_RP)
<             pn2 = pn2->pn_kid;
<         if (!js_FoldConstants(cx, pn2, tc))
---
> #if JS_HAS_DEBUGGER_KEYWORD
>       case TOK_DEBUGGER:
>         if (!WellTerminated(cx, ts, TOK_ERROR))
4049,4051c1853,1854
<         if (pn2->pn_type == TOK_LP &&
<             pn2->pn_op != JSOP_SETCALL &&
<             !MakeSetCall(cx, pn2, tc, JSMSG_BAD_DELETE_OPERAND)) {
---
>         pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc);
>         if (!pn)
4053,4055c1856,1859
<         }
<         pn->pn_kid = pn2;
<         break;
---
>         pn->pn_type = TOK_DEBUGGER;
>         tc->flags |= TCF_FUN_HEAVYWEIGHT;
>         return pn;
> #endif /* JS_HAS_DEBUGGER_KEYWORD */
4060a1865
>         lastExprType = CURRENT_TOKEN(ts).type;
4062,4063c1867,1868
<         pn = MemberExpr(cx, ts, tc, JS_TRUE);
<         if (!pn)
---
>         pn2 = Expr(cx, ts, tc);
>         if (!pn2)
4066,4076c1871,1881
<         /* Don't look across a newline boundary for a postfix incop. */
<         if (ON_CURRENT_LINE(ts, pn->pn_pos)) {
<             ts->flags |= TSF_OPERAND;
<             tt = js_PeekTokenSameLine(cx, ts);
<             ts->flags &= ~TSF_OPERAND;
<             if (tt == TOK_INC || tt == TOK_DEC) {
<                 (void) js_GetToken(cx, ts);
<                 pn2 = NewParseNode(cx, ts, PN_UNARY, tc);
<                 if (!pn2)
<                     return NULL;
<                 if (!SetIncOpKid(cx, ts, tc, pn2, pn, tt, JS_FALSE))
---
>         if (js_PeekToken(cx, ts) == TOK_COLON) {
>             if (pn2->pn_type != TOK_NAME) {
>                 js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
>                                             JSMSG_BAD_LABEL);
>                 return NULL;
>             }
>             label = pn2->pn_atom;
>             for (stmt = tc->topStmt; stmt; stmt = stmt->down) {
>                 if (stmt->type == STMT_LABEL && stmt->label == label) {
>                     js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
>                                                 JSMSG_DUPLICATE_LABEL);
4078,4079c1883
<                 pn2->pn_pos.begin = pn->pn_pos.begin;
<                 pn = pn2;
---
>                 }
4080a1885,1905
>             (void) js_GetToken(cx, ts);
> 
>             /* Push a label struct and parse the statement. */
>             js_PushStatement(tc, &stmtInfo, STMT_LABEL, -1);
>             stmtInfo.label = label;
>             pn = Statement(cx, ts, tc);
>             if (!pn)
>                 return NULL;
> 
>             /* Pop the label, set pn_expr, and return early. */
>             js_PopStatement(tc);
>             pn2->pn_type = TOK_COLON;
>             pn2->pn_pos.end = pn->pn_pos.end;
>             pn2->pn_expr = pn;
>             return pn2;
>         }
> 
>         /* Check termination of (possibly multi-line) function expression. */
>         if (pn2->pn_pos.end.lineno == ts->lineno &&
>             !WellTerminated(cx, ts, lastExprType)) {
>             return NULL;
4081a1907,1913
> 
>         pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc);
>         if (!pn)
>             return NULL;
>         pn->pn_type = TOK_SEMI;
>         pn->pn_pos = pn2->pn_pos;
>         pn->pn_kid = pn2;
4083a1916,1917
> 
>     (void) js_MatchToken(cx, ts, TOK_SEMI);
4087,4097d1920
< #if JS_HAS_GENERATORS
< 
< /*
<  * Starting from a |for| keyword after the first array initialiser element or
<  * an expression in an open parenthesis, parse the tail of the comprehension
<  * or generator expression signified by this |for| keyword in context.
<  *
<  * Return null on failure, else return the top-most parse node for the array
<  * comprehension or generator expression, with a unary node as the body of the
<  * (possibly nested) for-loop, initialized by |type, op, kid|.
<  */
4099,4100c1922
< ComprehensionTail(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
<                   JSTokenType type, JSOp op, JSParseNode *kid)
---
> Variables(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
4102,4106c1924,1929
<     JSParseNode *pn, *pn2, *pn3, **pnp;
<     JSStmtInfo stmtInfo;
<     BindData data;
<     JSRuntime *rt;
<     JSTokenType tt;
---
>     JSParseNode *pn, *pn2;
>     JSObject *obj, *pobj;
>     JSStackFrame *fp;
>     JSFunction *fun;
>     JSClass *clasp;
>     JSPropertyOp getter, setter, currentGetter, currentSetter;
4108,4110c1931,1935
< 
<     JS_ASSERT(type == TOK_SEMI || type == TOK_ARRAYPUSH);
<     JS_ASSERT(CURRENT_TOKEN(ts).type == TOK_FOR);
---
>     JSAtomListElement *ale;
>     JSOp prevop;
>     JSProperty *prop;
>     JSScopeProperty *sprop;
>     JSBool ok;
4113,4114c1938,1943
<      * Make a parse-node and literal object representing the block scope of
<      * this array comprehension or generator expression.
---
>      * The tricky part of this code is to create special parsenode opcodes for
>      * getting and setting variables (which will be stored as special slots in
>      * the frame).  The complex special case is an eval() inside a function.
>      * If the evaluated string references variables in the enclosing function,
>      * then we need to generate the special variable opcodes.  We determine
>      * this by looking up the variable id in the current variable scope.
4116c1945,1946
<     pn = PushLexicalScope(cx, ts, tc, &stmtInfo);
---
>     JS_ASSERT(CURRENT_TOKEN(ts).type == TOK_VAR);
>     pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc);
4119c1949,1951
<     pnp = &pn->pn_expr;
---
>     pn->pn_op = CURRENT_TOKEN(ts).t_op;
>     pn->pn_extra = JS_FALSE;            /* assume no JSOP_POP needed */
>     PN_INIT_LIST(pn);
4121,4125c1953,1981
<     data.pn = NULL;
<     data.op = JSOP_NOP;
<     data.binder = BindLet;
<     data.u.let.index = 0;
<     data.u.let.overflow = JSMSG_ARRAY_INIT_TOO_BIG;
---
>     /*
>      * Skip eval and debugger frames when looking for the function whose code
>      * is being compiled.  If we are called from FunctionBody, TCF_IN_FUNCTION
>      * will be set in tc->flags, and we can be sure fp->fun is the function to
>      * use.  But if a function calls eval, the string argument is treated as a
>      * Program (per ECMA), so TCF_IN_FUNCTION won't be set.
>      *
>      * What's more, when the following code is reached from eval, cx->fp->fun
>      * is eval's JSFunction (a native function), so we need to skip its frame.
>      * We should find the scripted caller's function frame just below it, but
>      * we code a loop out of paranoia.
>      */
>     for (fp = cx->fp; (fp->flags & JSFRAME_SPECIAL) && fp->down; fp = fp->down)
>         continue;
>     obj = fp->varobj;
>     fun = fp->fun;
>     clasp = OBJ_GET_CLASS(cx, obj);
>     if (fun && clasp == &js_FunctionClass) {
>         /* We are compiling code inside a function */
>         getter = js_GetLocalVariable;
>         setter = js_SetLocalVariable;
>     } else if (fun && clasp == &js_CallClass) {
>         /* We are compiling code from an eval inside a function */
>         getter = js_GetCallVariable;
>         setter = js_SetCallVariable;
>     } else {
>         getter = clasp->getProperty;
>         setter = clasp->setProperty;
>     }
4127c1983
<     rt = cx->runtime;
---
>     ok = JS_TRUE;
4129,4134c1985,2020
<         /*
<          * FOR node is binary, left is loop control and right is body.  Use
<          * index to count each block-local let-variable on the left-hand side
<          * of the IN.
<          */
<         pn2 = NewParseNode(cx, ts, PN_BINARY, tc);
---
>         currentGetter = getter;
>         currentSetter = setter;
>         MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NO_VARIABLE_NAME);
>         atom = CURRENT_TOKEN(ts).t_atom;
> 
>         ATOM_LIST_SEARCH(ale, &tc->decls, atom);
>         if (ale) {
>             prevop = ALE_JSOP(ale);
>             if ((JS_HAS_STRICT_OPTION(cx) ||
>                  pn->pn_op == JSOP_DEFCONST ||
>                  prevop == JSOP_DEFCONST) &&
>                 !js_ReportCompileErrorNumber(cx, ts, NULL,
>                                              (pn->pn_op != JSOP_DEFCONST &&
>                                               prevop != JSOP_DEFCONST)
>                                              ? JSREPORT_WARNING|JSREPORT_STRICT
>                                              : JSREPORT_ERROR,
>                                              JSMSG_REDECLARED_VAR,
>                                              (prevop == JSOP_DEFFUN ||
>                                               prevop == JSOP_CLOSURE)
>                                              ? js_function_str
>                                              : (prevop == JSOP_DEFCONST)
>                                              ? js_const_str
>                                              : js_var_str,
>                                              ATOM_BYTES(atom))) {
>                 return NULL;
>             }
>             if (pn->pn_op == JSOP_DEFVAR && prevop == JSOP_CLOSURE)
>                 tc->flags |= TCF_FUN_CLOSURE_VS_VAR;
>         } else {
>             ale = js_IndexAtom(cx, atom, &tc->decls);
>             if (!ale)
>                 return NULL;
>         }
>         ALE_SET_JSOP(ale, pn->pn_op);
> 
>         pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NAME, tc);
4136a2023,2031
>         pn2->pn_op = JSOP_NAME;
>         pn2->pn_atom = atom;
>         pn2->pn_expr = NULL;
>         pn2->pn_slot = -1;
>         pn2->pn_attrs = (pn->pn_op == JSOP_DEFCONST)
>                         ? JSPROP_ENUMERATE | JSPROP_PERMANENT |
>                           JSPROP_READONLY
>                         : JSPROP_ENUMERATE | JSPROP_PERMANENT;
>         PN_APPEND(pn, pn2);
4138,4145c2033,2078
<         pn2->pn_op = JSOP_FORIN;
<         if (js_MatchToken(cx, ts, TOK_NAME)) {
<             if (CURRENT_TOKEN(ts).t_atom == rt->atomState.eachAtom)
<                 pn2->pn_op = JSOP_FOREACH;
<             else
<                 js_UngetToken(ts);
<         }
<         MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_AFTER_FOR);
---
>         if (!OBJ_LOOKUP_PROPERTY(cx, obj, (jsid)atom, &pobj, &prop))
>             return NULL;
>         if (pobj == obj &&
>             OBJ_IS_NATIVE(pobj) &&
>             (sprop = (JSScopeProperty *)prop) != NULL) {
>             if (sprop->getter == js_GetArgument) {
>                 if (pn->pn_op == JSOP_DEFCONST) {
>                     js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
>                                                 JSMSG_REDECLARED_PARAM,
>                                                 ATOM_BYTES(atom));
>                     ok = JS_FALSE;
>                 } else {
>                     currentGetter = js_GetArgument;
>                     currentSetter = js_SetArgument;
>                     ok = js_ReportCompileErrorNumber(cx, ts, NULL,
>                                                      JSREPORT_WARNING |
>                                                      JSREPORT_STRICT,
>                                                      JSMSG_VAR_HIDES_ARG,
>                                                      ATOM_BYTES(atom));
>                 }
>             } else {
>                 if (fun) {
>                     /* Not an argument, must be a redeclared local var. */
>                     if (clasp == &js_FunctionClass) {
>                         JS_ASSERT(sprop->getter == js_GetLocalVariable);
>                         JS_ASSERT((sprop->flags & SPROP_HAS_SHORTID) &&
>                                   sprop->shortid < fun->nvars);
>                     } else if (clasp == &js_CallClass) {
>                         if (sprop->getter == js_GetCallVariable) {
>                             /*
>                              * Referencing a variable introduced by a var
>                              * statement in the enclosing function. Check
>                              * that the slot number we have is in range.
>                              */
>                             JS_ASSERT((sprop->flags & SPROP_HAS_SHORTID) &&
>                                       sprop->shortid < fun->nvars);
>                         } else {
>                             /*
>                              * A variable introduced through another eval:
>                              * don't use the special getters and setters
>                              * since we can't allocate a slot in the frame.
>                              */
>                             currentGetter = sprop->getter;
>                             currentSetter = sprop->setter;
>                         }
>                     }
4147,4154c2080,2121
<         tt = js_GetToken(cx, ts);
<         switch (tt) {
< #if JS_HAS_DESTRUCTURING
<           case TOK_LB:
<           case TOK_LC:
<             pn3 = DestructuringExpr(cx, &data, tc, tt);
<             if (!pn3)
<                 return NULL;
---
>                     /* Override the old getter and setter, to handle eval. */
>                     sprop = js_ChangeNativePropertyAttrs(cx, obj, sprop,
>                                                          0, sprop->attrs,
>                                                          currentGetter,
>                                                          currentSetter);
>                     if (!sprop)
>                         ok = JS_FALSE;
>                 }
>             }
>         } else {
>             /*
>              * Property not found in current variable scope: we have not seen
>              * this variable before.  Define a new local variable by adding a
>              * property to the function's scope, allocating one slot in the
>              * function's frame.  Global variables and any locals declared in
>              * with statement bodies are handled at runtime, by script prolog
>              * JSOP_DEFVAR bytecodes generated for slot-less vars.
>              */
>             sprop = NULL;
>             if (prop) {
>                 OBJ_DROP_PROPERTY(cx, pobj, prop);
>                 prop = NULL;
>             }
>             if (currentGetter == js_GetCallVariable) {
>                 /* Can't increase fun->nvars in an active frame! */
>                 currentGetter = clasp->getProperty;
>                 currentSetter = clasp->setProperty;
>             }
>             if (currentGetter == js_GetLocalVariable &&
>                 atom != cx->runtime->atomState.argumentsAtom &&
>                 fp->scopeChain == obj &&
>                 !js_InWithStatement(tc)) {
>                 if (!js_AddNativeProperty(cx, obj, (jsid)atom,
>                                           currentGetter, currentSetter,
>                                           SPROP_INVALID_SLOT,
>                                           pn2->pn_attrs | JSPROP_SHARED,
>                                           SPROP_HAS_SHORTID, fun->nvars)) {
>                     ok = JS_FALSE;
>                 }
>                 fun->nvars++;
>             }
>         }
4156c2123,2124
<             if (pn3->pn_type != TOK_RB || pn3->pn_count != 2) {
---
>         if (js_MatchToken(cx, ts, TOK_ASSIGN)) {
>             if (CURRENT_TOKEN(ts).t_op != JSOP_NOP) {
4158,4159c2126,2138
<                                             JSMSG_BAD_FOR_LEFTSIDE);
<                 return NULL;
---
>                                             JSMSG_BAD_VAR_INIT);
>                 ok = JS_FALSE;
>             } else {
>                 pn2->pn_expr = AssignExpr(cx, ts, tc);
>                 if (!pn2->pn_expr) {
>                     ok = JS_FALSE;
>                 } else {
>                     pn2->pn_op = (pn->pn_op == JSOP_DEFCONST)
>                                  ? JSOP_SETCONST
>                                  : JSOP_SETNAME;
>                     if (atom == cx->runtime->atomState.argumentsAtom)
>                         tc->flags |= TCF_FUN_HEAVYWEIGHT;
>                 }
4160a2140
>         }
4162,4168c2142,2146
<             if (JSVERSION_NUMBER(cx) == JSVERSION_1_7) {
<                 /* Destructuring requires [key, value] enumeration in JS1.7. */
<                 if (pn2->pn_op != JSOP_FOREACH)
<                     pn2->pn_op = JSOP_FOREACHKEYVAL;
<             }
<             break;
< #endif
---
>         if (prop)
>             OBJ_DROP_PROPERTY(cx, pobj, prop);
>         if (!ok)
>             return NULL;
>     } while (js_MatchToken(cx, ts, TOK_COMMA));
4170,4173c2148,2150
<           case TOK_NAME:
<             atom = CURRENT_TOKEN(ts).t_atom;
<             if (!data.binder(cx, &data, atom, tc))
<                 return NULL;
---
>     pn->pn_pos.end = PN_LAST(pn)->pn_pos.end;
>     return pn;
> }
4175,4183c2152,2167
<             /*
<              * Create a name node with pn_op JSOP_NAME.  We can't set pn_op to
<              * JSOP_GETLOCAL here, because we don't yet know the block's depth
<              * in the operand stack frame.  The code generator computes that,
<              * and it tries to bind all names to slots, so we must let it do
<              * the deed.
<              */
<             pn3 = NewParseNode(cx, ts, PN_NAME, tc);
<             if (!pn3)
---
> static JSParseNode *
> Expr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
> {
>     JSParseNode *pn, *pn2;
> 
>     pn = AssignExpr(cx, ts, tc);
>     if (pn && js_MatchToken(cx, ts, TOK_COMMA)) {
>         pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc);
>         if (!pn2)
>             return NULL;
>         pn2->pn_pos.begin = pn->pn_pos.begin;
>         PN_INIT_LIST_1(pn2, pn);
>         pn = pn2;
>         do {
>             pn2 = AssignExpr(cx, ts, tc);
>             if (!pn2)
4185,4188c2169,2174
<             pn3->pn_op = JSOP_NAME;
<             pn3->pn_atom = atom;
<             pn3->pn_slot = -1;
<             break;
---
>             PN_APPEND(pn, pn2);
>         } while (js_MatchToken(cx, ts, TOK_COMMA));
>         pn->pn_pos.end = PN_LAST(pn)->pn_pos.end;
>     }
>     return pn;
> }
4190,4192c2176,2227
<           default:
<             js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                         JSMSG_NO_VARIABLE_NAME);
---
> static JSParseNode *
> AssignExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
> {
>     JSParseNode *pn, *pn2;
>     JSTokenType tt;
>     JSOp op;
> 
>     pn = CondExpr(cx, ts, tc);
>     if (!pn)
>         return NULL;
> 
>     tt = js_GetToken(cx, ts);
> #if JS_HAS_GETTER_SETTER
>     if (tt == TOK_NAME) {
>         tt = CheckGetterOrSetter(cx, ts, TOK_ASSIGN);
>         if (tt == TOK_ERROR)
>             return NULL;
>     }
> #endif
>     if (tt != TOK_ASSIGN) {
>         js_UngetToken(ts);
>         return pn;
>     }
> 
>     op = CURRENT_TOKEN(ts).t_op;
>     for (pn2 = pn; pn2->pn_type == TOK_RP; pn2 = pn2->pn_kid)
>         continue;
>     switch (pn2->pn_type) {
>       case TOK_NAME:
>         pn2->pn_op = JSOP_SETNAME;
>         if (pn2->pn_atom == cx->runtime->atomState.argumentsAtom)
>             tc->flags |= TCF_FUN_HEAVYWEIGHT;
>         break;
>       case TOK_DOT:
>         pn2->pn_op = JSOP_SETPROP;
>         break;
>       case TOK_LB:
>         pn2->pn_op = JSOP_SETELEM;
>         break;
> #if JS_HAS_LVALUE_RETURN
>       case TOK_LP:
>         pn2->pn_op = JSOP_SETCALL;
>         break;
> #endif
>       default:
>         js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
>                                     JSMSG_BAD_LEFTSIDE_OF_ASS);
>         return NULL;
>     }
>     pn = NewBinary(cx, TOK_ASSIGN, op, pn2, AssignExpr(cx, ts, tc), tc);
>     return pn;
> }
4194,4196c2229,2235
<           case TOK_ERROR:
<             return NULL;
<         }
---
> static JSParseNode *
> CondExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
> {
>     JSParseNode *pn, *pn1, *pn2, *pn3;
> #if JS_HAS_IN_OPERATOR
>     uintN oldflags;
> #endif /* JS_HAS_IN_OPERATOR */
4198,4201c2237,2241
<         MUST_MATCH_TOKEN(TOK_IN, JSMSG_IN_AFTER_FOR_NAME);
<         pn3 = NewBinary(cx, TOK_IN, JSOP_NOP, pn3,
<                         Expr(cx, ts, tc), tc);
<         if (!pn3)
---
>     pn = OrExpr(cx, ts, tc);
>     if (pn && js_MatchToken(cx, ts, TOK_HOOK)) {
>         pn1 = pn;
>         pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_TERNARY, tc);
>         if (!pn)
4202a2243,2255
> #if JS_HAS_IN_OPERATOR
>         /*
>          * Always accept the 'in' operator in the middle clause of a ternary,
>          * where it's unambiguous, even if we might be parsing the init of a
>          * for statement.
>          */
>         oldflags = tc->flags;
>         tc->flags &= ~TCF_IN_FOR_INIT;
> #endif /* JS_HAS_IN_OPERATOR */
>         pn2 = AssignExpr(cx, ts, tc);
> #if JS_HAS_IN_OPERATOR
>         tc->flags = oldflags | (tc->flags & TCF_FUN_FLAGS);
> #endif /* JS_HAS_IN_OPERATOR */
4204,4211d2256
<         MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_FOR_CTRL);
<         pn2->pn_left = pn3;
<         *pnp = pn2;
<         pnp = &pn2->pn_right;
<     } while (js_MatchToken(cx, ts, TOK_FOR));
< 
<     if (js_MatchToken(cx, ts, TOK_IF)) {
<         pn2 = NewParseNode(cx, ts, PN_TERNARY, tc);
4214,4215c2259,2261
<         pn2->pn_kid1 = Condition(cx, ts, tc);
<         if (!pn2->pn_kid1)
---
>         MUST_MATCH_TOKEN(TOK_COLON, JSMSG_COLON_IN_COND);
>         pn3 = AssignExpr(cx, ts, tc);
>         if (!pn3)
4217,4218c2263,2267
<         *pnp = pn2;
<         pnp = &pn2->pn_kid2;
---
>         pn->pn_pos.begin = pn1->pn_pos.begin;
>         pn->pn_pos.end = pn3->pn_pos.end;
>         pn->pn_kid1 = pn1;
>         pn->pn_kid2 = pn2;
>         pn->pn_kid3 = pn3;
4220,4229d2268
< 
<     pn2 = NewParseNode(cx, ts, PN_UNARY, tc);
<     if (!pn2)
<         return NULL;
<     pn2->pn_type = type;
<     pn2->pn_op = op;
<     pn2->pn_kid = kid;
<     *pnp = pn2;
< 
<     js_PopStatement(tc);
4233,4249d2271
< #if JS_HAS_GENERATOR_EXPRS
< 
< /*
<  * Starting from a |for| keyword after an expression, parse the comprehension
<  * tail completing this generator expression. Wrap the expression at kid in a
<  * generator function that is immediately called to evaluate to the generator
<  * iterator that is the value of this generator expression.
<  *
<  * Callers pass a blank unary node via pn, which GeneratorExpr fills in as the
<  * yield expression, which ComprehensionTail in turn wraps in a TOK_SEMI-type
<  * expression-statement node that constitutes the body of the |for| loop(s) in
<  * the generator function.
<  *
<  * Note how unlike Python, we do not evaluate the expression to the right of
<  * the first |in| in the chain of |for| heads. Instead, a generator expression
<  * is merely sugar for a generator function expression and its application.
<  */
4251,4252c2273
< GeneratorExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
<               uintN oldflags, JSParseNode *pn, JSParseNode *kid)
---
> OrExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
4254,4312c2275
<     JSParseNode *body, *lambda;
<     JSFunction *fun;
< 
<     /* Initialize pn, connecting it to kid. */
<     JS_ASSERT(pn->pn_arity == PN_UNARY);
<     pn->pn_type = TOK_YIELD;
<     pn->pn_op = JSOP_YIELD;
<     pn->pn_pos = kid->pn_pos;
<     pn->pn_kid = kid;
<     pn->pn_hidden = JS_TRUE;
< 
<     /*
<      * Parse the comprehension tail at hand, making pn the kid of the loop
<      * body's expression statement.
<      */
<     body = ComprehensionTail(cx, ts, tc, TOK_SEMI, JSOP_NOP, pn);
<     if (!body)
<         return NULL;
<     body->pn_pos.begin = kid->pn_pos.begin;
< 
<     /*
<      * Make the generator function and flag it as interpreted ASAP (see the
<      * comment in FunctionBody).
<      */
<     fun = NewCompilerFunction(cx, tc, NULL, JSFUN_LAMBDA);
<     if (!fun)
<         return NULL;
< 
<     /*
<      * This generator function is referenced by an anonymous function object
<      * node. Here is where we must take care to propagate certain tc->flags
<      * that may have changed from oldflags to reflect crucial facts about the
<      * expression on the left of |for| and in the comprehension tail after it.
<      */
<     lambda = NewParseNode(cx, ts, PN_FUNC, tc);
<     if (!lambda)
<         return NULL;
<     lambda->pn_type = TOK_FUNCTION;
<     lambda->pn_op = JSOP_ANONFUNOBJ;
<     lambda->pn_pos.begin = body->pn_pos.begin;
<     lambda->pn_funpob = js_NewParsedObjectBox(cx, tc->parseContext,
<                                               fun->object);
<     if (!lambda->pn_funpob)
<         return NULL;
<     lambda->pn_body = body;
<     lambda->pn_flags = TCF_FUN_IS_GENERATOR | TCF_GENEXP_LAMBDA |
<                        ((oldflags ^ tc->flags) & TCF_FUN_FLAGS);
< 
<     /*
<      * Re-use pn to name the result node, a call expression invoking the
<      * anonymous generator function object.
<      */
<     pn = NewParseNode(cx, ts, PN_LIST, tc);
<     if (!pn)
<         return NULL;
<     pn->pn_type = TOK_LP;
<     pn->pn_op = JSOP_CALL;
<     pn->pn_pos.begin = lambda->pn_pos.begin;
<     PN_INIT_LIST_1(pn, lambda);
---
>     JSParseNode *pn;
4314,4315c2277,2279
<     body->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
<     tc->flags = oldflags;
---
>     pn = AndExpr(cx, ts, tc);
>     if (pn && js_MatchToken(cx, ts, TOK_OR))
>         pn = NewBinary(cx, TOK_OR, JSOP_OR, pn, OrExpr(cx, ts, tc), tc);
4319c2283,2286
< static const char js_generator_str[] = "generator";
---
> static JSParseNode *
> AndExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
> {
>     JSParseNode *pn;
4321,4322c2288,2292
< #endif /* JS_HAS_GENERATOR_EXPRS */
< #endif /* JS_HAS_GENERATORS */
---
>     pn = BitOrExpr(cx, ts, tc);
>     if (pn && js_MatchToken(cx, ts, TOK_AND))
>         pn = NewBinary(cx, TOK_AND, JSOP_AND, pn, AndExpr(cx, ts, tc), tc);
>     return pn;
> }
4324,4326c2294,2295
< static JSBool
< ArgumentList(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
<              JSParseNode *listNode)
---
> static JSParseNode *
> BitOrExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
4328,4367c2297
<     JSBool matched;
< 
<     ts->flags |= TSF_OPERAND;
<     matched = js_MatchToken(cx, ts, TOK_RP);
<     ts->flags &= ~TSF_OPERAND;
<     if (!matched) {
<         do {
< #if JS_HAS_GENERATOR_EXPRS
<             uintN oldflags = tc->flags;
< #endif
<             JSParseNode *argNode = AssignExpr(cx, ts, tc);
<             if (!argNode)
<                 return JS_FALSE;
< #if JS_HAS_GENERATORS
<             if (argNode->pn_type == TOK_YIELD) {
<                 js_ReportCompileErrorNumber(cx, ts, argNode, JSREPORT_ERROR,
<                                             JSMSG_BAD_GENERATOR_SYNTAX,
<                                             js_yield_str);
<                 return JS_FALSE;
<             }
< #endif
< #if JS_HAS_GENERATOR_EXPRS
<             if (js_MatchToken(cx, ts, TOK_FOR)) {
<                 JSParseNode *pn = NewParseNode(cx, ts, PN_UNARY, tc);
<                 if (!pn)
<                     return JS_FALSE;
<                 argNode = GeneratorExpr(cx, ts, tc, oldflags, pn, argNode);
<                 if (!argNode)
<                     return JS_FALSE;
<                 if (listNode->pn_count > 1 ||
<                     js_PeekToken(cx, ts) == TOK_COMMA) {
<                     js_ReportCompileErrorNumber(cx, ts, argNode, JSREPORT_ERROR,
<                                                 JSMSG_BAD_GENERATOR_SYNTAX,
<                                                 js_generator_str);
<                     return JS_FALSE;
<                 }
<             }
< #endif
<             PN_APPEND(listNode, argNode);
<         } while (js_MatchToken(cx, ts, TOK_COMMA));
---
>     JSParseNode *pn;
4369,4373c2299,2302
<         if (js_GetToken(cx, ts) != TOK_RP) {
<             js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                         JSMSG_PAREN_AFTER_ARGS);
<             return JS_FALSE;
<         }
---
>     pn = BitXorExpr(cx, ts, tc);
>     while (pn && js_MatchToken(cx, ts, TOK_BITOR)) {
>         pn = NewBinary(cx, TOK_BITOR, JSOP_BITOR, pn, BitXorExpr(cx, ts, tc),
>                        tc);
4375c2304
<     return JS_TRUE;
---
>     return pn;
4379,4380c2308
< MemberExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
<            JSBool allowCallSyntax)
---
> BitXorExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
4382,4413c2310
<     JSParseNode *pn, *pn2, *pn3;
<     JSTokenType tt;
< 
<     JS_CHECK_RECURSION(cx, return NULL);
< 
<     /* Check for new expression first. */
<     ts->flags |= TSF_OPERAND;
<     tt = js_GetToken(cx, ts);
<     ts->flags &= ~TSF_OPERAND;
<     if (tt == TOK_NEW) {
<         pn = NewParseNode(cx, ts, PN_LIST, tc);
<         if (!pn)
<             return NULL;
<         pn2 = MemberExpr(cx, ts, tc, JS_FALSE);
<         if (!pn2)
<             return NULL;
<         pn->pn_op = JSOP_NEW;
<         PN_INIT_LIST_1(pn, pn2);
<         pn->pn_pos.begin = pn2->pn_pos.begin;
< 
<         if (js_MatchToken(cx, ts, TOK_LP) && !ArgumentList(cx, ts, tc, pn))
<             return NULL;
<         if (pn->pn_count > ARGC_LIMIT) {
<             JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
<                                  JSMSG_TOO_MANY_CON_ARGS);
<             return NULL;
<         }
<         pn->pn_pos.end = PN_LAST(pn)->pn_pos.end;
<     } else {
<         pn = PrimaryExpr(cx, ts, tc, tt, JS_FALSE);
<         if (!pn)
<             return NULL;
---
>     JSParseNode *pn;
4415,4427c2312,2315
<         if (pn->pn_type == TOK_ANYNAME ||
<             pn->pn_type == TOK_AT ||
<             pn->pn_type == TOK_DBLCOLON) {
<             pn2 = NewOrRecycledNode(cx, tc);
<             if (!pn2)
<                 return NULL;
<             pn2->pn_type = TOK_UNARYOP;
<             pn2->pn_pos = pn->pn_pos;
<             pn2->pn_op = JSOP_XMLNAME;
<             pn2->pn_arity = PN_UNARY;
<             pn2->pn_kid = pn;
<             pn = pn2;
<         }
---
>     pn = BitAndExpr(cx, ts, tc);
>     while (pn && js_MatchToken(cx, ts, TOK_BITXOR)) {
>         pn = NewBinary(cx, TOK_BITXOR, JSOP_BITXOR, pn, BitAndExpr(cx, ts, tc),
>                        tc);
4428a2317,2318
>     return pn;
> }
4430,4546c2320,2323
<     while ((tt = js_GetToken(cx, ts)) > TOK_EOF) {
<         if (tt == TOK_DOT) {
<             pn2 = NewParseNode(cx, ts, PN_NAME, tc);
<             if (!pn2)
<                 return NULL;
<             pn2->pn_slot = -1;
< #if JS_HAS_XML_SUPPORT
<             ts->flags |= TSF_OPERAND | TSF_KEYWORD_IS_NAME;
<             tt = js_GetToken(cx, ts);
<             ts->flags &= ~(TSF_OPERAND | TSF_KEYWORD_IS_NAME);
<             pn3 = PrimaryExpr(cx, ts, tc, tt, JS_TRUE);
<             if (!pn3)
<                 return NULL;
<             tt = PN_TYPE(pn3);
<             if (tt == TOK_NAME) {
<                 pn2->pn_op = JSOP_GETPROP;
<                 pn2->pn_expr = pn;
<                 pn2->pn_atom = pn3->pn_atom;
<                 RecycleTree(pn3, tc);
<             } else {
<                 if (TOKEN_TYPE_IS_XML(tt)) {
<                     pn2->pn_type = TOK_LB;
<                     pn2->pn_op = JSOP_GETELEM;
<                 } else if (tt == TOK_RP) {
<                     JSParseNode *group = pn3;
< 
<                     /* Recycle the useless TOK_RP/JSOP_GROUP node. */
<                     pn3 = group->pn_kid;
<                     group->pn_kid = NULL;
<                     RecycleTree(group, tc);
<                     pn2->pn_type = TOK_FILTER;
<                     pn2->pn_op = JSOP_FILTER;
< 
<                     /* A filtering predicate is like a with statement. */
<                     tc->flags |= TCF_FUN_HEAVYWEIGHT;
<                 } else {
<                     js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                                 JSMSG_NAME_AFTER_DOT);
<                     return NULL;
<                 }
<                 pn2->pn_arity = PN_BINARY;
<                 pn2->pn_left = pn;
<                 pn2->pn_right = pn3;
<             }
< #else
<             ts->flags |= TSF_KEYWORD_IS_NAME;
<             MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NAME_AFTER_DOT);
<             ts->flags &= ~TSF_KEYWORD_IS_NAME;
<             pn2->pn_op = JSOP_GETPROP;
<             pn2->pn_expr = pn;
<             pn2->pn_atom = CURRENT_TOKEN(ts).t_atom;
< #endif
<             pn2->pn_pos.begin = pn->pn_pos.begin;
<             pn2->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
< #if JS_HAS_XML_SUPPORT
<         } else if (tt == TOK_DBLDOT) {
<             pn2 = NewParseNode(cx, ts, PN_BINARY, tc);
<             if (!pn2)
<                 return NULL;
<             ts->flags |= TSF_OPERAND | TSF_KEYWORD_IS_NAME;
<             tt = js_GetToken(cx, ts);
<             ts->flags &= ~(TSF_OPERAND | TSF_KEYWORD_IS_NAME);
<             pn3 = PrimaryExpr(cx, ts, tc, tt, JS_TRUE);
<             if (!pn3)
<                 return NULL;
<             tt = PN_TYPE(pn3);
<             if (tt == TOK_NAME) {
<                 pn3->pn_type = TOK_STRING;
<                 pn3->pn_arity = PN_NULLARY;
<                 pn3->pn_op = JSOP_QNAMEPART;
<             } else if (!TOKEN_TYPE_IS_XML(tt)) {
<                 js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                             JSMSG_NAME_AFTER_DOT);
<                 return NULL;
<             }
<             pn2->pn_op = JSOP_DESCENDANTS;
<             pn2->pn_left = pn;
<             pn2->pn_right = pn3;
<             pn2->pn_pos.begin = pn->pn_pos.begin;
<             pn2->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
< #endif
<         } else if (tt == TOK_LB) {
<             pn2 = NewParseNode(cx, ts, PN_BINARY, tc);
<             if (!pn2)
<                 return NULL;
<             pn3 = Expr(cx, ts, tc);
<             if (!pn3)
<                 return NULL;
< 
<             MUST_MATCH_TOKEN(TOK_RB, JSMSG_BRACKET_IN_INDEX);
<             pn2->pn_pos.begin = pn->pn_pos.begin;
<             pn2->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
< 
<             /* Optimize o['p'] to o.p by rewriting pn2. */
<             if (pn3->pn_type == TOK_STRING) {
<                 pn2->pn_type = TOK_DOT;
<                 pn2->pn_op = JSOP_GETPROP;
<                 pn2->pn_arity = PN_NAME;
<                 pn2->pn_expr = pn;
<                 pn2->pn_atom = pn3->pn_atom;
<             } else {
<                 pn2->pn_op = JSOP_GETELEM;
<                 pn2->pn_left = pn;
<                 pn2->pn_right = pn3;
<             }
<         } else if (allowCallSyntax && tt == TOK_LP) {
<             pn2 = NewParseNode(cx, ts, PN_LIST, tc);
<             if (!pn2)
<                 return NULL;
< 
<             /* Pick JSOP_EVAL and flag tc as heavyweight if eval(...). */
<             pn2->pn_op = JSOP_CALL;
<             if (pn->pn_op == JSOP_NAME &&
<                 pn->pn_atom == cx->runtime->atomState.evalAtom) {
<                 pn2->pn_op = JSOP_EVAL;
<                 tc->flags |= TCF_FUN_HEAVYWEIGHT;
<             }
---
> static JSParseNode *
> BitAndExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
> {
>     JSParseNode *pn;
4548,4549c2325,2329
<             PN_INIT_LIST_1(pn2, pn);
<             pn2->pn_pos.begin = pn->pn_pos.begin;
---
>     pn = EqExpr(cx, ts, tc);
>     while (pn && js_MatchToken(cx, ts, TOK_BITAND))
>         pn = NewBinary(cx, TOK_BITAND, JSOP_BITAND, pn, EqExpr(cx, ts, tc), tc);
>     return pn;
> }
4551,4562c2331,2335
<             if (!ArgumentList(cx, ts, tc, pn2))
<                 return NULL;
<             if (pn2->pn_count > ARGC_LIMIT) {
<                 JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
<                                      JSMSG_TOO_MANY_FUN_ARGS);
<                 return NULL;
<             }
<             pn2->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
<         } else {
<             js_UngetToken(ts);
<             return pn;
<         }
---
> static JSParseNode *
> EqExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
> {
>     JSParseNode *pn;
>     JSOp op;
4564c2337,2340
<         pn = pn2;
---
>     pn = RelExpr(cx, ts, tc);
>     while (pn && js_MatchToken(cx, ts, TOK_EQOP)) {
>         op = CURRENT_TOKEN(ts).t_op;
>         pn = NewBinary(cx, TOK_EQOP, op, pn, RelExpr(cx, ts, tc), tc);
4566,4567d2341
<     if (tt == TOK_ERROR)
<         return NULL;
4572c2346
< BracketedExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
---
> RelExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
4574d2347
<     uintN oldflags;
4575a2349,2352
>     JSTokenType tt;
>     JSOp op;
> #if JS_HAS_IN_OPERATOR
>     uintN inForInitFlag;
4576a2354
>     inForInitFlag = tc->flags & TCF_IN_FOR_INIT;
4578,4580c2356,2357
<      * Always accept the 'in' operator in a parenthesized expression,
<      * where it's unambiguous, even if we might be parsing the init of a
<      * for statement.
---
>      * Uses of the in operator in ShiftExprs are always unambiguous,
>      * so unset the flag that prohibits recognizing it.
4582d2358
<     oldflags = tc->flags;
4584,4585c2360,2384
<     pn = Expr(cx, ts, tc);
<     tc->flags = oldflags | (tc->flags & TCF_FUN_FLAGS);
---
> #endif /* JS_HAS_IN_OPERATOR */
> 
>     pn = ShiftExpr(cx, ts, tc);
>     while (pn &&
>            (js_MatchToken(cx, ts, TOK_RELOP)
> #if JS_HAS_IN_OPERATOR
>             /*
>              * Recognize the 'in' token as an operator only if we're not
>              * currently in the init expr of a for loop.
>              */
>             || (inForInitFlag == 0 && js_MatchToken(cx, ts, TOK_IN))
> #endif /* JS_HAS_IN_OPERATOR */
> #if JS_HAS_INSTANCEOF
>             || js_MatchToken(cx, ts, TOK_INSTANCEOF)
> #endif /* JS_HAS_INSTANCEOF */
>             )) {
>         tt = CURRENT_TOKEN(ts).type;
>         op = CURRENT_TOKEN(ts).t_op;
>         pn = NewBinary(cx, tt, op, pn, ShiftExpr(cx, ts, tc), tc);
>     }
> #if JS_HAS_IN_OPERATOR
>     /* Restore previous state of inForInit flag. */
>     tc->flags |= inForInitFlag;
> #endif /* JS_HAS_IN_OPERATOR */
> 
4589,4590d2387
< #if JS_HAS_XML_SUPPORT
< 
4592c2389
< EndBracketedExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
---
> ShiftExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
4594a2392
>     JSOp op;
4596,4600c2394,2398
<     pn = BracketedExpr(cx, ts, tc);
<     if (!pn)
<         return NULL;
< 
<     MUST_MATCH_TOKEN(TOK_RB, JSMSG_BRACKET_AFTER_ATTR_EXPR);
---
>     pn = AddExpr(cx, ts, tc);
>     while (pn && js_MatchToken(cx, ts, TOK_SHOP)) {
>         op = CURRENT_TOKEN(ts).t_op;
>         pn = NewBinary(cx, TOK_SHOP, op, pn, AddExpr(cx, ts, tc), tc);
>     }
4604,4654d2401
< /*
<  * From the ECMA-357 grammar in 11.1.1 and 11.1.2:
<  *
<  *      AttributeIdentifier:
<  *              @ PropertySelector
<  *              @ QualifiedIdentifier
<  *              @ [ Expression ]
<  *
<  *      PropertySelector:
<  *              Identifier
<  *              *
<  *
<  *      QualifiedIdentifier:
<  *              PropertySelector :: PropertySelector
<  *              PropertySelector :: [ Expression ]
<  *
<  * We adapt AttributeIdentifier and QualifiedIdentier to be LL(1), like so:
<  *
<  *      AttributeIdentifier:
<  *              @ QualifiedIdentifier
<  *              @ [ Expression ]
<  *
<  *      PropertySelector:
<  *              Identifier
<  *              *
<  *
<  *      QualifiedIdentifier:
<  *              PropertySelector :: PropertySelector
<  *              PropertySelector :: [ Expression ]
<  *              PropertySelector
<  *
<  * As PrimaryExpression: Identifier is in ECMA-262 and we want the semantics
<  * for that rule to result in a name node, but ECMA-357 extends the grammar
<  * to include PrimaryExpression: QualifiedIdentifier, we must factor further:
<  *
<  *      QualifiedIdentifier:
<  *              PropertySelector QualifiedSuffix
<  *
<  *      QualifiedSuffix:
<  *              :: PropertySelector
<  *              :: [ Expression ]
<  *              /nothing/
<  *
<  * And use this production instead of PrimaryExpression: QualifiedIdentifier:
<  *
<  *      PrimaryExpression:
<  *              Identifier QualifiedSuffix
<  *
<  * We hoist the :: match into callers of QualifiedSuffix, in order to tweak
<  * PropertySelector vs. Identifier pn_arity, pn_op, and other members.
<  */
4656c2403
< PropertySelector(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
---
> AddExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
4658a2406,2407
>     JSTokenType tt;
>     JSOp op;
4660,4672c2409,2415
<     pn = NewParseNode(cx, ts, PN_NULLARY, tc);
<     if (!pn)
<         return NULL;
<     if (pn->pn_type == TOK_STAR) {
<         pn->pn_type = TOK_ANYNAME;
<         pn->pn_op = JSOP_ANYNAME;
<         pn->pn_atom = cx->runtime->atomState.starAtom;
<     } else {
<         JS_ASSERT(pn->pn_type == TOK_NAME);
<         pn->pn_op = JSOP_QNAMEPART;
<         pn->pn_arity = PN_NAME;
<         pn->pn_atom = CURRENT_TOKEN(ts).t_atom;
<         pn->pn_slot = -1;
---
>     pn = MulExpr(cx, ts, tc);
>     while (pn &&
>            (js_MatchToken(cx, ts, TOK_PLUS) ||
>             js_MatchToken(cx, ts, TOK_MINUS))) {
>         tt = CURRENT_TOKEN(ts).type;
>         op = (tt == TOK_PLUS) ? JSOP_ADD : JSOP_SUB;
>         pn = NewBinary(cx, tt, op, pn, MulExpr(cx, ts, tc), tc);
4678,4679c2421
< QualifiedSuffix(JSContext *cx, JSTokenStream *ts, JSParseNode *pn,
<                 JSTreeContext *tc)
---
> MulExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
4681c2423
<     JSParseNode *pn2, *pn3;
---
>     JSParseNode *pn;
4682a2425
>     JSOp op;
4684,4704c2427,2433
<     JS_ASSERT(CURRENT_TOKEN(ts).type == TOK_DBLCOLON);
<     pn2 = NewParseNode(cx, ts, PN_NAME, tc);
<     if (!pn2)
<         return NULL;
< 
<     /* Left operand of :: must be evaluated if it is an identifier. */
<     if (pn->pn_op == JSOP_QNAMEPART)
<         pn->pn_op = JSOP_NAME;
< 
<     ts->flags |= TSF_KEYWORD_IS_NAME;
<     tt = js_GetToken(cx, ts);
<     ts->flags &= ~TSF_KEYWORD_IS_NAME;
<     if (tt == TOK_STAR || tt == TOK_NAME) {
<         /* Inline and specialize PropertySelector for JSOP_QNAMECONST. */
<         pn2->pn_op = JSOP_QNAMECONST;
<         pn2->pn_atom = (tt == TOK_STAR)
<                        ? cx->runtime->atomState.starAtom
<                        : CURRENT_TOKEN(ts).t_atom;
<         pn2->pn_expr = pn;
<         pn2->pn_slot = -1;
<         return pn2;
---
>     pn = UnaryExpr(cx, ts, tc);
>     while (pn &&
>            (js_MatchToken(cx, ts, TOK_STAR) ||
>             js_MatchToken(cx, ts, TOK_DIVOP))) {
>         tt = CURRENT_TOKEN(ts).type;
>         op = CURRENT_TOKEN(ts).t_op;
>         pn = NewBinary(cx, tt, op, pn, UnaryExpr(cx, ts, tc), tc);
4705a2435,2436
>     return pn;
> }
4707c2438,2449
<     if (tt != TOK_LB) {
---
> static JSParseNode *
> SetLvalKid(JSContext *cx, JSTokenStream *ts, JSParseNode *pn, JSParseNode *kid,
>            const char *name)
> {
>     while (kid->pn_type == TOK_RP)
>         kid = kid->pn_kid;
>     if (kid->pn_type != TOK_NAME &&
>         kid->pn_type != TOK_DOT &&
> #if JS_HAS_LVALUE_RETURN
>         (kid->pn_type != TOK_LP || kid->pn_op != JSOP_CALL) &&
> #endif
>         kid->pn_type != TOK_LB) {
4709c2451
<                                     JSMSG_SYNTAX_ERROR);
---
>                                     JSMSG_BAD_OPERAND, name);
4712,4720c2454,2455
<     pn3 = EndBracketedExpr(cx, ts, tc);
<     if (!pn3)
<         return NULL;
< 
<     pn2->pn_op = JSOP_QNAME;
<     pn2->pn_arity = PN_BINARY;
<     pn2->pn_left = pn;
<     pn2->pn_right = pn3;
<     return pn2;
---
>     pn->pn_kid = kid;
>     return kid;
4723,4724c2458,2463
< static JSParseNode *
< QualifiedIdentifier(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
---
> static const char *incop_name_str[] = {"increment", "decrement"};
> 
> static JSBool
> SetIncOpKid(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
>             JSParseNode *pn, JSParseNode *kid,
>             JSTokenType tt, JSBool preorder)
4726c2465
<     JSParseNode *pn;
---
>     JSOp op;
4728,4734c2467,2477
<     pn = PropertySelector(cx, ts, tc);
<     if (!pn)
<         return NULL;
<     if (js_MatchToken(cx, ts, TOK_DBLCOLON))
<         pn = QualifiedSuffix(cx, ts, pn, tc);
<     return pn;
< }
---
>     kid = SetLvalKid(cx, ts, pn, kid, incop_name_str[tt == TOK_DEC]);
>     if (!kid)
>         return JS_FALSE;
>     switch (kid->pn_type) {
>       case TOK_NAME:
>         op = (tt == TOK_INC)
>              ? (preorder ? JSOP_INCNAME : JSOP_NAMEINC)
>              : (preorder ? JSOP_DECNAME : JSOP_NAMEDEC);
>         if (kid->pn_atom == cx->runtime->atomState.argumentsAtom)
>             tc->flags |= TCF_FUN_HEAVYWEIGHT;
>         break;
4736,4740c2479,2483
< static JSParseNode *
< AttributeIdentifier(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
< {
<     JSParseNode *pn, *pn2;
<     JSTokenType tt;
---
>       case TOK_DOT:
>         op = (tt == TOK_INC)
>              ? (preorder ? JSOP_INCPROP : JSOP_PROPINC)
>              : (preorder ? JSOP_DECPROP : JSOP_PROPDEC);
>         break;
4742,4757c2485,2497
<     JS_ASSERT(CURRENT_TOKEN(ts).type == TOK_AT);
<     pn = NewParseNode(cx, ts, PN_UNARY, tc);
<     if (!pn)
<         return NULL;
<     pn->pn_op = JSOP_TOATTRNAME;
<     ts->flags |= TSF_KEYWORD_IS_NAME;
<     tt = js_GetToken(cx, ts);
<     ts->flags &= ~TSF_KEYWORD_IS_NAME;
<     if (tt == TOK_STAR || tt == TOK_NAME) {
<         pn2 = QualifiedIdentifier(cx, ts, tc);
<     } else if (tt == TOK_LB) {
<         pn2 = EndBracketedExpr(cx, ts, tc);
<     } else {
<         js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                     JSMSG_SYNTAX_ERROR);
<         return NULL;
---
> #if JS_HAS_LVALUE_RETURN
>       case TOK_LP:
>         kid->pn_op = JSOP_SETCALL;
> #endif
>       case TOK_LB:
>         op = (tt == TOK_INC)
>              ? (preorder ? JSOP_INCELEM : JSOP_ELEMINC)
>              : (preorder ? JSOP_DECELEM : JSOP_ELEMDEC);
>         break;
> 
>       default:
>         JS_ASSERT(0);
>         op = JSOP_NOP;
4759,4762c2499,2500
<     if (!pn2)
<         return NULL;
<     pn->pn_kid = pn2;
<     return pn;
---
>     pn->pn_op = op;
>     return JS_TRUE;
4765,4767d2502
< /*
<  * Make a TOK_LC unary node whose pn_kid is an expression.
<  */
4769c2504
< XMLExpr(JSContext *cx, JSTokenStream *ts, JSBool inTag, JSTreeContext *tc)
---
> UnaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
4770a2506
>     JSTokenType tt;
4772d2507
<     uintN oldflags;
4774,4777c2509,2511
<     JS_ASSERT(CURRENT_TOKEN(ts).type == TOK_LC);
<     pn = NewParseNode(cx, ts, PN_UNARY, tc);
<     if (!pn)
<         return NULL;
---
>     ts->flags |= TSF_REGEXP;
>     tt = js_GetToken(cx, ts);
>     ts->flags &= ~TSF_REGEXP;
4779,4788c2513,2560
<     /*
<      * Turn off XML tag mode, but don't restore it after parsing this braced
<      * expression.  Instead, simply restore ts's old flags.  This is required
<      * because XMLExpr is called both from within a tag, and from within text
<      * contained in an element, but outside of any start, end, or point tag.
<      */
<     oldflags = ts->flags;
<     ts->flags = oldflags & ~TSF_XMLTAGMODE;
<     pn2 = Expr(cx, ts, tc);
<     if (!pn2)
---
>     switch (tt) {
>       case TOK_UNARYOP:
>       case TOK_PLUS:
>       case TOK_MINUS:
>         pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc);
>         if (!pn)
>             return NULL;
>         pn->pn_type = TOK_UNARYOP;      /* PLUS and MINUS are binary */
>         pn->pn_op = CURRENT_TOKEN(ts).t_op;
>         pn2 = UnaryExpr(cx, ts, tc);
>         if (!pn2)
>             return NULL;
>         pn->pn_pos.end = pn2->pn_pos.end;
>         pn->pn_kid = pn2;
>         break;
> 
>       case TOK_INC:
>       case TOK_DEC:
>         pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc);
>         if (!pn)
>             return NULL;
>         pn2 = MemberExpr(cx, ts, tc, JS_TRUE);
>         if (!pn2)
>             return NULL;
>         if (!SetIncOpKid(cx, ts, tc, pn, pn2, tt, JS_TRUE))
>             return NULL;
>         pn->pn_pos.end = pn2->pn_pos.end;
>         break;
> 
>       case TOK_DELETE:
>         pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc);
>         if (!pn)
>             return NULL;
>         pn2 = UnaryExpr(cx, ts, tc);
>         if (!pn2)
>             return NULL;
>         pn->pn_pos.end = pn2->pn_pos.end;
> 
>         /*
>          * Under ECMA3, deleting any unary expression is valid -- it simply
>          * returns true. Here we strip off any parentheses.
>          */
>         while (pn2->pn_type == TOK_RP)
>             pn2 = pn2->pn_kid;
>         pn->pn_kid = pn2;
>         break;
> 
>       case TOK_ERROR:
4791,4794c2563,2584
<     MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_IN_XML_EXPR);
<     ts->flags = oldflags;
<     pn->pn_kid = pn2;
<     pn->pn_op = inTag ? JSOP_XMLTAGEXPR : JSOP_XMLELTEXPR;
---
>       default:
>         js_UngetToken(ts);
>         pn = MemberExpr(cx, ts, tc, JS_TRUE);
>         if (!pn)
>             return NULL;
> 
>         /* Don't look across a newline boundary for a postfix incop. */
>         if (pn->pn_pos.end.lineno == ts->lineno) {
>             tt = js_PeekTokenSameLine(cx, ts);
>             if (tt == TOK_INC || tt == TOK_DEC) {
>                 (void) js_GetToken(cx, ts);
>                 pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc);
>                 if (!pn2)
>                     return NULL;
>                 if (!SetIncOpKid(cx, ts, tc, pn2, pn, tt, JS_FALSE))
>                     return NULL;
>                 pn2->pn_pos.begin = pn->pn_pos.begin;
>                 pn = pn2;
>             }
>         }
>         break;
>     }
4798,4805c2588,2590
< /*
<  * Make a terminal node for one of TOK_XMLNAME, TOK_XMLATTR, TOK_XMLSPACE,
<  * TOK_XMLTEXT, TOK_XMLCDATA, TOK_XMLCOMMENT, or TOK_XMLPI.  When converting
<  * parse tree to XML, we preserve a TOK_XMLSPACE node only if it's the sole
<  * child of a container tag.
<  */
< static JSParseNode *
< XMLAtomNode(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
---
> static JSBool
> ArgumentList(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
>              JSParseNode *listNode)
4807,4808c2592
<     JSParseNode *pn;
<     JSToken *tp;
---
>     JSBool matched;
4810,4818c2594,2611
<     pn = NewParseNode(cx, ts, PN_NULLARY, tc);
<     if (!pn)
<         return NULL;
<     tp = &CURRENT_TOKEN(ts);
<     pn->pn_op = tp->t_op;
<     pn->pn_atom = tp->t_atom;
<     if (tp->type == TOK_XMLPI)
<         pn->pn_atom2 = tp->t_atom2;
<     return pn;
---
>     ts->flags |= TSF_REGEXP;
>     matched = js_MatchToken(cx, ts, TOK_RP);
>     ts->flags &= ~TSF_REGEXP;
>     if (!matched) {
>         do {
>             JSParseNode *argNode = AssignExpr(cx, ts, tc);
>             if (!argNode)
>                 return JS_FALSE;
>             PN_APPEND(listNode, argNode);
>         } while (js_MatchToken(cx, ts, TOK_COMMA));
> 
>         if (js_GetToken(cx, ts) != TOK_RP) {
>             js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
>                                         JSMSG_PAREN_AFTER_ARGS);
>             return JS_FALSE;
>         }
>     }
>     return JS_TRUE;
4821,4832d2613
< /*
<  * Parse the productions:
<  *
<  *      XMLNameExpr:
<  *              XMLName XMLNameExpr?
<  *              { Expr } XMLNameExpr?
<  *
<  * Return a PN_LIST, PN_UNARY, or PN_NULLARY according as XMLNameExpr produces
<  * a list of names and/or expressions, a single expression, or a single name.
<  * If PN_LIST or PN_NULLARY, pn_type will be TOK_XMLNAME; if PN_UNARY, pn_type
<  * will be TOK_LC.
<  */
4834c2615,2616
< XMLNameExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
---
> MemberExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
>            JSBool allowCallSyntax)
4836c2618
<     JSParseNode *pn, *pn2, *list;
---
>     JSParseNode *pn, *pn2, *pn3;
4839,4843c2621,2654
<     pn = list = NULL;
<     do {
<         tt = CURRENT_TOKEN(ts).type;
<         if (tt == TOK_LC) {
<             pn2 = XMLExpr(cx, ts, JS_TRUE, tc);
---
>     /* Check for new expression first. */
>     ts->flags |= TSF_REGEXP;
>     tt = js_PeekToken(cx, ts);
>     ts->flags &= ~TSF_REGEXP;
>     if (tt == TOK_NEW) {
>         (void) js_GetToken(cx, ts);
> 
>         pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc);
>         if (!pn)
>             return NULL;
>         pn2 = MemberExpr(cx, ts, tc, JS_FALSE);
>         if (!pn2)
>             return NULL;
>         pn->pn_op = JSOP_NEW;
>         PN_INIT_LIST_1(pn, pn2);
>         pn->pn_pos.begin = pn2->pn_pos.begin;
> 
>         if (js_MatchToken(cx, ts, TOK_LP) && !ArgumentList(cx, ts, tc, pn))
>             return NULL;
>         if (pn->pn_count - 1 >= ARGC_LIMIT) {
>             JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
>                                  JSMSG_TOO_MANY_CON_ARGS);
>             return NULL;
>         }
>         pn->pn_pos.end = PN_LAST(pn)->pn_pos.end;
>     } else {
>         pn = PrimaryExpr(cx, ts, tc);
>         if (!pn)
>             return NULL;
>     }
> 
>     while ((tt = js_GetToken(cx, ts)) > TOK_EOF) {
>         if (tt == TOK_DOT) {
>             pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NAME, tc);
4846,4848c2657,2664
<         } else {
<             JS_ASSERT(tt == TOK_XMLNAME);
<             pn2 = XMLAtomNode(cx, ts, tc);
---
>             MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NAME_AFTER_DOT);
>             pn2->pn_pos.begin = pn->pn_pos.begin;
>             pn2->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
>             pn2->pn_op = JSOP_GETPROP;
>             pn2->pn_expr = pn;
>             pn2->pn_atom = CURRENT_TOKEN(ts).t_atom;
>         } else if (tt == TOK_LB) {
>             pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_BINARY, tc);
4851c2667,2669
<         }
---
>             pn3 = Expr(cx, ts, tc);
>             if (!pn3)
>                 return NULL;
4853,4864c2671,2685
<         if (!pn) {
<             pn = pn2;
<         } else {
<             if (!list) {
<                 list = NewParseNode(cx, ts, PN_LIST, tc);
<                 if (!list)
<                     return NULL;
<                 list->pn_type = TOK_XMLNAME;
<                 list->pn_pos.begin = pn->pn_pos.begin;
<                 PN_INIT_LIST_1(list, pn);
<                 list->pn_extra = PNX_CANTFOLD;
<                 pn = list;
---
>             MUST_MATCH_TOKEN(TOK_RB, JSMSG_BRACKET_IN_INDEX);
>             pn2->pn_pos.begin = pn->pn_pos.begin;
>             pn2->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
> 
>             /* Optimize o['p'] to o.p by rewriting pn2. */
>             if (pn3->pn_type == TOK_STRING) {
>                 pn2->pn_type = TOK_DOT;
>                 pn2->pn_op = JSOP_GETPROP;
>                 pn2->pn_arity = PN_NAME;
>                 pn2->pn_expr = pn;
>                 pn2->pn_atom = pn3->pn_atom;
>             } else {
>                 pn2->pn_op = JSOP_GETELEM;
>                 pn2->pn_left = pn;
>                 pn2->pn_right = pn3;
4866,4867c2687,2713
<             pn->pn_pos.end = pn2->pn_pos.end;
<             PN_APPEND(pn, pn2);
---
>         } else if (allowCallSyntax && tt == TOK_LP) {
>             pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc);
>             if (!pn2)
>                 return NULL;
> 
>             /* Pick JSOP_EVAL and flag tc as heavyweight if eval(...). */
>             pn2->pn_op = JSOP_CALL;
>             if (pn->pn_op == JSOP_NAME &&
>                 pn->pn_atom == cx->runtime->atomState.evalAtom) {
>                 pn2->pn_op = JSOP_EVAL;
>                 tc->flags |= TCF_FUN_HEAVYWEIGHT;
>             }
> 
>             PN_INIT_LIST_1(pn2, pn);
>             pn2->pn_pos.begin = pn->pn_pos.begin;
> 
>             if (!ArgumentList(cx, ts, tc, pn2))
>                 return NULL;
>             if (pn2->pn_count - 1 >= ARGC_LIMIT) {
>                 JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
>                                      JSMSG_TOO_MANY_FUN_ARGS);
>                 return NULL;
>             }
>             pn2->pn_pos.end = PN_LAST(pn2)->pn_pos.end;
>         } else {
>             js_UngetToken(ts);
>             return pn;
4869d2714
<     } while ((tt = js_GetToken(cx, ts)) == TOK_XMLNAME || tt == TOK_LC);
4871c2716,2719
<     js_UngetToken(ts);
---
>         pn = pn2;
>     }
>     if (tt == TOK_ERROR)
>         return NULL;
4875,4899c2723
< /*
<  * Macro to test whether an XMLNameExpr or XMLTagContent node can be folded
<  * at compile time into a JSXML tree.
<  */
< #define XML_FOLDABLE(pn)        ((pn)->pn_arity == PN_LIST                    \
<                                  ? ((pn)->pn_extra & PNX_CANTFOLD) == 0       \
<                                  : (pn)->pn_type != TOK_LC)
< 
< /*
<  * Parse the productions:
<  *
<  *      XMLTagContent:
<  *              XMLNameExpr
<  *              XMLTagContent S XMLNameExpr S? = S? XMLAttr
<  *              XMLTagContent S XMLNameExpr S? = S? { Expr }
<  *
<  * Return a PN_LIST, PN_UNARY, or PN_NULLARY according to how XMLTagContent
<  * produces a list of name and attribute values and/or braced expressions, a
<  * single expression, or a single name.
<  *
<  * If PN_LIST or PN_NULLARY, pn_type will be TOK_XMLNAME for the case where
<  * XMLTagContent: XMLNameExpr.  If pn_type is not TOK_XMLNAME but pn_arity is
<  * PN_LIST, pn_type will be tagtype.  If PN_UNARY, pn_type will be TOK_LC and
<  * we parsed exactly one expression.
<  */
---
> #ifdef _UTF8
4901,4902c2725
< XMLTagContent(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
<               JSTokenType tagtype, JSAtom **namep)
---
> PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
4904d2726
<     JSParseNode *pn, *pn2, *list;
4905a2728,2734
>     JSParseNode *pn, *pn2, *pn3;
>     char *badWord;
> #if JS_HAS_GETTER_SETTER
>     JSAtom *atom;
>     JSRuntime *rt;
> #endif
> 	size_t mbLength;
4907,4911c2736,2738
<     pn = XMLNameExpr(cx, ts, tc);
<     if (!pn)
<         return NULL;
<     *namep = (pn->pn_arity == PN_NULLARY) ? pn->pn_atom : NULL;
<     list = NULL;
---
> #if JS_HAS_SHARP_VARS
>     JSParseNode *defsharp;
>     JSBool notsharp;
4913,4918c2740,2748
<     while (js_MatchToken(cx, ts, TOK_XMLSPACE)) {
<         tt = js_GetToken(cx, ts);
<         if (tt != TOK_XMLNAME && tt != TOK_LC) {
<             js_UngetToken(ts);
<             break;
<         }
---
>     defsharp = NULL;
>     notsharp = JS_FALSE;
>   again:
>     /*
>      * Control flows here after #n= is scanned.  If the following primary is
>      * not valid after such a "sharp variable" definition, the token type case
>      * should set notsharp.
>      */
> #endif
4920,4934c2750,2752
<         pn2 = XMLNameExpr(cx, ts, tc);
<         if (!pn2)
<             return NULL;
<         if (!list) {
<             list = NewParseNode(cx, ts, PN_LIST, tc);
<             if (!list)
<                 return NULL;
<             list->pn_type = tagtype;
<             list->pn_pos.begin = pn->pn_pos.begin;
<             PN_INIT_LIST_1(list, pn);
<             pn = list;
<         }
<         PN_APPEND(pn, pn2);
<         if (!XML_FOLDABLE(pn2))
<             pn->pn_extra |= PNX_CANTFOLD;
---
>     ts->flags |= TSF_REGEXP;
>     tt = js_GetToken(cx, ts);
>     ts->flags &= ~TSF_REGEXP;
4936,4951c2754,2757
<         js_MatchToken(cx, ts, TOK_XMLSPACE);
<         MUST_MATCH_TOKEN(TOK_ASSIGN, JSMSG_NO_ASSIGN_IN_XML_ATTR);
<         js_MatchToken(cx, ts, TOK_XMLSPACE);
< 
<         tt = js_GetToken(cx, ts);
<         if (tt == TOK_XMLATTR) {
<             pn2 = XMLAtomNode(cx, ts, tc);
<         } else if (tt == TOK_LC) {
<             pn2 = XMLExpr(cx, ts, JS_TRUE, tc);
<             pn->pn_extra |= PNX_CANTFOLD;
<         } else {
<             js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                         JSMSG_BAD_XML_ATTR_VALUE);
<             return NULL;
<         }
<         if (!pn2)
---
> #if JS_HAS_GETTER_SETTER
>     if (tt == TOK_NAME) {
>         tt = CheckGetterOrSetter(cx, ts, TOK_FUNCTION);
>         if (tt == TOK_ERROR)
4953,4954d2758
<         pn->pn_pos.end = pn2->pn_pos.end;
<         PN_APPEND(pn, pn2);
4955a2760
> #endif
4957,4958c2762,2769
<     return pn;
< }
---
>     switch (tt) {
> #if JS_HAS_LEXICAL_CLOSURE
>       case TOK_FUNCTION:
>         pn = FunctionExpr(cx, ts, tc);
>         if (!pn)
>             return NULL;
>         break;
> #endif
4960,4969c2771,2775
< #define XML_CHECK_FOR_ERROR_AND_EOF(tt,result)                                \
<     JS_BEGIN_MACRO                                                            \
<         if ((tt) <= TOK_EOF) {                                                \
<             if ((tt) == TOK_EOF) {                                            \
<                 js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,     \
<                                             JSMSG_END_OF_XML_SOURCE);         \
<             }                                                                 \
<             return result;                                                    \
<         }                                                                     \
<     JS_END_MACRO
---
> #if JS_HAS_INITIALIZERS
>       case TOK_LB:
>       {
>         JSBool matched;
>         jsuint atomIndex;
4971,4973c2777,2781
< static JSParseNode *
< XMLElementOrList(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
<                  JSBool allowList);
---
>         pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc);
>         if (!pn)
>             return NULL;
>         pn->pn_type = TOK_RB;
>         pn->pn_extra = JS_FALSE;
4975,4985c2783,2789
< /*
<  * Consume XML element tag content, including the TOK_XMLETAGO (</) sequence
<  * that opens the end tag for the container.
<  */
< static JSBool
< XMLElementContent(JSContext *cx, JSTokenStream *ts, JSParseNode *pn,
<                   JSTreeContext *tc)
< {
<     JSTokenType tt;
<     JSParseNode *pn2;
<     JSAtom *textAtom;
---
> #if JS_HAS_SHARP_VARS
>         if (defsharp) {
>             PN_INIT_LIST_1(pn, defsharp);
>             defsharp = NULL;
>         } else
> #endif
>             PN_INIT_LIST(pn);
4987,5003c2791,2802
<     ts->flags &= ~TSF_XMLTAGMODE;
<     for (;;) {
<         ts->flags |= TSF_XMLTEXTMODE;
<         tt = js_GetToken(cx, ts);
<         ts->flags &= ~TSF_XMLTEXTMODE;
<         XML_CHECK_FOR_ERROR_AND_EOF(tt, JS_FALSE);
< 
<         JS_ASSERT(tt == TOK_XMLSPACE || tt == TOK_XMLTEXT);
<         textAtom = CURRENT_TOKEN(ts).t_atom;
<         if (textAtom) {
<             /* Non-zero-length XML text scanned. */
<             pn2 = XMLAtomNode(cx, ts, tc);
<             if (!pn2)
<                 return JS_FALSE;
<             pn->pn_pos.end = pn2->pn_pos.end;
<             PN_APPEND(pn, pn2);
<         }
---
>         ts->flags |= TSF_REGEXP;
>         matched = js_MatchToken(cx, ts, TOK_RB);
>         ts->flags &= ~TSF_REGEXP;
>         if (!matched) {
>             for (atomIndex = 0; atomIndex < ATOM_INDEX_LIMIT; atomIndex++) {
>                 ts->flags |= TSF_REGEXP;
>                 tt = js_PeekToken(cx, ts);
>                 ts->flags &= ~TSF_REGEXP;
>                 if (tt == TOK_RB) {
>                     pn->pn_extra = JS_TRUE;
>                     break;
>                 }
5005,5010c2804,2812
<         ts->flags |= TSF_OPERAND;
<         tt = js_GetToken(cx, ts);
<         ts->flags &= ~TSF_OPERAND;
<         XML_CHECK_FOR_ERROR_AND_EOF(tt, JS_FALSE);
<         if (tt == TOK_XMLETAGO)
<             break;
---
>                 if (tt == TOK_COMMA) {
>                     /* So CURRENT_TOKEN gets TOK_COMMA and not TOK_LB. */
>                     js_MatchToken(cx, ts, TOK_COMMA);
>                     pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc);
>                 } else
>                     pn2 = AssignExpr(cx, ts, tc);
>                 if (!pn2)
>                     return NULL;
>                 PN_APPEND(pn, pn2);
5012,5019c2814,2818
<         if (tt == TOK_LC) {
<             pn2 = XMLExpr(cx, ts, JS_FALSE, tc);
<             pn->pn_extra |= PNX_CANTFOLD;
<         } else if (tt == TOK_XMLSTAGO) {
<             pn2 = XMLElementOrList(cx, ts, tc, JS_FALSE);
<             if (pn2) {
<                 pn2->pn_extra &= ~PNX_XMLROOT;
<                 pn->pn_extra |= pn2->pn_extra;
---
>                 if (tt != TOK_COMMA) {
>                     /* If we didn't already match TOK_COMMA in above case. */
>                     if (!js_MatchToken(cx, ts, TOK_COMMA))
>                         break;
>                 }
5021,5024c2820,2821
<         } else {
<             JS_ASSERT(tt == TOK_XMLCDATA || tt == TOK_XMLCOMMENT ||
<                       tt == TOK_XMLPI);
<             pn2 = XMLAtomNode(cx, ts, tc);
---
> 
>             MUST_MATCH_TOKEN(TOK_RB, JSMSG_BRACKET_AFTER_LIST);
5026,5030c2823,2825
<         if (!pn2)
<             return JS_FALSE;
<         pn->pn_pos.end = pn2->pn_pos.end;
<         PN_APPEND(pn, pn2);
<     }
---
>         pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
>         return pn;
>       }
5032,5035c2827,2831
<     JS_ASSERT(CURRENT_TOKEN(ts).type == TOK_XMLETAGO);
<     ts->flags |= TSF_XMLTAGMODE;
<     return JS_TRUE;
< }
---
>       case TOK_LC:
>         pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc);
>         if (!pn)
>             return NULL;
>         pn->pn_type = TOK_RC;
5037,5046c2833,2920
< /*
<  * Return a PN_LIST node containing an XML or XMLList Initialiser.
<  */
< static JSParseNode *
< XMLElementOrList(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
<                  JSBool allowList)
< {
<     JSParseNode *pn, *pn2, *list;
<     JSTokenType tt;
<     JSAtom *startAtom, *endAtom;
---
> #if JS_HAS_SHARP_VARS
>         if (defsharp) {
>             PN_INIT_LIST_1(pn, defsharp);
>             defsharp = NULL;
>         } else
> #endif
>             PN_INIT_LIST(pn);
> 
>         if (!js_MatchToken(cx, ts, TOK_RC)) {
>             do {
>                 JSOp op;
> 
>                 tt = js_GetToken(cx, ts);
>                 switch (tt) {
>                   case TOK_NUMBER:
>                     pn3 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc);
>                     if (pn3)
>                         pn3->pn_dval = CURRENT_TOKEN(ts).t_dval;
>                     break;
>                   case TOK_NAME:
> #if JS_HAS_GETTER_SETTER
>                     atom = CURRENT_TOKEN(ts).t_atom;
>                     rt = cx->runtime;
>                     if (atom == rt->atomState.getAtom ||
>                         atom == rt->atomState.setAtom) {
>                         op = (atom == rt->atomState.getAtom)
>                              ? JSOP_GETTER
>                              : JSOP_SETTER;
>                         if (js_MatchToken(cx, ts, TOK_NAME)) {
>                             pn3 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NAME,
>                                                tc);
>                             if (!pn3)
>                                 return NULL;
>                             pn3->pn_atom = CURRENT_TOKEN(ts).t_atom;
>                             pn3->pn_expr = NULL;
> 
>                             /* We have to fake a 'function' token here. */
>                             CURRENT_TOKEN(ts).t_op = JSOP_NOP;
>                             CURRENT_TOKEN(ts).type = TOK_FUNCTION;
>                             pn2 = FunctionExpr(cx, ts, tc);
>                             pn2 = NewBinary(cx, TOK_COLON, op, pn3, pn2, tc);
>                             goto skip;
>                         }
>                     }
>                     /* else fall thru ... */
> #endif
>                   case TOK_STRING:
>                     pn3 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc);
>                     if (pn3)
>                         pn3->pn_atom = CURRENT_TOKEN(ts).t_atom;
>                     break;
>                   case TOK_RC:
>                     if (!js_ReportCompileErrorNumber(cx, ts, NULL,
>                                                      JSREPORT_WARNING |
>                                                      JSREPORT_STRICT,
>                                                      JSMSG_TRAILING_COMMA)) {
>                         return NULL;
>                     }
>                     goto end_obj_init;
>                   default:
>                     js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
>                                                 JSMSG_BAD_PROP_ID);
>                     return NULL;
>                 }
> 
>                 tt = js_GetToken(cx, ts);
> #if JS_HAS_GETTER_SETTER
>                 if (tt == TOK_NAME) {
>                     tt = CheckGetterOrSetter(cx, ts, TOK_COLON);
>                     if (tt == TOK_ERROR)
>                         return NULL;
>                 }
> #endif
>                 if (tt != TOK_COLON) {
>                     js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
>                                                 JSMSG_COLON_AFTER_ID);
>                     return NULL;
>                 }
>                 op = CURRENT_TOKEN(ts).t_op;
>                 pn2 = NewBinary(cx, TOK_COLON, op, pn3, AssignExpr(cx, ts, tc),
>                                 tc);
> #if JS_HAS_GETTER_SETTER
>               skip:
> #endif
>                 if (!pn2)
>                     return NULL;
>                 PN_APPEND(pn, pn2);
>             } while (js_MatchToken(cx, ts, TOK_COMMA));
5048c2922,2926
<     JS_CHECK_RECURSION(cx, return NULL);
---
>             MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_LIST);
>         }
>       end_obj_init:
>         pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
>         return pn;
5050,5053c2928,2937
<     JS_ASSERT(CURRENT_TOKEN(ts).type == TOK_XMLSTAGO);
<     pn = NewParseNode(cx, ts, PN_LIST, tc);
<     if (!pn)
<         return NULL;
---
> #if JS_HAS_SHARP_VARS
>       case TOK_DEFSHARP:
>         if (defsharp)
>             goto badsharp;
>         defsharp = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc);
>         if (!defsharp)
>             return NULL;
>         defsharp->pn_kid = NULL;
>         defsharp->pn_num = (jsint) CURRENT_TOKEN(ts).t_dval;
>         goto again;
5055,5058c2939,2948
<     ts->flags |= TSF_XMLTAGMODE;
<     tt = js_GetToken(cx, ts);
<     if (tt == TOK_ERROR)
<         return NULL;
---
>       case TOK_USESHARP:
>         /* Check for forward/dangling references at runtime, to allow eval. */
>         pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc);
>         if (!pn)
>             return NULL;
>         pn->pn_num = (jsint) CURRENT_TOKEN(ts).t_dval;
>         notsharp = JS_TRUE;
>         break;
> #endif /* JS_HAS_SHARP_VARS */
> #endif /* JS_HAS_INITIALIZERS */
5060c2950,2958
<     if (tt == TOK_XMLNAME || tt == TOK_LC) {
---
>       case TOK_LP:
>       {
> #if JS_HAS_IN_OPERATOR
>         uintN oldflags;
> #endif
>         pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc);
>         if (!pn)
>             return NULL;
> #if JS_HAS_IN_OPERATOR
5062c2960,2962
<          * XMLElement.  Append the tag and its contents, if any, to pn.
---
>          * Always accept the 'in' operator in a parenthesized expression,
>          * where it's unambiguous, even if we might be parsing the init of a
>          * for statement.
5064c2964,2970
<         pn2 = XMLTagContent(cx, ts, tc, TOK_XMLSTAGO, &startAtom);
---
>         oldflags = tc->flags;
>         tc->flags &= ~TCF_IN_FOR_INIT;
> #endif
>         pn2 = Expr(cx, ts, tc);
> #if JS_HAS_IN_OPERATOR
>         tc->flags = oldflags | (tc->flags & TCF_FUN_FLAGS);
> #endif
5067,5103d2972
<         js_MatchToken(cx, ts, TOK_XMLSPACE);
< 
<         tt = js_GetToken(cx, ts);
<         if (tt == TOK_XMLPTAGC) {
<             /* Point tag (/>): recycle pn if pn2 is a list of tag contents. */
<             if (pn2->pn_type == TOK_XMLSTAGO) {
<                 PN_INIT_LIST(pn);
<                 RecycleTree(pn, tc);
<                 pn = pn2;
<             } else {
<                 JS_ASSERT(pn2->pn_type == TOK_XMLNAME ||
<                           pn2->pn_type == TOK_LC);
<                 PN_INIT_LIST_1(pn, pn2);
<                 if (!XML_FOLDABLE(pn2))
<                     pn->pn_extra |= PNX_CANTFOLD;
<             }
<             pn->pn_type = TOK_XMLPTAGC;
<             pn->pn_extra |= PNX_XMLROOT;
<         } else {
<             /* We had better have a tag-close (>) at this point. */
<             if (tt != TOK_XMLTAGC) {
<                 js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                             JSMSG_BAD_XML_TAG_SYNTAX);
<                 return NULL;
<             }
<             pn2->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
< 
<             /* Make sure pn2 is a TOK_XMLSTAGO list containing tag contents. */
<             if (pn2->pn_type != TOK_XMLSTAGO) {
<                 PN_INIT_LIST_1(pn, pn2);
<                 if (!XML_FOLDABLE(pn2))
<                     pn->pn_extra |= PNX_CANTFOLD;
<                 pn2 = pn;
<                 pn = NewParseNode(cx, ts, PN_LIST, tc);
<                 if (!pn)
<                     return NULL;
<             }
5105,5114c2974,2979
<             /* Now make pn a nominal-root TOK_XMLELEM list containing pn2. */
<             pn->pn_type = TOK_XMLELEM;
<             PN_INIT_LIST_1(pn, pn2);
<             if (!XML_FOLDABLE(pn2))
<                 pn->pn_extra |= PNX_CANTFOLD;
<             pn->pn_extra |= PNX_XMLROOT;
< 
<             /* Get element contents and delimiting end-tag-open sequence. */
<             if (!XMLElementContent(cx, ts, pn, tc))
<                 return NULL;
---
>         MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_IN_PAREN);
>         pn->pn_type = TOK_RP;
>         pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
>         pn->pn_kid = pn2;
>         break;
>       }
5116,5122c2981,2997
<             tt = js_GetToken(cx, ts);
<             XML_CHECK_FOR_ERROR_AND_EOF(tt, NULL);
<             if (tt != TOK_XMLNAME && tt != TOK_LC) {
<                 js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                             JSMSG_BAD_XML_TAG_SYNTAX);
<                 return NULL;
<             }
---
>       case TOK_STRING:
> #if JS_HAS_SHARP_VARS
>         notsharp = JS_TRUE;
> #endif
>         /* FALL THROUGH */
>       case TOK_NAME:
>       case TOK_OBJECT:
>         pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc);
>         if (!pn)
>             return NULL;
>         pn->pn_op = CURRENT_TOKEN(ts).t_op;
>         pn->pn_atom = CURRENT_TOKEN(ts).t_atom;
>         if (tt == TOK_NAME) {
>             pn->pn_arity = PN_NAME;
>             pn->pn_expr = NULL;
>             pn->pn_slot = -1;
>             pn->pn_attrs = 0;
5124,5132c2999,3002
<             /* Parse end tag; check mismatch at compile-time if we can. */
<             pn2 = XMLTagContent(cx, ts, tc, TOK_XMLETAGO, &endAtom);
<             if (!pn2)
<                 return NULL;
<             if (pn2->pn_type == TOK_XMLETAGO) {
<                 /* Oops, end tag has attributes! */
<                 js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                             JSMSG_BAD_XML_TAG_SYNTAX);
<                 return NULL;
---
>             /* Unqualified __parent__ and __proto__ uses require activations. */
>             if (pn->pn_atom == cx->runtime->atomState.parentAtom ||
>                 pn->pn_atom == cx->runtime->atomState.protoAtom) {
>                 tc->flags |= TCF_FUN_HEAVYWEIGHT;
5134,5135c3004,3005
<             if (endAtom && startAtom && endAtom != startAtom) {
<                 JSString *str = ATOM_TO_STRING(startAtom);
---
>         }
>         break;
5137,5143c3007,3015
<                 /* End vs. start tag name mismatch: point to the tag name. */
<                 js_ReportCompileErrorNumber(cx, ts, pn2,
<                                             JSREPORT_UC | JSREPORT_ERROR,
<                                             JSMSG_XML_TAG_NAME_MISMATCH,
<                                             JSSTRING_CHARS(str));
<                 return NULL;
<             }
---
>       case TOK_NUMBER:
>         pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc);
>         if (!pn)
>             return NULL;
>         pn->pn_dval = CURRENT_TOKEN(ts).t_dval;
> #if JS_HAS_SHARP_VARS
>         notsharp = JS_TRUE;
> #endif
>         break;
5145,5170c3017,3019
<             /* Make a TOK_XMLETAGO list with pn2 as its single child. */
<             JS_ASSERT(pn2->pn_type == TOK_XMLNAME || pn2->pn_type == TOK_LC);
<             list = NewParseNode(cx, ts, PN_LIST, tc);
<             if (!list)
<                 return NULL;
<             list->pn_type = TOK_XMLETAGO;
<             PN_INIT_LIST_1(list, pn2);
<             PN_APPEND(pn, list);
<             if (!XML_FOLDABLE(pn2)) {
<                 list->pn_extra |= PNX_CANTFOLD;
<                 pn->pn_extra |= PNX_CANTFOLD;
<             }
< 
<             js_MatchToken(cx, ts, TOK_XMLSPACE);
<             MUST_MATCH_TOKEN(TOK_XMLTAGC, JSMSG_BAD_XML_TAG_SYNTAX);
<         }
< 
<         /* Set pn_op now that pn has been updated to its final value. */
<         pn->pn_op = JSOP_TOXML;
<     } else if (allowList && tt == TOK_XMLTAGC) {
<         /* XMLList Initialiser. */
<         pn->pn_type = TOK_XMLLIST;
<         pn->pn_op = JSOP_TOXMLLIST;
<         PN_INIT_LIST(pn);
<         pn->pn_extra |= PNX_XMLROOT;
<         if (!XMLElementContent(cx, ts, pn, tc))
---
>       case TOK_PRIMARY:
>         pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc);
>         if (!pn)
5171a3021,3025
>         pn->pn_op = CURRENT_TOKEN(ts).t_op;
> #if JS_HAS_SHARP_VARS
>         notsharp = JS_TRUE;
> #endif
>         break;
5173,5174c3027,3034
<         MUST_MATCH_TOKEN(TOK_XMLTAGC, JSMSG_BAD_XML_LIST_SYNTAX);
<     } else {
---
> #if !JS_HAS_EXPORT_IMPORT
>       case TOK_EXPORT:
>       case TOK_IMPORT:
> #endif
>       case TOK_RESERVED:
>         badWord = js_DeflateString(cx, CURRENT_TOKEN(ts).ptr,
>                                    (size_t) CURRENT_TOKEN(ts).pos.end.index
>                                           - CURRENT_TOKEN(ts).pos.begin.index,&mbLength);
5176c3036,3037
<                                     JSMSG_BAD_XML_NAME_SYNTAX);
---
>                                     JSMSG_RESERVED_ID, badWord);
>         JS_free(cx, badWord);
5178,5211d3038
<     }
< 
<     pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
<     ts->flags &= ~TSF_XMLTAGMODE;
<     return pn;
< }
< 
< static JSParseNode *
< XMLElementOrListRoot(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
<                      JSBool allowList)
< {
<     uint32 oldopts;
<     JSParseNode *pn;
< 
<     /*
<      * Force XML support to be enabled so that comments and CDATA literals
<      * are recognized, instead of <! followed by -- starting an HTML comment
<      * to end of line (used in script tags to hide content from old browsers
<      * that don't recognize <script>).
<      */
<     oldopts = JS_SetOptions(cx, cx->options | JSOPTION_XML);
<     pn = XMLElementOrList(cx, ts, tc, allowList);
<     JS_SetOptions(cx, oldopts);
<     return pn;
< }
< 
< JS_FRIEND_API(JSParseNode *)
< js_ParseXMLText(JSContext *cx, JSObject *chain, JSParseContext *pc,
<                 JSBool allowList)
< {
<     JSStackFrame *fp, frame;
<     JSParseNode *pn;
<     JSTreeContext tc;
<     JSTokenType tt;
5213,5220c3040,3042
<     /*
<      * Push a compiler frame if we have no frames, or if the top frame is a
<      * lightweight function activation, or if its scope chain doesn't match
<      * the one passed to us.
<      */
<     fp = cx->fp;
<     MaybeSetupFrame(cx, chain, fp, &frame);
<     TREE_CONTEXT_INIT(&tc, pc);
---
>       case TOK_ERROR:
>         /* The scanner or one of its subroutines reported the error. */
>         return NULL;
5222,5232c3044,3047
<     /* Set XML-only mode to turn off special treatment of {expr} in XML. */
<     TS(pc)->flags |= TSF_OPERAND | TSF_XMLONLYMODE;
<     tt = js_GetToken(cx, TS(pc));
<     TS(pc)->flags &= ~TSF_OPERAND;
< 
<     if (tt != TOK_XMLSTAGO) {
<         js_ReportCompileErrorNumber(cx, TS(pc), NULL, JSREPORT_ERROR,
<                                     JSMSG_BAD_XML_MARKUP);
<         pn = NULL;
<     } else {
<         pn = XMLElementOrListRoot(cx, TS(pc), &tc, allowList);
---
>       default:
>         js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
>                                     JSMSG_SYNTAX_ERROR);
>         return NULL;
5235,5237c3050,3061
<     TS(pc)->flags &= ~TSF_XMLONLYMODE;
<     TREE_CONTEXT_FINISH(&tc);
<     cx->fp = fp;
---
> #if JS_HAS_SHARP_VARS
>     if (defsharp) {
>         if (notsharp) {
>   badsharp:
>             js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
>                                         JSMSG_BAD_SHARP_VAR_DEF);
>             return NULL;
>         }
>         defsharp->pn_kid = pn;
>         return defsharp;
>     }
> #endif
5240,5242c3064
< 
< #endif /* JS_HAS_XMLSUPPORT */
< 
---
> #else //#ifdef _UTF8
5244,5245c3066
< PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
<             JSTokenType tt, JSBool afterDot)
---
> PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
5246a3068
>     JSTokenType tt;
5248c3070,3075
<     JSOp op;
---
>     char *badWord;
> #if JS_HAS_GETTER_SETTER
>     JSAtom *atom;
>     JSRuntime *rt;
> #endif
> 
5252d3078
< #endif
5254,5256d3079
<     JS_CHECK_RECURSION(cx, return NULL);
< 
< #if JS_HAS_SHARP_VARS
5262c3085
<      * not valid after such a "sharp variable" definition, the tt switch case
---
>      * not valid after such a "sharp variable" definition, the token type case
5266a3090,3093
>     ts->flags |= TSF_REGEXP;
>     tt = js_GetToken(cx, ts);
>     ts->flags &= ~TSF_REGEXP;
> 
5275a3103
> #if JS_HAS_LEXICAL_CLOSURE
5277,5291d3104
< #if JS_HAS_XML_SUPPORT
<         ts->flags |= TSF_KEYWORD_IS_NAME;
<         if (js_MatchToken(cx, ts, TOK_DBLCOLON)) {
<             ts->flags &= ~TSF_KEYWORD_IS_NAME;
<             pn2 = NewParseNode(cx, ts, PN_NULLARY, tc);
<             if (!pn2)
<                 return NULL;
<             pn2->pn_type = TOK_FUNCTION;
<             pn = QualifiedSuffix(cx, ts, pn2, tc);
<             if (!pn)
<                 return NULL;
<             break;
<         }
<         ts->flags &= ~TSF_KEYWORD_IS_NAME;
< #endif
5295a3109
> #endif
5296a3111
> #if JS_HAS_INITIALIZERS
5300c3115
<         jsuint index;
---
>         jsuint atomIndex;
5302c3117
<         pn = NewParseNode(cx, ts, PN_LIST, tc);
---
>         pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc);
5305a3121
>         pn->pn_extra = JS_FALSE;
5315c3131
<         ts->flags |= TSF_OPERAND;
---
>         ts->flags |= TSF_REGEXP;
5317c3133
<         ts->flags &= ~TSF_OPERAND;
---
>         ts->flags &= ~TSF_REGEXP;
5319,5326c3135,3136
<             for (index = 0; ; index++) {
<                 if (index == ARRAY_INIT_LIMIT) {
<                     js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                                 JSMSG_ARRAY_INIT_TOO_BIG);
<                     return NULL;
<                 }
< 
<                 ts->flags |= TSF_OPERAND;
---
>             for (atomIndex = 0; atomIndex < ATOM_INDEX_LIMIT; atomIndex++) {
>                 ts->flags |= TSF_REGEXP;
5328c3138
<                 ts->flags &= ~TSF_OPERAND;
---
>                 ts->flags &= ~TSF_REGEXP;
5330c3140
<                     pn->pn_extra |= PNX_ENDCOMMA;
---
>                     pn->pn_extra = JS_TRUE;
5337,5338c3147,3148
<                     pn2 = NewParseNode(cx, ts, PN_NULLARY, tc);
<                 } else {
---
>                     pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc);
>                 } else
5340d3149
<                 }
5352,5423d3160
< #if JS_HAS_GENERATORS
<             /*
<              * At this point, (index == 0 && pn->pn_count != 0) implies one
<              * element initialiser was parsed (possibly with a defsharp before
<              * the left bracket).
<              *
<              * An array comprehension of the form:
<              *
<              *   [i * j for (i in o) for (j in p) if (i != j)]
<              *
<              * translates to roughly the following let expression:
<              *
<              *   let (array = new Array, i, j) {
<              *     for (i in o) let {
<              *       for (j in p)
<              *         if (i != j)
<              *           array.push(i * j)
<              *     }
<              *     array
<              *   }
<              *
<              * where array is a nameless block-local variable.  The "roughly"
<              * means that an implementation may optimize away the array.push.
<              * An array comprehension opens exactly one block scope, no matter
<              * how many for heads it contains.
<              *
<              * Each let () {...} or for (let ...) ... compiles to:
<              *
<              *   JSOP_ENTERBLOCK <o> ... JSOP_LEAVEBLOCK <n>
<              *
<              * where <o> is a literal object representing the block scope,
<              * with <n> properties, naming each var declared in the block.
<              *
<              * Each var declaration in a let-block binds a name in <o> at
<              * compile time, and allocates a slot on the operand stack at
<              * runtime via JSOP_ENTERBLOCK.  A block-local var is accessed
<              * by the JSOP_GETLOCAL and JSOP_SETLOCAL ops, and iterated with
<              * JSOP_FORLOCAL.  These ops all have an immediate operand, the
<              * local slot's stack index from fp->spbase.
<              *
<              * The array comprehension iteration step, array.push(i * j) in
<              * the example above, is done by <i * j>; JSOP_ARRAYCOMP <array>,
<              * where <array> is the index of array's stack slot.
<              */
<             if (index == 0 &&
<                 pn->pn_count != 0 &&
<                 js_MatchToken(cx, ts, TOK_FOR)) {
<                 JSParseNode *pnexp, *pntop;
< 
<                 /* Relabel pn as an array comprehension node. */
<                 pn->pn_type = TOK_ARRAYCOMP;
< 
<                 /*
<                  * Remove the comprehension expression from pn's linked list
<                  * and save it via pnexp.  We'll re-install it underneath the
<                  * ARRAYPUSH node after we parse the rest of the comprehension.
<                  */
<                 pnexp = PN_LAST(pn);
<                 JS_ASSERT(pn->pn_count == 1 || pn->pn_count == 2);
<                 pn->pn_tail = (--pn->pn_count == 1)
<                               ? &pn->pn_head->pn_next
<                               : &pn->pn_head;
<                 *pn->pn_tail = NULL;
< 
<                 pntop = ComprehensionTail(cx, ts, tc, TOK_ARRAYPUSH,
<                                           JSOP_ARRAYPUSH, pnexp);
<                 if (!pntop)
<                     return NULL;
<                 PN_APPEND(pn, pntop);
<             }
< #endif /* JS_HAS_GENERATORS */
< 
5431,5435c3168
<       {
<         JSBool afterComma;
<         JSParseNode *pnval;
< 
<         pn = NewParseNode(cx, ts, PN_LIST, tc);
---
>         pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc);
5448,5462c3181,3183
<         afterComma = JS_FALSE;
<         for (;;) {
<             ts->flags |= TSF_KEYWORD_IS_NAME;
<             tt = js_GetToken(cx, ts);
<             ts->flags &= ~TSF_KEYWORD_IS_NAME;
<             switch (tt) {
<               case TOK_NUMBER:
<                 pn3 = NewParseNode(cx, ts, PN_NULLARY, tc);
<                 if (pn3)
<                     pn3->pn_dval = CURRENT_TOKEN(ts).t_dval;
<                 break;
<               case TOK_NAME:
< #if JS_HAS_GETTER_SETTER
<                 {
<                     JSAtom *atom;
---
>         if (!js_MatchToken(cx, ts, TOK_RC)) {
>             do {
>                 JSOp op;
5463a3185,3193
>                 tt = js_GetToken(cx, ts);
>                 switch (tt) {
>                   case TOK_NUMBER:
>                     pn3 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc);
>                     if (pn3)
>                         pn3->pn_dval = CURRENT_TOKEN(ts).t_dval;
>                     break;
>                   case TOK_NAME:
> #if JS_HAS_GETTER_SETTER
5465,5477c3195,3215
<                     if (atom == cx->runtime->atomState.getAtom)
<                         op = JSOP_GETTER;
<                     else if (atom == cx->runtime->atomState.setAtom)
<                         op = JSOP_SETTER;
<                     else
<                         goto property_name;
< 
<                     ts->flags |= TSF_KEYWORD_IS_NAME;
<                     tt = js_GetToken(cx, ts);
<                     ts->flags &= ~TSF_KEYWORD_IS_NAME;
<                     if (tt != TOK_NAME) {
<                         js_UngetToken(ts);
<                         goto property_name;
---
>                     rt = cx->runtime;
>                     if (atom == rt->atomState.getAtom ||
>                         atom == rt->atomState.setAtom) {
>                         op = (atom == rt->atomState.getAtom)
>                              ? JSOP_GETTER
>                              : JSOP_SETTER;
>                         if (js_MatchToken(cx, ts, TOK_NAME)) {
>                             pn3 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NAME,
>                                                tc);
>                             if (!pn3)
>                                 return NULL;
>                             pn3->pn_atom = CURRENT_TOKEN(ts).t_atom;
>                             pn3->pn_expr = NULL;
> 
>                             /* We have to fake a 'function' token here. */
>                             CURRENT_TOKEN(ts).t_op = JSOP_NOP;
>                             CURRENT_TOKEN(ts).type = TOK_FUNCTION;
>                             pn2 = FunctionExpr(cx, ts, tc);
>                             pn2 = NewBinary(cx, TOK_COLON, op, pn3, pn2, tc);
>                             goto skip;
>                         }
5479,5492c3217
<                     pn3 = NewParseNode(cx, ts, PN_NAME, tc);
<                     if (!pn3)
<                         return NULL;
<                     pn3->pn_atom = CURRENT_TOKEN(ts).t_atom;
<                     pn3->pn_slot = -1;
< 
<                     /* We have to fake a 'function' token here. */
<                     CURRENT_TOKEN(ts).t_op = JSOP_NOP;
<                     CURRENT_TOKEN(ts).type = TOK_FUNCTION;
<                     pn2 = FunctionExpr(cx, ts, tc);
<                     pn2 = NewBinary(cx, TOK_COLON, op, pn3, pn2, tc);
<                     goto skip;
<                 }
<               property_name:
---
>                     /* else fall thru ... */
5494,5504c3219,3228
<               case TOK_STRING:
<                 pn3 = NewParseNode(cx, ts, PN_NULLARY, tc);
<                 if (pn3)
<                     pn3->pn_atom = CURRENT_TOKEN(ts).t_atom;
<                 break;
<               case TOK_RC:
<                 if (afterComma &&
<                     !js_ReportCompileErrorNumber(cx, ts, NULL,
<                                                  JSREPORT_WARNING |
<                                                  JSREPORT_STRICT,
<                                                  JSMSG_TRAILING_COMMA)) {
---
>                   case TOK_STRING:
>                     pn3 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc);
>                     if (pn3)
>                         pn3->pn_atom = CURRENT_TOKEN(ts).t_atom;
>                     break;
>                   case TOK_RC:
>                     if (!js_ReportCompileErrorNumber(cx, ts, NULL,
>                                                      JSREPORT_WARNING |
>                                                      JSREPORT_STRICT,
>                                                      JSMSG_TRAILING_COMMA)) {
5505a3230,3235
>                     }
>                     goto end_obj_init;
>                   default:
>                     js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
>                                                 JSMSG_BAD_PROP_ID);
>                     return NULL;
5507,5512d3236
<                 goto end_obj_init;
<               default:
<                 js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                             JSMSG_BAD_PROP_ID);
<                 return NULL;
<             }
5514c3238
<             tt = js_GetToken(cx, ts);
---
>                 tt = js_GetToken(cx, ts);
5516,5525c3240,3244
<             if (tt == TOK_NAME) {
<                 tt = CheckGetterOrSetter(cx, ts, TOK_COLON);
<                 if (tt == TOK_ERROR)
<                     return NULL;
<             }
< #endif
< 
<             if (tt != TOK_COLON) {
< #if JS_HAS_DESTRUCTURING_SHORTHAND
<                 if (tt != TOK_COMMA && tt != TOK_RC) {
---
>                 if (tt == TOK_NAME) {
>                     tt = CheckGetterOrSetter(cx, ts, TOK_COLON);
>                     if (tt == TOK_ERROR)
>                         return NULL;
>                 }
5526a3246
>                 if (tt != TOK_COLON) {
5530,5544d3249
< #if JS_HAS_DESTRUCTURING_SHORTHAND
<                 }
< 
<                 /*
<                  * Support, e.g., |var {x, y} = o| as destructuring shorthand
<                  * for |var {x: x, y: y} = o|, per proposed JS2/ES4 for JS1.8.
<                  */
<                 js_UngetToken(ts);
<                 pn->pn_extra |= PNX_SHORTHAND;
<                 pnval = pn3;
<                 if (pnval->pn_type == TOK_NAME) {
<                     pnval->pn_arity = PN_NAME;
<                     pnval->pn_expr = NULL;
<                     pnval->pn_slot = -1;
<                     pnval->pn_const = JS_FALSE;
5546,5548d3250
<                 op = JSOP_NOP;
< #endif
<             } else {
5550,5553c3252,3253
<                 pnval = AssignExpr(cx, ts, tc);
<             }
< 
<             pn2 = NewBinary(cx, TOK_COLON, op, pn3, pnval, tc);
---
>                 pn2 = NewBinary(cx, TOK_COLON, op, pn3, AssignExpr(cx, ts, tc),
>                                 tc);
5555c3255
<           skip:
---
>               skip:
5557,5559c3257,3260
<             if (!pn2)
<                 return NULL;
<             PN_APPEND(pn, pn2);
---
>                 if (!pn2)
>                     return NULL;
>                 PN_APPEND(pn, pn2);
>             } while (js_MatchToken(cx, ts, TOK_COMMA));
5561,5569c3262
<             tt = js_GetToken(cx, ts);
<             if (tt == TOK_RC)
<                 goto end_obj_init;
<             if (tt != TOK_COMMA) {
<                 js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                             JSMSG_CURLY_AFTER_LIST);
<                 return NULL;
<             }
<             afterComma = JS_TRUE;
---
>             MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_LIST);
5571d3263
< 
5575,5583d3266
<       }
< 
< #if JS_HAS_BLOCK_SCOPE
<       case TOK_LET:
<         pn = LetBlock(cx, ts, tc, JS_FALSE);
<         if (!pn)
<             return NULL;
<         break;
< #endif
5589c3272
<         defsharp = NewParseNode(cx, ts, PN_UNARY, tc);
---
>         defsharp = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc);
5591a3275
>         defsharp->pn_kid = NULL;
5593,5595d3276
<         ts->flags |= TSF_OPERAND;
<         tt = js_GetToken(cx, ts);
<         ts->flags &= ~TSF_OPERAND;
5600c3281
<         pn = NewParseNode(cx, ts, PN_NULLARY, tc);
---
>         pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc);
5606a3288
> #endif /* JS_HAS_INITIALIZERS */
5610,5612c3292,3295
<         JSBool genexp;
< 
<         pn = NewParseNode(cx, ts, PN_UNARY, tc);
---
> #if JS_HAS_IN_OPERATOR
>         uintN oldflags;
> #endif
>         pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc);
5615c3298,3310
<         pn2 = ParenExpr(cx, ts, tc, pn, &genexp);
---
> #if JS_HAS_IN_OPERATOR
>         /*
>          * Always accept the 'in' operator in a parenthesized expression,
>          * where it's unambiguous, even if we might be parsing the init of a
>          * for statement.
>          */
>         oldflags = tc->flags;
>         tc->flags &= ~TCF_IN_FOR_INIT;
> #endif
>         pn2 = Expr(cx, ts, tc);
> #if JS_HAS_IN_OPERATOR
>         tc->flags = oldflags | (tc->flags & TCF_FUN_FLAGS);
> #endif
5618,5619d3312
<         if (genexp)
<             return pn2;
5622,5642c3315
<         if (pn2->pn_type == TOK_RP ||
<             (js_CodeSpec[pn2->pn_op].prec >= js_CodeSpec[JSOP_GETPROP].prec &&
<              !afterDot)) {
<             /*
<              * Avoid redundant JSOP_GROUP opcodes, for efficiency and mainly
<              * to help the decompiler look ahead from a JSOP_ENDINIT to see a
<              * JSOP_GROUP followed by a POP or POPV.  That sequence means the
<              * parentheses are mandatory, to disambiguate object initialisers
<              * as expression statements from block statements.
<              *
<              * Also drop pn if pn2 is a member or a primary expression of any
<              * kind.  This is required to avoid generating a JSOP_GROUP that
<              * will null the |obj| interpreter register, causing |this| in any
<              * call of that member expression to bind to the global object.
<              */
<             RecycleTree(pn, tc);
<             pn = pn2;
<         } else {
<             pn->pn_type = TOK_RP;
<             pn->pn_kid = pn2;
<         }
---
>         pn->pn_type = TOK_RP;
5643a3317
>         pn->pn_kid = pn2;
5647,5669d3320
< #if JS_HAS_XML_SUPPORT
<       case TOK_STAR:
<         pn = QualifiedIdentifier(cx, ts, tc);
<         if (!pn)
<             return NULL;
<         notsharp = JS_TRUE;
<         break;
< 
<       case TOK_AT:
<         pn = AttributeIdentifier(cx, ts, tc);
<         if (!pn)
<             return NULL;
<         notsharp = JS_TRUE;
<         break;
< 
<       case TOK_XMLSTAGO:
<         pn = XMLElementOrListRoot(cx, ts, tc, JS_TRUE);
<         if (!pn)
<             return NULL;
<         notsharp = JS_TRUE;     /* XXXbe could be sharp? */
<         break;
< #endif /* JS_HAS_XML_SUPPORT */
< 
5673,5679d3323
<         /* FALL THROUGH */
< #endif
< 
< #if JS_HAS_XML_SUPPORT
<       case TOK_XMLCDATA:
<       case TOK_XMLCOMMENT:
<       case TOK_XMLPI:
5680a3325
>         /* FALL THROUGH */
5682c3327,3328
<         pn = NewParseNode(cx, ts, PN_NULLARY, tc);
---
>       case TOK_OBJECT:
>         pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc);
5684a3331
>         pn->pn_op = CURRENT_TOKEN(ts).t_op;
5686,5691d3332
< #if JS_HAS_XML_SUPPORT
<         if (tt == TOK_XMLPI)
<             pn->pn_atom2 = CURRENT_TOKEN(ts).t_atom2;
<         else
< #endif
<             pn->pn_op = CURRENT_TOKEN(ts).t_op;
5693a3335
>             pn->pn_expr = NULL;
5695,5725c3337
< 
< #if JS_HAS_XML_SUPPORT
<             if (js_MatchToken(cx, ts, TOK_DBLCOLON)) {
<                 if (afterDot) {
<                     JSString *str;
< 
<                     /*
<                      * Here PrimaryExpr is called after '.' or '..' and we
<                      * just scanned .name:: or ..name:: . This is the only
<                      * case where a keyword after '.' or '..' is not
<                      * treated as a property name.
<                      */
<                     str = ATOM_TO_STRING(pn->pn_atom);
<                     tt = js_CheckKeyword(JSSTRING_CHARS(str),
<                                          JSSTRING_LENGTH(str));
<                     if (tt == TOK_FUNCTION) {
<                         pn->pn_arity = PN_NULLARY;
<                         pn->pn_type = TOK_FUNCTION;
<                     } else if (tt != TOK_EOF) {
<                         js_ReportCompileErrorNumber(
<                             cx, ts, NULL, JSREPORT_ERROR,
<                             JSMSG_KEYWORD_NOT_NS);
<                         return NULL;
<                     }
<                 }
<                 pn = QualifiedSuffix(cx, ts, pn, tc);
<                 if (!pn)
<                     return NULL;
<                 break;
<             }
< #endif
---
>             pn->pn_attrs = 0;
5731,5745d3342
<             } else if (!(tc->flags & TCF_IN_FUNCTION)) {
<                 JSAtomListElement *ale;
<                 JSStackFrame *fp;
<                 JSBool loopy;
< 
<                 /* Measure optimizable global variable uses. */
<                 ATOM_LIST_SEARCH(ale, &tc->decls, pn->pn_atom);
<                 if (ale &&
<                     !(fp = cx->fp)->fun &&
<                     fp->scopeChain == fp->varobj &&
<                     js_IsGlobalReference(tc, pn->pn_atom, &loopy)) {
<                     tc->globalUses++;
<                     if (loopy)
<                         tc->loopyGlobalUses++;
<                 }
5750,5778d3346
<       case TOK_REGEXP:
<       {
<         JSObject *obj;
< 
<         pn = NewParseNode(cx, ts, PN_NULLARY, tc);
<         if (!pn)
<             return NULL;
< 
<         /* Token stream ensures that tokenbuf is NUL-terminated. */
<         JS_ASSERT(*ts->tokenbuf.ptr == (jschar) 0);
<         obj = js_NewRegExpObject(cx, ts,
<                                  ts->tokenbuf.base,
<                                  ts->tokenbuf.ptr - ts->tokenbuf.base,
<                                  CURRENT_TOKEN(ts).t_reflags);
<         if (!obj)
<             return NULL;
<         if (!(tc->flags & TCF_COMPILE_N_GO)) {
<             STOBJ_SET_PARENT(obj, NULL);
<             STOBJ_SET_PROTO(obj, NULL);
<         }
< 
<         pn->pn_pob = js_NewParsedObjectBox(cx, tc->parseContext, obj);
<         if (!pn->pn_pob)
<             return NULL;
< 
<         pn->pn_op = JSOP_REGEXP;
<         break;
<       }
< 
5780c3348
<         pn = NewParseNode(cx, ts, PN_NULLARY, tc);
---
>         pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc);
5790c3358
<         pn = NewParseNode(cx, ts, PN_NULLARY, tc);
---
>         pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc);
5802a3371,3379
>       case TOK_RESERVED:
>         badWord = js_DeflateString(cx, CURRENT_TOKEN(ts).ptr,
>                                    (size_t) CURRENT_TOKEN(ts).pos.end.index
>                                           - CURRENT_TOKEN(ts).pos.begin.index);
>         js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
>                                     JSMSG_RESERVED_ID, badWord);
>         JS_free(cx, badWord);
>         return NULL;
> 
5827,5830c3404,3406
< 
< static JSParseNode *
< ParenExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
<           JSParseNode *pn1, JSBool *genexp)
---
> #endif //#ifdef _UTF8
> static JSBool
> ContainsVarStmt(JSParseNode *pn)
5832,5839c3408
<     JSTokenPtr begin;
<     JSParseNode *pn;
< #if JS_HAS_GENERATOR_EXPRS
<     uintN oldflags = tc->flags;
< #endif
< 
<     JS_ASSERT(CURRENT_TOKEN(ts).type == TOK_LP);
<     begin = CURRENT_TOKEN(ts).pos.begin;
---
>     JSParseNode *pn2;
5841,5843d3409
<     if (genexp)
<         *genexp = JS_FALSE;
<     pn = BracketedExpr(cx, ts, tc);
5845,5878c3411,3418
<         return NULL;
< 
< #if JS_HAS_GENERATOR_EXPRS
<     if (js_MatchToken(cx, ts, TOK_FOR)) {
<         if (pn->pn_type == TOK_YIELD) {
<             js_ReportCompileErrorNumber(cx, ts, pn, JSREPORT_ERROR,
<                                         JSMSG_BAD_GENERATOR_SYNTAX,
<                                         js_yield_str);
<             return NULL;
<         }
<         if (pn->pn_type == TOK_COMMA) {
<             js_ReportCompileErrorNumber(cx, ts, PN_LAST(pn), JSREPORT_ERROR,
<                                         JSMSG_BAD_GENERATOR_SYNTAX,
<                                         js_generator_str);
<             return NULL;
<         }
<         if (!pn1) {
<             pn1 = NewParseNode(cx, ts, PN_UNARY, tc);
<             if (!pn1)
<                 return NULL;
<         }
<         pn->pn_pos.begin = begin;
<         pn = GeneratorExpr(cx, ts, tc, oldflags, pn1, pn);
<         if (!pn)
<             return NULL;
<         if (genexp) {
<             if (js_GetToken(cx, ts) != TOK_RP) {
<                 js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
<                                             JSMSG_BAD_GENERATOR_SYNTAX,
<                                             js_generator_str);
<                 return NULL;
<             }
<             pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
<             *genexp = JS_TRUE;
---
>         return JS_FALSE;
>     switch (pn->pn_arity) {
>       case PN_LIST:
>         if (pn->pn_type == TOK_VAR)
>             return JS_TRUE;
>         for (pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) {
>             if (ContainsVarStmt(pn2))
>                 return JS_TRUE;
5879a3420,3437
>         break;
>       case PN_TERNARY:
>         return ContainsVarStmt(pn->pn_kid1) ||
>                ContainsVarStmt(pn->pn_kid2) ||
>                ContainsVarStmt(pn->pn_kid3);
>       case PN_BINARY:
>         /*
>          * Limit recursion if pn is a binary expression, which can't contain a
>          * var statement.
>          */
>         if (pn->pn_op != JSOP_NOP)
>             return JS_FALSE;
>         return ContainsVarStmt(pn->pn_left) || ContainsVarStmt(pn->pn_right);
>       case PN_UNARY:
>         if (pn->pn_op != JSOP_NOP)
>             return JS_FALSE;
>         return ContainsVarStmt(pn->pn_kid);
>       default:;
5881,5883c3439
< #endif /* JS_HAS_GENERATOR_EXPRS */
< 
<     return pn;
---
>     return JS_FALSE;
5902c3458
<                 pn->pn_op = JSOP_DOUBLE;
---
>                 pn->pn_op = JSOP_NUMBER;
5935a3492
>     uint32 u;
5943,5944c3500,3503
<         i = js_DoubleToECMAInt32(d);
<         j = js_DoubleToECMAInt32(d2);
---
>         if (!js_DoubleToECMAInt32(cx, d, &i))
>             return JS_FALSE;
>         if (!js_DoubleToECMAInt32(cx, d2, &j))
>             return JS_FALSE;
5950c3509,3512
<         j = js_DoubleToECMAInt32(d2);
---
>         if (!js_DoubleToECMAUint32(cx, d, &u))
>             return JS_FALSE;
>         if (!js_DoubleToECMAInt32(cx, d2, &j))
>             return JS_FALSE;
5952c3514
<         d = js_DoubleToECMAUint32(d) >> j;
---
>         d = u >> j;
5969c3531
< #if defined(XP_WIN)
---
> #if defined(XP_WIN) || defined(XP_OS2)
5990c3552
< #if defined(XP_WIN)
---
> #if defined(XP_WIN) || defined(XP_OS2)
6007c3569
<     pn->pn_op = JSOP_DOUBLE;
---
>     pn->pn_op = JSOP_NUMBER;
6013,6207d3574
< #if JS_HAS_XML_SUPPORT
< 
< static JSBool
< FoldXMLConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc)
< {
<     JSTokenType tt;
<     JSParseNode **pnp, *pn1, *pn2;
<     JSString *accum, *str;
<     uint32 i, j;
< 
<     JS_ASSERT(pn->pn_arity == PN_LIST);
<     tt = PN_TYPE(pn);
<     pnp = &pn->pn_head;
<     pn1 = *pnp;
<     accum = NULL;
<     if ((pn->pn_extra & PNX_CANTFOLD) == 0) {
<         if (tt == TOK_XMLETAGO)
<             accum = ATOM_TO_STRING(cx->runtime->atomState.etagoAtom);
<         else if (tt == TOK_XMLSTAGO || tt == TOK_XMLPTAGC)
<             accum = ATOM_TO_STRING(cx->runtime->atomState.stagoAtom);
<     }
< 
<     for (pn2 = pn1, i = j = 0; pn2; pn2 = pn2->pn_next, i++) {
<         /* The parser already rejected end-tags with attributes. */
<         JS_ASSERT(tt != TOK_XMLETAGO || i == 0);
<         switch (pn2->pn_type) {
<           case TOK_XMLATTR:
<             if (!accum)
<                 goto cantfold;
<             /* FALL THROUGH */
<           case TOK_XMLNAME:
<           case TOK_XMLSPACE:
<           case TOK_XMLTEXT:
<           case TOK_STRING:
<             if (pn2->pn_arity == PN_LIST)
<                 goto cantfold;
<             str = ATOM_TO_STRING(pn2->pn_atom);
<             break;
< 
<           case TOK_XMLCDATA:
<             str = js_MakeXMLCDATAString(cx, ATOM_TO_STRING(pn2->pn_atom));
<             if (!str)
<                 return JS_FALSE;
<             break;
< 
<           case TOK_XMLCOMMENT:
<             str = js_MakeXMLCommentString(cx, ATOM_TO_STRING(pn2->pn_atom));
<             if (!str)
<                 return JS_FALSE;
<             break;
< 
<           case TOK_XMLPI:
<             str = js_MakeXMLPIString(cx, ATOM_TO_STRING(pn2->pn_atom),
<                                          ATOM_TO_STRING(pn2->pn_atom2));
<             if (!str)
<                 return JS_FALSE;
<             break;
< 
<           cantfold:
<           default:
<             JS_ASSERT(*pnp == pn1);
<             if ((tt == TOK_XMLSTAGO || tt == TOK_XMLPTAGC) &&
<                 (i & 1) ^ (j & 1)) {
< #ifdef DEBUG_brendanXXX
<                 printf("1: %d, %d => ", i, j);
<                 if (accum)
<                     js_FileEscapedString(stdout, accum, 0);
<                 else
<                     fputs("NULL", stdout);
<                 fputc('\n', stdout);
< #endif
<             } else if (accum && pn1 != pn2) {
<                 while (pn1->pn_next != pn2) {
<                     pn1 = RecycleTree(pn1, tc);
<                     --pn->pn_count;
<                 }
<                 pn1->pn_type = TOK_XMLTEXT;
<                 pn1->pn_op = JSOP_STRING;
<                 pn1->pn_arity = PN_NULLARY;
<                 pn1->pn_atom = js_AtomizeString(cx, accum, 0);
<                 if (!pn1->pn_atom)
<                     return JS_FALSE;
<                 JS_ASSERT(pnp != &pn1->pn_next);
<                 *pnp = pn1;
<             }
<             pnp = &pn2->pn_next;
<             pn1 = *pnp;
<             accum = NULL;
<             continue;
<         }
< 
<         if (accum) {
<             str = ((tt == TOK_XMLSTAGO || tt == TOK_XMLPTAGC) && i != 0)
<                   ? js_AddAttributePart(cx, i & 1, accum, str)
<                   : js_ConcatStrings(cx, accum, str);
<             if (!str)
<                 return JS_FALSE;
< #ifdef DEBUG_brendanXXX
<             printf("2: %d, %d => ", i, j);
<             js_FileEscapedString(stdout, str, 0);
<             printf(" (%u)\n", JSSTRING_LENGTH(str));
< #endif
<             ++j;
<         }
<         accum = str;
<     }
< 
<     if (accum) {
<         str = NULL;
<         if ((pn->pn_extra & PNX_CANTFOLD) == 0) {
<             if (tt == TOK_XMLPTAGC)
<                 str = ATOM_TO_STRING(cx->runtime->atomState.ptagcAtom);
<             else if (tt == TOK_XMLSTAGO || tt == TOK_XMLETAGO)
<                 str = ATOM_TO_STRING(cx->runtime->atomState.tagcAtom);
<         }
<         if (str) {
<             accum = js_ConcatStrings(cx, accum, str);
<             if (!accum)
<                 return JS_FALSE;
<         }
< 
<         JS_ASSERT(*pnp == pn1);
<         while (pn1->pn_next) {
<             pn1 = RecycleTree(pn1, tc);
<             --pn->pn_count;
<         }
<         pn1->pn_type = TOK_XMLTEXT;
<         pn1->pn_op = JSOP_STRING;
<         pn1->pn_arity = PN_NULLARY;
<         pn1->pn_atom = js_AtomizeString(cx, accum, 0);
<         if (!pn1->pn_atom)
<             return JS_FALSE;
<         JS_ASSERT(pnp != &pn1->pn_next);
<         *pnp = pn1;
<     }
< 
<     if (pn1 && pn->pn_count == 1) {
<         /*
<          * Only one node under pn, and it has been folded: move pn1 onto pn
<          * unless pn is an XML root (in which case we need it to tell the code
<          * generator to emit a JSOP_TOXML or JSOP_TOXMLLIST op).  If pn is an
<          * XML root *and* it's a point-tag, rewrite it to TOK_XMLELEM to avoid
<          * extra "<" and "/>" bracketing at runtime.
<          */
<         if (!(pn->pn_extra & PNX_XMLROOT)) {
<             PN_MOVE_NODE(pn, pn1);
<         } else if (tt == TOK_XMLPTAGC) {
<             pn->pn_type = TOK_XMLELEM;
<             pn->pn_op = JSOP_TOXML;
<         }
<     }
<     return JS_TRUE;
< }
< 
< #endif /* JS_HAS_XML_SUPPORT */
< 
< static JSBool
< StartsWith(JSParseNode *pn, JSTokenType tt)
< {
< #define TAIL_RECURSE(pn2) JS_BEGIN_MACRO pn = (pn2); goto recur; JS_END_MACRO
< 
< recur:
<     if (pn->pn_type == tt)
<         return JS_TRUE;
<     switch (pn->pn_arity) {
<       case PN_FUNC:
<         return  tt == TOK_FUNCTION;
<       case PN_LIST:
<         if (pn->pn_head)
<             TAIL_RECURSE(pn->pn_head);
<         break;
<       case PN_TERNARY:
<         if (pn->pn_kid1)
<             TAIL_RECURSE(pn->pn_kid1);
<         break;
<       case PN_BINARY:
<         if (pn->pn_left)
<             TAIL_RECURSE(pn->pn_left);
<         break;
<       case PN_UNARY:
<         /* A parenthesized expression starts with a left parenthesis. */
<         if (pn->pn_type == TOK_RP)
<             return tt == TOK_LP;
<         if (pn->pn_kid)
<             TAIL_RECURSE(pn->pn_kid);
<         break;
<       case PN_NAME:
<         if (pn->pn_type == TOK_DOT || pn->pn_type == TOK_DBLDOT)
<             TAIL_RECURSE(pn->pn_expr);
<         /* FALL THROUGH */
<     }
<     return JS_FALSE;
< #undef TAIL_RECURSE
< }
< 
6213,6214d3579
<     JS_CHECK_RECURSION(cx, return JS_FALSE);
< 
6217,6220d3581
<       {
<         uint16 oldflags = tc->flags;
< 
<         tc->flags = (uint16) pn->pn_flags;
6223d3583
<         tc->flags = oldflags;
6225d3584
<       }
6228,6271d3586
< #if 0 /* JS_HAS_XML_SUPPORT */
<         switch (pn->pn_type) {
<           case TOK_XMLELEM:
<           case TOK_XMLLIST:
<           case TOK_XMLPTAGC:
<             /*
<              * Try to fold this XML parse tree once, from the top down, into
<              * a JSXML tree with just one object wrapping the tree root.
<              *
<              * Certain subtrees could be folded similarly, but we'd have to
<              * ensure that none used namespace prefixes declared elsewhere in
<              * its super-tree, and we would have to convert each XML object
<              * created at runtime for such sub-trees back into a string, and
<              * concatenate and re-parse anyway.
<              */
<             if ((pn->pn_extra & (PNX_XMLROOT | PNX_CANTFOLD)) == PNX_XMLROOT &&
<                 !(tc->flags & TCF_HAS_DEFXMLNS)) {
<                 JSObject *obj;
<                 JSParsedObjectBox *xmlpob;
< 
<                 obj = js_ParseNodeToXMLObject(cx, pn);
<                 if (!obj)
<                     return JS_FALSE;
<                 xmlpob = js_NewParsedObjectBox(cx, ts, obj);
<                 if (!xmlpob)
<                     return JS_FALSE;
<                 pn->pn_op = JSOP_XMLOBJECT;
<                 pn->pn_arity = PN_NULLARY;
<                 pn->pn_pob = xmlpob;
<                 return JS_TRUE;
<             }
< 
<             /*
<              * Can't fold from parse node to XML tree -- try folding strings
<              * as much as possible, and folding XML sub-trees bottom up to
<              * minimize string concatenation and ToXML/ToXMLList operations
<              * at runtime.
<              */
<             break;
< 
<           default:;
<         }
< #endif
< 
6329c3644
<         if (ContainsStmt(pn2, TOK_VAR) || ContainsStmt(pn3, TOK_VAR))
---
>         if (ContainsVarStmt(pn2) || ContainsVarStmt(pn3))
6335,6336d3649
<         while (pn1->pn_type == TOK_RP)
<             pn1 = pn1->pn_kid;
6339c3652
<             if (pn1->pn_dval == 0 || JSDOUBLE_IS_NaN(pn1->pn_dval))
---
>             if (pn1->pn_dval == 0)
6359,6364d3671
< #if JS_HAS_GENERATOR_EXPRS
<         /* Don't fold a trailing |if (0)| in a generator expression. */
<         if (!pn2 && (tc->flags & TCF_GENEXP_LAMBDA))
<             break;
< #endif
< 
6366,6390c3673,3679
<             /*
<              * pn2 is the then- or else-statement subtree to compile.  Take
<              * care not to expose an object initialiser, which would be parsed
<              * as a block, to the Statement parser via eval(uneval(e)) where e
<              * is '1 ? {p:2, q:3}[i] : r;' or the like.
<              */
<             if (pn->pn_type == TOK_HOOK && StartsWith(pn2, TOK_RC)) {
<                 pn->pn_type = TOK_RP;
<                 pn->pn_arity = PN_UNARY;
<                 pn->pn_kid = pn2;
<             } else {
<                 PN_MOVE_NODE(pn, pn2);
<             }
<         }
<         if (!pn2 || (pn->pn_type == TOK_SEMI && !pn->pn_kid)) {
<             /*
<              * False condition and no else, or an empty then-statement was
<              * moved up over pn.  Either way, make pn an empty block (not an
<              * empty statement, which does not decompile, even when labeled).
<              * NB: pn must be a TOK_IF as TOK_HOOK can never have a null kid
<              * or an empty statement for a child.
<              */
<             pn->pn_type = TOK_LC;
<             pn->pn_arity = PN_LIST;
<             PN_INIT_LIST(pn);
---
>             /* pn2 is the then- or else-statement subtree to compile. */
>             PN_MOVE_NODE(pn, pn2);
>         } else {
>             /* False condition and no else: make pn an empty statement. */
>             pn->pn_type = TOK_SEMI;
>             pn->pn_arity = PN_UNARY;
>             pn->pn_kid = NULL;
6397,6409d3685
<       case TOK_ASSIGN:
<         /*
<          * Compound operators such as *= should be subject to folding, in case
<          * the left-hand side is constant, and so that the decompiler produces
<          * the same string that you get from decompiling a script or function
<          * compiled from that same string.  As with +, += is special.
<          */
<         if (pn->pn_op == JSOP_NOP)
<             break;
<         if (pn->pn_op != JSOP_ADD)
<             goto do_binary_op;
<         /* FALL THROUGH */
< 
6435c3711
<                 length += JSFLATSTR_LENGTH(ATOM_TO_STRING(pn2->pn_atom));
---
>                 length += ATOM_TO_STRING(pn2->pn_atom)->length;
6438a3715
>             XMEMTAG("jsparse TOK_PLUS");
6442c3719
<             str = js_NewString(cx, chars, length);
---
>             str = js_NewString(cx, chars, length, 0);
6449c3726
<             for (pn2 = pn1; pn2; pn2 = RecycleTree(pn2, tc)) {
---
>             for (pn2 = pn1; pn2; pn2 = pn3) {
6451,6452c3728,3729
<                 length2 = JSFLATSTR_LENGTH(str2);
<                 js_strncpy(chars, JSFLATSTR_CHARS(str2), length2);
---
>                 length2 = str2->length;
>                 js_strncpy(chars, str2->chars, length2);
6453a3731,3732
>                 pn3 = pn2->pn_next;
>                 RecycleTree(pn2, tc);
6512,6513d3790
<             }
<             for (pn2 = pn1; pn2; pn2 = pn2->pn_next) {
6519c3796
<                 JSOp op = PN_OP(pn);
---
>                 JSOp op = pn->pn_op;
6538c3815
<                 if (!FoldBinaryNumeric(cx, PN_OP(pn), pn1, pn2, pn, tc))
---
>                 if (!FoldBinaryNumeric(cx, pn->pn_op, pn1, pn2, pn, tc))
6545,6546d3821
<         while (pn1->pn_type == TOK_RP)
<             pn1 = pn1->pn_kid;
6548a3824
>             int32 i;
6554c3830,3832
<                 d = ~js_DoubleToECMAInt32(d);
---
>                 if (!js_DoubleToECMAInt32(cx, d, &i))
>                     return JS_FALSE;
>                 d = ~i;
6575c3853
<                 pn->pn_op = (d == 0 || JSDOUBLE_IS_NaN(d)) ? JSOP_TRUE : JSOP_FALSE;
---
>                 pn->pn_op = (d == 0) ? JSOP_TRUE : JSOP_FALSE;
6584c3862
<             pn->pn_op = JSOP_DOUBLE;
---
>             pn->pn_op = JSOP_NUMBER;
6591,6628d3868
< #if JS_HAS_XML_SUPPORT
<       case TOK_XMLELEM:
<       case TOK_XMLLIST:
<       case TOK_XMLPTAGC:
<       case TOK_XMLSTAGO:
<       case TOK_XMLETAGO:
<       case TOK_XMLNAME:
<         if (pn->pn_arity == PN_LIST) {
<             JS_ASSERT(pn->pn_type == TOK_XMLLIST || pn->pn_count != 0);
<             if (!FoldXMLConstants(cx, pn, tc))
<                 return JS_FALSE;
<         }
<         break;
< 
<       case TOK_AT:
<         if (pn1->pn_type == TOK_XMLNAME) {
<             jsval v;
<             JSParsedObjectBox *xmlpob;
< 
<             v = ATOM_KEY(pn1->pn_atom);
<             if (!js_ToAttributeName(cx, &v))
<                 return JS_FALSE;
<             JS_ASSERT(!JSVAL_IS_PRIMITIVE(v));
< 
<             xmlpob = js_NewParsedObjectBox(cx, tc->parseContext,
<                                            JSVAL_TO_OBJECT(v));
<             if (!xmlpob)
<                 return JS_FALSE;
< 
<             pn->pn_type = TOK_XMLNAME;
<             pn->pn_op = JSOP_OBJECT;
<             pn->pn_arity = PN_NULLARY;
<             pn->pn_pob = xmlpob;
<             RecycleTree(pn1, tc);
<         }
<         break;
< #endif /* JS_HAS_XML_SUPPORT */
< 
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsparse.h /Volumes/Swap/js_D11/src/jsparse.h
2d1
<  * vim: set ts=8 sw=4 et tw=78:
4,15c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
20,39c16,33
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
46d39
< #include "jsconfig.h"
64,67c57,60
<  * TOK_FUNCTION func        pn_funpob: JSParsedObjectBox holding function
<  *                            object containing arg and var properties.  We
<  *                            create the function object at parse (not emit)
<  *                            time to specialize arg and var bytecodes early.
---
>  * TOK_FUNCTION func        pn_fun: function, contains arg and var properties
>  *                            NB: We create the function object at parse (not
>  *                            emit) time, in order to specialize arg and var
>  *                            bytecodes early.
71c64
<  *                          pn_sclen: maximum lexical scope chain length
---
>  *                          pn_tryCount: of try statements in function
85,88c78
<  *                            TOK_DEFAULT node, or if there are let bindings
<  *                            in the top level of the switch body's cases, a
<  *                            TOK_LEXICALSCOPE node that contains the list of
<  *                            TOK_CASE nodes.
---
>  *                            TOK_DEFAULT node
91d80
<  *                          pn_val: constant value if lookup or table switch
97,98d85
<  *                                if TOK_VAR, its pn_extra may have PNX_POPVAR
<  *                                and PNX_FORINVAR bits set
108,114c95,99
<  *                          pn_kid2: null or TOK_RESERVED list of
<  *                          TOK_LEXICALSCOPE nodes, each with pn_expr pointing
<  *                          to a TOK_CATCH node
<  *                          pn_kid3: null or finally block
<  * TOK_CATCH    ternary     pn_kid1: TOK_NAME, TOK_RB, or TOK_RC catch var node
<  *                                   (TOK_RB or TOK_RC if destructuring)
<  *                          pn_kid2: null or the catch guard expression
---
>  *                          pn_kid2: catch blocks or null
>  *                          pn_kid3: finally block or null
>  * TOK_CATCH    ternary     pn_kid1: PN_NAME node for catch var (with pn_expr
>  *                                   null or the catch guard expression)
>  *                          pn_kid2: more catch blocks or null
140,141c125
<  *                          pn_op: JSOP_EQ, JSOP_NE,
<  *                                 JSOP_STRICTEQ, JSOP_STRICTNE
---
>  *                          pn_op: JSOP_EQ, JSOP_NE, JSOP_NEW_EQ, JSOP_NEW_NE
166,167c150,151
<  * TOK_DOT,     name        pn_expr: MEMBER expr to left of .
<  * TOK_DBLDOT               pn_atom: name to right of .
---
>  * TOK_DOT      name        pn_expr: MEMBER expr to left of .
>  *                          pn_atom: name to right of .
176c160
<  *                          pn_extra: PN_ENDCOMMA if extra comma at end
---
>  *                          pn_extra: true if extra comma at end
180,182d163
<  *                          var {x} = object destructuring shorthand shares
<  *                          PN_NAME node for x on left and right of TOK_COLON
<  *                          node in TOK_RC's list, has PNX_SHORTHAND flag
190,193c171,173
<  * TOK_STRING,              pn_op: JSOP_NAME, JSOP_STRING, or JSOP_OBJECT, or
<  *                                 JSOP_REGEXP
<  * TOK_REGEXP               If JSOP_NAME, pn_op may be JSOP_*ARG or JSOP_*VAR
<  *                          with pn_slot >= 0 and pn_const telling const-ness
---
>  * TOK_STRING,              pn_op: JSOP_NAME, JSOP_STRING, or JSOP_OBJECT
>  * TOK_OBJECT               If JSOP_NAME, pn_op may be JSOP_*ARG or JSOP_*VAR
>  *                          with pn_slot >= 0 and pn_attrs telling const-ness
196,264d175
<  *
<  * <E4X node descriptions>
<  * TOK_ANYNAME  nullary     pn_op: JSOP_ANYNAME
<  *                          pn_atom: cx->runtime->atomState.starAtom
<  * TOK_AT       unary       pn_op: JSOP_TOATTRNAME; pn_kid attribute id/expr
<  * TOK_DBLCOLON binary      pn_op: JSOP_QNAME
<  *                          pn_left: TOK_ANYNAME or TOK_NAME node
<  *                          pn_right: TOK_STRING "*" node, or expr within []
<  *              name        pn_op: JSOP_QNAMECONST
<  *                          pn_expr: TOK_ANYNAME or TOK_NAME left operand
<  *                          pn_atom: name on right of ::
<  * TOK_XMLELEM  list        XML element node
<  *                          pn_head: start tag, content1, ... contentN, end tag
<  *                          pn_count: 2 + N where N is number of content nodes
<  *                                    N may be > x.length() if {expr} embedded
<  * TOK_XMLLIST  list        XML list node
<  *                          pn_head: content1, ... contentN
<  * TOK_XMLSTAGO, list       XML start, end, and point tag contents
<  * TOK_XMLETAGC,            pn_head: tag name or {expr}, ... XML attrs ...
<  * TOK_XMLPTAGO
<  * TOK_XMLNAME  nullary     pn_atom: XML name, with no {expr} embedded
<  * TOK_XMLNAME  list        pn_head: tag name or {expr}, ... name or {expr}
<  * TOK_XMLATTR, nullary     pn_atom: attribute value string; pn_op: JSOP_STRING
<  * TOK_XMLCDATA,
<  * TOK_XMLCOMMENT
<  * TOK_XMLPI    nullary     pn_atom: XML processing instruction target
<  *                          pn_atom2: XML PI content, or null if no content
<  * TOK_XMLTEXT  nullary     pn_atom: marked-up text, or null if empty string
<  * TOK_LC       unary       {expr} in XML tag or content; pn_kid is expr
<  *
<  * So an XML tag with no {expr} and three attributes is a list with the form:
<  *
<  *    (tagname attrname1 attrvalue1 attrname2 attrvalue2 attrname2 attrvalue3)
<  *
<  * An XML tag with embedded expressions like so:
<  *
<  *    <name1{expr1} name2{expr2}name3={expr3}>
<  *
<  * would have the form:
<  *
<  *    ((name1 {expr1}) (name2 {expr2} name3) {expr3})
<  *
<  * where () bracket a list with elements separated by spaces, and {expr} is a
<  * TOK_LC unary node with expr as its kid.
<  *
<  * Thus, the attribute name/value pairs occupy successive odd and even list
<  * locations, where pn_head is the TOK_XMLNAME node at list location 0.  The
<  * parser builds the same sort of structures for elements:
<  *
<  *    <a x={x}>Hi there!<b y={y}>How are you?</b><answer>{x + y}</answer></a>
<  *
<  * translates to:
<  *
<  *    ((a x {x}) 'Hi there!' ((b y {y}) 'How are you?') ((answer) {x + y}))
<  *
<  * <Non-E4X node descriptions, continued>
<  *
<  * Label              Variant   Members
<  * -----              -------   -------
<  * TOK_LEXICALSCOPE   name      pn_op: JSOP_LEAVEBLOCK or JSOP_LEAVEBLOCKEXPR
<  *                              pn_pob: block object
<  *                              pn_expr: block body
<  * TOK_ARRAYCOMP      list      pn_head: list of pn_count (1 or 2) elements
<  *                              if pn_count is 2, first element is #n=[...]
<  *                                last element is block enclosing for loop(s)
<  *                                and optionally if-guarded TOK_ARRAYPUSH
<  *                              pn_extra: stack slot, used during code gen
<  * TOK_ARRAYPUSH      unary     pn_op: JSOP_ARRAYCOMP
<  *                              pn_kid: array comprehension expression
277,279c188
<     uint16              pn_type;
<     uint8               pn_op;
<     int8                pn_arity;
---
>     JSTokenType         pn_type;
280a190
>     JSOp                pn_op;
281a192
>     JSParseNodeArity    pn_arity;
283,329c194,226
<         struct {                        /* TOK_FUNCTION node */
<             JSParsedObjectBox *funpob;  /* function object */
<             JSParseNode *body;          /* TOK_LC list of statements */
<             uint16      flags;          /* accumulated tree context flags */
<             uint16      sclen;          /* maximum scope chain length */
<             uint32      index;          /* emitter's index */
<         } func;
<         struct {                        /* list of next-linked nodes */
<             JSParseNode *head;          /* first node in list */
<             JSParseNode **tail;         /* ptr to ptr to last node in list */
<             uint32      count;          /* number of nodes in list */
<             uint32      extra;          /* extra flags, see below */
<         } list;
<         struct {                        /* ternary: if, for(;;), ?: */
<             JSParseNode *kid1;          /* condition, discriminant, etc. */
<             JSParseNode *kid2;          /* then-part, case list, etc. */
<             JSParseNode *kid3;          /* else-part, default case, etc. */
<         } ternary;
<         struct {                        /* two kids if binary */
<             JSParseNode *left;
<             JSParseNode *right;
<             jsval       val;            /* switch case value */
<         } binary;
<         struct {                        /* one kid if unary */
<             JSParseNode *kid;
<             jsint       num;            /* -1 or sharp variable number */
<             JSBool      hidden;         /* hidden genexp-induced JSOP_YIELD */
<         } unary;
<         struct {                        /* name, labeled statement, etc. */
<             JSAtom      *atom;          /* name or label atom, null if slot */
<             JSParseNode *expr;          /* object or initializer */
<             jsint       slot;           /* -1 or arg or local var slot */
<             JSBool      isconst;        /* true for const names */
<         } name;
<         struct {                        /* lexical scope. */
<             JSParsedObjectBox *pob;     /* block object */
<             JSParseNode *expr;          /* object or initializer */
<             jsint       slot;           /* -1 or arg or local var slot */
<         } lexical;
<         struct {
<             JSAtom      *atom;          /* first atom in pair */
<             JSAtom      *atom2;         /* second atom in pair or null */
<         } apair;
<         struct {                        /* object literal */
<             JSParsedObjectBox *pob;
<         } object;
<         jsdouble        dval;           /* aligned numeric literal value */
---
> 	struct {                        /* TOK_FUNCTION node */
> 	    JSFunction  *fun;           /* function object private data */
> 	    JSParseNode *body;          /* TOK_LC list of statements */
>             uint32      flags;          /* accumulated tree context flags */
> 	    uint32      tryCount;       /* count of try statements in body */
> 	} func;
> 	struct {                        /* list of next-linked nodes */
> 	    JSParseNode *head;          /* first node in list */
> 	    JSParseNode **tail;         /* ptr to ptr to last node in list */
> 	    uint32      count;          /* number of nodes in list */
> 	    uint32      extra;          /* extra comma flag for [1,2,,] */
> 	} list;
> 	struct {                        /* ternary: if, for(;;), ?: */
> 	    JSParseNode *kid1;          /* condition, discriminant, etc. */
> 	    JSParseNode *kid2;          /* then-part, case list, etc. */
> 	    JSParseNode *kid3;          /* else-part, default case, etc. */
> 	} ternary;
> 	struct {                        /* two kids if binary */
> 	    JSParseNode *left;
> 	    JSParseNode *right;
> 	    jsval       val;            /* switch case value */
> 	} binary;
> 	struct {                        /* one kid if unary */
> 	    JSParseNode *kid;
> 	    jsint       num;            /* -1 or sharp variable number */
> 	} unary;
> 	struct {                        /* name, labeled statement, etc. */
> 	    JSAtom      *atom;          /* name or label atom, null if slot */
> 	    JSParseNode *expr;          /* object or initializer */
> 	    jsint       slot;           /* -1 or arg or local var slot */
>             uintN       attrs;          /* attributes if local var or const */
> 	} name;
> 	jsdouble        dval;           /* aligned numeric literal value */
334c231
< #define pn_funpob       pn_u.func.funpob
---
> #define pn_fun          pn_u.func.fun
337,338c234
< #define pn_sclen        pn_u.func.sclen
< #define pn_index        pn_u.func.index
---
> #define pn_tryCount     pn_u.func.tryCount
351d246
< #define pn_hidden       pn_u.unary.hidden
355c250
< #define pn_const        pn_u.name.isconst
---
> #define pn_attrs        pn_u.name.attrs
357,358d251
< #define pn_atom2        pn_u.apair.atom2
< #define pn_pob          pn_u.object.pob
361,373c254,255
< #define PNX_STRCAT      0x01            /* TOK_PLUS list has string term */
< #define PNX_CANTFOLD    0x02            /* TOK_PLUS list has unfoldable term */
< #define PNX_POPVAR      0x04            /* TOK_VAR last result needs popping */
< #define PNX_FORINVAR    0x08            /* TOK_VAR is left kid of TOK_IN node,
<                                            which is left kid of TOK_FOR */
< #define PNX_ENDCOMMA    0x10            /* array literal has comma at end */
< #define PNX_XMLROOT     0x20            /* top-most node in XML literal tree */
< #define PNX_GROUPINIT   0x40            /* var [a, b] = [c, d]; unit list */
< #define PNX_NEEDBRACES  0x80            /* braces necessary due to closure */
< #define PNX_FUNCDEFS   0x100            /* contains top-level function
<                                            statements */
< #define PNX_SHORTHAND  0x200            /* shorthand syntax used, at present
<                                            object destructuring ({x,y}) only */
---
> #define PNX_STRCAT      0x1             /* TOK_PLUS list has string term */
> #define PNX_CANTFOLD    0x2             /* TOK_PLUS list has unfoldable term */
401,403d282
< #define PN_OP(pn)    ((JSOp)(pn)->pn_op)
< #define PN_TYPE(pn)  ((JSTokenType)(pn)->pn_type)
< 
413,415c292,294
<         (list)->pn_head = NULL;                                               \
<         (list)->pn_tail = &(list)->pn_head;                                   \
<         (list)->pn_count = (list)->pn_extra = 0;                              \
---
> 	(list)->pn_head = NULL;                                               \
> 	(list)->pn_tail = &(list)->pn_head;                                   \
> 	(list)->pn_count = 0;                                                 \
420,423c299,301
<         (list)->pn_head = (pn);                                               \
<         (list)->pn_tail = &(pn)->pn_next;                                     \
<         (list)->pn_count = 1;                                                 \
<         (list)->pn_extra = 0;                                                 \
---
> 	(list)->pn_head = (pn);                                               \
> 	(list)->pn_tail = &(pn)->pn_next;                                     \
> 	(list)->pn_count = 1;                                                 \
428,430c306,308
<         *(list)->pn_tail = (pn);                                              \
<         (list)->pn_tail = &(pn)->pn_next;                                     \
<         (list)->pn_count++;                                                   \
---
> 	*(list)->pn_tail = (pn);                                              \
> 	(list)->pn_tail = &(pn)->pn_next;                                     \
> 	(list)->pn_count++;                                                   \
433,454d310
< struct JSParsedObjectBox {
<     JSParsedObjectBox   *traceLink;
<     JSParsedObjectBox   *emitLink;
<     JSObject            *object;
< };
< 
< struct JSParseContext {
<     JSTokenStream       tokenStream;
<     void                *tempPoolMark;  /* initial JSContext.tempPool mark */
<     JSPrincipals        *principals;    /* principals associated with source */
<     JSParseNode         *nodeList;      /* list of recyclable parse-node
<                                            structs */
<     JSParsedObjectBox   *traceListHead; /* list of parsed object for GC
<                                            tracing */
<     JSTempValueRooter   tempRoot;       /* root to trace traceListHead */
< };
< 
< /*
<  * Convenience macro to access JSParseContext.tokenStream as a pointer.
<  */
< #define TS(pc) (&(pc)->tokenStream)
< 
456a313,315
>  *
>  * The caller must prevent the GC from running while this function is active,
>  * because atoms and function newborns are not rooted yet.
458,459c317,318
< extern JSParseNode *
< js_ParseScript(JSContext *cx, JSObject *chain, JSParseContext *pc);
---
> extern JS_FRIEND_API(JSParseNode *)
> js_ParseTokenStream(JSContext *cx, JSObject *chain, JSTokenStream *ts);
461,464c320,322
< extern JSScript *
< js_CompileScript(JSContext *cx, JSObject *obj, JSPrincipals *principals,
<                  uint32 tcflags, const jschar *chars, size_t length,
<                  FILE *file, const char *filename, uintN lineno);
---
> extern JS_FRIEND_API(JSBool)
> js_CompileTokenStream(JSContext *cx, JSObject *chain, JSTokenStream *ts,
> 		      JSCodeGenerator *cg);
467,469c325
< js_CompileFunctionBody(JSContext *cx, JSFunction *fun, JSPrincipals *principals,
<                        const jschar *chars, size_t length,
<                        const char *filename, uintN lineno);
---
> js_CompileFunctionBody(JSContext *cx, JSTokenStream *ts, JSFunction *fun);
474,508d329
< #if JS_HAS_XML_SUPPORT
< JS_FRIEND_API(JSParseNode *)
< js_ParseXMLText(JSContext *cx, JSObject *chain, JSParseContext *pc,
<                 JSBool allowList);
< #endif
< 
< /*
<  * Initialize a parse context. All parameters after pc are passed to
<  * js_InitTokenStream.
<  *
<  * The parse context owns the arena pool "tops-of-stack" space above the
<  * current JSContext.tempPool mark. This means you cannot allocate from
<  * tempPool and save the pointer beyond the next js_FinishParseContext.
<  */
< extern JSBool
< js_InitParseContext(JSContext *cx, JSParseContext *pc, JSPrincipals *principals,
<                     const jschar *base, size_t length, FILE *fp,
<                     const char *filename, uintN lineno);
< 
< extern void
< js_FinishParseContext(JSContext *cx, JSParseContext *pc);
< 
< extern void
< js_InitCompilePrincipals(JSContext *cx, JSParseContext *pc,
<                          JSPrincipals *principals);
< 
< /*
<  * Allocate a new parseed object node from cx->tempPool.
<  */
< extern JSParsedObjectBox *
< js_NewParsedObjectBox(JSContext *cx, JSParseContext *pc, JSObject *obj);
< 
< extern void
< js_TraceParseContext(JSTracer *trc, JSParseContext *pc);
< 
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsprf.c /Volumes/Swap/js_D11/src/jsprf.c
2,8c2,6
< /* ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
---
> /*
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
10,13c8,11
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
18,21c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
25,37c23,33
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
48c44
< #include <stdlib.h>
---
> #include "xstdlib.h"
52,53c48,50
< #include "jspubtd.h"
< #include "jsstr.h"
---
> #include "jsapi.h"
> 
> //#include "_optimize.h"
110d106
< #define TYPE_WSTRING    11
401,421d396
< static int cvt_ws(SprintfState *ss, const jschar *ws, int width, int prec,
<                   int flags)
< {
<     int result;
<     /*
<      * Supply NULL as the JSContext; errors are not reported,
<      * and malloc() is used to allocate the buffer buffer.
<      */
<     if (ws) {
<         int slen = js_strlen(ws);
<         char *s = js_DeflateString(NULL, ws, slen);
<         if (!s)
<             return -1; /* JSStuffFunc error indicator. */
<         result = cvt_s(ss, s, width, prec, flags);
<         free(s);
<     } else {
<         result = cvt_s(ss, NULL, width, prec, flags);
<     }
<     return result;
< }
< 
423c398
< ** BuildArgArray stands for Numbered Argument list Sprintf
---
> ** BiuldArgArray stands for Numbered Argument list Sprintf
432,434c407,409
<     const char *p;
<     char c;
<     struct NumArgState *nas;
---
>     const char* p;
>     char  c;
>     struct NumArgState* nas;
479c454,455
<         nas = (struct NumArgState*)malloc( number * sizeof( struct NumArgState ) );
---
>     	XMEMTAG("jsprf NumArgState");
>         nas = (struct NumArgState*)xmalloc( number * sizeof( struct NumArgState ) );
505c481
<         while( c && c != '$' ){     /* should improve error check later */
---
>         while( c && c != '$' ){     /* should imporve error check later */
605c581
<             nas[ cn ].type = (nas[ cn ].type == TYPE_UINT16) ? TYPE_WSTRING : TYPE_STRING;
---
>             nas[ cn ].type = TYPE_STRING;
633c609
<             free( nas );
---
>             JS_DELETE( nas );
662,663d637
<         case TYPE_WSTRING:      (void)va_arg( ap, jschar* );            break;
< 
670c644
<                 free( nas );
---
>                 JS_DELETE( nas );
691d664
<         jschar wch;
697d669
<         const jschar* ws;
705,710c677,681
<     struct NumArgState *nas = NULL;
<     struct NumArgState nasArray[ NAS_DEFAULT_NUM ];
<     char pattern[20];
<     const char *dolPt = NULL;  /* in "%4$.2f", dolPt will poiont to . */
<     uint8 utf8buf[6];
<     int utf8len;
---
>     struct NumArgState* nas = NULL;
>     struct NumArgState  nasArray[ NAS_DEFAULT_NUM ];
>     char  pattern[20];
>     const char* dolPt = NULL;  /* in "%4$.2f", dolPt will poiont to . */
> 
759c730
<                     free( nas );
---
>                     JS_DELETE( nas );
936a908
>             u.ch = va_arg(ap, int);
945,958c917
<             switch (type) {
<               case TYPE_INT16:
<                 /* Treat %hc as %c unless js_CStringsAreUTF8. */
<                 if (js_CStringsAreUTF8) {
<                     u.wch = va_arg(ap, int);
<                     utf8len = js_OneUcs4ToUtf8Char (utf8buf, u.wch);
<                     rv = (*ss->stuff)(ss, (char *)utf8buf, utf8len);
<                     break;
<                 }
<               case TYPE_INTN:
<                 u.ch = va_arg(ap, int);
<                 rv = (*ss->stuff)(ss, &u.ch, 1);
<                 break;
<             }
---
>             rv = (*ss->stuff)(ss, &u.ch, 1);
997,1007c956,957
<             if(type == TYPE_INT16) {
<                 /*
<                  * This would do a simple string/byte conversion
<                  * unless js_CStringsAreUTF8.
<                  */
<                 u.ws = va_arg(ap, const jschar*);
<                 rv = cvt_ws(ss, u.ws, width, prec, flags);
<             } else {
<                 u.s = va_arg(ap, const char*);
<                 rv = cvt_s(ss, u.s, width, prec, flags);
<             }
---
>             u.s = va_arg(ap, const char*);
>             rv = cvt_s(ss, u.s, width, prec, flags);
1040c990
<         free( nas );
---
>         JS_DELETE( nas );
1101c1051,1052
<             newbase = (char*) realloc(ss->base, newlen);
---
>         	XMEMTAG("jsprf GrowStuff xrealloc");
>             newbase = (char*) xrealloc(ss->base, newlen);
1103c1054,1055
<             newbase = (char*) malloc(newlen);
---
>         	XMEMTAG("jsprf GrowStuff xmalloc");
>             newbase = (char*) xmalloc(newlen);
1142c1094
<         free(mem);
---
>         JS_DELETE(mem);
1157c1109
<             free(ss.base);
---
>             JS_DELETE(ss.base);
1219,1220c1171,1172
<     if( (ss.cur != ss.base) && (ss.cur[-1] != '\0') )
<         ss.cur[-1] = '\0';
---
>     if( (ss.cur != ss.base) && (*(ss.cur - 1) != '\0') )
>         *(--ss.cur) = '\0';
1256c1208
<             free(ss.base);
---
>             JS_DELETE(ss.base);
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsprf.h /Volumes/Swap/js_D11/src/jsprf.h
2,13c2,11
< /* ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
> /*
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
18,37c16,33
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
44,58c40,52
< **      %d - decimal
< **      %u - unsigned decimal
< **      %x - unsigned hex
< **      %X - unsigned uppercase hex
< **      %o - unsigned octal
< **      %hd, %hu, %hx, %hX, %ho - 16-bit versions of above
< **      %ld, %lu, %lx, %lX, %lo - 32-bit versions of above
< **      %lld, %llu, %llx, %llX, %llo - 64 bit versions of above
< **      %s - string
< **      %hs - 16-bit version of above (only available if js_CStringsAreUTF8)
< **      %c - character
< **      %hc - 16-bit version of above (only available if js_CStringsAreUTF8)
< **      %p - pointer (deals with machine dependent pointer size)
< **      %f - float
< **      %g - float
---
> **	%d - decimal
> **	%u - unsigned decimal
> **	%x - unsigned hex
> **	%X - unsigned uppercase hex
> **	%o - unsigned octal
> **	%hd, %hu, %hx, %hX, %ho - 16-bit versions of above
> **	%ld, %lu, %lx, %lX, %lo - 32-bit versions of above
> **	%lld, %llu, %llx, %llX, %llo - 64 bit versions of above
> **	%s - string
> **	%c - character
> **	%p - pointer (deals with machine dependent pointer size)
> **	%f - float
> **	%g - float
Only in /Volumes/Swap/js-14-2-2008/js/src: jsproto.tbl
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsprvtd.h /Volumes/Swap/js_D11/src/jsprvtd.h
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
59,82d53
< /* Internal identifier (jsid) macros. */
< 
< #define JSID_IS_ATOM(id)            JSVAL_IS_STRING((jsval)(id))
< #define JSID_TO_ATOM(id)            ((JSAtom *)(id))
< #define ATOM_TO_JSID(atom)          (JS_ASSERT(ATOM_IS_STRING(atom)),         \
<                                      (jsid)(atom))
< 
< #define JSID_IS_INT(id)             JSVAL_IS_INT((jsval)(id))
< #define JSID_TO_INT(id)             JSVAL_TO_INT((jsval)(id))
< #define INT_TO_JSID(i)              ((jsid)INT_TO_JSVAL(i))
< #define INT_JSVAL_TO_JSID(v)        ((jsid)(v))
< #define INT_JSID_TO_JSVAL(id)       ((jsval)(id))
< 
< #define JSID_IS_OBJECT(id)          JSVAL_IS_OBJECT((jsval)(id))
< #define JSID_TO_OBJECT(id)          JSVAL_TO_OBJECT((jsval)(id))
< #define OBJECT_TO_JSID(obj)         ((jsid)OBJECT_TO_JSVAL(obj))
< #define OBJECT_JSVAL_TO_JSID(v)     ((jsid)v)
< 
< /*
<  * Convenience constants.
<  */
< #define JS_BITS_PER_UINT32_LOG2 5
< #define JS_BITS_PER_UINT32      32
< 
90a62,64
> typedef struct JSDependentString    JSDependentString;
> typedef struct JSGCLockHashEntry    JSGCLockHashEntry;
> typedef struct JSGCRootHashEntry    JSGCRootHashEntry;
92,94d65
< typedef struct JSGenerator          JSGenerator;
< typedef struct JSParseContext       JSParseContext;
< typedef struct JSParsedObjectBox    JSParsedObjectBox;
96d66
< typedef struct JSPropCacheEntry     JSPropCacheEntry;
98,99d67
< typedef struct JSTempValueRooter    JSTempValueRooter;
< typedef struct JSThread             JSThread;
106d73
< typedef struct JSWeakRoots          JSWeakRoots;
120a88
> typedef struct JSStackFrame         JSStackFrame;
122d89
< typedef struct JSStringBuffer       JSStringBuffer;
124,128d90
< typedef struct JSXML                JSXML;
< typedef struct JSXMLNamespace       JSXMLNamespace;
< typedef struct JSXMLQName           JSXMLQName;
< typedef struct JSXMLArray           JSXMLArray;
< typedef struct JSXMLArrayCursor     JSXMLArrayCursor;
140,141c102,103
< (* JS_DLL_CALLBACK JSTrapHandler)(JSContext *cx, JSScript *script,
<                                   jsbytecode *pc, jsval *rval, void *closure);
---
> (* JS_DLL_CALLBACK JSTrapHandler)(JSContext *cx, JSScript *script, jsbytecode *pc, 
>                                   jsval *rval, void *closure);
151c113
<                                     uintN      lineno,     /* first line */
---
>                                     uintN      lineno,     /* line script starts */
158,159c120,121
< (* JS_DLL_CALLBACK JSDestroyScriptHook)(JSContext *cx,
<                                         JSScript  *script,
---
> (* JS_DLL_CALLBACK JSDestroyScriptHook)(JSContext *cx, 
>                                         JSScript  *script, 
163,164c125,126
< (* JS_DLL_CALLBACK JSSourceHandler)(const char *filename, uintN lineno,
<                                     jschar *str, size_t length,
---
> (* JS_DLL_CALLBACK JSSourceHandler)(const char *filename, uintN lineno, 
>                                     jschar *str, size_t length, 
168,191c130,156
<  * This hook captures high level script execution and function calls (JS or
<  * native).  It is used by JS_SetExecuteHook to hook top level scripts and by
<  * JS_SetCallHook to hook function calls.  It will get called twice per script
<  * or function call: just before execution begins and just after it finishes.
<  * In both cases the 'current' frame is that of the executing code.
<  *
<  * The 'before' param is JS_TRUE for the hook invocation before the execution
<  * and JS_FALSE for the invocation after the code has run.
<  *
<  * The 'ok' param is significant only on the post execution invocation to
<  * signify whether or not the code completed 'normally'.
<  *
<  * The 'closure' param is as passed to JS_SetExecuteHook or JS_SetCallHook
<  * for the 'before'invocation, but is whatever value is returned from that
<  * invocation for the 'after' invocation. Thus, the hook implementor *could*
<  * allocate a structure in the 'before' invocation and return a pointer to that
<  * structure. The pointer would then be handed to the hook for the 'after'
<  * invocation. Alternately, the 'before' could just return the same value as
<  * in 'closure' to cause the 'after' invocation to be called with the same
<  * 'closure' value as the 'before'.
<  *
<  * Returning NULL in the 'before' hook will cause the 'after' hook *not* to
<  * be called.
<  */
---
> * This hook captures high level script execution and function calls
> * (JS or native). 
> * It is used by JS_SetExecuteHook to hook top level scripts and by
> * JS_SetCallHook to hook function calls.
> * It will get called twice per script or function call:
> * just before execution begins and just after it finishes. In both cases
> * the 'current' frame is that of the executing code.
> *
> * The 'before' param is JS_TRUE for the hook invocation before the execution
> * and JS_FALSE for the invocation after the code has run.
> *
> * The 'ok' param is significant only on the post execution invocation to
> * signify whether or not the code completed 'normally'.
> *
> * The 'closure' param is as passed to JS_SetExecuteHook or JS_SetCallHook 
> * for the 'before'invocation, but is whatever value is returned from that 
> * invocation for the 'after' invocation. Thus, the hook implementor *could*
> * allocate a stucture in the 'before' invocation and return a pointer
> * to that structure. The pointer would then be handed to the hook for
> * the 'after' invocation. Alternately, the 'before' could just return the
> * same value as in 'closure' to cause the 'after' invocation to be called 
> * with the same 'closure' value as the 'before'.
> *
> * Returning NULL in the 'before' hook will cause the 'after' hook to
> * NOT be called.
> */
> 
197c162
< (* JS_DLL_CALLBACK JSObjectHook)(JSContext *cx, JSObject *obj, JSBool isNew,
---
> (* JS_DLL_CALLBACK JSObjectHook)(JSContext *cx, JSObject *obj, JSBool isNew, 
204,262c169,170
< typedef struct JSDebugHooks {
<     JSTrapHandler       interruptHandler;
<     void                *interruptHandlerData;
<     JSNewScriptHook     newScriptHook;
<     void                *newScriptHookData;
<     JSDestroyScriptHook destroyScriptHook;
<     void                *destroyScriptHookData;
<     JSTrapHandler       debuggerHandler;
<     void                *debuggerHandlerData;
<     JSSourceHandler     sourceHandler;
<     void                *sourceHandlerData;
<     JSInterpreterHook   executeHook;
<     void                *executeHookData;
<     JSInterpreterHook   callHook;
<     void                *callHookData;
<     JSObjectHook        objectHook;
<     void                *objectHookData;
<     JSTrapHandler       throwHook;
<     void                *throwHookData;
<     JSDebugErrorHook    debugErrorHook;
<     void                *debugErrorHookData;
< } JSDebugHooks;
< 
< /*
<  * Type definitions for temporary GC roots that register with GC local C
<  * variables. See jscntxt.h for details.
<  */
< typedef void
< (* JS_DLL_CALLBACK JSTempValueTrace)(JSTracer *trc, JSTempValueRooter *tvr);
< 
< typedef union JSTempValueUnion {
<     jsval               value;
<     JSObject            *object;
<     JSString            *string;
<     JSFunction          *function;
<     JSXML               *xml;
<     JSXMLQName          *qname;
<     JSTempValueTrace    trace;
<     JSScopeProperty     *sprop;
<     JSWeakRoots         *weakRoots;
<     JSParseContext      *parseContext;
<     JSScript            *script;
<     jsval               *array;
< } JSTempValueUnion;
< 
< struct JSTempValueRooter {
<     JSTempValueRooter   *down;
<     ptrdiff_t           count;
<     JSTempValueUnion    u;
< };
< 
< /*
<  * The following determines whether JS_EncodeCharacters and JS_DecodeBytes
<  * treat char[] as utf-8 or simply as bytes that need to be inflated/deflated.
<  */
< #ifdef JS_C_STRINGS_ARE_UTF8
< # define js_CStringsAreUTF8 JS_TRUE
< #else
< extern JSBool js_CStringsAreUTF8;
---
> #if 1 // !!dp
> typedef void (*LGenericOutProc)(void *param, char *format, ... );
diff -r /Volumes/Swap/js-14-2-2008/js/src/jspubtd.h /Volumes/Swap/js_D11/src/jspubtd.h
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
59,63d53
< /*
<  * Run-time version enumeration.  See jsconfig.h for compile-time counterparts
<  * to these values that may be selected by the JS_VERSION macro, and tested by
<  * #if expressions.
<  */
70d59
<     JSVERSION_ECMA_3  = 148,
72,74d60
<     JSVERSION_1_6     = 160,
<     JSVERSION_1_7     = 170,
<     JSVERSION_1_8     = 180,
76,77c62
<     JSVERSION_UNKNOWN = -1,
<     JSVERSION_LATEST  = JSVERSION_1_8
---
>     JSVERSION_UNKNOWN = -1
91,92d75
<     JSTYPE_NULL,                /* null */
<     JSTYPE_XML,                 /* xml object */
96,103d78
< /* Dense index into cached prototypes and class atoms for standard objects. */
< typedef enum JSProtoKey {
< #define JS_PROTO(name,code,init) JSProto_##name = code,
< #include "jsproto.tbl"
< #undef JS_PROTO
<     JSProto_LIMIT
< } JSProtoKey;
< 
129d103
< typedef struct JSExtendedClass   JSExtendedClass;
135d108
< typedef struct JSTracer          JSTracer;
142d114
< typedef struct JSXMLObjectOps    JSXMLObjectOps;
144c116
< typedef struct JSRuntime         JSTaskState;   /* XXX deprecated name */
---
> typedef struct JSRuntime         JSTaskState;	/* XXX deprecated name */
146d117
< typedef struct JSStackFrame      JSStackFrame;
148c119
< typedef struct JSXDRState        JSXDRState;
---
> typedef struct JSXDRState	 JSXDRState;
224,226d194
<  *  JSRESOLVE_DETECTING   'if (o.p)...' or similar detection opcode sequence
<  *  JSRESOLVE_DECLARING   var, const, or function prolog declaration opcode
<  *  JSRESOLVE_CLASSNAME   class name used when constructing
279,282c247,250
<  * a private (int-tagged) pointer in obj slots. In contrast, all native and
<  * host objects have a JSObjectMap at obj->map, which may be shared among a
<  * number of objects, and which contains the JSObjectOps *ops pointer used to
<  * dispatch object operations from API calls.
---
>  * a private (int-tagged) pointer in obj->slots[JSSLOT_CLASS].  In contrast,
>  * all native and host objects have a JSObjectMap at obj->map, which may be
>  * shared among a number of objects, and which contains the JSObjectOps *ops
>  * pointer used to dispatch object operations from API calls.
287,288c255
<  * find the class's JSObjectOps struct, by calling clasp->getObjectOps, and to
<  * finalize the object.
---
>  * find the class's JSObjectOps struct, by calling clasp->getObjectOps.
294,297d260
<  *
<  * Further extension to preserve API compatibility: if this function returns
<  * a pointer to JSXMLObjectOps.base, not to JSObjectOps, then the engine calls
<  * extended hooks needed for E4X.
335,337c298,313
<  * Deprecated function type for JSClass.mark. All new code should define
<  * JSTraceOp instead to ensure the traversal of traceable things stored in
<  * the native structures.
---
>  * Function type for JSClass.mark and JSObjectOps.mark, called from the GC to
>  * scan live GC-things reachable from obj's private data structure.  For each
>  * such thing, a mark implementation must call
>  *
>  *    JS_MarkGCThing(cx, thing, name, arg);
>  *
>  * The trailing name and arg parameters are used for GC_MARK_DEBUG-mode heap
>  * dumping and ref-path tracing.  The mark function should pass a (typically
>  * literal) string naming the private data member for name, and it must pass
>  * the opaque arg parameter through from its caller.
>  *
>  * For the JSObjectOps.mark hook, the return value is the number of slots at
>  * obj->slots to scan.  For JSClass.mark, the return value is ignored.
>  *
>  * NB: JSMarkOp implementations cannot allocate new GC-things (JS_NewObject
>  * called from a mark function will fail silently, e.g.).
342,418d317
< /*
<  * Function type for trace operation of the class called to enumerate all
<  * traceable things reachable from obj's private data structure. For each such
<  * thing, a trace implementation must call
<  *
<  *    JS_CallTracer(trc, thing, kind);
<  *
<  * or one of its convenience macros as described in jsapi.h.
<  *
<  * JSTraceOp implementation can assume that no other threads mutates object
<  * state. It must not change state of the object or corresponding native
<  * structures. The only exception for this rule is the case when the embedding
<  * needs a tight integration with GC. In that case the embedding can check if
<  * the traversal is a part of the marking phase through calling
<  * JS_IsGCMarkingTracer and apply a special code like emptying caches or
<  * marking its native structures.
<  *
<  * To define the tracer for a JSClass, the implementation must add
<  * JSCLASS_MARK_IS_TRACE to class flags and use JS_CLASS_TRACE(method)
<  * macro below to convert JSTraceOp to JSMarkOp when initializing or
<  * assigning JSClass.mark field.
<  */
< typedef void
< (* JS_DLL_CALLBACK JSTraceOp)(JSTracer *trc, JSObject *obj);
< 
< #if defined __GNUC__ && __GNUC__ >= 4 && !defined __cplusplus
< # define JS_CLASS_TRACE(method)                                               \
<     (__builtin_types_compatible_p(JSTraceOp, __typeof(&(method)))             \
<      ? (JSMarkOp)(method)                                                     \
<      : js_WrongTypeForClassTracer)
< 
< extern JSMarkOp js_WrongTypeForClassTracer;
< 
< #else
< # define JS_CLASS_TRACE(method) ((JSMarkOp)(method))
< #endif
< 
< /*
<  * Tracer callback, called for each traceable thing directly refrenced by a
<  * particular object or runtime structure. It is the callback responsibility
<  * to ensure the traversal of the full object graph via calling eventually
<  * JS_TraceChildren on the passed thing. In this case the callback must be
<  * prepared to deal with cycles in the traversal graph.
<  *
<  * kind argument is one of JSTRACE_OBJECT, JSTRACE_DOUBLE, JSTRACE_STRING or
<  * a tag denoting internal implementation-specific traversal kind. In the
<  * latter case the only operations on thing that the callback can do is to call
<  * JS_TraceChildren or DEBUG-only JS_PrintTraceThingInfo.
<  */
< typedef void
< (* JS_DLL_CALLBACK JSTraceCallback)(JSTracer *trc, void *thing, uint32 kind);
< 
< /*
<  * DEBUG only callback that JSTraceOp implementation can provide to return
<  * a string describing the reference traced with JS_CallTracer.
<  */
< #ifdef DEBUG
< typedef void
< (* JS_DLL_CALLBACK JSTraceNamePrinter)(JSTracer *trc, char *buf,
<                                        size_t bufsize);
< #endif
< 
< /*
<  * The optional JSClass.reserveSlots hook allows a class to make computed
<  * per-instance object slots reservations, in addition to or instead of using
<  * JSCLASS_HAS_RESERVED_SLOTS(n) in the JSClass.flags initializer to reserve
<  * a constant-per-class number of slots.  Implementations of this hook should
<  * return the number of slots to reserve, not including any reserved by using
<  * JSCLASS_HAS_RESERVED_SLOTS(n) in JSClass.flags.
<  *
<  * NB: called with obj locked by the JSObjectOps-specific mutual exclusion
<  * mechanism appropriate for obj, so don't nest other operations that might
<  * also lock obj.
<  */
< typedef uint32
< (* JS_DLL_CALLBACK JSReserveSlotsOp)(JSContext *cx, JSObject *obj);
< 
465c364,368
<                                    JSObject **objp, JSProperty **propp);
---
>                                    JSObject **objp, JSProperty **propp
> #if defined JS_THREADSAFE && defined DEBUG
>                                  , const char *file, uintN line
> #endif
>                                   );
526,533d428
<  * Hook that creates an iterator object for a given object. Returns the
<  * iterator object or null if an error or exception was thrown on cx.
<  */
< typedef JSObject *
< (* JS_DLL_CALLBACK JSIteratorOp)(JSContext *cx, JSObject *obj,
<                                  JSBool keysonly);
< 
< /*
544,546c439,441
<  * Function pointer type for JSObjectOps.setProto and JSObjectOps.setParent.
<  * These hooks must check for cycles without deadlocking, and otherwise take
<  * special steps. See jsobj.c and jsgc.c for details.
---
>  * Function type for JSObjectOps.setProto and JSObjectOps.setParent.  These
>  * hooks must check for cycles without deadlocking, and otherwise take special
>  * steps.  See jsobj.c, js_SetProtoOrParent, for an example.
559c454
<  * NB: the slot parameter is a zero-based index into obj slots, unlike the
---
>  * NB: the slot parameter is a zero-based index into obj->slots[], unlike the
569c464
< typedef JSBool
---
> typedef void
573,593d467
< typedef JSObject *
< (* JS_DLL_CALLBACK JSGetMethodOp)(JSContext *cx, JSObject *obj, jsid id,
<                                   jsval *vp);
< 
< typedef JSBool
< (* JS_DLL_CALLBACK JSSetMethodOp)(JSContext *cx, JSObject *obj, jsid id,
<                                   jsval *vp);
< 
< typedef JSBool
< (* JS_DLL_CALLBACK JSEnumerateValuesOp)(JSContext *cx, JSObject *obj,
<                                         JSIterateOp enum_op,
<                                         jsval *statep, jsid *idp, jsval *vp);
< 
< typedef JSBool
< (* JS_DLL_CALLBACK JSEqualityOp)(JSContext *cx, JSObject *obj, jsval v,
<                                  JSBool *bp);
< 
< typedef JSBool
< (* JS_DLL_CALLBACK JSConcatenateOp)(JSContext *cx, JSObject *obj, jsval v,
<                                     jsval *vp);
< 
600,603d473
< /* See jsapi.h, the JS_CALLEE, JS_THIS, etc. macros. */
< typedef JSBool
< (* JS_DLL_CALLBACK JSFastNative)(JSContext *cx, uintN argc, jsval *vp);
< 
606,626d475
< typedef enum JSContextOp {
<     JSCONTEXT_NEW,
<     JSCONTEXT_DESTROY
< } JSContextOp;
< 
< /*
<  * The possible values for contextOp when the runtime calls the callback are:
<  *   JSCONTEXT_NEW      JS_NewContext successfully created a new JSContext
<  *                      instance. The callback can initialize the instance as
<  *                      required. If the callback returns false, the instance
<  *                      will be destroyed and JS_NewContext returns null. In
<  *                      this case the callback is not called again.
<  *   JSCONTEXT_DESTROY  One of JS_DestroyContext* methods is called. The
<  *                      callback may perform its own cleanup and must always
<  *                      return true.
<  *   Any other value    For future compatibility the callback must do nothing
<  *                      and return true in this case.
<  */
< typedef JSBool
< (* JS_DLL_CALLBACK JSContextCallback)(JSContext *cx, uintN contextOp);
< 
637,649d485
< /*
<  * Generic trace operation that calls JS_CallTracer on each traceable thing
<  * stored in data.
<  */
< typedef void
< (* JS_DLL_CALLBACK JSTraceDataOp)(JSTracer *trc, void *data);
< 
< typedef JSBool
< (* JS_DLL_CALLBACK JSOperationCallback)(JSContext *cx);
< 
< /*
<  * Deprecated form of JSOperationCallback.
<  */
657,674d492
< /*
<  * Possible exception types. These types are part of a JSErrorFormatString
<  * structure. They define which error to throw in case of a runtime error.
<  * JSEXN_NONE marks an unthrowable error.
<  */
< typedef enum JSExnType {
<     JSEXN_NONE = -1,
<       JSEXN_ERR,
<         JSEXN_INTERNALERR,
<         JSEXN_EVALERR,
<         JSEXN_RANGEERR,
<         JSEXN_REFERENCEERR,
<         JSEXN_SYNTAXERR,
<         JSEXN_TYPEERR,
<         JSEXN_URIERR,
<         JSEXN_LIMIT
< } JSExnType;
< 
676d493
<     /* The error format string (UTF-8 if js_CStringsAreUTF8). */
678,683c495
< 
<     /* The number of arguments to expand in the formatted error message. */
<     uint16 argCount;
< 
<     /* One of the JSExnType constants above. */
<     int16 exnType;
---
>     uintN argCount;
688c500
<                                     const uintN errorNumber);
---
> 			            const uintN errorNumber);
699c511
< typedef JSBool
---
> typedef JSBool 
712,714d523
< typedef JSBool
< (* JS_DLL_CALLBACK JSLocaleToUnicode)(JSContext *cx, char *src, jsval *rval);
< 
731,740c540,559
< /*
<  * Return a weak reference to the principals associated with obj, possibly via
<  * the immutable parent chain leading from obj to a top-level container (e.g.,
<  * a window object in the DOM level 0).  If there are no principals associated
<  * with obj, return null.  Therefore null does not mean an error was reported;
<  * in no event should an error be reported or an exception be thrown by this
<  * callback's implementation.
<  */
< typedef JSPrincipals *
< (* JS_DLL_CALLBACK JSObjectPrincipalsFinder)(JSContext *cx, JSObject *obj);
---
> #if 0		// !!dp
> typedef void *
> (* JS_DLL_CALLBACK LMemAlloc)(size_t nbytes);
> 
> typedef void *
> (* JS_DLL_CALLBACK LMemRealloc)(void * ptr, size_t nbytes);
> 
> typedef void *
> (* JS_DLL_CALLBACK LMemCAlloc)(size_t ssize, size_t nbytes);
> 
> typedef void 
> (* JS_DLL_CALLBACK LMemFree)(void * ptr);
> 
> typedef struct LMemHookProcs {
>     LMemAlloc	mallocp;
>     LMemRealloc	reallocp;
>     LMemCAlloc	callocp;
>     LMemFree	freep;
> } LMemHookProcs;
> #endif
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsregexp.c /Volumes/Swap/js_D11/src/jsregexp.c
2d1
<  * vim: set sw=4 ts=8 et tw=78:
4,5c3,6
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
7,15c8,11
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
20,25c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
27,37c21
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
---
>  * Contributor(s): 
39c23,33
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
45c39
< #include <stdlib.h>
---
> #include "xstdlib.h"
47d40
< #include <stdarg.h>
67,87c60,61
< typedef enum REOp {
< #define REOP_DEF(opcode, name) opcode,
< #include "jsreops.tbl"
< #undef REOP_DEF
<     REOP_LIMIT /* META: no operator >= to this */
< } REOp;
< 
< #define REOP_IS_SIMPLE(op)  ((op) <= REOP_NCLASS)
< 
< #ifdef REGEXP_DEBUG
< const char *reop_names[] = {
< #define REOP_DEF(opcode, name) name,
< #include "jsreops.tbl"
< #undef REOP_DEF
<     NULL
< };
< #endif
< 
< #ifdef __GNUC__
< static int
< re_debug(const char *fmt, ...) __attribute__ ((format(printf, 1, 2)));
---
> #ifdef XP_MAC
> #include <MacMemory.h>
90,101c64
< #ifdef REGEXP_DEBUG
< static int
< re_debug(const char *fmt, ...)
< {
<     va_list ap;
<     int retval;
< 
<     va_start(ap, fmt);
<     retval = vprintf(fmt, ap);
<     va_end(ap);
<     return retval;
< }
---
> //#include "_optimize.h"
103,106c66
< static void
< re_debug_chars(const jschar *chrs, size_t length)
< {
<     int i = 0;
---
> #if JS_HAS_REGEXPS
108,120c68,113
<     printf(" \"");
<     while (*chrs && i++ < length) {
<         putchar((char)*chrs++);
<     }
<     printf("\"");
< }
< #else  /* !REGEXP_DEBUG */
< /* This should be optimized to a no-op by our tier-1 compilers. */
< static int
< re_debug(const char *fmt, ...)
< {
<     return 0;
< }
---
> typedef enum REOp {
>     REOP_EMPTY      = 0,  /* match rest of input against rest of r.e. */
>     REOP_ALT        = 1,  /* alternative subexpressions in kid and next */
>     REOP_BOL        = 2,  /* beginning of input (or line if multiline) */
>     REOP_EOL        = 3,  /* end of input (or line if multiline) */
>     REOP_WBDRY      = 4,  /* match "" at word boundary */
>     REOP_WNONBDRY   = 5,  /* match "" at word non-boundary */
>     REOP_QUANT      = 6,  /* quantified atom: atom{1,2} */
>     REOP_STAR       = 7,  /* zero or more occurrences of kid */
>     REOP_PLUS       = 8,  /* one or more occurrences of kid */
>     REOP_OPT        = 9,  /* optional subexpression in kid */
>     REOP_LPAREN     = 10, /* left paren bytecode: kid is u.num'th sub-regexp */
>     REOP_RPAREN     = 11, /* right paren bytecode */
>     REOP_DOT        = 12, /* stands for any character */
>     REOP_CCLASS     = 13, /* character class: [a-f] */
>     REOP_DIGIT      = 14, /* match a digit char: [0-9] */
>     REOP_NONDIGIT   = 15, /* match a non-digit char: [^0-9] */
>     REOP_ALNUM      = 16, /* match an alphanumeric char: [0-9a-z_A-Z] */
>     REOP_NONALNUM   = 17, /* match a non-alphanumeric char: [^0-9a-z_A-Z] */
>     REOP_SPACE      = 18, /* match a whitespace char */
>     REOP_NONSPACE   = 19, /* match a non-whitespace char */
>     REOP_BACKREF    = 20, /* back-reference (e.g., \1) to a parenthetical */
>     REOP_FLAT       = 21, /* match a flat string */
>     REOP_FLAT1      = 22, /* match a single char */
>     REOP_JUMP       = 23, /* for deoptimized closure loops */
>     REOP_DOTSTAR    = 24, /* optimize .* to use a single opcode */
>     REOP_ANCHOR     = 25, /* like .* but skips left context to unanchored r.e. */
>     REOP_EOLONLY    = 26, /* $ not preceded by any pattern */
>     REOP_UCFLAT     = 27, /* flat Unicode string; len immediate counts chars */
>     REOP_UCFLAT1    = 28, /* single Unicode char */
>     REOP_UCCLASS    = 29, /* Unicode character class, vector of chars to match */
>     REOP_NUCCLASS   = 30, /* negated Unicode character class */
>     REOP_BACKREFi   = 31, /* case-independent REOP_BACKREF */
>     REOP_FLATi      = 32, /* case-independent REOP_FLAT */
>     REOP_FLAT1i     = 33, /* case-independent REOP_FLAT1 */
>     REOP_UCFLATi    = 34, /* case-independent REOP_UCFLAT */
>     REOP_UCFLAT1i   = 35, /* case-independent REOP_UCFLAT1 */
>     REOP_ANCHOR1    = 36, /* first-char discriminating REOP_ANCHOR */
>     REOP_NCCLASS    = 37, /* negated 8-bit character class */
>     REOP_DOTSTARMIN = 38, /* ungreedy version of REOP_DOTSTAR */
>     REOP_LPARENNON  = 39, /* non-capturing version of REOP_LPAREN */
>     REOP_RPARENNON  = 40, /* non-capturing version of REOP_RPAREN */
>     REOP_ASSERT     = 41, /* zero width positive lookahead assertion */
>     REOP_ASSERT_NOT = 42, /* zero width negative lookahead assertion */
>     REOP_END
> } REOp;
122,126c115
< static void
< re_debug_chars(const jschar *chrs, size_t length)
< {
< }
< #endif /* !REGEXP_DEBUG */
---
> #define REOP_FLATLEN_MAX 255    /* maximum length of FLAT string */
129c118,122
<     REOp            op;         /* r.e. op bytecode */
---
>     uint8           op;         /* packed r.e. op bytecode */
>     uint8           flags;      /* flags, see below */
> #ifdef DEBUG
>     uint16          offset;     /* bytecode offset */
> #endif
133,156c126,137
<         void        *kid2;      /* second operand */
<         jsint       num;        /* could be a number */
<         size_t      parenIndex; /* or a parenthesis index */
<         struct {                /* or a quantifier range */
<             uintN  min;
<             uintN  max;
<             JSPackedBool greedy;
<         } range;
<         struct {                /* or a character class */
<             size_t  startIndex;
<             size_t  kidlen;     /* length of string at kid, in jschars */
<             size_t  index;      /* index into class list */
<             uint16  bmsize;     /* bitmap size, based on max char code */
<             JSPackedBool sense;
<         } ucclass;
<         struct {                /* or a literal sequence */
<             jschar  chr;        /* of one character */
<             size_t  length;     /* or many (via the kid) */
<         } flat;
<         struct {
<             RENode  *kid2;      /* second operand from ALT */
<             jschar  ch1;        /* match char for ALTPREREQ */
<             jschar  ch2;        /* ditto, or class index for ALTPREREQ2 */
<         } altprereq;
---
> 	void        *kid2;      /* second operand */
> 	jsint       num;        /* could be a number */
> 	jschar      chr;        /* or a character */
> 	struct {                /* or a quantifier range */
> 	    uint16  min;
> 	    uint16  max;
> 	} range;
> 	struct {                /* or a Unicode character class */
> 	    uint16  kidlen;     /* length of string at kid, in jschars */
> 	    uint16  bmsize;     /* bitmap size, based on max char code */
>             uint8   *bitmap;
> 	} ucclass;
160,163c141
< #define RE_IS_LETTER(c)     (((c >= 'A') && (c <= 'Z')) ||                    \
<                              ((c >= 'a') && (c <= 'z')) )
< #define RE_IS_LINE_TERM(c)  ((c == '\n') || (c == '\r') ||                    \
<                              (c == LINE_SEPARATOR) || (c == PARA_SEPARATOR))
---
> #define REOP(ren)   ((REOp)(ren)->op)
165c143,150
< #define CLASS_CACHE_SIZE    4
---
> #define RENODE_ANCHORED 0x01    /* anchored at the front */
> #define RENODE_SINGLE   0x02    /* matches a single char */
> #define RENODE_NONEMPTY 0x04    /* does not match empty string */
> #define RENODE_ISNEXT   0x08    /* ren is next after at least one node */
> #define RENODE_GOODNEXT 0x10    /* ren->next is a tree-like edge in the graph */
> #define RENODE_ISJOIN   0x20    /* ren is a join point in the graph */
> #define RENODE_REALLOK  0x40    /* REOP_FLAT owns tempPool space to realloc */
> #define RENODE_MINIMAL  0x80    /* un-greedy matching for ? * + {} */
173,184c158,160
<     size_t          parenCount;
<     size_t          classCount;   /* number of [] encountered */
<     size_t          treeDepth;    /* maximum depth of parse tree */
<     size_t          progLength;   /* estimated bytecode length */
<     RENode          *result;
<     size_t          classBitmapsMem; /* memory to hold all class bitmaps */
<     struct {
<         const jschar *start;        /* small cache of class strings */
<         size_t length;              /* since they're often the same */
<         size_t index;
<     } classCache[CLASS_CACHE_SIZE];
<     uint16          flags;
---
>     uintN           flags;
>     uintN           parenCount;
>     size_t          progLength;
187,196c163
< typedef struct EmitStateStackEntry {
<     jsbytecode      *altHead;       /* start of REOP_ALT* opcode */
<     jsbytecode      *nextAltFixup;  /* fixup pointer to next-alt offset */
<     jsbytecode      *nextTermFixup; /* fixup ptr. to REOP_JUMP offset */
<     jsbytecode      *endTermFixup;  /* fixup ptr. to REOPT_ALTPREREQ* offset */
<     RENode          *continueNode;  /* original REOP_ALT* node being stacked */
<     jsbytecode      continueOp;     /* REOP_JUMP or REOP_ENDALT continuation */
<     JSPackedBool    jumpToJumpFlag; /* true if we've patched jump-to-jump to
<                                        avoid 16-bit unsigned offset overflow */
< } EmitStateStackEntry;
---
> #ifdef DEBUG
198,216c165
< /*
<  * Immediate operand sizes and getter/setters.  Unlike the ones in jsopcode.h,
<  * the getters and setters take the pc of the offset, not of the opcode before
<  * the offset.
<  */
< #define ARG_LEN             2
< #define GET_ARG(pc)         ((uint16)(((pc)[0] << 8) | (pc)[1]))
< #define SET_ARG(pc, arg)    ((pc)[0] = (jsbytecode) ((arg) >> 8),       \
<                              (pc)[1] = (jsbytecode) (arg))
< 
< #define OFFSET_LEN          ARG_LEN
< #define OFFSET_MAX          (JS_BIT(ARG_LEN * 8) - 1)
< #define GET_OFFSET(pc)      GET_ARG(pc)
< 
< /*
<  * Maximum supported tree depth is maximum size of EmitStateStackEntry stack.
<  * For sanity, we limit it to 2^24 bytes.
<  */
< #define TREE_DEPTH_MAX  (JS_BIT(24) / sizeof(EmitStateStackEntry))
---
> #include <stdio.h>
218,222c167,212
< /*
<  * The maximum memory that can be allocated for class bitmaps.
<  * For sanity, we limit it to 2^24 bytes.
<  */
< #define CLASS_BITMAPS_MEM_LIMIT JS_BIT(24)
---
> static char *reopname[] = {
>     "empty",
>     "alt",
>     "bol",
>     "eol",
>     "wbdry",
>     "wnonbdry",
>     "quant",
>     "star",
>     "plus",
>     "opt",
>     "lparen",
>     "rparen",
>     "dot",
>     "cclass",
>     "digit",
>     "nondigit",
>     "alnum",
>     "nonalnum",
>     "space",
>     "nonspace",
>     "backref",
>     "flat",
>     "flat1",
>     "jump",
>     "dotstar",
>     "anchor",
>     "eolonly",
>     "ucflat",
>     "ucflat1",
>     "ucclass",
>     "nucclass",
>     "backrefi",
>     "flati",
>     "flat1i",
>     "ucflati",
>     "ucflat1i",
>     "anchor1",
>     "ncclass",
>     "dotstar_min",
>     "lparen_non",
>     "rparen_non",
>     "assert",
>     "assert_not",
>     "end"
> };
224,232c214,215
< /*
<  * Functions to get size and write/read bytecode that represent small indexes
<  * compactly.
<  * Each byte in the code represent 7-bit chunk of the index. 8th bit when set
<  * indicates that the following byte brings more bits to the index. Otherwise
<  * this is the last byte in the index bytecode representing highest index bits.
<  */
< static size_t
< GetCompactIndexWidth(size_t index)
---
> static void
> PrintChar(jschar c)
234,237c217,225
<     size_t width;
< 
<     for (width = 1; (index >>= 7) != 0; ++width) { }
<     return width;
---
>     if (c >> 8)
> 	printf("\\u%04X", c);
>     else
> #if defined _MSC_VER && _MSC_VER <= 800
> 	/* XXX is there a better way with MSVC1.52? */
> 	printf("%c", c);
> #else
> 	putchar((char)c);
> #endif
240,251c228
< JS_INLINE(static jsbytecode *
< WriteCompactIndex(jsbytecode *pc, size_t index))
< {
<     size_t next;
< 
<     while ((next = index >> 7) != 0) {
<         *pc++ = (jsbytecode)(index | 0x80);
<         index = next;
<     }
<     *pc++ = (jsbytecode)index;
<     return pc;
< }
---
> static int gOffset = 0;
253,254c230,232
< JS_INLINE(static jsbytecode *
< ReadCompactIndex(jsbytecode *pc, size_t *result))
---
> #ifdef _UTF8
> static JSBool
> DumpRegExp(JSContext *cx, RENode *ren)
256,273c234,370
<     size_t nextByte;
< 
<     nextByte = *pc++;
<     if ((nextByte & 0x80) == 0) {
<         /*
<          * Short-circuit the most common case when compact index <= 127.
<          */
<         *result = nextByte;
<     } else {
<         size_t shift = 7;
<         *result = 0x7F & nextByte;
<         do {
<             nextByte = *pc++;
<             *result |= (nextByte & 0x7F) << shift;
<             shift += 7;
<         } while ((nextByte & 0x80) != 0);
<     }
<     return pc;
---
>     static int level;
>     JSBool ok;
>     int i, len;
>     jschar *cp;
>     char *cstr;
> 	size_t mbLength;
> 
>     if (level == 0)
> 	printf("level offset  flags  description\n");
>     level++;
>     ok = JS_TRUE;
>     do {
> 	printf("%5d %6d %6d %c%c%c%c%c%c%c  %s",
> 	       level,
>                (int)ren->offset, (ren->next) ? (int)ren->next->offset : -1,
> 	       (ren->flags & RENODE_ANCHORED) ? 'A' : '-',
> 	       (ren->flags & RENODE_SINGLE)   ? 'S' : '-',
> 	       (ren->flags & RENODE_NONEMPTY) ? 'F' : '-',	/* F for full */
> 	       (ren->flags & RENODE_ISNEXT)   ? 'N' : '-',	/* N for next */
> 	       (ren->flags & RENODE_GOODNEXT) ? 'G' : '-',
> 	       (ren->flags & RENODE_ISJOIN)   ? 'J' : '-',
> 	       (ren->flags & RENODE_MINIMAL)  ? 'M' : '-',
> 	       reopname[ren->op]);
> 
> 	switch (REOP(ren)) {
> 	  case REOP_ALT:
> 	    printf(" %d\n", ren->next->offset);
> 	    ok = DumpRegExp(cx, (RENode*) ren->kid);
> 	    if (!ok)
> 		goto out;
> 	    break;
> 
> 	  case REOP_STAR:
> 	  case REOP_PLUS:
> 	  case REOP_OPT:
> 	  case REOP_ANCHOR1:
> 	  case REOP_ASSERT:
> 	  case REOP_ASSERT_NOT:
> 	    printf("\n");
> 	    ok = DumpRegExp(cx, (RENode*) ren->kid);
> 	    if (!ok)
> 		goto out;
> 	    break;
> 
> 	  case REOP_QUANT:
> 	    printf(" next %d min %d max %d\n",
> 		   ren->next->offset, ren->u.range.min, ren->u.range.max);
> 	    ok = DumpRegExp(cx, (RENode*) ren->kid);
> 	    if (!ok)
> 		goto out;
> 	    break;
> 
> 	  case REOP_LPAREN:
> 	    printf(" num %d\n", (int)ren->u.num);
> 	    ok = DumpRegExp(cx, (RENode*) ren->kid);
> 	    if (!ok)
> 		goto out;
> 	    break;
> 
> 	  case REOP_LPARENNON:
>             printf("\n");
> 	    ok = DumpRegExp(cx, (RENode*) ren->kid);
> 	    if (!ok)
> 		goto out;
> 	    break;
> 
> 	  case REOP_RPAREN:
> 	    printf(" num %d\n", (int)ren->u.num);
> 	    break;
> 
> 	  case REOP_CCLASS:
> 	    len = (jschar *)ren->u.kid2 - (jschar *)ren->kid;
> 	    cstr = js_DeflateString(cx, (jschar *)ren->kid, len,&mbLength);
> 	    if (!cstr) {
> 		ok = JS_FALSE;
> 		goto out;
> 	    }
> 	    printf(" [%s]\n", cstr);
> 	    JS_free(cx, cstr);
> 	    break;
> 
> 	  case REOP_BACKREF:
> 	    printf(" num %d\n", (int)ren->u.num);
> 	    break;
> 
> 	  case REOP_FLAT:
> 	    len = (jschar *)ren->u.kid2 - (jschar *)ren->kid;
> 	    cstr = js_DeflateString(cx, (jschar *)ren->kid, len,&mbLength);
> 	    if (!cstr) {
> 		ok = JS_FALSE;
> 		goto out;
> 	    }
> 	    printf(" %s (%d)\n", cstr, len);
> 	    JS_free(cx, cstr);
> 	    break;
> 
> 	  case REOP_FLAT1:
> 	    printf(" %c ('\\%o')\n", (char)ren->u.chr, ren->u.chr);
> 	    break;
> 
> 	  case REOP_JUMP:
> 	    printf(" %d\n", ren->next->offset);
> 	    break;
> 
> 	  case REOP_UCFLAT:
> 	    cp = (jschar*) ren->kid;
> 	    len = (jschar *)ren->u.kid2 - cp;
> 	    for (i = 0; i < len; i++)
> 		PrintChar(cp[i]);
>             printf("\n");
> 	    break;
> 
> 	  case REOP_UCFLAT1:
> 	    PrintChar(ren->u.chr);
> 	    printf("\n");
> 	    break;
> 
> 	  case REOP_UCCLASS:
> 	    cp = (jschar*) ren->kid;
> 	    len = ren->u.ucclass.kidlen;
> 	    printf(" [");
> 	    for (i = 0; i < len; i++)
> 		PrintChar(cp[i]);
> 	    printf("]\n");
> 	    break;
> 
> 	  default:
> 	    printf("\n");
> 	    break;
> 	}
> 
> 	if (!(ren->flags & RENODE_GOODNEXT))
> 	    break;
>     } while ((ren = ren->next) != NULL);
> out:
>     level--;
>     return ok;
275,357c372,374
< 
< typedef struct RECapture {
<     ptrdiff_t index;           /* start of contents, -1 for empty  */
<     size_t length;             /* length of capture */
< } RECapture;
< 
< typedef struct REMatchState {
<     const jschar *cp;
<     RECapture parens[1];      /* first of 're->parenCount' captures,
<                                  allocated at end of this struct */
< } REMatchState;
< 
< struct REBackTrackData;
< 
< typedef struct REProgState {
<     jsbytecode *continue_pc;        /* current continuation data */
<     jsbytecode continue_op;
<     ptrdiff_t index;                /* progress in text */
<     size_t parenSoFar;              /* highest indexed paren started */
<     union {
<         struct {
<             uintN min;             /* current quantifier limits */
<             uintN max;
<         } quantifier;
<         struct {
<             size_t top;             /* backtrack stack state */
<             size_t sz;
<         } assertion;
<     } u;
< } REProgState;
< 
< typedef struct REBackTrackData {
<     size_t sz;                      /* size of previous stack entry */
<     jsbytecode *backtrack_pc;       /* where to backtrack to */
<     jsbytecode backtrack_op;
<     const jschar *cp;               /* index in text of match at backtrack */
<     size_t parenIndex;              /* start index of saved paren contents */
<     size_t parenCount;              /* # of saved paren contents */
<     size_t saveStateStackTop;       /* number of parent states */
<     /* saved parent states follow */
<     /* saved paren contents follow */
< } REBackTrackData;
< 
< #define INITIAL_STATESTACK  100
< #define INITIAL_BACKTRACK   8000
< 
< typedef struct REGlobalData {
<     JSContext *cx;
<     JSRegExp *regexp;               /* the RE in execution */
<     JSBool ok;                      /* runtime error (out_of_memory only?) */
<     size_t start;                   /* offset to start at */
<     ptrdiff_t skipped;              /* chars skipped anchoring this r.e. */
<     const jschar    *cpbegin;       /* text base address */
<     const jschar    *cpend;         /* text limit address */
< 
<     REProgState *stateStack;        /* stack of state of current parents */
<     size_t stateStackTop;
<     size_t stateStackLimit;
< 
<     REBackTrackData *backTrackStack;/* stack of matched-so-far positions */
<     REBackTrackData *backTrackSP;
<     size_t backTrackStackSize;
<     size_t cursz;                   /* size of current stack entry */
<     size_t backTrackCount;          /* how many times we've backtracked */
<     size_t backTrackLimit;          /* upper limit on backtrack states */
< 
<     JSArenaPool     pool;           /* It's faster to use one malloc'd pool
<                                        than to malloc/free the three items
<                                        that are allocated from this pool */
< } REGlobalData;
< 
< /*
<  * 1. If IgnoreCase is false, return ch.
<  * 2. Let u be ch converted to upper case as if by calling
<  *    String.prototype.toUpperCase on the one-character string ch.
<  * 3. If u does not consist of a single character, return ch.
<  * 4. Let cu be u's character.
<  * 5. If ch's code point value is greater than or equal to decimal 128 and cu's
<  *    code point value is less than decimal 128, then return ch.
<  * 6. Return cu.
<  */
< JS_INLINE(static uintN
< upcase(uintN ch))
---
> #else //#ifdef _UTF8
> static JSBool
> DumpRegExp(JSContext *cx, RENode *ren)
359,369c376,511
<     uintN cu;
< 
<     JS_ASSERT((uintN) (jschar) ch == ch);
<     if (ch < 128) {
<         if (ch - (uintN) 'a' <= (uintN) ('z' - 'a'))
<             ch -= (uintN) ('a' - 'A');
<         return ch;
<     }
< 
<     cu = JS_TOUPPER(ch);
<     return (cu < 128) ? ch : cu;
---
>     static int level;
>     JSBool ok;
>     int i, len;
>     jschar *cp;
>     char *cstr;
> 
>     if (level == 0)
> 	printf("level offset  flags  description\n");
>     level++;
>     ok = JS_TRUE;
>     do {
> 	printf("%5d %6d %6d %c%c%c%c%c%c%c  %s",
> 	       level,
>                (int)ren->offset, (ren->next) ? (int)ren->next->offset : -1,
> 	       (ren->flags & RENODE_ANCHORED) ? 'A' : '-',
> 	       (ren->flags & RENODE_SINGLE)   ? 'S' : '-',
> 	       (ren->flags & RENODE_NONEMPTY) ? 'F' : '-',	/* F for full */
> 	       (ren->flags & RENODE_ISNEXT)   ? 'N' : '-',	/* N for next */
> 	       (ren->flags & RENODE_GOODNEXT) ? 'G' : '-',
> 	       (ren->flags & RENODE_ISJOIN)   ? 'J' : '-',
> 	       (ren->flags & RENODE_MINIMAL)  ? 'M' : '-',
> 	       reopname[ren->op]);
> 
> 	switch (REOP(ren)) {
> 	  case REOP_ALT:
> 	    printf(" %d\n", ren->next->offset);
> 	    ok = DumpRegExp(cx, (RENode*) ren->kid);
> 	    if (!ok)
> 		goto out;
> 	    break;
> 
> 	  case REOP_STAR:
> 	  case REOP_PLUS:
> 	  case REOP_OPT:
> 	  case REOP_ANCHOR1:
> 	  case REOP_ASSERT:
> 	  case REOP_ASSERT_NOT:
> 	    printf("\n");
> 	    ok = DumpRegExp(cx, (RENode*) ren->kid);
> 	    if (!ok)
> 		goto out;
> 	    break;
> 
> 	  case REOP_QUANT:
> 	    printf(" next %d min %d max %d\n",
> 		   ren->next->offset, ren->u.range.min, ren->u.range.max);
> 	    ok = DumpRegExp(cx, (RENode*) ren->kid);
> 	    if (!ok)
> 		goto out;
> 	    break;
> 
> 	  case REOP_LPAREN:
> 	    printf(" num %d\n", (int)ren->u.num);
> 	    ok = DumpRegExp(cx, (RENode*) ren->kid);
> 	    if (!ok)
> 		goto out;
> 	    break;
> 
> 	  case REOP_LPARENNON:
>             printf("\n");
> 	    ok = DumpRegExp(cx, (RENode*) ren->kid);
> 	    if (!ok)
> 		goto out;
> 	    break;
> 
> 	  case REOP_RPAREN:
> 	    printf(" num %d\n", (int)ren->u.num);
> 	    break;
> 
> 	  case REOP_CCLASS:
> 	    len = (jschar *)ren->u.kid2 - (jschar *)ren->kid;
> 	    cstr = js_DeflateString(cx, (jschar *)ren->kid, len);
> 	    if (!cstr) {
> 		ok = JS_FALSE;
> 		goto out;
> 	    }
> 	    printf(" [%s]\n", cstr);
> 	    JS_free(cx, cstr);
> 	    break;
> 
> 	  case REOP_BACKREF:
> 	    printf(" num %d\n", (int)ren->u.num);
> 	    break;
> 
> 	  case REOP_FLAT:
> 	    len = (jschar *)ren->u.kid2 - (jschar *)ren->kid;
> 	    cstr = js_DeflateString(cx, (jschar *)ren->kid, len);
> 	    if (!cstr) {
> 		ok = JS_FALSE;
> 		goto out;
> 	    }
> 	    printf(" %s (%d)\n", cstr, len);
> 	    JS_free(cx, cstr);
> 	    break;
> 
> 	  case REOP_FLAT1:
> 	    printf(" %c ('\\%o')\n", (char)ren->u.chr, ren->u.chr);
> 	    break;
> 
> 	  case REOP_JUMP:
> 	    printf(" %d\n", ren->next->offset);
> 	    break;
> 
> 	  case REOP_UCFLAT:
> 	    cp = (jschar*) ren->kid;
> 	    len = (jschar *)ren->u.kid2 - cp;
> 	    for (i = 0; i < len; i++)
> 		PrintChar(cp[i]);
>             printf("\n");
> 	    break;
> 
> 	  case REOP_UCFLAT1:
> 	    PrintChar(ren->u.chr);
> 	    printf("\n");
> 	    break;
> 
> 	  case REOP_UCCLASS:
> 	    cp = (jschar*) ren->kid;
> 	    len = ren->u.ucclass.kidlen;
> 	    printf(" [");
> 	    for (i = 0; i < len; i++)
> 		PrintChar(cp[i]);
> 	    printf("]\n");
> 	    break;
> 
> 	  default:
> 	    printf("\n");
> 	    break;
> 	}
> 
> 	if (!(ren->flags & RENODE_GOODNEXT))
> 	    break;
>     } while ((ren = ren->next) != NULL);
> out:
>     level--;
>     return ok;
370a513
> #endif //#ifdef _UTF8
372,383c515
< JS_INLINE(static uintN
< downcase(uintN ch))
< {
<     JS_ASSERT((uintN) (jschar) ch == ch);
<     if (ch < 128) {
<         if (ch - (uintN) 'A' <= (uintN) ('Z' - 'A'))
<             ch += (uintN) ('a' - 'A');
<         return ch;
<     }
< 
<     return JS_TOLOWER(ch);
< }
---
> #endif /* DEBUG */
385d516
< /* Construct and initialize an RENode, returning NULL for out-of-memory */
387c518
< NewRENode(CompilerState *state, REOp op)
---
> NewRENode(CompilerState *state, REOp op, void *kid)
393c524,525
<     JS_ARENA_ALLOCATE_CAST(ren, RENode *, &cx->tempPool, sizeof *ren);
---
> 	XMEMTAG("jsregexp NewRENode");
>     ren = (RENode*) JS_malloc(cx, sizeof *ren);
395,396c527,528
<         js_ReportOutOfScriptQuota(cx);
<         return NULL;
---
> 	JS_ReportOutOfMemory(cx);
> 	return NULL;
398c530,534
<     ren->op = op;
---
>     ren->op = (uint8)op;
>     ren->flags = 0;
> #ifdef DEBUG
>     ren->offset = gOffset++;
> #endif
400c536
<     ren->kid = NULL;
---
>     ren->kid = kid;
404,406d539
< /*
<  * Validates and converts hex ascii value.
<  */
408c541
< isASCIIHexDigit(jschar c, uintN *digit)
---
> FixNext(CompilerState *state, RENode *ren1, RENode *ren2, RENode *oldnext)
410c543,544
<     uintN cv = c;
---
>     JSBool goodnext;
>     RENode *next, *kid, *ren;
412,445c546
<     if (cv < '0')
<         return JS_FALSE;
<     if (cv <= '9') {
<         *digit = cv - '0';
<         return JS_TRUE;
<     }
<     cv |= 0x20;
<     if (cv >= 'a' && cv <= 'f') {
<         *digit = cv - 'a' + 10;
<         return JS_TRUE;
<     }
<     return JS_FALSE;
< }
< 
< 
< typedef struct {
<     REOp op;
<     const jschar *errPos;
<     size_t parenIndex;
< } REOpData;
< 
< static JSBool
< ReportRegExpErrorHelper(CompilerState *state, uintN flags, uintN errorNumber,
<                         const jschar *arg)
< {
<     if (state->tokenStream) {
<         return js_ReportCompileErrorNumber(state->context, state->tokenStream,
<                                            NULL, JSREPORT_UC | flags,
<                                            errorNumber, arg);
<     }
<     return JS_ReportErrorFlagsAndNumberUC(state->context, flags,
<                                           js_GetErrorMessage, NULL,
<                                           errorNumber, arg);
< }
---
>     goodnext = ren2 && !(ren2->flags & RENODE_ISNEXT);
447,451c548,573
< static JSBool
< ReportRegExpError(CompilerState *state, uintN flags, uintN errorNumber)
< {
<     return ReportRegExpErrorHelper(state, flags, errorNumber, NULL);
< }
---
>     /*
>      * Find the final node in a list of alternatives, or concatenations, or
>      * even a concatenation of alternatives followed by non-alternatives (e.g.
>      * ((x|y)z)w where ((x|y)z) is ren1 and w is ren2).
>      */
>     for (; (next = ren1->next) != NULL && next != oldnext; ren1 = next) {
> 	if (REOP(ren1) == REOP_ALT) {
> 	    /* Find the end of this alternative's operand list. */
> 	    kid = (RENode*) ren1->kid;
> 	    if (REOP(kid) == REOP_JUMP)
> 		continue;
> 	    for (ren = kid; ren->next; ren = ren->next)
> 		JS_ASSERT(REOP(ren) != REOP_ALT);
> 
> 	    /* Append a jump node to all but the last alternative. */
> 	    ren->next = NewRENode(state, REOP_JUMP, NULL);
> 	    if (!ren->next)
> 		return JS_FALSE;
> 	    ren->next->flags |= RENODE_ISNEXT;
> 	    ren->flags |= RENODE_GOODNEXT;
> 
> 	    /* Recur to fix all descendent nested alternatives. */
> 	    if (!FixNext(state, kid, ren2, oldnext))
> 		return JS_FALSE;
> 	}
>     }
453,461c575,588
< /*
<  * Process the op against the two top operands, reducing them to a single
<  * operand in the penultimate slot. Update progLength and treeDepth.
<  */
< static JSBool
< ProcessOp(CompilerState *state, REOpData *opData, RENode **operandStack,
<           intN operandSP)
< {
<     RENode *result;
---
>     /*
>      * Now ren1 points to the last alternative, or to the final node on a
>      * concatenation list.  Set its next link to ren2, flagging a join point
>      * if appropriate.
>      */
>     if (ren2) {
> 	if (!(ren2->flags & RENODE_ISNEXT))
> 	    ren2->flags |= RENODE_ISNEXT;
> 	else
> 	    ren2->flags |= RENODE_ISJOIN;
>     }
>     ren1->next = ren2;
>     if (goodnext)
> 	ren1->flags |= RENODE_GOODNEXT;
463c590,594
<     switch (opData->op) {
---
>     /*
>      * The following ops have a kid subtree through which to recur.  Here is
>      * where we fix the next links under the final ALT node's kid.
>      */
>     switch (REOP(ren1)) {
465,529c596,601
<         result = NewRENode(state, REOP_ALT);
<         if (!result)
<             return JS_FALSE;
<         result->kid = operandStack[operandSP - 2];
<         result->u.kid2 = operandStack[operandSP - 1];
<         operandStack[operandSP - 2] = result;
< 
<         if (state->treeDepth == TREE_DEPTH_MAX) {
<             ReportRegExpError(state, JSREPORT_ERROR, JSMSG_REGEXP_TOO_COMPLEX);
<             return JS_FALSE;
<         }
<         ++state->treeDepth;
< 
<         /*
<          * Look at both alternates to see if there's a FLAT or a CLASS at
<          * the start of each. If so, use a prerequisite match.
<          */
<         if (((RENode *) result->kid)->op == REOP_FLAT &&
<             ((RENode *) result->u.kid2)->op == REOP_FLAT &&
<             (state->flags & JSREG_FOLD) == 0) {
<             result->op = REOP_ALTPREREQ;
<             result->u.altprereq.ch1 = ((RENode *) result->kid)->u.flat.chr;
<             result->u.altprereq.ch2 = ((RENode *) result->u.kid2)->u.flat.chr;
<             /* ALTPREREQ, <end>, uch1, uch2, <next>, ...,
<                                             JUMP, <end> ... ENDALT */
<             state->progLength += 13;
<         }
<         else
<         if (((RENode *) result->kid)->op == REOP_CLASS &&
<             ((RENode *) result->kid)->u.ucclass.index < 256 &&
<             ((RENode *) result->u.kid2)->op == REOP_FLAT &&
<             (state->flags & JSREG_FOLD) == 0) {
<             result->op = REOP_ALTPREREQ2;
<             result->u.altprereq.ch1 = ((RENode *) result->u.kid2)->u.flat.chr;
<             result->u.altprereq.ch2 = ((RENode *) result->kid)->u.ucclass.index;
<             /* ALTPREREQ2, <end>, uch1, uch2, <next>, ...,
<                                             JUMP, <end> ... ENDALT */
<             state->progLength += 13;
<         }
<         else
<         if (((RENode *) result->kid)->op == REOP_FLAT &&
<             ((RENode *) result->u.kid2)->op == REOP_CLASS &&
<             ((RENode *) result->u.kid2)->u.ucclass.index < 256 &&
<             (state->flags & JSREG_FOLD) == 0) {
<             result->op = REOP_ALTPREREQ2;
<             result->u.altprereq.ch1 = ((RENode *) result->kid)->u.flat.chr;
<             result->u.altprereq.ch2 =
<                 ((RENode *) result->u.kid2)->u.ucclass.index;
<             /* ALTPREREQ2, <end>, uch1, uch2, <next>, ...,
<                                           JUMP, <end> ... ENDALT */
<             state->progLength += 13;
<         }
<         else {
<             /* ALT, <next>, ..., JUMP, <end> ... ENDALT */
<             state->progLength += 7;
<         }
<         break;
< 
<       case REOP_CONCAT:
<         result = operandStack[operandSP - 2];
<         while (result->next)
<             result = result->next;
<         result->next = operandStack[operandSP - 1];
<         break;
< 
---
>       case REOP_QUANT:
>       case REOP_STAR:
>       case REOP_PLUS:
>       case REOP_OPT:
>       case REOP_LPAREN:
>       case REOP_LPARENNON:
532,538c604,606
<       case REOP_LPARENNON:
<       case REOP_LPAREN:
<         /* These should have been processed by a close paren. */
<         ReportRegExpErrorHelper(state, JSREPORT_ERROR, JSMSG_MISSING_PAREN,
<                                 opData->errPos);
<         return JS_FALSE;
< 
---
> 	if (!FixNext(state, (RENode*) ren1->kid, ren2, oldnext))
> 	    return JS_FALSE;
> 	break;
543a612,617
> static JSBool
> SetNext(CompilerState *state, RENode *ren1, RENode *ren2)
> {
>     return FixNext(state, ren1, ren2, NULL);
> }
> 
547,549c621,627
< static JSBool ParseTerm(CompilerState *state);
< static JSBool ParseQuantifier(CompilerState *state);
< static intN ParseMinMaxQuantifier(CompilerState *state, JSBool ignoreValues);
---
> typedef RENode *REParser(CompilerState *state);
> 
> static REParser ParseRegExp;
> static REParser ParseAltern;
> static REParser ParseItem;
> static REParser ParseQuantAtom;
> static REParser ParseAtom;
557,559c635
< #define INITIAL_STACK_SIZE  128
< 
< static JSBool
---
> static RENode *
562,571c638,639
<     size_t parenIndex;
<     RENode *operand;
<     REOpData *operatorStack;
<     RENode **operandStack;
<     REOp op;
<     intN i;
<     JSBool result = JS_FALSE;
< 
<     intN operatorSP = 0, operatorStackSize = INITIAL_STACK_SIZE;
<     intN operandSP = 0, operandStackSize = INITIAL_STACK_SIZE;
---
>     RENode *ren, *kid, *ren1, *ren2;
>     const jschar *cp;
573,576c641,671
<     /* Watch out for empty regexp */
<     if (state->cp == state->cpend) {
<         state->result = NewRENode(state, REOP_EMPTY);
<         return (state->result != NULL);
---
>     ren = ParseAltern(state);
>     if (!ren)
> 	return NULL;
>     cp = state->cp;
>     if ((cp < state->cpend) && (*cp == '|')) {
> 	kid = ren;
> 	ren = NewRENode(state, REOP_ALT, kid);
> 	if (!ren)
> 	    return NULL;
> 	ren->flags = kid->flags & (RENODE_ANCHORED | RENODE_NONEMPTY);
> 	ren1 = ren;
> 	do {
> 	    /* (balance: */
> 	    state->cp = ++cp;
> 	    if (*cp == '|' || *cp == ')') {
> 		kid = NewRENode(state, REOP_EMPTY, NULL);
> 	    } else {
> 		kid = ParseAltern(state);
> 		cp = state->cp;
> 	    }
> 	    if (!kid)
> 		return NULL;
> 	    ren2 = NewRENode(state, REOP_ALT, kid);
> 	    if (!ren2)
> 		return NULL;
> 	    ren1->next = ren2;
> 	    ren1->flags |= RENODE_GOODNEXT;
> 	    ren2->flags = (kid->flags & (RENODE_ANCHORED | RENODE_NONEMPTY))
> 			  | RENODE_ISNEXT;
> 	    ren1 = ren2;
> 	} while ((cp < state->cpend) && (*cp == '|'));
577a673,674
>     return ren;
> }
579,582c676,686
<     operatorStack = (REOpData *)
<         JS_malloc(state->context, sizeof(REOpData) * operatorStackSize);
<     if (!operatorStack)
<         return JS_FALSE;
---
> /*
>  *  altern:     item                    An alternative is one or more items,
>  *              item altern             concatenated together.
>  */
> static RENode *
> ParseAltern(CompilerState *state)
> {
>     RENode *ren, *ren1, *ren2;
>     uintN flags;
>     const jschar *cp;
>     jschar c;
584,587c688,703
<     operandStack = (RENode **)
<         JS_malloc(state->context, sizeof(RENode *) * operandStackSize);
<     if (!operandStack)
<         goto out;
---
>     ren = ren1 = ParseItem(state);
>     if (!ren)
> 	return NULL;
>     flags = 0;
>     cp = state->cp;
>     /* (balance: */
>     while ((cp < state->cpend) && (c = *cp) != '|' && c != ')') {
> 	ren2 = ParseItem(state);
> 	if (!ren2)
> 	    return NULL;
> 	if (!SetNext(state, ren1, ren2))
> 	    return NULL;
> 	flags |= ren2->flags;
> 	ren1 = ren2;
> 	cp = state->cp;
>     }
589,640c705,713
<     for (;;) {
<         parenIndex = state->parenCount;
<         if (state->cp == state->cpend) {
<             /*
<              * If we are at the end of the regexp and we're short one or more
<              * operands, the regexp must have the form /x|/ or some such, with
<              * left parentheses making us short more than one operand.
<              */
<             if (operatorSP >= operandSP) {
<                 operand = NewRENode(state, REOP_EMPTY);
<                 if (!operand)
<                     goto out;
<                 goto pushOperand;
<             }
<         } else {
<             switch (*state->cp) {
<               case '(':
<                 ++state->cp;
<                 if (state->cp + 1 < state->cpend &&
<                     *state->cp == '?' &&
<                     (state->cp[1] == '=' ||
<                      state->cp[1] == '!' ||
<                      state->cp[1] == ':')) {
<                     switch (state->cp[1]) {
<                       case '=':
<                         op = REOP_ASSERT;
<                         /* ASSERT, <next>, ... ASSERTTEST */
<                         state->progLength += 4;
<                         break;
<                       case '!':
<                         op = REOP_ASSERT_NOT;
<                         /* ASSERTNOT, <next>, ... ASSERTNOTTEST */
<                         state->progLength += 4;
<                         break;
<                       default:
<                         op = REOP_LPARENNON;
<                         break;
<                     }
<                     state->cp += 2;
<                 } else {
<                     op = REOP_LPAREN;
<                     /* LPAREN, <index>, ... RPAREN, <index> */
<                     state->progLength
<                         += 2 * (1 + GetCompactIndexWidth(parenIndex));
<                     state->parenCount++;
<                     if (state->parenCount == 65535) {
<                         ReportRegExpError(state, JSREPORT_ERROR,
<                                           JSMSG_TOO_MANY_PARENS);
<                         goto out;
<                     }
<                 }
<                 goto pushOperator;
---
>     /*
>      * Propagate NONEMPTY to the front of a concatenation list, so that the
>      * first alternative in (^a|b) is considered non-empty.  The first node
>      * in a list may match the empty string (as ^ does), but if the list is
>      * non-empty, then the first node's NONEMPTY flag must be set.
>      */
>     ren->flags |= flags & RENODE_NONEMPTY;
>     return ren;
> }
642,659c715,733
<               case ')':
<                 /*
<                  * If there's no stacked open parenthesis, throw syntax error.
<                  */
<                 for (i = operatorSP - 1; ; i--) {
<                     if (i < 0) {
<                         ReportRegExpError(state, JSREPORT_ERROR,
<                                           JSMSG_UNMATCHED_RIGHT_PAREN);
<                         goto out;
<                     }
<                     if (operatorStack[i].op == REOP_ASSERT ||
<                         operatorStack[i].op == REOP_ASSERT_NOT ||
<                         operatorStack[i].op == REOP_LPARENNON ||
<                         operatorStack[i].op == REOP_LPAREN) {
<                         break;
<                     }
<                 }
<                 /* FALL THROUGH */
---
> /*
>  *  item:       assertion               An item is either an assertion or
>  *              quantatom               a quantified atom.
>  *
>  *  assertion:  '^'                     Assertions match beginning of string
>  *                                      (or line if the class static property
>  *                                      RegExp.multiline is true).
>  *              '$'                     End of string (or line if the class
>  *                                      static property RegExp.multiline is
>  *                                      true).
>  *              '\b'                    Word boundary (between \w and \W).
>  *              '\B'                    Word non-boundary.
>  */
> static RENode *
> ParseItem(CompilerState *state)
> {
>     const jschar *cp;
>     RENode *ren;
>     REOp op;
661,666c735,753
<               case '|':
<                 /* Expected an operand before these, so make an empty one */
<                 operand = NewRENode(state, REOP_EMPTY);
<                 if (!operand)
<                     goto out;
<                 goto pushOperand;
---
>     cp = state->cp;
>     if (cp < state->cpend)
>         switch (*cp) {
>           case '^':
> 	    state->cp = cp + 1;
> 	    ren = NewRENode(state, REOP_BOL, NULL);
> 	    if (ren)
> 	        ren->flags |= RENODE_ANCHORED;
> 	    return ren;
> 
>           case '$':
> 	    state->cp = cp + 1;
> 	    return NewRENode(state,
> 			     (cp == state->cpbegin ||
> 			      ((cp[-1] == '(' || cp[-1] == '|') && /*balance)*/
> 			       (cp - 1 == state->cpbegin || cp[-2] != '\\')))
> 			     ? REOP_EOLONLY
> 			     : REOP_EOL,
> 			     NULL);
668,686c755,775
<               default:
<                 if (!ParseTerm(state))
<                     goto out;
<                 operand = state->result;
< pushOperand:
<                 if (operandSP == operandStackSize) {
<                     RENode **tmp;
<                     operandStackSize += operandStackSize;
<                     tmp = (RENode **)
<                         JS_realloc(state->context, operandStack,
<                                    sizeof(RENode *) * operandStackSize);
<                     if (!tmp)
<                         goto out;
<                     operandStack = tmp;
<                 }
<                 operandStack[operandSP++] = operand;
<                 break;
<             }
<         }
---
>           case '\\':
> 	    switch (*++cp) {
> 	      case 'b':
> 	        op = REOP_WBDRY;
> 	        break;
> 	      case 'B':
> 	        op = REOP_WNONBDRY;
> 	        break;
> 	      default:
> 	        return ParseQuantAtom(state);
> 	    }
> 
> 	    /*
> 	     * Word boundaries and non-boundaries are flagged as non-empty so they
> 	     * will be prefixed by an anchoring node.
> 	     */
> 	    state->cp = cp + 1;
> 	    ren = NewRENode(state, op, NULL);
> 	    if (ren)
> 	        ren->flags |= RENODE_NONEMPTY;
> 	    return ren;
688,701c777
<         /* At the end; process remaining operators. */
< restartOperator:
<         if (state->cp == state->cpend) {
<             while (operatorSP) {
<                 --operatorSP;
<                 if (!ProcessOp(state, &operatorStack[operatorSP],
<                                operandStack, operandSP))
<                     goto out;
<                 --operandSP;
<             }
<             JS_ASSERT(operandSP == 1);
<             state->result = operandStack[0];
<             result = JS_TRUE;
<             goto out;
---
>           default:;
702a779,780
>     return ParseQuantAtom(state);
> }
704,777c782,800
<         switch (*state->cp) {
<           case '|':
<             /* Process any stacked 'concat' operators */
<             ++state->cp;
<             while (operatorSP &&
<                    operatorStack[operatorSP - 1].op == REOP_CONCAT) {
<                 --operatorSP;
<                 if (!ProcessOp(state, &operatorStack[operatorSP],
<                                operandStack, operandSP)) {
<                     goto out;
<                 }
<                 --operandSP;
<             }
<             op = REOP_ALT;
<             goto pushOperator;
< 
<           case ')':
<             /*
<              * If there's no stacked open parenthesis, throw syntax error.
<              */
<             for (i = operatorSP - 1; ; i--) {
<                 if (i < 0) {
<                     ReportRegExpError(state, JSREPORT_ERROR,
<                                       JSMSG_UNMATCHED_RIGHT_PAREN);
<                     goto out;
<                 }
<                 if (operatorStack[i].op == REOP_ASSERT ||
<                     operatorStack[i].op == REOP_ASSERT_NOT ||
<                     operatorStack[i].op == REOP_LPARENNON ||
<                     operatorStack[i].op == REOP_LPAREN) {
<                     break;
<                 }
<             }
<             ++state->cp;
< 
<             /* Process everything on the stack until the open parenthesis. */
<             for (;;) {
<                 JS_ASSERT(operatorSP);
<                 --operatorSP;
<                 switch (operatorStack[operatorSP].op) {
<                   case REOP_ASSERT:
<                   case REOP_ASSERT_NOT:
<                   case REOP_LPAREN:
<                     operand = NewRENode(state, operatorStack[operatorSP].op);
<                     if (!operand)
<                         goto out;
<                     operand->u.parenIndex =
<                         operatorStack[operatorSP].parenIndex;
<                     JS_ASSERT(operandSP);
<                     operand->kid = operandStack[operandSP - 1];
<                     operandStack[operandSP - 1] = operand;
<                     if (state->treeDepth == TREE_DEPTH_MAX) {
<                         ReportRegExpError(state, JSREPORT_ERROR,
<                                           JSMSG_REGEXP_TOO_COMPLEX);
<                         goto out;
<                     }
<                     ++state->treeDepth;
<                     /* FALL THROUGH */
< 
<                   case REOP_LPARENNON:
<                     state->result = operandStack[operandSP - 1];
<                     if (!ParseQuantifier(state))
<                         goto out;
<                     operandStack[operandSP - 1] = state->result;
<                     goto restartOperator;
<                   default:
<                     if (!ProcessOp(state, &operatorStack[operatorSP],
<                                    operandStack, operandSP))
<                         goto out;
<                     --operandSP;
<                     break;
<                 }
<             }
<             break;
---
> /*
>  *  quantatom:  atom                    An unquantified atom.
>  *              quantatom '{' n ',' m '}'
>  *                                      Atom must occur between n and m times.
>  *              quantatom '{' n ',' '}' Atom must occur at least n times.
>  *              quantatom '{' n '}'     Atom must occur exactly n times.
>  *              quantatom '*'           Zero or more times (same as {0,}).
>  *              quantatom '+'           One or more times (same as {1,}).
>  *              quantatom '?'           Zero or one time (same as {0,1}).
>   *
>  *              any of which can be optionally followed by '?' for ungreedy
> */
> static RENode *
> ParseQuantAtom(CompilerState *state)
> {
>     RENode *ren, *ren2;
>     const jschar *cp, *up;
>     jschar c;
>     uint32 min, max;
778a802,809
>     ren = ParseAtom(state);
>     if (!ren)
> 	return NULL;
> 
>     cp = state->cp;
> loop:
>     if (cp < state->cpend)
>         switch (*cp) {
780,781c811,890
<           {
<             const jschar *errp = state->cp;
---
> 	    c = *++cp;
> 	    if (!JS7_ISDEC(c)) {
>                 js_ReportCompileErrorNumber(state->context, state->tokenStream,
>                                             NULL, JSREPORT_ERROR,
>                                             JSMSG_BAD_QUANTIFIER, state->cp);
> 	        return NULL;
> 	    }
> 	    min = (uint32)JS7_UNDEC(c);
> 	    for (c = *++cp; JS7_ISDEC(c); c = *++cp) {
> 	        min = 10 * min + (uint32)JS7_UNDEC(c);
> 	        if (min >> 16) {
>                     js_ReportCompileErrorNumber(state->context,
>                                                 state->tokenStream, NULL,
>                                                 JSREPORT_ERROR,
>                                                 JSMSG_MIN_TOO_BIG, state->cp);
> 		    return NULL;
> 	        }
> 	    }
> 	    if (*cp == ',') {
> 	        up = ++cp;
> 	        if (JS7_ISDEC(*cp)) {
> 		    max = (uint32)JS7_UNDEC(*cp);
> 		    for (c = *++cp; JS7_ISDEC(c); c = *++cp) {
> 		        max = 10 * max + (uint32)JS7_UNDEC(c);
> 		        if (max >> 16) {
>                             js_ReportCompileErrorNumber(state->context,
>                                                         state->tokenStream,
>                                                         NULL,
>                                                         JSREPORT_ERROR,
>                                                         JSMSG_MAX_TOO_BIG, up);
> 			    return NULL;
> 		        }
> 		    }
> 		    if (max == 0)
> 		        goto zero_quant;
> 		    if (min > max) {
>                         js_ReportCompileErrorNumber(state->context,
>                                                     state->tokenStream,
>                                                     NULL,
>                                                     JSREPORT_ERROR,
>                                                     JSMSG_OUT_OF_ORDER, up);
> 		        return NULL;
> 		    }
> 	        } else {
> 		    /* 0 means no upper bound. */
> 		    max = 0;
> 	        }
> 	    } else {
> 	        /* Exactly n times. */
> 	        if (min == 0) {
>           zero_quant:
>                     js_ReportCompileErrorNumber(state->context,
>                                                 state->tokenStream,
>                                                 NULL,
>                                                 JSREPORT_ERROR,
>                                                 JSMSG_ZERO_QUANTIFIER,
>                                                 state->cp);
> 		    return NULL;
> 	        }
> 	        max = min;
> 	    }
> 	    if (*cp != '}') {
>                 js_ReportCompileErrorNumber(state->context,
>                                             state->tokenStream,
>                                             NULL,
>                                             JSREPORT_ERROR,
>                                             JSMSG_UNTERM_QUANTIFIER, state->cp);
> 	        return NULL;
> 	    }
> 	    cp++;
> 
> 	    ren2 = NewRENode(state, REOP_QUANT, ren);
> 	    if (!ren2)
> 	        return NULL;
> 	    if (min > 0 && (ren->flags & RENODE_NONEMPTY))
> 	        ren2->flags |= RENODE_NONEMPTY;
> 	    ren2->u.range.min = (uint16)min;
> 	    ren2->u.range.max = (uint16)max;
> 	    ren = ren2;
>             goto parseMinimalFlag;
783,789c892,898
<             if (ParseMinMaxQuantifier(state, JS_TRUE) < 0) {
<                 /*
<                  * This didn't even scan correctly as a quantifier, so we should
<                  * treat it as flat.
<                  */
<                 op = REOP_CONCAT;
<                 goto pushOperator;
---
>           case '*':
> 	    cp++; 
> 	    ren = NewRENode(state, REOP_STAR, ren);
>     parseMinimalFlag :
>             if (*cp == '?') {
>                 ren->flags |= RENODE_MINIMAL;
>                 cp++;
791,794c900
< 
<             state->cp = errp;
<             /* FALL THROUGH */
<           }
---
> 	    goto loop;
797,802c903,910
<           case '*':
<           case '?':
<             ReportRegExpErrorHelper(state, JSREPORT_ERROR, JSMSG_BAD_QUANTIFIER,
<                                     state->cp);
<             result = JS_FALSE;
<             goto out;
---
> 	    cp++;
> 	    ren2 = NewRENode(state, REOP_PLUS, ren);
> 	    if (!ren2)
> 	        return NULL;
> 	    if (ren->flags & RENODE_NONEMPTY)
> 	        ren2->flags |= RENODE_NONEMPTY;
> 	    ren = ren2;
> 	    goto parseMinimalFlag;
804,821c912,915
<           default:
<             /* Anything else is the start of the next term. */
<             op = REOP_CONCAT;
< pushOperator:
<             if (operatorSP == operatorStackSize) {
<                 REOpData *tmp;
<                 operatorStackSize += operatorStackSize;
<                 tmp = (REOpData *)
<                     JS_realloc(state->context, operatorStack,
<                                sizeof(REOpData) * operatorStackSize);
<                 if (!tmp)
<                     goto out;
<                 operatorStack = tmp;
<             }
<             operatorStack[operatorSP].op = op;
<             operatorStack[operatorSP].errPos = state->cp;
<             operatorStack[operatorSP++].parenIndex = parenIndex;
<             break;
---
>           case '?':
> 	    cp++;
> 	    ren = NewRENode(state, REOP_OPT, ren);
> 	    goto parseMinimalFlag;
823,830d916
<     }
< out:
<     if (operatorStack)
<         JS_free(state->context, operatorStack);
<     if (operandStack)
<         JS_free(state->context, operandStack);
<     return result;
< }
832,837c918,920
< /*
<  * Hack two bits in CompilerState.flags, for use within FindParenCount to flag
<  * its being on the stack, and to propagate errors to its callers.
<  */
< #define JSREG_FIND_PAREN_COUNT  0x8000
< #define JSREG_FIND_PAREN_ERROR  0x4000
---
>     state->cp = cp;
>     return ren;
> }
840,1113d922
<  * Magic return value from FindParenCount and GetDecimalValue, to indicate
<  * overflow beyond GetDecimalValue's max parameter, or a computed maximum if
<  * its findMax parameter is non-null.
<  */
< #define OVERFLOW_VALUE          ((uintN)-1)
< 
< static uintN
< FindParenCount(CompilerState *state)
< {
<     CompilerState temp;
<     int i;
< 
<     if (state->flags & JSREG_FIND_PAREN_COUNT)
<         return OVERFLOW_VALUE;
< 
<     /*
<      * Copy state into temp, flag it so we never report an invalid backref,
<      * and reset its members to parse the entire regexp.  This is obviously
<      * suboptimal, but GetDecimalValue calls us only if a backref appears to
<      * refer to a forward parenthetical, which is rare.
<      */
<     temp = *state;
<     temp.flags |= JSREG_FIND_PAREN_COUNT;
<     temp.cp = temp.cpbegin;
<     temp.parenCount = 0;
<     temp.classCount = 0;
<     temp.progLength = 0;
<     temp.treeDepth = 0;
<     temp.classBitmapsMem = 0;
<     for (i = 0; i < CLASS_CACHE_SIZE; i++)
<         temp.classCache[i].start = NULL;
< 
<     if (!ParseRegExp(&temp)) {
<         state->flags |= JSREG_FIND_PAREN_ERROR;
<         return OVERFLOW_VALUE;
<     }
<     return temp.parenCount;
< }
< 
< /*
<  * Extract and return a decimal value at state->cp.  The initial character c
<  * has already been read.  Return OVERFLOW_VALUE if the result exceeds max.
<  * Callers who pass a non-null findMax should test JSREG_FIND_PAREN_ERROR in
<  * state->flags to discover whether an error occurred under findMax.
<  */
< static uintN
< GetDecimalValue(jschar c, uintN max, uintN (*findMax)(CompilerState *state),
<                 CompilerState *state)
< {
<     uintN value = JS7_UNDEC(c);
<     JSBool overflow = (value > max && (!findMax || value > findMax(state)));
< 
<     /* The following restriction allows simpler overflow checks. */
<     JS_ASSERT(max <= ((uintN)-1 - 9) / 10);
<     while (state->cp < state->cpend) {
<         c = *state->cp;
<         if (!JS7_ISDEC(c))
<             break;
<         value = 10 * value + JS7_UNDEC(c);
<         if (!overflow && value > max && (!findMax || value > findMax(state)))
<             overflow = JS_TRUE;
<         ++state->cp;
<     }
<     return overflow ? OVERFLOW_VALUE : value;
< }
< 
< /*
<  * Calculate the total size of the bitmap required for a class expression.
<  */
< static JSBool
< CalculateBitmapSize(CompilerState *state, RENode *target, const jschar *src,
<                     const jschar *end)
< {
<     uintN max = 0;
<     JSBool inRange = JS_FALSE;
<     jschar c, rangeStart = 0;
<     uintN n, digit, nDigits, i;
< 
<     target->u.ucclass.bmsize = 0;
<     target->u.ucclass.sense = JS_TRUE;
< 
<     if (src == end)
<         return JS_TRUE;
< 
<     if (*src == '^') {
<         ++src;
<         target->u.ucclass.sense = JS_FALSE;
<     }
< 
<     while (src != end) {
<         JSBool canStartRange = JS_TRUE;
<         uintN localMax = 0;
< 
<         switch (*src) {
<           case '\\':
<             ++src;
<             c = *src++;
<             switch (c) {
<               case 'b':
<                 localMax = 0x8;
<                 break;
<               case 'f':
<                 localMax = 0xC;
<                 break;
<               case 'n':
<                 localMax = 0xA;
<                 break;
<               case 'r':
<                 localMax = 0xD;
<                 break;
<               case 't':
<                 localMax = 0x9;
<                 break;
<               case 'v':
<                 localMax = 0xB;
<                 break;
<               case 'c':
<                 if (src < end && RE_IS_LETTER(*src)) {
<                     localMax = (uintN) (*src++) & 0x1F;
<                 } else {
<                     --src;
<                     localMax = '\\';
<                 }
<                 break;
<               case 'x':
<                 nDigits = 2;
<                 goto lexHex;
<               case 'u':
<                 nDigits = 4;
< lexHex:
<                 n = 0;
<                 for (i = 0; (i < nDigits) && (src < end); i++) {
<                     c = *src++;
<                     if (!isASCIIHexDigit(c, &digit)) {
<                         /*
<                          * Back off to accepting the original
<                          *'\' as a literal.
<                          */
<                         src -= i + 1;
<                         n = '\\';
<                         break;
<                     }
<                     n = (n << 4) | digit;
<                 }
<                 localMax = n;
<                 break;
<               case 'd':
<                 canStartRange = JS_FALSE;
<                 if (inRange) {
<                     JS_ReportErrorNumber(state->context,
<                                          js_GetErrorMessage, NULL,
<                                          JSMSG_BAD_CLASS_RANGE);
<                     return JS_FALSE;
<                 }
<                 localMax = '9';
<                 break;
<               case 'D':
<               case 's':
<               case 'S':
<               case 'w':
<               case 'W':
<                 canStartRange = JS_FALSE;
<                 if (inRange) {
<                     JS_ReportErrorNumber(state->context,
<                                          js_GetErrorMessage, NULL,
<                                          JSMSG_BAD_CLASS_RANGE);
<                     return JS_FALSE;
<                 }
<                 max = 65535;
< 
<                 /*
<                  * If this is the start of a range, ensure that it's less than
<                  * the end.
<                  */
<                 localMax = 0;
<                 break;
<               case '0':
<               case '1':
<               case '2':
<               case '3':
<               case '4':
<               case '5':
<               case '6':
<               case '7':
<                 /*
<                  *  This is a non-ECMA extension - decimal escapes (in this
<                  *  case, octal!) are supposed to be an error inside class
<                  *  ranges, but supported here for backwards compatibility.
<                  *
<                  */
<                 n = JS7_UNDEC(c);
<                 c = *src;
<                 if ('0' <= c && c <= '7') {
<                     src++;
<                     n = 8 * n + JS7_UNDEC(c);
<                     c = *src;
<                     if ('0' <= c && c <= '7') {
<                         src++;
<                         i = 8 * n + JS7_UNDEC(c);
<                         if (i <= 0377)
<                             n = i;
<                         else
<                             src--;
<                     }
<                 }
<                 localMax = n;
<                 break;
< 
<               default:
<                 localMax = c;
<                 break;
<             }
<             break;
<           default:
<             localMax = *src++;
<             break;
<         }
<         if (state->flags & JSREG_FOLD) {
<             jschar uc = upcase(localMax);
<             jschar dc = downcase(localMax);
< 
<             c = JS_MAX(uc, dc);
<             if (c > localMax)
<                 localMax = c;
<         }
<         if (inRange) {
<             if (rangeStart > localMax) {
<                 JS_ReportErrorNumber(state->context,
<                                      js_GetErrorMessage, NULL,
<                                      JSMSG_BAD_CLASS_RANGE);
<                 return JS_FALSE;
<             }
<             inRange = JS_FALSE;
<         } else {
<             if (canStartRange && src < end - 1) {
<                 if (*src == '-') {
<                     ++src;
<                     inRange = JS_TRUE;
<                     rangeStart = (jschar)localMax;
<                     continue;
<                 }
<             }
<         }
<         if (localMax > max)
<             max = localMax;
<     }
<     target->u.ucclass.bmsize = max;
<     return JS_TRUE;
< }
< 
< /*
<  *  item:       assertion               An item is either an assertion or
<  *              quantatom               a quantified atom.
<  *
<  *  assertion:  '^'                     Assertions match beginning of string
<  *                                      (or line if the class static property
<  *                                      RegExp.multiline is true).
<  *              '$'                     End of string (or line if the class
<  *                                      static property RegExp.multiline is
<  *                                      true).
<  *              '\b'                    Word boundary (between \w and \W).
<  *              '\B'                    Word non-boundary.
<  *
<  *  quantatom:  atom                    An unquantified atom.
<  *              quantatom '{' n ',' m '}'
<  *                                      Atom must occur between n and m times.
<  *              quantatom '{' n ',' '}' Atom must occur at least n times.
<  *              quantatom '{' n '}'     Atom must occur exactly n times.
<  *              quantatom '*'           Zero or more times (same as {0,}).
<  *              quantatom '+'           One or more times (same as {1,}).
<  *              quantatom '?'           Zero or one time (same as {0,1}).
<  *
<  *              any of which can be optionally followed by '?' for ungreedy
<  *
1137d945
<  *              '\u' unicode            A unicode escape (must be four digits).
1144,1145c952,961
< static JSBool
< ParseTerm(CompilerState *state)
---
> static jschar metachars[] = {
>     '|', '^', '$', '{', '*', '+', '?', '(', ')', '.', '[', '\\', '}', 0
> };
> 
> static jschar closurechars[] = {
>     '{', '*', '+', '?', 0	/* balance} */
> };
> 
> static RENode *
> ParseAtom(CompilerState *state)
1147,1236c963,967
<     jschar c = *state->cp++;
<     uintN nDigits;
<     uintN num, tmp, n, i;
<     const jschar *termStart;
< 
<     switch (c) {
<     /* assertions and atoms */
<       case '^':
<         state->result = NewRENode(state, REOP_BOL);
<         if (!state->result)
<             return JS_FALSE;
<         state->progLength++;
<         return JS_TRUE;
<       case '$':
<         state->result = NewRENode(state, REOP_EOL);
<         if (!state->result)
<             return JS_FALSE;
<         state->progLength++;
<         return JS_TRUE;
<       case '\\':
<         if (state->cp >= state->cpend) {
<             /* a trailing '\' is an error */
<             ReportRegExpError(state, JSREPORT_ERROR, JSMSG_TRAILING_SLASH);
<             return JS_FALSE;
<         }
<         c = *state->cp++;
<         switch (c) {
<         /* assertion escapes */
<           case 'b' :
<             state->result = NewRENode(state, REOP_WBDRY);
<             if (!state->result)
<                 return JS_FALSE;
<             state->progLength++;
<             return JS_TRUE;
<           case 'B':
<             state->result = NewRENode(state, REOP_WNONBDRY);
<             if (!state->result)
<                 return JS_FALSE;
<             state->progLength++;
<             return JS_TRUE;
<           /* Decimal escape */
<           case '0':
<             /* Give a strict warning. See also the note below. */
<             if (!ReportRegExpError(state, JSREPORT_WARNING | JSREPORT_STRICT,
<                                    JSMSG_INVALID_BACKREF)) {
<                 return JS_FALSE;
<             }
<      doOctal:
<             num = 0;
<             while (state->cp < state->cpend) {
<                 c = *state->cp;
<                 if (c < '0' || '7' < c)
<                     break;
<                 state->cp++;
<                 tmp = 8 * num + (uintN)JS7_UNDEC(c);
<                 if (tmp > 0377)
<                     break;
<                 num = tmp;
<             }
<             c = (jschar)num;
<     doFlat:
<             state->result = NewRENode(state, REOP_FLAT);
<             if (!state->result)
<                 return JS_FALSE;
<             state->result->u.flat.chr = c;
<             state->result->u.flat.length = 1;
<             state->progLength += 3;
<             break;
<           case '1':
<           case '2':
<           case '3':
<           case '4':
<           case '5':
<           case '6':
<           case '7':
<           case '8':
<           case '9':
<             termStart = state->cp - 1;
<             num = GetDecimalValue(c, state->parenCount, FindParenCount, state);
<             if (state->flags & JSREG_FIND_PAREN_ERROR)
<                 return JS_FALSE;
<             if (num == OVERFLOW_VALUE) {
<                 /* Give a strict mode warning. */
<                 if (!ReportRegExpError(state,
<                                        JSREPORT_WARNING | JSREPORT_STRICT,
<                                        (c >= '8')
<                                        ? JSMSG_INVALID_BACKREF
<                                        : JSMSG_BAD_BACKREF)) {
<                     return JS_FALSE;
<                 }
---
>     const jschar *cp, *ocp;
>     uintN tmp, num, len;
>     RENode *ren, *ren2;
>     jschar c;
>     REOp op;
1238,1249c969
<                 /*
<                  * Note: ECMA 262, 15.10.2.9 says that we should throw a syntax
<                  * error here. However, for compatibility with IE, we treat the
<                  * whole backref as flat if the first character in it is not a
<                  * valid octal character, and as an octal escape otherwise.
<                  */
<                 state->cp = termStart;
<                 if (c >= '8') {
<                     /* Treat this as flat. termStart - 1 is the \. */
<                     c = '\\';
<                     goto asFlat;
<                 }
---
>     cp = ocp = state->cp;
1251,1306c971,989
<                 /* Treat this as an octal escape. */
<                 goto doOctal;
<             }
<             JS_ASSERT(1 <= num && num <= 0x10000);
<             state->result = NewRENode(state, REOP_BACKREF);
<             if (!state->result)
<                 return JS_FALSE;
<             state->result->u.parenIndex = num - 1;
<             state->progLength
<                 += 1 + GetCompactIndexWidth(state->result->u.parenIndex);
<             break;
<           /* Control escape */
<           case 'f':
<             c = 0xC;
<             goto doFlat;
<           case 'n':
<             c = 0xA;
<             goto doFlat;
<           case 'r':
<             c = 0xD;
<             goto doFlat;
<           case 't':
<             c = 0x9;
<             goto doFlat;
<           case 'v':
<             c = 0xB;
<             goto doFlat;
<           /* Control letter */
<           case 'c':
<             if (state->cp < state->cpend && RE_IS_LETTER(*state->cp)) {
<                 c = (jschar) (*state->cp++ & 0x1F);
<             } else {
<                 /* back off to accepting the original '\' as a literal */
<                 --state->cp;
<                 c = '\\';
<             }
<             goto doFlat;
<           /* HexEscapeSequence */
<           case 'x':
<             nDigits = 2;
<             goto lexHex;
<           /* UnicodeEscapeSequence */
<           case 'u':
<             nDigits = 4;
< lexHex:
<             n = 0;
<             for (i = 0; i < nDigits && state->cp < state->cpend; i++) {
<                 uintN digit;
<                 c = *state->cp++;
<                 if (!isASCIIHexDigit(c, &digit)) {
<                     /*
<                      * Back off to accepting the original 'u' or 'x' as a
<                      * literal.
<                      */
<                     state->cp -= i + 2;
<                     n = *state->cp++;
---
>         /* handle /|a/ by returning an empty node for the leftside */
>     if ((cp == state->cpend) || (*cp == '|'))
>         return NewRENode(state, REOP_EMPTY, NULL);
> 
>     ren = NULL; /* suppress warning */
>     switch (*cp) {
>       case '(':
>         num = -1;   /* suppress warning */
>         op = REOP_END;
>         if (cp[1] == '?') {
>             switch (cp[2]) {
>                 case ':' :
>                     op = REOP_LPARENNON;
>                     break;
>                 case '=' :
>                     op = REOP_ASSERT;
>                     break;
>                 case '!' :
>                     op = REOP_ASSERT_NOT;
1308,1309d990
<                 }
<                 n = (n << 4) | digit;
1311,1345d991
<             c = (jschar) n;
<             goto doFlat;
<           /* Character class escapes */
<           case 'd':
<             state->result = NewRENode(state, REOP_DIGIT);
< doSimple:
<             if (!state->result)
<                 return JS_FALSE;
<             state->progLength++;
<             break;
<           case 'D':
<             state->result = NewRENode(state, REOP_NONDIGIT);
<             goto doSimple;
<           case 's':
<             state->result = NewRENode(state, REOP_SPACE);
<             goto doSimple;
<           case 'S':
<             state->result = NewRENode(state, REOP_NONSPACE);
<             goto doSimple;
<           case 'w':
<             state->result = NewRENode(state, REOP_ALNUM);
<             goto doSimple;
<           case 'W':
<             state->result = NewRENode(state, REOP_NONALNUM);
<             goto doSimple;
<           /* IdentityEscape */
<           default:
<             state->result = NewRENode(state, REOP_FLAT);
<             if (!state->result)
<                 return JS_FALSE;
<             state->result->u.flat.chr = c;
<             state->result->u.flat.length = 1;
<             state->result->kid = (void *) (state->cp - 1);
<             state->progLength += 3;
<             break;
1347,1371c993,996
<         break;
<       case '[':
<         state->result = NewRENode(state, REOP_CLASS);
<         if (!state->result)
<             return JS_FALSE;
<         termStart = state->cp;
<         state->result->u.ucclass.startIndex = termStart - state->cpbegin;
<         for (;;) {
<             if (state->cp == state->cpend) {
<                 ReportRegExpErrorHelper(state, JSREPORT_ERROR,
<                                         JSMSG_UNTERM_CLASS, termStart);
< 
<                 return JS_FALSE;
<             }
<             if (*state->cp == '\\') {
<                 state->cp++;
<                 if (state->cp != state->cpend)
<                     state->cp++;
<                 continue;
<             }
<             if (*state->cp == ']') {
<                 state->result->u.ucclass.kidlen = state->cp - termStart;
<                 break;
<             }
<             state->cp++;
---
>         if (op == REOP_END) {
>             num = state->parenCount++;	/* \1 is numbered 0, etc. */
>             op = REOP_LPAREN;
>             cp++;
1373,1390c998,1015
<         for (i = 0; i < CLASS_CACHE_SIZE; i++) {
<             if (!state->classCache[i].start) {
<                 state->classCache[i].start = termStart;
<                 state->classCache[i].length = state->result->u.ucclass.kidlen;
<                 state->classCache[i].index = state->classCount;
<                 break;
<             }
<             if (state->classCache[i].length ==
<                 state->result->u.ucclass.kidlen) {
<                 for (n = 0; ; n++) {
<                     if (n == state->classCache[i].length) {
<                         state->result->u.ucclass.index
<                             = state->classCache[i].index;
<                         goto claim;
<                     }
<                     if (state->classCache[i].start[n] != termStart[n])
<                         break;
<                 }
---
>         else
>             cp += 3;
>         state->cp = cp;
>         /* Handle empty paren */
>         if (*cp == ')') {
>             ren2 = NewRENode(state, REOP_EMPTY, NULL);
>         }
>         else {
>             ren2 = ParseRegExp(state);
>             if (!ren2)
>                 return NULL;
>             cp = state->cp;
>             if (*cp != ')') {
>                 js_ReportCompileErrorNumber(state->context, state->tokenStream,
>                                             NULL,
>                                             JSREPORT_ERROR,
>                                             JSMSG_MISSING_PAREN, ocp);
>                 return NULL;
1393,1410c1018,1029
<         state->result->u.ucclass.index = state->classCount++;
< 
<     claim:
<         /*
<          * Call CalculateBitmapSize now as we want any errors it finds
<          * to be reported during the parse phase, not at execution.
<          */
<         if (!CalculateBitmapSize(state, state->result, termStart, state->cp++))
<             return JS_FALSE;
<         /*
<          * Update classBitmapsMem with number of bytes to hold bmsize bits,
<          * which is (bitsCount + 7) / 8 or (highest_bit + 1 + 7) / 8
<          * or highest_bit / 8 + 1 where highest_bit is u.ucclass.bmsize.
<          */
<         n = (state->result->u.ucclass.bmsize >> 3) + 1;
<         if (n > CLASS_BITMAPS_MEM_LIMIT - state->classBitmapsMem) {
<             ReportRegExpError(state, JSREPORT_ERROR, JSMSG_REGEXP_TOO_COMPLEX);
<             return JS_FALSE;
---
>         cp++;
>         ren = NewRENode(state, op, ren2);
>         if (!ren)
> 	    return NULL;
>         ren->flags = ren2->flags & (RENODE_ANCHORED | RENODE_NONEMPTY);
>         ren->u.num = num;
>         if ((op == REOP_LPAREN) || (op == REOP_LPARENNON)) {
>                 /* Assume RPAREN ops immediately succeed LPAREN ops */
>             ren2 = NewRENode(state, (REOp)(op + 1), NULL);
>             if (!ren2 || !SetNext(state, ren, ren2))
>                 return NULL;
>             ren2->u.num = num;
1412,1415d1030
<         state->classBitmapsMem += n;
<         /* CLASS, <index> */
<         state->progLength
<             += 1 + GetCompactIndexWidth(state->result->u.ucclass.index);
1419,1420c1034,1047
<         state->result = NewRENode(state, REOP_DOT);
<         goto doSimple;
---
> 	cp++;
>         op = REOP_DOT;
>         if (*cp == '*') {
> 	    cp++;
>             op = REOP_DOTSTAR;
>             if (*cp == '?') {
>                 cp++;
>                 op = REOP_DOTSTARMIN;
>             }
>         }
> 	ren = NewRENode(state, op, NULL);
> 	if (ren && op == REOP_DOT)
> 	    ren->flags = RENODE_SINGLE | RENODE_NONEMPTY;
> 	break;
1422,1453c1049,1053
<       case '{':
<       {
<         const jschar *errp = state->cp--;
<         intN err;
< 
<         err = ParseMinMaxQuantifier(state, JS_TRUE);
<         state->cp = errp;
< 
<         if (err < 0)
<             goto asFlat;
< 
<         /* FALL THROUGH */
<       }
<       case '*':
<       case '+':
<       case '?':
<         ReportRegExpErrorHelper(state, JSREPORT_ERROR,
<                                 JSMSG_BAD_QUANTIFIER, state->cp - 1);
<         return JS_FALSE;
<       default:
< asFlat:
<         state->result = NewRENode(state, REOP_FLAT);
<         if (!state->result)
<             return JS_FALSE;
<         state->result->u.flat.chr = c;
<         state->result->u.flat.length = 1;
<         state->result->kid = (void *) (state->cp - 1);
<         state->progLength += 3;
<         break;
<     }
<     return ParseQuantifier(state);
< }
---
>       case '[':
>         ++cp;
>         ren = NewRENode(state, REOP_CCLASS, (void *)cp);
>         if (!ren)
>             return NULL;
1455,1498c1055,1074
< static JSBool
< ParseQuantifier(CompilerState *state)
< {
<     RENode *term;
<     term = state->result;
<     if (state->cp < state->cpend) {
<         switch (*state->cp) {
<           case '+':
<             state->result = NewRENode(state, REOP_QUANT);
<             if (!state->result)
<                 return JS_FALSE;
<             state->result->u.range.min = 1;
<             state->result->u.range.max = (uintN)-1;
<             /* <PLUS>, <next> ... <ENDCHILD> */
<             state->progLength += 4;
<             goto quantifier;
<           case '*':
<             state->result = NewRENode(state, REOP_QUANT);
<             if (!state->result)
<                 return JS_FALSE;
<             state->result->u.range.min = 0;
<             state->result->u.range.max = (uintN)-1;
<             /* <STAR>, <next> ... <ENDCHILD> */
<             state->progLength += 4;
<             goto quantifier;
<           case '?':
<             state->result = NewRENode(state, REOP_QUANT);
<             if (!state->result)
<                 return JS_FALSE;
<             state->result->u.range.min = 0;
<             state->result->u.range.max = 1;
<             /* <OPT>, <next> ... <ENDCHILD> */
<             state->progLength += 4;
<             goto quantifier;
<           case '{':       /* balance '}' */
<           {
<             intN err;
<             const jschar *errp = state->cp;
< 
<             err = ParseMinMaxQuantifier(state, JS_FALSE);
<             if (err == 0)
<                 goto quantifier;
<             if (err == -1)
<                 return JS_TRUE;
---
>         do {
>             if (cp == state->cpend) {
>                 js_ReportCompileErrorNumber(state->context, state->tokenStream,
>                                             NULL,
>                                             JSREPORT_ERROR,
>                                             JSMSG_UNTERM_CLASS, ocp);
>                 return NULL;
>             }
>             if ((c = *cp++) == ']')
>                 break;
>             if (c == '\\' && (cp != state->cpend))
>                 cp++;
>         } while (JS_TRUE);
>         ren->u.kid2 = (void *)(cp - 1);
>         
>         ren->u.ucclass.bitmap = NULL;
> 
>         /* Since we rule out [] and [^], we can set the non-empty flag. */
> 	ren->flags = RENODE_SINGLE | RENODE_NONEMPTY;
> 	break;
1500,1506c1076,1129
<             ReportRegExpErrorHelper(state, JSREPORT_ERROR, err, errp);
<             return JS_FALSE;
<           }
<           default:;
<         }
<     }
<     return JS_TRUE;
---
>       case '\\':
> 	c = *++cp;
>         if (cp == state->cpend) {
>             js_ReportCompileErrorNumber(state->context, state->tokenStream,
>                                         NULL,
>                                         JSREPORT_ERROR,
>                                         JSMSG_TRAILING_SLASH);
> 	    return NULL;
>         }
> 	switch (c) {
> 	  case 'f':
> 	  case 'n':
> 	  case 'r':
> 	  case 't':
> 	  case 'v':
> 	    ren = NewRENode(state, REOP_FLAT1, NULL);
> 	    c = js_strchr(js_EscapeMap, c)[-1];
> 	    break;
> 
> 	  case 'd':
> 	    ren = NewRENode(state, REOP_DIGIT, NULL);
> 	    break;
> 	  case 'D':
> 	    ren = NewRENode(state, REOP_NONDIGIT, NULL);
> 	    break;
> 	  case 'w':
> 	    ren = NewRENode(state, REOP_ALNUM, NULL);
> 	    break;
> 	  case 'W':
> 	    ren = NewRENode(state, REOP_NONALNUM, NULL);
> 	    break;
> 	  case 's':
> 	    ren = NewRENode(state, REOP_SPACE, NULL);
> 	    break;
> 	  case 'S':
> 	    ren = NewRENode(state, REOP_NONSPACE, NULL);
> 	    break;
>           case '0':
>             if (JS_HAS_STRICT_OPTION(state->context))
>                 c = 0;
>             else {
>         do_octal:
>                 num = 0;
>                 while ('0' <= (c = *++cp) && c <= '7') {
>                     tmp = 8 * num + (uintN)JS7_UNDEC(c);
>                     if (tmp > 0377)
>                         break;
>                     num = tmp;
>                 }
>                 cp--;
>                 ren = NewRENode(state, REOP_FLAT1, NULL);
>                 c = (jschar)num;
>             }
>             break;
1508,1512c1131,1153
< quantifier:
<     if (state->treeDepth == TREE_DEPTH_MAX) {
<         ReportRegExpError(state, JSREPORT_ERROR, JSMSG_REGEXP_TOO_COMPLEX);
<         return JS_FALSE;
<     }
---
>           case '1':
>           case '2':
>           case '3':
>           case '4':
>           case '5':
>           case '6':
>           case '7':
>           case '8':
>           case '9':
>             num = (uintN)JS7_UNDEC(c);
>             for (c = *++cp; JS7_ISDEC(c); c = *++cp)
>                 num = 10 * num - (uintN)JS7_UNDEC(c);
>             if (num > 9 &&
>                 num > state->parenCount &&
>                 !JS_HAS_STRICT_OPTION(state->context)) {
>                 cp = ocp;
>                 goto do_octal;
>             }
>             cp--;
>             ren = NewRENode(state, REOP_BACKREF, NULL);
>             if (!ren)
>                 return NULL;
>             ren->u.num = num - 1;       /* \1 is numbered 0, etc. */
1514,1524c1155,1225
<     ++state->treeDepth;
<     ++state->cp;
<     state->result->kid = term;
<     if (state->cp < state->cpend && *state->cp == '?') {
<         ++state->cp;
<         state->result->u.range.greedy = JS_FALSE;
<     } else {
<         state->result->u.range.greedy = JS_TRUE;
<     }
<     return JS_TRUE;
< }
---
>             /* Avoid common chr- and flags-setting code after switch. */
>             ren->flags = RENODE_NONEMPTY;
>             goto bump_cp;
> 
> 
> 	  case 'x':
> 	    ocp = cp;
> 	    c = *++cp;
> 	    if (JS7_ISHEX(c)) {
> 		num = JS7_UNHEX(c);
> 		c = *++cp;
> 		if (JS7_ISHEX(c)) {
> 		    num <<= 4;
> 		    num += JS7_UNHEX(c);
> 		} else {
>                     if (state->context->version != JSVERSION_DEFAULT &&
> 			      state->context->version <= JSVERSION_1_4)
> 		        cp--;	/* back up so cp points to last hex char */
>                     else
>                         goto nothex; /* ECMA 2 insists on pairs */
> 		}
> 	    } else {
> nothex:
> 		cp = ocp;	/* \xZZ is xZZ (Perl does \0ZZ!) */
> 		num = 'x';
> 	    }
> 	    ren = NewRENode(state, REOP_FLAT1, NULL);
> 	    c = (jschar)num;
> 	    break;
> 
> 	  case 'c':
> 	    c = *++cp;
> 	    if (!JS7_ISLET(c)) {
> 		cp -= 2;
> 		ocp = cp;
> 		goto do_flat;
> 	    }
> 	    c = (jschar)JS_TOUPPER(c);
> 	    c = JS_TOCTRL(c);
> 	    ren = NewRENode(state, REOP_FLAT1, NULL);
> 	    break;
> 
> 	  case 'u':
> 	    if (JS7_ISHEX(cp[1]) && JS7_ISHEX(cp[2]) &&
> 		JS7_ISHEX(cp[3]) && JS7_ISHEX(cp[4])) {
> 		c = (((((JS7_UNHEX(cp[1]) << 4) + JS7_UNHEX(cp[2])) << 4)
> 		      + JS7_UNHEX(cp[3])) << 4) + JS7_UNHEX(cp[4]);
> 		cp += 4;
> 		ren = NewRENode(state, REOP_FLAT1, NULL);
> 		break;
> 	    }
> 
> 	    /* Unlike Perl \xZZ, we take \uZZZ to be literal-u then ZZZ. */
> 	    ocp = cp;
> 	    goto do_flat;
> 
> 	  default:
> 	    ocp = cp;
> 	    goto do_flat;
> 	}
> 
> 	/* Common chr- and flags-setting code for escape opcodes. */
> 	if (ren) {
> 	    ren->u.chr = c;
> 	    ren->flags = RENODE_SINGLE | RENODE_NONEMPTY;
> 	}
> 
>       bump_cp:
> 	/* Skip to next unparsed char. */
> 	cp++;
> 	break;
1526,1531c1227
< static intN
< ParseMinMaxQuantifier(CompilerState *state, JSBool ignoreValues)
< {
<     uintN min, max;
<     jschar c;
<     const jschar *errp = state->cp++;
---
>       default:
1533,1573c1229,1252
<     c = *state->cp;
<     if (JS7_ISDEC(c)) {
<         ++state->cp;
<         min = GetDecimalValue(c, 0xFFFF, NULL, state);
<         c = *state->cp;
< 
<         if (!ignoreValues && min == OVERFLOW_VALUE)
<             return JSMSG_MIN_TOO_BIG;
< 
<         if (c == ',') {
<             c = *++state->cp;
<             if (JS7_ISDEC(c)) {
<                 ++state->cp;
<                 max = GetDecimalValue(c, 0xFFFF, NULL, state);
<                 c = *state->cp;
<                 if (!ignoreValues && max == OVERFLOW_VALUE)
<                     return JSMSG_MAX_TOO_BIG;
<                 if (!ignoreValues && min > max)
<                     return JSMSG_OUT_OF_ORDER;
<             } else {
<                 max = (uintN)-1;
<             }
<         } else {
<             max = min;
<         }
<         if (c == '}') {
<             state->result = NewRENode(state, REOP_QUANT);
<             if (!state->result)
<                 return JSMSG_OUT_OF_MEMORY;
<             state->result->u.range.min = min;
<             state->result->u.range.max = max;
<             /*
<              * QUANT, <min>, <max>, <next> ... <ENDCHILD>
<              * where <max> is written as compact(max+1) to make
<              * (uintN)-1 sentinel to occupy 1 byte, not width_of(max)+1.
<              */
<             state->progLength += (1 + GetCompactIndexWidth(min)
<                                   + GetCompactIndexWidth(max + 1)
<                                   +3);
<             return 0;
<         }
---
>       do_flat:
> 	while ((c = *++cp) && (cp != state->cpend) && !js_strchr(metachars, c))
> 	    ;
> 	len = (uintN)(cp - ocp);
> 	if ((cp != state->cpend) && len > 1 && js_strchr(closurechars, c)) {
> 	    cp--;
> 	    len--;
> 	}
> 	if (len > REOP_FLATLEN_MAX) {
> 	    len = REOP_FLATLEN_MAX;
> 	    cp = ocp + len;
> 	}
> 	ren = NewRENode(state, (len == 1) ? REOP_FLAT1 : REOP_FLAT,
> 			(void *)ocp);
> 	if (!ren)
> 	    return NULL;
> 	ren->flags = RENODE_NONEMPTY;
> 	if (len > 1) {
> 	    ren->u.kid2 = (void *)cp;
> 	} else {
> 	    ren->flags |= RENODE_SINGLE;
> 	    ren->u.chr = *ocp;
> 	}
> 	break;
1576,1577c1255,1256
<     state->cp = errp;
<     return -1;
---
>     state->cp = cp;
>     return ren;
1580,1581c1259,1261
< static JSBool
< SetForwardJumpOffset(jsbytecode *jump, jsbytecode *target)
---
> JSRegExp *
> js_NewRegExp(JSContext *cx, JSTokenStream *ts,
>              JSString *str, uintN flags, JSBool flat)
1583,1593c1263,1267
<     ptrdiff_t offset = target - jump;
< 
<     /* Check that target really points forward. */
<     JS_ASSERT(offset >= 2);
<     if ((size_t)offset > OFFSET_MAX)
<         return JS_FALSE;
< 
<     jump[0] = JUMP_OFFSET_HI(offset);
<     jump[1] = JUMP_OFFSET_LO(offset);
<     return JS_TRUE;
< }
---
>     JSRegExp *re;
>     void *mark;
>     CompilerState state;
>     RENode *ren, *ren2, *end;
>     size_t resize;
1595,1605c1269,1270
< /*
<  * Generate bytecode for the tree rooted at t using an explicit stack instead
<  * of recursion.
<  */
< static jsbytecode *
< EmitREBytecode(CompilerState *state, JSRegExp *re, size_t treeDepth,
<                jsbytecode *pc, RENode *t)
< {
<     EmitStateStackEntry *emitStateSP, *emitStateStack;
<     RECharSet *charSet;
<     REOp op;
---
>     const jschar *cp;
>     size_t len;
1607,1626c1272,1273
<     if (treeDepth == 0) {
<         emitStateStack = NULL;
<     } else {
<         emitStateStack =
<             (EmitStateStackEntry *)JS_malloc(state->context,
<                                              sizeof(EmitStateStackEntry) *
<                                              treeDepth);
<         if (!emitStateStack)
<             return NULL;
<     }
<     emitStateSP = emitStateStack;
<     op = t->op;
<     JS_ASSERT(op < REOP_LIMIT);
< 
<     for (;;) {
<         *pc++ = op;
<         switch (op) {
<           case REOP_EMPTY:
<             --pc;
<             break;
---
>     re = NULL;
>     mark = JS_ARENA_MARK(&cx->tempPool);
1628,1663c1275,1281
<           case REOP_ALTPREREQ2:
<           case REOP_ALTPREREQ:
<             JS_ASSERT(emitStateSP);
<             emitStateSP->altHead = pc - 1;
<             emitStateSP->endTermFixup = pc;
<             pc += OFFSET_LEN;
<             SET_ARG(pc, t->u.altprereq.ch1);
<             pc += ARG_LEN;
<             SET_ARG(pc, t->u.altprereq.ch2);
<             pc += ARG_LEN;
< 
<             emitStateSP->nextAltFixup = pc;    /* offset to next alternate */
<             pc += OFFSET_LEN;
< 
<             emitStateSP->continueNode = t;
<             emitStateSP->continueOp = REOP_JUMP;
<             emitStateSP->jumpToJumpFlag = JS_FALSE;
<             ++emitStateSP;
<             JS_ASSERT((size_t)(emitStateSP - emitStateStack) <= treeDepth);
<             t = (RENode *) t->kid;
<             op = t->op;
<             JS_ASSERT(op < REOP_LIMIT);
<             continue;
< 
<           case REOP_JUMP:
<             emitStateSP->nextTermFixup = pc;    /* offset to following term */
<             pc += OFFSET_LEN;
<             if (!SetForwardJumpOffset(emitStateSP->nextAltFixup, pc))
<                 goto jump_too_big;
<             emitStateSP->continueOp = REOP_ENDALT;
<             ++emitStateSP;
<             JS_ASSERT((size_t)(emitStateSP - emitStateStack) <= treeDepth);
<             t = (RENode *) t->u.kid2;
<             op = t->op;
<             JS_ASSERT(op < REOP_LIMIT);
<             continue;
---
>     state.context = cx;
>     state.tokenStream = ts;
>     state.cpbegin = state.cp = JSSTRING_CHARS(str);
>     state.cpend = state.cp + JSSTRING_LENGTH(str);
>     state.flags = flags;
>     state.parenCount = 0;
>     state.progLength = 0;
1665,1943d1282
<           case REOP_ENDALT:
<             /*
<              * If we already patched emitStateSP->nextTermFixup to jump to
<              * a nearer jump, to avoid 16-bit immediate offset overflow, we
<              * are done here.
<              */
<             if (emitStateSP->jumpToJumpFlag)
<                 break;
< 
<             /*
<              * Fix up the REOP_JUMP offset to go to the op after REOP_ENDALT.
<              * REOP_ENDALT is executed only on successful match of the last
<              * alternate in a group.
<              */
<             if (!SetForwardJumpOffset(emitStateSP->nextTermFixup, pc))
<                 goto jump_too_big;
<             if (t->op != REOP_ALT) {
<                 if (!SetForwardJumpOffset(emitStateSP->endTermFixup, pc))
<                     goto jump_too_big;
<             }
< 
<             /*
<              * If the program is bigger than the REOP_JUMP offset range, then
<              * we must check for alternates before this one that are part of
<              * the same group, and fix up their jump offsets to target jumps
<              * close enough to fit in a 16-bit unsigned offset immediate.
<              */
<             if ((size_t)(pc - re->program) > OFFSET_MAX &&
<                 emitStateSP > emitStateStack) {
<                 EmitStateStackEntry *esp, *esp2;
<                 jsbytecode *alt, *jump;
<                 ptrdiff_t span, header;
< 
<                 esp2 = emitStateSP;
<                 alt = esp2->altHead;
<                 for (esp = esp2 - 1; esp >= emitStateStack; --esp) {
<                     if (esp->continueOp == REOP_ENDALT &&
<                         !esp->jumpToJumpFlag &&
<                         esp->nextTermFixup + OFFSET_LEN == alt &&
<                         (size_t)(pc - ((esp->continueNode->op != REOP_ALT)
<                                        ? esp->endTermFixup
<                                        : esp->nextTermFixup)) > OFFSET_MAX) {
<                         alt = esp->altHead;
<                         jump = esp->nextTermFixup;
< 
<                         /*
<                          * The span must be 1 less than the distance from
<                          * jump offset to jump offset, so we actually jump
<                          * to a REOP_JUMP bytecode, not to its offset!
<                          */
<                         for (;;) {
<                             JS_ASSERT(jump < esp2->nextTermFixup);
<                             span = esp2->nextTermFixup - jump - 1;
<                             if ((size_t)span <= OFFSET_MAX)
<                                 break;
<                             do {
<                                 if (--esp2 == esp)
<                                     goto jump_too_big;
<                             } while (esp2->continueOp != REOP_ENDALT);
<                         }
< 
<                         jump[0] = JUMP_OFFSET_HI(span);
<                         jump[1] = JUMP_OFFSET_LO(span);
< 
<                         if (esp->continueNode->op != REOP_ALT) {
<                             /*
<                              * We must patch the offset at esp->endTermFixup
<                              * as well, for the REOP_ALTPREREQ{,2} opcodes.
<                              * If we're unlucky and endTermFixup is more than
<                              * OFFSET_MAX bytes from its target, we cheat by
<                              * jumping 6 bytes to the jump whose offset is at
<                              * esp->nextTermFixup, which has the same target.
<                              */
<                             jump = esp->endTermFixup;
<                             header = esp->nextTermFixup - jump;
<                             span += header;
<                             if ((size_t)span > OFFSET_MAX)
<                                 span = header;
< 
<                             jump[0] = JUMP_OFFSET_HI(span);
<                             jump[1] = JUMP_OFFSET_LO(span);
<                         }
< 
<                         esp->jumpToJumpFlag = JS_TRUE;
<                     }
<                 }
<             }
<             break;
< 
<           case REOP_ALT:
<             JS_ASSERT(emitStateSP);
<             emitStateSP->altHead = pc - 1;
<             emitStateSP->nextAltFixup = pc;     /* offset to next alternate */
<             pc += OFFSET_LEN;
<             emitStateSP->continueNode = t;
<             emitStateSP->continueOp = REOP_JUMP;
<             emitStateSP->jumpToJumpFlag = JS_FALSE;
<             ++emitStateSP;
<             JS_ASSERT((size_t)(emitStateSP - emitStateStack) <= treeDepth);
<             t = (RENode *) t->kid;
<             op = t->op;
<             JS_ASSERT(op < REOP_LIMIT);
<             continue;
< 
<           case REOP_FLAT:
<             /*
<              * Coalesce FLATs if possible and if it would not increase bytecode
<              * beyond preallocated limit. The latter happens only when bytecode
<              * size for coalesced string with offset p and length 2 exceeds 6
<              * bytes preallocated for 2 single char nodes, i.e. when
<              * 1 + GetCompactIndexWidth(p) + GetCompactIndexWidth(2) > 6 or
<              * GetCompactIndexWidth(p) > 4.
<              * Since when GetCompactIndexWidth(p) <= 4 coalescing of 3 or more
<              * nodes strictly decreases bytecode size, the check has to be
<              * done only for the first coalescing.
<              */
<             if (t->kid &&
<                 GetCompactIndexWidth((jschar *)t->kid - state->cpbegin) <= 4)
<             {
<                 while (t->next &&
<                        t->next->op == REOP_FLAT &&
<                        (jschar*)t->kid + t->u.flat.length ==
<                        (jschar*)t->next->kid) {
<                     t->u.flat.length += t->next->u.flat.length;
<                     t->next = t->next->next;
<                 }
<             }
<             if (t->kid && t->u.flat.length > 1) {
<                 pc[-1] = (state->flags & JSREG_FOLD) ? REOP_FLATi : REOP_FLAT;
<                 pc = WriteCompactIndex(pc, (jschar *)t->kid - state->cpbegin);
<                 pc = WriteCompactIndex(pc, t->u.flat.length);
<             } else if (t->u.flat.chr < 256) {
<                 pc[-1] = (state->flags & JSREG_FOLD) ? REOP_FLAT1i : REOP_FLAT1;
<                 *pc++ = (jsbytecode) t->u.flat.chr;
<             } else {
<                 pc[-1] = (state->flags & JSREG_FOLD)
<                          ? REOP_UCFLAT1i
<                          : REOP_UCFLAT1;
<                 SET_ARG(pc, t->u.flat.chr);
<                 pc += ARG_LEN;
<             }
<             break;
< 
<           case REOP_LPAREN:
<             JS_ASSERT(emitStateSP);
<             pc = WriteCompactIndex(pc, t->u.parenIndex);
<             emitStateSP->continueNode = t;
<             emitStateSP->continueOp = REOP_RPAREN;
<             ++emitStateSP;
<             JS_ASSERT((size_t)(emitStateSP - emitStateStack) <= treeDepth);
<             t = (RENode *) t->kid;
<             op = t->op;
<             continue;
< 
<           case REOP_RPAREN:
<             pc = WriteCompactIndex(pc, t->u.parenIndex);
<             break;
< 
<           case REOP_BACKREF:
<             pc = WriteCompactIndex(pc, t->u.parenIndex);
<             break;
< 
<           case REOP_ASSERT:
<             JS_ASSERT(emitStateSP);
<             emitStateSP->nextTermFixup = pc;
<             pc += OFFSET_LEN;
<             emitStateSP->continueNode = t;
<             emitStateSP->continueOp = REOP_ASSERTTEST;
<             ++emitStateSP;
<             JS_ASSERT((size_t)(emitStateSP - emitStateStack) <= treeDepth);
<             t = (RENode *) t->kid;
<             op = t->op;
<             continue;
< 
<           case REOP_ASSERTTEST:
<           case REOP_ASSERTNOTTEST:
<             if (!SetForwardJumpOffset(emitStateSP->nextTermFixup, pc))
<                 goto jump_too_big;
<             break;
< 
<           case REOP_ASSERT_NOT:
<             JS_ASSERT(emitStateSP);
<             emitStateSP->nextTermFixup = pc;
<             pc += OFFSET_LEN;
<             emitStateSP->continueNode = t;
<             emitStateSP->continueOp = REOP_ASSERTNOTTEST;
<             ++emitStateSP;
<             JS_ASSERT((size_t)(emitStateSP - emitStateStack) <= treeDepth);
<             t = (RENode *) t->kid;
<             op = t->op;
<             continue;
< 
<           case REOP_QUANT:
<             JS_ASSERT(emitStateSP);
<             if (t->u.range.min == 0 && t->u.range.max == (uintN)-1) {
<                 pc[-1] = (t->u.range.greedy) ? REOP_STAR : REOP_MINIMALSTAR;
<             } else if (t->u.range.min == 0 && t->u.range.max == 1) {
<                 pc[-1] = (t->u.range.greedy) ? REOP_OPT : REOP_MINIMALOPT;
<             } else if (t->u.range.min == 1 && t->u.range.max == (uintN) -1) {
<                 pc[-1] = (t->u.range.greedy) ? REOP_PLUS : REOP_MINIMALPLUS;
<             } else {
<                 if (!t->u.range.greedy)
<                     pc[-1] = REOP_MINIMALQUANT;
<                 pc = WriteCompactIndex(pc, t->u.range.min);
<                 /*
<                  * Write max + 1 to avoid using size_t(max) + 1 bytes
<                  * for (uintN)-1 sentinel.
<                  */
<                 pc = WriteCompactIndex(pc, t->u.range.max + 1);
<             }
<             emitStateSP->nextTermFixup = pc;
<             pc += OFFSET_LEN;
<             emitStateSP->continueNode = t;
<             emitStateSP->continueOp = REOP_ENDCHILD;
<             ++emitStateSP;
<             JS_ASSERT((size_t)(emitStateSP - emitStateStack) <= treeDepth);
<             t = (RENode *) t->kid;
<             op = t->op;
<             continue;
< 
<           case REOP_ENDCHILD:
<             if (!SetForwardJumpOffset(emitStateSP->nextTermFixup, pc))
<                 goto jump_too_big;
<             break;
< 
<           case REOP_CLASS:
<             if (!t->u.ucclass.sense)
<                 pc[-1] = REOP_NCLASS;
<             pc = WriteCompactIndex(pc, t->u.ucclass.index);
<             charSet = &re->classList[t->u.ucclass.index];
<             charSet->converted = JS_FALSE;
<             charSet->length = t->u.ucclass.bmsize;
<             charSet->u.src.startIndex = t->u.ucclass.startIndex;
<             charSet->u.src.length = t->u.ucclass.kidlen;
<             charSet->sense = t->u.ucclass.sense;
<             break;
< 
<           default:
<             break;
<         }
< 
<         t = t->next;
<         if (t) {
<             op = t->op;
<         } else {
<             if (emitStateSP == emitStateStack)
<                 break;
<             --emitStateSP;
<             t = emitStateSP->continueNode;
<             op = (REOp) emitStateSP->continueOp;
<         }
<     }
< 
<   cleanup:
<     if (emitStateStack)
<         JS_free(state->context, emitStateStack);
<     return pc;
< 
<   jump_too_big:
<     ReportRegExpError(state, JSREPORT_ERROR, JSMSG_REGEXP_TOO_COMPLEX);
<     pc = NULL;
<     goto cleanup;
< }
< 
< 
< JSRegExp *
< js_NewRegExp(JSContext *cx, JSTokenStream *ts,
<              JSString *str, uintN flags, JSBool flat)
< {
<     JSRegExp *re;
<     void *mark;
<     CompilerState state;
<     size_t resize;
<     jsbytecode *endPC;
<     uintN i;
<     size_t len;
< 
<     re = NULL;
<     mark = JS_ARENA_MARK(&cx->tempPool);
1945,3215c1284,1307
< 
<     state.context = cx;
<     state.tokenStream = ts;
<     state.cp = js_UndependString(cx, str);
<     if (!state.cp)
<         goto out;
<     state.cpbegin = state.cp;
<     state.cpend = state.cp + len;
<     state.flags = flags;
<     state.parenCount = 0;
<     state.classCount = 0;
<     state.progLength = 0;
<     state.treeDepth = 0;
<     state.classBitmapsMem = 0;
<     for (i = 0; i < CLASS_CACHE_SIZE; i++)
<         state.classCache[i].start = NULL;
< 
<     if (len != 0 && flat) {
<         state.result = NewRENode(&state, REOP_FLAT);
<         if (!state.result)
<             goto out;
<         state.result->u.flat.chr = *state.cpbegin;
<         state.result->u.flat.length = len;
<         state.result->kid = (void *) state.cpbegin;
<         /* Flat bytecode: REOP_FLAT compact(string_offset) compact(len). */
<         state.progLength += 1 + GetCompactIndexWidth(0)
<                           + GetCompactIndexWidth(len);
<     } else {
<         if (!ParseRegExp(&state))
<             goto out;
<     }
<     resize = offsetof(JSRegExp, program) + state.progLength + 1;
<     re = (JSRegExp *) JS_malloc(cx, resize);
<     if (!re)
<         goto out;
< 
<     re->nrefs = 1;
<     JS_ASSERT(state.classBitmapsMem <= CLASS_BITMAPS_MEM_LIMIT);
<     re->classCount = state.classCount;
<     if (re->classCount) {
<         re->classList = (RECharSet *)
<             JS_malloc(cx, re->classCount * sizeof(RECharSet));
<         if (!re->classList) {
<             js_DestroyRegExp(cx, re);
<             re = NULL;
<             goto out;
<         }
<         for (i = 0; i < re->classCount; i++)
<             re->classList[i].converted = JS_FALSE;
<     } else {
<         re->classList = NULL;
<     }
<     endPC = EmitREBytecode(&state, re, state.treeDepth, re->program, state.result);
<     if (!endPC) {
<         js_DestroyRegExp(cx, re);
<         re = NULL;
<         goto out;
<     }
<     *endPC++ = REOP_END;
<     /*
<      * Check whether size was overestimated and shrink using realloc.
<      * This is safe since no pointers to newly parsed regexp or its parts
<      * besides re exist here.
<      */
<     if ((size_t)(endPC - re->program) != state.progLength + 1) {
<         JSRegExp *tmp;
<         JS_ASSERT((size_t)(endPC - re->program) < state.progLength + 1);
<         resize = offsetof(JSRegExp, program) + (endPC - re->program);
<         tmp = (JSRegExp *) JS_realloc(cx, re, resize);
<         if (tmp)
<             re = tmp;
<     }
< 
<     re->flags = flags;
<     re->parenCount = state.parenCount;
<     re->source = str;
< 
< out:
<     JS_ARENA_RELEASE(&cx->tempPool, mark);
<     return re;
< }
< 
< JSRegExp *
< js_NewRegExpOpt(JSContext *cx, JSString *str, JSString *opt, JSBool flat)
< {
<     uintN flags;
<     jschar *s;
<     size_t i, n;
<     char charBuf[2];
< 
<     flags = 0;
<     if (opt) {
<         JSSTRING_CHARS_AND_LENGTH(opt, s, n);
<         for (i = 0; i < n; i++) {
<             switch (s[i]) {
<               case 'g':
<                 flags |= JSREG_GLOB;
<                 break;
<               case 'i':
<                 flags |= JSREG_FOLD;
<                 break;
<               case 'm':
<                 flags |= JSREG_MULTILINE;
<                 break;
<               case 'y':
<                 flags |= JSREG_STICKY;
<                 break;
<               default:
<                 charBuf[0] = (char)s[i];
<                 charBuf[1] = '\0';
<                 JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR,
<                                              js_GetErrorMessage, NULL,
<                                              JSMSG_BAD_FLAG, charBuf);
<                 return NULL;
<             }
<         }
<     }
<     return js_NewRegExp(cx, NULL, str, flags, flat);
< }
< 
< /*
<  * Save the current state of the match - the position in the input
<  * text as well as the position in the bytecode. The state of any
<  * parent expressions is also saved (preceding state).
<  * Contents of parenCount parentheses from parenIndex are also saved.
<  */
< static REBackTrackData *
< PushBackTrackState(REGlobalData *gData, REOp op,
<                    jsbytecode *target, REMatchState *x, const jschar *cp,
<                    size_t parenIndex, size_t parenCount)
< {
<     size_t i;
<     REBackTrackData *result =
<         (REBackTrackData *) ((char *)gData->backTrackSP + gData->cursz);
< 
<     size_t sz = sizeof(REBackTrackData) +
<                 gData->stateStackTop * sizeof(REProgState) +
<                 parenCount * sizeof(RECapture);
< 
<     ptrdiff_t btsize = gData->backTrackStackSize;
<     ptrdiff_t btincr = ((char *)result + sz) -
<                        ((char *)gData->backTrackStack + btsize);
< 
<     re_debug("\tBT_Push: %lu,%lu",
<              (unsigned long) parenIndex, (unsigned long) parenCount);
< 
<     JS_COUNT_OPERATION(gData->cx, JSOW_JUMP * (1 + parenCount));
<     if (btincr > 0) {
<         ptrdiff_t offset = (char *)result - (char *)gData->backTrackStack;
< 
<         JS_COUNT_OPERATION(gData->cx, JSOW_ALLOCATION);
<         btincr = JS_ROUNDUP(btincr, btsize);
<         JS_ARENA_GROW_CAST(gData->backTrackStack, REBackTrackData *,
<                            &gData->pool, btsize, btincr);
<         if (!gData->backTrackStack) {
<             js_ReportOutOfScriptQuota(gData->cx);
<             gData->ok = JS_FALSE;
<             return NULL;
<         }
<         gData->backTrackStackSize = btsize + btincr;
<         result = (REBackTrackData *) ((char *)gData->backTrackStack + offset);
<     }
<     gData->backTrackSP = result;
<     result->sz = gData->cursz;
<     gData->cursz = sz;
< 
<     result->backtrack_op = op;
<     result->backtrack_pc = target;
<     result->cp = cp;
<     result->parenCount = parenCount;
<     result->parenIndex = parenIndex;
< 
<     result->saveStateStackTop = gData->stateStackTop;
<     JS_ASSERT(gData->stateStackTop);
<     memcpy(result + 1, gData->stateStack,
<            sizeof(REProgState) * result->saveStateStackTop);
< 
<     if (parenCount != 0) {
<         memcpy((char *)(result + 1) +
<                sizeof(REProgState) * result->saveStateStackTop,
<                &x->parens[parenIndex],
<                sizeof(RECapture) * parenCount);
<         for (i = 0; i != parenCount; i++)
<             x->parens[parenIndex + i].index = -1;
<     }
< 
<     return result;
< }
< 
< 
< /*
<  *   Consecutive literal characters.
<  */
< #if 0
< static REMatchState *
< FlatNMatcher(REGlobalData *gData, REMatchState *x, jschar *matchChars,
<              size_t length)
< {
<     size_t i;
<     if (length > gData->cpend - x->cp)
<         return NULL;
<     for (i = 0; i != length; i++) {
<         if (matchChars[i] != x->cp[i])
<             return NULL;
<     }
<     x->cp += length;
<     return x;
< }
< #endif
< 
< JS_INLINE(static REMatchState *
< FlatNIMatcher(REGlobalData *gData, REMatchState *x, jschar *matchChars,
<               size_t length))
< {
<     size_t i;
<     JS_ASSERT(gData->cpend >= x->cp);
<     if (length > (size_t)(gData->cpend - x->cp))
<         return NULL;
<     for (i = 0; i != length; i++) {
<         if (upcase(matchChars[i]) != upcase(x->cp[i]))
<             return NULL;
<     }
<     x->cp += length;
<     return x;
< }
< 
< /*
<  * 1. Evaluate DecimalEscape to obtain an EscapeValue E.
<  * 2. If E is not a character then go to step 6.
<  * 3. Let ch be E's character.
<  * 4. Let A be a one-element RECharSet containing the character ch.
<  * 5. Call CharacterSetMatcher(A, false) and return its Matcher result.
<  * 6. E must be an integer. Let n be that integer.
<  * 7. If n=0 or n>NCapturingParens then throw a SyntaxError exception.
<  * 8. Return an internal Matcher closure that takes two arguments, a State x
<  *    and a Continuation c, and performs the following:
<  *     1. Let cap be x's captures internal array.
<  *     2. Let s be cap[n].
<  *     3. If s is undefined, then call c(x) and return its result.
<  *     4. Let e be x's endIndex.
<  *     5. Let len be s's length.
<  *     6. Let f be e+len.
<  *     7. If f>InputLength, return failure.
<  *     8. If there exists an integer i between 0 (inclusive) and len (exclusive)
<  *        such that Canonicalize(s[i]) is not the same character as
<  *        Canonicalize(Input [e+i]), then return failure.
<  *     9. Let y be the State (f, cap).
<  *     10. Call c(y) and return its result.
<  */
< static REMatchState *
< BackrefMatcher(REGlobalData *gData, REMatchState *x, size_t parenIndex)
< {
<     size_t len, i;
<     const jschar *parenContent;
<     RECapture *cap = &x->parens[parenIndex];
< 
<     if (cap->index == -1)
<         return x;
< 
<     len = cap->length;
<     if (x->cp + len > gData->cpend)
<         return NULL;
< 
<     parenContent = &gData->cpbegin[cap->index];
<     if (gData->regexp->flags & JSREG_FOLD) {
<         for (i = 0; i < len; i++) {
<             if (upcase(parenContent[i]) != upcase(x->cp[i]))
<                 return NULL;
<         }
<     } else {
<         for (i = 0; i < len; i++) {
<             if (parenContent[i] != x->cp[i])
<                 return NULL;
<         }
<     }
<     x->cp += len;
<     return x;
< }
< 
< 
< /* Add a single character to the RECharSet */
< static void
< AddCharacterToCharSet(RECharSet *cs, jschar c)
< {
<     uintN byteIndex = (uintN)(c >> 3);
<     JS_ASSERT(c <= cs->length);
<     cs->u.bits[byteIndex] |= 1 << (c & 0x7);
< }
< 
< 
< /* Add a character range, c1 to c2 (inclusive) to the RECharSet */
< static void
< AddCharacterRangeToCharSet(RECharSet *cs, uintN c1, uintN c2)
< {
<     uintN i;
< 
<     uintN byteIndex1 = c1 >> 3;
<     uintN byteIndex2 = c2 >> 3;
< 
<     JS_ASSERT((c2 <= cs->length) && (c1 <= c2));
< 
<     c1 &= 0x7;
<     c2 &= 0x7;
< 
<     if (byteIndex1 == byteIndex2) {
<         cs->u.bits[byteIndex1] |= ((uint8)0xFF >> (7 - (c2 - c1))) << c1;
<     } else {
<         cs->u.bits[byteIndex1] |= 0xFF << c1;
<         for (i = byteIndex1 + 1; i < byteIndex2; i++)
<             cs->u.bits[i] = 0xFF;
<         cs->u.bits[byteIndex2] |= (uint8)0xFF >> (7 - c2);
<     }
< }
< 
< /* Compile the source of the class into a RECharSet */
< static JSBool
< ProcessCharSet(REGlobalData *gData, RECharSet *charSet)
< {
<     const jschar *src, *end;
<     JSBool inRange = JS_FALSE;
<     jschar rangeStart = 0;
<     uintN byteLength, n;
<     jschar c, thisCh;
<     intN nDigits, i;
< 
<     JS_ASSERT(!charSet->converted);
<     /*
<      * Assert that startIndex and length points to chars inside [] inside
<      * source string.
<      */
<     JS_ASSERT(1 <= charSet->u.src.startIndex);
<     JS_ASSERT(charSet->u.src.startIndex
<               < JSSTRING_LENGTH(gData->regexp->source));
<     JS_ASSERT(charSet->u.src.length <= JSSTRING_LENGTH(gData->regexp->source)
<                                        - 1 - charSet->u.src.startIndex);
< 
<     charSet->converted = JS_TRUE;
<     src = JSSTRING_CHARS(gData->regexp->source) + charSet->u.src.startIndex;
<     end = src + charSet->u.src.length;
<     JS_ASSERT(src[-1] == '[');
<     JS_ASSERT(end[0] == ']');
< 
<     byteLength = (charSet->length >> 3) + 1;
<     charSet->u.bits = (uint8 *)JS_malloc(gData->cx, byteLength);
<     if (!charSet->u.bits) {
<         JS_ReportOutOfMemory(gData->cx);
<         gData->ok = JS_FALSE;
<         return JS_FALSE;
<     }
<     memset(charSet->u.bits, 0, byteLength);
< 
<     if (src == end)
<         return JS_TRUE;
< 
<     if (*src == '^') {
<         JS_ASSERT(charSet->sense == JS_FALSE);
<         ++src;
<     } else {
<         JS_ASSERT(charSet->sense == JS_TRUE);
<     }
< 
<     while (src != end) {
<         switch (*src) {
<           case '\\':
<             ++src;
<             c = *src++;
<             switch (c) {
<               case 'b':
<                 thisCh = 0x8;
<                 break;
<               case 'f':
<                 thisCh = 0xC;
<                 break;
<               case 'n':
<                 thisCh = 0xA;
<                 break;
<               case 'r':
<                 thisCh = 0xD;
<                 break;
<               case 't':
<                 thisCh = 0x9;
<                 break;
<               case 'v':
<                 thisCh = 0xB;
<                 break;
<               case 'c':
<                 if (src < end && JS_ISWORD(*src)) {
<                     thisCh = (jschar)(*src++ & 0x1F);
<                 } else {
<                     --src;
<                     thisCh = '\\';
<                 }
<                 break;
<               case 'x':
<                 nDigits = 2;
<                 goto lexHex;
<               case 'u':
<                 nDigits = 4;
<             lexHex:
<                 n = 0;
<                 for (i = 0; (i < nDigits) && (src < end); i++) {
<                     uintN digit;
<                     c = *src++;
<                     if (!isASCIIHexDigit(c, &digit)) {
<                         /*
<                          * Back off to accepting the original '\'
<                          * as a literal
<                          */
<                         src -= i + 1;
<                         n = '\\';
<                         break;
<                     }
<                     n = (n << 4) | digit;
<                 }
<                 thisCh = (jschar)n;
<                 break;
<               case '0':
<               case '1':
<               case '2':
<               case '3':
<               case '4':
<               case '5':
<               case '6':
<               case '7':
<                 /*
<                  *  This is a non-ECMA extension - decimal escapes (in this
<                  *  case, octal!) are supposed to be an error inside class
<                  *  ranges, but supported here for backwards compatibility.
<                  */
<                 n = JS7_UNDEC(c);
<                 c = *src;
<                 if ('0' <= c && c <= '7') {
<                     src++;
<                     n = 8 * n + JS7_UNDEC(c);
<                     c = *src;
<                     if ('0' <= c && c <= '7') {
<                         src++;
<                         i = 8 * n + JS7_UNDEC(c);
<                         if (i <= 0377)
<                             n = i;
<                         else
<                             src--;
<                     }
<                 }
<                 thisCh = (jschar)n;
<                 break;
< 
<               case 'd':
<                 AddCharacterRangeToCharSet(charSet, '0', '9');
<                 continue;   /* don't need range processing */
<               case 'D':
<                 AddCharacterRangeToCharSet(charSet, 0, '0' - 1);
<                 AddCharacterRangeToCharSet(charSet,
<                                            (jschar)('9' + 1),
<                                            (jschar)charSet->length);
<                 continue;
<               case 's':
<                 for (i = (intN)charSet->length; i >= 0; i--)
<                     if (JS_ISSPACE(i))
<                         AddCharacterToCharSet(charSet, (jschar)i);
<                 continue;
<               case 'S':
<                 for (i = (intN)charSet->length; i >= 0; i--)
<                     if (!JS_ISSPACE(i))
<                         AddCharacterToCharSet(charSet, (jschar)i);
<                 continue;
<               case 'w':
<                 for (i = (intN)charSet->length; i >= 0; i--)
<                     if (JS_ISWORD(i))
<                         AddCharacterToCharSet(charSet, (jschar)i);
<                 continue;
<               case 'W':
<                 for (i = (intN)charSet->length; i >= 0; i--)
<                     if (!JS_ISWORD(i))
<                         AddCharacterToCharSet(charSet, (jschar)i);
<                 continue;
<               default:
<                 thisCh = c;
<                 break;
< 
<             }
<             break;
< 
<           default:
<             thisCh = *src++;
<             break;
< 
<         }
<         if (inRange) {
<             if (gData->regexp->flags & JSREG_FOLD) {
<                 if (upcase(rangeStart) < upcase(thisCh)) {
<                     AddCharacterRangeToCharSet(charSet, upcase(rangeStart),
<                                                         upcase(thisCh));
<                 }
<                 if (downcase(rangeStart) < downcase(thisCh)) {
<                     AddCharacterRangeToCharSet(charSet, downcase(rangeStart),
<                                                         downcase(thisCh));
<                 }
<             } else {
<                 AddCharacterRangeToCharSet(charSet, rangeStart, thisCh);
<             }
<             inRange = JS_FALSE;
<         } else {
<             if (gData->regexp->flags & JSREG_FOLD) {
<                 AddCharacterToCharSet(charSet, upcase(thisCh));
<                 AddCharacterToCharSet(charSet, downcase(thisCh));
<             } else {
<                 AddCharacterToCharSet(charSet, thisCh);
<             }
<             if (src < end - 1) {
<                 if (*src == '-') {
<                     ++src;
<                     inRange = JS_TRUE;
<                     rangeStart = thisCh;
<                 }
<             }
<         }
<     }
<     return JS_TRUE;
< }
< 
< void
< js_DestroyRegExp(JSContext *cx, JSRegExp *re)
< {
<     if (JS_ATOMIC_DECREMENT(&re->nrefs) == 0) {
<         if (re->classList) {
<             uintN i;
<             for (i = 0; i < re->classCount; i++) {
<                 if (re->classList[i].converted)
<                     JS_free(cx, re->classList[i].u.bits);
<                 re->classList[i].u.bits = NULL;
<             }
<             JS_free(cx, re->classList);
<         }
<         JS_free(cx, re);
<     }
< }
< 
< static JSBool
< ReallocStateStack(REGlobalData *gData)
< {
<     size_t limit = gData->stateStackLimit;
<     size_t sz = sizeof(REProgState) * limit;
< 
<     JS_ARENA_GROW_CAST(gData->stateStack, REProgState *, &gData->pool, sz, sz);
<     if (!gData->stateStack) {
<         js_ReportOutOfScriptQuota(gData->cx);
<         gData->ok = JS_FALSE;
<         return JS_FALSE;
<     }
<     gData->stateStackLimit = limit + limit;
<     return JS_TRUE;
< }
< 
< #define PUSH_STATE_STACK(data)                                                \
<     JS_BEGIN_MACRO                                                            \
<         ++(data)->stateStackTop;                                              \
<         if ((data)->stateStackTop == (data)->stateStackLimit &&               \
<             !ReallocStateStack((data))) {                                     \
<             return NULL;                                                      \
<         }                                                                     \
<     JS_END_MACRO
< 
< /*
<  * Apply the current op against the given input to see if it's going to match
<  * or fail. Return false if we don't get a match, true if we do. If updatecp is
<  * true, then update the current state's cp. Always update startpc to the next
<  * op.
<  */
< JS_INLINE(static REMatchState *
< SimpleMatch(REGlobalData *gData, REMatchState *x, REOp op,
<             jsbytecode **startpc, JSBool updatecp))
< {
<     REMatchState *result = NULL;
<     jschar matchCh;
<     size_t parenIndex;
<     size_t offset, length, index;
<     jsbytecode *pc = *startpc;  /* pc has already been incremented past op */
<     jschar *source;
<     const jschar *startcp = x->cp;
<     jschar ch;
<     RECharSet *charSet;
< 
< #ifdef REGEXP_DEBUG
<     const char *opname = reop_names[op];
<     re_debug("\n%06d: %*s%s", pc - gData->regexp->program,
<              gData->stateStackTop * 2, "", opname);
< #endif
<     switch (op) {
<       case REOP_EMPTY:
<         result = x;
<         break;
<       case REOP_BOL:
<         if (x->cp != gData->cpbegin) {
<             if (!gData->cx->regExpStatics.multiline &&
<                 !(gData->regexp->flags & JSREG_MULTILINE)) {
<                 break;
<             }
<             if (!RE_IS_LINE_TERM(x->cp[-1]))
<                 break;
<         }
<         result = x;
<         break;
<       case REOP_EOL:
<         if (x->cp != gData->cpend) {
<             if (!gData->cx->regExpStatics.multiline &&
<                 !(gData->regexp->flags & JSREG_MULTILINE)) {
<                 break;
<             }
<             if (!RE_IS_LINE_TERM(*x->cp))
<                 break;
<         }
<         result = x;
<         break;
<       case REOP_WBDRY:
<         if ((x->cp == gData->cpbegin || !JS_ISWORD(x->cp[-1])) ^
<             !(x->cp != gData->cpend && JS_ISWORD(*x->cp))) {
<             result = x;
<         }
<         break;
<       case REOP_WNONBDRY:
<         if ((x->cp == gData->cpbegin || !JS_ISWORD(x->cp[-1])) ^
<             (x->cp != gData->cpend && JS_ISWORD(*x->cp))) {
<             result = x;
<         }
<         break;
<       case REOP_DOT:
<         if (x->cp != gData->cpend && !RE_IS_LINE_TERM(*x->cp)) {
<             result = x;
<             result->cp++;
<         }
<         break;
<       case REOP_DIGIT:
<         if (x->cp != gData->cpend && JS7_ISDEC(*x->cp)) {
<             result = x;
<             result->cp++;
<         }
<         break;
<       case REOP_NONDIGIT:
<         if (x->cp != gData->cpend && !JS7_ISDEC(*x->cp)) {
<             result = x;
<             result->cp++;
<         }
<         break;
<       case REOP_ALNUM:
<         if (x->cp != gData->cpend && JS_ISWORD(*x->cp)) {
<             result = x;
<             result->cp++;
<         }
<         break;
<       case REOP_NONALNUM:
<         if (x->cp != gData->cpend && !JS_ISWORD(*x->cp)) {
<             result = x;
<             result->cp++;
<         }
<         break;
<       case REOP_SPACE:
<         if (x->cp != gData->cpend && JS_ISSPACE(*x->cp)) {
<             result = x;
<             result->cp++;
<         }
<         break;
<       case REOP_NONSPACE:
<         if (x->cp != gData->cpend && !JS_ISSPACE(*x->cp)) {
<             result = x;
<             result->cp++;
<         }
<         break;
<       case REOP_BACKREF:
<         pc = ReadCompactIndex(pc, &parenIndex);
<         JS_ASSERT(parenIndex < gData->regexp->parenCount);
<         result = BackrefMatcher(gData, x, parenIndex);
<         break;
<       case REOP_FLAT:
<         pc = ReadCompactIndex(pc, &offset);
<         JS_ASSERT(offset < JSSTRING_LENGTH(gData->regexp->source));
<         pc = ReadCompactIndex(pc, &length);
<         JS_ASSERT(1 <= length);
<         JS_ASSERT(length <= JSSTRING_LENGTH(gData->regexp->source) - offset);
<         if (length <= (size_t)(gData->cpend - x->cp)) {
<             source = JSSTRING_CHARS(gData->regexp->source) + offset;
<             re_debug_chars(source, length);
<             for (index = 0; index != length; index++) {
<                 if (source[index] != x->cp[index])
<                     return NULL;
<             }
<             x->cp += length;
<             result = x;
<         }
<         break;
<       case REOP_FLAT1:
<         matchCh = *pc++;
<         re_debug(" '%c' == '%c'", (char)matchCh, (char)*x->cp);
<         if (x->cp != gData->cpend && *x->cp == matchCh) {
<             result = x;
<             result->cp++;
<         }
<         break;
<       case REOP_FLATi:
<         pc = ReadCompactIndex(pc, &offset);
<         JS_ASSERT(offset < JSSTRING_LENGTH(gData->regexp->source));
<         pc = ReadCompactIndex(pc, &length);
<         JS_ASSERT(1 <= length);
<         JS_ASSERT(length <= JSSTRING_LENGTH(gData->regexp->source) - offset);
<         source = JSSTRING_CHARS(gData->regexp->source);
<         result = FlatNIMatcher(gData, x, source + offset, length);
<         break;
<       case REOP_FLAT1i:
<         matchCh = *pc++;
<         if (x->cp != gData->cpend && upcase(*x->cp) == upcase(matchCh)) {
<             result = x;
<             result->cp++;
<         }
<         break;
<       case REOP_UCFLAT1:
<         matchCh = GET_ARG(pc);
<         re_debug(" '%c' == '%c'", (char)matchCh, (char)*x->cp);
<         pc += ARG_LEN;
<         if (x->cp != gData->cpend && *x->cp == matchCh) {
<             result = x;
<             result->cp++;
<         }
<         break;
<       case REOP_UCFLAT1i:
<         matchCh = GET_ARG(pc);
<         pc += ARG_LEN;
<         if (x->cp != gData->cpend && upcase(*x->cp) == upcase(matchCh)) {
<             result = x;
<             result->cp++;
<         }
<         break;
<       case REOP_CLASS:
<         pc = ReadCompactIndex(pc, &index);
<         JS_ASSERT(index < gData->regexp->classCount);
<         if (x->cp != gData->cpend) {
<             charSet = &gData->regexp->classList[index];
<             JS_ASSERT(charSet->converted);
<             ch = *x->cp;
<             index = ch >> 3;
<             if (charSet->length != 0 &&
<                 ch <= charSet->length &&
<                 (charSet->u.bits[index] & (1 << (ch & 0x7)))) {
<                 result = x;
<                 result->cp++;
<             }
<         }
<         break;
<       case REOP_NCLASS:
<         pc = ReadCompactIndex(pc, &index);
<         JS_ASSERT(index < gData->regexp->classCount);
<         if (x->cp != gData->cpend) {
<             charSet = &gData->regexp->classList[index];
<             JS_ASSERT(charSet->converted);
<             ch = *x->cp;
<             index = ch >> 3;
<             if (charSet->length == 0 ||
<                 ch > charSet->length ||
<                 !(charSet->u.bits[index] & (1 << (ch & 0x7)))) {
<                 result = x;
<                 result->cp++;
<             }
<         }
<         break;
< 
<       default:
<         JS_ASSERT(JS_FALSE);
<     }
<     if (result) {
<         if (!updatecp)
<             x->cp = startcp;
<         *startpc = pc;
<         re_debug(" * ");
<         return result;
<     }
<     x->cp = startcp;
<     return NULL;
< }
< 
< JS_INLINE(static REMatchState *
< ExecuteREBytecode(REGlobalData *gData, REMatchState *x))
< {
<     REMatchState *result = NULL;
<     REBackTrackData *backTrackData;
<     jsbytecode *nextpc, *testpc;
<     REOp nextop;
<     RECapture *cap;
<     REProgState *curState;
<     const jschar *startcp;
<     size_t parenIndex, k;
<     size_t parenSoFar = 0;
< 
<     jschar matchCh1, matchCh2;
<     RECharSet *charSet;
< 
<     JSBool anchor;
<     jsbytecode *pc = gData->regexp->program;
<     REOp op = (REOp) *pc++;
< 
<     /*
<      * If the first node is a simple match, step the index into the string
<      * until that match is made, or fail if it can't be found at all.
<      */
<     if (REOP_IS_SIMPLE(op) && !(gData->regexp->flags & JSREG_STICKY)) {
<         anchor = JS_FALSE;
<         while (x->cp <= gData->cpend) {
<             nextpc = pc;    /* reset back to start each time */
<             result = SimpleMatch(gData, x, op, &nextpc, JS_TRUE);
<             if (result) {
<                 anchor = JS_TRUE;
<                 x = result;
<                 pc = nextpc;    /* accept skip to next opcode */
<                 op = (REOp) *pc++;
<                 JS_ASSERT(op < REOP_LIMIT);
<                 break;
<             }
<             gData->skipped++;
<             x->cp++;
<         }
<         if (!anchor)
<             goto bad;
<     }
< 
<     for (;;) {
< #ifdef REGEXP_DEBUG
<         const char *opname = reop_names[op];
<         re_debug("\n%06d: %*s%s", pc - gData->regexp->program,
<                  gData->stateStackTop * 2, "", opname);
< #endif
<         if (REOP_IS_SIMPLE(op)) {
<             result = SimpleMatch(gData, x, op, &pc, JS_TRUE);
<         } else {
<             curState = &gData->stateStack[gData->stateStackTop];
<             switch (op) {
<               case REOP_END:
<                 goto good;
<               case REOP_ALTPREREQ2:
<                 nextpc = pc + GET_OFFSET(pc);   /* start of next op */
<                 pc += ARG_LEN;
<                 matchCh2 = GET_ARG(pc);
<                 pc += ARG_LEN;
<                 k = GET_ARG(pc);
<                 pc += ARG_LEN;
< 
<                 if (x->cp != gData->cpend) {
<                     if (*x->cp == matchCh2)
<                         goto doAlt;
< 
<                     charSet = &gData->regexp->classList[k];
<                     if (!charSet->converted && !ProcessCharSet(gData, charSet))
<                         goto bad;
<                     matchCh1 = *x->cp;
<                     k = matchCh1 >> 3;
<                     if ((charSet->length == 0 ||
<                          matchCh1 > charSet->length ||
<                          !(charSet->u.bits[k] & (1 << (matchCh1 & 0x7)))) ^
<                         charSet->sense) {
<                         goto doAlt;
<                     }
<                 }
<                 result = NULL;
<                 break;
< 
<               case REOP_ALTPREREQ:
<                 nextpc = pc + GET_OFFSET(pc);   /* start of next op */
<                 pc += ARG_LEN;
<                 matchCh1 = GET_ARG(pc);
<                 pc += ARG_LEN;
<                 matchCh2 = GET_ARG(pc);
<                 pc += ARG_LEN;
<                 if (x->cp == gData->cpend ||
<                     (*x->cp != matchCh1 && *x->cp != matchCh2)) {
<                     result = NULL;
<                     break;
<                 }
<                 /* else false thru... */
< 
<               case REOP_ALT:
<               doAlt:
<                 nextpc = pc + GET_OFFSET(pc);   /* start of next alternate */
<                 pc += ARG_LEN;                  /* start of this alternate */
<                 curState->parenSoFar = parenSoFar;
<                 PUSH_STATE_STACK(gData);
<                 op = (REOp) *pc++;
<                 startcp = x->cp;
<                 if (REOP_IS_SIMPLE(op)) {
<                     if (!SimpleMatch(gData, x, op, &pc, JS_TRUE)) {
<                         op = (REOp) *nextpc++;
<                         pc = nextpc;
<                         continue;
<                     }
<                     result = x;
<                     op = (REOp) *pc++;
<                 }
<                 nextop = (REOp) *nextpc++;
<                 if (!PushBackTrackState(gData, nextop, nextpc, x, startcp, 0, 0))
<                     goto bad;
<                 continue;
< 
<               /*
<                * Occurs at (successful) end of REOP_ALT,
<                */
<               case REOP_JUMP:
<                 /*
<                  * If we have not gotten a result here, it is because of an
<                  * empty match.  Do the same thing REOP_EMPTY would do.
<                  */
<                 if (!result)
<                     result = x;
< 
<                 --gData->stateStackTop;
<                 pc += GET_OFFSET(pc);
<                 op = (REOp) *pc++;
<                 continue;
< 
<               /*
<                * Occurs at last (successful) end of REOP_ALT,
<                */
<               case REOP_ENDALT:
<                 /*
<                  * If we have not gotten a result here, it is because of an
<                  * empty match.  Do the same thing REOP_EMPTY would do.
<                  */
<                 if (!result)
<                     result = x;
< 
<                 --gData->stateStackTop;
<                 op = (REOp) *pc++;
<                 continue;
< 
<               case REOP_LPAREN:
<                 pc = ReadCompactIndex(pc, &parenIndex);
<                 re_debug("[ %lu ]", (unsigned long) parenIndex);
<                 JS_ASSERT(parenIndex < gData->regexp->parenCount);
<                 if (parenIndex + 1 > parenSoFar)
<                     parenSoFar = parenIndex + 1;
<                 x->parens[parenIndex].index = x->cp - gData->cpbegin;
<                 x->parens[parenIndex].length = 0;
<                 op = (REOp) *pc++;
<                 continue;
< 
<               case REOP_RPAREN:
<               {
<                 ptrdiff_t delta;
< 
<                 pc = ReadCompactIndex(pc, &parenIndex);
<                 JS_ASSERT(parenIndex < gData->regexp->parenCount);
<                 cap = &x->parens[parenIndex];
<                 delta = x->cp - (gData->cpbegin + cap->index);
<                 cap->length = (delta < 0) ? 0 : (size_t) delta;
<                 op = (REOp) *pc++;
< 
<                 if (!result)
<                     result = x;
<                 continue;
<               }
<               case REOP_ASSERT:
<                 nextpc = pc + GET_OFFSET(pc);  /* start of term after ASSERT */
<                 pc += ARG_LEN;                 /* start of ASSERT child */
<                 op = (REOp) *pc++;
<                 testpc = pc;
<                 if (REOP_IS_SIMPLE(op) &&
<                     !SimpleMatch(gData, x, op, &testpc, JS_FALSE)) {
<                     result = NULL;
<                     break;
<                 }
<                 curState->u.assertion.top =
<                     (char *)gData->backTrackSP - (char *)gData->backTrackStack;
<                 curState->u.assertion.sz = gData->cursz;
<                 curState->index = x->cp - gData->cpbegin;
<                 curState->parenSoFar = parenSoFar;
<                 PUSH_STATE_STACK(gData);
<                 if (!PushBackTrackState(gData, REOP_ASSERTTEST,
<                                         nextpc, x, x->cp, 0, 0)) {
<                     goto bad;
<                 }
<                 continue;
< 
<               case REOP_ASSERT_NOT:
<                 nextpc = pc + GET_OFFSET(pc);
<                 pc += ARG_LEN;
<                 op = (REOp) *pc++;
<                 testpc = pc;
<                 if (REOP_IS_SIMPLE(op) /* Note - fail to fail! */ &&
<                     SimpleMatch(gData, x, op, &testpc, JS_FALSE) &&
<                     *testpc == REOP_ASSERTNOTTEST) {
<                     result = NULL;
<                     break;
<                 }
<                 curState->u.assertion.top
<                     = (char *)gData->backTrackSP -
<                       (char *)gData->backTrackStack;
<                 curState->u.assertion.sz = gData->cursz;
<                 curState->index = x->cp - gData->cpbegin;
<                 curState->parenSoFar = parenSoFar;
<                 PUSH_STATE_STACK(gData);
<                 if (!PushBackTrackState(gData, REOP_ASSERTNOTTEST,
<                                         nextpc, x, x->cp, 0, 0)) {
<                     goto bad;
<                 }
<                 continue;
< 
<               case REOP_ASSERTTEST:
<                 --gData->stateStackTop;
<                 --curState;
<                 x->cp = gData->cpbegin + curState->index;
<                 gData->backTrackSP =
<                     (REBackTrackData *) ((char *)gData->backTrackStack +
<                                          curState->u.assertion.top);
<                 gData->cursz = curState->u.assertion.sz;
<                 if (result)
<                     result = x;
<                 break;
< 
<               case REOP_ASSERTNOTTEST:
<                 --gData->stateStackTop;
<                 --curState;
<                 x->cp = gData->cpbegin + curState->index;
<                 gData->backTrackSP =
<                     (REBackTrackData *) ((char *)gData->backTrackStack +
<                                          curState->u.assertion.top);
<                 gData->cursz = curState->u.assertion.sz;
<                 result = (!result) ? x : NULL;
<                 break;
<               case REOP_STAR:
<                 curState->u.quantifier.min = 0;
<                 curState->u.quantifier.max = (uintN)-1;
<                 goto quantcommon;
<               case REOP_PLUS:
<                 curState->u.quantifier.min = 1;
<                 curState->u.quantifier.max = (uintN)-1;
<                 goto quantcommon;
<               case REOP_OPT:
<                 curState->u.quantifier.min = 0;
<                 curState->u.quantifier.max = 1;
<                 goto quantcommon;
<               case REOP_QUANT:
<                 pc = ReadCompactIndex(pc, &k);
<                 curState->u.quantifier.min = k;
<                 pc = ReadCompactIndex(pc, &k);
<                 /* max is k - 1 to use one byte for (uintN)-1 sentinel. */
<                 curState->u.quantifier.max = k - 1;
<                 JS_ASSERT(curState->u.quantifier.min
<                           <= curState->u.quantifier.max);
<               quantcommon:
<                 if (curState->u.quantifier.max == 0) {
<                     pc = pc + GET_OFFSET(pc);
<                     op = (REOp) *pc++;
<                     result = x;
<                     continue;
<                 }
<                 /* Step over <next> */
<                 nextpc = pc + ARG_LEN;
<                 op = (REOp) *nextpc++;
<                 startcp = x->cp;
<                 if (REOP_IS_SIMPLE(op)) {
<                     if (!SimpleMatch(gData, x, op, &nextpc, JS_TRUE)) {
<                         if (curState->u.quantifier.min == 0)
<                             result = x;
<                         else
<                             result = NULL;
<                         pc = pc + GET_OFFSET(pc);
<                         break;
<                     }
<                     op = (REOp) *nextpc++;
<                     result = x;
<                 }
<                 curState->index = startcp - gData->cpbegin;
<                 curState->continue_op = REOP_REPEAT;
<                 curState->continue_pc = pc;
<                 curState->parenSoFar = parenSoFar;
<                 PUSH_STATE_STACK(gData);
<                 if (curState->u.quantifier.min == 0 &&
<                     !PushBackTrackState(gData, REOP_REPEAT, pc, x, startcp,
<                                         0, 0)) {
<                     goto bad;
<                 }
<                 pc = nextpc;
<                 continue;
< 
<               case REOP_ENDCHILD: /* marks the end of a quantifier child */
<                 pc = curState[-1].continue_pc;
<                 op = (REOp) curState[-1].continue_op;
< 
<                 if (!result)
<                     result = x;
<                 continue;
< 
<               case REOP_REPEAT:
<                 --curState;
<                 do {
<                     --gData->stateStackTop;
<                     if (!result) {
<                         /* Failed, see if we have enough children. */
<                         if (curState->u.quantifier.min == 0)
<                             goto repeatDone;
<                         goto break_switch;
<                     }
<                     if (curState->u.quantifier.min == 0 &&
<                         x->cp == gData->cpbegin + curState->index) {
<                         /* matched an empty string, that'll get us nowhere */
<                         result = NULL;
<                         goto break_switch;
<                     }
<                     if (curState->u.quantifier.min != 0)
<                         curState->u.quantifier.min--;
<                     if (curState->u.quantifier.max != (uintN) -1)
<                         curState->u.quantifier.max--;
<                     if (curState->u.quantifier.max == 0)
<                         goto repeatDone;
<                     nextpc = pc + ARG_LEN;
<                     nextop = (REOp) *nextpc;
<                     startcp = x->cp;
<                     if (REOP_IS_SIMPLE(nextop)) {
<                         nextpc++;
<                         if (!SimpleMatch(gData, x, nextop, &nextpc, JS_TRUE)) {
<                             if (curState->u.quantifier.min == 0)
<                                 goto repeatDone;
<                             result = NULL;
<                             goto break_switch;
<                         }
<                         result = x;
<                     }
<                     curState->index = startcp - gData->cpbegin;
<                     PUSH_STATE_STACK(gData);
<                     if (curState->u.quantifier.min == 0 &&
<                         !PushBackTrackState(gData, REOP_REPEAT,
<                                             pc, x, startcp,
<                                             curState->parenSoFar,
<                                             parenSoFar -
<                                             curState->parenSoFar)) {
<                         goto bad;
<                     }
<                 } while (*nextpc == REOP_ENDCHILD);
<                 pc = nextpc;
<                 op = (REOp) *pc++;
<                 parenSoFar = curState->parenSoFar;
<                 continue;
< 
<               repeatDone:
<                 result = x;
<                 pc += GET_OFFSET(pc);
<                 goto break_switch;
< 
<               case REOP_MINIMALSTAR:
<                 curState->u.quantifier.min = 0;
<                 curState->u.quantifier.max = (uintN)-1;
<                 goto minimalquantcommon;
<               case REOP_MINIMALPLUS:
<                 curState->u.quantifier.min = 1;
<                 curState->u.quantifier.max = (uintN)-1;
<                 goto minimalquantcommon;
<               case REOP_MINIMALOPT:
<                 curState->u.quantifier.min = 0;
<                 curState->u.quantifier.max = 1;
<                 goto minimalquantcommon;
<               case REOP_MINIMALQUANT:
<                 pc = ReadCompactIndex(pc, &k);
<                 curState->u.quantifier.min = k;
<                 pc = ReadCompactIndex(pc, &k);
<                 /* See REOP_QUANT comments about k - 1. */
<                 curState->u.quantifier.max = k - 1;
<                 JS_ASSERT(curState->u.quantifier.min
<                           <= curState->u.quantifier.max);
<               minimalquantcommon:
<                 curState->index = x->cp - gData->cpbegin;
<                 curState->parenSoFar = parenSoFar;
<                 PUSH_STATE_STACK(gData);
<                 if (curState->u.quantifier.min != 0) {
<                     curState->continue_op = REOP_MINIMALREPEAT;
<                     curState->continue_pc = pc;
<                     /* step over <next> */
<                     pc += OFFSET_LEN;
<                     op = (REOp) *pc++;
<                 } else {
<                     if (!PushBackTrackState(gData, REOP_MINIMALREPEAT,
<                                             pc, x, x->cp, 0, 0)) {
<                         goto bad;
<                     }
<                     --gData->stateStackTop;
<                     pc = pc + GET_OFFSET(pc);
<                     op = (REOp) *pc++;
<                 }
<                 continue;
< 
<               case REOP_MINIMALREPEAT:
<                 --gData->stateStackTop;
<                 --curState;
< 
<                 re_debug("{%d,%d}", curState->u.quantifier.min,
<                          curState->u.quantifier.max);
< #define PREPARE_REPEAT()                                                      \
<     JS_BEGIN_MACRO                                                            \
<         curState->index = x->cp - gData->cpbegin;                             \
<         curState->continue_op = REOP_MINIMALREPEAT;                           \
<         curState->continue_pc = pc;                                           \
<         pc += ARG_LEN;                                                        \
<         for (k = curState->parenSoFar; k < parenSoFar; k++)                   \
<             x->parens[k].index = -1;                                          \
<         PUSH_STATE_STACK(gData);                                              \
<         op = (REOp) *pc++;                                                    \
<         JS_ASSERT(op < REOP_LIMIT);                                           \
<     JS_END_MACRO
< 
<                 if (!result) {
<                     re_debug(" - ");
<                     /*
<                      * Non-greedy failure - try to consume another child.
<                      */
<                     if (curState->u.quantifier.max == (uintN) -1 ||
<                         curState->u.quantifier.max > 0) {
<                         PREPARE_REPEAT();
<                         continue;
<                     }
<                     /* Don't need to adjust pc since we're going to pop. */
<                     break;
<                 }
<                 if (curState->u.quantifier.min == 0 &&
<                     x->cp == gData->cpbegin + curState->index) {
<                     /* Matched an empty string, that'll get us nowhere. */
<                     result = NULL;
<                     break;
<                 }
<                 if (curState->u.quantifier.min != 0)
<                     curState->u.quantifier.min--;
<                 if (curState->u.quantifier.max != (uintN) -1)
<                     curState->u.quantifier.max--;
<                 if (curState->u.quantifier.min != 0) {
<                     PREPARE_REPEAT();
<                     continue;
<                 }
<                 curState->index = x->cp - gData->cpbegin;
<                 curState->parenSoFar = parenSoFar;
<                 PUSH_STATE_STACK(gData);
<                 if (!PushBackTrackState(gData, REOP_MINIMALREPEAT,
<                                         pc, x, x->cp,
<                                         curState->parenSoFar,
<                                         parenSoFar - curState->parenSoFar)) {
<                     goto bad;
<                 }
<                 --gData->stateStackTop;
<                 pc = pc + GET_OFFSET(pc);
<                 op = (REOp) *pc++;
<                 JS_ASSERT(op < REOP_LIMIT);
<                 continue;
<               default:
<                 JS_ASSERT(JS_FALSE);
<                 result = NULL;
<             }
<           break_switch:;
<         }
< 
<         /*
<          *  If the match failed and there's a backtrack option, take it.
<          *  Otherwise this is a complete and utter failure.
<          */
<         if (!result) {
<             if (gData->cursz == 0)
<                 return NULL;
<             if (!JS_CHECK_OPERATION_LIMIT(gData->cx, JSOW_JUMP)) {
<                 gData->ok = JS_FALSE;
<                 return NULL;
<             }
< 
<             /* Potentially detect explosive regex here. */
<             gData->backTrackCount++;
<             if (gData->backTrackLimit &&
<                 gData->backTrackCount >= gData->backTrackLimit) {
<                 JS_ReportErrorNumber(gData->cx, js_GetErrorMessage, NULL,
<                                      JSMSG_REGEXP_TOO_COMPLEX);
<                 gData->ok = JS_FALSE;
<                 return NULL;
---
>     if (len != 0 && flat) {
>         cp = state.cpbegin;
>         ren = NULL;
>         do {
>             ren2 = NewRENode(&state, 
>                              (len == 1) ? REOP_FLAT1 : REOP_FLAT,
>                              (void *)cp);
> 	    if (!ren2)
> 	        goto out;
> 	    ren2->flags = RENODE_NONEMPTY;
> 	    if (len > 1) {
>                 if (len > REOP_FLATLEN_MAX) {
>                     cp += REOP_FLATLEN_MAX;
>                     len -= REOP_FLATLEN_MAX;
>                 }
>                 else {
>                     cp += len;
>                     len = 0;
>                 }
> 	        ren2->u.kid2 = (void *)cp;                
> 	    } else {
> 	        ren2->flags |= RENODE_SINGLE;
> 	        ren2->u.chr = *cp;
>                 len = 0;
3217,3242c1309,1311
< 
<             backTrackData = gData->backTrackSP;
<             gData->cursz = backTrackData->sz;
<             gData->backTrackSP =
<                 (REBackTrackData *) ((char *)backTrackData - backTrackData->sz);
<             x->cp = backTrackData->cp;
<             pc = backTrackData->backtrack_pc;
<             op = (REOp) backTrackData->backtrack_op;
<             JS_ASSERT(op < REOP_LIMIT);
<             gData->stateStackTop = backTrackData->saveStateStackTop;
<             JS_ASSERT(gData->stateStackTop);
< 
<             memcpy(gData->stateStack, backTrackData + 1,
<                    sizeof(REProgState) * backTrackData->saveStateStackTop);
<             curState = &gData->stateStack[gData->stateStackTop - 1];
< 
<             if (backTrackData->parenCount) {
<                 memcpy(&x->parens[backTrackData->parenIndex],
<                        (char *)(backTrackData + 1) +
<                        sizeof(REProgState) * backTrackData->saveStateStackTop,
<                        sizeof(RECapture) * backTrackData->parenCount);
<                 parenSoFar = backTrackData->parenIndex + backTrackData->parenCount;
<             } else {
<                 for (k = curState->parenSoFar; k < parenSoFar; k++)
<                     x->parens[k].index = -1;
<                 parenSoFar = curState->parenSoFar;
---
>             if (ren) {
>                 if (!SetNext(&state, ren, ren2))
>                     goto out;
3243a1313,1329
>             else
>                 ren = ren2;
>         } while (len > 0);
>     }
>     else
>         ren = ParseRegExp(&state);
>     if (!ren)
> 	goto out;
> 
>     end = NewRENode(&state, REOP_END, NULL);
>     if (!end || !SetNext(&state, ren, end))
> 	goto out;
> 
> #ifdef DEBUG_notme
>     if (!DumpRegExp(cx, ren))
> 	goto out;
> #endif
3245,3250c1331,1340
<             re_debug("\tBT_Pop: %ld,%ld",
<                      (unsigned long) backTrackData->parenIndex,
<                      (unsigned long) backTrackData->parenCount);
<             continue;
<         }
<         x = result;
---
>     resize = sizeof *re + state.progLength - 1;
>  	XMEMTAG("jsregexp JSRegExp");
>    	re = (JSRegExp *) JS_malloc(cx, JS_ROUNDUP(resize, sizeof(jsword)));
>     if (!re)
> 	goto out;
>     re->nrefs = 1;
>     re->parenCount = state.parenCount;
>     re->flags = flags;
>     re->source = str;
>     re->ren = ren;
3252,3257c1342,1345
<         /*
<          *  Continue with the expression.
<          */
<         op = (REOp)*pc++;
<         JS_ASSERT(op < REOP_LIMIT);
<     }
---
> out:
>     JS_ARENA_RELEASE(&cx->tempPool, mark);
>     return re;
> }
3259,3261c1347,1353
< bad:
<     re_debug("\n");
<     return NULL;
---
> JSRegExp *
> js_NewRegExpOpt(JSContext *cx, JSTokenStream *ts, 
>                 JSString *str, JSString *opt, JSBool flat)
> {
>     uintN flags;
>     jschar *s;
>     size_t i, n;
3263,3265c1355,1412
< good:
<     re_debug("\n");
<     return x;
---
>     flags = 0;
>     if (opt) {
> 	s = JSSTRING_CHARS(opt);
> 	for (i = 0, n = JSSTRING_LENGTH(opt); i < n; i++) {
> 	    switch (s[i]) {
> 	      case 'g':
> 		flags |= JSREG_GLOB;
> 		break;
> 	      case 'i':
> 		flags |= JSREG_FOLD;
> 		break;
> 	      case 'm':
> 		flags |= JSREG_MULTILINE;
> 		break;
> 	      default: {
> 		char charBuf[2] = " ";
> 		charBuf[0] = (char)s[i];
>                 js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
>                                             JSMSG_BAD_FLAG, charBuf);
> 		return NULL;
> 	      }
> 	    }
> 	}
>     }
>     return js_NewRegExp(cx, ts, str, flags, flat);
> }
> 
> static void freeRENtree(JSContext *cx, RENode *ren,  RENode *stop)
> {
>     while (ren && (ren != stop)) {
>         RENode *n;
>         switch (ren->op) {
>             case REOP_ALT: {
>                         RENode *altStop = (RENode *)(ren->next);
>                         while (altStop && (altStop->op == REOP_ALT))
>                             altStop = altStop->next;
>                         freeRENtree(cx, (RENode *)(ren->kid), altStop);
>                     }
>                     break;
>             case REOP_QUANT:
>             case REOP_PLUS:
>             case REOP_STAR:
>             case REOP_OPT:
>             case REOP_LPAREN:
>             case REOP_LPARENNON:
>             case REOP_ASSERT:
>             case REOP_ASSERT_NOT:
>                 freeRENtree(cx, (RENode *)(ren->kid), (RENode *)(ren->next));
>                 break;
>             case REOP_CCLASS:
>                 if (ren->u.ucclass.bitmap)
>                     JS_free(cx, ren->u.ucclass.bitmap);
>                 break;
>         }
>         n = ren->next;
>         JS_free(cx, ren);
>         ren = n;
>     }
3268,3274c1415,1416
< static REMatchState *
< MatchRegExp(REGlobalData *gData, REMatchState *x)
< {
<     REMatchState *result;
<     const jschar *cp = x->cp;
<     const jschar *cp2;
<     uintN j;
---
> #define HOLD_REGEXP(cx, re) JS_ATOMIC_INCREMENT(&(re)->nrefs)
> #define DROP_REGEXP(cx, re) js_DestroyRegExp(cx, re)
3276,3291c1418,1423
<     /*
<      * Have to include the position beyond the last character
<      * in order to detect end-of-input/line condition.
<      */
<     for (cp2 = cp; cp2 <= gData->cpend; cp2++) {
<         gData->skipped = cp2 - cp;
<         x->cp = cp2;
<         for (j = 0; j < gData->regexp->parenCount; j++)
<             x->parens[j].index = -1;
<         result = ExecuteREBytecode(gData, x);
<         if (!gData->ok || result || (gData->regexp->flags & JSREG_STICKY))
<             return result;
<         gData->backTrackSP = gData->backTrackStack;
<         gData->cursz = 0;
<         gData->stateStackTop = 0;
<         cp2 = cp + gData->skipped;
---
> void
> js_DestroyRegExp(JSContext *cx, JSRegExp *re)
> {
>     if (JS_ATOMIC_DECREMENT(&re->nrefs) == 0) {
>         freeRENtree(cx, re->ren, NULL);
>         JS_free(cx, re);
3293d1424
<     return NULL;
3296c1427,1443
< #define MIN_BACKTRACK_LIMIT 400000
---
> typedef struct MatchState {
>     JSContext       *context;           /* for access to regExpStatics */
>     JSBool          anchoring;          /* true if multiline anchoring ^/$ */
>     jsbytecode      *pcend;             /* pc limit (fencepost) */
>     const jschar    *cpbegin, *cpend;   /* cp base address and limit */
>     size_t          start;              /* offset from cpbegin to start at */
>     ptrdiff_t       skipped;            /* chars skipped anchoring this r.e. */
>     uint8           flags;              /* flags */
>     uintN           parenCount;         /* number of paren substring matches */
>     JSSubString     *maybeParens;       /* possible paren substring pointers */
>     JSSubString     *parens;            /* certain paren substring matches */
>     JSBool          ok;                 /* indicates runtime error during matching */
> } MatchState;
> 
> /*
>  * Returns updated cp on match, null on mismatch.
>  */
3298,3299c1445
< static REMatchState *
< InitMatch(JSContext *cx, REGlobalData *gData, JSRegExp *re, size_t length)
---
> static JSBool matchChar(int flags, jschar c, jschar c2)
3301,3302c1447,1456
<     REMatchState *result;
<     uintN i;
---
>     if (c == c2)
>         return JS_TRUE;
>     else
>         if ((flags & JSREG_FOLD) != 0) {
>             return ((c = (jschar)JS_TOUPPER(c)) == (c2 = (jschar)JS_TOUPPER(c2)))
>                     || (JS_TOLOWER(c) == JS_TOLOWER(c2));
>         }
>         else
>             return JS_FALSE;
> }
3304,3309c1458,1459
<     gData->backTrackStackSize = INITIAL_BACKTRACK;
<     JS_ARENA_ALLOCATE_CAST(gData->backTrackStack, REBackTrackData *,
<                            &gData->pool,
<                            INITIAL_BACKTRACK);
<     if (!gData->backTrackStack)
<         goto bad;
---
> static const jschar *matchRENodes(MatchState *state, RENode *ren, RENode *stop,
>                                                 const jschar *cp);
3311,3318c1461,1481
<     gData->backTrackSP = gData->backTrackStack;
<     gData->cursz = 0;
<     gData->backTrackCount = 0;
<     gData->backTrackLimit = 0;
<     if (JS_GetOptions(cx) & JSOPTION_RELIMIT) {
<         gData->backTrackLimit = length * length * length; /* O(n^3) */
<         if (gData->backTrackLimit < MIN_BACKTRACK_LIMIT)
<             gData->backTrackLimit = MIN_BACKTRACK_LIMIT;
---
> typedef struct {
>     MatchState *state;
>     RENode *kid;
>     RENode *next;
>     RENode *stop;
>     int kidCount;
>     int maxKid;
> } GreedyState;
> 
> 
> static const jschar *greedyRecurse(GreedyState *grState, const jschar *cp, const jschar *previousKid)
> {
>     const jschar *kidMatch;
>     const jschar *match;
>     int num = grState->state->parenCount;
> 
> #ifdef XP_MAC
>     if (StackSpace() < 16384) {
>         JS_ReportOutOfMemory (grState->state->context);
>         grState->state->ok = JS_FALSE;
>         return NULL;
3319a1483
> #endif
3321,3326c1485,1522
<     gData->stateStackLimit = INITIAL_STATESTACK;
<     JS_ARENA_ALLOCATE_CAST(gData->stateStack, REProgState *,
<                            &gData->pool,
<                            sizeof(REProgState) * INITIAL_STATESTACK);
<     if (!gData->stateStack)
<         goto bad;
---
> /*
> *    When the kid match fails, we reset the parencount and run any 
> *    previously succesful kid in order to restablish it's paren
> *    contents.
> */
> 
>     kidMatch = matchRENodes(grState->state, grState->kid, grState->next, cp);
>     if (kidMatch == NULL) {        
>         match = matchRENodes(grState->state, grState->next, grState->stop, cp);
>         if (match) {
>             grState->state->parenCount = num;
>             if (previousKid != NULL)
>                 matchRENodes(grState->state, grState->kid, grState->next, previousKid);
>             return cp;
>         }
>             return NULL;
>     }
>     else {
>         if (kidMatch == cp) {
>             if (previousKid != NULL)
>                 matchRENodes(grState->state, grState->kid, grState->next, previousKid);
>             return kidMatch;    /* no point pursuing an empty match forever */
>         }
>         if (!grState->maxKid || (++grState->kidCount < grState->maxKid)) {
>             match = greedyRecurse(grState, kidMatch, cp);
>             if (match)
>                 return match;
>             if (grState->maxKid)
>             --grState->kidCount;
>         }
>         grState->state->parenCount = num;
>         if (matchRENodes(grState->state, grState->next, grState->stop, kidMatch)) {
>             matchRENodes(grState->state, grState->kid, grState->next, cp);
>             return kidMatch;
>         }
>             return NULL;
>     }
> }
3328,3338c1524,1545
<     gData->stateStackTop = 0;
<     gData->cx = cx;
<     gData->regexp = re;
<     gData->ok = JS_TRUE;
< 
<     JS_ARENA_ALLOCATE_CAST(result, REMatchState *,
<                            &gData->pool,
<                            offsetof(REMatchState, parens)
<                            + re->parenCount * sizeof(RECapture));
<     if (!result)
<         goto bad;
---
> static const jschar *matchGreedyKid(MatchState *state, RENode *ren, RENode *stop,
>                         int kidCount, const jschar *cp, const jschar *previousKid)
> {
>     GreedyState grState;
>     const jschar *match;
>     grState.state = state;
>     grState.kid = (RENode *)ren->kid;
>     grState.next = ren->next;
>     grState.kidCount = kidCount;
>     grState.maxKid = (ren->op == REOP_QUANT) ? ren->u.range.max : 0;
>     /*
>         We try to match the sub-tree to completion first, and if that
>         doesn't work, match only up to the given end of the sub-tree.
>     */
>     grState.stop = NULL;
>     match = greedyRecurse(&grState, cp, previousKid);
>     if (match || !stop) 
>         return match;
>     grState.kidCount = kidCount;
>     grState.stop = stop;
>     return greedyRecurse(&grState, cp, previousKid);
> }
3340,3343c1547,1599
<     for (i = 0; i < re->classCount; i++) {
<         if (!re->classList[i].converted &&
<             !ProcessCharSet(gData, &re->classList[i])) {
<             return NULL;
---
> 
> static const jschar *matchNonGreedyKid(MatchState *state, RENode *ren,
>                         int kidCount, int maxKid,
>                         const jschar *cp)
> {
>     const jschar *kidMatch;
>     const jschar *match;
> 
>     match = matchRENodes(state, ren->next, NULL, cp);
>     if (match != NULL) return cp;
>     kidMatch = matchRENodes(state, (RENode *)ren->kid, ren->next, cp);
>     if (kidMatch == NULL)
>         return NULL;
>     if (kidMatch == cp)
>         return kidMatch;    /* no point pursuing an empty match forever */
>         return matchNonGreedyKid(state, ren, kidCount, maxKid, kidMatch);
>     }
> 
> static void calcBMSize(MatchState *state, RENode *ren)
> {
>     const jschar *cp  = (const jschar *) ren->kid;
>     const jschar *cp2 = (const jschar *) ren->u.kid2;
>     uintN maxc = 0;
>     jschar c, c2;
>     while (cp < cp2) {
>         c = *cp++;
>         if (c == '\\') {
>             if (cp + 5 <= cp2 && *cp == 'u' &&
>                 JS7_ISHEX(cp[1]) && JS7_ISHEX(cp[2]) &&
>                 JS7_ISHEX(cp[3]) && JS7_ISHEX(cp[4])) {
>                 c = (((((JS7_UNHEX(cp[1]) << 4)
>                         + JS7_UNHEX(cp[2])) << 4)
>                       + JS7_UNHEX(cp[3])) << 4)
>                     + JS7_UNHEX(cp[4]);
>                 cp += 5;
>             } 
>             else {
>                 /* 
>                  * For the not whitespace, not word or not digit cases
>                  * we widen the range to the complete unicode range.
>                  */
>                 if ((*cp == 'S') || (*cp == 'W') || (*cp == 'D')) {
>                     maxc = 65535;
>                     break;  /* leave now, it can't get worse */
>                 }
>                 if (maxc < 255) maxc = 255;
>                 /*
>                  * Octal and hex escapes can't be > 255.  Skip this
>                  * backslash and let the loop pass over the remaining
>                  * escape sequence as if it were text to match.
>                  */
>                 continue;
>             }
3344a1601,1642
>         if (state->flags & JSREG_FOLD) {
>             /*
>              * Don't assume that lowercase are above uppercase, or
>              * that c is either even when c has upper and lowercase
>              * versions.
>              */
>             if ((c2 = (jschar)JS_TOUPPER(c)) > maxc)
>                 maxc = c2;
>             if ((c2 = (jschar)JS_TOLOWER(c2)) > maxc)
>                 maxc = c2;
>         }
>         if (c > maxc)
>             maxc = c;
>     }
>     ren->u.ucclass.bmsize = (uint16)((size_t)(maxc + JS_BITS_PER_BYTE) 
>                                                     / JS_BITS_PER_BYTE);
> }
> 
> static JSBool buildBitmap(MatchState *state, RENode *ren)
> {
>     uintN   i, n, b, c, lastc, foldc, nchars;
>     uint8   *bitmap;
>     uint8   fill;
>     JSBool  inrange;
>     const jschar *cp = (const jschar *) ren->kid;
>     const jschar *end = (const jschar *) ren->u.kid2;
>     const jschar *ocp;
> 
>     calcBMSize(state, ren);
>     XMEMTAG("jsregexp buildBitmap");
>     ren->u.ucclass.bitmap = bitmap = (uint8*) JS_malloc(state->context, 
>                                             ren->u.ucclass.bmsize);
>     if (!bitmap) {
> 	JS_ReportOutOfMemory(state->context);
> 	return JS_FALSE;
>     }
> 
>     if (*cp == '^') {
> 	fill = 0xff;
> 	cp++;
>     } else {
> 	fill = 0;
3347c1645,1822
<     return result;
---
>     n = (uintN)ren->u.ucclass.bmsize;
>     for (i = 0; i < n; i++)
> 	bitmap[i] = fill;
>     nchars = n * JS_BITS_PER_BYTE;
> 
> /* Split ops up into statements to keep MSVC1.52 from crashing. */
> #define MATCH_BIT(c)    { i = (c) >> 3; b = (c) & 7; b = 1 << b;              \
> 		  if (fill) bitmap[i] &= ~b; else bitmap[i] |= b; }
> 
>     lastc = nchars;
>     inrange = JS_FALSE;
> 
>     while (cp < end) {
> 	c = (uintN) *cp++;
> 	if (c == '\\') {
> 	    c = *cp++;
> 	    switch (c) {
> 	      case 'b':
> 	      case 'f':
> 	      case 'n':
> 	      case 'r':
> 	      case 't':
> 	      case 'v':
> 		c = js_strchr(js_EscapeMap, (jschar)c)[-1];
> 		break;
> 
> #define CHECK_RANGE() if (inrange) { MATCH_BIT(lastc); MATCH_BIT('-');        \
> 			     inrange = JS_FALSE; }
> 
> 	      case 'd':
> 		CHECK_RANGE();
> 		for (c = '0'; c <= '9'; c++)
> 		    MATCH_BIT(c);
> 		continue;
> 
> 	      case 'D':
> 		CHECK_RANGE();
> 		for (c = 0; c < '0'; c++)
> 		    MATCH_BIT(c);
> 		for (c = '9' + 1; c < nchars; c++)
> 		    MATCH_BIT(c);
> 		continue;
> 
> 	      case 'w':
> 		CHECK_RANGE();
> 		for (c = 0; c < nchars; c++)
> 		    if (JS_ISWORD(c))
> 			MATCH_BIT(c);
> 		continue;
> 
> 	      case 'W':
> 		CHECK_RANGE();
> 		for (c = 0; c < nchars; c++)
> 		    if (!JS_ISWORD(c))
> 			MATCH_BIT(c);
> 		continue;
> 
> 	      case 's':
> 		CHECK_RANGE();
> 		for (c = 0; c < nchars; c++)
> 		    if (JS_ISSPACE(c))
> 			MATCH_BIT(c);
> 		continue;
> 
> 	      case 'S':
> 		CHECK_RANGE();
> 		for (c = 0; c < nchars; c++)
> 		    if (!JS_ISSPACE(c))
> 			MATCH_BIT(c);
> 		continue;
> 
> #undef CHECK_RANGE
> 
> 	      case '0':
> 	      case '1':
> 	      case '2':
> 	      case '3':
> 	      case '4':
> 	      case '5':
> 	      case '6':
> 	      case '7':
> 		n = JS7_UNDEC(c);
> 		ocp = cp - 2;
> 		c = *cp;
> 		if ('0' <= c && c <= '7') {
> 		    cp++;
> 		    n = 8 * n + JS7_UNDEC(c);
> 
> 		    c = *cp;
> 		    if ('0' <= c && c <= '7') {
> 			cp++;
> 			i = 8 * n + JS7_UNDEC(c);
> 			if (i <= 0377)
> 			    n = i;
> 			else
> 			    cp--;
> 		    }
> 		}
> 		c = n;
> 		break;
> 
> 	      case 'x':
> 		ocp = cp;
> 		c = *cp++;
> 		if (JS7_ISHEX(c)) {
> 		    n = JS7_UNHEX((char) c);
> 		    c = *cp++;
> 		    if (JS7_ISHEX(c)) {
> 			n <<= 4;
> 			n += JS7_UNHEX((char) c);
> 		    }
> 		} else {
> 		    cp = ocp;	/* \xZZ is xZZ (Perl does \0ZZ!) */
> 		    n = 'x';
> 		}
> 		c = n;
> 		break;
> 
> 	      case 'u':
> 		if (JS7_ISHEX(cp[0]) && JS7_ISHEX(cp[1]) &&
> 		    JS7_ISHEX(cp[2]) && JS7_ISHEX(cp[3])) {
> 		    n = (((((JS7_UNHEX(cp[0]) << 4)
> 			    + JS7_UNHEX(cp[1])) << 4)
> 			  + JS7_UNHEX(cp[2])) << 4)
> 			+ JS7_UNHEX(cp[3]);
> 		    c = n;
> 		    cp += 4;
> 		}
> 		break;
> 
> 	      case 'c':
> 		c = *cp++;
> 		c = JS_TOUPPER(c);
> 		c = JS_TOCTRL(c);
> 		break;
> 	    }
> 	}
> 
> 	if (inrange) {
> 	    if (lastc > c) {
> 		JS_ReportErrorNumber(state->context,
> 				     js_GetErrorMessage, NULL,
> 				     JSMSG_BAD_CLASS_RANGE);
> 		return JS_FALSE;
> 	    }
> 	    inrange = JS_FALSE;
> 	} else {
> 	    /* Set lastc so we match just c's bit in the for loop. */
> 	    lastc = c;
> 
> 	    /* [balance: */
> 	    if (*cp == '-' && cp + 1 < end && cp[1] != ']') {
> 		cp++;
> 		inrange = JS_TRUE;
> 		continue;
> 	    }
> 	}
> 
> 	/* Match characters in the range [lastc, c]. */
> 	for (; lastc <= c; lastc++) {
> 	    MATCH_BIT(lastc);
> 	    if (state->flags & JSREG_FOLD) {
> 		/*
> 		 * Must do both upper and lower for Turkish dotless i,
> 		 * Georgian, etc.
> 		 */
> 		foldc = JS_TOUPPER(lastc);
> 		MATCH_BIT(foldc);
> 		foldc = JS_TOLOWER(foldc);
> 		MATCH_BIT(foldc);
> 	    }
> 	}
> 	lastc = c;
>     }
> #define IS_LINE_TERMINATOR(c) ( (c == '\n')               \
>                                 || (c == '\r')            \
>                                 || (c == LINE_SEPARATOR)  \
>                                 || (c == PARA_SEPARATOR) )
3349,3351c1824,2170
< bad:
<     js_ReportOutOfScriptQuota(cx);
<     gData->ok = JS_FALSE;
---
>     return JS_TRUE;
> }
> 
> static const jschar *matchRENodes(MatchState *state, RENode *ren, RENode *stop,
>                                                 const jschar *cp)
> {
>     const jschar *cp2, *kidMatch, *lastKid, *source, *cpend = state->cpend;
>     jschar c;
>     JSSubString *parsub;
>     uintN i, b, bit, num, length;
> 
>     while ((ren != stop) && (ren != NULL))
>     {
>       switch (ren->op) {
>         case REOP_EMPTY:
>           break;
>         case REOP_ALT:
>           if (ren->next->op != REOP_ALT) {
>               ren = (RENode *)ren->kid;
>               continue;
>           }
>           num = state->parenCount;
>           kidMatch = matchRENodes(state, (RENode *)ren->kid, stop, cp);
>           if (kidMatch != NULL)
>               return kidMatch;
>           for (i = num; i < state->parenCount; i++)
>               state->parens[i].length = 0;
>           state->parenCount = num;
>           break;
>         case REOP_QUANT:
>           lastKid = NULL;
>           for (num = 0; num < ren->u.range.min; num++) {
>               kidMatch = matchRENodes(state, (RENode *)ren->kid,
>                                           ren->next, cp);
>               if (kidMatch == NULL)
>                   return NULL;
>               lastKid = cp;
>               cp = kidMatch;
>           }
>           if (num == ren->u.range.max) break;
>           if ((ren->flags & RENODE_MINIMAL) == 0) {
>               cp2 = matchGreedyKid(state, ren, stop, num, cp, lastKid);
>               if (cp2 == NULL) {
>                   if (lastKid)
>                       cp = matchRENodes(state, (RENode *)ren->kid, ren->next,
>                                         lastKid);
>               }
>               else
>                   cp = cp2;
>           }
>           else {
>               cp = matchNonGreedyKid(state, ren, num,
>                               ren->u.range.max, cp);
>               if (cp == NULL)
>                   return NULL;
>           }
>           break;
>         case REOP_PLUS:
>           kidMatch = matchRENodes(state, (RENode *)ren->kid,
>                                           ren->next, cp);
>           if (kidMatch == NULL)
>               return NULL;
>           if ((ren->flags & RENODE_MINIMAL) == 0) {
>               cp2 = matchGreedyKid(state, ren, stop, 1, kidMatch, cp);
>               if (cp2 == NULL)
>                   cp = matchRENodes(state, (RENode *)ren->kid, ren->next, cp);
>               else
>                   cp = cp2;
>           }
>           else
>               cp = matchNonGreedyKid(state, ren, 1, 0, kidMatch);
>           if (cp == NULL)
>               return NULL;
>           break;
>         case REOP_STAR:
>           if ((ren->flags & RENODE_MINIMAL) == 0) {
>               cp2 = matchGreedyKid(state, ren, stop, 0, cp, NULL);
>               if (cp2)
>                   cp = cp2;
>           }
>           else {
>               cp = matchNonGreedyKid(state, ren, 0, 0, cp);
>               if (cp == NULL)
>                   return NULL;
>           }
>           break;
>         case REOP_OPT:
>           num = state->parenCount;
>           if (ren->flags & RENODE_MINIMAL) {
>               const jschar *restMatch = matchRENodes(state, ren->next,
>                                             stop, cp);
>               if (restMatch != NULL)
>                   return restMatch;
>           }
>           kidMatch = matchRENodes(state, (RENode *)ren->kid,
>                                         ren->next, cp);
>           if (kidMatch == NULL) {
>               /* need to undo the result of running the kid */
>               for (i = num; i < state->parenCount; i++)
>                   state->parens[i].length = 0;
>               state->parenCount = num;
>               break;
>           }
>           else {
>               const jschar *restMatch = matchRENodes(state, ren->next,
>                                             stop, kidMatch);
>               if (restMatch == NULL) {
>                     /* need to undo the result of running the kid */
>                   for (i = num; i < state->parenCount; i++)
>                       state->parens[i].length = 0;
>                   state->parenCount = num;
>                   break;
>               }
>               else
>                   return restMatch;
>           }
>         case REOP_LPARENNON:
>           ren = (RENode *)ren->kid;
>           continue;
>         case REOP_RPARENNON:
>           break;
>         case REOP_LPAREN:
>           num = ren->u.num;
>           ren = (RENode *)ren->kid;
> 	  parsub = &state->parens[num];
> 	  parsub->chars = cp;
>           parsub->length = 0;
>           if (num >= state->parenCount)
>               state->parenCount = num + 1;
>           continue;
>         case REOP_RPAREN:
>           num = ren->u.num;
>           parsub = &state->parens[num];
>           parsub->length = cp - parsub->chars;
>           break;
>         case REOP_ASSERT:
>           kidMatch = matchRENodes(state, (RENode *)ren->kid,
>                                             ren->next, cp);
>           if (kidMatch == NULL)
>               return NULL;
>           break;
>         case REOP_ASSERT_NOT:
>           kidMatch = matchRENodes(state, (RENode *)ren->kid,
>                                             ren->next, cp);
>           if (kidMatch != NULL)
>               return NULL;
>           break;
>         case REOP_BACKREF:
>           num = ren->u.num;
>           if (num >= state->parenCount) {
> 	    JS_ReportErrorNumber(state->context, js_GetErrorMessage, NULL,
> 				 JSMSG_BAD_BACKREF);
>             state->ok = JS_FALSE;
>             return NULL;
>           }
>           parsub = &state->parens[num];
>           if ((cp + parsub->length) > cpend)
>               return NULL;
>           else {
>               cp2 = parsub->chars;
>               for (i = 0; i < parsub->length; i++) {
>                   if (!matchChar(state->flags, *cp++, *cp2++))
>                       return NULL;
>               }
>           }
>           break;
>         case REOP_CCLASS:
>           if (cp != cpend) {
>               if (ren->u.ucclass.bitmap == NULL) {
>                   if (!buildBitmap(state, ren)) {
>                       state->ok = JS_FALSE;
>                       return NULL;
>                   }
>               }
>               c = *cp;
>               b = (c >> 3);
>               if (b >= ren->u.ucclass.bmsize) {
>                   cp2 = (jschar*) ren->kid;
>                   if (*cp2 == '^')
>                       cp++;
>                   else
>                       return NULL;
>               }
>               else {
>                   bit = c & 7;
>                   bit = 1 << bit;
>                   if ((ren->u.ucclass.bitmap[b] & bit) != 0)
>                       cp++;
>                   else
>                       return NULL;
>               }
>           }
>           else
>               return NULL;
>           break;
>         case REOP_DOT:
>           if ((cp != cpend) && !IS_LINE_TERMINATOR(*cp))
>               cp++;
>           else
>               return NULL;
>           break;
>         case REOP_DOTSTARMIN:
>           for (cp2 = cp; cp2 <= cpend; cp2++) {
>               const jschar *cp3 = matchRENodes(state, ren->next, stop, cp2);
>               if (cp3 != NULL)
>                   return cp3;
>               if ((cp2 == cpend) || IS_LINE_TERMINATOR(*cp2))
>                   return NULL;
>           }
>           return NULL;
>         case REOP_DOTSTAR:
>           for (cp2 = cp; cp2 < cpend; cp2++)
>               if (IS_LINE_TERMINATOR(*cp2))
>                   break;
>           while (cp2 >= cp) {
>               const jschar *cp3 = matchRENodes(state, ren->next, NULL, cp2);
>               if (cp3 != NULL) {
>                   cp = cp2;
>                   break;
>               }
>               cp2--;
>           }
>           break;
>        case REOP_WBDRY:
>           if (((cp == state->cpbegin) || !JS_ISWORD(cp[-1]))
>                   ^ ((cp >= cpend) || !JS_ISWORD(*cp)))
>                 ; /* leave cp */
>           else
>               return NULL;
>           break;
>        case REOP_WNONBDRY:
>           if (((cp == state->cpbegin) || !JS_ISWORD(cp[-1]))
>                   ^ ((cp < cpend) && JS_ISWORD(*cp)))
>                 ; /* leave cp */
>           else
>               return NULL;
>           break;
>         case REOP_EOLONLY:
>         case REOP_EOL:
>           if (cp == cpend)
>               ; /* leave cp */
>           else {
>               if (state->context->regExpStatics.multiline
>                     || ((state->flags & JSREG_MULTILINE) != 0))
>                   if (IS_LINE_TERMINATOR(*cp))
>                       ;/* leave cp */
>                   else
>                       return NULL;
>               else
>                   return NULL;
>           }
>           break;
>         case REOP_BOL:
>           if (cp != state->cpbegin) {
>               if ((cp < cpend)
>                    && (state->context->regExpStatics.multiline
>                       || ((state->flags & JSREG_MULTILINE) != 0))) {
>                   if (IS_LINE_TERMINATOR(cp[-1])) {
>                       break;
>                   }
>               }
>               return NULL;
>           }
>           /* leave cp */
>           break;
>         case REOP_DIGIT:
>           if ((cp != cpend) && JS_ISDIGIT(*cp))
>               cp++;
>           else
>               return NULL;
>           break;
>         case REOP_NONDIGIT:
>           if ((cp != cpend) && !JS_ISDIGIT(*cp))
>               cp++;
>           else
>               return NULL;
>           break;
>         case REOP_ALNUM:
>           if ((cp != cpend) && JS_ISWORD(*cp))
>               cp++;
>           else
>               return NULL;
>           break;
>         case REOP_NONALNUM:
>           if ((cp != cpend) && !JS_ISWORD(*cp))
>               cp++;
>           else
>               return NULL;
>           break;
>         case REOP_SPACE:
>           if ((cp != cpend) && JS_ISSPACE(*cp))
>               cp++;
>           else
>               return NULL;
>           break;
>         case REOP_NONSPACE:
>           if ((cp != cpend) && !JS_ISSPACE(*cp))
>               cp++;
>           else
>               return NULL;
>           break;
>         case REOP_FLAT1:
>           if ((cp != cpend)
>                     && matchChar(state->flags, ren->u.chr, *cp))
>               cp++;
>           else
>               return NULL;
>           break;
>         case REOP_FLAT:
>           source = (jschar*) ren->kid;
>           length = (const jschar *)ren->u.kid2 - source;
>           if ((cp + length) > cpend)
>               return NULL;
>           else {
>               for (i = 0; i < length; i++) {
>                   if (!matchChar(state->flags, *cp++, *source++))
>                       return NULL;
>               }
>           }
>           break;
>         case REOP_JUMP:
>           break;
>         case REOP_END:
>           break;
>         default :
>           JS_ASSERT(JS_FALSE);
>           break;
>         }
>         ren = ren->next;
>     }
>     return cp;
> }
> 
> static const jschar *
> MatchRegExp(MatchState *state, RENode *ren, const jschar *cp)
> {
>     const jschar *cp2, *cp3;
>     /* have to include the position beyond the last character
>      in order to detect end-of-input/line condition */
>     for (cp2 = cp; cp2 <= state->cpend; cp2++) {
>         state->skipped = cp2 - cp;
>         state->parenCount = 0;
>         cp3 = matchRENodes(state, ren, NULL, cp2);
>         if (!state->ok) return NULL;
>         if (cp3 != NULL)
>             return cp3;
>     }
3354a2174
> 
3357c2177
<                  JSBool test, jsval *rval)
---
> 		 JSBool test, jsval *rval)
3359,3361c2179
<     REGlobalData gData;
<     REMatchState *x, *result;
< 
---
>     MatchState state;
3364c2182,2183
<     JSSubString *morepar;
---
>     void *mark;
>     JSSubString *parsub, *morepar;
3372c2191,2196
<     RECapture *parsub = NULL;
---
>     /*
>      * Initialize a state struct to minimize recursive argument traffic.
>      */
>     state.context = cx;
>     state.anchoring = JS_FALSE;
>     state.flags = (uint8) re->flags;
3379c2203
<     JSSTRING_CHARS_AND_LENGTH(str, cp, length);
---
>     length = JSSTRING_LENGTH(str);
3381,3383c2205,2208
<         start = length;
<     gData.cpbegin = cp;
<     gData.cpend = cp + length;
---
> 	start = length;
>     cp = JSSTRING_CHARS(str);
>     state.cpbegin = cp;
>     state.cpend = cp + length;
3385,3386c2210,2211
<     gData.start = start;
<     gData.skipped = 0;
---
>     state.start = start;
>     state.skipped = 0;
3389,3393c2214,2216
<      * To avoid multiple allocations in InitMatch(), the arena size parameter
<      * should be at least as big as:
<      * INITIAL_BACKTRACK
<      * + (sizeof(REProgState) * INITIAL_STATESTACK)
<      * + (offsetof(REMatchState, parens) + avgParanSize * sizeof(RECapture))
---
>      * Use the temporary arena pool to grab space for parenthetical matches.
>      * After the JS_ARENA_ALLOCATE early return on error, goto out to be sure
>      * to free this memory.
3395,3401c2218,2223
<     JS_INIT_ARENA_POOL(&gData.pool, "RegExpPool", 12288, 4,
<                        &cx->scriptStackQuota);
<     x = InitMatch(cx, &gData, re, length);
< 
<     if (!x) {
<         ok = JS_FALSE;
<         goto out;
---
>     length = 2 * sizeof(JSSubString) * re->parenCount;
>     mark = JS_ARENA_MARK(&cx->tempPool);
>     JS_ARENA_ALLOCATE_CAST(parsub, JSSubString *, &cx->tempPool, length);
>     if (!parsub) {
> 	JS_ReportOutOfMemory(cx);
> 	return JS_FALSE;
3403c2225,2229
<     x->cp = cp;
---
>     memset(parsub, 0, length);
>     state.parenCount = 0;
>     state.maybeParens = parsub;
>     state.parens = parsub + re->parenCount;
>     state.ok = JS_TRUE;
3409,3415c2235,2239
<     result = MatchRegExp(&gData, x);
<     ok = gData.ok;
<     if (!ok)
<         goto out;
<     if (!result) {
<         *rval = JSVAL_NULL;
<         goto out;
---
>     cp = MatchRegExp(&state, re->ren, cp);
>     if (!(ok = state.ok)) goto out;
>     if (!cp) {
> 	*rval = JSVAL_NULL;
> 	goto out;
3417,3418c2241
<     cp = result->cp;
<     i = cp - gData.cpbegin;
---
>     i = PTRDIFF(cp, state.cpbegin, jschar);
3420c2243
<     matchlen = i - (start + gData.skipped);
---
>     matchlen = i - (start + state.skipped);
3425,3429c2248,2252
<         /*
<          * Testing for a match and updating cx->regExpStatics: don't allocate
<          * an array object, do return true.
<          */
<         *rval = JSVAL_TRUE;
---
> 	/*
> 	 * Testing for a match and updating cx->regExpStatics: don't allocate
> 	 * an array object, do return true.
> 	 */
> 	*rval = JSVAL_TRUE;
3434,3445c2257,2268
<         /*
<          * The array returned on match has element 0 bound to the matched
<          * string, elements 1 through state.parenCount bound to the paren
<          * matches, an index property telling the length of the left context,
<          * and an input property referring to the input string.
<          */
<         obj = js_NewArrayObject(cx, 0, NULL);
<         if (!obj) {
<             ok = JS_FALSE;
<             goto out;
<         }
<         *rval = OBJECT_TO_JSVAL(obj);
---
> 	/*
> 	 * The array returned on match has element 0 bound to the matched
> 	 * string, elements 1 through state.parenCount bound to the paren
> 	 * matches, an index property telling the length of the left context,
> 	 * and an input property referring to the input string.
> 	 */
> 	obj = js_NewArrayObject(cx, 0, NULL);
> 	if (!obj) {
> 	    ok = JS_FALSE;
> 	    goto out;
> 	}
> 	*rval = OBJECT_TO_JSVAL(obj);
3449,3450c2272,2273
<                            JS_PropertyStub, JS_PropertyStub,                  \
<                            JSPROP_ENUMERATE, NULL);                           \
---
> 			   JS_PropertyStub, JS_PropertyStub,                  \
> 			   JSPROP_ENUMERATE, NULL);                           \
3452,3454c2275,2277
<         cx->weakRoots.newborn[GCX_OBJECT] = NULL;                             \
<         cx->weakRoots.newborn[GCX_STRING] = NULL;                             \
<         goto out;                                                             \
---
> 	cx->newborn[GCX_OBJECT] = NULL;                                       \
> 	cx->newborn[GCX_STRING] = NULL;                                       \
> 	goto out;                                                             \
3458,3464c2281,2287
<         matchstr = js_NewStringCopyN(cx, cp, matchlen);
<         if (!matchstr) {
<             cx->weakRoots.newborn[GCX_OBJECT] = NULL;
<             ok = JS_FALSE;
<             goto out;
<         }
<         DEFVAL(STRING_TO_JSVAL(matchstr), INT_TO_JSID(0));
---
> 	matchstr = js_NewStringCopyN(cx, cp, matchlen, 0);
> 	if (!matchstr) {
> 	    cx->newborn[GCX_OBJECT] = NULL;
> 	    ok = JS_FALSE;
> 	    goto out;
> 	}
> 	DEFVAL(STRING_TO_JSVAL(matchstr), INT_TO_JSVAL(0));
3469,3471c2292,2295
<     res->parenCount = re->parenCount;
<     if (re->parenCount == 0) {
<         res->lastParen = js_EmptySubString;
---
>     JS_ASSERT(state.parenCount <= re->parenCount);
>     if (state.parenCount == 0) {
> 	res->parenCount = 0;
> 	res->lastParen = js_EmptySubString;
3473,3541c2297,2343
<         for (num = 0; num < re->parenCount; num++) {
<             parsub = &result->parens[num];
<             if (num < 9) {
<                 if (parsub->index == -1) {
<                     res->parens[num].chars = NULL;
<                     res->parens[num].length = 0;
<                 } else {
<                     res->parens[num].chars = gData.cpbegin + parsub->index;
<                     res->parens[num].length = parsub->length;
<                 }
<             } else {
<                 morenum = num - 9;
<                 morepar = res->moreParens;
<                 if (!morepar) {
<                     res->moreLength = 10;
<                     morepar = (JSSubString*)
<                         JS_malloc(cx, 10 * sizeof(JSSubString));
<                 } else if (morenum >= res->moreLength) {
<                     res->moreLength += 10;
<                     morepar = (JSSubString*)
<                         JS_realloc(cx, morepar,
<                                    res->moreLength * sizeof(JSSubString));
<                 }
<                 if (!morepar) {
<                     cx->weakRoots.newborn[GCX_OBJECT] = NULL;
<                     cx->weakRoots.newborn[GCX_STRING] = NULL;
<                     ok = JS_FALSE;
<                     goto out;
<                 }
<                 res->moreParens = morepar;
<                 if (parsub->index == -1) {
<                     morepar[morenum].chars = NULL;
<                     morepar[morenum].length = 0;
<                 } else {
<                     morepar[morenum].chars = gData.cpbegin + parsub->index;
<                     morepar[morenum].length = parsub->length;
<                 }
<             }
<             if (test)
<                 continue;
<             if (parsub->index == -1) {
<                 ok = js_DefineProperty(cx, obj, INT_TO_JSID(num + 1),
<                                        JSVAL_VOID, NULL, NULL,
<                                        JSPROP_ENUMERATE, NULL);
<             } else {
<                 parstr = js_NewStringCopyN(cx, gData.cpbegin + parsub->index,
<                                            parsub->length);
<                 if (!parstr) {
<                     cx->weakRoots.newborn[GCX_OBJECT] = NULL;
<                     cx->weakRoots.newborn[GCX_STRING] = NULL;
<                     ok = JS_FALSE;
<                     goto out;
<                 }
<                 ok = js_DefineProperty(cx, obj, INT_TO_JSID(num + 1),
<                                        STRING_TO_JSVAL(parstr), NULL, NULL,
<                                        JSPROP_ENUMERATE, NULL);
<             }
<             if (!ok) {
<                 cx->weakRoots.newborn[GCX_OBJECT] = NULL;
<                 cx->weakRoots.newborn[GCX_STRING] = NULL;
<                 goto out;
<             }
<         }
<         if (parsub->index == -1) {
<             res->lastParen = js_EmptySubString;
<         } else {
<             res->lastParen.chars = gData.cpbegin + parsub->index;
<             res->lastParen.length = parsub->length;
<         }
---
> 	for (num = 0; num < state.parenCount; num++) {
> 	    parsub = &state.parens[num];
> 	    if (num < 9) {
> 		res->parens[num] = *parsub;
> 	    } else {
> 		morenum = num - 9;
> 		morepar = res->moreParens;
> 		if (!morepar) {
> 		    res->moreLength = 10;
> 		    XMEMTAG("jsregexp JSSubString");
> 		    morepar = (JSSubString*) JS_malloc(cx,
>                                                        10 * sizeof(JSSubString));
> 		} else if (morenum >= res->moreLength) {
> 		    res->moreLength += 10;
> 		    XMEMTAG("jsregexp realloc");
> 		    morepar = (JSSubString*) JS_realloc(cx, morepar,
> 					 res->moreLength * sizeof(JSSubString));
> 		}
> 		if (!morepar) {
> 		    cx->newborn[GCX_OBJECT] = NULL;
> 		    cx->newborn[GCX_STRING] = NULL;
> 		    ok = JS_FALSE;
> 		    goto out;
> 		}
> 		res->moreParens = morepar;
> 		morepar[morenum] = *parsub;
> 	    }
> 	    if (test)
> 		continue;
> 	    parstr = js_NewStringCopyN(cx, parsub->chars, parsub->length, 0);
> 	    if (!parstr) {
> 		cx->newborn[GCX_OBJECT] = NULL;
> 		cx->newborn[GCX_STRING] = NULL;
> 		ok = JS_FALSE;
> 		goto out;
> 	    }
> 	    ok = js_DefineProperty(cx, obj, INT_TO_JSVAL(num + 1),
> 				   STRING_TO_JSVAL(parstr), NULL, NULL,
> 				   JSPROP_ENUMERATE, NULL);
> 	    if (!ok) {
> 		cx->newborn[GCX_OBJECT] = NULL;
> 		cx->newborn[GCX_STRING] = NULL;
> 		goto out;
> 	    }
> 	}
> 	res->parenCount = num;
> 	res->lastParen = *parsub;
3545,3552c2347,2354
<         /*
<          * Define the index and input properties last for better for/in loop
<          * order (so they come after the elements).
<          */
<         DEFVAL(INT_TO_JSVAL(start + gData.skipped),
<                ATOM_TO_JSID(cx->runtime->atomState.indexAtom));
<         DEFVAL(STRING_TO_JSVAL(str),
<                ATOM_TO_JSID(cx->runtime->atomState.inputAtom));
---
> 	/*
> 	 * Define the index and input properties last for better for/in loop
> 	 * order (so they come after the elements).
> 	 */
> 	DEFVAL(INT_TO_JSVAL(start + state.skipped),
> 	       (jsid)cx->runtime->atomState.indexAtom);
> 	DEFVAL(STRING_TO_JSVAL(str),
> 	       (jsid)cx->runtime->atomState.inputAtom);
3559,3566c2361,2382
< 
<     /*
<      * For JS1.3 and ECMAv2, emulate Perl5 exactly:
<      *
<      * js1.3        "hi", "hi there"            "hihitherehi therebye"
<      */
<     res->leftContext.chars = JSSTRING_CHARS(str);
<     res->leftContext.length = start + gData.skipped;
---
>     if (cx->version == JSVERSION_1_2) {
> 	/*
> 	 * JS1.2 emulated Perl4.0.1.8 (patch level 36) for global regexps used
> 	 * in scalar contexts, and unintentionally for the string.match "list"
> 	 * psuedo-context.  On "hi there bye", the following would result:
> 	 *
> 	 * Language     while(/ /g){print("$`");}   s/ /$`/g
> 	 * perl4.036    "hi", "there"               "hihitherehi therebye"
> 	 * perl5        "hi", "hi there"            "hihitherehi therebye"
> 	 * js1.2        "hi", "there"               "hihitheretherebye"
> 	 */
> 	res->leftContext.chars = JSSTRING_CHARS(str) + start;
> 	res->leftContext.length = state.skipped;
>     } else {
> 	/*
> 	 * For JS1.3 and ECMAv2, emulate Perl5 exactly:
> 	 *
> 	 * js1.3        "hi", "hi there"            "hihitherehi therebye"
> 	 */
> 	res->leftContext.chars = JSSTRING_CHARS(str);
> 	res->leftContext.length = start + state.skipped;
>     }
3568c2384
<     res->rightContext.length = gData.cpend - ep;
---
>     res->rightContext.length = state.cpend - ep;
3571c2387
<     JS_FinishArenaPool(&gData.pool);
---
>     JS_ARENA_RELEASE(&cx->tempPool, mark);
3582,3583c2398
<     REGEXP_MULTILINE    = -5,
<     REGEXP_STICKY       = -6
---
>     REGEXP_MULTILINE    = -5
3586,3587c2401
< #define REGEXP_PROP_ATTRS     (JSPROP_PERMANENT | JSPROP_SHARED)
< #define RO_REGEXP_PROP_ATTRS  (REGEXP_PROP_ATTRS | JSPROP_READONLY)
---
> #define REGEXP_PROP_ATTRS (JSPROP_PERMANENT | JSPROP_SHARED)
3590,3592c2404,2406
<     {"source",     REGEXP_SOURCE,      RO_REGEXP_PROP_ATTRS,0,0},
<     {"global",     REGEXP_GLOBAL,      RO_REGEXP_PROP_ATTRS,0,0},
<     {"ignoreCase", REGEXP_IGNORE_CASE, RO_REGEXP_PROP_ATTRS,0,0},
---
>     {"source",     REGEXP_SOURCE,      REGEXP_PROP_ATTRS | JSPROP_READONLY,0,0},
>     {"global",     REGEXP_GLOBAL,      REGEXP_PROP_ATTRS | JSPROP_READONLY,0,0},
>     {"ignoreCase", REGEXP_IGNORE_CASE, REGEXP_PROP_ATTRS | JSPROP_READONLY,0,0},
3594,3595c2408
<     {"multiline",  REGEXP_MULTILINE,   RO_REGEXP_PROP_ATTRS,0,0},
<     {"sticky",     REGEXP_STICKY,      RO_REGEXP_PROP_ATTRS,0,0},
---
>     {"multiline",  REGEXP_MULTILINE,   REGEXP_PROP_ATTRS | JSPROP_READONLY,0,0},
3606c2419
<         return JS_TRUE;
---
> 	return JS_TRUE;
3614,3630c2427,2440
<         switch (slot) {
<           case REGEXP_SOURCE:
<             *vp = STRING_TO_JSVAL(re->source);
<             break;
<           case REGEXP_GLOBAL:
<             *vp = BOOLEAN_TO_JSVAL((re->flags & JSREG_GLOB) != 0);
<             break;
<           case REGEXP_IGNORE_CASE:
<             *vp = BOOLEAN_TO_JSVAL((re->flags & JSREG_FOLD) != 0);
<             break;
<           case REGEXP_MULTILINE:
<             *vp = BOOLEAN_TO_JSVAL((re->flags & JSREG_MULTILINE) != 0);
<             break;
<           case REGEXP_STICKY:
<             *vp = BOOLEAN_TO_JSVAL((re->flags & JSREG_STICKY) != 0);
<             break;
<         }
---
> 	switch (slot) {
> 	  case REGEXP_SOURCE:
> 	    *vp = STRING_TO_JSVAL(re->source);
> 	    break;
> 	  case REGEXP_GLOBAL:
> 	    *vp = BOOLEAN_TO_JSVAL((re->flags & JSREG_GLOB) != 0);
> 	    break;
> 	  case REGEXP_IGNORE_CASE:
> 	    *vp = BOOLEAN_TO_JSVAL((re->flags & JSREG_FOLD) != 0);
> 	    break;
> 	  case REGEXP_MULTILINE:
> 	    *vp = BOOLEAN_TO_JSVAL((re->flags & JSREG_MULTILINE) != 0);
> 	    break;
> 	}
3645c2455
<         return ok;
---
> 	return ok;
3687,3688c2497,2498
<         JS_free(cx, res->moreParens);
<         res->moreParens = NULL;
---
> 	JS_free(cx, res->moreParens);
> 	res->moreParens = NULL;
3703c2513
<         return JS_TRUE;
---
> 	return JS_TRUE;
3707,3709c2517,2519
<         *vp = res->input ? STRING_TO_JSVAL(res->input)
<                          : JS_GetEmptyStringValue(cx);
<         return JS_TRUE;
---
> 	*vp = res->input ? STRING_TO_JSVAL(res->input)
> 			 : JS_GetEmptyStringValue(cx);
> 	return JS_TRUE;
3711,3712c2521,2522
<         *vp = BOOLEAN_TO_JSVAL(res->multiline);
<         return JS_TRUE;
---
> 	*vp = BOOLEAN_TO_JSVAL(res->multiline);
> 	return JS_TRUE;
3714,3715c2524,2525
<         sub = &res->lastMatch;
<         break;
---
> 	sub = &res->lastMatch;
> 	break;
3717,3718c2527,2528
<         sub = &res->lastParen;
<         break;
---
> 	sub = &res->lastParen;
> 	break;
3720,3721c2530,2531
<         sub = &res->leftContext;
<         break;
---
> 	sub = &res->leftContext;
> 	break;
3723,3724c2533,2534
<         sub = &res->rightContext;
<         break;
---
> 	sub = &res->rightContext;
> 	break;
3726,3727c2536,2537
<         sub = REGEXP_PAREN_SUBSTRING(res, slot);
<         break;
---
> 	sub = REGEXP_PAREN_SUBSTRING(res, slot);
> 	break;
3729c2539
<     str = js_NewStringCopyN(cx, sub->chars, sub->length);
---
>     str = js_NewStringCopyN(cx, sub->chars, sub->length, 0);
3731c2541
<         return JS_FALSE;
---
> 	return JS_FALSE;
3742c2552
<         return JS_TRUE;
---
> 	return JS_TRUE;
3746,3750c2556,2560
<         if (!JSVAL_IS_STRING(*vp) &&
<             !JS_ConvertValue(cx, *vp, JSTYPE_STRING, vp)) {
<             return JS_FALSE;
<         }
<         res->input = JSVAL_TO_STRING(*vp);
---
> 	if (!JSVAL_IS_STRING(*vp) &&
> 	    !JS_ConvertValue(cx, *vp, JSTYPE_STRING, vp)) {
> 	    return JS_FALSE;
> 	}
> 	res->input = JSVAL_TO_STRING(*vp);
3752,3756c2562,2566
<         if (!JSVAL_IS_BOOLEAN(*vp) &&
<             !JS_ConvertValue(cx, *vp, JSTYPE_BOOLEAN, vp)) {
<             return JS_FALSE;
<         }
<         res->multiline = JSVAL_TO_BOOLEAN(*vp);
---
> 	if (!JSVAL_IS_BOOLEAN(*vp) &&
> 	    !JS_ConvertValue(cx, *vp, JSTYPE_BOOLEAN, vp)) {
> 	    return JS_FALSE;
> 	}
> 	res->multiline = JSVAL_TO_BOOLEAN(*vp);
3760,3761d2569
< #define REGEXP_STATIC_PROP_ATTRS    (REGEXP_PROP_ATTRS | JSPROP_ENUMERATE)
< #define RO_REGEXP_STATIC_PROP_ATTRS (REGEXP_STATIC_PROP_ATTRS | JSPROP_READONLY)
3766c2574
<      REGEXP_STATIC_PROP_ATTRS,
---
>      JSPROP_ENUMERATE|JSPROP_SHARED,
3770c2578
<      REGEXP_STATIC_PROP_ATTRS,
---
>      JSPROP_ENUMERATE|JSPROP_SHARED,
3774c2582
<      RO_REGEXP_STATIC_PROP_ATTRS,
---
>      JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
3778c2586
<      RO_REGEXP_STATIC_PROP_ATTRS,
---
>      JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
3782c2590
<      RO_REGEXP_STATIC_PROP_ATTRS,
---
>      JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
3786c2594
<      RO_REGEXP_STATIC_PROP_ATTRS,
---
>      JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
3790c2598
<     {"$1", 0, RO_REGEXP_STATIC_PROP_ATTRS,
---
>     {"$1", 0, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
3792c2600
<     {"$2", 1, RO_REGEXP_STATIC_PROP_ATTRS,
---
>     {"$2", 1, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
3794c2602
<     {"$3", 2, RO_REGEXP_STATIC_PROP_ATTRS,
---
>     {"$3", 2, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
3796c2604
<     {"$4", 3, RO_REGEXP_STATIC_PROP_ATTRS,
---
>     {"$4", 3, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
3798c2606
<     {"$5", 4, RO_REGEXP_STATIC_PROP_ATTRS,
---
>     {"$5", 4, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
3800c2608
<     {"$6", 5, RO_REGEXP_STATIC_PROP_ATTRS,
---
>     {"$6", 5, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
3802c2610
<     {"$7", 6, RO_REGEXP_STATIC_PROP_ATTRS,
---
>     {"$7", 6, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
3804c2612
<     {"$8", 7, RO_REGEXP_STATIC_PROP_ATTRS,
---
>     {"$8", 7, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
3806c2614
<     {"$9", 8, RO_REGEXP_STATIC_PROP_ATTRS,
---
>     {"$9", 8, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
3819c2627
<         return;
---
> 	return;
3825,3826c2633,2634
< regexp_exec_sub(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
<                 JSBool test, jsval *rval);
---
> regexp_exec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
> 	    jsval *rval);
3831,3832c2639
<     return regexp_exec_sub(cx, JSVAL_TO_OBJECT(argv[-2]), argc, argv,
<                            JS_FALSE, rval);
---
>     return regexp_exec(cx, JSVAL_TO_OBJECT(argv[-2]), argc, argv, rval);
3844,3845c2651
<     uint32 flagsword;
<     JSObject *obj;
---
>     uint8 flags;
3848,3852c2654,2658
<         re = (JSRegExp *) JS_GetPrivate(xdr->cx, *objp);
<         if (!re)
<             return JS_FALSE;
<         source = re->source;
<         flagsword = (uint32)re->flags;
---
> 	re = (JSRegExp *) JS_GetPrivate(xdr->cx, *objp);
> 	if (!re)
> 	    return JS_FALSE;
> 	source = re->source;
> 	flags = (uint8) re->flags;
3855,3856c2661,2662
<         !JS_XDRUint32(xdr, &flagsword)) {
<         return JS_FALSE;
---
> 	!JS_XDRUint8(xdr, &flags)) {
> 	return JS_FALSE;
3859,3872c2665,2675
<         obj = js_NewObject(xdr->cx, &js_RegExpClass, NULL, NULL);
<         if (!obj)
<             return JS_FALSE;
<         STOBJ_SET_PARENT(obj, NULL);
<         STOBJ_SET_PROTO(obj, NULL);
<         re = js_NewRegExp(xdr->cx, NULL, source, (uint8)flagsword, JS_FALSE);
<         if (!re)
<             return JS_FALSE;
<         if (!JS_SetPrivate(xdr->cx, obj, re) ||
<             !js_SetLastIndex(xdr->cx, obj, 0)) {
<             js_DestroyRegExp(xdr->cx, re);
<             return JS_FALSE;
<         }
<         *objp = obj;
---
> 	*objp = js_NewObject(xdr->cx, &js_RegExpClass, NULL, NULL);
> 	if (!*objp)
> 	    return JS_FALSE;
> 	re = js_NewRegExp(xdr->cx, NULL, source, flags, JS_FALSE);
> 	if (!re)
> 	    return JS_FALSE;
> 	if (!JS_SetPrivate(xdr->cx, *objp, re) ||
>             !js_SetLastIndex(xdr->cx, *objp, 0)) {
> 	    js_DestroyRegExp(xdr->cx, re);
> 	    return JS_FALSE;
> 	}
3883,3884c2686,2687
< static void
< regexp_trace(JSTracer *trc, JSObject *obj)
---
> static uint32
> regexp_mark(JSContext *cx, JSObject *obj, void *arg)
3886,3890c2689,2692
<     JSRegExp *re;
< 
<     re = (JSRegExp *) JS_GetPrivate(trc->context, obj);
<     if (re && re->source)
<         JS_CALL_STRING_TRACER(trc, re->source, "source");
---
>     JSRegExp *re = (JSRegExp *) JS_GetPrivate(cx, obj);
>     if (re)
>         JS_MarkGCThing(cx, re->source, "source", arg);
>     return 0;
3895,3904c2697,2701
<     JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(1) |
<     JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_RegExp),
<     JS_PropertyStub,    JS_PropertyStub,
<     regexp_getProperty, regexp_setProperty,
<     JS_EnumerateStub,   JS_ResolveStub,
<     JS_ConvertStub,     regexp_finalize,
<     NULL,               NULL,
<     regexp_call,        NULL,
<     regexp_xdrObject,   NULL,
<     JS_CLASS_TRACE(regexp_trace), 0
---
>     JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(1),
>     JS_PropertyStub,  JS_PropertyStub,  regexp_getProperty, regexp_setProperty,
>     JS_EnumerateStub, JS_ResolveStub,   JS_ConvertStub,     regexp_finalize,
>     NULL,             NULL,             regexp_call,        NULL,
>     regexp_xdrObject, NULL,             regexp_mark,        0
3907,3910c2704,2706
< static const jschar empty_regexp_ucstr[] = {'(', '?', ':', ')', 0};
< 
< JSBool
< js_regexp_toString(JSContext *cx, JSObject *obj, jsval *vp)
---
> static JSBool
> regexp_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
> 		jsval *rval)
3913d2708
<     const jschar *source;
3919,3920c2714,2715
<     if (!JS_InstanceOf(cx, obj, &js_RegExpClass, vp + 2))
<         return JS_FALSE;
---
>     if (!JS_InstanceOf(cx, obj, &js_RegExpClass, argv))
> 	return JS_FALSE;
3925,3926c2720,2721
<         *vp = STRING_TO_JSVAL(cx->runtime->emptyString);
<         return JS_TRUE;
---
> 	*rval = STRING_TO_JSVAL(cx->runtime->emptyString);
> 	return JS_TRUE;
3929,3934c2724
<     JSSTRING_CHARS_AND_LENGTH(re->source, source, length);
<     if (length == 0) {
<         source = empty_regexp_ucstr;
<         length = JS_ARRAY_LENGTH(empty_regexp_ucstr) - 1;
<     }
<     length += 2;
---
>     length = JSSTRING_LENGTH(re->source) + 2;
3937c2727,2728
<         nflags++;
---
> 	nflags++;
> 	XMEMTAG("jsregexp regexp_toString");
3945c2736
<     js_strncpy(&chars[1], source, length - 2);
---
>     js_strncpy(&chars[1], JSSTRING_CHARS(re->source), length - 2);
3948,3955c2739,2744
<         if (re->flags & JSREG_GLOB)
<             chars[length++] = 'g';
<         if (re->flags & JSREG_FOLD)
<             chars[length++] = 'i';
<         if (re->flags & JSREG_MULTILINE)
<             chars[length++] = 'm';
<         if (re->flags & JSREG_STICKY)
<             chars[length++] = 'y';
---
> 	if (re->flags & JSREG_GLOB)
> 	    chars[length++] = 'g';
> 	if (re->flags & JSREG_FOLD)
> 	    chars[length++] = 'i';
> 	if (re->flags & JSREG_MULTILINE)
> 	    chars[length++] = 'm';
3960c2749
<     str = js_NewString(cx, chars, length);
---
>     str = js_NewString(cx, chars, length, 0);
3962,3963c2751,2752
<         JS_free(cx, chars);
<         return JS_FALSE;
---
> 	JS_free(cx, chars);
> 	return JS_FALSE;
3965c2754
<     *vp = STRING_TO_JSVAL(str);
---
>     *rval = STRING_TO_JSVAL(str);
3970,3977c2759,2760
< regexp_toString(JSContext *cx, uintN argc, jsval *vp)
< {
<     return js_regexp_toString(cx, JS_THIS_OBJECT(cx, vp), vp);
< }
< 
< static JSBool
< regexp_compile_sub(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
<                    jsval *rval)
---
> regexp_compile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
> 	       jsval *rval)
3981c2764
<     JSBool ok, ok2;
---
>     JSBool ok;
3983,3985d2765
<     size_t length, nbytes;
<     const jschar *cp, *start, *end;
<     jschar *nstart, *ncp, *tmp;
3988c2768
<         return JS_FALSE;
---
> 	return JS_FALSE;
3991c2771
<         str = cx->runtime->emptyString;
---
> 	str = cx->runtime->emptyString;
4004c2784
<                     JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
---
>                     JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, 
4016c2796
<                 goto created;
---
>                 goto madeit;
4020,4022c2800,2802
<         if (!str)
<             return JS_FALSE;
<         argv[0] = STRING_TO_JSVAL(str);
---
> 	if (!str)
> 	    return JS_FALSE;
> 	argv[0] = STRING_TO_JSVAL(str);
4033,4072d2812
< 
<         /* Escape any naked slashes in the regexp source. */
<         JSSTRING_CHARS_AND_LENGTH(str, start, length);
<         end = start + length;
<         nstart = ncp = NULL;
<         for (cp = start; cp < end; cp++) {
<             if (*cp == '/' && (cp == start || cp[-1] != '\\')) {
<                 nbytes = (++length + 1) * sizeof(jschar);
<                 if (!nstart) {
<                     nstart = (jschar *) JS_malloc(cx, nbytes);
<                     if (!nstart)
<                         return JS_FALSE;
<                     ncp = nstart + (cp - start);
<                     js_strncpy(nstart, start, cp - start);
<                 } else {
<                     tmp = (jschar *) JS_realloc(cx, nstart, nbytes);
<                     if (!tmp) {
<                         JS_free(cx, nstart);
<                         return JS_FALSE;
<                     }
<                     ncp = tmp + (ncp - nstart);
<                     nstart = tmp;
<                 }
<                 *ncp++ = '\\';
<             }
<             if (nstart)
<                 *ncp++ = *cp;
<         }
< 
<         if (nstart) {
<             /* Don't forget to store the backstop after the new string. */
<             JS_ASSERT((size_t)(ncp - nstart) == length);
<             *ncp = 0;
<             str = js_NewString(cx, nstart, length);
<             if (!str) {
<                 JS_free(cx, nstart);
<                 return JS_FALSE;
<             }
<             argv[0] = STRING_TO_JSVAL(str);
<         }
4074,4076c2814,2815
< 
<     re = js_NewRegExpOpt(cx, str, opt, JS_FALSE);
< created:
---
>     re = js_NewRegExpOpt(cx, NULL, str, opt, JS_FALSE);
> madeit:
4078c2817
<         return JS_FALSE;
---
> 	return JS_FALSE;
4081,4082c2820
<     ok = JS_SetPrivate(cx, obj, re);
<     ok2 = js_SetLastIndex(cx, obj, 0);
---
>     ok = JS_SetPrivate(cx, obj, re) && js_SetLastIndex(cx, obj, 0);
4085,4086c2823,2827
<         js_DestroyRegExp(cx, re);
<         return JS_FALSE;
---
> 	js_DestroyRegExp(cx, re);
>     } else {
>         if (oldre)
>             js_DestroyRegExp(cx, oldre);
>         *rval = OBJECT_TO_JSVAL(obj);
4088,4097c2829
<     if (oldre)
<         js_DestroyRegExp(cx, oldre);
<     *rval = OBJECT_TO_JSVAL(obj);
<     return ok2;
< }
< 
< static JSBool
< regexp_compile(JSContext *cx, uintN argc, jsval *vp)
< {
<     return regexp_compile_sub(cx, JS_THIS_OBJECT(cx, vp), argc, vp + 2, vp);
---
>     return ok;
4102c2834
<                 JSBool test, jsval *rval)
---
> 		JSBool test, jsval *rval)
4104c2836
<     JSBool ok, sticky;
---
>     JSBool ok;
4112c2844
<         return JS_FALSE;
---
> 	return JS_FALSE;
4116,4117c2848,2849
<         JS_UNLOCK_OBJ(cx, obj);
<         return JS_TRUE;
---
> 	JS_UNLOCK_OBJ(cx, obj);
> 	return JS_TRUE;
4122,4123c2854
<     sticky = (re->flags & JSREG_STICKY) != 0;
<     if (re->flags & (JSREG_GLOB | JSREG_STICKY)) {
---
>     if (re->flags & JSREG_GLOB) {
4134,4146c2865,2872
<         str = cx->regExpStatics.input;
<         if (!str) {
<             const char *bytes = js_GetStringBytes(cx, re->source);
< 
<             if (bytes) {
<                 JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
<                                      JSMSG_NO_INPUT,
<                                      bytes,
<                                      (re->flags & JSREG_GLOB) ? "g" : "",
<                                      (re->flags & JSREG_FOLD) ? "i" : "",
<                                      (re->flags & JSREG_MULTILINE) ? "m" : "",
<                                      (re->flags & JSREG_STICKY) ? "y" : "");
<             }
---
> 	str = cx->regExpStatics.input;
> 	if (!str) {
> 	    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
> 				 JSMSG_NO_INPUT,
> 				 JS_GetStringBytes(re->source),
> 				 (re->flags & JSREG_GLOB) ? "g" : "",
> 				 (re->flags & JSREG_FOLD) ? "i" : "",
> 				 (re->flags & JSREG_MULTILINE) ? "m" : "");
4149c2875
<         }
---
> 	}
4151,4156c2877,2880
<         str = js_ValueToString(cx, argv[0]);
<         if (!str) {
<             ok = JS_FALSE;
<             goto out;
<         }
<         argv[0] = STRING_TO_JSVAL(str);
---
> 	str = js_ValueToString(cx, argv[0]);
> 	if (!str)
> 	    goto out;
> 	argv[0] = STRING_TO_JSVAL(str);
4165,4166c2889
<         if (ok &&
<             ((re->flags & JSREG_GLOB) || (*rval != JSVAL_NULL && sticky))) {
---
>         if (ok && (re->flags & JSREG_GLOB))
4168d2890
<         }
4177c2899
< regexp_exec(JSContext *cx, uintN argc, jsval *vp)
---
> regexp_exec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
4179,4180c2901
<     return regexp_exec_sub(cx, JS_THIS_OBJECT(cx, vp), argc, vp + 2, JS_FALSE,
<                            vp);
---
>     return regexp_exec_sub(cx, obj, argc, argv, JS_FALSE, rval);
4184c2905
< regexp_test(JSContext *cx, uintN argc, jsval *vp)
---
> regexp_test(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
4186,4189c2907,2910
<     if (!regexp_exec_sub(cx, JS_THIS_OBJECT(cx, vp), argc, vp + 2, JS_TRUE, vp))
<         return JS_FALSE;
<     if (*vp != JSVAL_TRUE)
<         *vp = JSVAL_FALSE;
---
>     if (!regexp_exec_sub(cx, obj, argc, argv, JS_TRUE, rval))
> 	return JS_FALSE;
>     if (*rval != JSVAL_TRUE)
> 	*rval = JSVAL_FALSE;
4195c2916
<     JS_FN(js_toSource_str,  regexp_toString,    0,0,0),
---
>     {js_toSource_str,   regexp_toString,        0,0,0},
4197,4201c2918,2922
<     JS_FN(js_toString_str,  regexp_toString,    0,0,0),
<     JS_FN("compile",        regexp_compile,     0,2,0),
<     JS_FN("exec",           regexp_exec,        0,1,0),
<     JS_FN("test",           regexp_test,        0,1,0),
<     JS_FS_END
---
>     {js_toString_str,   regexp_toString,        0,0,0},
>     {"compile",         regexp_compile,         1,0,0},
>     {"exec",            regexp_exec,            0,0,0},
>     {"test",            regexp_test,            0,0,0},
>     {0,0,0,0,0}
4210c2931
<          * (regexp_compile_sub detects the regexp + flags case and throws a
---
>          * (regexp_compile detects the regexp + flags case and throws a
4213,4214c2934
<         if ((argc < 2 || JSVAL_IS_VOID(argv[1])) &&
<             !JSVAL_IS_PRIMITIVE(argv[0]) &&
---
>         if ((argc < 2 || JSVAL_IS_VOID(argv[1])) && JSVAL_IS_OBJECT(argv[0]) &&
4221,4229c2941,2943
<         obj = js_NewObject(cx, &js_RegExpClass, NULL, NULL);
<         if (!obj)
<             return JS_FALSE;
< 
<         /*
<          * regexp_compile_sub does not use rval to root its temporaries so we
<          * can use it to root obj.
<          */
<         *rval = OBJECT_TO_JSVAL(obj);
---
> 	obj = js_NewObject(cx, &js_RegExpClass, NULL, NULL);
> 	if (!obj)
> 	    return JS_FALSE;
4231c2945
<     return regexp_compile_sub(cx, obj, argc, argv, rval);
---
>     return regexp_compile(cx, obj, argc, argv, rval);
4241,4242c2955,2956
<                          regexp_props, regexp_methods,
<                          regexp_static_props, NULL);
---
> 			 regexp_props, regexp_methods,
> 			 regexp_static_props, NULL);
4245c2959
<         return NULL;
---
> 	return NULL;
4247,4252c2961,2966
<         !JS_AliasProperty(cx, ctor, "multiline",    "$*") ||
<         !JS_AliasProperty(cx, ctor, "lastMatch",    "$&") ||
<         !JS_AliasProperty(cx, ctor, "lastParen",    "$+") ||
<         !JS_AliasProperty(cx, ctor, "leftContext",  "$`") ||
<         !JS_AliasProperty(cx, ctor, "rightContext", "$'")) {
<         goto bad;
---
> 	!JS_AliasProperty(cx, ctor, "multiline",    "$*") ||
> 	!JS_AliasProperty(cx, ctor, "lastMatch",    "$&") ||
> 	!JS_AliasProperty(cx, ctor, "lastParen",    "$+") ||
> 	!JS_AliasProperty(cx, ctor, "leftContext",  "$`") ||
> 	!JS_AliasProperty(cx, ctor, "rightContext", "$'")) {
> 	goto bad;
4256c2970
<     if (!regexp_compile_sub(cx, proto, 0, NULL, &rval))
---
>     if (!regexp_compile(cx, proto, 0, NULL, &rval))
4272d2985
<     JSTempValueRooter tvr;
4274c2987
<     str = js_NewStringCopyN(cx, chars, length);
---
>     str = js_NewStringCopyN(cx, chars, length, 0);
4276c2989
<         return NULL;
---
> 	return NULL;
4279,4280c2992
<         return NULL;
<     JS_PUSH_TEMP_ROOT_STRING(cx, str, &tvr);
---
> 	return NULL;
4282,4284c2994,2996
<     if (!obj || !JS_SetPrivate(cx, obj, re)) {
<         js_DestroyRegExp(cx, re);
<         obj = NULL;
---
>     if (!obj || !JS_SetPrivate(cx, obj, re) || !js_SetLastIndex(cx, obj, 0)) {
> 	js_DestroyRegExp(cx, re);
> 	return NULL;
4286,4288d2997
<     if (obj && !js_SetLastIndex(cx, obj, 0))
<         obj = NULL;
<     JS_POP_TEMP_ROOT(cx, &tvr);
4302c3011
<     re = (JSRegExp *) JS_GetPrivate(cx, obj);
---
>     re = JS_GetPrivate(cx, obj);
4304c3013
<         cx->weakRoots.newborn[GCX_OBJECT] = NULL;
---
>         cx->newborn[GCX_OBJECT] = NULL;
4328a3038
> #endif /* JS_HAS_REGEXPS */
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsregexp.h /Volumes/Swap/js_D11/src/jsregexp.h
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
49,54d43
< #ifdef JS_THREADSAFE
< #include "jsdhash.h"
< #endif
< 
< JS_BEGIN_EXTERN_C
< 
58,59c47,48
<     uint16      parenCount;     /* number of valid elements in parens[] */
<     uint16      moreLength;     /* number of allocated elements in moreParens */
---
>     uintN       parenCount;     /* number of valid elements in parens[] */
>     uintN       moreLength;     /* number of allocated elements in moreParens */
69,89d57
<  * This struct holds a bitmap representation of a class from a regexp.
<  * There's a list of these referenced by the classList field in the JSRegExp
<  * struct below. The initial state has startIndex set to the offset in the
<  * original regexp source of the beginning of the class contents. The first
<  * use of the class converts the source representation into a bitmap.
<  *
<  */
< typedef struct RECharSet {
<     JSPackedBool    converted;
<     JSPackedBool    sense;
<     uint16          length;
<     union {
<         uint8       *bits;
<         struct {
<             size_t  startIndex;
<             size_t  length;
<         } src;
<     } u;
< } RECharSet;
< 
< /*
104,107c72,74
<     uint16       flags;         /* flags, see jsapi.h's JSREG_* defines */
<     size_t       parenCount;    /* number of parenthesized submatches */
<     size_t       classCount;    /* count [...] bitmaps */
<     RECharSet    *classList;    /* list of [...] bitmaps */
---
>     uint32       parenCount:24, /* number of parenthesized submatches */
>                  flags:8;       /* flags, see jsapi.h's JSREG_* defines */
>     RENode       *ren;          /* regular expression tree root */
109d75
<     jsbytecode   program[1];    /* regular expression bytecode */
117,120c83,84
< js_NewRegExpOpt(JSContext *cx, JSString *str, JSString *opt, JSBool flat);
< 
< #define HOLD_REGEXP(cx, re) JS_ATOMIC_INCREMENT(&(re)->nrefs)
< #define DROP_REGEXP(cx, re) js_DestroyRegExp(cx, re)
---
> js_NewRegExpOpt(JSContext *cx, JSTokenStream *ts,
>                 JSString *str, JSString *opt, JSBool flat);
132c96
<                  JSBool test, jsval *rval);
---
> 		 JSBool test, jsval *rval);
154,160c118
<  * Export js_regexp_toString to the decompiler.
<  */
< extern JSBool
< js_regexp_toString(JSContext *cx, JSObject *obj, jsval *vp);
< 
< /*
<  * Create, serialize/deserialize, or clone a RegExp object.
---
>  * Create a new RegExp object.
166,168d123
< extern JSBool
< js_XDRRegExp(JSXDRState *xdr, JSObject **objp);
< 
172,174d126
< /*
<  * Get and set the per-object (clone or clone-parent) lastIndex slot.
<  */
181,182d132
< JS_END_EXTERN_C
< 
Only in /Volumes/Swap/js-14-2-2008/js/src: jsreops.tbl
Only in /Volumes/Swap/js-14-2-2008/js/src: jsscan.c
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsscan.h /Volumes/Swap/js_D11/src/jsscan.h
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
47d41
< #include "jsconfig.h"
54,58d47
< #define JS_KEYWORD(keyword, type, op, version) \
<     extern const char js_##keyword##_str[];
< #include "jskeyword.tbl"
< #undef JS_KEYWORD
< 
87c76
<     TOK_REGEXP = 32,                    /* RegExp constant */
---
>     TOK_OBJECT = 32,                    /* RegExp or other object constant */
116,140d104
<     TOK_XMLSTAGO = 61,                  /* XML start tag open (<) */
<     TOK_XMLETAGO = 62,                  /* XML end tag open (</) */
<     TOK_XMLPTAGC = 63,                  /* XML point tag close (/>) */
<     TOK_XMLTAGC = 64,                   /* XML start or end tag close (>) */
<     TOK_XMLNAME = 65,                   /* XML start-tag non-final fragment */
<     TOK_XMLATTR = 66,                   /* XML quoted attribute value */
<     TOK_XMLSPACE = 67,                  /* XML whitespace */
<     TOK_XMLTEXT = 68,                   /* XML text */
<     TOK_XMLCOMMENT = 69,                /* XML comment */
<     TOK_XMLCDATA = 70,                  /* XML CDATA section */
<     TOK_XMLPI = 71,                     /* XML processing instruction */
<     TOK_AT = 72,                        /* XML attribute op (@) */
<     TOK_DBLCOLON = 73,                  /* namespace qualified name op (::) */
<     TOK_ANYNAME = 74,                   /* XML AnyName singleton (*) */
<     TOK_DBLDOT = 75,                    /* XML descendant op (..) */
<     TOK_FILTER = 76,                    /* XML filtering predicate op (.()) */
<     TOK_XMLELEM = 77,                   /* XML element node type (no token) */
<     TOK_XMLLIST = 78,                   /* XML list node type (no token) */
<     TOK_YIELD = 79,                     /* yield from generator function */
<     TOK_ARRAYCOMP = 80,                 /* array comprehension initialiser */
<     TOK_ARRAYPUSH = 81,                 /* array push within comprehension */
<     TOK_LEXICALSCOPE = 82,              /* block scope AST node label */
<     TOK_LET = 83,                       /* let keyword */
<     TOK_BODY = 84,                      /* synthetic body of function with
<                                            destructuring formal parameters */
148,187d111
< #define TOKEN_TYPE_IS_XML(tt) \
<     (tt == TOK_AT || tt == TOK_DBLCOLON || tt == TOK_ANYNAME)
< 
< #if JS_HAS_BLOCK_SCOPE
< # define TOKEN_TYPE_IS_DECL(tt) ((tt) == TOK_VAR || (tt) == TOK_LET)
< #else
< # define TOKEN_TYPE_IS_DECL(tt) ((tt) == TOK_VAR)
< #endif
< 
< struct JSStringBuffer {
<     jschar      *base;
<     jschar      *limit;         /* length limit for quick bounds check */
<     jschar      *ptr;           /* slot for next non-NUL char to store */
<     void        *data;
<     JSBool      (*grow)(JSStringBuffer *sb, size_t newlength);
<     void        (*free)(JSStringBuffer *sb);
< };
< 
< #define STRING_BUFFER_ERROR_BASE        ((jschar *) 1)
< #define STRING_BUFFER_OK(sb)            ((sb)->base != STRING_BUFFER_ERROR_BASE)
< #define STRING_BUFFER_OFFSET(sb)        ((sb)->ptr -(sb)->base)
< 
< extern void
< js_InitStringBuffer(JSStringBuffer *sb);
< 
< extern void
< js_FinishStringBuffer(JSStringBuffer *sb);
< 
< extern void
< js_AppendChar(JSStringBuffer *sb, jschar c);
< 
< extern void
< js_RepeatChar(JSStringBuffer *sb, jschar c, uintN count);
< 
< extern void
< js_AppendCString(JSStringBuffer *sb, const char *asciiz);
< 
< extern void
< js_AppendJSString(JSStringBuffer *sb, JSString *str);
< 
203c127
<         struct {                        /* name or string literal */
---
>         struct {
207,212d130
<         uintN           reflags;        /* regexp flags, use tokenbuf to access
<                                            regexp chars */
<         struct {                        /* atom pair, for XML PIs */
<             JSAtom      *atom2;         /* auxiliary atom table entry */
<             JSAtom      *atom;          /* main atom table entry */
<         } p;
218d135
< #define t_reflags       u.reflags
220d136
< #define t_atom2         u.p.atom2
246c162
<     JSStringBuffer      tokenbuf;       /* current token string buffer */
---
>     JSTokenBuf          tokenbuf;       /* current token string buffer */
248a165
>     JSPrincipals        *principals;    /* principals associated with source */
252,253d168
<     jschar              *saveEOL;       /* save next end of line in userbuf, to
<                                            optimize for very long lines */
256,257c171
< #define CURRENT_TOKEN(ts)       ((ts)->tokens[(ts)->cursor])
< #define ON_CURRENT_LINE(ts,pos) ((uint16)(ts)->lineno == (pos).end.lineno)
---
> #define CURRENT_TOKEN(ts) ((ts)->tokens[(ts)->cursor])
263c177
< #define TSF_OPERAND     0x08            /* looking for operand, not operator */
---
> #define TSF_REGEXP      0x08            /* looking for a regular expression */
266,297c180
< #define TSF_DIRTYLINE   0x80            /* non-whitespace since start of line */
< #define TSF_OWNFILENAME 0x100           /* ts->filename is malloc'd */
< #define TSF_XMLTAGMODE  0x200           /* scanning within an XML tag in E4X */
< #define TSF_XMLTEXTMODE 0x400           /* scanning XMLText terminal from E4X */
< #define TSF_XMLONLYMODE 0x800           /* don't scan {expr} within text/tag */
< 
< /* Flag indicating unexpected end of input, i.e. TOK_EOF not at top-level. */
< #define TSF_UNEXPECTED_EOF 0x1000
< 
< /*
<  * To handle the hard case of contiguous HTML comments, we want to clear the
<  * TSF_DIRTYINPUT flag at the end of each such comment.  But we'd rather not
<  * scan for --> within every //-style comment unless we have to.  So we set
<  * TSF_IN_HTML_COMMENT when a <!-- is scanned as an HTML begin-comment, and
<  * clear it (and TSF_DIRTYINPUT) when we scan --> either on a clean line, or
<  * only if (ts->flags & TSF_IN_HTML_COMMENT), in a //-style comment.
<  *
<  * This still works as before given a malformed comment hiding hack such as:
<  *
<  *    <script>
<  *      <!-- comment hiding hack #1
<  *      code goes here
<  *      // --> oops, markup for script-unaware browsers goes here!
<  *    </script>
<  *
<  * It does not cope with malformed comment hiding hacks where --> is hidden
<  * by C-style comments, or on a dirty line.  Such cases are already broken.
<  */
< #define TSF_IN_HTML_COMMENT 0x2000
< 
< /* Ignore keywords and return TOK_NAME instead to the parser. */
< #define TSF_KEYWORD_IS_NAME 0x4000
---
> #define TSF_DIRTYLINE   0x80            /* stuff other than whitespace since start of line */
307,309c190,192
<  * The function uses JSContext.tempPool to allocate internal buffers. The
<  * caller should release them using JS_ARENA_RELEASE after it has finished
<  * with the token stream and has called js_CloseTokenStream.
---
>  * NB: All of js_New{,Buffer,File}TokenStream() return a pointer to transient
>  * memory in the current context's temp pool.  This memory is deallocated via
>  * JS_ARENA_RELEASE() after parsing is finished.
311,314c194,196
< extern JSBool
< js_InitTokenStream(JSContext *cx, JSTokenStream *ts,
<                    const jschar *base, size_t length,
<                    FILE *fp, const char *filename, uintN lineno);
---
> extern JSTokenStream *
> js_NewTokenStream(JSContext *cx, const jschar *base, size_t length,
>                   const char *filename, uintN lineno, JSPrincipals *principals);
316,317c198,202
< extern void
< js_CloseTokenStream(JSContext *cx, JSTokenStream *ts);
---
> extern JS_FRIEND_API(JSTokenStream *)
> js_NewBufferTokenStream(JSContext *cx, const jschar *base, size_t length);
> 
> extern JS_FRIEND_API(JSTokenStream *)
> js_NewFileTokenStream(JSContext *cx, const char *filename, FILE *defaultfp);
319,320c204,205
< extern JS_FRIEND_API(int)
< js_fgets(char *buf, int size, FILE *file);
---
> extern JS_FRIEND_API(JSBool)
> js_CloseTokenStream(JSContext *cx, JSTokenStream *ts);
323,324c208
<  * If the given char array forms JavaScript keyword, return corresponding
<  * token. Otherwise return TOK_EOF.
---
>  * Initialize the scanner, installing JS keywords into cx's global scope.
326,327c210,211
< extern JSTokenType
< js_CheckKeyword(const jschar *chars, size_t length);
---
> extern JSBool
> js_InitScanner(JSContext *cx);
337,338c221,222
<  * Check that str forms a valid JS identifier name. The function does not
<  * check if str is a JS keyword.
---
>  * Report a compile-time error by its number, using ts or cg to show context.
>  * Return true for a warning, false for an error.
341,356c225,227
< js_IsIdentifier(JSString *str);
< 
< /*
<  * Report a compile-time error by its number. Return true for a warning, false
<  * for an error. When pn is not null, use it to report error's location.
<  * Otherwise use ts, which must not be null.
<  */
< JSBool
< js_ReportCompileErrorNumber(JSContext *cx, JSTokenStream *ts, JSParseNode *pn,
<                             uintN flags, uintN errorNumber, ...);
< 
< /*
<  * Steal one JSREPORT_* bit (see jsapi.h) to tell that arguments to the error
<  * message have const jschar* type, not const char*.
<  */
< #define JSREPORT_UC 0x100
---
> js_ReportCompileErrorNumber(JSContext *cx, JSTokenStream *ts,
>                             JSCodeGenerator *cg, uintN flags,
>                             const uintN errorNumber, ...);
Only in /Volumes/Swap/js-14-2-2008/js/src: jsscope.c
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsscope.h /Volumes/Swap/js_D11/src/jsscope.h
2d1
<  * vim: set ts=8 sw=4 et tw=78:
4,15c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
20,23c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
27,39c23,33
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
47d40
< #include "jslock.h"
52c45,47
< JS_BEGIN_EXTERN_C
---
> #ifdef JS_THREADSAFE
> # include "jslock.h"
> #endif
102c97
<  *
---
>  * 
121c116,119
<  * reachable from scopes, performing remove-node operations as needed.
---
>  * reachable from scopes, performing remove-node operations as needed.  Note
>  * also that the stable storage of the property nodes during active requests
>  * permits the property cache (see jsinterp.h) to dereference JSScopeProperty
>  * weak references safely.
201,204c199,200
<     uint32          shape;              /* property cache shape identifier */
<     uint8           flags;              /* flags, see below */
<     int8            hashShift;          /* multiplicative hash shift */
<     uint16          spare;              /* reserved */
---
>     uint16          flags;              /* flags, see below */
>     int16           hashShift;          /* multiplicative hash shift */
216c212
< #ifdef JS_DEBUG_SCOPE_LOCKS
---
> #ifdef DEBUG
224d219
< #define SCOPE_GENERATE_PCTYPE(cx,scope) ((scope)->shape = js_GenerateShape(cx))
232d226
< #define SCOPE_BRANDED                   0x0004
240,255c234
< #if 0
< /*
<  * Don't define this, it can't be done safely because JS_LOCK_OBJ will avoid
<  * taking the lock if the object owns its scope and the scope is sealed.
<  */
< #undef  SCOPE_CLR_SEALED(scope)         ((scope)->flags &= ~SCOPE_SEALED)
< #endif
< 
< /*
<  * A branded scope's object contains plain old methods (function-valued
<  * properties without magic getters and setters), and its scope->shape
<  * evolves whenever a function value changes.
<  */
< #define SCOPE_IS_BRANDED(scope)         ((scope)->flags & SCOPE_BRANDED)
< #define SCOPE_SET_BRANDED(scope)        ((scope)->flags |= SCOPE_BRANDED)
< #define SCOPE_CLR_BRANDED(scope)        ((scope)->flags &= ~SCOPE_BRANDED)
---
> #define SCOPE_CLR_SEALED(scope)         ((scope)->flags &= ~SCOPE_SEALED)
269c248
<     uint32          slot;               /* abstract index in object slots */
---
>     uint32          slot;               /* index in obj->slots vector */
276d254
<     uint32          shape;              /* property cache shape identifier */
301,303c279,281
< #define SPROP_IS_ALIAS                  0x02
< #define SPROP_HAS_SHORTID               0x04
< #define SPROP_FLAG_SHAPE_REGEN          0x08
---
> #define SPROP_IS_DUPLICATE              0x02
> #define SPROP_IS_ALIAS                  0x04
> #define SPROP_HAS_SHORTID               0x08
315,316c293,294
< #define SLOT_IN_SCOPE(slot,scope)         ((slot) < (scope)->map.freeslot)
< #define SPROP_HAS_VALID_SLOT(sprop,scope) SLOT_IN_SCOPE((sprop)->slot, scope)
---
> #define SPROP_HAS_VALID_SLOT(sprop, scope)                                    \
>     ((sprop)->slot < (scope)->map.freeslot)
318,319c296,301
< #define SPROP_HAS_STUB_GETTER(sprop)    (!(sprop)->getter)
< #define SPROP_HAS_STUB_SETTER(sprop)    (!(sprop)->setter)
---
> #define SPROP_CALL_GETTER(cx,sprop,getter,obj,obj2,vp)                        \
>     (!(getter) ||                                                             \
>      (getter)(cx, OBJ_THIS_OBJECT(cx,obj), SPROP_USERID(sprop), vp))
> #define SPROP_CALL_SETTER(cx,sprop,setter,obj,obj2,vp)                        \
>     (!(setter) ||                                                             \
>      (setter)(cx, OBJ_THIS_OBJECT(cx,obj), SPROP_USERID(sprop), vp))
321,323d302
< /*
<  * NB: SPROP_GET must not be called if SPROP_HAS_STUB_GETTER(sprop).
<  */
329c308
<      : (sprop)->getter(cx, OBJ_THIS_OBJECT(cx,obj), SPROP_USERID(sprop), vp))
---
>      : SPROP_CALL_GETTER(cx, sprop, (sprop)->getter, obj, obj2, vp))
331,334d309
< /*
<  * NB: SPROP_SET must not be called if (SPROP_HAS_STUB_SETTER(sprop) &&
<  * !(sprop->attrs & JSPROP_GETTER)).
<  */
343c318
<      : (sprop)->setter(cx, OBJ_THIS_OBJECT(cx,obj), SPROP_USERID(sprop), vp))
---
>      : SPROP_CALL_SETTER(cx, sprop, (sprop)->setter, obj, obj2, vp))
359c334,337
< #define ID_TO_VALUE(id) ((jsval)(id))
---
> #define ID_TO_VALUE(id) (((id) & JSVAL_INT) ? id : ATOM_KEY((JSAtom *)(id)))
> #define HASH_ID(id)     (((id) & JSVAL_INT)                                   \
>                          ? (jsatomid) JSVAL_TO_INT(id)                        \
>                          : ((JSAtom *)id)->number)
386,392c364
< /*
<  * These macros used to inline short code sequences, but they grew over time.
<  * We retain them for internal backward compatibility, and in case one or both
<  * ever shrink to inline-able size.
<  */
< #define TRACE_ID(trc, id)                js_TraceId(trc, id)
< #define TRACE_SCOPE_PROPERTY(trc, sprop) js_TraceScopeProperty(trc, sprop)
---
> #define MARK_SCOPE_PROPERTY(sprop)      ((sprop)->flags |= SPROP_MARK)
395,401c367
< js_TraceId(JSTracer *trc, jsid id);
< 
< extern void
< js_TraceScopeProperty(JSTracer *trc, JSScopeProperty *sprop);
< 
< extern void
< js_SweepScopeProperties(JSContext *cx);
---
> js_SweepScopeProperties(JSRuntime *rt);
409,410d374
< JS_END_EXTERN_C
< 
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsscript.c /Volumes/Swap/js_D11/src/jsscript.c
2d1
<  * vim: set ts=8 sw=4 et tw=78:
4,15c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
20,39c16,33
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
57d50
< #include "jslock.h"
60d52
< #include "jsparse.h"
66,69c58
< #if JS_HAS_SCRIPT_OBJECT
< 
< static const char js_script_exec_str[]    = "Script.prototype.exec";
< static const char js_script_compile_str[] = "Script.prototype.compile";
---
> //#include "_optimize.h"
71,94c60
< /*
<  * This routine requires that obj has been locked previously.
<  */
< static jsint
< GetScriptExecDepth(JSContext *cx, JSObject *obj)
< {
<     jsval v;
< 
<     JS_ASSERT(JS_IS_OBJ_LOCKED(cx, obj));
<     v = LOCKED_OBJ_GET_SLOT(obj, JSSLOT_START(&js_ScriptClass));
<     return JSVAL_TO_INT(v);
< }
< 
< static void
< AdjustScriptExecDepth(JSContext *cx, JSObject *obj, jsint delta)
< {
<     jsint execDepth;
< 
<     JS_LOCK_OBJ(cx, obj);
<     execDepth = GetScriptExecDepth(cx, obj);
<     LOCKED_OBJ_SET_SLOT(obj, JSSLOT_START(&js_ScriptClass),
<                         INT_TO_JSVAL(execDepth + delta));
<     JS_UNLOCK_OBJ(cx, obj);
< }
---
> #if JS_HAS_SCRIPT_OBJECT
98c64,65
< script_toSource(JSContext *cx, uintN argc, jsval *vp)
---
> script_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
>                 jsval *rval)
100,101d66
<     JSObject *obj;
<     uint32 indent;
105a71
>     uint32 indent;
108,113c74
<     obj = JS_THIS_OBJECT(cx, vp);
<     if (!JS_InstanceOf(cx, obj, &js_ScriptClass, vp + 2))
<         return JS_FALSE;
< 
<     indent = 0;
<     if (argc != 0 && !js_ValueToECMAUint32(cx, vp[2], &indent))
---
>     if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv))
115d75
< 
125a86,88
>         indent = 0;
>         if (argc && !js_ValueToECMAUint32(cx, argv[0], &indent))
>             return JS_FALSE;
133c96,97
<         JSSTRING_CHARS_AND_LENGTH(str, s, k);
---
>         s = JSSTRING_CHARS(str);
>         k = JSSTRING_LENGTH(str);
137a102
>     XMEMTAG("jsscript ");
155c120
<     *vp = STRING_TO_JSVAL(str);
---
>     *rval = STRING_TO_JSVAL(str);
161c126,127
< script_toString(JSContext *cx, uintN argc, jsval *vp)
---
> script_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
>                 jsval *rval)
163,164d128
<     uint32 indent;
<     JSObject *obj;
165a130
>     uint32 indent;
168,173c133
<     indent = 0;
<     if (argc != 0 && !js_ValueToECMAUint32(cx, vp[2], &indent))
<         return JS_FALSE;
< 
<     obj = JS_THIS_OBJECT(cx, vp);
<     if (!JS_InstanceOf(cx, obj, &js_ScriptClass, vp + 2))
---
>     if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv))
177c137
<         *vp = STRING_TO_JSVAL(cx->runtime->emptyString);
---
>         *rval = STRING_TO_JSVAL(cx->runtime->emptyString);
180a141,143
>     indent = 0;
>     if (argc && !js_ValueToECMAUint32(cx, argv[0], &indent))
>         return JS_FALSE;
185c148
<     *vp = STRING_TO_JSVAL(str);
---
>     *rval = STRING_TO_JSVAL(str);
190,191c153,154
< script_compile_sub(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
<                    jsval *rval)
---
> script_compile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
>                jsval *rval)
192a156
>     JSScript *oldscript, *script;
194,196d157
<     JSObject *scopeobj;
<     jsval v;
<     JSScript *script, *oldscript;
197a159
>     JSObject *scopeobj;
201,202d162
<     uint32 tcflags;
<     jsint execDepth;
216c176,180
<     argv[0] = STRING_TO_JSVAL(str);
---
> 
>     /* Compile using the caller's scope chain, which js_Invoke passes to fp. */
>     fp = cx->fp;
>     caller = fp->down;
>     JS_ASSERT(fp->scopeChain == caller->scopeChain);
223a188,189
>     if (!scopeobj)
>         scopeobj = caller->scopeChain;
225,237c191
<     /* Compile using the caller's scope chain, which js_Invoke passes to fp. */
<     fp = cx->fp;
<     caller = JS_GetScriptedCaller(cx, fp);
<     JS_ASSERT(!caller || fp->scopeChain == caller->scopeChain);
< 
<     if (caller) {
<         if (!scopeobj) {
<             scopeobj = js_GetScopeChain(cx, caller);
<             if (!scopeobj)
<                 return JS_FALSE;
<             fp->scopeChain = scopeobj;  /* for the compiler's benefit */
<         }
< 
---
>     if (caller->script) {
239,240c193,194
<         line = js_PCToLineNumber(cx, caller->script, caller->pc);
<         principals = JS_EvalFramePrincipals(cx, fp, caller);
---
>         line = js_PCToLineNumber(caller->script, caller->pc);
>         principals = caller->script->principals;
247,264c201,205
<     /* Ensure we compile this script with the right (inner) principals. */
<     scopeobj = js_CheckScopeChainValidity(cx, scopeobj, js_script_compile_str);
<     if (!scopeobj)
<         return JS_FALSE;
< 
<     /*
<      * Compile the new script using the caller's scope chain, a la eval().
<      * Unlike jsobj.c:obj_eval, however, we do not pass TCF_COMPILE_N_GO in
<      * tcflags, because compilation is here separated from execution, and the
<      * run-time scope chain may not match the compile-time.  JSFRAME_EVAL is
<      * tested in jsemit.c and jsscan.c to optimize based on identity of run-
<      * and compile-time scope.
<      */
<     fp->flags |= JSFRAME_SCRIPT_OBJECT;
<     tcflags = 0;
<     script = js_CompileScript(cx, scopeobj, principals, tcflags,
<                               JSSTRING_CHARS(str), JSSTRING_LENGTH(str),
<                               NULL, file, line);
---
>     /* Compile the new script using the caller's scope chain, a la eval(). */
>     script = JS_CompileUCScriptForPrincipals(cx, scopeobj, principals,
>                                              JSSTRING_CHARS(str),
>                                              JSSTRING_LENGTH(str),
>                                              file, line);
268,278c209,212
<     JS_LOCK_OBJ(cx, obj);
<     execDepth = GetScriptExecDepth(cx, obj);
< 
<     /*
<      * execDepth must be 0 to allow compilation here, otherwise the JSScript
<      * struct can be released while running.
<      */
<     if (execDepth > 0) {
<         JS_UNLOCK_OBJ(cx, obj);
<         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
<                              JSMSG_COMPILE_EXECED_SCRIPT);
---
>     /* Swap script for obj's old script, if any. */
>     oldscript = (JSScript *) JS_GetPrivate(cx, obj);
>     if (!JS_SetPrivate(cx, obj, script)) {
>         js_DestroyScript(cx, script);
281,287d214
< 
<     /* Swap script for obj's old script, if any. */
<     v = LOCKED_OBJ_GET_SLOT(obj, JSSLOT_PRIVATE);
<     oldscript = !JSVAL_IS_VOID(v) ? JSVAL_TO_PRIVATE(v) : NULL;
<     LOCKED_OBJ_SET_SLOT(obj, JSSLOT_PRIVATE, PRIVATE_TO_JSVAL(script));
<     JS_UNLOCK_OBJ(cx, obj);
< 
292,293d218
<     js_CallNewScriptHook(cx, script, NULL);
< 
301,308c226
< script_compile(JSContext *cx, uintN argc, jsval *vp)
< {
<     return script_compile_sub(cx, JS_THIS_OBJECT(cx, vp), argc, vp + 2, vp);
< }
< 
< static JSBool
< script_exec_sub(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
<                 jsval *rval)
---
> script_exec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
310,312d227
<     JSObject *scopeobj, *parent;
<     JSStackFrame *fp, *caller;
<     JSPrincipals *principals;
314c229,230
<     JSBool ok;
---
>     JSStackFrame *fp, *caller;
>     JSObject *scopeobj;
317a234,236
>     script = (JSScript *) JS_GetPrivate(cx, obj);
>     if (!script)
>         return JS_TRUE;
320c239
<     if (argc != 0) {
---
>     if (argc) {
326,337c245
<     /*
<      * Emulate eval() by using caller's this, var object, sharp array, etc.,
<      * all propagated by js_Execute via a non-null fourth (down) argument to
<      * js_Execute.  If there is no scripted caller, js_Execute uses its second
<      * (chain) argument to set the exec frame's varobj, thisp, and scopeChain.
<      *
<      * Unlike eval, which the compiler detects, Script.prototype.exec may be
<      * called from a lightweight function, or even from native code (in which
<      * case fp->varobj and fp->scopeChain are null).  If exec is called from
<      * a lightweight function, we will need to get a Call object representing
<      * its frame, to act as the var object and scope chain head.
<      */
---
>     /* Emulate eval() by using caller's this, scope chain, and sharp array. */
339,373c247
<     caller = JS_GetScriptedCaller(cx, fp);
<     if (caller && !caller->varobj) {
<         /* Called from a lightweight function. */
<         JS_ASSERT(caller->fun && !JSFUN_HEAVYWEIGHT_TEST(caller->fun->flags));
< 
<         /* Scope chain links from Call object to callee's parent. */
<         parent = OBJ_GET_PARENT(cx, caller->callee);
<         if (!js_GetCallObject(cx, caller, parent))
<             return JS_FALSE;
<     }
< 
<     if (!scopeobj) {
<         /* No scope object passed in: try to use the caller's scope chain. */
<         if (caller) {
<             /*
<              * Load caller->scopeChain after the conditional js_GetCallObject
<              * call above, which resets scopeChain as well as varobj.
<              */
<             scopeobj = js_GetScopeChain(cx, caller);
<             if (!scopeobj)
<                 return JS_FALSE;
<         } else {
<             /*
<              * Called from native code, so we don't know what scope object to
<              * use.  We could use parent (see above), but Script.prototype.exec
<              * might be a shared/sealed "superglobal" method.  A more general
<              * approach would use cx->globalObject, which will be the same as
<              * exec.__parent__ in the non-superglobal case.  In the superglobal
<              * case it's the right object: the global, not the superglobal.
<              */
<             scopeobj = cx->globalObject;
<         }
<     }
< 
<     scopeobj = js_CheckScopeChainValidity(cx, scopeobj, js_script_exec_str);
---
>     caller = fp->down;
375c249,254
<         return JS_FALSE;
---
>       scopeobj = caller->scopeChain;
>     fp->thisp = caller->thisp;
>     JS_ASSERT(fp->scopeChain == caller->scopeChain);
>     fp->sharpArray = caller->sharpArray;
>     return js_Execute(cx, scopeobj, script, fp, 0, rval);
> }
377,378c256,261
<     /* Keep track of nesting depth for the script. */
<     AdjustScriptExecDepth(cx, obj, 1);
---
> #if JS_HAS_XDR
> static JSBool
> XDRAtomListElement(JSXDRState *xdr, JSAtomListElement *ale)
> {
>     jsval value;
>     jsatomid index;
380,385c263,264
<     /* Must get to out label after this */
<     script = (JSScript *) JS_GetPrivate(cx, obj);
<     if (!script) {
<         ok = JS_FALSE;
<         goto out;
<     }
---
>     if (xdr->mode == JSXDR_ENCODE)
>         value = ATOM_KEY(ALE_ATOM(ale));
387,392c266,269
<     /* Belt-and-braces: check that this script object has access to scopeobj. */
<     principals = script->principals;
<     ok = js_CheckPrincipalsAccess(cx, scopeobj, principals,
<                                   CLASS_ATOM(cx, Script));
<     if (!ok)
<         goto out;
---
>     index = ALE_INDEX(ale);
>     if (!JS_XDRUint32(xdr, &index))
>         return JS_FALSE;
>     ALE_SET_INDEX(ale, index);
394c271,272
<     ok = js_Execute(cx, scopeobj, script, caller, JSFRAME_EVAL, rval);
---
>     if (!JS_XDRValue(xdr, &value))
>         return JS_FALSE;
396,398c274,278
< out:
<     AdjustScriptExecDepth(cx, obj, -1);
<     return ok;
---
>     if (xdr->mode == JSXDR_DECODE) {
>         if (!ALE_SET_ATOM(ale, js_AtomizeValue(xdr->cx, value, 0)))
>             return JS_FALSE;
>     }
>     return JS_TRUE;
402c282
< script_exec(JSContext *cx, uintN argc, jsval *vp)
---
> XDRAtomMap(JSXDRState *xdr, JSAtomMap *map)
404,405c284,286
<     return script_exec_sub(cx, JS_THIS_OBJECT(cx, vp), argc, vp + 2, vp);
< }
---
>     uint32 length;
>     uintN i;
>     JSBool ok;
407c288,289
< #endif /* JS_HAS_SCRIPT_OBJECT */
---
>     if (xdr->mode == JSXDR_ENCODE)
>         length = map->length;
409c291,332
< #if JS_HAS_XDR
---
>     if (!JS_XDRUint32(xdr, &length))
>         return JS_FALSE;
> 
>     if (xdr->mode == JSXDR_DECODE) {
>         JSContext *cx;
>         void *mark;
>         JSAtomList al;
>         JSAtomListElement *ale;
> 
>         cx = xdr->cx;
>         mark = JS_ARENA_MARK(&cx->tempPool);
>         ATOM_LIST_INIT(&al);
>         for (i = 0; i < length; i++) {
>             JS_ARENA_ALLOCATE_TYPE(ale, JSAtomListElement, &cx->tempPool);
>             if (!ale ||
>                 !XDRAtomListElement(xdr, ale)) {
>                 if (!ale)
>                     JS_ReportOutOfMemory(cx);
>                 JS_ARENA_RELEASE(&cx->tempPool, mark);
>                 return JS_FALSE;
>             }
>             ALE_SET_NEXT(ale, al.list);
>             al.count++;
>             al.list = ale;
>         }
>         ok = js_InitAtomMap(cx, map, &al);
>         JS_ARENA_RELEASE(&cx->tempPool, mark);
>         return ok;
>     }
> 
>     if (xdr->mode == JSXDR_ENCODE) {
>         JSAtomListElement ale;
> 
>         for (i = 0; i < map->length; i++) {
>             ALE_SET_ATOM(&ale, map->vector[i]);
>             ALE_SET_INDEX(&ale, i);
>             if (!XDRAtomListElement(xdr, &ale))
>                 return JS_FALSE;
>         }
>     }
>     return JS_TRUE;
> }
414,417c337,338
<     JSContext *cx;
<     JSScript *script, *oldscript;
<     uint32 length, lineno, depth, magic;
<     uint32 natoms, nsrcnotes, ntrynotes, nobjects, nregexps, i;
---
>     JSScript *script;
>     uint32 length, lineno, depth, magic, notelen, numtrys;
419,423d339
<     JSTempValueRooter tvr;
<     JSPrincipals *principals;
<     uint32 encodeable;
<     JSBool filenameWasSaved;
<     jssrcnote *notes, *sn;
425d340
<     cx = xdr->cx;
427,429c342
<     nsrcnotes = ntrynotes = natoms = nobjects = nregexps = 0;
<     filenameWasSaved = JS_FALSE;
<     notes = NULL;
---
>     numtrys = 0;
430a344,348
>     /*
>      * Encode prologLength and version after script->length (_2 or greater),
>      * but decode both new (>= _2) and old, prolog&version-free (_1) scripts.
>      * Version _3 supports principals serialization.
>      */
435,436c353,355
<     if (magic != JSXDR_MAGIC_SCRIPT_CURRENT) {
<         /* We do not provide binary compatibility with older scripts. */
---
>     if (magic != JSXDR_MAGIC_SCRIPT_3 &&
>         magic != JSXDR_MAGIC_SCRIPT_2 &&
>         magic != JSXDR_MAGIC_SCRIPT_1) {
438c357
<             JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
---
>             JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL,
448a368
>         jssrcnote *sn = script->notes;
450,452c370,371
<         prologLength = PTRDIFF(script->main, script->code, jsbytecode);
<         JS_ASSERT((int16)script->version != JSVERSION_UNKNOWN);
<         version = (uint32)script->version | (script->ngvars << 16);
---
>         prologLength = script->main - script->code;
>         version = (int32)script->version;
455d373
<         natoms = (uint32)script->atomMap.length;
457,469c375,386
<         /* Count the srcnotes, keeping notes pointing at the first one. */
<         notes = SCRIPT_NOTES(script);
<         for (sn = notes; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn))
<             continue;
<         nsrcnotes = PTRDIFF(sn, notes, jssrcnote);
<         nsrcnotes++;            /* room for the terminator */
< 
<         if (script->objectsOffset != 0)
<             nobjects = JS_SCRIPT_OBJECTS(script)->length;
<         if (script->regexpsOffset != 0)
<             nregexps = JS_SCRIPT_REGEXPS(script)->length;
<         if (script->trynotesOffset != 0)
<             ntrynotes = JS_SCRIPT_TRYNOTES(script)->length;
---
>         /* Count the trynotes. */
>         if (script->trynotes) {
>             for (; script->trynotes[numtrys].catchStart; numtrys++)
>                 continue;
>             numtrys++;          /* room for the end marker */
>         }
> 
>         /* Count the src notes. */
>         while (!SN_IS_TERMINATOR(sn))
>             sn = SN_NEXT(sn);
>         notelen = sn - script->notes;
>         notelen++;              /* room for the terminator */
474,492c391,396
<     if (!JS_XDRUint32(xdr, &prologLength))
<         return JS_FALSE;
<     if (!JS_XDRUint32(xdr, &version))
<         return JS_FALSE;
< 
<     /*
<      * To fuse allocations, we need srcnote, atom, objects, regexp and trynote
<      * counts early.
<      */
<     if (!JS_XDRUint32(xdr, &natoms))
<         return JS_FALSE;
<     if (!JS_XDRUint32(xdr, &nsrcnotes))
<         return JS_FALSE;
<     if (!JS_XDRUint32(xdr, &ntrynotes))
<         return JS_FALSE;
<     if (!JS_XDRUint32(xdr, &nobjects))
<         return JS_FALSE;
<     if (!JS_XDRUint32(xdr, &nregexps))
<         return JS_FALSE;
---
>     if (magic >= JSXDR_MAGIC_SCRIPT_2) {
>         if (!JS_XDRUint32(xdr, &prologLength))
>             return JS_FALSE;
>         if (!JS_XDRUint32(xdr, &version))
>             return JS_FALSE;
>     }
495,496c399
<         script = js_NewScript(cx, length, nsrcnotes, natoms, nobjects, nregexps,
<                               ntrynotes);
---
>         script = js_NewScript(xdr->cx, length);
499,505c402,405
< 
<         script->main += prologLength;
<         script->version = (JSVersion) (version & 0xffff);
<         script->ngvars = (uint16) (version >> 16);
< 
<         /* If we know nsrcnotes, we allocated space for notes in script. */
<         notes = SCRIPT_NOTES(script);
---
>         if (magic >= JSXDR_MAGIC_SCRIPT_2) {
>             script->main += prologLength;
>             script->version = (JSVersion) version;
>         }
507d406
<         JS_PUSH_TEMP_ROOT_SCRIPT(cx, script, &tvr);
510,519c409,417
<     /*
<      * Control hereafter must goto error on failure, in order for the
<      * DECODE case to destroy script.
<      */
<     oldscript = xdr->script;
<     xdr->script = script;
<     if (!JS_XDRBytes(xdr, (char *)script->code, length * sizeof(jsbytecode)))
<         goto error;
< 
<     if (!JS_XDRBytes(xdr, (char *)notes, nsrcnotes * sizeof(jssrcnote)) ||
---
>     /* Control hereafter must goto error on failure, to destroy script. */
>     if (!JS_XDRBytes(xdr, (char **)&script->code, length) ||
>         !XDRAtomMap(xdr, &script->atomMap) ||
>         !JS_XDRUint32(xdr, &notelen) ||
>         /* malloc on decode only */
>         (!(xdr->mode == JSXDR_ENCODE ||
>            (script->notes = (jssrcnote *)
>             JS_malloc(xdr->cx, notelen)) != NULL)) ||
>         !JS_XDRBytes(xdr, (char **)&script->notes, notelen) ||
522c420,421
<         !JS_XDRUint32(xdr, &depth)) {
---
>         !JS_XDRUint32(xdr, &depth) ||
>         !JS_XDRUint32(xdr, &numtrys)) {
526,541c425,435
<     if (xdr->mode == JSXDR_ENCODE) {
<         principals = script->principals;
<         encodeable = (cx->runtime->principalsTranscoder != NULL);
<         if (!JS_XDRUint32(xdr, &encodeable))
<             goto error;
<         if (encodeable &&
<             !cx->runtime->principalsTranscoder(xdr, &principals)) {
<             goto error;
<         }
<     } else {
<         if (!JS_XDRUint32(xdr, &encodeable))
<             goto error;
<         if (encodeable) {
<             if (!cx->runtime->principalsTranscoder) {
<                 JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
<                                      JSMSG_CANT_DECODE_PRINCIPALS);
---
>     if (magic >= JSXDR_MAGIC_SCRIPT_3) {
>         JSPrincipals *principals;
>         uint32 encodeable;
> 
>         if (xdr->mode == JSXDR_ENCODE) {
>             principals = script->principals;
>             encodeable = (xdr->cx->runtime->principalsTranscoder != NULL);
>             if (!JS_XDRUint32(xdr, &encodeable))
>                 goto error;
>             if (encodeable &&
>                 !xdr->cx->runtime->principalsTranscoder(xdr, &principals)) {
544c438,439
<             if (!cx->runtime->principalsTranscoder(xdr, &principals))
---
>         } else {
>             if (!JS_XDRUint32(xdr, &encodeable))
546c441,450
<             script->principals = principals;
---
>             if (encodeable) {
>                 if (!xdr->cx->runtime->principalsTranscoder) {
>                     JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL,
>                                          JSMSG_CANT_DECODE_PRINCIPALS);
>                     goto error;
>                 }
>                 if (!xdr->cx->runtime->principalsTranscoder(xdr, &principals))
>                     goto error;
>                 script->principals = principals;
>             }
551,559d454
<         const char *filename = script->filename;
<         if (filename) {
<             filename = js_SaveScriptFilename(cx, filename);
<             if (!filename)
<                 goto error;
<             JS_free(cx, (void *) script->filename);
<             script->filename = filename;
<             filenameWasSaved = JS_TRUE;
<         }
561a457,465
>         if (numtrys) {
>         	XMEMTAG("jsscript trynotes");
>             script->trynotes = (JSTryNote *)
>                 JS_malloc(xdr->cx, sizeof(JSTryNote) * (numtrys + 1));
>             if (!script->trynotes)
>                 goto error;
>         } else {
>             script->trynotes = NULL;
>         }
563,580c467,474
< 
<     for (i = 0; i != natoms; ++i) {
<         if (!js_XDRAtom(xdr, &script->atomMap.vector[i]))
<             goto error;
<     }
< 
<     /*
<      * Here looping from 0-to-length to xdr objects is essential. It ensures
<      * that block objects from the script->objects will be written and
<      * restored in the outer-to-inner order. block_xdrObject uses this to
<      * restore the parent chain.
<      */
<     for (i = 0; i != nobjects; ++i) {
<         if (!js_XDRObject(xdr, &JS_SCRIPT_OBJECTS(script)->vector[i]))
<             goto error;
<     }
<     for (i = 0; i != nregexps; ++i) {
<         if (!js_XDRObject(xdr, &JS_SCRIPT_REGEXPS(script)->vector[i]))
---
>     for (; numtrys; numtrys--) {
>         JSTryNote *tn = &script->trynotes[numtrys - 1];
>         uint32 start = (ptrdiff_t) tn->start,
>                catchLength = (ptrdiff_t) tn->length,
>                catchStart = (ptrdiff_t) tn->catchStart;
>         if (!JS_XDRUint32(xdr, &start) ||
>             !JS_XDRUint32(xdr, &catchLength) ||
>             !JS_XDRUint32(xdr, &catchStart)) {
581a476,479
>         }
>         tn->start = (ptrdiff_t) start;
>         tn->length = (ptrdiff_t) catchLength;
>         tn->catchStart = (ptrdiff_t) catchStart;
583,617d480
< 
<     if (ntrynotes != 0) {
<         /*
<          * We combine tn->kind and tn->stackDepth when serializing as XDR is not
<          * efficient when serializing small integer types.
<          */
<         JSTryNote *tn, *tnfirst;
<         uint32 kindAndDepth;
<         JS_STATIC_ASSERT(sizeof(tn->kind) == sizeof(uint8));
<         JS_STATIC_ASSERT(sizeof(tn->stackDepth) == sizeof(uint16));
< 
<         tnfirst = JS_SCRIPT_TRYNOTES(script)->vector;
<         JS_ASSERT(JS_SCRIPT_TRYNOTES(script)->length == ntrynotes);
<         tn = tnfirst + ntrynotes;
<         do {
<             --tn;
<             if (xdr->mode == JSXDR_ENCODE) {
<                 kindAndDepth = ((uint32)tn->kind << 16)
<                                | (uint32)tn->stackDepth;
<             }
<             if (!JS_XDRUint32(xdr, &kindAndDepth) ||
<                 !JS_XDRUint32(xdr, &tn->start) ||
<                 !JS_XDRUint32(xdr, &tn->length)) {
<                 goto error;
<             }
<             if (xdr->mode == JSXDR_DECODE) {
<                 tn->kind = (uint8)(kindAndDepth >> 16);
<                 tn->stackDepth = (uint16)kindAndDepth;
<             }
<         } while (tn != tnfirst);
<     }
< 
<     xdr->script = oldscript;
<     if (xdr->mode == JSXDR_DECODE)
<         JS_POP_TEMP_ROOT(cx, &tvr);
622,627c485
<         JS_POP_TEMP_ROOT(cx, &tvr);
<         if (script->filename && !filenameWasSaved) {
<             JS_free(cx, (void *) script->filename);
<             script->filename = NULL;
<         }
<         js_DestroyScript(cx, script);
---
>         js_DestroyScript(xdr->cx, script);
630d487
<     xdr->script = oldscript;
634,640d490
< #if JS_HAS_SCRIPT_OBJECT && JS_HAS_XDR_FREEZE_THAW
< /*
<  * These cannot be exposed to web content, and chrome does not need them, so
<  * we take them out of the Mozilla client altogether.  Fortunately, there is
<  * no way to serialize a native function (see fun_xdrObject in jsfun.c).
<  */
< 
642c492,493
< script_freeze(JSContext *cx, uintN argc, jsval *vp)
---
> script_freeze(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
>               jsval *rval)
644d494
<     JSObject *obj;
652,653c502
<     obj = JSVAL_TO_OBJECT(vp[1]);
<     if (!JS_InstanceOf(cx, obj, &js_ScriptClass, vp + 2))
---
>     if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv))
669c518
<         *vp = JSVAL_VOID;
---
>         *rval = JSVAL_VOID;
680a530,535
>     str = JS_NewUCStringCopyN(cx, (jschar *)buf, len);
>     if (!str) {
>         ok = JS_FALSE;
>         goto out;
>     }
> 
687c542
<     chars = (jschar *)buf;
---
>     chars = JS_GetStringChars(str);
692,698c547
<     str = JS_NewUCStringCopyN(cx, (jschar *)buf, len);
<     if (!str) {
<         ok = JS_FALSE;
<         goto out;
<     }
< 
<     *vp = STRING_TO_JSVAL(str);
---
>     *rval = STRING_TO_JSVAL(str);
706c555,556
< script_thaw(JSContext *cx, uintN argc, jsval *vp)
---
> script_thaw(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
>             jsval *rval)
708d557
<     JSObject *obj;
713d561
<     jsval v;
716d563
<     jsint execDepth;
718,719c565
<     obj = JSVAL_TO_OBJECT(vp[1]);
<     if (!JS_InstanceOf(cx, obj, &js_ScriptClass, vp + 2))
---
>     if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv))
724c570
<     str = js_ValueToString(cx, vp[2]);
---
>     str = js_ValueToString(cx, argv[0]);
727d572
<     vp[2] = STRING_TO_JSVAL(str);
734c579,580
<     JSSTRING_CHARS_AND_LENGTH(str, buf, len);
---
>     buf = JS_GetStringChars(str);
>     len = JS_GetStringLength(str);
741a588
>     XMEMTAG("jsscript to");
760c607
<         *vp = JSVAL_FALSE;
---
>         *rval = JSVAL_FALSE;
764,774c611,615
<     JS_LOCK_OBJ(cx, obj);
<     execDepth = GetScriptExecDepth(cx, obj);
< 
<     /*
<      * execDepth must be 0 to allow compilation here, otherwise the JSScript
<      * struct can be released while running.
<      */
<     if (execDepth > 0) {
<         JS_UNLOCK_OBJ(cx, obj);
<         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
<                              JSMSG_COMPILE_EXECED_SCRIPT);
---
>     /* Swap script for obj's old script, if any. */
>     oldscript = (JSScript *) JS_GetPrivate(cx, obj);
>     ok = JS_SetPrivate(cx, obj, script);
>     if (!ok) {
>         JS_free(cx, script);
777,783d617
< 
<     /* Swap script for obj's old script, if any. */
<     v = LOCKED_OBJ_GET_SLOT(obj, JSSLOT_PRIVATE);
<     oldscript = !JSVAL_IS_VOID(v) ? JSVAL_TO_PRIVATE(v) : NULL;
<     LOCKED_OBJ_SET_SLOT(obj, JSSLOT_PRIVATE, PRIVATE_TO_JSVAL(script));
<     JS_UNLOCK_OBJ(cx, obj);
< 
793c627
<      * memory owned by str (vp[2]).
---
>      * memory owned by str (argv[0]).
800c634
<     *vp = JSVAL_TRUE;
---
>     *rval = JSVAL_TRUE;
804,806d637
< static const char js_thaw_str[] = "thaw";
< 
< #endif /* JS_HAS_SCRIPT_OBJECT && JS_HAS_XDR_FREEZE_THAW */
809c640
< #if JS_HAS_SCRIPT_OBJECT
---
> static char js_thaw_str[] = "thaw";
813c644
<     JS_FN(js_toSource_str,   script_toSource,   0,0,0),
---
>     {js_toSource_str,   script_toSource,        0,0,0},
815,822c646,653
<     JS_FN(js_toString_str,   script_toString,   0,0,0),
<     JS_FN("compile",         script_compile,    0,2,0),
<     JS_FN("exec",            script_exec,       0,1,0),
< #if JS_HAS_XDR_FREEZE_THAW
<     JS_FN("freeze",          script_freeze,     0,0,0),
<     JS_FN(js_thaw_str,       script_thaw,       0,1,0),
< #endif /* JS_HAS_XDR_FREEZE_THAW */
<     JS_FS_END
---
>     {js_toString_str,   script_toString,        0,0,0},
>     {"compile",         script_compile,         2,0,0},
>     {"exec",            script_exec,            1,0,0},
> #if JS_HAS_XDR
>     {"freeze",          script_freeze,          0,0,0},
>     {js_thaw_str,       script_thaw,            1,0,0},
> #endif /* JS_HAS_XDR */
>     {0,0,0,0,0}
841c672
<     return script_exec_sub(cx, JSVAL_TO_OBJECT(argv[-2]), argc, argv, rval);
---
>     return script_exec(cx, JSVAL_TO_OBJECT(argv[-2]), argc, argv, rval);
847,848c678,679
< static void
< script_trace(JSTracer *trc, JSObject *obj)
---
> static uint32
> script_mark(JSContext *cx, JSObject *obj, void *arg)
852c683
<     script = (JSScript *) JS_GetPrivate(trc->context, obj);
---
>     script = (JSScript *) JS_GetPrivate(cx, obj);
854c685,686
<         js_TraceScript(trc, script);
---
>         js_MarkScript(cx, script, arg);
>     return 0;
857,860d688
< #if !JS_HAS_SCRIPT_OBJECT
< #define JSProto_Script  JSProto_Object
< #endif
< 
863,864c691
<     JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(1) |
<     JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_Script),
---
>     JSCLASS_HAS_PRIVATE,
868c695
<     NULL,             NULL,             JS_CLASS_TRACE(script_trace), NULL
---
>     NULL,             NULL,             script_mark,      0
881,886d707
< 
<         /*
<          * script_compile_sub does not use rval to root its temporaries so we
<          * can use it to root obj.
<          */
<         *rval = OBJECT_TO_JSVAL(obj);
888,892c709
< 
<     if (!JS_SetReservedSlot(cx, obj, 0, INT_TO_JSVAL(0)))
<         return JS_FALSE;
< 
<     return script_compile_sub(cx, obj, argc, argv, rval);
---
>     return script_compile(cx, obj, argc, argv, rval);
895c712
< #if JS_HAS_SCRIPT_OBJECT && JS_HAS_XDR_FREEZE_THAW
---
> #if JS_HAS_XDR
898c715,716
< script_static_thaw(JSContext *cx, uintN argc, jsval *vp)
---
> script_static_thaw(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
>                    jsval *rval)
900,901d717
<     JSObject *obj;
< 
905,906c721
<     vp[1] = OBJECT_TO_JSVAL(obj);
<     if (!script_thaw(cx, vp))
---
>     if (!script_thaw(cx, obj, argc, argv, rval))
908c723
<     *vp = OBJECT_TO_JSVAL(obj);
---
>     *rval = OBJECT_TO_JSVAL(obj);
913,914c728,729
<     JS_FN(js_thaw_str,       script_static_thaw,     1,1,0),
<     JS_FS_END
---
>     {js_thaw_str,       script_static_thaw,     1,0,0},
>     {0,0,0,0,0}
917c732
< #else  /* !JS_HAS_SCRIPT_OBJECT || !JS_HAS_XDR_FREEZE_THAW */
---
> #else  /* !JS_HAS_XDR */
921c736
< #endif /* !JS_HAS_SCRIPT_OBJECT || !JS_HAS_XDR_FREEZE_THAW */
---
> #endif /* !JS_HAS_XDR */
932,1310d746
< /*
<  * Shared script filename management.
<  */
< JS_STATIC_DLL_CALLBACK(int)
< js_compare_strings(const void *k1, const void *k2)
< {
<     return strcmp((const char *) k1, (const char *) k2) == 0;
< }
< 
< /* NB: This struct overlays JSHashEntry -- see jshash.h, do not reorganize. */
< typedef struct ScriptFilenameEntry {
<     JSHashEntry         *next;          /* hash chain linkage */
<     JSHashNumber        keyHash;        /* key hash function result */
<     const void          *key;           /* ptr to filename, below */
<     uint32              flags;          /* user-defined filename prefix flags */
<     JSPackedBool        mark;           /* GC mark flag */
<     char                filename[3];    /* two or more bytes, NUL-terminated */
< } ScriptFilenameEntry;
< 
< JS_STATIC_DLL_CALLBACK(void *)
< js_alloc_table_space(void *priv, size_t size)
< {
<     return malloc(size);
< }
< 
< JS_STATIC_DLL_CALLBACK(void)
< js_free_table_space(void *priv, void *item)
< {
<     free(item);
< }
< 
< JS_STATIC_DLL_CALLBACK(JSHashEntry *)
< js_alloc_sftbl_entry(void *priv, const void *key)
< {
<     size_t nbytes = offsetof(ScriptFilenameEntry, filename) +
<                     strlen((const char *) key) + 1;
< 
<     return (JSHashEntry *) malloc(JS_MAX(nbytes, sizeof(JSHashEntry)));
< }
< 
< JS_STATIC_DLL_CALLBACK(void)
< js_free_sftbl_entry(void *priv, JSHashEntry *he, uintN flag)
< {
<     if (flag != HT_FREE_ENTRY)
<         return;
<     free(he);
< }
< 
< static JSHashAllocOps sftbl_alloc_ops = {
<     js_alloc_table_space,   js_free_table_space,
<     js_alloc_sftbl_entry,   js_free_sftbl_entry
< };
< 
< JSBool
< js_InitRuntimeScriptState(JSRuntime *rt)
< {
< #ifdef JS_THREADSAFE
<     JS_ASSERT(!rt->scriptFilenameTableLock);
<     rt->scriptFilenameTableLock = JS_NEW_LOCK();
<     if (!rt->scriptFilenameTableLock)
<         return JS_FALSE;
< #endif
<     JS_ASSERT(!rt->scriptFilenameTable);
<     rt->scriptFilenameTable =
<         JS_NewHashTable(16, JS_HashString, js_compare_strings, NULL,
<                         &sftbl_alloc_ops, NULL);
<     if (!rt->scriptFilenameTable) {
<         js_FinishRuntimeScriptState(rt);    /* free lock if threadsafe */
<         return JS_FALSE;
<     }
<     JS_INIT_CLIST(&rt->scriptFilenamePrefixes);
<     return JS_TRUE;
< }
< 
< typedef struct ScriptFilenamePrefix {
<     JSCList     links;      /* circular list linkage for easy deletion */
<     const char  *name;      /* pointer to pinned ScriptFilenameEntry string */
<     size_t      length;     /* prefix string length, precomputed */
<     uint32      flags;      /* user-defined flags to inherit from this prefix */
< } ScriptFilenamePrefix;
< 
< void
< js_FinishRuntimeScriptState(JSRuntime *rt)
< {
<     if (rt->scriptFilenameTable) {
<         JS_HashTableDestroy(rt->scriptFilenameTable);
<         rt->scriptFilenameTable = NULL;
<     }
< #ifdef JS_THREADSAFE
<     if (rt->scriptFilenameTableLock) {
<         JS_DESTROY_LOCK(rt->scriptFilenameTableLock);
<         rt->scriptFilenameTableLock = NULL;
<     }
< #endif
< }
< 
< void
< js_FreeRuntimeScriptState(JSRuntime *rt)
< {
<     ScriptFilenamePrefix *sfp;
< 
<     if (!rt->scriptFilenameTable)
<         return;
< 
<     while (!JS_CLIST_IS_EMPTY(&rt->scriptFilenamePrefixes)) {
<         sfp = (ScriptFilenamePrefix *) rt->scriptFilenamePrefixes.next;
<         JS_REMOVE_LINK(&sfp->links);
<         free(sfp);
<     }
<     js_FinishRuntimeScriptState(rt);
< }
< 
< #ifdef DEBUG_brendan
< #define DEBUG_SFTBL
< #endif
< #ifdef DEBUG_SFTBL
< size_t sftbl_savings = 0;
< #endif
< 
< static ScriptFilenameEntry *
< SaveScriptFilename(JSRuntime *rt, const char *filename, uint32 flags)
< {
<     JSHashTable *table;
<     JSHashNumber hash;
<     JSHashEntry **hep;
<     ScriptFilenameEntry *sfe;
<     size_t length;
<     JSCList *head, *link;
<     ScriptFilenamePrefix *sfp;
< 
<     table = rt->scriptFilenameTable;
<     hash = JS_HashString(filename);
<     hep = JS_HashTableRawLookup(table, hash, filename);
<     sfe = (ScriptFilenameEntry *) *hep;
< #ifdef DEBUG_SFTBL
<     if (sfe)
<         sftbl_savings += strlen(sfe->filename);
< #endif
< 
<     if (!sfe) {
<         sfe = (ScriptFilenameEntry *)
<               JS_HashTableRawAdd(table, hep, hash, filename, NULL);
<         if (!sfe)
<             return NULL;
<         sfe->key = strcpy(sfe->filename, filename);
<         sfe->flags = 0;
<         sfe->mark = JS_FALSE;
<     }
< 
<     /* If saving a prefix, add it to the set in rt->scriptFilenamePrefixes. */
<     if (flags != 0) {
<         /* Search in case filename was saved already; we must be idempotent. */
<         sfp = NULL;
<         length = strlen(filename);
<         for (head = link = &rt->scriptFilenamePrefixes;
<              link->next != head;
<              link = link->next) {
<             /* Lag link behind sfp to insert in non-increasing length order. */
<             sfp = (ScriptFilenamePrefix *) link->next;
<             if (!strcmp(sfp->name, filename))
<                 break;
<             if (sfp->length <= length) {
<                 sfp = NULL;
<                 break;
<             }
<             sfp = NULL;
<         }
< 
<         if (!sfp) {
<             /* No such prefix: add one now. */
<             sfp = (ScriptFilenamePrefix *) malloc(sizeof(ScriptFilenamePrefix));
<             if (!sfp)
<                 return NULL;
<             JS_INSERT_AFTER(&sfp->links, link);
<             sfp->name = sfe->filename;
<             sfp->length = length;
<             sfp->flags = 0;
<         }
< 
<         /*
<          * Accumulate flags in both sfe and sfp: sfe for later access from the
<          * JS_GetScriptedCallerFilenameFlags debug-API, and sfp so that longer
<          * filename entries can inherit by prefix.
<          */
<         sfe->flags |= flags;
<         sfp->flags |= flags;
<     }
< 
<     return sfe;
< }
< 
< const char *
< js_SaveScriptFilename(JSContext *cx, const char *filename)
< {
<     JSRuntime *rt;
<     ScriptFilenameEntry *sfe;
<     JSCList *head, *link;
<     ScriptFilenamePrefix *sfp;
< 
<     rt = cx->runtime;
<     JS_ACQUIRE_LOCK(rt->scriptFilenameTableLock);
<     sfe = SaveScriptFilename(rt, filename, 0);
<     if (!sfe) {
<         JS_RELEASE_LOCK(rt->scriptFilenameTableLock);
<         JS_ReportOutOfMemory(cx);
<         return NULL;
<     }
< 
<     /*
<      * Try to inherit flags by prefix.  We assume there won't be more than a
<      * few (dozen! ;-) prefixes, so linear search is tolerable.
<      * XXXbe every time I've assumed that in the JS engine, I've been wrong!
<      */
<     for (head = &rt->scriptFilenamePrefixes, link = head->next;
<          link != head;
<          link = link->next) {
<         sfp = (ScriptFilenamePrefix *) link;
<         if (!strncmp(sfp->name, filename, sfp->length)) {
<             sfe->flags |= sfp->flags;
<             break;
<         }
<     }
<     JS_RELEASE_LOCK(rt->scriptFilenameTableLock);
<     return sfe->filename;
< }
< 
< const char *
< js_SaveScriptFilenameRT(JSRuntime *rt, const char *filename, uint32 flags)
< {
<     ScriptFilenameEntry *sfe;
< 
<     /* This may be called very early, via the jsdbgapi.h entry point. */
<     if (!rt->scriptFilenameTable && !js_InitRuntimeScriptState(rt))
<         return NULL;
< 
<     JS_ACQUIRE_LOCK(rt->scriptFilenameTableLock);
<     sfe = SaveScriptFilename(rt, filename, flags);
<     JS_RELEASE_LOCK(rt->scriptFilenameTableLock);
<     if (!sfe)
<         return NULL;
< 
<     return sfe->filename;
< }
< 
< /*
<  * Back up from a saved filename by its offset within its hash table entry.
<  */
< #define FILENAME_TO_SFE(fn) \
<     ((ScriptFilenameEntry *) ((fn) - offsetof(ScriptFilenameEntry, filename)))
< 
< /*
<  * The sfe->key member, redundant given sfe->filename but required by the old
<  * jshash.c code, here gives us a useful sanity check.  This assertion will
<  * very likely botch if someone tries to mark a string that wasn't allocated
<  * as an sfe->filename.
<  */
< #define ASSERT_VALID_SFE(sfe)   JS_ASSERT((sfe)->key == (sfe)->filename)
< 
< uint32
< js_GetScriptFilenameFlags(const char *filename)
< {
<     ScriptFilenameEntry *sfe;
< 
<     sfe = FILENAME_TO_SFE(filename);
<     ASSERT_VALID_SFE(sfe);
<     return sfe->flags;
< }
< 
< void
< js_MarkScriptFilename(const char *filename)
< {
<     ScriptFilenameEntry *sfe;
< 
<     sfe = FILENAME_TO_SFE(filename);
<     ASSERT_VALID_SFE(sfe);
<     sfe->mark = JS_TRUE;
< }
< 
< JS_STATIC_DLL_CALLBACK(intN)
< js_script_filename_marker(JSHashEntry *he, intN i, void *arg)
< {
<     ScriptFilenameEntry *sfe = (ScriptFilenameEntry *) he;
< 
<     sfe->mark = JS_TRUE;
<     return HT_ENUMERATE_NEXT;
< }
< 
< void
< js_MarkScriptFilenames(JSRuntime *rt, JSBool keepAtoms)
< {
<     JSCList *head, *link;
<     ScriptFilenamePrefix *sfp;
< 
<     if (!rt->scriptFilenameTable)
<         return;
< 
<     if (keepAtoms) {
<         JS_HashTableEnumerateEntries(rt->scriptFilenameTable,
<                                      js_script_filename_marker,
<                                      rt);
<     }
<     for (head = &rt->scriptFilenamePrefixes, link = head->next;
<          link != head;
<          link = link->next) {
<         sfp = (ScriptFilenamePrefix *) link;
<         js_MarkScriptFilename(sfp->name);
<     }
< }
< 
< JS_STATIC_DLL_CALLBACK(intN)
< js_script_filename_sweeper(JSHashEntry *he, intN i, void *arg)
< {
<     ScriptFilenameEntry *sfe = (ScriptFilenameEntry *) he;
< 
<     if (!sfe->mark)
<         return HT_ENUMERATE_REMOVE;
<     sfe->mark = JS_FALSE;
<     return HT_ENUMERATE_NEXT;
< }
< 
< void
< js_SweepScriptFilenames(JSRuntime *rt)
< {
<     if (!rt->scriptFilenameTable)
<         return;
< 
<     JS_HashTableEnumerateEntries(rt->scriptFilenameTable,
<                                  js_script_filename_sweeper,
<                                  rt);
< #ifdef DEBUG_notme
< #ifdef DEBUG_SFTBL
<     printf("script filename table savings so far: %u\n", sftbl_savings);
< #endif
< #endif
< }
< 
< /*
<  * JSScript data structures memory alignment:
<  *
<  * JSScript
<  * JSObjectArray    script objects' descriptor if JSScript.objectsOffset != 0,
<  *                    use JS_SCRIPT_OBJECTS(script) macro to access it.
<  * JSObjectArray    script regexps' descriptor if JSScript.regexpsOffset != 0,
<  *                    use JS_SCRIPT_REGEXPS(script) macro to access it.
<  * JSTryNoteArray   script try notes' descriptor if JSScript.tryNotesOffset
<  *                    != 0, use JS_SCRIPT_TRYNOTES(script) macro to access it.
<  * JSAtom *a[]      array of JSScript.atomMap.length atoms pointed by
<  *                    JSScript.atomMap.vector if any.
<  * JSObject *o[]    array of JS_SCRIPT_OBJECTS(script)->length objects if any
<  *                    pointed by JS_SCRIPT_OBJECTS(script)->vector.
<  * JSObject *r[]    array of JS_SCRIPT_REGEXPS(script)->length regexps if any
<  *                    pointed by JS_SCRIPT_REGEXPS(script)->vector.
<  * JSTryNote t[]    array of JS_SCRIPT_TRYNOTES(script)->length try notes if any
<  *                    pointed by JS_SCRIPT_TRYNOTES(script)->vector.
<  * jsbytecode b[]   script bytecode pointed by JSScript.code.
<  * jssrcnote  s[]   script source notes, use SCRIPT_NOTES(script) to access it
<  *
<  * The alignment avoids gaps between entries as alignment requirement for each
<  * subsequent structure or array is the same or divides the alignment
<  * requirement for the previous one.
<  *
<  * The followings asserts checks that assuming that the alignment requirement
<  * for JSObjectArray and JSTryNoteArray are sizeof(void *) and for JSTryNote
<  * it is sizeof(uint32) as the structure consists of 3 uint32 fields.
<  */
< JS_STATIC_ASSERT(sizeof(JSScript) % sizeof(void *) == 0);
< JS_STATIC_ASSERT(sizeof(JSObjectArray) % sizeof(void *) == 0);
< JS_STATIC_ASSERT(sizeof(JSTryNoteArray) == sizeof(JSObjectArray));
< JS_STATIC_ASSERT(sizeof(JSAtom *) == sizeof(JSObject *));
< JS_STATIC_ASSERT(sizeof(JSObject *) % sizeof(uint32) == 0);
< JS_STATIC_ASSERT(sizeof(JSTryNote) == 3 * sizeof(uint32));
< JS_STATIC_ASSERT(sizeof(uint32) % sizeof(jsbytecode) == 0);
< JS_STATIC_ASSERT(sizeof(jsbytecode) % sizeof(jssrcnote) == 0);
< 
< /*
<  * Check that uint8 offset for object, regexp and try note arrays is sufficient.
<  */
< JS_STATIC_ASSERT(sizeof(JSScript) + 2 * sizeof(JSObjectArray) < JS_BIT(8));
< 
1312,1313c748
< js_NewScript(JSContext *cx, uint32 length, uint32 nsrcnotes, uint32 natoms,
<              uint32 nobjects, uint32 nregexps, uint32 ntrynotes)
---
> js_NewScript(JSContext *cx, uint32 length)
1315d749
<     size_t size, vectorSize;
1317,1328d750
<     uint8 *cursor;
< 
<     size = sizeof(JSScript) +
<            sizeof(JSAtom *) * natoms +
<            length * sizeof(jsbytecode) +
<            nsrcnotes * sizeof(jssrcnote);
<     if (nobjects != 0)
<         size += sizeof(JSObjectArray) + nobjects * sizeof(JSObject *);
<     if (nregexps != 0)
<         size += sizeof(JSObjectArray) + nregexps * sizeof(JSObject *);
<     if (ntrynotes != 0)
<         size += sizeof(JSTryNoteArray) + ntrynotes * sizeof(JSTryNote);
1330c752,754
<     script = (JSScript *) JS_malloc(cx, size);
---
> 	XMEMTAG("jsscript js_NewScript");
>     script = (JSScript *)
>         JS_malloc(cx, sizeof(JSScript) + length * sizeof(jsbytecode));
1333a758
>     script->code = script->main = (jsbytecode *)(script + 1);
1336,1395d760
< 
<     cursor = (uint8 *)script + sizeof(JSScript);
<     if (nobjects != 0) {
<         script->objectsOffset = (uint8)(cursor - (uint8 *)script);
<         cursor += sizeof(JSObjectArray);
<     }
<     if (nregexps != 0) {
<         script->regexpsOffset = (uint8)(cursor - (uint8 *)script);
<         cursor += sizeof(JSObjectArray);
<     }
<     if (ntrynotes != 0) {
<         script->trynotesOffset = (uint8)(cursor - (uint8 *)script);
<         cursor += sizeof(JSTryNoteArray);
<     }
< 
<     if (natoms != 0) {
<         script->atomMap.length = natoms;
<         script->atomMap.vector = (JSAtom **)cursor;
<         vectorSize = natoms * sizeof(script->atomMap.vector[0]);
< 
<         /*
<          * Clear object map's vector so the GC tracing can run when not yet
<          * all atoms are copied to the array.
<          */
<         memset(cursor, 0, vectorSize);
<         cursor += vectorSize;
<     }
<     if (nobjects != 0) {
<         JS_SCRIPT_OBJECTS(script)->length = nobjects;
<         JS_SCRIPT_OBJECTS(script)->vector = (JSObject **)cursor;
<         vectorSize = nobjects * sizeof(JS_SCRIPT_OBJECTS(script)->vector[0]);
<         memset(cursor, 0, vectorSize);
<         cursor += vectorSize;
<     }
<     if (nregexps != 0) {
<         JS_SCRIPT_REGEXPS(script)->length = nregexps;
<         JS_SCRIPT_REGEXPS(script)->vector = (JSObject **)cursor;
<         vectorSize = nregexps * sizeof(JS_SCRIPT_REGEXPS(script)->vector[0]);
<         memset(cursor, 0, vectorSize);
<         cursor += vectorSize;
<     }
<     if (ntrynotes != 0) {
<         JS_SCRIPT_TRYNOTES(script)->length = ntrynotes;
<         JS_SCRIPT_TRYNOTES(script)->vector = (JSTryNote *)cursor;
<         vectorSize = ntrynotes * sizeof(JS_SCRIPT_TRYNOTES(script)->vector[0]);
< #ifdef DEBUG
<         memset(cursor, 0, vectorSize);
< #endif
<         cursor += vectorSize;
<     }
< 
<     script->code = script->main = (jsbytecode *)cursor;
<     JS_ASSERT(cursor +
<               length * sizeof(jsbytecode) +
<               nsrcnotes * sizeof(jssrcnote) ==
<               (uint8 *)script + size);
< 
< #ifdef CHECK_SCRIPT_OWNER
<     script->owner = cx->thread;
< #endif
1400c765,769
< js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg)
---
> js_NewScriptFromParams(JSContext *cx, jsbytecode *code, uint32 length,
>                        jsbytecode *prolog, uint32 prologLength,
>                        const char *filename, uintN lineno, uintN depth,
>                        jssrcnote *notes, JSTryNote *trynotes,
>                        JSPrincipals *principals)
1402d770
<     uint32 mainLength, prologLength, nsrcnotes;
1404,1405d771
<     const char *filename;
<     JSFunction *fun;
1407,1417c773
<     /* The counts of indexed things must be checked during code generation. */
<     JS_ASSERT(cg->atomList.count <= INDEX_LIMIT);
<     JS_ASSERT(cg->objectList.length <= INDEX_LIMIT);
<     JS_ASSERT(cg->regexpList.length <= INDEX_LIMIT);
< 
<     mainLength = CG_OFFSET(cg);
<     prologLength = CG_PROLOG_OFFSET(cg);
<     CG_COUNT_FINAL_SRCNOTES(cg, nsrcnotes);
<     script = js_NewScript(cx, prologLength + mainLength, nsrcnotes,
<                           cg->atomList.count, cg->objectList.length,
<                           cg->regexpList.length, cg->ntrynotes);
---
>     script = js_NewScript(cx, prologLength + length);
1420,1421d775
< 
<     /* Now that we have script, error control flow must go to label bad. */
1423,1429c777,778
<     memcpy(script->code, CG_PROLOG_BASE(cg), prologLength * sizeof(jsbytecode));
<     memcpy(script->main, CG_BASE(cg), mainLength * sizeof(jsbytecode));
<     script->ngvars = cg->treeContext.ngvars;
< 
<     js_InitAtomMap(cx, &script->atomMap, &cg->atomList);
< 
<     filename = cg->treeContext.parseContext->tokenStream.filename;
---
>     memcpy(script->code, prolog, prologLength * sizeof(jsbytecode));
>     memcpy(script->main, code, length * sizeof(jsbytecode));
1431,1439c780,794
<         script->filename = js_SaveScriptFilename(cx, filename);
<         if (!script->filename)
<             goto bad;
<     }
<     script->lineno = cg->firstLine;
<     script->depth = cg->maxStackDepth;
<     script->principals = cg->treeContext.parseContext->principals;
<     if (script->principals)
<         JSPRINCIPALS_HOLD(cx, script->principals);
---
>         script->filename = JS_strdup(cx, filename);
>         if (!script->filename) {
>             js_DestroyScript(cx, script);
>             return NULL;
>         }
>     }
>     script->lineno = lineno;
>     script->depth = depth;
>     script->notes = notes;
>     script->trynotes = trynotes;
>     if (principals)
>         JSPRINCIPALS_HOLD(cx, principals);
>     script->principals = principals;
>     return script;
> }
1441,1448c796,801
<     if (!js_FinishTakingSrcNotes(cx, cg, SCRIPT_NOTES(script)))
<         goto bad;
<     if (cg->ntrynotes != 0)
<         js_FinishTakingTryNotes(cg, JS_SCRIPT_TRYNOTES(script));
<     if (cg->objectList.length != 0)
<         FinishParsedObjects(&cg->objectList, JS_SCRIPT_OBJECTS(script));
<     if (cg->regexpList.length != 0)
<         FinishParsedObjects(&cg->regexpList, JS_SCRIPT_REGEXPS(script));
---
> JS_FRIEND_API(JSScript *)
> js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg, JSFunction *fun)
> {
>     JSTryNote *trynotes;
>     jssrcnote *notes;
>     JSScript *script;
1450,1466c803,815
<     /*
<      * We initialize fun->u.script to be the script constructed above
<      * so that the debugger has a valid FUN_SCRIPT(fun).
<      */
<     fun = NULL;
<     if (cg->treeContext.flags & TCF_IN_FUNCTION) {
<         fun = cg->treeContext.fun;
<         JS_ASSERT(FUN_INTERPRETED(fun) && !FUN_SCRIPT(fun));
<         js_FreezeLocalNames(cx, fun);
<         fun->u.i.script = script;
< #ifdef CHECK_SCRIPT_OWNER
<         script->owner = NULL;
< #endif
<         if (cg->treeContext.flags & TCF_FUN_HEAVYWEIGHT)
<             fun->flags |= JSFUN_HEAVYWEIGHT;
<         if (fun->flags & JSFUN_HEAVYWEIGHT)
<             ++cg->treeContext.maxScopeDepth;
---
>     if (!js_FinishTakingTryNotes(cx, cg, &trynotes))
>         return NULL;
>     notes = js_FinishTakingSrcNotes(cx, cg);
>     script = js_NewScriptFromParams(cx, CG_BASE(cg), CG_OFFSET(cg),
>                                     CG_PROLOG_BASE(cg), CG_PROLOG_OFFSET(cg),
>                                     cg->filename, cg->firstLine,
>                                     cg->maxStackDepth, notes, trynotes,
>                                     cg->principals);
>     if (!script)
>         return NULL;
>     if (!notes || !js_InitAtomMap(cx, &script->atomMap, &cg->atomList)) {
>         js_DestroyScript(cx, script);
>         return NULL;
1469,1473d817
< #ifdef JS_SCOPE_DEPTH_METER
<     JS_BASIC_STATS_ACCUM(&cx->runtime->lexicalScopeDepthStats,
<                          cg->treeContext.maxScopeDepth);
< #endif
< 
1477,1480d820
< 
< bad:
<     js_DestroyScript(cx, script);
<     return NULL;
1485a826
>     JSRuntime *rt;
1488c829,830
<     hook = cx->debugHooks->newScriptHook;
---
>     rt = cx->runtime;
>     hook = rt->newScriptHook;
1490c832,846
<         JS_KEEP_ATOMS(cx->runtime);
---
>         /*
>          * We use a dummy stack frame to protect the script from a GC caused
>          * by debugger-hook execution.
>          *
>          * XXX We really need a way to manage local roots and such more
>          * XXX automatically, at which point we can remove this one-off hack
>          * XXX and others within the engine.  See bug 40757 for discussion.
>          */
>         JSStackFrame dummy;
>         
>         memset(&dummy, 0, sizeof dummy);
>         dummy.down = cx->fp;
>         dummy.script = script;
>         cx->fp = &dummy;
> 
1492,1493c848,850
<              cx->debugHooks->newScriptHookData);
<         JS_UNKEEP_ATOMS(cx->runtime);
---
>              rt->newScriptHookData);
> 
>         cx->fp = dummy.down;
1497,1498c854,855
< JS_FRIEND_API(void)
< js_CallDestroyScriptHook(JSContext *cx, JSScript *script)
---
> void
> js_DestroyScript(JSContext *cx, JSScript *script)
1499a857
>     JSRuntime *rt;
1502c860,861
<     hook = cx->debugHooks->destroyScriptHook;
---
>     rt = cx->runtime;
>     hook = rt->destroyScriptHook;
1504,1505c863
<         hook(cx, script, cx->debugHooks->destroyScriptHookData);
< }
---
>         (*hook)(cx, script, rt->destroyScriptHookData);
1507,1510d864
< void
< js_DestroyScript(JSContext *cx, JSScript *script)
< {
<     js_CallDestroyScriptHook(cx, script);
1512c866,869
< 
---
>     js_FreeAtomMap(cx, &script->atomMap);
>     JS_free(cx, (void *)script->filename);
>     JS_free(cx, script->notes);
>     JS_free(cx, script->trynotes);
1515,1544d871
< 
<     if (JS_GSN_CACHE(cx).script == script)
<         JS_CLEAR_GSN_CACHE(cx);
< 
<     /*
<      * The GC flushes all property caches, so no need to purge just the
<      * entries for this script.
<      *
<      * JS_THREADSAFE note: js_FlushPropertyCacheForScript flushes only the
<      * current thread's property cache, so a script not owned by a function
<      * or object, which hands off lifetime management for that script to the
<      * GC, must be used by only one thread over its lifetime.
<      *
<      * This should be an API-compatible change, since a script is never safe
<      * against premature GC if shared among threads without a rooted object
<      * wrapping it to protect the script's mapped atoms against GC. We use
<      * script->owner to enforce this requirement via assertions.
<      */
< #ifdef CHECK_SCRIPT_OWNER
<     JS_ASSERT_IF(cx->runtime->gcRunning, !script->owner);
< #endif
< 
<     if (!cx->runtime->gcRunning &&
<         !(cx->fp && (cx->fp->flags & JSFRAME_EVAL))) {
< #ifdef CHECK_SCRIPT_OWNER
<         JS_ASSERT(script->owner == cx->thread);
< #endif
<         js_FlushPropertyCacheForScript(cx, script);
<     }
< 
1549c876
< js_TraceScript(JSTracer *trc, JSScript *script)
---
> js_MarkScript(JSContext *cx, JSScript *script, void *arg)
1554,1555d880
<     jsval v;
<     JSObjectArray *objarray;
1560,1593c885,886
<     for (i = 0; i < length; i++) {
<         v = ATOM_KEY(vector[i]);
<         if (JSVAL_IS_TRACEABLE(v)) {
<             JS_SET_TRACING_INDEX(trc, "atomMap", i);
<             JS_CallTracer(trc, JSVAL_TO_TRACEABLE(v), JSVAL_TRACE_KIND(v));
<         }
<     }
< 
<     if (script->objectsOffset != 0) {
<         objarray = JS_SCRIPT_OBJECTS(script);
<         i = objarray->length;
<         do {
<             --i;
<             if (objarray->vector[i]) {
<                 JS_SET_TRACING_INDEX(trc, "objects", i);
<                 JS_CallTracer(trc, objarray->vector[i], JSTRACE_OBJECT);
<             }
<         } while (i != 0);
<     }
< 
<     if (script->regexpsOffset != 0) {
<         objarray = JS_SCRIPT_REGEXPS(script);
<         i = objarray->length;
<         do {
<             --i;
<             if (objarray->vector[i]) {
<                 JS_SET_TRACING_INDEX(trc, "regexps", i);
<                 JS_CallTracer(trc, objarray->vector[i], JSTRACE_OBJECT);
<             }
<         } while (i != 0);
<     }
< 
<     if (IS_GC_MARKING_TRACER(trc) && script->filename)
<         js_MarkScriptFilename(script->filename);
---
>     for (i = 0; i < length; i++)
>         GC_MARK_ATOM(cx, vector[i], arg);
1596,1603d888
< typedef struct GSNCacheEntry {
<     JSDHashEntryHdr     hdr;
<     jsbytecode          *pc;
<     jssrcnote           *sn;
< } GSNCacheEntry;
< 
< #define GSN_CACHE_THRESHOLD     100
< 
1605c890
< js_GetSrcNoteCached(JSContext *cx, JSScript *script, jsbytecode *pc)
---
> js_GetSrcNote(JSScript *script, jsbytecode *pc)
1607,1611c892,893
<     ptrdiff_t target, offset;
<     GSNCacheEntry *entry;
<     jssrcnote *sn, *result;
<     uintN nsrcnotes;
< 
---
>     jssrcnote *sn;
>     ptrdiff_t offset, target;
1613,1614c895,896
<     target = PTRDIFF(pc, script->code, jsbytecode);
<     if ((uint32)target >= script->length)
---
>     sn = script->notes;
>     if (!sn)
1616,1631c898,901
< 
<     if (JS_GSN_CACHE(cx).script == script) {
<         JS_METER_GSN_CACHE(cx, hits);
<         entry = (GSNCacheEntry *)
<                 JS_DHashTableOperate(&JS_GSN_CACHE(cx).table, pc,
<                                      JS_DHASH_LOOKUP);
<         return entry->sn;
<     }
< 
<     JS_METER_GSN_CACHE(cx, misses);
<     offset = 0;
<     for (sn = SCRIPT_NOTES(script); ; sn = SN_NEXT(sn)) {
<         if (SN_IS_TERMINATOR(sn)) {
<             result = NULL;
<             break;
<         }
---
>     target = PTRDIFF(pc, script->main, jsbytecode);
>     if ((uintN)target >= script->length)
>         return NULL;
>     for (offset = 0; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) {
1633,1636c903,904
<         if (offset == target && SN_IS_GETTABLE(sn)) {
<             result = sn;
<             break;
<         }
---
>         if (offset == target && SN_IS_GETTABLE(sn))
>             return sn;
1638,1670c906
< 
<     if (JS_GSN_CACHE(cx).script != script &&
<         script->length >= GSN_CACHE_THRESHOLD) {
<         JS_CLEAR_GSN_CACHE(cx);
<         nsrcnotes = 0;
<         for (sn = SCRIPT_NOTES(script); !SN_IS_TERMINATOR(sn);
<              sn = SN_NEXT(sn)) {
<             if (SN_IS_GETTABLE(sn))
<                 ++nsrcnotes;
<         }
<         if (!JS_DHashTableInit(&JS_GSN_CACHE(cx).table, JS_DHashGetStubOps(),
<                                NULL, sizeof(GSNCacheEntry),
<                                JS_DHASH_DEFAULT_CAPACITY(nsrcnotes))) {
<             JS_GSN_CACHE(cx).table.ops = NULL;
<         } else {
<             pc = script->code;
<             for (sn = SCRIPT_NOTES(script); !SN_IS_TERMINATOR(sn);
<                  sn = SN_NEXT(sn)) {
<                 pc += SN_DELTA(sn);
<                 if (SN_IS_GETTABLE(sn)) {
<                     entry = (GSNCacheEntry *)
<                             JS_DHashTableOperate(&JS_GSN_CACHE(cx).table, pc,
<                                                  JS_DHASH_ADD);
<                     entry->pc = pc;
<                     entry->sn = sn;
<                 }
<             }
<             JS_GSN_CACHE(cx).script = script;
<             JS_METER_GSN_CACHE(cx, fills);
<         }
<     }
< 
<     return result;
---
>     return NULL;
1674c910
< js_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc)
---
> js_PCToLineNumber(JSScript *script, jsbytecode *pc)
1676,1679d911
<     JSObject *obj;
<     JSFunction *fun;
<     uintN lineno;
<     ptrdiff_t offset, target;
1680a913,914
>     ptrdiff_t offset, target;
>     uintN lineno;
1683,1684c917,918
<     /* Cope with JSStackFrame.pc value prior to entering js_Interpret. */
<     if (!pc)
---
>     sn = script->notes;
>     if (!sn)
1686,1704c920
< 
<     /*
<      * Special case: function definition needs no line number note because
<      * the function's script contains its starting line number.
<      */
<     if (js_CodeSpec[*pc].format & JOF_INDEXBASE)
<         pc += js_CodeSpec[*pc].length;
<     if (*pc == JSOP_DEFFUN) {
<         GET_FUNCTION_FROM_BYTECODE(script, pc, 0, obj);
<         fun = GET_FUNCTION_PRIVATE(cx, obj);
<         JS_ASSERT(FUN_INTERPRETED(fun));
<         return fun->u.i.script->lineno;
<     }
< 
<     /*
<      * General case: walk through source notes accumulating their deltas,
<      * keeping track of line-number notes, until we pass the note for pc's
<      * offset within script->code.
<      */
---
>     target = PTRDIFF(pc, script->main, jsbytecode);
1706,1708c922
<     offset = 0;
<     target = PTRDIFF(pc, script->code, jsbytecode);
<     for (sn = SCRIPT_NOTES(script); !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) {
---
>     for (offset = 0; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) {
1724,1726d937
< /* The line number limit is the same as the jssrcnote offset limit. */
< #define SN_LINE_LIMIT   (SN_3BYTE_OFFSET_FLAG << 16)
< 
1730,1731d940
<     ptrdiff_t offset, best;
<     uintN lineno, bestdiff, diff;
1732a942,943
>     uintN lineno;
>     ptrdiff_t offset;
1735,1736c946,948
<     offset = 0;
<     best = -1;
---
>     sn = script->notes;
>     if (!sn)
>         return NULL;
1738,1752c950,952
<     bestdiff = SN_LINE_LIMIT;
<     for (sn = SCRIPT_NOTES(script); !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) {
<         /*
<          * Exact-match only if offset is not in the prolog; otherwise use
<          * nearest greater-or-equal line number match.
<          */
<         if (lineno == target && script->code + offset >= script->main)
<             goto out;
<         if (lineno >= target) {
<             diff = lineno - target;
<             if (diff < bestdiff) {
<                 bestdiff = diff;
<                 best = offset;
<             }
<         }
---
>     for (offset = 0; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) {
>         if (lineno >= target)
>             break;
1761,1764c961
<     if (best >= 0)
<         offset = best;
< out:
<     return script->code + offset;
---
>     return script->main + offset;
1767c964
< JS_FRIEND_API(uintN)
---
> uintN
1770d966
<     uintN lineno;
1771a968
>     uintN lineno;
1773a971,973
>     sn = script->notes;
>     if (!sn)
>         return 0;
1775c975
<     for (sn = SCRIPT_NOTES(script); !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) {
---
>     for (; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) {
1785,1816d984
< 
< #if JS_HAS_GENERATORS
< 
< JSBool
< js_IsInsideTryWithFinally(JSScript *script, jsbytecode *pc)
< {
<     JSTryNoteArray *tarray;
<     JSTryNote *tn, *tnlimit;
<     uint32 off;
< 
<     JS_ASSERT(script->code <= pc);
<     JS_ASSERT(pc < script->code + script->length);
< 
<     if (!script->trynotesOffset != 0)
<         return JS_FALSE;
<     tarray = JS_SCRIPT_TRYNOTES(script);
<     JS_ASSERT(tarray->length != 0);
< 
<     tn = tarray->vector;
<     tnlimit = tn + tarray->length;
<     off = (uint32)(pc - script->main);
<     do {
<         if (off - tn->start < tn->length) {
<             if (tn->kind == JSTN_FINALLY)
<                 return JS_TRUE;
<             JS_ASSERT(tn->kind == JSTN_CATCH);
<         }
<     } while (++tn != tnlimit);
<     return JS_FALSE;
< }
< 
< #endif
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsscript.h /Volumes/Swap/js_D11/src/jsscript.h
2d1
<  * vim: set ts=8 sw=4 et tw=78:
4,15c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
20,39c16,33
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
52,62c46,50
<  * Type of try note associated with each catch or finally block or with for-in
<  * loop.
<  */
< typedef enum JSTryNoteKind {
<     JSTN_CATCH,
<     JSTN_FINALLY,
<     JSTN_ITER
< } JSTryNoteKind;
< 
< /*
<  * Exception handling record.
---
>  * Exception handling runtime information.
>  *
>  * All fields except length are code offsets, relative to the beginning of
>  * the script.  If script->trynotes is not null, it points to a vector of
>  * these structs terminated by one with catchStart == 0.
65,70c53,55
<     uint8           kind;       /* one of JSTryNoteKind */
<     uint8           padding;    /* explicit padding on uint16 boundary */
<     uint16          stackDepth; /* stack depth upon exception handler entry */
<     uint32          start;      /* start of the try statement or for-in loop
<                                    relative to script->main */
<     uint32          length;     /* length of the try statement or for-in loop */
---
>     ptrdiff_t    start;         /* start of try statement */
>     ptrdiff_t    length;        /* count of try statement bytecodes */
>     ptrdiff_t    catchStart;    /* start of catch block (0 if end) */
73,89d57
< typedef struct JSTryNoteArray {
<     JSTryNote       *vector;    /* array of indexed try notes */
<     uint32          length;     /* count of indexded try notes */
< } JSTryNoteArray;
< 
< typedef struct JSObjectArray {
<     JSObject        **vector;   /* array of indexed objects */
<     uint32          length;     /* count of indexded objects */
< } JSObjectArray;
< 
< #define JS_OBJECT_ARRAY_SIZE(length)                                          \
<     (offsetof(JSObjectArray, vector) + sizeof(JSObject *) * (length))
< 
< #if defined DEBUG && defined JS_THREADSAFE
< # define CHECK_SCRIPT_OWNER 1
< #endif
< 
91,111c59,74
<     jsbytecode      *code;      /* bytecodes and their immediate operands */
<     uint32          length;     /* length of code vector */
<     uint16          version;    /* JS version under which script was compiled */
<     uint16          ngvars;     /* declared global var/const/function count */
<     uint8           objectsOffset;  /* offset to the array of nested function,
<                                        block, scope, xml and one-time regexps
<                                        objects or 0 if none */
<     uint8           regexpsOffset;  /* offset to the array of to-be-cloned
<                                        regexps or 0 if none. */
<     uint8           trynotesOffset; /* offset to the array of try notes or
<                                        0 if none */
<     jsbytecode      *main;      /* main entry point, after predef'ing prolog */
<     JSAtomMap       atomMap;    /* maps immediate index to literal struct */
<     const char      *filename;  /* source filename or null */
<     uintN           lineno;     /* base line number of script */
<     uintN           depth;      /* maximum stack depth in slots */
<     JSPrincipals    *principals;/* principals for this script */
<     JSObject        *object;    /* optional Script-class object wrapper */
< #ifdef CHECK_SCRIPT_OWNER
<     JSThread        *owner;     /* for thread-safe life-cycle assertions */
< #endif
---
>     jsbytecode   *code;         /* bytecodes and their immediate operands */
>     uint32       length;        /* length of code vector */
>     jsbytecode   *main;         /* main entry point, after predef'ing prolog */
>     JSVersion    version;       /* JS version under which script was compiled */
>     JSAtomMap    atomMap;       /* maps immediate index to literal struct */
>     const char   *filename;     /* source filename or null */
>     uintN        lineno;        /* base line number of script */
>     uintN        depth;         /* maximum stack depth in slots */
>     jssrcnote    *notes;        /* line number and other decompiling data */
>     JSTryNote    *trynotes;     /* exception table for this script */
>     JSPrincipals *principals;   /* principals for this script */
>     JSObject     *object;       /* optional Script-class object wrapper */
>     #if 1 // !!dp
>     void		*lscript;		// Reference to lingo script
>     int			imeth;			// Method in lingo script.
>     #endif
114,129c77
< /* No need to store script->notes now that it is allocated right after code. */
< #define SCRIPT_NOTES(script)    ((jssrcnote*)((script)->code+(script)->length))
< 
< #define JS_SCRIPT_OBJECTS(script)                                             \
<     (JS_ASSERT((script)->objectsOffset != 0),                                 \
<      (JSObjectArray *)((uint8 *)(script) + (script)->objectsOffset))
< 
< #define JS_SCRIPT_REGEXPS(script)                                             \
<     (JS_ASSERT((script)->regexpsOffset != 0),                                 \
<      (JSObjectArray *)((uint8 *)(script) + (script)->regexpsOffset))
< 
< #define JS_SCRIPT_TRYNOTES(script)                                            \
<     (JS_ASSERT((script)->trynotesOffset != 0),                                \
<      (JSTryNoteArray *)((uint8 *)(script) + (script)->trynotesOffset))
< 
< #define JS_GET_SCRIPT_ATOM(script, index, atom)                               \
---
> #define JSSCRIPT_FIND_CATCH_START(script, pc, catchpc)                        \
131,133c79,88
<         JSAtomMap *atoms_ = &(script)->atomMap;                               \
<         JS_ASSERT((uint32)(index) < atoms_->length);                          \
<         (atom) = atoms_->vector[(index)];                                     \
---
>         JSTryNote *tn_ = (script)->trynotes;                                  \
>         jsbytecode *catchpc_ = NULL;                                          \
>         if (tn_) {                                                            \
>             ptrdiff_t offset_ = PTRDIFF(pc, (script)->main, jsbytecode);      \
>             while (JS_UPTRDIFF(offset_, tn_->start) >= (jsuword)tn_->length)  \
>                 tn_++;                                                        \
>             if (tn_->catchStart)                                              \
>                 catchpc_ = (script)->main + tn_->catchStart;                  \
>         }                                                                     \
>         catchpc = catchpc_;                                                   \
136,158d90
< #define JS_GET_SCRIPT_OBJECT(script, index, obj)                              \
<     JS_BEGIN_MACRO                                                            \
<         JSObjectArray *objects_ = JS_SCRIPT_OBJECTS(script);                  \
<         JS_ASSERT((uint32)(index) < objects_->length);                        \
<         (obj) = objects_->vector[(index)];                                    \
<     JS_END_MACRO
< 
< #define JS_GET_SCRIPT_REGEXP(script, index, obj)                              \
<     JS_BEGIN_MACRO                                                            \
<         JSObjectArray *regexps_ = JS_SCRIPT_REGEXPS(script);                  \
<         JS_ASSERT((uint32)(index) < regexps_->length);                        \
<         (obj) = regexps_->vector[(index)];                                    \
<         JS_ASSERT(STOBJ_GET_CLASS(obj) == &js_RegExpClass);                   \
<     JS_END_MACRO
< 
< /*
<  * Check if pc is inside a try block that has finally code. GC calls this to
<  * check if it is necessary to schedule generator.close() invocation for an
<  * unreachable generator.
<  */
< JSBool
< js_IsInsideTryWithFinally(JSScript *script, jsbytecode *pc);
< 
165,208c97,98
<  * On first new context in rt, initialize script runtime state, specifically
<  * the script filename table and its lock.
<  */
< extern JSBool
< js_InitRuntimeScriptState(JSRuntime *rt);
< 
< /*
<  * On last context destroy for rt, if script filenames are all GC'd, free the
<  * script filename table and its lock.
<  */
< extern void
< js_FinishRuntimeScriptState(JSRuntime *rt);
< 
< /*
<  * On JS_DestroyRuntime(rt), forcibly free script filename prefixes and any
<  * script filename table entries that have not been GC'd, the latter using
<  * js_FinishRuntimeScriptState.
<  *
<  * This allows script filename prefixes to outlive any context in rt.
<  */
< extern void
< js_FreeRuntimeScriptState(JSRuntime *rt);
< 
< extern const char *
< js_SaveScriptFilename(JSContext *cx, const char *filename);
< 
< extern const char *
< js_SaveScriptFilenameRT(JSRuntime *rt, const char *filename, uint32 flags);
< 
< extern uint32
< js_GetScriptFilenameFlags(const char *filename);
< 
< extern void
< js_MarkScriptFilename(const char *filename);
< 
< extern void
< js_MarkScriptFilenames(JSRuntime *rt, JSBool keepAtoms);
< 
< extern void
< js_SweepScriptFilenames(JSRuntime *rt);
< 
< /*
<  * Two successively less primitive ways to make a new JSScript.  The first
<  * does *not* call a non-null cx->runtime->newScriptHook -- only the second,
---
>  * Three successively less primitive ways to make a new JSScript.  The first
>  * two do *not* call a non-null cx->runtime->newScriptHook -- only the last,
218,219c108
< js_NewScript(JSContext *cx, uint32 length, uint32 nsrcnotes, uint32 natoms,
<              uint32 nobjects, uint32 nregexps, uint32 ntrynotes);
---
> js_NewScript(JSContext *cx, uint32 length);
222c111,118
< js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg);
---
> js_NewScriptFromParams(JSContext *cx, jsbytecode *code, uint32 length,
> 		       jsbytecode *prolog, uint32 prologLength,
> 		       const char *filename, uintN lineno, uintN depth,
> 		       jssrcnote *notes, JSTryNote *trynotes,
> 		       JSPrincipals *principals);
> 
> extern JS_FRIEND_API(JSScript *)
> js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg, JSFunction *fun);
233,235d128
< extern JS_FRIEND_API(void)
< js_CallDestroyScriptHook(JSContext *cx, JSScript *script);
< 
240,247c133
< js_TraceScript(JSTracer *trc, JSScript *script);
< 
< /*
<  * To perturb as little code as possible, we introduce a js_GetSrcNote lookup
<  * cache without adding an explicit cx parameter.  Thus js_GetSrcNote becomes
<  * a macro that uses cx from its calls' lexical environments.
<  */
< #define js_GetSrcNote(script,pc) js_GetSrcNoteCached(cx, script, pc)
---
> js_MarkScript(JSContext *cx, JSScript *script, void *arg);
250c136
< js_GetSrcNoteCached(JSContext *cx, JSScript *script, jsbytecode *pc);
---
> js_GetSrcNote(JSScript *script, jsbytecode *pc);
252d137
< /* XXX need cx to lock function objects declared by prolog bytecodes. */
254c139
< js_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc);
---
> js_PCToLineNumber(JSScript *script, jsbytecode *pc);
259c144
< extern JS_FRIEND_API(uintN)
---
> extern uintN
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsshell.msg /Volumes/Swap/js_D11/src/jsshell.msg
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsstddef.h /Volumes/Swap/js_D11/src/jsstddef.h
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Netscape Communications
>  * Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
77c72
<         ((p1) - (p2))
---
> 	((p1) - (p2))
Only in /Volumes/Swap/js-14-2-2008/js/src: jsstr.c
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsstr.h /Volumes/Swap/js_D11/src/jsstr.h
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
49a45,48
>  *
>  * When a string is treated as an object (by following it with . or []), the
>  * runtime wraps it with a JSObject whose valueOf method returns the unwrapped
>  * string descriptor.
53a53
> #include "jshash.h"
58,65c58,62
<  * The GC-thing "string" type.
<  *
<  * When the JSSTRFLAG_DEPENDENT bit of the length field is unset, the u.chars
<  * field points to a flat character array owned by its GC-thing descriptor.
<  * The array is terminated at index length by a zero character and the size of
<  * the array in bytes is (length + 1) * sizeof(jschar). The terminator is
<  * purely a backstop, in case the chars pointer flows out to native code that
<  * requires \u0000 termination.
---
>  * The original GC-thing "string" type, a flat character string owned by its
>  * GC-thing descriptor.  The chars member points to a vector having byte size
>  * (length + 1) * sizeof(jschar), terminated at index length by a zero jschar.
>  * The terminator is purely a backstop, in case the chars pointer flows out to
>  * native code that requires \u0000 termination.
67,92c64,65
<  * A flat string with JSSTRFLAG_MUTABLE set means the string is accessible
<  * only from one thread and it is possible to turn it into a dependent string
<  * of the same length to optimize js_ConcatStrings. It also possible to grow
<  * such string but extreme care must be taken to ensure that no other code
<  * relies on the original length of the string.
<  *
<  * A flat string with JSSTRFLAG_ATOMIZED set means that the string is hashed
<  * as an atom. This flag is used to avoid re-hashing of the already-atomized
<  * string.
<  *
<  * When JSSTRFLAG_DEPENDENT is set, the string depends on characters of
<  * another string strongly referenced by the u.base field. The base member may
<  * point to another dependent string if JSSTRING_CHARS has not been called
<  * yet.
<  *
<  * JSSTRFLAG_PREFIX determines the kind of the dependent string. When the flag
<  * is unset, the length field encodes both starting position relative to the
<  * base string and the number of characters in the dependent string, see
<  * JSSTRDEP_START_MASK and JSSTRDEP_LENGTH_MASK macros below for details.
<  *
<  * When JSSTRFLAG_PREFIX is set, the dependent string is a prefix of the base
<  * string. The number of characters in the prefix is encoded using all
<  * non-flag bits of the length field and spans the same 0 .. SIZE_T_MAX/4
<  * range as the length of the flat string.
<  *
<  * NB: Always use the JSSTRING_LENGTH and JSSTRING_CHARS accessor macros.
---
>  * NB: Always use the JSSTRING_LENGTH and JSSTRING_CHARS accessor macros,
>  * unless you guard str->member uses with !JSSTRING_IS_DEPENDENT(str).
96,99c69
<     union {
<         jschar      *chars;
<         JSString    *base;
<     } u;
---
>     jschar          *chars;
103,112c73,84
<  * Definitions for flags stored in the high order bits of JSString.length.
<  * JSSTRFLAG_PREFIX and JSSTRFLAG_MUTABLE are two aliases for the same value.
<  * JSSTRFLAG_PREFIX should be used only if JSSTRFLAG_DEPENDENT is set and
<  * JSSTRFLAG_MUTABLE should be used only if the string is flat.
<  * JSSTRFLAG_ATOMIZED is used only with the flat immutable strings.
<  */
< #define JSSTRFLAG_DEPENDENT         JSSTRING_BIT(JS_BITS_PER_WORD - 1)
< #define JSSTRFLAG_PREFIX            JSSTRING_BIT(JS_BITS_PER_WORD - 2)
< #define JSSTRFLAG_MUTABLE           JSSTRFLAG_PREFIX
< #define JSSTRFLAG_ATOMIZED          JSSTRING_BIT(JS_BITS_PER_WORD - 3)
---
>  * Overlay structure for a string that depends on another string's characters.
>  * Distinguished by the JSSTRFLAG_DEPENDENT bit being set in length.  The base
>  * member may point to another dependent string if JSSTRING_CHARS has not been
>  * called yet.  The length chars in a dependent string are stored starting at
>  * base->chars + start, and are not necessarily zero-terminated.  If start is
>  * 0, it is not stored, length is a full size_t (minus the JSSTRFLAG_* bits in
>  * the high two positions), and the JSSTRFLAG_PREFIX flag is set.
>  */
> struct JSDependentString {
>     size_t          length;
>     JSString        *base;
> };
114,115c86,91
< #define JSSTRING_LENGTH_BITS        (JS_BITS_PER_WORD - 3)
< #define JSSTRING_LENGTH_MASK        JSSTRING_BITMASK(JSSTRING_LENGTH_BITS)
---
> /* Definitions for flags stored in the high order bits of JSString.length. */
> #define JSSTRFLAG_BITS              2
> #define JSSTRFLAG_SHIFT(flg)        ((size_t)(flg) << JSSTRING_LENGTH_BITS)
> #define JSSTRFLAG_MASK              JSSTRFLAG_SHIFT(JS_BITMASK(JSSTRFLAG_BITS))
> #define JSSTRFLAG_DEPENDENT         JSSTRFLAG_SHIFT(1)
> #define JSSTRFLAG_PREFIX            JSSTRFLAG_SHIFT(2)
122,129c98
< #define JSSTRING_IS_FLAT(str)       (!JSSTRING_IS_DEPENDENT(str))
< #define JSSTRING_IS_MUTABLE(str)    (((str)->length & (JSSTRFLAG_DEPENDENT |  \
<                                                        JSSTRFLAG_MUTABLE)) == \
<                                      JSSTRFLAG_MUTABLE)
< #define JSSTRING_IS_ATOMIZED(str)   (((str)->length & (JSSTRFLAG_DEPENDENT |  \
<                                                        JSSTRFLAG_ATOMIZED)) ==\
<                                      JSSTRFLAG_ATOMIZED)
< 
---
> #define JSSTRING_IS_PREFIX(str)     JSSTRING_HAS_FLAG(str, JSSTRFLAG_PREFIX)
132c101
<                                      : JSFLATSTR_CHARS(str))
---
>                                      : (str)->chars)
135,197c104,107
<                                      : JSFLATSTR_LENGTH(str))
< 
< #define JSSTRING_CHARS_AND_LENGTH(str, chars_, length_)                       \
<     ((void)(JSSTRING_IS_DEPENDENT(str)                                        \
<             ? ((length_) = JSSTRDEP_LENGTH(str),                              \
<                (chars_) = JSSTRDEP_CHARS(str))                                \
<             : ((length_) = JSFLATSTR_LENGTH(str),                             \
<                (chars_) = JSFLATSTR_CHARS(str))))
< 
< #define JSSTRING_CHARS_AND_END(str, chars_, end)                              \
<     ((void)((end) = JSSTRING_IS_DEPENDENT(str)                                \
<                   ? JSSTRDEP_LENGTH(str) + ((chars_) = JSSTRDEP_CHARS(str))   \
<                   : JSFLATSTR_LENGTH(str) + ((chars_) = JSFLATSTR_CHARS(str))))
< 
< /* Specific flat string initializer and accessor macros. */
< #define JSFLATSTR_INIT(str, chars_, length_)                                  \
<     ((void)(JS_ASSERT(((length_) & ~JSSTRING_LENGTH_MASK) == 0),              \
<             (str)->length = (length_), (str)->u.chars = (chars_)))
< 
< #define JSFLATSTR_LENGTH(str)                                                 \
<     (JS_ASSERT(JSSTRING_IS_FLAT(str)), (str)->length & JSSTRING_LENGTH_MASK)
< 
< #define JSFLATSTR_CHARS(str)                                                  \
<     (JS_ASSERT(JSSTRING_IS_FLAT(str)), (str)->u.chars)
< 
< /*
<  * Macros to manipulate atomized and mutable flags of flat strings. It is safe
<  * to use these without extra locking due to the following properties:
<  *
<  *   * We do not have a macro like JSFLATSTR_CLEAR_ATOMIZED as a string
<  *     remains atomized until the GC collects it.
<  *
<  *   * A thread may call JSFLATSTR_SET_MUTABLE only when it is the only thread
<  *     accessing the string until a later call to JSFLATSTR_CLEAR_MUTABLE.
<  *
<  *   * Multiple threads can call JSFLATSTR_CLEAR_MUTABLE but the macro
<  *     actually clears the mutable flag only when the flag is set -- in which
<  *     case only one thread can access the string (see previous property).
<  *
<  * Thus, when multiple threads access the string, JSFLATSTR_SET_ATOMIZED is
<  * the only macro that can update the length field of the string by changing
<  * the mutable bit from 0 to 1. We call the macro only after the string has
<  * been hashed. When some threads in js_ValueToStringId see that the flag is
<  * set, it knows that the string was atomized.
<  *
<  * On the other hand, if the thread sees that the flag is unset, it could be
<  * seeing a stale value when another thread has just atomized the string and
<  * set the flag. But this can lead only to an extra call to js_AtomizeString.
<  * This function would find that the string was already hashed and return it
<  * with the atomized bit set.
<  */
< #define JSFLATSTR_SET_ATOMIZED(str)                                           \
<     ((void)(JS_ASSERT(JSSTRING_IS_FLAT(str) && !JSSTRING_IS_MUTABLE(str)),    \
<             (str)->length |= JSSTRFLAG_ATOMIZED))
< 
< #define JSFLATSTR_SET_MUTABLE(str)                                            \
<     ((void)(JS_ASSERT(JSSTRING_IS_FLAT(str) && !JSSTRING_IS_ATOMIZED(str)),   \
<             (str)->length |= JSSTRFLAG_MUTABLE))
< 
< #define JSFLATSTR_CLEAR_MUTABLE(str)                                          \
<     ((void)(JS_ASSERT(JSSTRING_IS_FLAT(str)),                                 \
<             JSSTRING_HAS_FLAG(str, JSSTRFLAG_MUTABLE) &&                      \
<             ((str)->length &= ~JSSTRFLAG_MUTABLE)))
---
>                                      : (str)->length)
> #define JSSTRING_LENGTH_BITS        (sizeof(size_t) * JS_BITS_PER_BYTE        \
>                                      - JSSTRFLAG_BITS)
> #define JSSTRING_LENGTH_MASK        JSSTRING_BITMASK(JSSTRING_LENGTH_BITS)
199c109
< /* Specific dependent string shift/mask accessor and mutator macros. */
---
> /* Specific JSDependentString shift/mask accessor and mutator macros. */
206,209c116,118
< #define JSSTRDEP_IS_PREFIX(str)     JSSTRING_HAS_FLAG(str, JSSTRFLAG_PREFIX)
< 
< #define JSSTRDEP_START(str)         (JSSTRDEP_IS_PREFIX(str) ? 0              \
<                                      : (((str)->length                        \
---
> #define JSSTRDEP(str)               ((JSDependentString *)(str))
> #define JSSTRDEP_START(str)         (JSSTRING_IS_PREFIX(str) ? 0              \
>                                      : ((JSSTRDEP(str)->length                \
212,213c121,122
< #define JSSTRDEP_LENGTH(str)        ((str)->length                            \
<                                      & (JSSTRDEP_IS_PREFIX(str)               \
---
> #define JSSTRDEP_LENGTH(str)        (JSSTRDEP(str)->length                    \
>                                      & (JSSTRING_IS_PREFIX(str)               \
217,225c126,131
< #define JSSTRDEP_INIT(str,bstr,off,len)                                       \
<     ((str)->length = JSSTRFLAG_DEPENDENT                                      \
<                    | ((off) << JSSTRDEP_START_SHIFT)                          \
<                    | (len),                                                   \
<      (str)->u.base = (bstr))
< 
< #define JSPREFIX_INIT(str,bstr,len)                                           \
<     ((str)->length = JSSTRFLAG_DEPENDENT | JSSTRFLAG_PREFIX | (len),          \
<      (str)->u.base = (bstr))
---
> #define JSSTRDEP_SET_START_AND_LENGTH(str,off,len)                            \
>     (JSSTRDEP(str)->length = JSSTRFLAG_DEPENDENT                              \
>                            | ((off) << JSSTRDEP_START_SHIFT)                  \
>                            | (len))
> #define JSPREFIX_SET_LENGTH(str,len)                                          \
>     (JSSTRDEP(str)->length = JSSTRFLAG_DEPENDENT | JSSTRFLAG_PREFIX | (len))
227c133,134
< #define JSSTRDEP_BASE(str)          ((str)->u.base)
---
> #define JSSTRDEP_BASE(str)          (JSSTRDEP(str)->base)
> #define JSSTRDEP_SET_BASE(str,bstr) (JSSTRDEP(str)->base = (bstr))
229c136
< #define JSPREFIX_SET_BASE(str,bstr) ((str)->u.base = (bstr))
---
> #define JSPREFIX_SET_BASE(str,bstr) JSSTRDEP_SET_BASE(str,bstr)
234c141
<      : JSFLATSTR_CHARS(JSSTRDEP_BASE(str)) + JSSTRDEP_START(str))
---
>      : JSSTRDEP_BASE(str)->chars + JSSTRDEP_START(str))
242,243c149,150
< extern const jschar *
< js_GetStringChars(JSContext *cx, JSString *str);
---
> extern jschar *
> js_GetStringChars(JSString *str);
251,258d157
< extern JSBool
< js_MakeStringImmutable(JSContext *cx, JSString *str);
< 
< typedef struct JSCharBuffer {
<     size_t          length;
<     jschar          *chars;
< } JSCharBuffer;
< 
304a204,209
> #define JS_CCODE_HACK 1
> #if JS_CCODE_HACK
> // !!@ 2003.11.16 jht: Work around optimzer bug
> uint32 JS_CCODE( uint32 c);
> uint32 JS_CTYPE( uint32 c);
> #else
306a212
> #endif
309,313c215,219
<                            (1 << JSCT_LOWERCASE_LETTER) |                     \
<                            (1 << JSCT_TITLECASE_LETTER) |                     \
<                            (1 << JSCT_MODIFIER_LETTER) |                      \
<                            (1 << JSCT_OTHER_LETTER))                          \
<                           >> JS_CTYPE(c)) & 1)
---
> 			   (1 << JSCT_LOWERCASE_LETTER) |                     \
> 			   (1 << JSCT_TITLECASE_LETTER) |                     \
> 			   (1 << JSCT_MODIFIER_LETTER) |                      \
> 			   (1 << JSCT_OTHER_LETTER))                          \
> 			  >> JS_CTYPE(c)) & 1)
316,321c222,227
<                            (1 << JSCT_LOWERCASE_LETTER) |                     \
<                            (1 << JSCT_TITLECASE_LETTER) |                     \
<                            (1 << JSCT_MODIFIER_LETTER) |                      \
<                            (1 << JSCT_OTHER_LETTER) |                         \
<                            (1 << JSCT_DECIMAL_DIGIT_NUMBER))                  \
<                           >> JS_CTYPE(c)) & 1)
---
> 			   (1 << JSCT_LOWERCASE_LETTER) |                     \
> 			   (1 << JSCT_TITLECASE_LETTER) |                     \
> 			   (1 << JSCT_MODIFIER_LETTER) |                      \
> 			   (1 << JSCT_OTHER_LETTER) |                         \
> 			   (1 << JSCT_DECIMAL_DIGIT_NUMBER))                  \
> 			  >> JS_CTYPE(c)) & 1)
324,346c230,252
< #define JS_ISLETTER(c)   ((((1 << JSCT_UPPERCASE_LETTER) |                    \
<                             (1 << JSCT_LOWERCASE_LETTER) |                    \
<                             (1 << JSCT_TITLECASE_LETTER) |                    \
<                             (1 << JSCT_MODIFIER_LETTER) |                     \
<                             (1 << JSCT_OTHER_LETTER) |                        \
<                             (1 << JSCT_LETTER_NUMBER))                        \
<                            >> JS_CTYPE(c)) & 1)
< 
< /*
<  * 'IdentifierPart' from ECMA grammar, is Unicode letter or combining mark or
<  * digit or connector punctuation.
<  */
< #define JS_ISIDPART(c)  ((((1 << JSCT_UPPERCASE_LETTER) |                     \
<                            (1 << JSCT_LOWERCASE_LETTER) |                     \
<                            (1 << JSCT_TITLECASE_LETTER) |                     \
<                            (1 << JSCT_MODIFIER_LETTER) |                      \
<                            (1 << JSCT_OTHER_LETTER) |                         \
<                            (1 << JSCT_LETTER_NUMBER) |                        \
<                            (1 << JSCT_NON_SPACING_MARK) |                     \
<                            (1 << JSCT_COMBINING_SPACING_MARK) |               \
<                            (1 << JSCT_DECIMAL_DIGIT_NUMBER) |                 \
<                            (1 << JSCT_CONNECTOR_PUNCTUATION))                 \
<                           >> JS_CTYPE(c)) & 1)
---
> #define JS_ISUC_LETTER(c)   ((((1 << JSCT_UPPERCASE_LETTER) |                 \
> 			   (1 << JSCT_LOWERCASE_LETTER) |                     \
> 			   (1 << JSCT_TITLECASE_LETTER) |                     \
> 			   (1 << JSCT_MODIFIER_LETTER) |                      \
> 			   (1 << JSCT_OTHER_LETTER) |                         \
> 			   (1 << JSCT_LETTER_NUMBER))                         \
> 			  >> JS_CTYPE(c)) & 1)
> 
> /*
> * 'IdentifierPart' from ECMA grammar, is Unicode letter or
> * combining mark or digit or connector punctuation.
> */
> #define JS_ISID_PART(c) ((((1 << JSCT_UPPERCASE_LETTER) |                     \
> 			   (1 << JSCT_LOWERCASE_LETTER) |                     \
> 			   (1 << JSCT_TITLECASE_LETTER) |                     \
> 			   (1 << JSCT_MODIFIER_LETTER) |                      \
> 			   (1 << JSCT_OTHER_LETTER) |                         \
> 			   (1 << JSCT_LETTER_NUMBER) |                        \
> 			   (1 << JSCT_NON_SPACING_MARK) |                     \
> 			   (1 << JSCT_COMBINING_SPACING_MARK) |               \
> 			   (1 << JSCT_DECIMAL_DIGIT_NUMBER) |                 \
> 			   (1 << JSCT_CONNECTOR_PUNCTUATION))                 \
> 			  >> JS_CTYPE(c)) & 1)
351,367c257,261
< /*
<  * Per ECMA-262 15.10.2.6, these characters are the only ones that make up a
<  * "word", as far as a RegExp is concerned.  If we want a Unicode-friendlier
<  * definition of "word", we should rename this macro to something regexp-y.
<  */
< #define JS_ISWORD(c)    ((c) < 128 && (isalnum(c) || (c) == '_'))
< 
< #define JS_ISIDSTART(c) (JS_ISLETTER(c) || (c) == '_' || (c) == '$')
< #define JS_ISIDENT(c)   (JS_ISIDPART(c) || (c) == '_' || (c) == '$')
< 
< #define JS_ISXMLSPACE(c)        ((c) == ' ' || (c) == '\t' || (c) == '\r' ||  \
<                                  (c) == '\n')
< #define JS_ISXMLNSSTART(c)      ((JS_CCODE(c) & 0x00000100) || (c) == '_')
< #define JS_ISXMLNS(c)           ((JS_CCODE(c) & 0x00000080) || (c) == '.' ||  \
<                                  (c) == '-' || (c) == '_')
< #define JS_ISXMLNAMESTART(c)    (JS_ISXMLNSSTART(c) || (c) == ':')
< #define JS_ISXMLNAME(c)         (JS_ISXMLNS(c) || (c) == ':')
---
> #define JS_ISWORD(c)    (JS_ISALNUM(c) || (c) == '_')
> 
> /* XXXbe unify on A/X/Y tbls, avoid ctype.h? */
> #define JS_ISIDENT_START(c) (JS_ISUC_LETTER(c) || (c) == '_' || (c) == '$')
> #define JS_ISIDENT(c)       (JS_ISID_PART(c) || (c) == '_' || (c) == '$')
371d264
< /* XXXbe unify on A/X/Y tbls, avoid ctype.h? */
379,384c272,273
< #define JS_TOUPPER(c)   ((jschar) ((JS_CCODE(c) & 0x00100000)                 \
<                                    ? (c) - ((int32)JS_CCODE(c) >> 22)         \
<                                    : (c)))
< #define JS_TOLOWER(c)   ((jschar) ((JS_CCODE(c) & 0x00200000)                 \
<                                    ? (c) + ((int32)JS_CCODE(c) >> 22)         \
<                                    : (c)))
---
> #define JS_TOUPPER(c)   ((JS_CCODE(c) & 0x00100000) ? (c) - ((int32)JS_CCODE(c) >> 22) : (c))
> #define JS_TOLOWER(c)   ((JS_CCODE(c) & 0x00200000) ? (c) + ((int32)JS_CCODE(c) >> 22) : (c))
386,390c275,278
< /*
<  * Shorthands for ASCII (7-bit) decimal and hex conversion.
<  * Manually inline isdigit for performance; MSVC doesn't do this for us.
<  */
< #define JS7_ISDEC(c)    ((((unsigned)(c)) - '0') <= 9)
---
> #define JS_TOCTRL(c)    ((c) ^ 64)      /* XXX unsafe! requires uppercase c */
> 
> /* Shorthands for ASCII (7-bit) decimal and hex conversion. */
> #define JS7_ISDEC(c)    ((c) < 128 && isdigit(c))
393c281
< #define JS7_UNHEX(c)    (uintN)(JS7_ISDEC(c) ? (c) - '0' : 10 + tolower(c) - 'a')
---
> #define JS7_UNHEX(c)    (uintN)(isdigit(c) ? (c) - '0' : 10 + tolower(c) - 'a')
396,399c284
< /* Initialize per-runtime string state for the first context in the runtime. */
< extern JSBool
< js_InitRuntimeStringState(JSContext *cx);
< 
---
> /* Initialize truly global state associated with JS strings. */
401,417c286
< js_InitDeflatedStringCache(JSRuntime *rt);
< 
< /*
<  * Maximum character code for which we will create a pinned unit string on
<  * demand -- see JSRuntime.unitStrings in jscntxt.h.
<  */
< #define UNIT_STRING_LIMIT 256U
< 
< /*
<  * Get the independent string containing only character code c (backstopped
<  * with a NUL as usual for independent strings).
<  *
<  * This function must be called only for c < UNIT_STRING_LIMIT. It asserts to
<  * insist on this requirement in DEBUG builds.
<  */
< extern JSString *
< js_GetUnitString(JSContext *cx, jschar c);
---
> js_InitStringGlobals(void);
420c289
< js_FinishUnitStrings(JSRuntime *rt);
---
> js_FreeStringGlobals(void);
423c292,296
< js_FinishRuntimeStringState(JSContext *cx);
---
> js_PurgeDeflatedStringCache(JSString *str);
> 
> /* Initialize per-runtime string state for the first context in the runtime. */
> extern JSBool
> js_InitRuntimeStringState(JSContext *cx);
426c299
< js_FinishDeflatedStringCache(JSRuntime *rt);
---
> js_FinishRuntimeStringState(JSContext *cx);
429,430d301
< extern JSClass js_StringClass;
< 
444c315
< js_NewString(JSContext *cx, jschar *chars, size_t length);
---
> js_NewString(JSContext *cx, jschar *chars, size_t length, uintN gcflag);
448c319
<                       size_t length);
---
>                       size_t length, uintN gcflag);
452c323
< js_NewStringCopyN(JSContext *cx, const jschar *s, size_t n);
---
> js_NewStringCopyN(JSContext *cx, const jschar *s, size_t n, uintN gcflag);
456c327
< js_NewStringCopyZ(JSContext *cx, const jschar *s);
---
> js_NewStringCopyZ(JSContext *cx, const jschar *s, uintN gcflag);
458,464c329
< /*
<  * Free the chars held by str when it is finalized by the GC. When type is
<  * less then zero, it denotes an internal string. Otherwise it denotes the
<  * type of the external string allocated with JS_NewExternalString.
<  *
<  * This function always needs rt but can live with null cx.
<  */
---
> /* Free the chars held by str when it is finalized by the GC. */
466,471c331
< js_FinalizeStringRT(JSRuntime *rt, JSString *str, intN type, JSContext *cx);
< 
< /*
<  * Convert a value to a printable C string.
<  */
< typedef JSString *(*JSValueToStringFun)(JSContext *cx, jsval v);
---
> js_FinalizeString(JSContext *cx, JSString *str);
473,477c333,334
< extern JS_FRIEND_API(const char *)
< js_ValueToPrintable(JSContext *cx, jsval v, JSValueToStringFun v2sfun);
< 
< #define js_ValueToPrintableString(cx,v) \
<     js_ValueToPrintable(cx, v, js_ValueToString)
---
> extern void
> js_FinalizeStringRT(JSRuntime *rt, JSString *str);
479,480c336,338
< #define js_ValueToPrintableSource(cx,v) \
<     js_ValueToPrintable(cx, v, js_ValueToSource)
---
> /* Wrap a string value in a String object. */
> extern JSObject *
> js_StringToObject(JSContext *cx, JSString *str);
486c344
< extern JS_FRIEND_API(JSString *)
---
> extern JSString *
493c351
< extern JS_FRIEND_API(JSString *)
---
> extern JSString *
495a354
> #ifdef HT_ENUMERATE_NEXT	/* XXX don't require jshash.h */
497,498c356
<  * Compute a hash function from str. The caller can call this function even if
<  * str is not a GC-allocated thing.
---
>  * Compute a hash function from str.
500c358
< extern uint32
---
> extern JSHashNumber
502,508c360
< 
< /*
<  * Test if strings are equal. The caller can call the function even if str1
<  * or str2 are not GC-allocated things.
<  */
< extern JSBool
< js_EqualStrings(JSString *str1, JSString *str2);
---
> #endif
549c401
< js_SkipWhiteSpace(const jschar *s, const jschar *end);
---
> js_SkipWhiteSpace(const jschar *s);
554c406
<  * was JS_malloc'ed. length is updated with the length of the new string in jschars.
---
>  * was JS_malloc'ed.
555a408,410
> 
> #ifdef _UTF8
> 
557c412,429
< js_InflateString(JSContext *cx, const char *bytes, size_t *length);
---
> js_InflateString(JSContext *cx, const char *bytes, size_t length, size_t *pWLength);
> 
> #else //#ifdef _UTF8
> 
> extern jschar *
> js_InflateString(JSContext *cx, const char *bytes, size_t length);
> 
> #endif //#ifdef _UTF8
> 
> 
> 
> 
> #ifdef _UTF8
> 
> char *
> js_DeflateString(JSContext *cx, const jschar *chars, size_t length, size_t *pMBLength);
> 
> #else //#ifdef _UTF8
562,570c434
< /*
<  * Inflate bytes to JS chars into a buffer. 'chars' must be large enough for
<  * 'length' jschars. The buffer is NOT null-terminated. The destination length
<  * must be be initialized with the buffer size and will contain on return the
<  * number of copied chars.
<  */
< extern JSBool
< js_InflateStringToBuffer(JSContext* cx, const char *bytes, size_t length,
<                          jschar *chars, size_t* charsLength);
---
> #endif //#ifdef _UTF8
572,577d435
< /*
<  * Get number of bytes in the deflated sequence of characters.
<  */
< extern size_t
< js_GetDeflatedStringLength(JSContext *cx, const jschar *chars,
<                            size_t charsLength);
580,583c438,439
<  * Deflate JS chars to bytes into a buffer. 'bytes' must be large enough for
<  * 'length chars. The buffer is NOT null-terminated. The destination length
<  * must to be initialized with the buffer size and will contain on return the
<  * number of copied bytes.
---
>  * Inflate bytes to JS chars into a buffer.
>  * 'chars' must be large enough for 'length'+1 jschars.
585,587c441,448
< extern JSBool
< js_DeflateStringToBuffer(JSContext* cx, const jschar *chars,
<                          size_t charsLength, char *bytes, size_t* length);
---
> 
> #ifdef _UTF8
> extern int
> js_InflateStringToBuffer(jschar *chars, const char *bytes, size_t length);
> #else //#ifdef _UTF8
> extern void
> js_InflateStringToBuffer(jschar *chars, const char *bytes, size_t length);
> #endif //#ifdef _UTF8
594c455
< js_SetStringBytes(JSContext *cx, JSString *str, char *bytes, size_t length);
---
> js_SetStringBytes(JSString *str, char *bytes, size_t length);
600,605c461,462
< extern const char *
< js_GetStringBytes(JSContext *cx, JSString *str);
< 
< /* Remove a deflated string cache entry associated with str if any. */
< extern void
< js_PurgeDeflatedStringCache(JSRuntime *rt, JSString *str);
---
> extern char *
> js_GetStringBytes(JSString *str);
611,643d467
< /*
<  * Convert one UCS-4 char and write it into a UTF-8 buffer, which must be at
<  * least 6 bytes long.  Return the number of UTF-8 bytes of data written.
<  */
< extern int
< js_OneUcs4ToUtf8Char(uint8 *utf8Buffer, uint32 ucs4Char);
< 
< /*
<  * Write str into buffer escaping any non-printable or non-ASCII character.
<  * Guarantees that a NUL is at the end of the buffer. Returns the length of
<  * the written output, NOT including the NUL. If buffer is null, just returns
<  * the length of the output. If quote is not 0, it must be a single or double
<  * quote character that will quote the output.
<  *
<  * The function is only defined for debug builds.
< */
< #define js_PutEscapedString(buffer, bufferSize, str, quote)                   \
<     js_PutEscapedStringImpl(buffer, bufferSize, NULL, str, quote)
< 
< /*
<  * Write str into file escaping any non-printable or non-ASCII character.
<  * Returns the number of bytes written to file. If quote is not 0, it must
<  * be a single or double quote character that will quote the output.
<  *
<  * The function is only defined for debug builds.
< */
< #define js_FileEscapedString(file, str, quote)                                \
<     (JS_ASSERT(file), js_PutEscapedStringImpl(NULL, 0, file, str, quote))
< 
< extern JS_FRIEND_API(size_t)
< js_PutEscapedStringImpl(char *buffer, size_t bufferSize, FILE *fp,
<                         JSString *str, uint32 quote);
< 
diff -r /Volumes/Swap/js-14-2-2008/js/src/jstypes.h /Volumes/Swap/js_D11/src/jstypes.h
2,8c2,6
< /* ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
---
> /*
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
10,13c8,11
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
18,21c16,32
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
23,24c34,37
<  * Contributor(s):
<  *   IBM Corp.
---
>  * This Original Code has been modified by IBM Corporation.
>  * Modifications made by IBM described herein are
>  * Copyright (c) International Business Machines
>  * Corporation, 2000
26,36c39,40
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
---
>  * Modifications to Mozilla code or documentation
>  * identified per MPL Section 3.3
38c42,44
<  * ***** END LICENSE BLOCK ***** */
---
>  * Date             Modified by     Description of modification
>  * 04/20/2000       IBM Corp.      OS/2 VisualAge build.
>  */
80d85
< 
82,98c87,131
< # define JS_EXTERN_API(__type)  extern __declspec(dllexport) __type
< # define JS_EXPORT_API(__type)  __declspec(dllexport) __type
< # define JS_EXTERN_DATA(__type) extern __declspec(dllexport) __type
< # define JS_EXPORT_DATA(__type) __declspec(dllexport) __type
< 
< # define JS_DLL_CALLBACK
< # define JS_STATIC_DLL_CALLBACK(__x)    static __x
< 
< #elif defined(XP_OS2) && defined(__declspec)
< 
< # define JS_EXTERN_API(__type)  extern __declspec(dllexport) __type
< # define JS_EXPORT_API(__type)  __declspec(dllexport) __type
< # define JS_EXTERN_DATA(__type) extern __declspec(dllexport) __type
< # define JS_EXPORT_DATA(__type) __declspec(dllexport) __type
< 
< # define JS_DLL_CALLBACK
< # define JS_STATIC_DLL_CALLBACK(__x)    static __x
---
> #define JS_EXTERN_API(__type) extern __declspec(dllexport) __type
> #define JS_EXPORT_API(__type) __declspec(dllexport) __type
> #define JS_EXTERN_DATA(__type) extern __declspec(dllexport) __type
> #define JS_EXPORT_DATA(__type) __declspec(dllexport) __type
> 
> #define JS_DLL_CALLBACK
> #define JS_STATIC_DLL_CALLBACK(__x) static __x
> 
> #elif defined(WIN16)
> 
> #ifdef _WINDLL
> #define JS_EXTERN_API(__type) extern __type _cdecl _export _loadds
> #define JS_EXPORT_API(__type) __type _cdecl _export _loadds
> #define JS_EXTERN_DATA(__type) extern __type _export
> #define JS_EXPORT_DATA(__type) __type _export
> 
> #define JS_DLL_CALLBACK             __cdecl __loadds
> #define JS_STATIC_DLL_CALLBACK(__x) static __x CALLBACK
> 
> #else /* this must be .EXE */
> #define JS_EXTERN_API(__type) extern __type _cdecl _export
> #define JS_EXPORT_API(__type) __type _cdecl _export
> #define JS_EXTERN_DATA(__type) extern __type _export
> #define JS_EXPORT_DATA(__type) __type _export
> 
> #define JS_DLL_CALLBACK             __cdecl __loadds
> #define JS_STATIC_DLL_CALLBACK(__x) __x JS_DLL_CALLBACK
> #endif /* _WINDLL */
> 
> #elif defined(XP_MAC)
> #define JS_EXTERN_API(__type) extern __declspec(export) __type
> #define JS_EXPORT_API(__type) __declspec(export) __type
> #define JS_EXTERN_DATA(__type) extern __declspec(export) __type
> #define JS_EXPORT_DATA(__type) __declspec(export) __type
> 
> #define JS_DLL_CALLBACK
> #define JS_STATIC_DLL_CALLBACK(__x) static __x
> 
> #elif defined(XP_OS2_VACPP) 
> #define JS_EXTERN_API(__type) extern __type
> #define JS_EXPORT_API(__type) __type
> #define JS_EXTERN_DATA(__type) extern __type
> #define JS_EXPORT_DATA(__type) __type
> #define JS_DLL_CALLBACK  _Optlink
> #define JS_STATIC_DLL_CALLBACK(__x) static __x JS_DLL_CALLBACK
102,111c135,138
< # ifdef HAVE_VISIBILITY_ATTRIBUTE
< #  define JS_EXTERNAL_VIS __attribute__((visibility ("default")))
< # else
< #  define JS_EXTERNAL_VIS
< # endif
< 
< # define JS_EXTERN_API(__type)  extern JS_EXTERNAL_VIS __type
< # define JS_EXPORT_API(__type)  JS_EXTERNAL_VIS __type
< # define JS_EXTERN_DATA(__type) extern JS_EXTERNAL_VIS __type
< # define JS_EXPORT_DATA(__type) JS_EXTERNAL_VIS __type
---
> #define JS_EXTERN_API(__type) extern __type
> #define JS_EXPORT_API(__type) __type
> #define JS_EXTERN_DATA(__type) extern __type
> #define JS_EXPORT_DATA(__type) __type
113,114c140,141
< # define JS_DLL_CALLBACK
< # define JS_STATIC_DLL_CALLBACK(__x)    static __x
---
> #define JS_DLL_CALLBACK
> #define JS_STATIC_DLL_CALLBACK(__x) static __x
119,125c146,150
< # if defined(__MWERKS__) || defined(__GNUC__)
< #  define JS_IMPORT_API(__x)    __x
< # else
< #  define JS_IMPORT_API(__x)    __declspec(dllimport) __x
< # endif
< #elif defined(XP_OS2) && defined(__declspec)
< # define JS_IMPORT_API(__x)     __declspec(dllimport) __x
---
> #  if defined(__MWERKS__) || defined(__GNUC__)
> #    define JS_IMPORT_API(__x)      __x
> #  else
> #    define JS_IMPORT_API(__x)      __declspec(dllimport) __x
> #  endif
127c152
< # define JS_IMPORT_API(__x)     JS_EXPORT_API (__x)
---
> #    define JS_IMPORT_API(__x)      JS_EXPORT_API (__x)
131,133c156
< # define JS_IMPORT_DATA(__x)      __declspec(dllimport) __x
< #elif defined(XP_OS2) && defined(__declspec)
< # define JS_IMPORT_DATA(__x)      __declspec(dllimport) __x
---
> #    define JS_IMPORT_DATA(__x)      __declspec(dllimport) __x
135c158
< # define JS_IMPORT_DATA(__x)     JS_EXPORT_DATA (__x)
---
> #    define JS_IMPORT_DATA(__x)     __x
140c163
<  * used within the JS library or not. Any source file within the JS
---
>  * used within the JS library or not.  Any source file within the JS
142c165
<  * should not. STATIC_JS_API is used to build JS as a static library.
---
>  * should not.
144,153c167,174
< #if defined(STATIC_JS_API)
< 
< # define JS_PUBLIC_API(t)   t
< # define JS_PUBLIC_DATA(t)  t
< 
< #elif defined(EXPORT_JS_API)
< 
< # define JS_PUBLIC_API(t)   JS_EXPORT_API(t)
< # define JS_PUBLIC_DATA(t)  JS_EXPORT_DATA(t)
< 
---
> #if 0
> #ifdef EXPORT_JS_API
> #define JS_PUBLIC_API(t)    JS_EXPORT_API(t)
> #define JS_PUBLIC_DATA(t)   JS_EXPORT_DATA(t)
> #else
> #define JS_PUBLIC_API(t)    JS_IMPORT_API(t)
> #define JS_PUBLIC_DATA(t)   JS_IMPORT_DATA(t)
> #endif
155,158c176,178
< 
< # define JS_PUBLIC_API(t)   JS_IMPORT_API(t)
< # define JS_PUBLIC_DATA(t)  JS_IMPORT_DATA(t)
< 
---
> // !!@!! Temp to get to link as static lib.
> #define JS_PUBLIC_API(t)    t
> #define JS_PUBLIC_DATA(t)   t
165c185
< # define JS_INLINE(x) __forceinline x
---
> #   define JS_INLINE __inline
167,171c187
< # ifndef DEBUG
< #  define JS_INLINE(x) x __attribute__((always_inline)); x
< # else
< #  define JS_INLINE(x) inline x
< # endif
---
> #   define JS_INLINE
173c189
< # define JS_INLINE(x) x
---
> #   define JS_INLINE
184,191c200
< 
< #if defined(_MSC_VER) && _MSC_VER >= 1400
< # define JS_END_MACRO                                                         \
<     } __pragma(warning(push)) __pragma(warning(disable:4127))                 \
<     while (0) __pragma(warning(pop))
< #else
< # define JS_END_MACRO   } while (0)
< #endif
---
> #define JS_END_MACRO    } while (0)
200,203c209,210
< 
< # define JS_BEGIN_EXTERN_C      extern "C" {
< # define JS_END_EXTERN_C        }
< 
---
> #define JS_BEGIN_EXTERN_C       extern "C" {
> #define JS_END_EXTERN_C         }
205,208c212,213
< 
< # define JS_BEGIN_EXTERN_C
< # define JS_END_EXTERN_C
< 
---
> #define JS_BEGIN_EXTERN_C
> #define JS_END_EXTERN_C
221,233d225
< ** MACROS:      JS_PTR_TO_INT32
< **              JS_PTR_TO_UINT32
< **              JS_INT32_TO_PTR
< **              JS_UINT32_TO_PTR
< ** DESCRIPTION:
< ** Integer to pointer and pointer to integer conversion macros.
< ***********************************************************************/
< #define JS_PTR_TO_INT32(x)  ((jsint)((char *)(x) - (char *)0))
< #define JS_PTR_TO_UINT32(x) ((jsuint)((char *)(x) - (char *)0))
< #define JS_INT32_TO_PTR(x)  ((void *)((char *)0 + (jsint)(x)))
< #define JS_UINT32_TO_PTR(x) ((void *)((char *)0 + (jsuint)(x)))
< 
< /***********************************************************************
246,247c238,239
< #if (defined(XP_WIN) && !defined(CROSS_COMPILE)) || defined (WINCE)
< # include "jscpucfg.h"      /* Use standard Mac or Windows configuration */
---
> #if (defined(XP_MAC) || defined(XP_WIN)) && !defined(CROSS_COMPILE)
> #    include "jscpucfg.h"        /* Use standard Mac or Windows configuration */
249,250c241,242
< # include "jsautocfg.h"     /* Use auto-detected configuration */
< # include "jsosdep.h"       /* ...and platform-specific flags */
---
> #    include "jsautocfg.h"       /* Use auto-detected configuration */
> #    include "jsosdep.h"         /* ...and platform-specific flags */
252c244
< # error "Must define one of XP_BEOS, XP_OS2, XP_WIN or XP_UNIX"
---
> #    error "Must define one of XP_BEOS, XP_MAC, XP_OS2, XP_WIN or XP_UNIX"
262c254
< **      is equivalent to a plain "char".
---
> **      is equivalent to a plain "char". 
268c260
< # error No suitable type for JSInt8/JSUint8
---
> #error No suitable type for JSInt8/JSUint8
275c267
< **  The int16 types are known to be 16 bits each.
---
> **  The int16 types are known to be 16 bits each. 
281c273
< # error No suitable type for JSInt16/JSUint16
---
> #error No suitable type for JSInt16/JSUint16
288c280
< **  The int32 types are known to be 32 bits each.
---
> **  The int32 types are known to be 32 bits each. 
293,294c285,286
< # define JS_INT32(x)    x
< # define JS_UINT32(x)   x ## U
---
> #define JS_INT32(x)  x
> #define JS_UINT32(x) x ## U
298,299c290,291
< # define JS_INT32(x)    x ## L
< # define JS_UINT32(x)   x ## UL
---
> #define JS_INT32(x)  x ## L
> #define JS_UINT32(x) x ## UL
301c293
< # error No suitable type for JSInt32/JSUint32
---
> #error No suitable type for JSInt32/JSUint32
315,316c307
< 
< # if JS_BYTES_PER_LONG == 8
---
> #if JS_BYTES_PER_LONG == 8
319c310
< # elif defined(WIN16)
---
> #elif defined(WIN16)
322c313
< # elif defined(WIN32) && !defined(__GNUC__)
---
> #elif defined(WIN32) && !defined(__GNUC__)
325c316
< # else
---
> #else
328,329c319
< # endif /* JS_BYTES_PER_LONG == 8 */
< 
---
> #endif /* JS_BYTES_PER_LONG == 8 */
331d320
< 
333c322
< # ifdef IS_LITTLE_ENDIAN
---
> #ifdef IS_LITTLE_ENDIAN
335c324
< # else
---
> #else
340d328
< 
350c338
< **      never valid for fields of a structure.
---
> **      never valid for fields of a structure. 
356c344
< # error 'sizeof(int)' not sufficient for platform use
---
> #error 'sizeof(int)' not sufficient for platform use
362c350
< **  NSPR's floating point type is always 64 bits.
---
> **  NSPR's floating point type is always 64 bits. 
369c357
< **  A type for representing the size of objects.
---
> **  A type for representing the size of objects. 
377c365
< **      for storing a pointer or pointer sutraction.
---
> **      for storing a pointer or pointer sutraction. 
385c373
< **      for storing a pointer or pointer sutraction.
---
> **      for storing a pointer or pointer sutraction. 
387,389d374
< #if JS_BYTES_PER_WORD == 8 && JS_BYTES_PER_LONG != 8
< typedef JSUint64 JSUptrdiff;
< #else
391d375
< #endif
399c383
< **      just as you would C int-valued conditions.
---
> **      just as you would C int-valued conditions. 
409c393
< **      but minimum and consistent overhead matters.
---
> **      but minimum and consistant overhead matters.
416,419d399
< #if JS_BYTES_PER_WORD == 8 && JS_BYTES_PER_LONG != 8
< typedef JSInt64 JSWord;
< typedef JSUint64 JSUword;
< #else
422d401
< #endif
426,473d404
< /***********************************************************************
< ** MACROS:      JS_LIKELY
< **              JS_UNLIKELY
< ** DESCRIPTION:
< **      These macros allow you to give a hint to the compiler about branch
< **      probability so that it can better optimize.  Use them like this:
< **
< **      if (JS_LIKELY(v == 1)) {
< **          ... expected code path ...
< **      }
< **
< **      if (JS_UNLIKELY(v == 0)) {
< **          ... non-expected code path ...
< **      }
< **
< ***********************************************************************/
< #if defined(__GNUC__) && (__GNUC__ > 2)
< 
< # define JS_LIKELY(x)   (__builtin_expect((x), 1))
< # define JS_UNLIKELY(x) (__builtin_expect((x), 0))
< 
< #else
< 
< # define JS_LIKELY(x)   (x)
< # define JS_UNLIKELY(x) (x)
< 
< #endif
< 
< /***********************************************************************
< ** MACROS:      JS_ARRAY_LENGTH
< **              JS_ARRAY_END
< ** DESCRIPTION:
< **      Macros to get the number of elements and the pointer to one past the
< **      last element of a C array. Use them like this:
< **
< **      jschar buf[10], *s;
< **      JSString *str;
< **      ...
< **      for (s = buf; s != JS_ARRAY_END(buf); ++s) *s = ...;
< **      ...
< **      str = JS_NewStringCopyN(cx, buf, JS_ARRAY_LENGTH(buf));
< **      ...
< **
< ***********************************************************************/
< 
< #define JS_ARRAY_LENGTH(array) (sizeof (array) / sizeof (array)[0])
< #define JS_ARRAY_END(array)    ((array) + JS_ARRAY_LENGTH(array))
< 
476a408
> 
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsutil.c /Volumes/Swap/js_D11/src/jsutil.c
1c1
< /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
---
> /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,25c16,36
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *   IBM Corp.
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  *
>  * This Original Code has been modified by IBM Corporation. Modifications made by IBM
>  * described herein are Copyright (c) International Business Machines Corporation, 2000.
>  * Modifications to Mozilla code or documentation identified per MPL Section 3.3
27,39c38,40
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * Date        Modified by     Description of modification
>  * 04/10/2000  IBM Corp.       Added DebugBreak() definitions for OS/2
>  */
46c47
< #include <stdlib.h>
---
> #include "xstdlib.h"
48a50,52
> #include "jsapi.h"
> 
> //#include "_optimize.h"
54,61c58,61
< JS_PUBLIC_API(void) JS_Assert(const char *s, const char *file, JSIntn ln)
< {
<     fprintf(stderr, "Assertion failure: %s, at %s:%d\n", s, file, ln);
< #if defined(WIN32)
<     DebugBreak();
<     exit(3);
< #elif defined(XP_OS2) || (defined(__GNUC__) && defined(__i386))
<     asm("int $3");
---
> #ifdef XP_MAC
> #	 include <Types.h>
> #    include <stdarg.h>
> #	 include "jsprf.h"
63,64d62
<     abort();
< }
66c64,78
< #ifdef JS_BASIC_STATS
---
> #if defined(XP_OS2) && defined(DEBUG)
> /* Added definitions for DebugBreak() for 2 different OS/2 compilers.  Doing
>  * the int3 on purpose for Visual Age so that a developer can step over the
>  * instruction if so desired.  Not always possible if trapping due to exception
>  * handling IBM-AKR
>  */
> #if defined(XP_OS2_VACPP)
>    #include <builtin.h>
>    #define DebugBreak() { _interrupt(3); }
> #elif defined(XP_OS2_EMX)
>    /* Force a trap */
>    #define DebugBreak() { int *pTrap=NULL; *pTrap = 1; }
> #else
>    #define DebugBreak()
> #endif
68,71c80,82
< #include <math.h>
< #include <string.h>
< #include "jscompat.h"
< #include "jsbit.h"
---
> #elif defined(XP_OS2)
>    #define DebugBreak()
> #endif /* XP_OS2 && DEBUG */
72a84
> #ifdef XP_MAC
74,80c86,90
<  * Histogram bins count occurrences of values <= the bin label, as follows:
<  *
<  *   linear:  0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10 or more
<  *     2**x:  0,   1,   2,   4,   8,  16,  32,  64, 128, 256, 512 or more
<  *    10**x:  0,   1,  10, 100, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9 or more
<  *
<  * We wish to count occurrences of 0 and 1 values separately, always.
---
>  * PStrFromCStr converts the source C string to a destination
>  * pascal string as it copies. The dest string will
>  * be truncated to fit into an Str255 if necessary.
>  * If the C String pointer is NULL, the pascal string's length is
>  * set to zero.
82,167c92
< static uint32
< BinToVal(uintN logscale, uintN bin)
< {
<     JS_ASSERT(bin <= 10);
<     if (bin <= 1 || logscale == 0)
<         return bin;
<     --bin;
<     if (logscale == 2)
<         return JS_BIT(bin);
<     JS_ASSERT(logscale == 10);
<     return (uint32) pow(10, bin);
< }
< 
< static uintN
< ValToBin(uintN logscale, uint32 val)
< {
<     uintN bin;
< 
<     if (val <= 1)
<         return val;
<     bin = (logscale == 10)
<           ? (uintN) ceil(log10(val))
<           : (logscale == 2)
<           ? (uintN) JS_CeilingLog2(val)
<           : val;
<     return JS_MIN(bin, 10);
< }
< 
< void
< JS_BasicStatsAccum(JSBasicStats *bs, uint32 val)
< {
<     uintN oldscale, newscale, bin;
<     double mean;
< 
<     ++bs->num;
<     if (bs->max < val)
<         bs->max = val;
<     bs->sum += val;
<     bs->sqsum += (double)val * val;
< 
<     oldscale = bs->logscale;
<     if (oldscale != 10) {
<         mean = bs->sum / bs->num;
<         if (bs->max > 16 && mean > 8) {
<             newscale = (bs->max > 1e6 && mean > 1000) ? 10 : 2;
<             if (newscale != oldscale) {
<                 uint32 newhist[11], newbin;
< 
<                 memset(newhist, 0, sizeof newhist);
<                 for (bin = 0; bin <= 10; bin++) {
<                     newbin = ValToBin(newscale, BinToVal(oldscale, bin));
<                     newhist[newbin] += bs->hist[bin];
<                 }
<                 memcpy(bs->hist, newhist, sizeof bs->hist);
<                 bs->logscale = newscale;
<             }
<         }
<     }
< 
<     bin = ValToBin(bs->logscale, val);
<     ++bs->hist[bin];
< }
< 
< double
< JS_MeanAndStdDev(uint32 num, double sum, double sqsum, double *sigma)
< {
<     double var;
< 
<     if (num == 0 || sum == 0) {
<         *sigma = 0;
<         return 0;
<     }
< 
<     var = num * sqsum - sum * sum;
<     if (var < 0 || num == 1)
<         var = 0;
<     else
<         var /= (double)num * (num - 1);
< 
<     /* Windows says sqrt(0.0) is "-1.#J" (?!) so we must test. */
<     *sigma = (var != 0) ? sqrt(var) : 0;
<     return sum / num;
< }
< 
< void
< JS_DumpBasicStats(JSBasicStats *bs, const char *title, FILE *fp)
---
> static void PStrFromCStr(const char* src, Str255 dst)
169c94
<     double mean, sigma;
---
> 	short 	length  = 0;
171,175c96,158
<     mean = JS_MeanAndStdDevBS(bs, &sigma);
<     fprintf(fp, "\nmean %s %g, std. deviation %g, max %lu\n",
<             title, mean, sigma, (unsigned long) bs->max);
<     JS_DumpHistogram(bs, fp);
< }
---
> 	/* handle case of overlapping strings */
> 	if ( (void*)src == (void*)dst )
> 	{
> 		unsigned char*		curdst = &dst[1];
> 		unsigned char		thisChar;
> 
> 		thisChar = *(const unsigned char*)src++;
> 		while ( thisChar != '\0' )
> 		{
> 			unsigned char	nextChar;
> 
> 			/*
>                          * Use nextChar so we don't overwrite what we
>                          * are about to read
>                          */
> 			nextChar = *(const unsigned char*)src++;
> 			*curdst++ = thisChar;
> 			thisChar = nextChar;
> 
> 			if ( ++length >= 255 )
> 				break;
> 		}
> 	}
> 	else if ( src != NULL )
> 	{
> 		unsigned char*		curdst = &dst[1];
> 		/* count down so test it loop is faster */
> 		short 				overflow = 255;
> 		register char		temp;
> 
> 		/*
>                  * Can't do the K&R C thing of while (*s++ = *t++)
>                  * because it will copy trailing zero which might
>                  * overrun pascal buffer.  Instead we use a temp variable.
>                  */
> 		while ( (temp = *src++) != 0 )
> 		{
> 			*(char*)curdst++ = temp;
> 
> 			if ( --overflow <= 0 )
> 				break;
> 		}
> 		length = 255 - overflow;
> 	}
> 	dst[0] = length;
> }
> 
> static void jsdebugstr(const char *debuggerMsg)
> {
> 	Str255		pStr;
> 
> 	PStrFromCStr(debuggerMsg, pStr);
> 	DebugStr(pStr);
> }
> 
> static void dprintf(const char *format, ...)
> {
>     va_list ap;
> 	char	*buffer;
> 
> 	va_start(ap, format);
> 	buffer = (char *)JS_vsmprintf(format, ap);
> 	va_end(ap);
177,208c160,161
< void
< JS_DumpHistogram(JSBasicStats *bs, FILE *fp)
< {
<     uintN bin;
<     uint32 cnt, max, prev, val, i;
<     double sum, mean;
< 
<     for (bin = 0, max = 0, sum = 0; bin <= 10; bin++) {
<         cnt = bs->hist[bin];
<         if (max < cnt)
<             max = cnt;
<         sum += cnt;
<     }
<     mean = sum / cnt;
<     for (bin = 0, prev = 0; bin <= 10; bin++, prev = val) {
<         val = BinToVal(bs->logscale, bin);
<         cnt = bs->hist[bin];
<         if (prev + 1 >= val)
<             fprintf(fp, "        [%6u]", val);
<         else
<             fprintf(fp, "[%6u, %6u]", prev + 1, val);
<         fprintf(fp, "%s %8u ", (bin == 10) ? "+" : ":", cnt);
<         if (cnt != 0) {
<             if (max > 1e6 && mean > 1e3)
<                 cnt = (uint32) ceil(log10(cnt));
<             else if (max > 16 && mean > 8)
<                 cnt = JS_CeilingLog2(cnt);
<             for (i = 0; i < cnt; i++)
<                 putc('*', fp);
<         }
<         putc('\n', fp);
<     }
---
> 	jsdebugstr(buffer);
> 	JS_DELETE(buffer);
209a163
> #endif   /* XP_MAC */
211,219c165,166
< #endif /* JS_BASIC_STATS */
< 
< #if defined DEBUG_notme && defined XP_UNIX
< 
< #define __USE_GNU 1
< #include <dlfcn.h>
< #include <string.h>
< #include "jshash.h"
< #include "jsprf.h"
---
> // 2003.09.09 jht: swat no prototype warning
> JS_PUBLIC_API(void) JS_Assert(const char *s, const char *file, JSIntn ln);
221d167
< JSCallsite js_calltree_root = {0, NULL, NULL, 0, NULL, NULL, NULL, NULL};
223,318c169
< static JSCallsite *
< CallTree(void **bp)
< {
<     void **bpup, **bpdown, *pc;
<     JSCallsite *parent, *site, **csp;
<     Dl_info info;
<     int ok, offset;
<     const char *symbol;
<     char *method;
< 
<     /* Reverse the stack frame list to avoid recursion. */
<     bpup = NULL;
<     for (;;) {
<         bpdown = (void**) bp[0];
<         bp[0] = (void*) bpup;
<         if ((void**) bpdown[0] < bpdown)
<             break;
<         bpup = bp;
<         bp = bpdown;
<     }
< 
<     /* Reverse the stack again, finding and building a path in the tree. */
<     parent = &js_calltree_root;
<     do {
<         bpup = (void**) bp[0];
<         bp[0] = (void*) bpdown;
<         pc = bp[1];
< 
<         csp = &parent->kids;
<         while ((site = *csp) != NULL) {
<             if (site->pc == pc) {
<                 /* Put the most recently used site at the front of siblings. */
<                 *csp = site->siblings;
<                 site->siblings = parent->kids;
<                 parent->kids = site;
< 
<                 /* Site already built -- go up the stack. */
<                 goto upward;
<             }
<             csp = &site->siblings;
<         }
< 
<         /* Check for recursion: see if pc is on our ancestor line. */
<         for (site = parent; site; site = site->parent) {
<             if (site->pc == pc)
<                 goto upward;
<         }
< 
<         /*
<          * Not in tree at all: let's find our symbolic callsite info.
<          * XXX static syms are masked by nearest lower global
<          */
<         info.dli_fname = info.dli_sname = NULL;
<         ok = dladdr(pc, &info);
<         if (ok < 0) {
<             fprintf(stderr, "dladdr failed!\n");
<             return NULL;
<         }
< 
< /* XXXbe sub 0x08040000? or something, see dbaron bug with tenthumbs comment */
<         symbol = info.dli_sname;
<         offset = (char*)pc - (char*)info.dli_fbase;
<         method = symbol
<                  ? strdup(symbol)
<                  : JS_smprintf("%s+%X",
<                                info.dli_fname ? info.dli_fname : "main",
<                                offset);
<         if (!method)
<             return NULL;
< 
<         /* Create a new callsite record. */
<         site = (JSCallsite *) malloc(sizeof(JSCallsite));
<         if (!site)
<             return NULL;
< 
<         /* Insert the new site into the tree. */
<         site->pc = pc;
<         site->name = method;
<         site->library = info.dli_fname;
<         site->offset = offset;
<         site->parent = parent;
<         site->siblings = parent->kids;
<         parent->kids = site;
<         site->kids = NULL;
< 
<       upward:
<         parent = site;
<         bpdown = bp;
<         bp = bpup;
<     } while (bp);
< 
<     return site;
< }
< 
< JSCallsite *
< JS_Backtrace(int skip)
---
> JS_PUBLIC_API(void) JS_Assert(const char *s, const char *file, JSIntn ln)
320,326c171,172
<     void **bp, **bpdown;
< 
<     /* Stack walking code adapted from Kipp's "leaky". */
< #if defined(__i386)
<     __asm__( "movl %%ebp, %0" : "=g"(bp));
< #elif defined(__x86_64__)
<     __asm__( "movq %%rbp, %0" : "=g"(bp));
---
> #ifdef XP_MAC
>     dprintf("Assertion failure: %s, at %s:%d\n", s, file, ln);
328,333c174,180
<     /*
<      * It would be nice if this worked uniformly, but at least on i386 and
<      * x86_64, it stopped working with gcc 4.1, because it points to the
<      * end of the saved registers instead of the start.
<      */
<     bp = (void**) __builtin_frame_address(0);
---
>     fprintf(stderr, "Assertion failure: %s, at %s:%d\n", s, file, ln);
> #endif
> #if defined(WIN32) || defined(XP_OS2)
>     DebugBreak();
> #endif
> #ifndef XP_MAC
> //    abort();
335,342d181
<     while (--skip >= 0) {
<         bpdown = (void**) *bp++;
<         if (bpdown < bp)
<             break;
<         bp = bpdown;
<     }
< 
<     return CallTree(bp);
344,345d182
< 
< #endif /* DEBUG_notme && XP_UNIX */
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsutil.h /Volumes/Swap/js_D11/src/jsutil.h
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
48a44,74
> /***********************************************************************
> ** FUNCTION:	JS_MALLOC()
> ** DESCRIPTION:
> **   JS_NEW() allocates an untyped item of size _size from the heap.
> ** INPUTS:  _size: size in bytes of item to be allocated
> ** OUTPUTS:	untyped pointer to the node allocated
> ** RETURN:	pointer to node or error returned from malloc().
> ***********************************************************************/
> #define JS_MALLOC(_bytes) (xmalloc((_bytes)))
> 
> /***********************************************************************
> ** FUNCTION:	JS_DELETE()
> ** DESCRIPTION:
> **   JS_DELETE() unallocates an object previosly allocated via JS_NEW()
> **   or JS_NEWZAP() to the heap.
> ** INPUTS:	pointer to previously allocated object
> ** OUTPUTS:	the referenced object is returned to the heap
> ** RETURN:	void
> ***********************************************************************/
> #define JS_DELETE(_ptr) { xfree(_ptr); (_ptr) = NULL; }
> 
> /***********************************************************************
> ** FUNCTION:	JS_NEW()
> ** DESCRIPTION:
> **   JS_NEW() allocates an item of type _struct from the heap.
> ** INPUTS:  _struct: a data type
> ** OUTPUTS:	pointer to _struct
> ** RETURN:	pointer to _struct or error returns from malloc().
> ***********************************************************************/
> #define JS_NEW(_struct) ((_struct *) JS_MALLOC(sizeof(_struct)))
> 
52a79,80
> #define JS_ASSERT(_expr) \
>     ((_expr)?((void)0):JS_Assert(# _expr,__FILE__,__LINE__))
54,61c82,83
< #define JS_ASSERT(expr)                                                       \
<     ((expr) ? (void)0 : JS_Assert(#expr, __FILE__, __LINE__))
< 
< #define JS_ASSERT_IF(cond, expr)                                              \
<     ((!(cond) || (expr)) ? (void)0 : JS_Assert(#expr, __FILE__, __LINE__))
< 
< #define JS_NOT_REACHED(reason)                                                \
<     JS_Assert(reason, __FILE__, __LINE__)
---
> #define JS_NOT_REACHED(_reasonStr) \
>     JS_Assert(_reasonStr,__FILE__,__LINE__)
65,67c87,88
< #define JS_ASSERT(expr)         ((void) 0)
< #define JS_ASSERT_IF(cond,expr) ((void) 0)
< #define JS_NOT_REACHED(reason)
---
> #define JS_ASSERT(expr) ((void) 0)
> #define JS_NOT_REACHED(reasonStr)
72,83c93,96
<  * Compile-time assert. "condition" must be a constant expression.
<  * The macro can be used only in places where an "extern" declaration is
<  * allowed.
<  */
< #define JS_STATIC_ASSERT(condition)                                           \
<     extern void js_static_assert(int arg[(condition) ? 1 : -1])
< 
< /*
<  * Abort the process in a non-graceful manner. This will cause a core file,
<  * call to the debugger or other moral equivalent as well as causing the
<  * entire process to stop.
<  */
---
> ** Abort the process in a non-graceful manner. This will cause a core file,
> ** call to the debugger or other moral equivalent as well as causing the
> ** entire process to stop.
> */
86,154d98
< #if 0
< # define JS_BASIC_STATS 1
< # define JS_SCOPE_DEPTH_METER 1
< #endif
< 
< #if defined DEBUG && !defined JS_BASIC_STATS
< # define JS_BASIC_STATS 1
< #endif
< 
< #ifdef JS_BASIC_STATS
< 
< #include <stdio.h>
< 
< typedef struct JSBasicStats {
<     uint32      num;
<     uint32      max;
<     double      sum;
<     double      sqsum;
<     uint32      logscale;           /* logarithmic scale: 0 (linear), 2, 10 */
<     uint32      hist[11];
< } JSBasicStats;
< 
< #define JS_INIT_STATIC_BASIC_STATS  {0,0,0,0,0,{0,0,0,0,0,0,0,0,0,0,0}}
< #define JS_BASIC_STATS_INIT(bs)     memset((bs), 0, sizeof(JSBasicStats))
< 
< #define JS_BASIC_STATS_ACCUM(bs,val)                                          \
<     JS_BasicStatsAccum(bs, val)
< 
< #define JS_MeanAndStdDevBS(bs,sigma)                                          \
<     JS_MeanAndStdDev((bs)->num, (bs)->sum, (bs)->sqsum, sigma)
< 
< extern void
< JS_BasicStatsAccum(JSBasicStats *bs, uint32 val);
< 
< extern double
< JS_MeanAndStdDev(uint32 num, double sum, double sqsum, double *sigma);
< 
< extern void
< JS_DumpBasicStats(JSBasicStats *bs, const char *title, FILE *fp);
< 
< extern void
< JS_DumpHistogram(JSBasicStats *bs, FILE *fp);
< 
< #else
< 
< #define JS_BASIC_STATS_ACCUM(bs,val) /* nothing */
< 
< #endif /* JS_BASIC_STATS */
< 
< 
< #ifdef XP_UNIX
< 
< typedef struct JSCallsite JSCallsite;
< 
< struct JSCallsite {
<     uint32      pc;
<     char        *name;
<     const char  *library;
<     int         offset;
<     JSCallsite  *parent;
<     JSCallsite  *siblings;
<     JSCallsite  *kids;
<     void        *handy;
< };
< 
< extern JSCallsite *JS_Backtrace(int skip);
< 
< #endif
< 
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsxdrapi.c /Volumes/Swap/js_D11/src/jsxdrapi.c
3,4c3,6
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
6,14c8,11
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,24c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
26,36c21
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
---
>  * Contributor(s): 
38c23,33
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
40,42d34
< #include "jsconfig.h"
< 
< #if JS_HAS_XDR
51d42
< #include "jsnum.h"
56a48,49
> #include "xstdlib.h"
> 
62a56,57
> //#include "_optimize.h"
> 
96c91
<                 MEM_BASE(xdr) = (char *) data_;                               \
---
>                 MEM_BASE(xdr) = data_;                                        \
126c121
< mem_getbytes(JSXDRState *xdr, char *bytes, uint32 len)
---
> mem_getbytes(JSXDRState *xdr, char **bytesp, uint32 len)
129c124
<     memcpy(bytes, MEM_DATA(xdr), len);
---
>     memcpy(*bytesp, MEM_DATA(xdr), len);
135c130
< mem_setbytes(JSXDRState *xdr, char *bytes, uint32 len)
---
> mem_setbytes(JSXDRState *xdr, char **bytesp, uint32 len)
138c133
<     memcpy(MEM_DATA(xdr), bytes, len);
---
>     memcpy(MEM_DATA(xdr), *bytesp, len);
236d230
<     xdr->script = NULL;
247c241
<         if (!(MEM_BASE(xdr) = (char *) JS_malloc(cx, MEM_BLOCK))) {
---
>         if (!(MEM_BASE(xdr) = JS_malloc(cx, MEM_BLOCK))) {
276c270
<     MEM_BASE(xdr) = (char *) data;
---
>     MEM_BASE(xdr) = data;
304c298
<             JS_DHashTableDestroy((JSDHashTable *) xdr->reghash);
---
>             JS_DHashTableDestroy(xdr->reghash);
344c338
< JS_XDRBytes(JSXDRState *xdr, char *bytes, uint32 len)
---
> JS_XDRBytes(JSXDRState *xdr, char **bytesp, uint32 len)
346a341
>     char *padbp;
350c345
<         if (!xdr->ops->setbytes(xdr, bytes, len))
---
>         if (!xdr->ops->setbytes(xdr, bytesp, len))
353c348
<         if (!xdr->ops->getbytes(xdr, bytes, len))
---
>         if (!xdr->ops->getbytes(xdr, bytesp, len))
360c355,356
<             if (!xdr->ops->setbytes(xdr, padbuf, padlen))
---
>             padbp = padbuf;
>             if (!xdr->ops->setbytes(xdr, &padbp, padlen))
387c383
<     if (!JS_XDRBytes(xdr, *sp, len)) {
---
>     if (!JS_XDRBytes(xdr, sp, len)) {
414,439d409
< static JSBool
< XDRChars(JSXDRState *xdr, jschar *chars, uint32 nchars)
< {
<     uint32 i, padlen, nbytes;
<     jschar *raw;
< 
<     nbytes = nchars * sizeof(jschar);
<     padlen = nbytes % JSXDR_ALIGN;
<     if (padlen) {
<         padlen = JSXDR_ALIGN - padlen;
<         nbytes += padlen;
<     }
<     if (!(raw = (jschar *) xdr->ops->raw(xdr, nbytes)))
<         return JS_FALSE;
<     if (xdr->mode == JSXDR_ENCODE) {
<         for (i = 0; i != nchars; i++)
<             raw[i] = JSXDR_SWAB16(chars[i]);
<         if (padlen)
<             memset((char *)raw + nbytes - padlen, 0, padlen);
<     } else if (xdr->mode == JSXDR_DECODE) {
<         for (i = 0; i != nchars; i++)
<             chars[i] = JSXDR_SWAB16(raw[i]);
<     }
<     return JS_TRUE;
< }
< 
446,447c416,417
<     uint32 nchars;
<     jschar *chars;
---
>     uint32 i, len, padlen, nbytes;
>     jschar *chars = NULL, *raw;
450,451c420,421
<         nchars = JSSTRING_LENGTH(*strp);
<     if (!JS_XDRUint32(xdr, &nchars))
---
>         len = JSSTRING_LENGTH(*strp);
>     if (!JS_XDRUint32(xdr, &len))
452a423
>     nbytes = len * sizeof(jschar);
455,456c426
<         chars = (jschar *) JS_malloc(xdr->cx, (nchars + 1) * sizeof(jschar));
<         if (!chars)
---
>         if (!(chars = (jschar *) JS_malloc(xdr->cx, nbytes + sizeof(jschar))))
462c432,437
<     if (!XDRChars(xdr, chars, nchars))
---
>     padlen = nbytes % JSXDR_ALIGN;
>     if (padlen) {
>         padlen = JSXDR_ALIGN - padlen;
>         nbytes += padlen;
>     }
>     if (!(raw = (jschar *) xdr->ops->raw(xdr, nbytes)))
464,467c439,461
<     if (xdr->mode == JSXDR_DECODE) {
<         chars[nchars] = 0;
<         *strp = JS_NewUCString(xdr->cx, chars, nchars);
<         if (!*strp)
---
>     if (xdr->mode == JSXDR_ENCODE) {
>     
>         // !!@ DP MOD
>         // Can't char map raw since byte swapped on Mac
>         x_CharacterRemapUC(xdr->cx, chars, len, kMapCharToFile );
>         
>         for (i = 0; i < len; i++)
>             raw[i] = JSXDR_SWAB16(chars[i]);
>         if (padlen)
>             memset((char *)raw + nbytes - padlen, 0, padlen);
>             
>         // !!@ DP MOD
>         x_CharacterRemapUC(xdr->cx, chars, len, kMapCharToNative );
>         
>     } else if (xdr->mode == JSXDR_DECODE) {
>         for (i = 0; i < len; i++)
>             chars[i] = JSXDR_SWAB16(raw[i]);
>         chars[len] = 0;
>         
>         // !!@ DP MOD
>         x_CharacterRemapUC(xdr->cx, chars, len, kMapCharToNative );
> 
>         if (!(*strp = JS_NewUCString(xdr->cx, chars, len)))
491,504d484
< static JSBool
< XDRDoubleValue(JSXDRState *xdr, jsdouble *dp)
< {
<     jsdpun u;
< 
<     if (xdr->mode == JSXDR_ENCODE)
<         u.d = *dp;
<     if (!JS_XDRUint32(xdr, &u.s.lo) || !JS_XDRUint32(xdr, &u.s.hi))
<         return JS_FALSE;
<     if (xdr->mode == JSXDR_DECODE)
<         *dp = u.d;
<     return JS_TRUE;
< }
< 
506c486
< JS_XDRDouble(JSXDRState *xdr, jsdouble **dpp)
---
> JS_XDRDouble(JSXDRState *xdr, jsdouble **dp)
509d488
< 
511,512c490,497
<         d = **dpp;
<     if (!XDRDoubleValue(xdr, &d))
---
>         d = **dp;
> #if IS_BIG_ENDIAN
>     if (!JS_XDRUint32(xdr, (uint32 *)&d + 1) ||
>         !JS_XDRUint32(xdr, (uint32 *)&d))
> #else
>     if (!JS_XDRUint32(xdr, (uint32 *)&d) ||
>         !JS_XDRUint32(xdr, (uint32 *)&d + 1))
> #endif
515,516c500,501
<         *dpp = JS_NewDouble(xdr->cx, d);
<         if (!*dpp)
---
>         *dp = JS_NewDouble(xdr->cx, d);
>         if (!*dp)
526,527c511,512
< static JSBool
< XDRValueBody(JSXDRState *xdr, uint32 type, jsval *vp)
---
> JS_PUBLIC_API(JSBool)
> JS_XDRValue(JSXDRState *xdr, jsval *vp)
528a514,526
>     uint32 type;
>     
>     if (xdr->mode == JSXDR_ENCODE) {
>         if (JSVAL_IS_NULL(*vp))
>             type = JSVAL_XDRNULL;
>         else if (JSVAL_IS_VOID(*vp))
>             type = JSVAL_XDRVOID;
>         else
>             type = JSVAL_TAG(*vp);
>     }
>     if (!JS_XDRUint32(xdr, &type))
>         return JS_FALSE;
> 
593,687d590
< JS_XDRValue(JSXDRState *xdr, jsval *vp)
< {
<     uint32 type;
< 
<     if (xdr->mode == JSXDR_ENCODE) {
<         if (JSVAL_IS_NULL(*vp))
<             type = JSVAL_XDRNULL;
<         else if (JSVAL_IS_VOID(*vp))
<             type = JSVAL_XDRVOID;
<         else
<             type = JSVAL_TAG(*vp);
<     }
<     return JS_XDRUint32(xdr, &type) && XDRValueBody(xdr, type, vp);
< }
< 
< JSBool
< js_XDRAtom(JSXDRState *xdr, JSAtom **atomp)
< {
<     jsval v;
<     uint32 type;
<     jsdouble d;
< 
<     if (xdr->mode == JSXDR_ENCODE) {
<         v = ATOM_KEY(*atomp);
<         return JS_XDRValue(xdr, &v);
<     }
< 
<     /*
<      * Inline JS_XDRValue when decoding to avoid ceation of GC things when
<      * then corresponding atom already exists. See bug 321985.
<      */
<     if (!JS_XDRUint32(xdr, &type))
<         return JS_FALSE;
<     if (type == JSVAL_STRING)
<         return js_XDRStringAtom(xdr, atomp);
< 
<     if (type == JSVAL_DOUBLE) {
<         if (!XDRDoubleValue(xdr, &d))
<             return JS_FALSE;
<         *atomp = js_AtomizeDouble(xdr->cx, d);
<         return *atomp != NULL;
<     }
< 
<     return XDRValueBody(xdr, type, &v) &&
<            js_AtomizePrimitiveValue(xdr->cx, v, atomp);
< }
< 
< extern JSBool
< js_XDRStringAtom(JSXDRState *xdr, JSAtom **atomp)
< {
<     JSString *str;
<     uint32 nchars;
<     JSAtom *atom;
<     JSContext *cx;
<     jschar *chars;
<     jschar stackChars[256];
< 
<     if (xdr->mode == JSXDR_ENCODE) {
<         JS_ASSERT(ATOM_IS_STRING(*atomp));
<         str = ATOM_TO_STRING(*atomp);
<         return JS_XDRString(xdr, &str);
<     }
< 
<     /*
<      * Inline JS_XDRString when decoding to avoid JSString allocation
<      * for already existing atoms. See bug 321985.
<      */
<     if (!JS_XDRUint32(xdr, &nchars))
<         return JS_FALSE;
<     atom = NULL;
<     cx = xdr->cx;
<     if (nchars <= JS_ARRAY_LENGTH(stackChars)) {
<         chars = stackChars;
<     } else {
<         /*
<          * This is very uncommon. Don't use the tempPool arena for this as
<          * most allocations here will be bigger than tempPool's arenasize.
<          */
<         chars = (jschar *) JS_malloc(cx, nchars * sizeof(jschar));
<         if (!chars)
<             return JS_FALSE;
<     }
< 
<     if (XDRChars(xdr, chars, nchars))
<         atom = js_AtomizeChars(cx, chars, nchars, 0);
<     if (chars != stackChars)
<         JS_free(cx, chars);
< 
<     if (!atom)
<         return JS_FALSE;
<     *atomp = atom;
<     return JS_TRUE;
< }
< 
< JS_PUBLIC_API(JSBool)
731,732c634
<             JS_DHashTableOperate((JSDHashTable *) xdr->reghash,
<                                  clasp->name, JS_DHASH_ADD);
---
>             JS_DHashTableOperate(xdr->reghash, clasp->name, JS_DHASH_ADD);
756,759c658,660
<             xdr->reghash =
<                 JS_NewDHashTable(JS_DHashGetStubOps(), NULL,
<                                  sizeof(JSRegHashEntry),
<                                  JS_DHASH_DEFAULT_CAPACITY(numclasses));
---
>             xdr->reghash = JS_NewDHashTable(JS_DHashGetStubOps(), NULL,
>                                             sizeof(JSRegHashEntry),
>                                             numclasses);
764,765c665,666
<                         JS_DHashTableOperate((JSDHashTable *) xdr->reghash,
<                                              clasp->name, JS_DHASH_ADD);
---
>                         JS_DHashTableOperate(xdr->reghash, clasp->name,
>                                              JS_DHASH_ADD);
775,776c676
<                 JS_DHashTableOperate((JSDHashTable *) xdr->reghash,
<                                      name, JS_DHASH_LOOKUP);
---
>                 JS_DHashTableOperate(xdr->reghash, name, JS_DHASH_LOOKUP);
799,800d698
< 
< #endif /* JS_HAS_XDR */
diff -r /Volumes/Swap/js-14-2-2008/js/src/jsxdrapi.h /Volumes/Swap/js_D11/src/jsxdrapi.h
2d1
<  * vim: set ts=8 sw=4 et tw=78:
4,15c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
20,39c16,33
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
101,102c95,96
<     JSBool      (*getbytes)(JSXDRState *, char *, uint32);
<     JSBool      (*setbytes)(JSXDRState *, char *, uint32);
---
>     JSBool      (*getbytes)(JSXDRState *, char **, uint32);
>     JSBool      (*setbytes)(JSXDRState *, char **, uint32);
118d111
<     JSScript    *script;
152c145
< JS_XDRBytes(JSXDRState *xdr, char *bytes, uint32 len);
---
> JS_XDRBytes(JSXDRState *xdr, char **bytes, uint32 len);
190,214c183
< #define JSXDR_MAGIC_SCRIPT_4        0xdead0004
< #define JSXDR_MAGIC_SCRIPT_5        0xdead0005
< #define JSXDR_MAGIC_SCRIPT_6        0xdead0006
< #define JSXDR_MAGIC_SCRIPT_7        0xdead0007
< #define JSXDR_MAGIC_SCRIPT_CURRENT  JSXDR_MAGIC_SCRIPT_7
< 
< /*
<  * Bytecode version number.  Decrement the second term whenever JS bytecode
<  * changes incompatibly.
<  *
<  * This version number should be XDR'ed once near the front of any file or
<  * larger storage unit containing XDR'ed bytecode and other data, and checked
<  * before deserialization of bytecode.  If the saved version does not match
<  * the current version, abort deserialization and invalidate the file.
<  */
< #define JSXDR_BYTECODE_VERSION      (0xb973c0de - 19)
< 
< /*
<  * Library-private functions.
<  */
< extern JSBool
< js_XDRAtom(JSXDRState *xdr, JSAtom **atomp);
< 
< extern JSBool
< js_XDRStringAtom(JSXDRState *xdr, JSAtom **atomp);
---
> #define JSXDR_MAGIC_SCRIPT_CURRENT  JSXDR_MAGIC_SCRIPT_3
Only in /Volumes/Swap/js-14-2-2008/js/src: jsxml.c
Only in /Volumes/Swap/js-14-2-2008/js/src: jsxml.h
Only in /Volumes/Swap/js-14-2-2008/js/src: lock_SunOS.s
Only in /Volumes/Swap/js-14-2-2008/js/src: perfect.js
Only in /Volumes/Swap/js-14-2-2008/js/src: plify_jsdhash.sed
diff -r /Volumes/Swap/js-14-2-2008/js/src/prmjtime.c /Volumes/Swap/js_D11/src/prmjtime.c
3,4c3,6
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
6,14c8,11
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,24c16,19
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
26,36c21
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
---
>  * Contributor(s): 
38c23,33
<  * ***** END LICENSE BLOCK ***** */
---
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
53d47
< #include "jslock.h"
55a50,51
> //#include "_optimize.h"
> 
62,72d57
< #include <windef.h>
< #include <winbase.h>
< #include <math.h>     /* for fabs */
< #include <mmsystem.h> /* for timeBegin/EndPeriod */
< #if _MSC_VER >= 1400 /* VC++ 8.0 or later */
< #define NS_HAVE_INVALID_PARAMETER_HANDLER 1
< #endif
< #ifdef NS_HAVE_INVALID_PARAMETER_HANDLER
< #include <stdlib.h>   /* for _set_invalid_parameter_handler */
< #include <crtdbg.h>   /* for _CrtSetReportMode */
< #endif
74,75c59,76
< #ifdef JS_THREADSAFE
< #include <prinit.h>
---
> /* !!@@!! jht: Director defines are in conflict */
> #undef WINVER
> #undef _WINVER
> 
> #include <WINDEF.H>
> #include <WINBASE.H>
> #endif
> 
> #ifdef XP_MAC
> #include <OSUtils.h>
> #include <TextUtils.h>
> #include <Resources.h>
> #include <Timer.h>
> #include <UTCUtils.h>
> #include <Power.h>
> #include <CodeFragments.h>
> #if !TARGET_CARBON
> #include <Traps.h>
77d77
< 
90,93c90,218
< #define PRMJ_YEAR_DAYS 365L
< #define PRMJ_FOUR_YEARS_DAYS (4 * PRMJ_YEAR_DAYS + 1)
< #define PRMJ_CENTURY_DAYS (25 * PRMJ_FOUR_YEARS_DAYS - 1)
< #define PRMJ_FOUR_CENTURIES_DAYS (4 * PRMJ_CENTURY_DAYS + 1)
---
> #ifdef XP_MAC
> static uint64 			 dstLocalBaseMicroseconds;
> static unsigned long	 gJanuaryFirst1970Seconds;
> 
> static void MacintoshInitializeTime(void)
> {
>     uint64					upTime;
>     unsigned long			currentLocalTimeSeconds,
> 	   startupTimeSeconds;
>     uint64				startupTimeMicroSeconds;
>     uint32				upTimeSeconds;
>     uint64				oneMillion, upTimeSecondsLong, microSecondsToSeconds;
>     DateTimeRec				firstSecondOfUnixTime;
> 
>     /*
>      * Figure out in local time what time the machine started up. This information can be added to
>      * upTime to figure out the current local time as well as GMT.
>      */
> 
>     Microseconds((UnsignedWide*)&upTime);
> 
>     GetDateTime(&currentLocalTimeSeconds);
> 
>     JSLL_I2L(microSecondsToSeconds, PRMJ_USEC_PER_SEC);
>     JSLL_DIV(upTimeSecondsLong, upTime, microSecondsToSeconds);
>     JSLL_L2I(upTimeSeconds, upTimeSecondsLong);
> 
>     startupTimeSeconds = currentLocalTimeSeconds - upTimeSeconds;
> 
>     /*  Make sure that we normalize the macintosh base seconds to the unix base of January 1, 1970.
>      */
> 
>     firstSecondOfUnixTime.year = 1970;
>     firstSecondOfUnixTime.month = 1;
>     firstSecondOfUnixTime.day = 1;
>     firstSecondOfUnixTime.hour = 0;
>     firstSecondOfUnixTime.minute = 0;
>     firstSecondOfUnixTime.second = 0;
>     firstSecondOfUnixTime.dayOfWeek = 0;
> 
>     DateToSeconds(&firstSecondOfUnixTime, &gJanuaryFirst1970Seconds);
> 
>     startupTimeSeconds -= gJanuaryFirst1970Seconds;
> 
>     /*  Now convert the startup time into a wide so that we can figure out GMT and DST.
>      */
> 
>     JSLL_I2L(startupTimeMicroSeconds, startupTimeSeconds);
>     JSLL_I2L(oneMillion, PRMJ_USEC_PER_SEC);
>     JSLL_MUL(dstLocalBaseMicroseconds, oneMillion, startupTimeMicroSeconds);
> }
> 
> static SleepQRec  gSleepQEntry = { NULL, sleepQType, NULL, 0 };
> static JSBool     gSleepQEntryInstalled = JS_FALSE;
> 
> static pascal long MySleepQProc(long message, SleepQRecPtr sleepQ)
> {
>     /* just woke up from sleeping, so must recompute dstLocalBaseMicroseconds. */
>     if (message == kSleepWakeUp)
>         MacintoshInitializeTime();
>     return 0;
> }
> 
> /* Because serial port and SLIP conflict with ReadXPram calls,
>  * we cache the call here
>  */
> 
> static void MyReadLocation(MachineLocation * loc)
> {
>     static MachineLocation storedLoc;	/* InsideMac, OSUtilities, page 4-20 */
>     static JSBool didReadLocation = JS_FALSE;
>     if (!didReadLocation)
>     {
>         MacintoshInitializeTime();
>         ReadLocation(&storedLoc);
>         /* install a sleep queue routine, so that when the machine wakes up, time can be recomputed. */
>         if (&SleepQInstall != (void*)kUnresolvedCFragSymbolAddress
> #if !TARGET_CARBON
>             && NGetTrapAddress(0xA28A, OSTrap) != NGetTrapAddress(_Unimplemented, ToolTrap)
> #endif
>            ) {
>             if ((gSleepQEntry.sleepQProc = NewSleepQUPP(MySleepQProc)) != NULL) {
>                 SleepQInstall(&gSleepQEntry);
>                 gSleepQEntryInstalled = JS_TRUE;
>             }
>         }
>         didReadLocation = JS_TRUE;
>      }
>      *loc = storedLoc;
> }
> 
> 
> #ifndef XP_MACOSX
> #if !(defined(__APPLE__) && defined(__MACH__))
> 
> /* CFM library init and terminate routines. We'll use the terminate routine
>    to clean up the sleep Q entry. On Mach-O, the sleep Q entry gets cleaned
>    up for us, so nothing to do there.
> */
> 
> extern pascal OSErr __NSInitialize(const CFragInitBlock* initBlock);
> extern pascal void __NSTerminate();
> 
> pascal OSErr __JSInitialize(const CFragInitBlock* initBlock);
> pascal void __JSTerminate(void);
> 
> pascal OSErr __JSInitialize(const CFragInitBlock* initBlock)
> {
> 	return __NSInitialize(initBlock);
> }
> 
> pascal void __JSTerminate()
> {
>   /* clean up the sleepQ entry */
>   if (gSleepQEntryInstalled)
>     SleepQRemove(&gSleepQEntry);
>   
> 	__NSTerminate();
> }
> #endif // (defined(__APPLE__) && defined(__MACH__))
> #endif /* XP_MACOSX */
> 
> #endif /* XP_MAC */
> 
> #define IS_LEAP(year) \
>    (year != 0 && ((((year & 0x3) == 0) &&  \
> 		   ((year - ((year/100) * 100)) != 0)) || \
> 		  (year - ((year/400) * 400)) == 0))
> 
96c221
< #define PRMJ_YEAR_SECONDS (PRMJ_DAY_SECONDS * PRMJ_YEAR_DAYS)
---
> #define PRMJ_YEAR_SECONDS (PRMJ_DAY_SECONDS * 365L)
98d222
< 
106a231
> #if defined(XP_UNIX) || defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS)
118c243,283
<     return (JSInt32)mktime(&ltime) - (24L * 3600L);
---
>     return mktime(&ltime) - (24L * 3600L);
> #endif
> #endif
> #if defined(XP_MAC)
>     static JSInt32   zone = -1L;
>     MachineLocation  machineLocation;
>     JSInt32 	     gmtOffsetSeconds;
> 
>     /* difference has been set no need to recalculate */
>     if (zone != -1)
>         return zone;
> 
>     /* Get the information about the local machine, including
>      * its GMT offset and its daylight savings time info.
>      * Convert each into wides that we can add to
>      * startupTimeMicroSeconds.
>      */
> 
>     MyReadLocation(&machineLocation);
> 
>     /* Mask off top eight bits of gmtDelta, sign extend lower three. */
>     gmtOffsetSeconds = (machineLocation.u.gmtDelta << 8);
>     gmtOffsetSeconds >>= 8;
> 
>     /* Backout OS adjustment for DST, to give consistent GMT offset. */
> 	{
> 		int dlsDelta = 0;
> #if (defined(__APPLE__) && defined(__MACH__))
> 	// i think this change happened for 10.4 SDK
> 	#if TARGET_RT_BIG_ENDIAN
> 		dlsDelta = machineLocation.u.dlsDelta;	
> 	#else
> 		dlsDelta = machineLocation.u.dls.Delta;
> 	#endif
> #else
> 	    dlsDelta = machineLocation.u.dlsDelta;
> #endif
> 	    if (dlsDelta != 0)
> 	        gmtOffsetSeconds -= PRMJ_HOUR_SECONDS;
>     }
>     return (zone = -gmtOffsetSeconds);
161,335d325
< #ifdef XP_WIN
< typedef struct CalibrationData
< {
<     long double freq;         /* The performance counter frequency */
<     long double offset;       /* The low res 'epoch' */
<     long double timer_offset; /* The high res 'epoch' */
< 
<     /* The last high res time that we returned since recalibrating */
<     JSInt64 last;
< 
<     JSBool calibrated;
< 
< #ifdef JS_THREADSAFE
<     CRITICAL_SECTION data_lock;
<     CRITICAL_SECTION calibration_lock;
< #endif
< } CalibrationData;
< 
< static const JSInt64 win2un = JSLL_INIT(0x19DB1DE, 0xD53E8000);
< 
< static CalibrationData calibration = { 0 };
< 
< #define FILETIME2INT64(ft) (((JSInt64)ft.dwHighDateTime) << 32LL | (JSInt64)ft.dwLowDateTime)
< 
< static void
< NowCalibrate()
< {
<     FILETIME ft, ftStart;
<     LARGE_INTEGER liFreq, now;
< 
<     if (calibration.freq == 0.0) {
<         if(!QueryPerformanceFrequency(&liFreq)) {
<             /* High-performance timer is unavailable */
<             calibration.freq = -1.0;
<         } else {
<             calibration.freq = (long double) liFreq.QuadPart;
<         }
<     } 
<     if (calibration.freq > 0.0) {
<         JSInt64 calibrationDelta = 0;
< 
<         /* By wrapping a timeBegin/EndPeriod pair of calls around this loop,
<            the loop seems to take much less time (1 ms vs 15ms) on Vista. */
<         timeBeginPeriod(1);
<         GetSystemTimeAsFileTime(&ftStart);
<         do {
<             GetSystemTimeAsFileTime(&ft);
<         } while (memcmp(&ftStart,&ft, sizeof(ft)) == 0);
<         timeEndPeriod(1);
< 
<         /*
<         calibrationDelta = (FILETIME2INT64(ft) - FILETIME2INT64(ftStart))/10;
<         fprintf(stderr, "Calibration delta was %I64d us\n", calibrationDelta);
<         */
< 
<         QueryPerformanceCounter(&now);
< 
<         calibration.offset = (long double) FILETIME2INT64(ft);
<         calibration.timer_offset = (long double) now.QuadPart;
< 
<         /* The windows epoch is around 1600. The unix epoch is around
<            1970. win2un is the difference (in windows time units which
<            are 10 times more highres than the JS time unit) */
<         calibration.offset -= win2un;
<         calibration.offset *= 0.1;
<         calibration.last = 0;
< 
<         calibration.calibrated = JS_TRUE;
<     }
< }
< 
< #define CALIBRATIONLOCK_SPINCOUNT 0
< #define DATALOCK_SPINCOUNT 4096
< #define LASTLOCK_SPINCOUNT 4096
< 
< #ifdef JS_THREADSAFE
< static PRStatus PR_CALLBACK
< NowInit(void)
< {
<     memset(&calibration, 0, sizeof(calibration));
<     NowCalibrate();
<     InitializeCriticalSectionAndSpinCount(&calibration.calibration_lock, CALIBRATIONLOCK_SPINCOUNT);
<     InitializeCriticalSectionAndSpinCount(&calibration.data_lock, DATALOCK_SPINCOUNT);
<     return PR_SUCCESS;
< }
< 
< void
< PRMJ_NowShutdown()
< {
<     DeleteCriticalSection(&calibration.calibration_lock);
<     DeleteCriticalSection(&calibration.data_lock);
< }
< 
< #define MUTEX_LOCK(m) EnterCriticalSection(m)
< #define MUTEX_TRYLOCK(m) TryEnterCriticalSection(m)
< #define MUTEX_UNLOCK(m) LeaveCriticalSection(m)
< #define MUTEX_SETSPINCOUNT(m, c) SetCriticalSectionSpinCount((m),(c))
< 
< static PRCallOnceType calibrationOnce = { 0 };
< 
< #else
< 
< #define MUTEX_LOCK(m)
< #define MUTEX_TRYLOCK(m) 1
< #define MUTEX_UNLOCK(m)
< #define MUTEX_SETSPINCOUNT(m, c)
< 
< #endif
< 
< 
< #endif /* XP_WIN */
< 
< /*
< 
< Win32 python-esque pseudo code
< Please see bug 363258 for why the win32 timing code is so complex.
< 
< calibration mutex : Win32CriticalSection(spincount=0)
< data mutex : Win32CriticalSection(spincount=4096)
< 
< def NowInit():
<   init mutexes
<   PRMJ_NowCalibration()
< 
< def NowCalibration():
<   expensive up-to-15ms call
< 
< def PRMJ_Now():
<   returnedTime = 0
<   needCalibration = False
<   cachedOffset = 0.0
<   calibrated = False
<   PR_CallOnce(PRMJ_NowInit)
<   do
<     if not global.calibrated or needCalibration:
<       acquire calibration mutex
<         acquire data mutex
< 
<           // Only recalibrate if someone didn't already
<           if cachedOffset == calibration.offset:
<             // Have all waiting threads immediately wait 
<             set data mutex spin count = 0
<             PRMJ_NowCalibrate()
<             calibrated = 1
< 
<             set data mutex spin count = default
<         release data mutex
<       release calibration mutex
< 
<     calculate lowres time
< 
<     if highres timer available:
<       acquire data mutex
<         calculate highres time
<         cachedOffset = calibration.offset
<         highres time = calibration.last = max(highres time, calibration.last)
<       release data mutex
< 
<       get kernel tick interval
< 
<       if abs(highres - lowres) < kernel tick:
<         returnedTime = highres time
<         needCalibration = False
<       else:
<         if calibrated:
<           returnedTime = lowres
<           needCalibration = False
<         else:
<           needCalibration = True
<     else:
<       returnedTime = lowres
<   while needCalibration
< 
< */
< 
344,351c334,337
<     static int nCalls = 0;
<     long double lowresTime, highresTimerValue;
<     FILETIME ft;
<     LARGE_INTEGER now;
<     JSBool calibrated = JS_FALSE;
<     JSBool needsCalibration = JS_FALSE;
<     JSInt64 returnedTime;
<     long double cachedOffset = 0.0;
---
>     JSInt64 s, us,
>     win2un = JSLL_INIT(0x19DB1DE, 0xD53E8000),
>     ten = JSLL_INIT(0, 10);
>     FILETIME time, midnight;
356a343,350
> #ifdef XP_MAC
>     JSUint64 upTime;
>     JSInt64	 localTime;
>     JSInt64       gmtOffset;
>     JSInt64    dstOffset;
>     JSInt32       gmtDiff;
>     JSInt64	 s2us;
> #endif /* XP_MAC */
370,495c364,382
< 
<     /* To avoid regressing startup time (where high resolution is likely
<        not needed), give the old behavior for the first few calls.
<        This does not appear to be needed on Vista as the timeBegin/timeEndPeriod
<        calls seem to immediately take effect. */
<     int thiscall = JS_ATOMIC_INCREMENT(&nCalls);
<     /* 10 seems to be the number of calls to load with a blank homepage */
<     if (thiscall <= 10) {
<         GetSystemTimeAsFileTime(&ft);
<         return (FILETIME2INT64(ft)-win2un)/10L;
<     }
< 
<     /* For non threadsafe platforms, NowInit is not necessary */
< #ifdef JS_THREADSAFE
<     PR_CallOnce(&calibrationOnce, NowInit);
< #endif
<     do {
<         if (!calibration.calibrated || needsCalibration) {
<             MUTEX_LOCK(&calibration.calibration_lock);
<             MUTEX_LOCK(&calibration.data_lock);
< 
<             /* Recalibrate only if no one else did before us */
<             if(calibration.offset == cachedOffset) {
<                 /* Since calibration can take a while, make any other
<                    threads immediately wait */
<                 MUTEX_SETSPINCOUNT(&calibration.data_lock, 0);
< 
<                 NowCalibrate();
< 
<                 calibrated = JS_TRUE;
< 
<                 /* Restore spin count */
<                 MUTEX_SETSPINCOUNT(&calibration.data_lock, DATALOCK_SPINCOUNT);
<             }
<             MUTEX_UNLOCK(&calibration.data_lock);
<             MUTEX_UNLOCK(&calibration.calibration_lock);
<         }
< 
< 
<         /* Calculate a low resolution time */
<         GetSystemTimeAsFileTime(&ft);
<         lowresTime = 0.1*(long double)(FILETIME2INT64(ft) - win2un);
< 
<         if (calibration.freq > 0.0) {
<             long double highresTime, diff;
< 
<             DWORD timeAdjustment, timeIncrement;
<             BOOL timeAdjustmentDisabled;
< 
<             /* Default to 15.625 ms if the syscall fails */
<             long double skewThreshold = 15625.25;
<             /* Grab high resolution time */
<             QueryPerformanceCounter(&now);
<             highresTimerValue = (long double)now.QuadPart;
< 
<             MUTEX_LOCK(&calibration.data_lock);
<             highresTime = calibration.offset + PRMJ_USEC_PER_SEC*
<                  (highresTimerValue-calibration.timer_offset)/calibration.freq;
<             cachedOffset = calibration.offset;
< 
<             /* On some dual processor/core systems, we might get an earlier time
<                so we cache the last time that we returned */
<             calibration.last = max(calibration.last,(JSInt64)highresTime);
<             returnedTime = calibration.last;
<             MUTEX_UNLOCK(&calibration.data_lock);
< 
<             /* Rather than assume the NT kernel ticks every 15.6ms, ask it */
<             if (GetSystemTimeAdjustment(&timeAdjustment,
<                                         &timeIncrement,
<                                         &timeAdjustmentDisabled)) {
<                 if (timeAdjustmentDisabled) {
<                     /* timeAdjustment is in units of 100ns */
<                     skewThreshold = timeAdjustment/10.0;
<                 } else {
<                     /* timeIncrement is in units of 100ns */
<                     skewThreshold = timeIncrement/10.0;
<                 }
<             }
< 
<             /* Check for clock skew */
<             diff = lowresTime - highresTime;
< 
<             /* For some reason that I have not determined, the skew can be
<                up to twice a kernel tick. This does not seem to happen by
<                itself, but I have only seen it triggered by another program
<                doing some kind of file I/O. The symptoms are a negative diff
<                followed by an equally large positive diff. */
<             if (fabs(diff) > 2*skewThreshold) {
<                 /*fprintf(stderr,"Clock skew detected (diff = %f)!\n", diff);*/
< 
<                 if (calibrated) {
<                     /* If we already calibrated once this instance, and the
<                        clock is still skewed, then either the processor(s) are
<                        wildly changing clockspeed or the system is so busy that
<                        we get switched out for long periods of time. In either
<                        case, it would be infeasible to make use of high
<                        resolution results for anything, so let's resort to old
<                        behavior for this call. It's possible that in the
<                        future, the user will want the high resolution timer, so
<                        we don't disable it entirely. */
<                     returnedTime = (JSInt64)lowresTime;
<                     needsCalibration = JS_FALSE;
<                 } else { 
<                     /* It is possible that when we recalibrate, we will return a
<                        value less than what we have returned before; this is
<                        unavoidable. We cannot tell the different between a
<                        faulty QueryPerformanceCounter implementation and user
<                        changes to the operating system time. Since we must
<                        respect user changes to the operating system time, we
<                        cannot maintain the invariant that Date.now() never
<                        decreases; the old implementation has this behavior as
<                        well. */
<                     needsCalibration = JS_TRUE;
<                 }
<             } else {
<                 /* No detectable clock skew */
<                 returnedTime = (JSInt64)highresTime;
<                 needsCalibration = JS_FALSE;
<             }
<         } else {
<             /* No high resolution timer is available, so fall back */
<             returnedTime = (JSInt64)lowresTime;
<         }
<     } while (needsCalibration);
< 
<     return returnedTime;
---
>     /* The windows epoch is around 1600. The unix epoch is around 1970.
>        win2un is the difference (in windows time units which are 10 times
>        more precise than the JS time unit) */
>     GetSystemTimeAsFileTime(&time);
>     /* Win9x gets confused at midnight
>        http://support.microsoft.com/default.aspx?scid=KB;en-us;q224423
>        So if the low part (precision <8mins) is 0 then we get the time
>        again. */
>     if (!time.dwLowDateTime) {
>         GetSystemTimeAsFileTime(&midnight);
>         time.dwHighDateTime = midnight.dwHighDateTime;
>     }
>     JSLL_UI2L(s, time.dwHighDateTime);
>     JSLL_UI2L(us, time.dwLowDateTime);
>     JSLL_SHL(s, s, 32);
>     JSLL_ADD(s, s, us);
>     JSLL_SUB(s, s, win2un);
>     JSLL_DIV(s, s, ten);
>     return s;
510a398,415
> #ifdef XP_MAC
>     JSLL_UI2L(localTime,0);
>     gmtDiff = PRMJ_LocalGMTDifference();
>     JSLL_I2L(gmtOffset,gmtDiff);
>     JSLL_UI2L(s2us, PRMJ_USEC_PER_SEC);
>     JSLL_MUL(gmtOffset,gmtOffset,s2us);
> 
>     /* don't adjust for DST since it sets ctime and gmtime off on the MAC */
>     Microseconds((UnsignedWide*)&upTime);
>     JSLL_ADD(localTime,localTime,gmtOffset);
>     JSLL_ADD(localTime,localTime, dstLocalBaseMicroseconds);
>     JSLL_ADD(localTime,localTime, upTime);
> 
>     dstOffset = PRMJ_DSTOffset(localTime);
>     JSLL_SUB(localTime,localTime,dstOffset);
> 
>     return *((JSUint64 *)&localTime);
> #endif /* XP_MAC */
517a423,440
> #ifdef XP_MAC
>     /*
>      * Convert the local time passed in to Macintosh epoch seconds. Use UTC utilities to convert
>      * to UTC time, then compare difference with our GMT offset. If they are the same, then
>      * DST must not be in effect for the input date/time.
>      */
>     UInt32 macLocalSeconds = (local_time / PRMJ_USEC_PER_SEC) + gJanuaryFirst1970Seconds, utcSeconds;
>     ConvertLocalTimeToUTC(macLocalSeconds, &utcSeconds);
>     if ((utcSeconds - macLocalSeconds) == PRMJ_LocalGMTDifference())
>         return 0;
>     else {
>         JSInt64 dlsOffset;
>     	JSLL_UI2L(us2s, PRMJ_USEC_PER_SEC);
>     	JSLL_UI2L(dlsOffset, PRMJ_HOUR_SECONDS);
>     	JSLL_MUL(dlsOffset, dlsOffset, us2s);
>         return dlsOffset;
>     }
> #else
564,575d486
< }
< 
< #ifdef NS_HAVE_INVALID_PARAMETER_HANDLER
< JS_STATIC_DLL_CALLBACK(void)
< PRMJ_InvalidParameterHandler(const wchar_t *expression,
<                              const wchar_t *function, 
<                              const wchar_t *file, 
<                              unsigned int   line, 
<                              uintptr_t      pReserved)
< {
<     /* empty */
< }
576a488
> }
580c492
< PRMJ_FormatTime(char *buf, int buflen, const char *fmt, PRMJTime *prtm)
---
> PRMJ_FormatTime(char *buf, int buflen, char *fmt, PRMJTime *prtm)
582,583c494
<     size_t result = 0;
< #if defined(XP_UNIX) || defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS)
---
> #if defined(XP_UNIX) || defined(XP_WIN) || defined(XP_OS2) || defined(XP_MAC) || defined(XP_BEOS)
585,589d495
<     int fake_tm_year = 0;
< #ifdef NS_HAVE_INVALID_PARAMETER_HANDLER
<     _invalid_parameter_handler oldHandler;
<     int oldReportMode;
< #endif
599c505
< 
---
>      
612,630c518
< 
<     /* 
<      * Years before 1900 and after 9999 cause strftime() to abort on Windows.
<      * To avoid that we replace it with FAKE_YEAR_BASE + year % 100 and then
<      * replace matching substrings in the strftime() result with the real year.
<      * Note that FAKE_YEAR_BASE should be a multiple of 100 to make 2-digit
<      * year formats (%y) work correctly (since we won't find the fake year
<      * in that case).
<      * e.g. new Date(1873, 0).toLocaleFormat('%Y %y') => "1873 73"
<      * See bug 327869.
<      */
< #define FAKE_YEAR_BASE 9900
<     if (prtm->tm_year < 1900 || prtm->tm_year > 9999) {
<         fake_tm_year = FAKE_YEAR_BASE + prtm->tm_year % 100;
<         a.tm_year = fake_tm_year - 1900;
<     }
<     else {
<         a.tm_year = prtm->tm_year - 1900;
<     }
---
>     a.tm_year = prtm->tm_year - 1900;
634,635c522
<     /*
<      * Even with the above, SunOS 4 seems to detonate if tm_zone and tm_gmtoff
---
>     /* Even with the above, SunOS 4 seems to detonate if tm_zone and tm_gmtoff
638a526
> 
653,688c541
< #ifdef NS_HAVE_INVALID_PARAMETER_HANDLER
<     oldHandler = _set_invalid_parameter_handler(PRMJ_InvalidParameterHandler);
<     oldReportMode = _CrtSetReportMode(_CRT_ASSERT, 0);
< #endif
< 
<     result = strftime(buf, buflen, fmt, &a);
< 
< #ifdef NS_HAVE_INVALID_PARAMETER_HANDLER
<     _set_invalid_parameter_handler(oldHandler);
<     _CrtSetReportMode(_CRT_ASSERT, oldReportMode);
< #endif
< 
<     if (fake_tm_year && result) {
<         char real_year[16];
<         char fake_year[16];
<         size_t real_year_len;
<         size_t fake_year_len;
<         char* p;
< 
<         sprintf(real_year, "%d", prtm->tm_year);
<         real_year_len = strlen(real_year);
<         sprintf(fake_year, "%d", fake_tm_year);
<         fake_year_len = strlen(fake_year);
< 
<         /* Replace the fake year in the result with the real year. */
<         for (p = buf; (p = strstr(p, fake_year)); p += real_year_len) {
<             size_t new_result = result + real_year_len - fake_year_len;
<             if ((int)new_result >= buflen) {
<                 return 0;
<             }
<             memmove(p + real_year_len, p + fake_year_len, strlen(p + fake_year_len));
<             memcpy(p, real_year, real_year_len);
<             result = new_result;
<             *(buf + result) = '\0';
<         }
<     }
---
>     return strftime(buf, buflen, fmt, &a);
690d542
<     return result;
720,721d571
< 
<     /* Temporaries used for various computations */
725d574
< 
728,750c577,579
<     /* Some variables for intermediate result storage to make computing isleap
<        easier/faster */
<     JSInt32 fourCenturyBlocks;
<     JSInt32 centuriesLeft;
<     JSInt32 fourYearBlocksLeft;
<     JSInt32 yearsLeft;
< 
<     /* Since leap years work by 400/100/4 year intervals, precompute the length
<        of those in seconds if they start at the beginning of year 1. */
<     JSInt64 fourYears;
<     JSInt64 century;
<     JSInt64 fourCenturies;
< 
<     JSLL_UI2L(result, PRMJ_DAY_SECONDS);
< 
<     JSLL_I2L(fourYears, PRMJ_FOUR_YEARS_DAYS);
<     JSLL_MUL(fourYears, fourYears, result);
< 
<     JSLL_I2L(century, PRMJ_CENTURY_DAYS);
<     JSLL_MUL(century, century, result);
< 
<     JSLL_I2L(fourCenturies, PRMJ_FOUR_CENTURIES_DAYS);
<     JSLL_MUL(fourCenturies, fourCenturies, result);
---
>     JSLL_UI2L(result,0);
>     JSLL_UI2L(result1,0);
>     JSLL_UI2L(result2,0);
758,763d586
<     /* Compute our |year|, |isleap|, and part of |days|.  When this part is
<        done, |year| should hold the year our date falls in (number of whole
<        years elapsed before our date), isleap should hold 1 if the year the
<        date falls in is a leap year and 0 otherwise. */
< 
<     /* First do year 0; it's special and nonleap. */
765,769c588,589
<     if (!JSLL_CMP(tsecs,<,result)) {
<         days = PRMJ_YEAR_DAYS;
<         year = 1;
<         JSLL_SUB(tsecs, tsecs, result);
<     }
---
>     JSLL_UI2L(result1,PRMJ_DAY_SECONDS);
>     JSLL_ADD(result2,result,result1);
771,803c591,603
<     /* Now use those constants we computed above */
<     JSLL_UDIVMOD(&result1, &result2, tsecs, fourCenturies);
<     JSLL_L2I(fourCenturyBlocks, result1);
<     year += fourCenturyBlocks * 400;
<     days += fourCenturyBlocks * PRMJ_FOUR_CENTURIES_DAYS;
<     tsecs = result2;
< 
<     JSLL_UDIVMOD(&result1, &result2, tsecs, century);
<     JSLL_L2I(centuriesLeft, result1);
<     year += centuriesLeft * 100;
<     days += centuriesLeft * PRMJ_CENTURY_DAYS;
<     tsecs = result2;
< 
<     JSLL_UDIVMOD(&result1, &result2, tsecs, fourYears);
<     JSLL_L2I(fourYearBlocksLeft, result1);
<     year += fourYearBlocksLeft * 4;
<     days += fourYearBlocksLeft * PRMJ_FOUR_YEARS_DAYS;
<     tsecs = result2;
< 
<     /* Recall that |result| holds PRMJ_YEAR_SECONDS */
<     JSLL_UDIVMOD(&result1, &result2, tsecs, result);
<     JSLL_L2I(yearsLeft, result1);
<     year += yearsLeft;
<     days += yearsLeft * PRMJ_YEAR_DAYS;
<     tsecs = result2;
< 
<     /* now compute isleap.  Note that we don't have to use %, since we've
<        already computed those remainders.  Also note that they're all offset by
<        1 because of the 1 for year 0. */
<     isleap =
<         (yearsLeft == 3) && (fourYearBlocksLeft != 24 || centuriesLeft == 3);
<     JS_ASSERT(isleap ==
<               ((year % 4 == 0) && (year % 100 != 0 || year % 400 == 0)));
---
>     /* get the year */
>     while ((isleap == 0) ? !JSLL_CMP(tsecs,<,result) : !JSLL_CMP(tsecs,<,result2)) {
>         /* subtract a year from tsecs */
>         JSLL_SUB(tsecs,tsecs,result);
>         days += 365;
>         /* is it a leap year ? */
>         if(IS_LEAP(year)){
>             JSLL_SUB(tsecs,tsecs,result1);
>             days++;
>         }
>         year++;
>         isleap = IS_LEAP(year);
>     }
diff -r /Volumes/Swap/js-14-2-2008/js/src/prmjtime.h /Volumes/Swap/js_D11/src/prmjtime.h
3,14c3,11
<  * ***** BEGIN LICENSE BLOCK *****
<  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
<  *
<  * The contents of this file are subject to the Mozilla Public License Version
<  * 1.1 (the "License"); you may not use this file except in compliance with
<  * the License. You may obtain a copy of the License at
<  * http://www.mozilla.org/MPL/
<  *
<  * Software distributed under the License is distributed on an "AS IS" basis,
<  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
<  * for the specific language governing rights and limitations under the
<  * License.
---
>  * The contents of this file are subject to the Netscape Public
>  * License Version 1.1 (the "License"); you may not use this file
>  * except in compliance with the License. You may obtain a copy of
>  * the License at http://www.mozilla.org/NPL/
>  *
>  * Software distributed under the License is distributed on an "AS
>  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
>  * implied. See the License for the specific language governing
>  * rights and limitations under the License.
19,38c16,33
<  * The Initial Developer of the Original Code is
<  * Netscape Communications Corporation.
<  * Portions created by the Initial Developer are Copyright (C) 1998
<  * the Initial Developer. All Rights Reserved.
<  *
<  * Contributor(s):
<  *
<  * Alternatively, the contents of this file may be used under the terms of
<  * either of the GNU General Public License Version 2 or later (the "GPL"),
<  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
<  * in which case the provisions of the GPL or the LGPL are applicable instead
<  * of those above. If you wish to allow use of your version of this file only
<  * under the terms of either the GPL or the LGPL, and not to allow others to
<  * use your version of this file under the terms of the MPL, indicate your
<  * decision by deleting the provisions above and replace them with the notice
<  * and other provisions required by the GPL or the LGPL. If you do not delete
<  * the provisions above, a recipient may use your version of this file under
<  * the terms of any one of the MPL, the GPL or the LGPL.
<  *
<  * ***** END LICENSE BLOCK ***** */
---
>  * The Initial Developer of the Original Code is Netscape
>  * Communications Corporation.  Portions created by Netscape are
>  * Copyright (C) 1998 Netscape Communications Corporation. All
>  * Rights Reserved.
>  *
>  * Contributor(s): 
>  *
>  * Alternatively, the contents of this file may be used under the
>  * terms of the GNU Public License (the "GPL"), in which case the
>  * provisions of the GPL are applicable instead of those above.
>  * If you wish to allow use of your version of this file only
>  * under the terms of the GPL and not to allow others to use your
>  * version of this file under the NPL, indicate your decision by
>  * deleting the provisions above and replace them with the notice
>  * and other provisions required by the GPL.  If you do not delete
>  * the provisions above, a recipient may use your version of this
>  * file under either the NPL or the GPL.
>  */
60,69c55,64
<     JSInt32 tm_usec;            /* microseconds of second (0-999999) */
<     JSInt8 tm_sec;              /* seconds of minute (0-59) */
<     JSInt8 tm_min;              /* minutes of hour (0-59) */
<     JSInt8 tm_hour;             /* hour of day (0-23) */
<     JSInt8 tm_mday;             /* day of month (1-31) */
<     JSInt8 tm_mon;              /* month of year (0-11) */
<     JSInt8 tm_wday;             /* 0=sunday, 1=monday, ... */
<     JSInt32 tm_year;            /* absolute year, AD */
<     JSInt16 tm_yday;            /* day of year (0 to 365) */
<     JSInt8 tm_isdst;            /* non-zero if DST in effect */
---
>     JSInt32 tm_usec;		/* microseconds of second (0-999999) */
>     JSInt8 tm_sec;		/* seconds of minute (0-59) */
>     JSInt8 tm_min;		/* minutes of hour (0-59) */
>     JSInt8 tm_hour;		/* hour of day (0-23) */
>     JSInt8 tm_mday;		/* day of month (1-31) */
>     JSInt8 tm_mon;		/* month of year (0-11) */
>     JSInt8 tm_wday;		/* 0=sunday, 1=monday, ... */
>     JSInt16 tm_year;		/* absolute year, AD */
>     JSInt16 tm_yday;		/* day of year (0 to 365) */
>     JSInt8 tm_isdst;		/* non-zero if DST in effect */
73,74c68,69
< #define PRMJ_USEC_PER_SEC       1000000L
< #define PRMJ_USEC_PER_MSEC      1000L
---
> #define PRMJ_USEC_PER_SEC	1000000L
> #define PRMJ_USEC_PER_MSEC	1000L
80,87d74
< /* Release the resources associated with PRMJ_Now; don't call PRMJ_Now again */
< #if defined(JS_THREADSAFE) && defined(XP_WIN)
< extern void
< PRMJ_NowShutdown(void);
< #else
< #define PRMJ_NowShutdown()
< #endif
< 
94c81
< PRMJ_FormatTime(char *buf, int buflen, const char *fmt, PRMJTime *tm);
---
> PRMJ_FormatTime(char *buf, int buflen, char *fmt, PRMJTime *tm);
Only in /Volumes/Swap/js-14-2-2008/js/src: resource.h
Only in /Volumes/Swap/js-14-2-2008/js/src: rules.mk
Only in /Volumes/Swap/js-14-2-2008/js/src: win32.order
Only in /Volumes/Swap/js_D11/src: xstdlib.c
Only in /Volumes/Swap/js_D11/src: xstdlib.h