Merge.
authorAndreas Gal <gal@mozilla.com>
Mon, 02 Feb 2009 17:26:22 -0800
changeset 24599 a556e7c0d6d7d39b250d22749ffdf651fad1531f
parent 24598 78da97bbec6894dd12e265ebbec2884ea3ef7516 (current diff)
parent 24597 240b7ff30110ba6183267b2cfefa5c57d2438f37 (diff)
child 24600 46826345bcb5c446e4a6e66ebad0df7a38b612fe
push id5132
push userrsayre@mozilla.com
push dateWed, 04 Feb 2009 20:48:09 +0000
treeherdermozilla-central@76ca30e94e5c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone1.9.2a1pre
Merge.
js/src/jsinterp.cpp
--- a/js/src/Makefile.in
+++ b/js/src/Makefile.in
@@ -355,29 +355,16 @@ endif
 # our build system doesn't handle subdir srcs very gracefully today
 export::
 	mkdir -p nanojit
 
 DEFINES		+= -DEXPORT_JS_API 
 
 INCLUDES	+= -I$(srcdir)
 
-# MSVC '-Gy' cc flag and '/OPT:REF' linker flag cause JS_GetArgument and
-# JS_GetLocalVariable to be folded to the same address by the linker, 
-# leading to a crash on startup. See bug 151066. So, in optimized builds,
-# add the /OPT:NOICF flag, which turns off 'identical COMDAT folding'.
-#
-# N.B.: 'identical COMDAT folding' that folds functions whose addresses
-# are taken violates the ISO C and C++ standards.
-ifndef MOZ_DEBUG
-ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
-LDFLAGS         += -OPT:NOICF
-endif
-endif
-
 GARBAGE		+= jscpucfg.o jsautocfg.h jsautocfg.tmp jscpucfg
 
 ifneq (,$(CROSS_COMPILE)$(filter-out WINNT,$(OS_ARCH)))
 TARGETS		+= jscpucfg$(HOST_BIN_SUFFIX)
 endif
 
 ifdef JS_SAFE_ARENA
 DEFINES		+= -DJS_USE_SAFE_ARENA
