bug 432917: Replace "must flow through label" comments with statically-checkable macro. r=igor

This commit is contained in:
Taras Glek 2008-09-08 10:51:10 -07:00
Родитель 98c9884ab2
Коммит ee4fd995ff
12 изменённых файлов: 95 добавлений и 22 удалений

Просмотреть файл

@ -78,6 +78,7 @@
#include "jsscript.h"
#include "jsstr.h"
#include "prmjtime.h"
#include "jsstaticcheck.h"
#ifdef JS_TRACER
#include "jstracer.h"
@ -4791,7 +4792,7 @@ JS_CompileUCFunctionForPrincipals(JSContext *cx, JSObject *obj,
if (!fun)
goto out2;
/* From this point the control must flow through the label out. */
MUST_FLOW_THROUGH("out");
JS_PUSH_TEMP_ROOT_OBJECT(cx, FUN_OBJECT(fun), &tvr);
for (i = 0; i < nargs; i++) {
argAtom = js_Atomize(cx, argnames[i], strlen(argnames[i]), 0);

Просмотреть файл

@ -97,6 +97,7 @@
#include "jsobj.h"
#include "jsscope.h"
#include "jsstr.h"
#include "jsstaticcheck.h"
/* 2^32 - 1 as a number and a string */
#define MAXINDEX 4294967295u
@ -2278,7 +2279,7 @@ array_splice(JSContext *cx, uintN argc, jsval *vp)
argv++;
}
/* After this, control must flow through label out: to exit. */
MUST_FLOW_THROUGH("out");
JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_NULL, &tvr);
/* If there are elements to remove, put them into the return value. */
@ -2391,7 +2392,7 @@ array_concat(JSContext *cx, uintN argc, jsval *vp)
length = 0;
}
/* After this, control must flow through label out: to exit. */
MUST_FLOW_THROUGH("out");
JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_NULL, &tvr);
/* Loop over [0, argc] to concat args into nobj, expanding all Arrays. */
@ -2519,7 +2520,7 @@ array_slice(JSContext *cx, uintN argc, jsval *vp)
return JS_FALSE;
*vp = OBJECT_TO_JSVAL(nobj);
/* After this, control must flow through label out: to exit. */
MUST_FLOW_THROUGH("out");
JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_NULL, &tvr);
for (slot = begin; slot < end; slot++) {
@ -2739,7 +2740,7 @@ array_extra(JSContext *cx, ArrayExtraMode mode, uintN argc, jsval *vp)
if (!elemroot)
return JS_FALSE;
/* From this point the control must flow through out:. */
MUST_FLOW_THROUGH("out");
ok = JS_TRUE;
invokevp = elemroot + 1;

Просмотреть файл

@ -65,8 +65,8 @@
#include "jsscan.h"
#include "jsscope.h"
#include "jsscript.h"
#include "jsautooplen.h"
#include "jsstaticcheck.h"
/* Allocation chunk counts, must be powers of two in general. */
#define BYTECODE_CHUNK 256 /* code allocation increment */
@ -2978,6 +2978,7 @@ EmitSwitch(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn,
* must set ok and goto out to exit this function. To keep things
* simple, all switchOp cases exit that way.
*/
MUST_FLOW_THROUGH("out");
if (cg->spanDeps) {
/*
* We have already generated at least one big jump so we must

Просмотреть файл

@ -61,6 +61,7 @@
#include "jsopcode.h"
#include "jsscope.h"
#include "jsscript.h"
#include "jsstaticcheck.h"
/* Forward declarations for js_ErrorClass's initializer. */
static JSBool
@ -901,7 +902,7 @@ exn_toSource(JSContext *cx, uintN argc, jsval *vp)
return JS_FALSE;
*vp = STRING_TO_JSVAL(name);
/* After this, control must flow through label out: to exit. */
MUST_FLOW_THROUGH("out");
JS_PUSH_TEMP_ROOT(cx, 3, localroots, &tvr);
#ifdef __GNUC__
@ -1207,7 +1208,7 @@ js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp)
if (cx->generatingError)
return JS_FALSE;
/* After this point the control must flow through the label out. */
MUST_FLOW_THROUGH("out");
cx->generatingError = JS_TRUE;
/* Protect the newly-created strings below from nesting GCs. */

Просмотреть файл

@ -65,6 +65,7 @@
#include "jsscript.h"
#include "jsstr.h"
#include "jsexn.h"
#include "jsstaticcheck.h"
#if JS_HAS_GENERATORS
# include "jsiter.h"
@ -717,7 +718,7 @@ call_enumerate(JSContext *cx, JSObject *obj)
mark = JS_ARENA_MARK(&cx->tempPool);
/* From this point the control must flow through the label out. */
MUST_FLOW_THROUGH("out");
names = js_GetLocalNameArray(cx, fun, &cx->tempPool);
if (!names) {
ok = JS_FALSE;

Просмотреть файл

@ -68,6 +68,7 @@
#include "jsscope.h"
#include "jsscript.h"
#include "jsstr.h"
#include "jsstaticcheck.h"
#ifdef JS_TRACER
#include "jstracer.h"
#endif
@ -931,7 +932,7 @@ js_OnUnknownMethod(JSContext *cx, jsval *vp)
obj = JSVAL_TO_OBJECT(vp[1]);
JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_NULL, &tvr);
/* From here on, control must flow through label out:. */
MUST_FLOW_THROUGH("out");
id = ATOM_TO_JSID(cx->runtime->atomState.noSuchMethodAtom);
#if JS_HAS_XML_SUPPORT
if (OBJECT_IS_XML(cx, obj)) {
@ -1270,7 +1271,7 @@ have_fun:
frame.xmlNamespace = NULL;
frame.blockChain = NULL;
/* From here on, control must flow through label out: to return. */
MUST_FLOW_THROUGH("out");
cx->fp = &frame;
/* Init these now in case we goto out before first hook call. */
@ -2658,7 +2659,7 @@ js_Interpret(JSContext *cx)
DO_OP(); \
JS_END_MACRO
/* From this point control must flow through the label exit. */
MUST_FLOW_THROUGH("exit");
++cx->interpLevel;
/*
@ -5691,6 +5692,7 @@ js_Interpret(JSContext *cx)
* paths from here must flow through the "Restore fp->scopeChain"
* code below the OBJ_DEFINE_PROPERTY call.
*/
MUST_FLOW_THROUGH("restore");
fp->scopeChain = obj;
rval = OBJECT_TO_JSVAL(obj);
@ -5750,6 +5752,7 @@ js_Interpret(JSContext *cx)
}
/* Restore fp->scopeChain now that obj is defined in fp->varobj. */
MUST_FLOW_LABEL(restore)
fp->scopeChain = obj2;
if (!ok) {
cx->weakRoots.newborn[GCX_OBJECT] = NULL;
@ -5838,6 +5841,7 @@ js_Interpret(JSContext *cx)
* paths from here must flow through the "Restore fp->scopeChain"
* code below the OBJ_DEFINE_PROPERTY call.
*/
MUST_FLOW_THROUGH("restore2");
fp->scopeChain = obj;
rval = OBJECT_TO_JSVAL(obj);
@ -5864,6 +5868,7 @@ js_Interpret(JSContext *cx)
NULL);
/* Restore fp->scopeChain now that obj is defined in parent. */
MUST_FLOW_LABEL(restore2)
fp->scopeChain = obj2;
if (!ok) {
cx->weakRoots.newborn[GCX_OBJECT] = NULL;

Просмотреть файл

@ -69,8 +69,8 @@
#include "jsscope.h"
#include "jsscript.h"
#include "jsstr.h"
#include "jsdbgapi.h" /* whether or not JS_HAS_OBJ_WATCHPOINT */
#include "jsstaticcheck.h"
#if JS_HAS_GENERATORS
#include "jsiter.h"
@ -635,7 +635,7 @@ obj_toSource(JSContext *cx, uintN argc, jsval *vp)
JS_CHECK_RECURSION(cx, return JS_FALSE);
/* After this, control must flow through out: to exit. */
MUST_FLOW_THROUGH("out");
JS_PUSH_TEMP_ROOT(cx, 4, localroot, &tvr);
/* If outermost, we need parentheses to be an expression, not a block. */
@ -1235,6 +1235,7 @@ js_obj_eval(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
}
/* From here on, control must exit through label out with ok set. */
MUST_FLOW_THROUGH("out");
if (!scopeobj) {
#if JS_HAS_EVAL_THIS_SCOPE
/* If obj.eval(str), emulate 'with (obj) eval(str)' in the caller. */
@ -2839,6 +2840,7 @@ js_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto,
* this point, all control flow must exit through label out with obj set.
*/
JS_PUSH_SINGLE_TEMP_ROOT(cx, cval, &tvr);
MUST_FLOW_THROUGH("out");
/*
* If proto or parent are NULL, set them to Constructor.prototype and/or

Просмотреть файл

@ -70,6 +70,7 @@
#include "jsscope.h"
#include "jsscript.h"
#include "jsstr.h"
#include "jsstaticcheck.h"
#if JS_HAS_DESTRUCTURING
# include "jsnum.h"
@ -2544,7 +2545,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
return NULL;
}
/* From here on, control must flow through enterblock_out. */
MUST_FLOW_THROUGH("enterblock_out");
#define LOCAL_ASSERT_OUT(expr) LOCAL_ASSERT_CUSTOM(expr, ok = JS_FALSE; \
goto enterblock_out)
for (sprop = OBJ_SCOPE(obj)->lastProp; sprop;
@ -5046,7 +5047,7 @@ DecompileExpression(JSContext *cx, JSScript *script, JSFunction *fun,
oldcode = script->code;
oldmain = script->main;
/* From this point the control must flow through the label out. */
MUST_FLOW_THROUGH("out");
code = js_UntrapScriptCode(cx, script);
if (code != oldcode) {
script->code = code;
@ -5122,7 +5123,7 @@ DecompileExpression(JSContext *cx, JSScript *script, JSFunction *fun,
goto out;
}
/* From this point the control must flow through the label out. */
MUST_FLOW_THROUGH("out");
pcdepth = ReconstructPCStack(cx, script, begin, pcstack);
if (pcdepth < 0) {
name = FAILED_EXPRESSION_DECOMPILER;

Просмотреть файл

@ -76,6 +76,7 @@
#include "jsscope.h"
#include "jsscript.h"
#include "jsstr.h"
#include "jsstaticcheck.h"
#if JS_HAS_XML_SUPPORT
#include "jsxml.h"
@ -537,7 +538,7 @@ js_CompileScript(JSContext *cx, JSObject *scopeChain, JSStackFrame *callerFrame,
js_InitCodeGenerator(cx, &cg, &pc, &codePool, &notePool,
pc.tokenStream.lineno);
/* From this point the control must flow via the label out. */
MUST_FLOW_THROUGH("out");
cg.treeContext.flags |= (uint16) tcflags;
cg.treeContext.u.scopeChain = scopeChain;
cg.staticDepth = TCF_GET_STATIC_DEPTH(tcflags);

Просмотреть файл

@ -69,6 +69,7 @@
#include "jsregexp.h"
#include "jsscan.h"
#include "jsscript.h"
#include "jsstaticcheck.h"
#if JS_HAS_XML_SUPPORT
#include "jsxml.h"
@ -535,7 +536,7 @@ js_ReportCompileErrorNumber(JSContext *cx, JSTokenStream *ts, JSParseNode *pn,
linechars = NULL;
linebytes = NULL;
/* From this point the control must flow through the label out.*/
MUST_FLOW_THROUGH("out");
va_start(ap, errorNumber);
ok = js_ExpandErrorArguments(cx, js_GetErrorMessage, NULL,
errorNumber, &message, &report, &warning,

57
js/src/jsstaticcheck.h Normal file
Просмотреть файл

@ -0,0 +1,57 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef jsstaticcheck_h___
#define jsstaticcheck_h___
#ifdef NS_STATIC_CHECKING
/*
* Trigger a control flow check to make sure that code flows through label
*/
inline __attribute__ ((unused)) void MUST_FLOW_THROUGH(const char *label) {
}
/* avoid unused goto-label warnings */
#define MUST_FLOW_LABEL(label) goto label; label:
#else
#define MUST_FLOW_THROUGH(label) ((void)0)
#define MUST_FLOW_LABEL(label)
#endif
#endif /* jsstaticcheck_h___ */

Просмотреть файл

@ -67,6 +67,7 @@
#include "jsscript.h"
#include "jsstr.h"
#include "jsxml.h"
#include "jsstaticcheck.h"
#ifdef DEBUG
#include <string.h> /* for #ifdef DEBUG memset calls */
@ -4088,10 +4089,10 @@ PutProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
vxml = (JSXML *) JS_GetPrivate(cx, vobj);
}
/* Control flow after here must exit via label out. */
ok = js_EnterLocalRootScope(cx);
if (!ok)
return JS_FALSE;
MUST_FLOW_THROUGH("out");
roots[OBJ_ROOT] = OBJECT_TO_JSVAL(obj);
roots[ID_ROOT] = id;
roots[VAL_ROOT] = *vp;
@ -6263,8 +6264,8 @@ xml_namespace(JSContext *cx, uintN argc, jsval *vp)
vp[2] = STRING_TO_JSVAL(prefix); /* local root */
}
/* After this point the control must flow through label out. */
InitTempNSArray(cx, &inScopeNSes);
MUST_FLOW_THROUGH("out");
ok = FindInScopeNamespaces(cx, xml, &inScopeNSes.array);
if (!ok)
goto out;
@ -8003,7 +8004,7 @@ js_GetXMLFunction(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
JS_ASSERT(OBJECT_IS_XML(cx, obj));
/* After this point, control must flow through label out: to exit. */
MUST_FLOW_THROUGH("out");
JS_PUSH_TEMP_ROOT_OBJECT(cx, NULL, &tvr);
/*