@@ -595,17 +582,17 @@ js-config: js-config.in Makefile $(DEPTH
 	&& mv js-config.tmp $@ && chmod +x $@
 
 SCRIPTS = js-config
 SDK_BINARY = js-config
 
 install:: $(INSTALLED_HEADERS)
 	$(SYSINSTALL) $^ $(includedir)/$(MODULE)
 
-install:: $(SCRIPTS) $(PROGRAM)
+install:: $(SCRIPTS)
 	$(SYSINSTALL) $^ $(bindir)
 
 install:: $(LIBRARY) $(SHARED_LIBRARY) $(IMPORT_LIBRARY)
 ifneq (,$(LIBRARY))
 	$(SYSINSTALL) $(LIBRARY) $(libdir)
 endif
 ifneq (,$(SHARED_LIBRARY))
 	$(SYSINSTALL) $(SHARED_LIBRARY) $(libdir)
@@ -638,15 +625,25 @@ ifdef HAVE_DTRACE
 	sed 's/if _DTRACE_VERSION/ifdef INCLUDE_MOZILLA_DTRACE/' \
 	    javascript-trace.h.in > javascript-trace.h
 
 # We can't automatically generate dependencies on auto-generated headers;
 # we have to list them explicitly.
 $(addsuffix .$(OBJ_SUFFIX),jsdtracef jsinterp jsobj): $(CURDIR)/javascript-trace.h
 endif
 
-imacro_asm.js: imacro_asm.js.in
-	$(CC) -c -x c -E -P -I$(srcdir) $? > $@
+ifdef GNU_CC
+imacro_asm.js: imacro_asm.js.in jsopcode.tbl
+	$(CC) -c -x c -E -P -I$(srcdir) $< > $@
+
+GARBAGE += imacros.c.out imacro_asm.js
 
-GARBAGE += imacro_asm.js
+ifndef CROSS_COMPILE
+# Build imacros.c.out after descending into DIRS and building the js shell.
+# This may result in an updated imacros.c.out file that requires a re-build
+# to stabilize.
+libs:: imacros.c.out
+	@cmp -s imacros.c.out $(srcdir)/$< || cp imacros.c.out $(srcdir)
 
-%.c.out: %.jsasm $(PROGRAM) imacro_asm.js
-	./$(PROGRAM) imacro_asm.js $< > $@
+%.c.out: %.jsasm imacro_asm.js
+	$(DIST)/bin/js imacro_asm.js $< > $@
+endif
+endif
--- a/js/src/imacro_asm.js.in
+++ b/js/src/imacro_asm.js.in
@@ -119,26 +119,16 @@ function immediate(op) {
     if (info.flags.indexOf("JOF_UINT16") >= 0) {
         if (imm1Expr)
             return '(_ & 0xff00) >> 8, (_ & 0xff)'.replace(/_/g, op.imm1);
         return ((op.imm1 & 0xff00) >> 8) + ", " + (op.imm1 & 0xff);
     }
     throw new Error(info.jsop + " format not yet implemented");
 }
 
-const line_regexp_parts = [
-    "^(?:(\\w+):)?",
-    "\\s*(\\.?\\w+)",
-    "(?:\\s+(\\w+|\\([^)]*\\)))?",
-    "(?:\\s+([\\w-]+|\\([^)]*\\)))?",
-    "(?:\\s*(?:#.*))?$"
-];
-
-const line_regexp = new RegExp(line_regexp_parts.join(""));
-
 /*
  * Syntax (spaces are significant only to delimit tokens):
  *
  *   Assembly   ::= (Directive? '\n')*
  *   Directive  ::= (name ':')? Operation
  *   Operation  ::= opname Operands?
  *   Operands   ::= Operand (',' Operand)*
  *   Operand    ::= name | number | '(' Expr ')'
@@ -148,21 +138,31 @@ const line_regexp = new RegExp(line_rege
  * We simplify given line structure and the maximum of one immediate operand,
  * by parsing using split and regexps.  For ease of parsing, parentheses are
  * banned in an Expr for now, even in quotes or a C++ comment.
  *
  * Pseudo-ops start with . and include .igroup and .imacro, terminated by .end.
  * .imacro must nest in .igroup, neither nests in itself. See imacros.jsasm for
  * examples.
  */
+const line_regexp_parts = [
+    "^(?:(\\w+):)?",                    // optional label at start of line
+    "\\s*(\\.?\\w+)",                   // optional spaces, (pseudo-)opcode
+    "(?:\\s+(\\w+|\\([^)]*\\)))?",      // optional first immediate operand
+    "(?:\\s+([\\w-]+|\\([^)]*\\)))?",   // optional second immediate operand
+    "(?:\\s*(?:#.*))?$"                 // optional spaces and comment
+];
+
+const line_regexp = new RegExp(line_regexp_parts.join(""));
+
 function assemble(filename) {
     let igroup = null, imacro = null;
     let opcode2extra = [];
 
-    print("/* GENERATED BY imacro_asm.js from " + filename + " -- DO NOT EDIT!!! */");
+    print("/* GENERATED BY imacro_asm.js -- DO NOT EDIT!!! */");
 
     let s = snarf(filename);
     let a = s.split('\n');
     for (let i = 0; i < a.length; i++) {
         if (/^\s*(?:#.*)?$/.test(a[i]))
             continue;
         let m = line_regexp.exec(a[i]);
         if (!m)
@@ -290,21 +290,21 @@ function assemble(filename) {
 
         if (!opname2info.hasOwnProperty(opname))
             throw new Error("unknown opcode " + opname + (label ? " (label " + label + ")" : ""));
 
         let info = opname2info[opname];
         if (info.oplen == -1)
             throw new Error("unimplemented opcode " + opname);
 
-        if (label) {
-            if (!imacro)
-                throw new Error("label " + label + " outside of .imacro");
+        if (!imacro)
+            throw new Error("opcode " + opname + " outside of .imacro");
+
+        if (label)
             imacro.labeldefs[label] = imacro.offset;
-        }
 
         let op = {offset: imacro.offset, info: info, imm1: imm1, imm2: imm2};
         if (info.flags.indexOf("JOF_JUMP") >= 0) {
             if (imacro.labeldefs.hasOwnProperty(imm1)) {
                 // Backward reference can be resolved right away, no backpatching needed.
                 op.target = imacro.labeldefs[imm1] - op.offset;
             } else {
                 // Link op into the .target-linked backpatch chain at labelrefs[imm1].
--- a/js/src/imacros.c.out
+++ b/js/src/imacros.c.out
@@ -1,9 +1,9 @@
-/* GENERATED BY imacro_asm.js from imacros.jsasm -- DO NOT EDIT!!! */
+/* GENERATED BY imacro_asm.js -- DO NOT EDIT!!! */
 static struct {
     jsbytecode any_obj[37];
     jsbytecode obj_any[39];
 } equality_imacros = {
     {
 /* 0*/  JSOP_DUP,
 /* 1*/  JSOP_DUP,
 /* 2*/  JSOP_GETPROP, 0, COMMON_ATOM_INDEX(valueOf),
@@ -704,17 +704,17 @@ uint8 js_opcode2extra[JSOP_LIMIT] = {
     0,  /* JSOP_PROPINC */
     0,  /* JSOP_ELEMINC */
     0,  /* JSOP_NAMEDEC */
     0,  /* JSOP_PROPDEC */
     0,  /* JSOP_ELEMDEC */
     0,  /* JSOP_GETPROP */
     0,  /* JSOP_SETPROP */
     2,  /* JSOP_GETELEM */
-    2,  /* JSOP_SETELEM */
+    3,  /* JSOP_SETELEM */
     0,  /* JSOP_CALLNAME */
     0,  /* JSOP_CALL */
     0,  /* JSOP_NAME */
     0,  /* JSOP_DOUBLE */
     0,  /* JSOP_STRING */
     0,  /* JSOP_ZERO */
     0,  /* JSOP_ONE */
     0,  /* JSOP_NULL */
@@ -726,31 +726,31 @@ uint8 js_opcode2extra[JSOP_LIMIT] = {
     0,  /* JSOP_TABLESWITCH */
     0,  /* JSOP_LOOKUPSWITCH */
     0,  /* JSOP_STRICTEQ */
     0,  /* JSOP_STRICTNE */
     0,  /* JSOP_NULLTHIS */
     3,  /* JSOP_ITER */
     2,  /* JSOP_NEXTITER */
     0,  /* JSOP_ENDITER */
-    7,  /* JSOP_APPLY */
+    8,  /* JSOP_APPLY */
     0,  /* JSOP_SWAP */
     0,  /* JSOP_OBJECT */
     0,  /* JSOP_POP */
     0,  /* JSOP_NEW */
     0,  /* JSOP_TRAP */
     0,  /* JSOP_GETARG */
     0,  /* JSOP_SETARG */
     0,  /* JSOP_GETLOCAL */
     0,  /* JSOP_SETLOCAL */
     0,  /* JSOP_UINT16 */
     0,  /* JSOP_NEWINIT */
     0,  /* JSOP_ENDINIT */
     0,  /* JSOP_INITPROP */
-    2,  /* JSOP_INITELEM */
+    3,  /* JSOP_INITELEM */
     0,  /* JSOP_DEFSHARP */
     0,  /* JSOP_USESHARP */
     0,  /* JSOP_INCARG */
     0,  /* JSOP_DECARG */
     0,  /* JSOP_ARGINC */
     0,  /* JSOP_ARGDEC */
     0,  /* JSOP_INCLOCAL */
     0,  /* JSOP_DECLOCAL */
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -1596,73 +1596,94 @@ js_CheckRedeclaration(JSContext *cx, JSO
 {
     JSObject *obj2;
     JSProperty *prop;
     uintN oldAttrs, report;
     JSBool isFunction;
     jsval value;
     const char *type, *name;
 
+    /*
+     * Both objp and propp must be either null or given. When given, *propp
+     * must be null. This way we avoid an extra "if (propp) *propp = NULL" for
+     * the common case of a non-existing property.
+     */
+    JS_ASSERT(!objp == !propp);
+    JS_ASSERT_IF(propp, !*propp);
+
+    /* The JSPROP_INITIALIZER case below may generate a warning. Since we must
+     * drop the property before reporting it, we insists on !propp to avoid
+     * looking up the property again after the reporting is done.
+     */
+    JS_ASSERT_IF(attrs & JSPROP_INITIALIZER, attrs == JSPROP_INITIALIZER);
+    JS_ASSERT_IF(attrs == JSPROP_INITIALIZER, !propp);
+
     if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop))
         return JS_FALSE;
-    if (propp) {
-        *objp = obj2;
-        *propp = prop;
-    }
     if (!prop)
         return JS_TRUE;
 
-    /*
-     * Use prop as a speedup hint to OBJ_GET_ATTRIBUTES, but drop it on error.
-     * An assertion at label bad: will insist that it is null.
-     */
+    /* Use prop as a speedup hint to OBJ_GET_ATTRIBUTES. */
     if (!OBJ_GET_ATTRIBUTES(cx, obj2, id, prop, &oldAttrs)) {
         OBJ_DROP_PROPERTY(cx, obj2, prop);
-#ifdef DEBUG
-        prop = NULL;
-#endif
-        goto bad;
+        return JS_FALSE;
     }
 
     /*
-     * From here, return true, or else goto bad on failure to null out params.
      * If our caller doesn't want prop, drop it (we don't need it any longer).
      */
     if (!propp) {
         OBJ_DROP_PROPERTY(cx, obj2, prop);
         prop = NULL;
+    } else {
+        *objp = obj2;
+        *propp = prop;
     }
 
     if (attrs == JSPROP_INITIALIZER) {
         /* Allow the new object to override properties. */
         if (obj2 != obj)
             return JS_TRUE;
+
+        /* The property must be dropped already. */
+        JS_ASSERT(!prop);
         report = JSREPORT_WARNING | JSREPORT_STRICT;
     } else {
         /* We allow redeclaring some non-readonly properties. */
         if (((oldAttrs | attrs) & JSPROP_READONLY) == 0) {
-            /*
-             * Allow redeclaration of variables and functions, but insist that
-             * the new value is not a getter if the old value was, ditto for
-             * setters -- unless prop is impermanent (in which case anyone
-             * could delete it and redefine it, willy-nilly).
-             */
+            /* Allow redeclaration of variables and functions. */
             if (!(attrs & (JSPROP_GETTER | JSPROP_SETTER)))
                 return JS_TRUE;
+
+            /*
+             * Allow adding a getter only if a property already has a setter
+             * but no getter and similarly for adding a setter. That is, we
+             * allow only the following transitions:
+             *
+             *   no-property --> getter --> getter + setter
+             *   no-property --> setter --> getter + setter
+             */
             if ((~(oldAttrs ^ attrs) & (JSPROP_GETTER | JSPROP_SETTER)) == 0)
                 return JS_TRUE;
+
+            /*
+             * Allow redeclaration of an impermanent property (in which case
+             * anyone could delete it and redefine it, willy-nilly).
+             */
             if (!(oldAttrs & JSPROP_PERMANENT))
                 return JS_TRUE;
         }
+        if (prop)
+            OBJ_DROP_PROPERTY(cx, obj2, prop);
 
         report = JSREPORT_ERROR;
         isFunction = (oldAttrs & (JSPROP_GETTER | JSPROP_SETTER)) != 0;
         if (!isFunction) {
             if (!OBJ_GET_PROPERTY(cx, obj, id, &value))
-                goto bad;
+                return JS_FALSE;
             isFunction = VALUE_IS_FUNCTION(cx, value);
         }
     }
 
     type = (attrs == JSPROP_INITIALIZER)
            ? "property"
            : (oldAttrs & attrs & JSPROP_GETTER)
            ? js_getter_str
@@ -1670,29 +1691,21 @@ js_CheckRedeclaration(JSContext *cx, JSO
            ? js_setter_str
            : (oldAttrs & JSPROP_READONLY)
            ? js_const_str
            : isFunction
            ? js_function_str
            : js_var_str;
     name = js_ValueToPrintableString(cx, ID_TO_VALUE(id));
     if (!name)
-        goto bad;
+        return JS_FALSE;
     return JS_ReportErrorFlagsAndNumber(cx, report,
                                         js_GetErrorMessage, NULL,
                                         JSMSG_REDECLARED_VAR,
                                         type, name);
-
-bad:
-    if (propp) {
-        *objp = NULL;
-        *propp = NULL;
-    }
-    JS_ASSERT(!prop);
-    return JS_FALSE;
 }
 
 JSBool
 js_StrictlyEqual(JSContext *cx, jsval lval, jsval rval)
 {
     jsval ltag = JSVAL_TAG(lval), rtag = JSVAL_TAG(rval);
     jsdouble ld, rd;
 
@@ -5654,16 +5667,17 @@ js_Interpret(JSContext *cx)
             attrs = JSPROP_ENUMERATE;
             if (!(fp->flags & JSFRAME_EVAL))
                 attrs |= JSPROP_PERMANENT;
             if (op == JSOP_DEFCONST)
                 attrs |= JSPROP_READONLY;
 
             /* Lookup id in order to check for redeclaration problems. */
             id = ATOM_TO_JSID(atom);
+            prop = NULL;
             if (!js_CheckRedeclaration(cx, obj, id, attrs, &obj2, &prop))
                 goto error;
 
             /* Bind a variable only if it's not yet defined. */
             if (!prop) {
                 if (!OBJ_DEFINE_PROPERTY(cx, obj, id, JSVAL_VOID,
                                          JS_PropertyStub, JS_PropertyStub,
                                          attrs, &prop)) {
@@ -5676,21 +5690,21 @@ js_Interpret(JSContext *cx)
             /*
              * Try to optimize a property we either just created, or found
              * directly in the global object, that is permanent, has a slot,
              * and has stub getter and setter, into a "fast global" accessed
              * by the JSOP_*GVAR opcodes.
              */
             if (!fp->fun &&
                 index < GlobalVarCount(fp) &&
-                (attrs & JSPROP_PERMANENT) &&
                 obj2 == obj &&
                 OBJ_IS_NATIVE(obj)) {
                 sprop = (JSScopeProperty *) prop;
-                if (SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(obj)) &&
+                if ((sprop->attrs & JSPROP_PERMANENT) &&
+                    SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(obj)) &&
                     SPROP_HAS_STUB_GETTER(sprop) &&
                     SPROP_HAS_STUB_SETTER(sprop)) {
                     /*
                      * Fast globals use frame variables to map the global
                      * name's atom index to the permanent fp->varobj slot
                      * number, tagged as a jsval. The atom index for the
                      * global's name literal is identical to its variable
                      * index.