Merge last green changeset from inbound to mozilla-central

This commit is contained in:
Matt Brubeck 2012-02-28 09:21:10 -08:00
Родитель 80f854ad96 0d377fa5bf
Коммит a39f4b9489
247 изменённых файлов: 4825 добавлений и 3270 удалений

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

@ -871,10 +871,11 @@ refChildCB(AtkObject *aAtkObj, gint aChildIndex)
if (!childAtkObj)
return nsnull;
g_object_ref(childAtkObj);
//this will addref parent
if (aAtkObj != childAtkObj->accessible_parent)
atk_object_set_parent(childAtkObj, aAtkObj);
return childAtkObj;
return childAtkObj;
}
gint

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

@ -110,3 +110,16 @@ StyleInfo::Margin(css::Side aSide, nsAString& aValue)
aValue.AppendFloat(nsPresContext::AppUnitsToFloatCSSPixels(coordVal));
aValue.AppendLiteral("px");
}
void
StyleInfo::Format(const nscolor& aValue, nsString& aFormattedValue)
{
// Combine the string like rgb(R, G, B) from nscolor.
aFormattedValue.AppendLiteral("rgb(");
aFormattedValue.AppendInt(NS_GET_R(aValue));
aFormattedValue.AppendLiteral(", ");
aFormattedValue.AppendInt(NS_GET_G(aValue));
aFormattedValue.AppendLiteral(", ");
aFormattedValue.AppendInt(NS_GET_B(aValue));
aFormattedValue.Append(')');
}

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

@ -60,6 +60,8 @@ public:
void MarginTop(nsAString& aValue) { Margin(css::eSideTop, aValue); }
void MarginBottom(nsAString& aValue) { Margin(css::eSideBottom, aValue); }
static void Format(const nscolor& aValue, nsString& aFormattedValue);
private:
StyleInfo() MOZ_DELETE;
StyleInfo(const StyleInfo&) MOZ_DELETE;

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

@ -364,9 +364,9 @@ nsAccDocManager::CreateDocOrRootAccessible(nsIDocument *aDocument)
aDocument->IsResourceDoc() || !aDocument->IsActive())
return nsnull;
// Ignore documents without presshell.
nsIPresShell *presShell = aDocument->GetShell();
if (!presShell)
// Ignore documents without presshell and not having root frame.
nsIPresShell* presShell = aDocument->GetShell();
if (!presShell || !presShell->GetRootFrame())
return nsnull;
// Do not create document accessible until role content is loaded, otherwise

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

@ -41,12 +41,16 @@
#include "nsAccUtils.h"
#include "nsCoreUtils.h"
#include "nsHyperTextAccessibleWrap.h"
#include "StyleInfo.h"
#include "gfxFont.h"
#include "gfxUserFontSet.h"
#include "nsFontMetrics.h"
#include "nsLayoutUtils.h"
using namespace mozilla;
using namespace mozilla::a11y;
////////////////////////////////////////////////////////////////////////////////
// Constants and structures
@ -70,7 +74,6 @@ const char* const kCopyValue = nsnull;
static nsCSSTextAttrMapItem gCSSTextAttrsMap[] =
{
// CSS name CSS value Attribute name Attribute value
{ "color", kAnyValue, &nsGkAtoms::color, kCopyValue },
{ "font-family", kAnyValue, &nsGkAtoms::font_family, kCopyValue },
{ "font-style", kAnyValue, &nsGkAtoms::font_style, kCopyValue },
{ "text-decoration", "line-through", &nsGkAtoms::textLineThroughStyle, "solid" },
@ -154,34 +157,34 @@ nsTextAttrsMgr::GetAttributes(nsIPersistentProperties *aAttributes,
nsLangTextAttr langTextAttr(mHyperTextAcc, hyperTextElm, offsetNode);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&langTextAttr));
// "color" text attribute
nsCSSTextAttr colorTextAttr(0, hyperTextElm, offsetElm);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&colorTextAttr));
// "font-family" text attribute
nsCSSTextAttr fontFamilyTextAttr(1, hyperTextElm, offsetElm);
nsCSSTextAttr fontFamilyTextAttr(0, hyperTextElm, offsetElm);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&fontFamilyTextAttr));
// "font-style" text attribute
nsCSSTextAttr fontStyleTextAttr(2, hyperTextElm, offsetElm);
nsCSSTextAttr fontStyleTextAttr(1, hyperTextElm, offsetElm);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&fontStyleTextAttr));
// "text-line-through-style" text attribute
nsCSSTextAttr lineThroughTextAttr(3, hyperTextElm, offsetElm);
nsCSSTextAttr lineThroughTextAttr(2, hyperTextElm, offsetElm);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&lineThroughTextAttr));
// "text-underline-style" text attribute
nsCSSTextAttr underlineTextAttr(4, hyperTextElm, offsetElm);
nsCSSTextAttr underlineTextAttr(3, hyperTextElm, offsetElm);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&underlineTextAttr));
// "text-position" text attribute
nsCSSTextAttr posTextAttr(5, hyperTextElm, offsetElm);
nsCSSTextAttr posTextAttr(4, hyperTextElm, offsetElm);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&posTextAttr));
// "background-color" text attribute
nsBGColorTextAttr bgColorTextAttr(rootFrame, frame);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&bgColorTextAttr));
// "color" text attribute
ColorTextAttr colorTextAttr(rootFrame, frame);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&colorTextAttr));
// "font-size" text attribute
nsFontSizeTextAttr fontSizeTextAttr(rootFrame, frame);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&fontSizeTextAttr));
@ -363,7 +366,7 @@ nsCSSTextAttr::Format(const nsAutoString& aValue, nsAString& aFormattedValue)
////////////////////////////////////////////////////////////////////////////////
// nsBackgroundTextAttr
// nsBGColorTextAttr
////////////////////////////////////////////////////////////////////////////////
nsBGColorTextAttr::nsBGColorTextAttr(nsIFrame *aRootFrame, nsIFrame *aFrame) :
@ -387,16 +390,8 @@ nsBGColorTextAttr::GetValueFor(nsIContent *aContent, nscolor *aValue)
void
nsBGColorTextAttr::Format(const nscolor& aValue, nsAString& aFormattedValue)
{
// Combine the string like rgb(R, G, B) from nscolor.
nsAutoString value;
value.AppendLiteral("rgb(");
value.AppendInt(NS_GET_R(aValue));
value.AppendLiteral(", ");
value.AppendInt(NS_GET_G(aValue));
value.AppendLiteral(", ");
value.AppendInt(NS_GET_B(aValue));
value.Append(')');
StyleInfo::Format(aValue, value);
aFormattedValue = value;
}
@ -426,6 +421,43 @@ nsBGColorTextAttr::GetColor(nsIFrame *aFrame, nscolor *aColor)
}
////////////////////////////////////////////////////////////////////////////////
// ColorTextAttr
////////////////////////////////////////////////////////////////////////////////
ColorTextAttr::ColorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
nsTextAttr<nscolor>(!aFrame)
{
mRootNativeValue = aRootFrame->GetStyleColor()->mColor;
mIsRootDefined = true;
if (aFrame) {
mNativeValue = aFrame->GetStyleColor()->mColor;
mIsDefined = true;
}
}
bool
ColorTextAttr::GetValueFor(nsIContent* aContent, nscolor* aValue)
{
nsIFrame* frame = aContent->GetPrimaryFrame();
if (frame) {
*aValue = frame->GetStyleColor()->mColor;
return true;
}
return false;
}
void
ColorTextAttr::Format(const nscolor& aValue, nsAString& aFormattedValue)
{
nsAutoString value;
StyleInfo::Format(aValue, value);
aFormattedValue = value;
}
////////////////////////////////////////////////////////////////////////////////
// nsFontSizeTextAttr
////////////////////////////////////////////////////////////////////////////////

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

@ -307,6 +307,25 @@ private:
};
/**
* Class is used for the work with 'color' text attribute in nsTextAttrsMgr
* class.
*/
class ColorTextAttr : public nsTextAttr<nscolor>
{
public:
ColorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
// nsITextAttr
virtual nsIAtom* GetName() const { return nsGkAtoms::color; }
protected:
// nsTextAttr
virtual bool GetValueFor(nsIContent* aContent, nscolor* aValue);
virtual void Format(const nscolor& aValue, nsAString& aFormattedValue);
};
/**
* Class is used for the work with "font-size" text attribute in nsTextAttrsMgr
* class.

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

@ -192,6 +192,7 @@
@BINPATH@/components/find.xpt
@BINPATH@/components/fuel.xpt
@BINPATH@/components/gfx.xpt
@BINPATH@/components/html5.xpt
@BINPATH@/components/htmlparser.xpt
@BINPATH@/components/imglib2.xpt
@BINPATH@/components/imgicon.xpt

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

@ -190,6 +190,7 @@
@BINPATH@/components/find.xpt
@BINPATH@/components/fuel.xpt
@BINPATH@/components/gfx.xpt
@BINPATH@/components/html5.xpt
@BINPATH@/components/htmlparser.xpt
@BINPATH@/components/imglib2.xpt
@BINPATH@/components/imgicon.xpt

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

@ -1191,6 +1191,7 @@ xpicleanup@BIN_SUFFIX@
components/fuel.xpt
components/gfx.xpt
components/gksvgrenderer.xpt
components/html5.xpt
components/htmlparser.xpt
components/imgicon.xpt
components/imglib2.xpt

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

@ -181,8 +181,4 @@ radio[pane=paneSync] {
margin-bottom: 1em;
}
#syncEnginesList {
height: 10em;
}
%endif

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

@ -239,8 +239,4 @@ caption {
margin-bottom: 1em;
}
#syncEnginesList {
height: 10em;
}
%endif

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

@ -169,10 +169,6 @@ radio[pane=paneSync] {
#syncAddDeviceLabel {
margin-top: 1em;
margin-bottom: 1em;
}
#syncEnginesList {
height: 11em;
}
%endif

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

@ -99,6 +99,33 @@ def build_linux_headers(inst_dir):
build_linux_headers_aux(inst_dir)
with_env({"PATH" : aux_inst_dir + "/bin:%s" % os.environ["PATH"]}, f)
def build_gcc(stage_dir, is_stage_one):
gcc_build_dir = stage_dir + '/gcc'
tool_inst_dir = stage_dir + '/inst'
lib_inst_dir = stage_dir + '/libinst'
gcc_configure_args = ["--prefix=%s" % tool_inst_dir,
"--enable-__cxa_atexit",
"--with-gmp=%s" % lib_inst_dir,
"--with-mpfr=%s" % lib_inst_dir,
"--with-mpc=%s" % lib_inst_dir,
"--enable-languages=c,c++",
"--disable-multilib",
"--disable-bootstrap"]
if is_stage_one:
# We build the stage1 gcc without shared libraries. Otherwise its
# libgcc.so would depend on the system libc.so, which causes problems
# when it tries to use that libgcc.so and the libc we are about to
# build.
gcc_configure_args.append("--disable-shared")
build_package(gcc_source_dir, gcc_build_dir, gcc_configure_args)
if is_stage_one:
# The glibc build system uses -lgcc_eh, but at least in this setup
# libgcc.a has all it needs.
d = tool_inst_dir + "/lib/gcc/x86_64-unknown-linux-gnu/4.5.2/"
os.symlink(d + "libgcc.a", d + "libgcc_eh.a")
def build_one_stage(env, stage_dir, is_stage_one):
def f():
build_one_stage_aux(stage_dir, is_stage_one)
@ -129,33 +156,18 @@ def build_one_stage_aux(stage_dir, is_stage_one):
build_package(binutils_source_dir, binutils_build_dir,
["--prefix=%s" % tool_inst_dir])
gcc_build_dir = stage_dir + '/gcc'
gcc_configure_args = ["--prefix=%s" % tool_inst_dir,
"--enable-__cxa_atexit",
"--with-gmp=%s" % lib_inst_dir,
"--with-mpfr=%s" % lib_inst_dir,
"--with-mpc=%s" % lib_inst_dir,
"--enable-languages=c,c++",
"--disable-multilib",
"--disable-bootstrap"]
# During stage one we have to build gcc first, this glibc doesn't even
# build with gcc 4.6. During stage two, we have to build glibc first.
# The problem is that libstdc++ is built with xgcc and if glibc has
# not been built yet xgcc will use the system one.
if is_stage_one:
# We build the stage1 gcc without shared libraries. Otherwise its
# libgcc.so would depend on the system libc.so, which causes problems
# when it tries to use that libgcc.so and the libc we are about to
# build.
gcc_configure_args.append("--disable-shared")
build_package(gcc_source_dir, gcc_build_dir, gcc_configure_args)
if is_stage_one:
# The glibc build system uses -lgcc_eh, but at least in this setup
# libgcc.a has all it needs.
d = tool_inst_dir + "/lib/gcc/x86_64-unknown-linux-gnu/4.5.2/"
os.symlink(d + "libgcc.a", d + "libgcc_eh.a")
build_glibc({"CC" : tool_inst_dir + "/bin/gcc",
"CXX" : tool_inst_dir + "/bin/g++"},
stage_dir, tool_inst_dir)
build_gcc(stage_dir, is_stage_one)
build_glibc({"CC" : tool_inst_dir + "/bin/gcc",
"CXX" : tool_inst_dir + "/bin/g++"},
stage_dir, tool_inst_dir)
else:
build_glibc({}, stage_dir, tool_inst_dir)
build_gcc(stage_dir, is_stage_one)
def build_tar_package(tar, name, base, directory):
name = os.path.realpath(name)

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

@ -318,7 +318,7 @@ if test -n "$gonkdir" ; then
STLPORT_CPPFLAGS="-I$gonkdir/ndk/sources/cxx-stl/stlport/stlport/"
STLPORT_LIBS="-lstlport"
CPPFLAGS="-DANDROID -isystem $gonkdir/bionic/libc/include/ -isystem $gonkdir/bionic/libc/kernel/common -isystem $gonkdir/bionic/libc/arch-arm/include -isystem $gonkdir/bionic/libc/kernel/arch-arm -isystem $gonkdir/bionic/libm/include -isystem $gonkdir/frameworks/base/opengl/include -isystem $gonkdir/frameworks/base/native/include -isystem $gonkdir/hardware/libhardware/include -isystem $gonkdir/hardware/libhardware_legacy/include -isystem $gonkdir/system/core/include -isystem $gonkdir/bionic -isystem $gonkdir/frameworks/base/include $STLPORT_CPPFLAGS $CPPFLAGS -isystem $gonkdir/frameworks/base/services/sensorservice"
CPPFLAGS="-DANDROID -I$gonkdir/bionic/libc/include/ -I$gonkdir/bionic/libc/kernel/common -I$gonkdir/bionic/libc/arch-arm/include -I$gonkdir/bionic/libc/kernel/arch-arm -I$gonkdir/bionic/libm/include -I$gonkdir/frameworks/base/opengl/include -I$gonkdir/frameworks/base/native/include -I$gonkdir/hardware/libhardware/include -I$gonkdir/hardware/libhardware_legacy/include -I$gonkdir/system/core/include -I$gonkdir/bionic -I$gonkdir/frameworks/base/include $STLPORT_CPPFLAGS $CPPFLAGS -I$gonkdir/frameworks/base/services/sensorservice"
CFLAGS="-mandroid -fno-short-enums -fno-exceptions $CFLAGS"
CXXFLAGS="-mandroid -fno-short-enums -fno-exceptions $CXXFLAGS"
LIBS="$LIBS $STLPORT_LIBS"

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

@ -1144,12 +1144,34 @@ public:
* @param aSourceBuffer the string to parse as an HTML document
* @param aTargetDocument the document object to parse into. Must not have
* child nodes.
* @param aScriptingEnabledForNoscriptParsing whether <noscript> is parsed
* as if scripting was enabled
* @return NS_ERROR_DOM_INVALID_STATE_ERR if a re-entrant attempt to parse
* fragments is made, NS_ERROR_OUT_OF_MEMORY if aSourceBuffer is too
* long and NS_OK otherwise.
*/
static nsresult ParseDocumentHTML(const nsAString& aSourceBuffer,
nsIDocument* aTargetDocument);
nsIDocument* aTargetDocument,
bool aScriptingEnabledForNoscriptParsing);
/**
* Converts HTML source to plain text by parsing the source and using the
* plain text serializer on the resulting tree.
*
* @param aSourceBuffer the string to parse as an HTML document
* @param aResultBuffer the string where the plain text result appears;
* may be the same string as aSourceBuffer
* @param aFlags Flags from nsIDocumentEncoder.
* @param aWrapCol Number of columns after which to line wrap; 0 for no
* auto-wrapping
* @return NS_ERROR_DOM_INVALID_STATE_ERR if a re-entrant attempt to parse
* fragments is made, NS_ERROR_OUT_OF_MEMORY if aSourceBuffer is too
* long and NS_OK otherwise.
*/
static nsresult ConvertToPlainText(const nsAString& aSourceBuffer,
nsAString& aResultBuffer,
PRUint32 aFlags,
PRUint32 aWrapCol);
/**
* Creates a new XML document, which is marked to be loaded as data.
@ -1941,6 +1963,32 @@ public:
*/
static bool URIIsChromeOrInPref(nsIURI *aURI, const char *aPref);
/**
* This will parse aSource, to extract the value of the pseudo attribute
* with the name specified in aName. See
* http://www.w3.org/TR/xml-stylesheet/#NT-StyleSheetPI for the specification
* which is used to parse aSource.
*
* @param aSource the string to parse
* @param aName the name of the attribute to get the value for
* @param aValue [out] the value for the attribute with name specified in
* aAttribute. Empty if the attribute isn't present.
* @return true if the attribute exists and was successfully parsed.
* false if the attribute doesn't exist, or has a malformed
* value, such as an unknown or unterminated entity.
*/
static bool GetPseudoAttributeValue(const nsString& aSource, nsIAtom *aName,
nsAString& aValue);
/**
* Returns true if the language name is a version of JavaScript and
* false otherwise
*/
static bool IsJavaScriptLanguage(const nsString& aName, PRUint32 *aVerFlags);
static void SplitMimeType(const nsAString& aValue, nsString& aType,
nsString& aParams);
private:
static bool InitializeEventTable();

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

@ -172,7 +172,8 @@ interface nsIDocumentEncoder : nsISupports
/**
* Output the content of noframes elements (only for serializing
* to plaintext).
* to plaintext). (Used only internally in the plain text serializer;
* ignored if passed by the caller.)
*/
const unsigned long OutputNoFramesContent = (1 << 12);

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

@ -127,7 +127,6 @@ CPPSRCS = \
nsNodeIterator.cpp \
nsNodeUtils.cpp \
nsObjectLoadingContent.cpp \
nsParserUtils.cpp \
nsPlainTextSerializer.cpp \
nsPropertyTable.cpp \
nsRange.cpp \

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

@ -80,7 +80,6 @@
#include "nsIPrompt.h"
#include "nsServiceManagerUtils.h"
#include "nsContentUtils.h"
#include "nsParserUtils.h"
#include "nsCRT.h"
#include "nsEscape.h"
#include "nsWeakReference.h"
@ -712,7 +711,7 @@ nsContentSink::ProcessStyleLink(nsIContent* aElement,
nsAutoString mimeType;
nsAutoString params;
nsParserUtils::SplitMimeType(aType, mimeType, params);
nsContentUtils::SplitMimeType(aType, mimeType, params);
// see bug 18817
if (!mimeType.IsEmpty() && !mimeType.LowerCaseEqualsLiteral("text/css")) {

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

@ -180,6 +180,7 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID);
#include "nsIViewManager.h"
#include "nsEventStateManager.h"
#include "nsIDOMHTMLInputElement.h"
#include "nsParserConstants.h"
#ifdef IBMBIDI
#include "nsIBidiKeyboard.h"
@ -720,6 +721,185 @@ nsContentUtils::URIIsChromeOrInPref(nsIURI *aURI, const char *aPref)
return false;
}
#define SKIP_WHITESPACE(iter, end_iter, end_res) \
while ((iter) != (end_iter) && nsCRT::IsAsciiSpace(*(iter))) { \
++(iter); \
} \
if ((iter) == (end_iter)) { \
return (end_res); \
}
#define SKIP_ATTR_NAME(iter, end_iter) \
while ((iter) != (end_iter) && !nsCRT::IsAsciiSpace(*(iter)) && \
*(iter) != '=') { \
++(iter); \
}
bool
nsContentUtils::GetPseudoAttributeValue(const nsString& aSource, nsIAtom *aName,
nsAString& aValue)
{
aValue.Truncate();
const PRUnichar *start = aSource.get();
const PRUnichar *end = start + aSource.Length();
const PRUnichar *iter;
while (start != end) {
SKIP_WHITESPACE(start, end, false)
iter = start;
SKIP_ATTR_NAME(iter, end)
if (start == iter) {
return false;
}
// Remember the attr name.
const nsDependentSubstring & attrName = Substring(start, iter);
// Now check whether this is a valid name="value" pair.
start = iter;
SKIP_WHITESPACE(start, end, false)
if (*start != '=') {
// No '=', so this is not a name="value" pair. We don't know
// what it is, and we have no way to handle it.
return false;
}
// Have to skip the value.
++start;
SKIP_WHITESPACE(start, end, false)
PRUnichar q = *start;
if (q != kQuote && q != kApostrophe) {
// Not a valid quoted value, so bail.
return false;
}
++start; // Point to the first char of the value.
iter = start;
while (iter != end && *iter != q) {
++iter;
}
if (iter == end) {
// Oops, unterminated quoted string.
return false;
}
// At this point attrName holds the name of the "attribute" and
// the value is between start and iter.
if (aName->Equals(attrName)) {
nsIParserService* parserService = nsContentUtils::GetParserService();
NS_ENSURE_TRUE(parserService, false);
// We'll accumulate as many characters as possible (until we hit either
// the end of the string or the beginning of an entity). Chunks will be
// delimited by start and chunkEnd.
const PRUnichar *chunkEnd = start;
while (chunkEnd != iter) {
if (*chunkEnd == kLessThan) {
aValue.Truncate();
return false;
}
if (*chunkEnd == kAmpersand) {
aValue.Append(start, chunkEnd - start);
// Point to first character after the ampersand.
++chunkEnd;
const PRUnichar *afterEntity;
PRUnichar result[2];
PRUint32 count =
parserService->DecodeEntity(chunkEnd, iter, &afterEntity, result);
if (count == 0) {
aValue.Truncate();
return false;
}
aValue.Append(result, count);
// Advance to after the entity and begin a new chunk.
start = chunkEnd = afterEntity;
}
else {
++chunkEnd;
}
}
// Append remainder.
aValue.Append(start, iter - start);
return true;
}
// Resume scanning after the end of the attribute value (past the quote
// char).
start = iter + 1;
}
return false;
}
bool
nsContentUtils::IsJavaScriptLanguage(const nsString& aName, PRUint32 *aFlags)
{
JSVersion version = JSVERSION_UNKNOWN;
if (aName.LowerCaseEqualsLiteral("javascript") ||
aName.LowerCaseEqualsLiteral("livescript") ||
aName.LowerCaseEqualsLiteral("mocha")) {
version = JSVERSION_DEFAULT;
} else if (aName.LowerCaseEqualsLiteral("javascript1.0")) {
version = JSVERSION_1_0;
} else if (aName.LowerCaseEqualsLiteral("javascript1.1")) {
version = JSVERSION_1_1;
} else if (aName.LowerCaseEqualsLiteral("javascript1.2")) {
version = JSVERSION_1_2;
} else if (aName.LowerCaseEqualsLiteral("javascript1.3")) {
version = JSVERSION_1_3;
} else if (aName.LowerCaseEqualsLiteral("javascript1.4")) {
version = JSVERSION_1_4;
} else if (aName.LowerCaseEqualsLiteral("javascript1.5")) {
version = JSVERSION_1_5;
} else if (aName.LowerCaseEqualsLiteral("javascript1.6")) {
version = JSVERSION_1_6;
} else if (aName.LowerCaseEqualsLiteral("javascript1.7")) {
version = JSVERSION_1_7;
} else if (aName.LowerCaseEqualsLiteral("javascript1.8")) {
version = JSVERSION_1_8;
}
if (version == JSVERSION_UNKNOWN) {
return false;
}
*aFlags = version;
return true;
}
void
nsContentUtils::SplitMimeType(const nsAString& aValue, nsString& aType,
nsString& aParams)
{
aType.Truncate();
aParams.Truncate();
PRInt32 semiIndex = aValue.FindChar(PRUnichar(';'));
if (-1 != semiIndex) {
aType = Substring(aValue, 0, semiIndex);
aParams = Substring(aValue, semiIndex + 1,
aValue.Length() - (semiIndex + 1));
aParams.StripWhitespace();
}
else {
aType = aValue;
}
aType.StripWhitespace();
}
/**
* Access a cached parser service. Don't addref. We need only one
* reference to it and this class has that one.
@ -3747,7 +3927,8 @@ nsContentUtils::ParseFragmentHTML(const nsAString& aSourceBuffer,
/* static */
nsresult
nsContentUtils::ParseDocumentHTML(const nsAString& aSourceBuffer,
nsIDocument* aTargetDocument)
nsIDocument* aTargetDocument,
bool aScriptingEnabledForNoscriptParsing)
{
if (nsContentUtils::sFragmentParsingActive) {
NS_NOTREACHED("Re-entrant fragment parsing attempted.");
@ -3761,7 +3942,8 @@ nsContentUtils::ParseDocumentHTML(const nsAString& aSourceBuffer,
}
nsresult rv =
sHTMLFragmentParser->ParseDocument(aSourceBuffer,
aTargetDocument);
aTargetDocument,
aScriptingEnabledForNoscriptParsing);
return rv;
}
@ -3812,6 +3994,44 @@ nsContentUtils::ParseFragmentXML(const nsAString& aSourceBuffer,
return rv;
}
/* static */
nsresult
nsContentUtils::ConvertToPlainText(const nsAString& aSourceBuffer,
nsAString& aResultBuffer,
PRUint32 aFlags,
PRUint32 aWrapCol)
{
nsCOMPtr<nsIURI> uri;
NS_NewURI(getter_AddRefs(uri), "about:blank");
nsCOMPtr<nsIPrincipal> principal =
do_CreateInstance("@mozilla.org/nullprincipal;1");
nsCOMPtr<nsIDOMDocument> domDocument;
nsresult rv = nsContentUtils::CreateDocument(EmptyString(),
EmptyString(),
nsnull,
uri,
uri,
principal,
nsnull,
DocumentFlavorHTML,
getter_AddRefs(domDocument));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDocument> document = do_QueryInterface(domDocument);
rv = nsContentUtils::ParseDocumentHTML(aSourceBuffer, document,
!(aFlags & nsIDocumentEncoder::OutputNoScriptContent));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDocumentEncoder> encoder = do_CreateInstance(
"@mozilla.org/layout/documentEncoder;1?type=text/plain");
rv = encoder->Init(domDocument, NS_LITERAL_STRING("text/plain"), aFlags);
NS_ENSURE_SUCCESS(rv, rv);
encoder->SetWrapColumn(aWrapCol);
return encoder->EncodeToString(aResultBuffer);
}
/* static */
nsresult

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

@ -48,7 +48,6 @@
#include "nsMimeTypes.h"
#include "nsIStreamConverterService.h"
#include "nsStringStream.h"
#include "nsParserUtils.h"
#include "nsGkAtoms.h"
#include "nsWhitespaceTokenizer.h"
#include "nsIChannelEventSink.h"

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

@ -102,7 +102,7 @@ nsDOMParser::ParseFromString(const PRUnichar *str,
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDocument> document = do_QueryInterface(domDocument);
nsDependentString sourceBuffer(str);
rv = nsContentUtils::ParseDocumentHTML(sourceBuffer, document);
rv = nsContentUtils::ParseDocumentHTML(sourceBuffer, document, false);
NS_ENSURE_SUCCESS(rv, rv);
// Keep the XULXBL state, base URL and principal setting in sync with the

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

@ -2901,6 +2901,14 @@ nsGenericElement::GetAttributeNodeNS(const nsAString& aNamespaceURI,
OwnerDoc()->WarnOnceAbout(nsIDocument::eGetAttributeNodeNS);
return GetAttributeNodeNSInternal(aNamespaceURI, aLocalName, aReturn);
}
nsresult
nsGenericElement::GetAttributeNodeNSInternal(const nsAString& aNamespaceURI,
const nsAString& aLocalName,
nsIDOMAttr** aReturn)
{
nsCOMPtr<nsIDOMNamedNodeMap> map;
nsresult rv = GetAttributes(getter_AddRefs(map));
NS_ENSURE_SUCCESS(rv, rv);
@ -5208,8 +5216,8 @@ nsGenericElement::SetAttrAndNotify(PRInt32 aNamespaceID,
nsCOMPtr<nsIDOMAttr> attrNode;
nsAutoString ns;
nsContentUtils::NameSpaceManager()->GetNameSpaceURI(aNamespaceID, ns);
GetAttributeNodeNS(ns, nsDependentAtomString(aName),
getter_AddRefs(attrNode));
GetAttributeNodeNSInternal(ns, nsDependentAtomString(aName),
getter_AddRefs(attrNode));
mutation.mRelatedNode = attrNode;
mutation.mAttrName = aName;
@ -5388,8 +5396,8 @@ nsGenericElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
if (hasMutationListeners) {
nsAutoString ns;
nsContentUtils::NameSpaceManager()->GetNameSpaceURI(aNameSpaceID, ns);
GetAttributeNodeNS(ns, nsDependentAtomString(aName),
getter_AddRefs(attrNode));
GetAttributeNodeNSInternal(ns, nsDependentAtomString(aName),
getter_AddRefs(attrNode));
}
// Clear binding to nsIDOMNamedNodeMap

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

@ -794,6 +794,10 @@ protected:
return this;
}
nsresult GetAttributeNodeNSInternal(const nsAString& aNamespaceURI,
const nsAString& aLocalName,
nsIDOMAttr** aReturn);
public:
// Because of a bug in MS C++ compiler nsDOMSlots must be declared public,
// otherwise nsXULElement::nsXULSlots doesn't compile.

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

@ -1,236 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** 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.
*
* 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 ***** */
/*
* Namespace class for some static parsing-related methods.
*/
#include "nsParserUtils.h"
#include "jsapi.h"
#include "nsReadableUtils.h"
#include "nsCRT.h"
#include "nsContentUtils.h"
#include "nsIParserService.h"
#include "nsParserConstants.h"
#define SKIP_WHITESPACE(iter, end_iter, end_res) \
while ((iter) != (end_iter) && nsCRT::IsAsciiSpace(*(iter))) { \
++(iter); \
} \
if ((iter) == (end_iter)) { \
return (end_res); \
}
#define SKIP_ATTR_NAME(iter, end_iter) \
while ((iter) != (end_iter) && !nsCRT::IsAsciiSpace(*(iter)) && \
*(iter) != '=') { \
++(iter); \
}
bool
nsParserUtils::GetQuotedAttributeValue(const nsString& aSource, nsIAtom *aName,
nsAString& aValue)
{
aValue.Truncate();
const PRUnichar *start = aSource.get();
const PRUnichar *end = start + aSource.Length();
const PRUnichar *iter;
while (start != end) {
SKIP_WHITESPACE(start, end, false)
iter = start;
SKIP_ATTR_NAME(iter, end)
if (start == iter) {
return false;
}
// Remember the attr name.
const nsDependentSubstring & attrName = Substring(start, iter);
// Now check whether this is a valid name="value" pair.
start = iter;
SKIP_WHITESPACE(start, end, false)
if (*start != '=') {
// No '=', so this is not a name="value" pair. We don't know
// what it is, and we have no way to handle it.
return false;
}
// Have to skip the value.
++start;
SKIP_WHITESPACE(start, end, false)
PRUnichar q = *start;
if (q != kQuote && q != kApostrophe) {
// Not a valid quoted value, so bail.
return false;
}
++start; // Point to the first char of the value.
iter = start;
while (iter != end && *iter != q) {
++iter;
}
if (iter == end) {
// Oops, unterminated quoted string.
return false;
}
// At this point attrName holds the name of the "attribute" and
// the value is between start and iter.
if (aName->Equals(attrName)) {
nsIParserService* parserService = nsContentUtils::GetParserService();
NS_ENSURE_TRUE(parserService, false);
// We'll accumulate as many characters as possible (until we hit either
// the end of the string or the beginning of an entity). Chunks will be
// delimited by start and chunkEnd.
const PRUnichar *chunkEnd = start;
while (chunkEnd != iter) {
if (*chunkEnd == kLessThan) {
aValue.Truncate();
return false;
}
if (*chunkEnd == kAmpersand) {
aValue.Append(start, chunkEnd - start);
// Point to first character after the ampersand.
++chunkEnd;
const PRUnichar *afterEntity;
PRUnichar result[2];
PRUint32 count =
parserService->DecodeEntity(chunkEnd, iter, &afterEntity, result);
if (count == 0) {
aValue.Truncate();
return false;
}
aValue.Append(result, count);
// Advance to after the entity and begin a new chunk.
start = chunkEnd = afterEntity;
}
else {
++chunkEnd;
}
}
// Append remainder.
aValue.Append(start, iter - start);
return true;
}
// Resume scanning after the end of the attribute value (past the quote
// char).
start = iter + 1;
}
return false;
}
// Returns true if the language name is a version of JavaScript and
// false otherwise
bool
nsParserUtils::IsJavaScriptLanguage(const nsString& aName, PRUint32 *aFlags)
{
JSVersion version = JSVERSION_UNKNOWN;
if (aName.LowerCaseEqualsLiteral("javascript") ||
aName.LowerCaseEqualsLiteral("livescript") ||
aName.LowerCaseEqualsLiteral("mocha")) {
version = JSVERSION_DEFAULT;
}
else if (aName.LowerCaseEqualsLiteral("javascript1.0")) {
version = JSVERSION_1_0;
}
else if (aName.LowerCaseEqualsLiteral("javascript1.1")) {
version = JSVERSION_1_1;
}
else if (aName.LowerCaseEqualsLiteral("javascript1.2")) {
version = JSVERSION_1_2;
}
else if (aName.LowerCaseEqualsLiteral("javascript1.3")) {
version = JSVERSION_1_3;
}
else if (aName.LowerCaseEqualsLiteral("javascript1.4")) {
version = JSVERSION_1_4;
}
else if (aName.LowerCaseEqualsLiteral("javascript1.5")) {
version = JSVERSION_1_5;
}
else if (aName.LowerCaseEqualsLiteral("javascript1.6")) {
version = JSVERSION_1_6;
}
else if (aName.LowerCaseEqualsLiteral("javascript1.7")) {
version = JSVERSION_1_7;
}
else if (aName.LowerCaseEqualsLiteral("javascript1.8")) {
version = JSVERSION_1_8;
}
if (version == JSVERSION_UNKNOWN)
return false;
*aFlags = version;
return true;
}
void
nsParserUtils::SplitMimeType(const nsAString& aValue, nsString& aType,
nsString& aParams)
{
aType.Truncate();
aParams.Truncate();
PRInt32 semiIndex = aValue.FindChar(PRUnichar(';'));
if (-1 != semiIndex) {
aType = Substring(aValue, 0, semiIndex);
aParams = Substring(aValue, semiIndex + 1,
aValue.Length() - (semiIndex + 1));
aParams.StripWhitespace();
}
else {
aType = aValue;
}
aType.StripWhitespace();
}

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

@ -1,79 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** 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.
*
* 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 ***** */
/*
* Namespace class for some static parsing-related methods.
*/
#ifndef nsParserUtils_h__
#define nsParserUtils_h__
#include "nsString.h"
class nsIAtom;
class nsParserUtils {
public:
/**
* This will parse aSource, to extract the value of the pseudo attribute
* with the name specified in aName. See
* http://www.w3.org/TR/xml-stylesheet/#NT-StyleSheetPI for the specification
* which is used to parse aSource.
*
* @param aSource the string to parse
* @param aName the name of the attribute to get the value for
* @param aValue [out] the value for the attribute with name specified in
* aAttribute. Empty if the attribute isn't present.
* @return true if the attribute exists and was successfully parsed.
* false if the attribute doesn't exist, or has a malformed
* value, such as an unknown or unterminated entity.
*/
static bool
GetQuotedAttributeValue(const nsString& aSource, nsIAtom *aName,
nsAString& aValue);
static bool
IsJavaScriptLanguage(const nsString& aName, PRUint32 *aVerFlags);
static void
SplitMimeType(const nsAString& aValue, nsString& aType,
nsString& aParams);
};
#endif // nsParserUtils_h__

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

@ -44,7 +44,6 @@
#include "jsapi.h"
#include "jsfriendapi.h"
#include "nsScriptLoader.h"
#include "nsParserUtils.h"
#include "nsICharsetConverterManager.h"
#include "nsIUnicodeDecoder.h"
#include "nsIContent.h"
@ -509,14 +508,14 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
if (scriptContent->IsHTML()) {
scriptContent->GetAttr(kNameSpaceID_None, nsGkAtoms::language, language);
if (!language.IsEmpty()) {
if (nsParserUtils::IsJavaScriptLanguage(language, &version))
if (nsContentUtils::IsJavaScriptLanguage(language, &version))
typeID = nsIProgrammingLanguage::JAVASCRIPT;
else
typeID = nsIProgrammingLanguage::UNKNOWN;
// IE, Opera, etc. do not respect language version, so neither should
// we at this late date in the browser wars saga. Note that this change
// affects HTML but not XUL or SVG (but note also that XUL has its own
// code to check nsParserUtils::IsJavaScriptLanguage -- that's probably
// code to check nsContentUtils::IsJavaScriptLanguage -- that's probably
// a separate bug, one we may not be able to fix short of XUL2). See
// bug 255895 (https://bugzilla.mozilla.org/show_bug.cgi?id=255895).
NS_ASSERTION(JSVERSION_DEFAULT == 0,

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

@ -37,37 +37,18 @@
#include "TestHarness.h"
#include "nsIParser.h"
#include "nsIHTMLToTextSink.h"
#include "nsIParser.h"
#include "nsIContentSink.h"
#include "nsIParserService.h"
#include "nsServiceManagerUtils.h"
#include "nsStringGlue.h"
#include "nsParserCIID.h"
#include "nsIDocumentEncoder.h"
#include "nsCRT.h"
static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
#include "nsIParserUtils.h"
void
ConvertBufToPlainText(nsString &aConBuf, int aFlag)
{
nsCOMPtr<nsIParser> parser = do_CreateInstance(kCParserCID);
if (parser) {
nsCOMPtr<nsIContentSink> sink;
sink = do_CreateInstance(NS_PLAINTEXTSINK_CONTRACTID);
if (sink) {
nsCOMPtr<nsIHTMLToTextSink> textSink(do_QueryInterface(sink));
if (textSink) {
nsAutoString convertedText;
textSink->Initialize(&convertedText, aFlag, 72);
parser->SetContentSink(sink);
parser->Parse(aConBuf, 0, NS_LITERAL_CSTRING("text/html"), true);
aConBuf = convertedText;
}
}
}
nsCOMPtr<nsIParserUtils> utils =
do_GetService(NS_PARSERUTILS_CONTRACTID);
utils->ConvertToPlainText(aConBuf, aFlag, 72, aConBuf);
}
// Test for ASCII with format=flowed; delsp=yes

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

@ -71,6 +71,7 @@ _CHROME_FILES = \
test_bug574596.html \
test_bug683852.xul \
test_bug599295.html \
test_bug650784.html \
$(NULL)
libs:: $(_TEST_FILES)

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

@ -0,0 +1,43 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=650776
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 650776</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=650776">Mozilla Bug 650776</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 650776 **/
var c = Components.interfaces.nsIDocumentEncoder;
var s = Components.classes["@mozilla.org/parserutils;1"]
.getService(Components.interfaces.nsIParserUtils);
is(s.convertToPlainText("foo", c.OutputLFLineBreak, 0), "foo", "Wrong conversion result 1");
is(s.convertToPlainText("foo foo foo", c.OutputWrap | c.OutputLFLineBreak, 7), "foo foo\nfoo", "Wrong conversion result 2");
is(s.convertToPlainText("<body><noscript>b<span>a</span>r</noscript>foo", c.OutputLFLineBreak, 0), "foo", "Wrong conversion result 3");
is(s.convertToPlainText("<body><noscript>b<span>a</span>r</noscript>foo", c.OutputNoScriptContent, 0), "barfoo", "Wrong conversion result 4");
is(s.convertToPlainText("foo\u00A0bar", c.OutputPersistNBSP | c.OutputLFLineBreak, 0), "foo\u00A0bar", "Wrong conversion result 5");
is(s.convertToPlainText("foo\u00A0bar", c.OutputLFLineBreak, 0), "foo bar", "Wrong conversion result 6");
is(s.convertToPlainText("<body><noframes>bar</noframes>foo", c.OutputLFLineBreak, 0), "foo", "Wrong conversion result 7");
// OutputNoFramesContent doesn't actually work, because the flag gets overridden by
// the browser.frames.enabled pref in all cases.
is(s.convertToPlainText("<body><noframes>bar</noframes>foo", c.OutputNoFramesContent | c.OutputLFLineBreak, 0), "foo", "Wrong conversion result 8");
is(s.convertToPlainText("<i>foo</i> <b>bar</b>", c.OutputFormatted | c.OutputLFLineBreak, 0), "/foo/ *bar*\n", "Wrong conversion result 9");
is(s.convertToPlainText("<p>foo</p> <p>bar</p>", c.OutputLFLineBreak, 0), "foo\n\nbar", "Wrong conversion result 10");
</script>
</pre>
</body>
</html>

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

@ -0,0 +1,18 @@
<html>
<script language=javascript>
function draw() {
var canv = document.getElementById("canv");
var ctx = canv.getContext("2d");
try {
canv.width = 50000;
} catch (e) { }
ctx.clearRect(0, 0, 10, 10);
}
</script>
<body onload="draw()">
<canvas id="canv" width="5" height="5"></canvas>
</body>
</html>

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

@ -3,3 +3,4 @@ load 421715-1.html
load 553938-1.html
load 647480.html
load 0px-size-font-667225.html
skip-if(cocoaWidget&&layersGPUAccelerated) load 729116.html # bug 731117

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

@ -362,8 +362,6 @@ WebGLContext::SetDimensions(PRInt32 width, PRInt32 height)
/*** end of early success return cases ***/
ScopedGfxFeatureReporter reporter("WebGL");
// At this point we know that the old context is not going to survive, even though we still don't
// know if creating the new context will succeed.
DestroyResourcesAndContext();
@ -386,6 +384,8 @@ WebGLContext::SetDimensions(PRInt32 width, PRInt32 height)
bool verbose =
Preferences::GetBool("webgl.verbose", false);
ScopedGfxFeatureReporter reporter("WebGL", forceEnabled);
if (disabled)
return NS_ERROR_FAILURE;

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

@ -42,7 +42,7 @@
using namespace mozilla;
class WebGLMemoryMultiReporter : public nsIMemoryMultiReporter
class WebGLMemoryMultiReporter MOZ_FINAL : public nsIMemoryMultiReporter
{
public:
NS_DECL_ISUPPORTS

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

@ -1306,6 +1306,10 @@ nsCanvasRenderingContext2DAzure::InitializeWithTarget(DrawTarget *target, PRInt3
mTarget = target;
} else {
mValid = false;
// Create a dummy target in the hopes that it will help us deal with users
// calling into us after having changed the size where the size resulted
// in an inability to create a correct DrawTarget.
mTarget = gfxPlatform::GetPlatform()->CreateOffscreenDrawTarget(IntSize(1, 1), FORMAT_B8G8R8A8);
}
mResetLayer = true;

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

@ -52,7 +52,6 @@
#include "nsIDOMEvent.h"
#include "nsIPrivateDOMEvent.h"
#include "nsIDOMEventTarget.h"
#include "nsParserUtils.h"
#include "nsContentUtils.h"
#include "nsPIDOMWindow.h"
#include "nsAsyncDOMEvent.h"
@ -439,7 +438,7 @@ nsHTMLLinkElement::GetStyleSheetInfo(nsAString& aTitle,
nsAutoString mimeType;
nsAutoString notUsed;
GetAttr(kNameSpaceID_None, nsGkAtoms::type, aType);
nsParserUtils::SplitMimeType(aType, mimeType, notUsed);
nsContentUtils::SplitMimeType(aType, mimeType, notUsed);
if (!mimeType.IsEmpty() && !mimeType.LowerCaseEqualsLiteral("text/css")) {
return;
}

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

@ -47,7 +47,6 @@
#include "nsNetUtil.h"
#include "nsIDocument.h"
#include "nsUnicharUtils.h"
#include "nsParserUtils.h"
#include "nsThreadUtils.h"
#include "nsContentUtils.h"
@ -347,7 +346,7 @@ nsHTMLStyleElement::GetStyleSheetInfo(nsAString& aTitle,
nsAutoString mimeType;
nsAutoString notUsed;
nsParserUtils::SplitMimeType(aType, mimeType, notUsed);
nsContentUtils::SplitMimeType(aType, mimeType, notUsed);
if (!mimeType.IsEmpty() && !mimeType.LowerCaseEqualsLiteral("text/css")) {
return;
}

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

@ -50,7 +50,6 @@
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIParser.h"
#include "nsParserUtils.h"
#include "nsScriptLoader.h"
#include "nsIURI.h"
#include "nsNetUtil.h"

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

@ -146,6 +146,11 @@ nsMathMLElement::ParseAttribute(PRInt32 aNamespaceID,
aValue, aResult);
}
static nsGenericElement::MappedAttributeEntry sMtableStyles[] = {
{ &nsGkAtoms::width },
{ nsnull }
};
static nsGenericElement::MappedAttributeEntry sTokenStyles[] = {
{ &nsGkAtoms::mathsize_ },
{ &nsGkAtoms::fontsize_ },
@ -171,6 +176,10 @@ static nsGenericElement::MappedAttributeEntry sCommonPresStyles[] = {
bool
nsMathMLElement::IsAttributeMapped(const nsIAtom* aAttribute) const
{
static const MappedAttributeEntry* const mtableMap[] = {
sMtableStyles,
sCommonPresStyles
};
static const MappedAttributeEntry* const tokenMap[] = {
sTokenStyles,
sCommonPresStyles
@ -194,6 +203,9 @@ nsMathMLElement::IsAttributeMapped(const nsIAtom* aAttribute) const
tag == nsGkAtoms::math)
return FindAttributeDependence(aAttribute, mstyleMap);
if (tag == nsGkAtoms::mtable_)
return FindAttributeDependence(aAttribute, mtableMap);
if (tag == nsGkAtoms::maction_ ||
tag == nsGkAtoms::maligngroup_ ||
tag == nsGkAtoms::malignmark_ ||
@ -211,7 +223,6 @@ nsMathMLElement::IsAttributeMapped(const nsIAtom* aAttribute) const
tag == nsGkAtoms::msub_ ||
tag == nsGkAtoms::msubsup_ ||
tag == nsGkAtoms::msup_ ||
tag == nsGkAtoms::mtable_ ||
tag == nsGkAtoms::mtd_ ||
tag == nsGkAtoms::mtr_ ||
tag == nsGkAtoms::munder_ ||
@ -459,6 +470,19 @@ nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
colorValue->SetColorValue(color);
}
}
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Position)) {
// width: value
nsCSSValue* width = aData->ValueForWidth();
if (width->GetUnit() == eCSSUnit_Null) {
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::width);
// This does not handle auto and unitless values
if (value && value->Type() == nsAttrValue::eString) {
ParseNumericValue(value->GetStringValue(), *width, 0);
}
}
}
}
nsresult

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

@ -39,8 +39,8 @@
#include "nsGkAtoms.h"
#include "nsUnicharUtils.h"
#include "nsXMLProcessingInstruction.h"
#include "nsParserUtils.h"
#include "nsContentCreatorFunctions.h"
#include "nsContentUtils.h"
nsresult
NS_NewXMLProcessingInstruction(nsIContent** aInstancePtrResult,
@ -129,7 +129,7 @@ nsXMLProcessingInstruction::GetAttrValue(nsIAtom *aName, nsAString& aValue)
nsAutoString data;
GetData(data);
return nsParserUtils::GetQuotedAttributeValue(data, aName, aValue);
return nsContentUtils::GetPseudoAttributeValue(data, aName, aValue);
}
bool

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

@ -45,7 +45,6 @@
#include "nsNetUtil.h"
#include "nsXMLProcessingInstruction.h"
#include "nsUnicharUtils.h"
#include "nsParserUtils.h"
#include "nsGkAtoms.h"
#include "nsThreadUtils.h"
#include "nsContentUtils.h"
@ -209,10 +208,12 @@ nsXMLStylesheetPI::GetStyleSheetInfo(nsAString& aTitle,
nsAutoString data;
GetData(data);
nsParserUtils::GetQuotedAttributeValue(data, nsGkAtoms::title, aTitle);
nsContentUtils::GetPseudoAttributeValue(data, nsGkAtoms::title, aTitle);
nsAutoString alternate;
nsParserUtils::GetQuotedAttributeValue(data, nsGkAtoms::alternate, alternate);
nsContentUtils::GetPseudoAttributeValue(data,
nsGkAtoms::alternate,
alternate);
// if alternate, does it have title?
if (alternate.EqualsLiteral("yes")) {
@ -223,13 +224,13 @@ nsXMLStylesheetPI::GetStyleSheetInfo(nsAString& aTitle,
*aIsAlternate = true;
}
nsParserUtils::GetQuotedAttributeValue(data, nsGkAtoms::media, aMedia);
nsContentUtils::GetPseudoAttributeValue(data, nsGkAtoms::media, aMedia);
nsAutoString type;
nsParserUtils::GetQuotedAttributeValue(data, nsGkAtoms::type, type);
nsContentUtils::GetPseudoAttributeValue(data, nsGkAtoms::type, type);
nsAutoString mimeType, notUsed;
nsParserUtils::SplitMimeType(type, mimeType, notUsed);
nsContentUtils::SplitMimeType(type, mimeType, notUsed);
if (!mimeType.IsEmpty() && !mimeType.LowerCaseEqualsLiteral("text/css")) {
aType.Assign(type);
return;

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

@ -68,7 +68,6 @@
#include "prtime.h"
#include "prlog.h"
#include "prmem.h"
#include "nsParserUtils.h"
#include "nsRect.h"
#include "nsGenericElement.h"
#include "nsIWebNavigation.h"
@ -265,11 +264,11 @@ CheckXSLTParamPI(nsIDOMProcessingInstruction* aPi,
if (target.EqualsLiteral("xslt-param-namespace")) {
aPi->GetData(data);
nsAutoString prefix, namespaceAttr;
nsParserUtils::GetQuotedAttributeValue(data, nsGkAtoms::prefix,
prefix);
nsContentUtils::GetPseudoAttributeValue(data, nsGkAtoms::prefix,
prefix);
if (!prefix.IsEmpty() &&
nsParserUtils::GetQuotedAttributeValue(data, nsGkAtoms::_namespace,
namespaceAttr)) {
nsContentUtils::GetPseudoAttributeValue(data, nsGkAtoms::_namespace,
namespaceAttr)) {
aProcessor->AddXSLTParamNamespace(prefix, namespaceAttr);
}
}
@ -278,14 +277,14 @@ CheckXSLTParamPI(nsIDOMProcessingInstruction* aPi,
else if (target.EqualsLiteral("xslt-param")) {
aPi->GetData(data);
nsAutoString name, namespaceAttr, select, value;
nsParserUtils::GetQuotedAttributeValue(data, nsGkAtoms::name,
name);
nsParserUtils::GetQuotedAttributeValue(data, nsGkAtoms::_namespace,
namespaceAttr);
if (!nsParserUtils::GetQuotedAttributeValue(data, nsGkAtoms::select, select)) {
nsContentUtils::GetPseudoAttributeValue(data, nsGkAtoms::name,
name);
nsContentUtils::GetPseudoAttributeValue(data, nsGkAtoms::_namespace,
namespaceAttr);
if (!nsContentUtils::GetPseudoAttributeValue(data, nsGkAtoms::select, select)) {
select.SetIsVoid(true);
}
if (!nsParserUtils::GetQuotedAttributeValue(data, nsGkAtoms::value, value)) {
if (!nsContentUtils::GetPseudoAttributeValue(data, nsGkAtoms::value, value)) {
value.SetIsVoid(true);
}
if (!name.IsEmpty()) {
@ -1340,7 +1339,7 @@ nsXMLContentSink::HandleProcessingInstruction(const PRUnichar *aTarget,
// If it's not a CSS stylesheet PI...
nsAutoString type;
nsParserUtils::GetQuotedAttributeValue(data, nsGkAtoms::type, type);
nsContentUtils::GetPseudoAttributeValue(data, nsGkAtoms::type, type);
if (mState != eXMLContentSinkState_InProlog ||
!target.EqualsLiteral("xml-stylesheet") ||
@ -1368,16 +1367,18 @@ nsXMLContentSink::ParsePIData(const nsString &aData, nsString &aHref,
bool &aIsAlternate)
{
// If there was no href, we can't do anything with this PI
if (!nsParserUtils::GetQuotedAttributeValue(aData, nsGkAtoms::href, aHref)) {
if (!nsContentUtils::GetPseudoAttributeValue(aData, nsGkAtoms::href, aHref)) {
return false;
}
nsParserUtils::GetQuotedAttributeValue(aData, nsGkAtoms::title, aTitle);
nsContentUtils::GetPseudoAttributeValue(aData, nsGkAtoms::title, aTitle);
nsParserUtils::GetQuotedAttributeValue(aData, nsGkAtoms::media, aMedia);
nsContentUtils::GetPseudoAttributeValue(aData, nsGkAtoms::media, aMedia);
nsAutoString alternate;
nsParserUtils::GetQuotedAttributeValue(aData, nsGkAtoms::alternate, alternate);
nsContentUtils::GetPseudoAttributeValue(aData,
nsGkAtoms::alternate,
alternate);
aIsAlternate = alternate.EqualsLiteral("yes");

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

@ -1368,7 +1368,8 @@ nsXULElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, bool aNotify)
if (hasMutationListeners) {
nsAutoString ns;
nsContentUtils::NameSpaceManager()->GetNameSpaceURI(aNameSpaceID, ns);
GetAttributeNodeNS(ns, nsDependentAtomString(aName), getter_AddRefs(attrNode));
GetAttributeNodeNSInternal(ns, nsDependentAtomString(aName),
getter_AddRefs(attrNode));
}
nsDOMSlots *slots = GetExistingDOMSlots();

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

@ -74,7 +74,6 @@
#include "nsLayoutCID.h"
#include "nsNetUtil.h"
#include "nsRDFCID.h"
#include "nsParserUtils.h"
#include "nsXPIDLString.h"
#include "nsReadableUtils.h"
#include "nsXULElement.h"
@ -1079,7 +1078,7 @@ XULContentSinkImpl::OpenScript(const PRUnichar** aAttributes,
// various version strings anyway. So we make no attempt to support
// languages other than JS for language=
nsAutoString lang(aAttributes[1]);
if (nsParserUtils::IsJavaScriptLanguage(lang, &version)) {
if (nsContentUtils::IsJavaScriptLanguage(lang, &version)) {
langID = nsIProgrammingLanguage::JAVASCRIPT;
// Even when JS version < 1.6 is specified, E4X is

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

@ -84,7 +84,6 @@
#include "nsXULContentUtils.h"
#include "nsIXULOverlayProvider.h"
#include "nsNetUtil.h"
#include "nsParserUtils.h"
#include "nsParserCIID.h"
#include "nsPIBoxObject.h"
#include "nsRDFCID.h"
@ -2545,9 +2544,9 @@ nsXULDocument::InsertXULOverlayPI(const nsXULPrototypePI* aProtoPI,
}
nsAutoString href;
nsParserUtils::GetQuotedAttributeValue(aProtoPI->mData,
nsGkAtoms::href,
href);
nsContentUtils::GetPseudoAttributeValue(aProtoPI->mData,
nsGkAtoms::href,
href);
// If there was no href, we can't do anything with this PI
if (href.IsEmpty()) {

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

@ -7667,19 +7667,8 @@ void nsGlobalWindow::MaybeUpdateTouchState()
if(this == focusedWindow) {
UpdateTouchState();
}
}
void nsGlobalWindow::UpdateTouchState()
{
FORWARD_TO_INNER_VOID(UpdateTouchState, ());
nsCOMPtr<nsIWidget> mainWidget = GetMainWidget();
if (!mainWidget)
return;
if (mMayHaveTouchEventListener) {
mainWidget->RegisterTouchWindow();
nsCOMPtr<nsIObserverService> observerService =
do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
@ -7688,6 +7677,20 @@ void nsGlobalWindow::UpdateTouchState()
DOM_TOUCH_LISTENER_ADDED,
nsnull);
}
}
}
void nsGlobalWindow::UpdateTouchState()
{
FORWARD_TO_INNER_VOID(UpdateTouchState, ());
nsCOMPtr<nsIWidget> mainWidget = GetMainWidget();
if (!mainWidget) {
return;
}
if (mMayHaveTouchEventListener) {
mainWidget->RegisterTouchWindow();
} else {
mainWidget->UnregisterTouchWindow();
}

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

@ -86,7 +86,7 @@ public:
/**
* Simple object that holds a single point in space.
*/
class nsGeoPositionCoords : public nsIDOMGeoPositionCoords
class nsGeoPositionCoords MOZ_FINAL : public nsIDOMGeoPositionCoords
{
public:
NS_DECL_ISUPPORTS
@ -96,8 +96,8 @@ public:
double aAlt, double aHError,
double aVError, double aHeading,
double aSpeed);
private:
~nsGeoPositionCoords();
private:
const double mLat, mLong, mAlt, mHError, mVError, mHeading, mSpeed;
};

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

@ -42,7 +42,7 @@
#include "nsIDOMGeoPosition.h"
typedef nsIDOMGeoPositionAddress *GeoPositionAddress;
typedef nsIDOMGeoPositionCoords *GeoPositionCoords;
typedef nsGeoPositionCoords *GeoPositionCoords;
typedef nsIDOMGeoPosition *GeoPosition;
namespace IPC {
@ -233,7 +233,7 @@ struct ParamTraits<GeoPosition>
nsCOMPtr<nsIDOMGeoPositionCoords> coords;
aParam->GetCoords(getter_AddRefs(coords));
GeoPositionCoords simpleCoords = coords.get();
GeoPositionCoords simpleCoords = static_cast<GeoPositionCoords>(coords.get());
WriteParam(aMsg, simpleCoords);
nsCOMPtr<nsIDOMGeoPositionAddress> address;

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

@ -85,6 +85,7 @@
#include "nsISHEntry.h"
#include "nsIWebPageDescriptor.h"
#include "nsIFormControl.h"
#include "nsContentUtils.h"
#include "nsIDOMNodeFilter.h"
#include "nsIDOMProcessingInstruction.h"
@ -2604,72 +2605,6 @@ nsWebBrowserPersist::EnumCleanupUploadList(nsHashKey *aKey, void *aData, void* c
return true;
}
bool
nsWebBrowserPersist::GetQuotedAttributeValue(
const nsAString &aSource, const nsAString &aAttribute, nsAString &aValue)
{
// NOTE: This code was lifted verbatim from nsParserUtils.cpp
aValue.Truncate();
nsAString::const_iterator start, end;
aSource.BeginReading(start);
aSource.EndReading(end);
nsAString::const_iterator iter(end);
while (start != end) {
if (FindInReadable(aAttribute, start, iter))
{
// walk past any whitespace
while (iter != end && nsCRT::IsAsciiSpace(*iter))
{
++iter;
}
if (iter == end)
break;
// valid name="value" pair?
if (*iter != '=')
{
start = iter;
iter = end;
continue;
}
// move past the =
++iter;
while (iter != end && nsCRT::IsAsciiSpace(*iter))
{
++iter;
}
if (iter == end)
break;
PRUnichar q = *iter;
if (q != '"' && q != '\'')
{
start = iter;
iter = end;
continue;
}
// point to the first char of the value
++iter;
start = iter;
if (FindCharInReadable(q, iter, end))
{
aValue = Substring(start, iter);
return true;
}
// we've run out of string. Just return...
break;
}
}
return false;
}
nsresult nsWebBrowserPersist::FixupXMLStyleSheetLink(nsIDOMProcessingInstruction *aPI, const nsAString &aHref)
{
NS_ENSURE_ARG_POINTER(aPI);
@ -2680,7 +2615,9 @@ nsresult nsWebBrowserPersist::FixupXMLStyleSheetLink(nsIDOMProcessingInstruction
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
nsAutoString href;
GetQuotedAttributeValue(data, NS_LITERAL_STRING("href"), href);
nsContentUtils::GetPseudoAttributeValue(data,
nsGkAtoms::href,
href);
// Construct and set a new data value for the xml-stylesheet
if (!aHref.IsEmpty() && !href.IsEmpty())
@ -2691,11 +2628,21 @@ nsresult nsWebBrowserPersist::FixupXMLStyleSheetLink(nsIDOMProcessingInstruction
nsAutoString type;
nsAutoString media;
GetQuotedAttributeValue(data, NS_LITERAL_STRING("alternate"), alternate);
GetQuotedAttributeValue(data, NS_LITERAL_STRING("charset"), charset);
GetQuotedAttributeValue(data, NS_LITERAL_STRING("title"), title);
GetQuotedAttributeValue(data, NS_LITERAL_STRING("type"), type);
GetQuotedAttributeValue(data, NS_LITERAL_STRING("media"), media);
nsContentUtils::GetPseudoAttributeValue(data,
nsGkAtoms::alternate,
alternate);
nsContentUtils::GetPseudoAttributeValue(data,
nsGkAtoms::charset,
charset);
nsContentUtils::GetPseudoAttributeValue(data,
nsGkAtoms::title,
title);
nsContentUtils::GetPseudoAttributeValue(data,
nsGkAtoms::type,
type);
nsContentUtils::GetPseudoAttributeValue(data,
nsGkAtoms::media,
media);
NS_NAMED_LITERAL_STRING(kCloseAttr, "\" ");
nsAutoString newData;
@ -2736,7 +2683,7 @@ nsresult nsWebBrowserPersist::GetXMLStyleSheetLink(nsIDOMProcessingInstruction *
rv = aPI->GetData(data);
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
GetQuotedAttributeValue(data, NS_LITERAL_STRING("href"), aHref);
nsContentUtils::GetPseudoAttributeValue(data, nsGkAtoms::href, aHref);
return NS_OK;
}

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

@ -152,8 +152,6 @@ private:
{
return StoreURIAttributeNS(aNode, "", aAttribute, aNeedsPersisting, aData);
}
bool GetQuotedAttributeValue(
const nsAString &aSource, const nsAString &aAttribute, nsAString &aValue);
bool DocumentEncoderExists(const PRUnichar *aContentType);
nsresult GetNodeToFixup(nsIDOMNode *aNodeIn, nsIDOMNode **aNodeOut);

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

@ -60,8 +60,7 @@ namespace mozilla {
namespace gl {
#ifdef DEBUG
// see comment near declaration in GLContext.h. Should be thread-local.
GLContext* GLContext::sCurrentGLContext = nsnull;
PRUintn GLContext::sCurrentGLContextTLS = -1;
#endif
PRUint32 GLContext::sDebugMode = 0;

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

@ -602,9 +602,15 @@ public:
virtual bool MakeCurrentImpl(bool aForce = false) = 0;
#ifdef DEBUG
static void StaticInit() {
PR_NewThreadPrivateIndex(&sCurrentGLContextTLS, NULL);
}
#endif
bool MakeCurrent(bool aForce = false) {
#ifdef DEBUG
sCurrentGLContext = this;
PR_SetThreadPrivate(sCurrentGLContextTLS, this);
#endif
return MakeCurrentImpl(aForce);
}
@ -1505,10 +1511,12 @@ protected:
GLContextSymbols mSymbols;
#ifdef DEBUG
// this should be thread-local, but that is slightly annoying to implement because on Mac
// we don't have any __thread-like keyword. So for now, MOZ_GL_DEBUG assumes (and asserts)
// that only the main thread is doing OpenGL calls.
static THEBES_API GLContext* sCurrentGLContext;
// GLDebugMode will check that we don't send call
// to a GLContext that isn't current on the current
// thread.
// Store the current context when binding to thread local
// storage to support DebugMode on an arbitrary thread.
static PRUintn sCurrentGLContextTLS;
#endif
void UpdateActualFormat();
@ -1632,21 +1640,16 @@ public:
void BeforeGLCall(const char* glFunction) {
if (DebugMode()) {
// since the static member variable sCurrentGLContext is not thread-local as it should,
// we have to assert that we're in the main thread. Note that sCurrentGLContext is only used
// for the OpenGL debug mode.
if (!NS_IsMainThread()) {
NS_ERROR("OpenGL call from non-main thread. While this is fine in itself, "
"the OpenGL debug mode, which is currently enabled, doesn't support this. "
"It needs to be patched by making GLContext::sCurrentGLContext be thread-local.\n");
NS_ABORT();
}
GLContext *currentGLContext = NULL;
currentGLContext = (GLContext*)PR_GetThreadPrivate(sCurrentGLContextTLS);
if (DebugMode() & DebugTrace)
printf_stderr("[gl:%p] > %s\n", this, glFunction);
if (this != sCurrentGLContext) {
if (this != currentGLContext) {
printf_stderr("Fatal: %s called on non-current context %p. "
"The current context for this thread is %p.\n",
glFunction, this, sCurrentGLContext);
glFunction, this, currentGLContext);
NS_ABORT();
}
}

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

@ -267,15 +267,6 @@ is_power_of_two(int v)
static void BeforeGLCall(const char* glFunction)
{
if (GLContext::DebugMode()) {
// since the static member variable sCurrentGLContext is not thread-local as it should,
// we have to assert that we're in the main thread. Note that sCurrentGLContext is only used
// for the OpenGL debug mode.
if (!NS_IsMainThread()) {
NS_ERROR("OpenGL call from non-main thread. While this is fine in itself, "
"the OpenGL debug mode, which is currently enabled, doesn't support this. "
"It needs to be patched by making GLContext::sCurrentGLContext be thread-local.\n");
NS_ABORT();
}
if (GLContext::DebugMode() & GLContext::DebugTrace)
printf_stderr("[egl] > %s\n", glFunction);
}

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

@ -125,9 +125,9 @@ LayerManagerD3D10::~LayerManagerD3D10()
}
bool
LayerManagerD3D10::Initialize()
LayerManagerD3D10::Initialize(bool force)
{
ScopedGfxFeatureReporter reporter("D3D10 Layers");
ScopedGfxFeatureReporter reporter("D3D10 Layers", force);
HRESULT hr;

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

@ -100,7 +100,7 @@ public:
*
* \return True is initialization was succesful, false when it was not.
*/
bool Initialize();
bool Initialize(bool force = false);
/*
* LayerManager implementation.

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

@ -70,9 +70,9 @@ LayerManagerD3D9::~LayerManagerD3D9()
}
bool
LayerManagerD3D9::Initialize()
LayerManagerD3D9::Initialize(bool force)
{
ScopedGfxFeatureReporter reporter("D3D9 Layers");
ScopedGfxFeatureReporter reporter("D3D9 Layers", force);
/* XXX: this preference and blacklist code should move out of the layer manager */
bool forceAccelerate =

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

@ -103,7 +103,7 @@ public:
*
* \return True is initialization was succesful, false when it was not.
*/
bool Initialize();
bool Initialize(bool force = false);
/*
* Sets the clipping region for this layer manager. This is important on

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

@ -171,9 +171,9 @@ LayerManagerOGL::CreateContext()
}
bool
LayerManagerOGL::Initialize(nsRefPtr<GLContext> aContext)
LayerManagerOGL::Initialize(nsRefPtr<GLContext> aContext, bool force)
{
ScopedGfxFeatureReporter reporter("GL Layers");
ScopedGfxFeatureReporter reporter("GL Layers", force);
// Do not allow double intiailization
NS_ABORT_IF_FALSE(mGLContext == nsnull, "Don't reiniailize layer managers");

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

@ -106,11 +106,11 @@ public:
*
* \return True is initialization was succesful, false when it was not.
*/
bool Initialize() {
return Initialize(CreateContext());
bool Initialize(bool force = false) {
return Initialize(CreateContext(), force);
}
bool Initialize(nsRefPtr<GLContext> aContext);
bool Initialize(nsRefPtr<GLContext> aContext, bool force = false);
/**
* Sets the clipping region for this layer manager. This is important on

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

@ -103,10 +103,9 @@ ScopedGfxFeatureReporter::WriteAppNote(char statusChar)
}
nsCAutoString featureString;
featureString.AppendPrintf("%s%c%c",
featureString.AppendPrintf("%s%c ",
mFeature,
statusChar,
statusChar == '?' ? ' ' : '\n');
statusChar);
if (!gFeaturesAlreadyReported->Contains(featureString)) {
gFeaturesAlreadyReported->AppendElement(featureString);

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

@ -53,9 +53,10 @@ namespace mozilla {
class NS_GFX ScopedGfxFeatureReporter
{
public:
ScopedGfxFeatureReporter(const char *aFeature) : mFeature(aFeature), mStatusChar('-')
ScopedGfxFeatureReporter(const char *aFeature, bool force = false)
: mFeature(aFeature), mStatusChar('-')
{
WriteAppNote('?');
WriteAppNote(force ? '!' : '?');
}
~ScopedGfxFeatureReporter() {
WriteAppNote(mStatusChar);

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

@ -298,6 +298,10 @@ gfxPlatform::Init()
#error "No gfxPlatform implementation available"
#endif
#ifdef DEBUG
mozilla::gl::GLContext::StaticInit();
#endif
nsresult rv;
#if defined(XP_MACOSX) || defined(XP_WIN) || defined(ANDROID) // temporary, until this is implemented on others

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

@ -501,7 +501,7 @@ gfxWindowsPlatform::VerifyD2DDevice(bool aAttemptForce)
mD2DDevice = nsnull;
}
mozilla::ScopedGfxFeatureReporter reporter("D2D");
mozilla::ScopedGfxFeatureReporter reporter("D2D", aAttemptForce);
HMODULE d3d10module = LoadLibraryA("d3d10_1.dll");
D3D10CreateDevice1Func createD3DDevice = (D3D10CreateDevice1Func)

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

@ -128,6 +128,7 @@ struct RuntimeStats
, runtimeTemporary(0)
, runtimeRegexpCode(0)
, runtimeStackCommitted(0)
, runtimeGCMarker(0)
, gcHeapChunkTotal(0)
, gcHeapChunkCleanUnused(0)
, gcHeapChunkDirtyUnused(0)
@ -159,6 +160,7 @@ struct RuntimeStats
size_t runtimeTemporary;
size_t runtimeRegexpCode;
size_t runtimeStackCommitted;
size_t runtimeGCMarker;
size_t gcHeapChunkTotal;
size_t gcHeapChunkCleanUnused;
size_t gcHeapChunkDirtyUnused;

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

@ -499,6 +499,17 @@ class Vector : private AllocPolicy
* shifting existing elements from |t + 1| onward one position lower.
*/
void erase(T *t);
/*
* Measure the size of the Vector's heap-allocated storage.
*/
size_t sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf) const;
/*
* Like sizeOfExcludingThis, but also measures the size of the Vector
* object (which must be heap-allocated) itself.
*/
size_t sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf) const;
};
/* This does the re-entrancy check plus several other sanity checks. */
@ -996,6 +1007,20 @@ Vector<T,N,AP>::replaceRawBuffer(T *p, size_t length)
#endif
}
template <class T, size_t N, class AP>
inline size_t
Vector<T,N,AP>::sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf) const
{
return usingInlineStorage() ? 0 : mallocSizeOf(beginNoCheck());
}
template <class T, size_t N, class AP>
inline size_t
Vector<T,N,AP>::sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf) const
{
return mallocSizeOf(this) + sizeOfExcludingThis(mallocSizeOf);
}
} /* namespace js */
#ifdef _MSC_VER

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

@ -211,10 +211,9 @@ CollectRuntimeStats(JSRuntime *rt, RuntimeStats *rtStats)
&rtStats->runtimeNormal,
&rtStats->runtimeTemporary,
&rtStats->runtimeRegexpCode,
&rtStats->runtimeStackCommitted);
&rtStats->runtimeStackCommitted,
&rtStats->runtimeGCMarker);
// Nb: we use sizeOfExcludingThis() because atomState.atoms is within
// JSRuntime, and so counted when JSRuntime is counted.
rtStats->runtimeAtomsTable =
rt->atomState.atoms.sizeOfExcludingThis(rtStats->mallocSizeOf);
@ -335,7 +334,8 @@ GetExplicitNonHeapForRuntime(JSRuntime *rt, int64_t *amount,
NULL,
NULL,
&regexpCode,
&stackCommitted);
&stackCommitted,
NULL);
*amount += regexpCode;
*amount += stackCommitted;

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

@ -243,6 +243,8 @@ UpdateDecomposeLength(BytecodeEmitter *bce, uintN start)
ptrdiff_t
frontend::Emit1(JSContext *cx, BytecodeEmitter *bce, JSOp op)
{
JS_ASSERT_IF(op == JSOP_ARGUMENTS, !bce->mayOverwriteArguments());
ptrdiff_t offset = EmitCheck(cx, bce, 1);
if (offset >= 0) {
@ -983,6 +985,14 @@ EmitSlotObjectOp(JSContext *cx, JSOp op, uintN slot, uint32_t index, BytecodeEmi
return true;
}
static bool
EmitArguments(JSContext *cx, BytecodeEmitter *bce)
{
if (!bce->mayOverwriteArguments())
return Emit1(cx, bce, JSOP_ARGUMENTS) >= 0;
return EmitAtomOp(cx, cx->runtime->atomState.argumentsAtom, JSOP_NAME, bce);
}
bool
BytecodeEmitter::shouldNoteClosedName(ParseNode *pn)
{
@ -1833,7 +1843,10 @@ EmitNameOp(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, JSBool callContex
}
}
if (op == JSOP_ARGUMENTS || op == JSOP_CALLEE) {
if (op == JSOP_ARGUMENTS) {
if (!EmitArguments(cx, bce))
return JS_FALSE;
} else if (op == JSOP_CALLEE) {
if (Emit1(cx, bce, op) < 0)
return JS_FALSE;
} else {
@ -3589,7 +3602,7 @@ EmitVariables(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, VarEmitOption
return JS_FALSE;
}
if (op == JSOP_ARGUMENTS) {
if (Emit1(cx, bce, op) < 0)
if (!EmitArguments(cx, bce))
return JS_FALSE;
} else if (!pn2->pn_cookie.isFree()) {
EMIT_UINT16_IMM_OP(op, atomIndex);
@ -3700,7 +3713,7 @@ EmitAssignment(JSContext *cx, BytecodeEmitter *bce, ParseNode *lhs, JSOp op, Par
if (lhs->isOp(JSOP_CALLEE)) {
if (Emit1(cx, bce, JSOP_CALLEE) < 0)
return false;
} else if (lhs->isOp(JSOP_NAME)) {
} else if (lhs->isOp(JSOP_NAME) || lhs->isOp(JSOP_GETGNAME)) {
if (!EmitIndex32(cx, lhs->getOp(), atomIndex, bce))
return false;
} else {

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

@ -168,21 +168,20 @@ struct StmtInfo {
#define TCF_IN_FOR_INIT 0x10 /* parsing init expr of for; exclude 'in' */
#define TCF_FUN_SETS_OUTER_NAME 0x20 /* function set outer name (lexical or free) */
#define TCF_FUN_PARAM_ARGUMENTS 0x40 /* function has parameter named arguments */
#define TCF_FUN_USES_ARGUMENTS 0x80 /* function uses arguments except as a
#define TCF_FUN_LOCAL_ARGUMENTS 0x80 /* function has local named arguments */
#define TCF_FUN_USES_ARGUMENTS 0x100 /* function uses arguments except as a
parameter name */
#define TCF_FUN_HEAVYWEIGHT 0x100 /* function needs Call object per call */
#define TCF_FUN_IS_GENERATOR 0x200 /* parsed yield statement in function */
#define TCF_FUN_USES_OWN_NAME 0x400 /* named function expression that uses its
#define TCF_FUN_HEAVYWEIGHT 0x200 /* function needs Call object per call */
#define TCF_FUN_IS_GENERATOR 0x400 /* parsed yield statement in function */
#define TCF_FUN_USES_OWN_NAME 0x800 /* named function expression that uses its
own name */
#define TCF_HAS_FUNCTION_STMT 0x800 /* block contains a function statement */
#define TCF_GENEXP_LAMBDA 0x1000 /* flag lambda from generator expression */
#define TCF_COMPILE_N_GO 0x2000 /* compile-and-go mode of script, can
#define TCF_HAS_FUNCTION_STMT 0x1000 /* block contains a function statement */
#define TCF_GENEXP_LAMBDA 0x2000 /* flag lambda from generator expression */
#define TCF_COMPILE_N_GO 0x4000 /* compile-and-go mode of script, can
optimize name references based on scope
chain */
#define TCF_NO_SCRIPT_RVAL 0x4000 /* API caller does not want result value
#define TCF_NO_SCRIPT_RVAL 0x8000 /* API caller does not want result value
from global script */
/* bit 0x8000 is unused */
/*
* Set when parsing a declaration-like destructuring pattern. This
* flag causes PrimaryExpr to create PN_NAME parse nodes for variable
@ -273,6 +272,7 @@ struct StmtInfo {
#define TCF_FUN_FLAGS (TCF_FUN_SETS_OUTER_NAME | \
TCF_FUN_USES_ARGUMENTS | \
TCF_FUN_PARAM_ARGUMENTS | \
TCF_FUN_LOCAL_ARGUMENTS | \
TCF_FUN_HEAVYWEIGHT | \
TCF_FUN_IS_GENERATOR | \
TCF_FUN_USES_OWN_NAME | \
@ -434,6 +434,15 @@ struct TreeContext { /* tree context for semantic checks */
return flags & TCF_FUN_MUTATES_PARAMETER;
}
bool mayOverwriteArguments() const {
JS_ASSERT(inFunction());
JS_ASSERT_IF(inStrictMode(),
!(flags & (TCF_FUN_PARAM_ARGUMENTS | TCF_FUN_LOCAL_ARGUMENTS)));
return !inStrictMode() &&
(callsEval() ||
flags & (TCF_FUN_PARAM_ARGUMENTS | TCF_FUN_LOCAL_ARGUMENTS));
}
void noteArgumentsNameUse(ParseNode *node) {
JS_ASSERT(inFunction());
JS_ASSERT(node->isKind(PNK_NAME));

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

@ -2431,7 +2431,7 @@ NoteLValue(JSContext *cx, ParseNode *pn, TreeContext *tc, uintN dflag = PND_ASSI
*/
JSAtom *lname = pn->pn_atom;
if (lname == cx->runtime->atomState.argumentsAtom) {
tc->flags |= TCF_FUN_HEAVYWEIGHT;
tc->flags |= (TCF_FUN_HEAVYWEIGHT | TCF_FUN_LOCAL_ARGUMENTS);
tc->countArgumentsUse(pn);
} else if (tc->inFunction() && lname == tc->fun()->atom) {
tc->flags |= TCF_FUN_HEAVYWEIGHT;
@ -2453,7 +2453,7 @@ BindDestructuringVar(JSContext *cx, BindData *data, ParseNode *pn, TreeContext *
JS_ASSERT(pn->isKind(PNK_NAME));
atom = pn->pn_atom;
if (atom == cx->runtime->atomState.argumentsAtom)
tc->flags |= TCF_FUN_HEAVYWEIGHT;
tc->flags |= (TCF_FUN_HEAVYWEIGHT | TCF_FUN_LOCAL_ARGUMENTS);
data->pn = pn;
if (!data->binder(cx, data, atom, tc))
@ -4424,7 +4424,7 @@ Parser::variables(ParseNodeKind kind, StaticBlockObject *blockObj, VarContext va
if (tc->inFunction() && name == context->runtime->atomState.argumentsAtom) {
tc->noteArgumentsNameUse(pn2);
if (!blockObj)
tc->flags |= TCF_FUN_HEAVYWEIGHT;
tc->flags |= (TCF_FUN_HEAVYWEIGHT | TCF_FUN_LOCAL_ARGUMENTS);
}
}
} while (tokenStream.matchToken(TOK_COMMA));

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

@ -178,8 +178,8 @@ TokenStream::init(const jschar *base, size_t length, const char *fn, uintN ln, J
prevLinebase = NULL;
sourceMap = NULL;
JSSourceHandler listener = cx->debugHooks->sourceHandler;
void *listenerData = cx->debugHooks->sourceHandlerData;
JSSourceHandler listener = cx->runtime->debugHooks.sourceHandler;
void *listenerData = cx->runtime->debugHooks.sourceHandlerData;
if (listener)
listener(fn, ln, base, length, &listenerTSData, listenerData);
@ -521,8 +521,8 @@ TokenStream::reportCompileErrorNumberVA(ParseNode *pn, uintN flags, uintN errorN
* sending the error on to the regular error reporter.
*/
bool reportError = true;
if (JSDebugErrorHook hook = cx->debugHooks->debugErrorHook)
reportError = hook(cx, message, &report, cx->debugHooks->debugErrorHookData);
if (JSDebugErrorHook hook = cx->runtime->debugHooks.debugErrorHook)
reportError = hook(cx, message, &report, cx->runtime->debugHooks.debugErrorHookData);
/* Report the error */
if (reportError && cx->errorReporter)

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

@ -46,40 +46,51 @@
namespace js {
static JS_ALWAYS_INLINE void
ClearValueRange(JSCompartment *comp, HeapValue *vec, uintN len, bool useHoles)
inline void
EncapsulatedValue::writeBarrierPre(const Value &value)
{
if (useHoles) {
for (uintN i = 0; i < len; i++)
vec[i].set(comp, MagicValue(JS_ARRAY_HOLE));
} else {
for (uintN i = 0; i < len; i++)
vec[i].set(comp, UndefinedValue());
#ifdef JSGC_INCREMENTAL
if (value.isMarkable()) {
js::gc::Cell *cell = (js::gc::Cell *)value.toGCThing();
writeBarrierPre(cell->compartment(), value);
}
#endif
}
static JS_ALWAYS_INLINE void
InitValueRange(HeapValue *vec, uintN len, bool useHoles)
inline void
EncapsulatedValue::writeBarrierPre(JSCompartment *comp, const Value &value)
{
if (useHoles) {
for (uintN i = 0; i < len; i++)
vec[i].init(MagicValue(JS_ARRAY_HOLE));
} else {
for (uintN i = 0; i < len; i++)
vec[i].init(UndefinedValue());
#ifdef JSGC_INCREMENTAL
if (comp->needsBarrier()) {
Value tmp(value);
js::gc::MarkValueUnbarriered(comp->barrierTracer(), &tmp, "write barrier");
JS_ASSERT(tmp == value);
}
#endif
}
static JS_ALWAYS_INLINE void
DestroyValueRange(HeapValue *vec, uintN len)
inline void
EncapsulatedValue::pre()
{
for (uintN i = 0; i < len; i++)
vec[i].~HeapValue();
writeBarrierPre(value);
}
inline void
EncapsulatedValue::pre(JSCompartment *comp)
{
writeBarrierPre(comp, value);
}
inline
HeapValue::HeapValue()
: EncapsulatedValue(UndefinedValue())
{
post();
}
inline
HeapValue::HeapValue(const Value &v)
: value(v)
: EncapsulatedValue(v)
{
JS_ASSERT(!IsPoisonedValue(v));
post();
@ -87,7 +98,7 @@ HeapValue::HeapValue(const Value &v)
inline
HeapValue::HeapValue(const HeapValue &v)
: value(v.value)
: EncapsulatedValue(v.value)
{
JS_ASSERT(!IsPoisonedValue(v.value));
post();
@ -114,61 +125,6 @@ HeapValue::init(JSCompartment *comp, const Value &v)
post(comp);
}
inline void
HeapValue::writeBarrierPre(const Value &value)
{
#ifdef JSGC_INCREMENTAL
if (value.isMarkable()) {
js::gc::Cell *cell = (js::gc::Cell *)value.toGCThing();
writeBarrierPre(cell->compartment(), value);
}
#endif
}
inline void
HeapValue::writeBarrierPost(const Value &value, void *addr)
{
}
inline void
HeapValue::writeBarrierPre(JSCompartment *comp, const Value &value)
{
#ifdef JSGC_INCREMENTAL
if (comp->needsBarrier()) {
Value tmp(value);
js::gc::MarkValueUnbarriered(comp->barrierTracer(), &tmp, "write barrier");
JS_ASSERT(tmp == value);
}
#endif
}
inline void
HeapValue::writeBarrierPost(JSCompartment *comp, const Value &value, void *addr)
{
}
inline void
HeapValue::pre()
{
writeBarrierPre(value);
}
inline void
HeapValue::post()
{
}
inline void
HeapValue::pre(JSCompartment *comp)
{
writeBarrierPre(comp, value);
}
inline void
HeapValue::post(JSCompartment *comp)
{
}
inline HeapValue &
HeapValue::operator=(const Value &v)
{
@ -206,6 +162,109 @@ HeapValue::set(JSCompartment *comp, const Value &v)
post(comp);
}
inline void
HeapValue::writeBarrierPost(const Value &value, void *addr)
{
}
inline void
HeapValue::writeBarrierPost(JSCompartment *comp, const Value &value, void *addr)
{
}
inline void
HeapValue::post()
{
}
inline void
HeapValue::post(JSCompartment *comp)
{
}
inline
HeapSlot::HeapSlot(JSObject *obj, uint32_t slot, const Value &v)
: EncapsulatedValue(v)
{
JS_ASSERT(!IsPoisonedValue(v));
post(obj, slot);
}
inline
HeapSlot::HeapSlot(JSObject *obj, uint32_t slot, const HeapSlot &s)
: EncapsulatedValue(s.value)
{
JS_ASSERT(!IsPoisonedValue(s.value));
post(obj, slot);
}
inline
HeapSlot::~HeapSlot()
{
pre();
}
inline void
HeapSlot::init(JSObject *obj, uint32_t slot, const Value &v)
{
value = v;
post(obj, slot);
}
inline void
HeapSlot::init(JSCompartment *comp, JSObject *obj, uint32_t slot, const Value &v)
{
value = v;
post(comp, obj, slot);
}
inline void
HeapSlot::set(JSObject *obj, uint32_t slot, const Value &v)
{
JS_ASSERT_IF(!obj->isArray(), &obj->getSlotRef(slot) == this);
JS_ASSERT_IF(obj->isDenseArray(), &obj->getDenseArrayElement(slot) == (const Value *)this);
pre();
JS_ASSERT(!IsPoisonedValue(v));
value = v;
post(obj, slot);
}
inline void
HeapSlot::set(JSCompartment *comp, JSObject *obj, uint32_t slot, const Value &v)
{
JS_ASSERT_IF(!obj->isArray(), &const_cast<JSObject *>(obj)->getSlotRef(slot) == this);
JS_ASSERT_IF(obj->isDenseArray(), &obj->getDenseArrayElement(slot) == (const Value *)this);
JS_ASSERT(obj->compartment() == comp);
pre(comp);
JS_ASSERT(!IsPoisonedValue(v));
value = v;
post(comp, obj, slot);
}
inline void
HeapSlot::writeBarrierPost(JSObject *obj, uint32_t slot)
{
}
inline void
HeapSlot::writeBarrierPost(JSCompartment *comp, JSObject *obj, uint32_t slotno)
{
}
inline void
HeapSlot::post(JSObject *owner, uint32_t slot)
{
HeapSlot::writeBarrierPost(owner, slot);
}
inline void
HeapSlot::post(JSCompartment *comp, JSObject *owner, uint32_t slot)
{
HeapSlot::writeBarrierPost(comp, owner, slot);
}
inline
HeapId::HeapId(jsid id)
: value(id)

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

@ -299,31 +299,24 @@ struct HeapPtrHasher
template <class T>
struct DefaultHasher< HeapPtr<T> >: HeapPtrHasher<T> { };
class HeapValue
class EncapsulatedValue
{
protected:
Value value;
public:
explicit HeapValue() : value(UndefinedValue()) {}
explicit inline HeapValue(const Value &v);
explicit inline HeapValue(const HeapValue &v);
inline ~HeapValue();
inline void init(const Value &v);
inline void init(JSCompartment *comp, const Value &v);
inline HeapValue &operator=(const Value &v);
inline HeapValue &operator=(const HeapValue &v);
/*
* This is a faster version of operator=. Normally, operator= has to
* determine the compartment of the value before it can decide whether to do
* the barrier. If you already know the compartment, it's faster to pass it
* in.
* Ensure that EncapsulatedValue is not constructable, except by our
* implementations.
*/
inline void set(JSCompartment *comp, const Value &v);
EncapsulatedValue() MOZ_DELETE;
EncapsulatedValue(const EncapsulatedValue &v) MOZ_DELETE;
EncapsulatedValue &operator=(const Value &v) MOZ_DELETE;
EncapsulatedValue &operator=(const EncapsulatedValue &v) MOZ_DELETE;
EncapsulatedValue(const Value &v) : value(v) {}
~EncapsulatedValue() {}
public:
const Value &get() const { return value; }
Value *unsafeGet() { return &value; }
operator const Value &() const { return value; }
@ -360,38 +353,93 @@ class HeapValue
#endif
static inline void writeBarrierPre(const Value &v);
static inline void writeBarrierPost(const Value &v, void *addr);
static inline void writeBarrierPre(JSCompartment *comp, const Value &v);
protected:
inline void pre();
inline void pre(JSCompartment *comp);
};
class HeapValue : public EncapsulatedValue
{
public:
explicit inline HeapValue();
explicit inline HeapValue(const Value &v);
explicit inline HeapValue(const HeapValue &v);
inline ~HeapValue();
inline void init(const Value &v);
inline void init(JSCompartment *comp, const Value &v);
inline HeapValue &operator=(const Value &v);
inline HeapValue &operator=(const HeapValue &v);
/*
* This is a faster version of operator=. Normally, operator= has to
* determine the compartment of the value before it can decide whether to do
* the barrier. If you already know the compartment, it's faster to pass it
* in.
*/
inline void set(JSCompartment *comp, const Value &v);
static inline void writeBarrierPost(const Value &v, void *addr);
static inline void writeBarrierPost(JSCompartment *comp, const Value &v, void *addr);
private:
inline void pre();
inline void post();
inline void pre(JSCompartment *comp);
inline void post(JSCompartment *comp);
};
static inline const Value *
Valueify(const HeapValue *array)
class HeapSlot : public EncapsulatedValue
{
JS_ASSERT(sizeof(HeapValue) == sizeof(Value));
/*
* Operator= is not valid for HeapSlot because is must take the object and
* slot offset to provide to the post/generational barrier.
*/
inline HeapSlot &operator=(const Value &v) MOZ_DELETE;
inline HeapSlot &operator=(const HeapValue &v) MOZ_DELETE;
inline HeapSlot &operator=(const HeapSlot &v) MOZ_DELETE;
public:
explicit inline HeapSlot() MOZ_DELETE;
explicit inline HeapSlot(JSObject *obj, uint32_t slot, const Value &v);
explicit inline HeapSlot(JSObject *obj, uint32_t slot, const HeapSlot &v);
inline ~HeapSlot();
inline void init(JSObject *owner, uint32_t slot, const Value &v);
inline void init(JSCompartment *comp, JSObject *owner, uint32_t slot, const Value &v);
inline void set(JSObject *owner, uint32_t slot, const Value &v);
inline void set(JSCompartment *comp, JSObject *owner, uint32_t slot, const Value &v);
static inline void writeBarrierPost(JSObject *obj, uint32_t slot);
static inline void writeBarrierPost(JSCompartment *comp, JSObject *obj, uint32_t slotno);
private:
inline void post(JSObject *owner, uint32_t slot);
inline void post(JSCompartment *comp, JSObject *owner, uint32_t slot);
};
static inline const Value *
Valueify(const EncapsulatedValue *array)
{
JS_STATIC_ASSERT(sizeof(HeapValue) == sizeof(Value));
JS_STATIC_ASSERT(sizeof(HeapSlot) == sizeof(Value));
return (const Value *)array;
}
class HeapValueArray
class HeapSlotArray
{
HeapValue *array;
HeapSlot *array;
public:
HeapValueArray(HeapValue *array) : array(array) {}
HeapSlotArray(HeapSlot *array) : array(array) {}
operator const Value *() const { return Valueify(array); }
operator HeapValue *() const { return array; }
operator HeapSlot *() const { return array; }
HeapValueArray operator +(int offset) const { return HeapValueArray(array + offset); }
HeapValueArray operator +(uint32_t offset) const { return HeapValueArray(array + offset); }
HeapSlotArray operator +(int offset) const { return HeapSlotArray(array + offset); }
HeapSlotArray operator +(uint32_t offset) const { return HeapSlotArray(array + offset); }
};
class HeapId

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

@ -0,0 +1,24 @@
function f() {
var a = arguments;
eval("assertEq(arguments[0], 42)");
eval("assertEq(arguments, a)");
arguments = undefined;
eval("assertEq(arguments, undefined)");
arguments = a;
eval("assertEq(arguments[0], 42)");
eval("assertEq(arguments, a)");
}
f(42);
function f(z) {
var a = arguments;
eval("assertEq(arguments[0], 42)");
eval("assertEq(arguments, a)");
arguments = undefined;
eval("assertEq(arguments, undefined)");
z = 17;
eval("assertEq(a[0], 17)");
a[0] = 'ponies';
eval("assertEq(z, 'ponies')");
}
f(42);

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

@ -110,6 +110,7 @@ bool called = false;
static JSTrapStatus
ThrowHook(JSContext *cx, JSScript *, jsbytecode *, jsval *rval, void *closure)
{
JS_ASSERT(!closure);
called = true;
JSObject *global = JS_GetGlobalForScopeChain(cx);
@ -126,9 +127,7 @@ BEGIN_TEST(testDebugger_throwHook)
uint32_t newopts = JS_GetOptions(cx) | JSOPTION_METHODJIT | JSOPTION_METHODJIT_ALWAYS;
uint32_t oldopts = JS_SetOptions(cx, newopts);
JSDebugHooks hooks = { 0 };
hooks.throwHook = ThrowHook;
JSDebugHooks *old = JS_SetContextDebugHooks(cx, &hooks);
CHECK(JS_SetThrowHook(rt, ThrowHook, NULL));
EXEC("function foo() { throw 3 };\n"
"for (var i = 0; i < 10; ++i) { \n"
" var x = <tag></tag>;\n"
@ -137,8 +136,7 @@ BEGIN_TEST(testDebugger_throwHook)
" } catch(e) {}\n"
"}\n");
CHECK(called);
JS_SetContextDebugHooks(cx, old);
CHECK(JS_SetThrowHook(rt, NULL, NULL));
JS_SetOptions(cx, oldopts);
return true;
}

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

@ -800,7 +800,7 @@ JSRuntime::JSRuntime()
JS_INIT_CLIST(&contextList);
JS_INIT_CLIST(&debuggerList);
PodZero(&globalDebugHooks);
PodZero(&debugHooks);
PodZero(&atomState);
#if JS_STACK_GROWTH_DIRECTION > 0

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

@ -1194,7 +1194,7 @@ array_trace(JSTracer *trc, JSObject *obj)
JS_ASSERT(obj->isDenseArray());
uint32_t initLength = obj->getDenseArrayInitializedLength();
MarkValueRange(trc, initLength, obj->getDenseArrayElements(), "element");
MarkSlotRange(trc, initLength, obj->getDenseArrayElements(), "element");
}
static JSBool
@ -1377,7 +1377,7 @@ JSObject::makeDenseArraySlow(JSContext *cx)
this->shape_ = shape;
/* Take ownership of the dense elements, reset to an empty dense array. */
HeapValue *elems = elements;
HeapSlot *elems = elements;
elements = emptyObjectElements;
/* Root all values in the array during conversion. */
@ -1389,7 +1389,8 @@ JSObject::makeDenseArraySlow(JSContext *cx)
*/
if (!AddLengthProperty(cx, this)) {
this->shape_ = oldShape;
cx->free_(getElementsHeader());
if (elements != emptyObjectElements)
cx->free_(getElementsHeader());
elements = elems;
return false;
}

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

@ -64,7 +64,12 @@ JSObject::ensureDenseArrayInitializedLength(JSContext *cx, uint32_t index, uint3
markDenseArrayNotPacked(cx);
if (initlen < index + extra) {
js::InitValueRange(elements + initlen, index + extra - initlen, true);
JSCompartment *comp = compartment();
size_t offset = initlen;
for (js::HeapSlot *sp = elements + initlen;
sp != elements + (index + extra);
sp++, offset++)
sp->init(comp, this, offset, js::MagicValue(JS_ARRAY_HOLE));
initlen = index + extra;
}
}

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

@ -95,7 +95,7 @@ using namespace js::gc;
void
JSRuntime::sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf, size_t *normal, size_t *temporary,
size_t *regexpCode, size_t *stackCommitted)
size_t *regexpCode, size_t *stackCommitted, size_t *gcMarkerSize)
{
if (normal)
*normal = mallocSizeOf(dtoaState);
@ -113,6 +113,9 @@ JSRuntime::sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf, size_t *normal, s
if (stackCommitted)
*stackCommitted = stackSpace.sizeOfCommitted();
if (gcMarkerSize)
*gcMarkerSize = gcMarker.sizeOfExcludingThis(mallocSizeOf);
}
JS_FRIEND_API(void)
@ -356,11 +359,9 @@ ReportError(JSContext *cx, const char *message, JSErrorReport *reportp,
if (!JS_IsRunning(cx) ||
!js_ErrorToException(cx, message, reportp, callback, userRef)) {
js_ReportErrorAgain(cx, message, reportp);
} else if (cx->debugHooks->debugErrorHook && cx->errorReporter) {
JSDebugErrorHook hook = cx->debugHooks->debugErrorHook;
/* test local in case debugErrorHook changed on another thread */
if (hook)
hook(cx, message, reportp, cx->debugHooks->debugErrorHookData);
} else if (JSDebugErrorHook hook = cx->runtime->debugHooks.debugErrorHook) {
if (cx->errorReporter)
hook(cx, message, reportp, cx->runtime->debugHooks.debugErrorHookData);
}
}
@ -419,9 +420,9 @@ js_ReportOutOfMemory(JSContext *cx)
*/
cx->clearPendingException();
if (onError) {
JSDebugErrorHook hook = cx->debugHooks->debugErrorHook;
JSDebugErrorHook hook = cx->runtime->debugHooks.debugErrorHook;
if (hook &&
!hook(cx, msg, &report, cx->debugHooks->debugErrorHookData)) {
!hook(cx, msg, &report, cx->runtime->debugHooks.debugErrorHookData)) {
onError = NULL;
}
}
@ -751,12 +752,9 @@ js_ReportErrorAgain(JSContext *cx, const char *message, JSErrorReport *reportp)
* sending the error on to the regular ErrorReporter.
*/
if (onError) {
JSDebugErrorHook hook = cx->debugHooks->debugErrorHook;
if (hook &&
!hook(cx, cx->lastMessage, reportp,
cx->debugHooks->debugErrorHookData)) {
JSDebugErrorHook hook = cx->runtime->debugHooks.debugErrorHook;
if (hook && !hook(cx, cx->lastMessage, reportp, cx->runtime->debugHooks.debugErrorHookData))
onError = NULL;
}
}
if (onError)
onError(cx, cx->lastMessage, reportp);
@ -981,7 +979,6 @@ JSContext::JSContext(JSRuntime *rt)
outstandingRequests(0),
#endif
autoGCRooters(NULL),
debugHooks(&rt->globalDebugHooks),
securityCallbacks(NULL),
resolveFlags(0),
rngSeed(0),

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

@ -475,7 +475,7 @@ struct JSRuntime : js::RuntimeFriendFields
}
/* Per runtime debug hooks -- see jsprvtd.h and jsdbgapi.h. */
JSDebugHooks globalDebugHooks;
JSDebugHooks debugHooks;
/* If true, new compartments are initially in debug mode. */
bool debugMode;
@ -689,7 +689,7 @@ struct JSRuntime : js::RuntimeFriendFields
}
void sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf, size_t *normal, size_t *temporary,
size_t *regexpCode, size_t *stackCommitted);
size_t *regexpCode, size_t *stackCommitted, size_t *gcMarker);
void purge(JSContext *cx);
};
@ -714,8 +714,6 @@ struct JSArgumentFormatMap {
};
#endif
extern const JSDebugHooks js_NullDebugHooks; /* defined in jsdbgapi.cpp */
namespace js {
template <typename T> class Root;
@ -1015,9 +1013,6 @@ struct JSContext : js::ContextFriendFields
#endif /* JSGC_ROOT_ANALYSIS */
/* Debug hooks associated with the current context. */
const JSDebugHooks *debugHooks;
/* Security callbacks that override any defined on the runtime. */
JSSecurityCallbacks *securityCallbacks;

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

@ -113,11 +113,11 @@ ScriptDebugPrologue(JSContext *cx, StackFrame *fp)
JS_ASSERT(fp == cx->fp());
if (fp->isFramePushedByExecute()) {
if (JSInterpreterHook hook = cx->debugHooks->executeHook)
fp->setHookData(hook(cx, Jsvalify(fp), true, 0, cx->debugHooks->executeHookData));
if (JSInterpreterHook hook = cx->runtime->debugHooks.executeHook)
fp->setHookData(hook(cx, Jsvalify(fp), true, 0, cx->runtime->debugHooks.executeHookData));
} else {
if (JSInterpreterHook hook = cx->debugHooks->callHook)
fp->setHookData(hook(cx, Jsvalify(fp), true, 0, cx->debugHooks->callHookData));
if (JSInterpreterHook hook = cx->runtime->debugHooks.callHook)
fp->setHookData(hook(cx, Jsvalify(fp), true, 0, cx->runtime->debugHooks.callHookData));
}
Value rval;
@ -148,10 +148,10 @@ ScriptDebugEpilogue(JSContext *cx, StackFrame *fp, bool okArg)
if (void *hookData = fp->maybeHookData()) {
if (fp->isFramePushedByExecute()) {
if (JSInterpreterHook hook = cx->debugHooks->executeHook)
if (JSInterpreterHook hook = cx->runtime->debugHooks.executeHook)
hook(cx, Jsvalify(fp), false, &ok, hookData);
} else {
if (JSInterpreterHook hook = cx->debugHooks->callHook)
if (JSInterpreterHook hook = cx->runtime->debugHooks.callHook)
hook(cx, Jsvalify(fp), false, &ok, hookData);
}
}
@ -238,8 +238,8 @@ JS_ClearAllTrapsForCompartment(JSContext *cx)
JS_PUBLIC_API(JSBool)
JS_SetInterrupt(JSRuntime *rt, JSInterruptHook hook, void *closure)
{
rt->globalDebugHooks.interruptHook = hook;
rt->globalDebugHooks.interruptHookData = closure;
rt->debugHooks.interruptHook = hook;
rt->debugHooks.interruptHookData = closure;
return JS_TRUE;
}
@ -247,11 +247,11 @@ JS_PUBLIC_API(JSBool)
JS_ClearInterrupt(JSRuntime *rt, JSInterruptHook *hoop, void **closurep)
{
if (hoop)
*hoop = rt->globalDebugHooks.interruptHook;
*hoop = rt->debugHooks.interruptHook;
if (closurep)
*closurep = rt->globalDebugHooks.interruptHookData;
rt->globalDebugHooks.interruptHook = 0;
rt->globalDebugHooks.interruptHookData = 0;
*closurep = rt->debugHooks.interruptHookData;
rt->debugHooks.interruptHook = 0;
rt->debugHooks.interruptHookData = 0;
return JS_TRUE;
}
@ -589,7 +589,7 @@ JS_GetFrameCallObject(JSContext *cx, JSStackFrame *fpArg)
* null returned above or in the #else
*/
if (!fp->hasCallObj() && fp->isNonEvalFunctionFrame())
return CreateFunCallObject(cx, fp);
return CallObject::createForFunction(cx, fp);
return &fp->callObj();
}
@ -728,16 +728,16 @@ JS_GetScriptVersion(JSContext *cx, JSScript *script)
JS_PUBLIC_API(void)
JS_SetNewScriptHook(JSRuntime *rt, JSNewScriptHook hook, void *callerdata)
{
rt->globalDebugHooks.newScriptHook = hook;
rt->globalDebugHooks.newScriptHookData = callerdata;
rt->debugHooks.newScriptHook = hook;
rt->debugHooks.newScriptHookData = callerdata;
}
JS_PUBLIC_API(void)
JS_SetDestroyScriptHook(JSRuntime *rt, JSDestroyScriptHook hook,
void *callerdata)
{
rt->globalDebugHooks.destroyScriptHook = hook;
rt->globalDebugHooks.destroyScriptHookData = callerdata;
rt->debugHooks.destroyScriptHook = hook;
rt->debugHooks.destroyScriptHookData = callerdata;
}
/***************************************************************************/
@ -844,10 +844,10 @@ JS_GetPropertyDesc(JSContext *cx, JSObject *obj, JSScopeProperty *sprop,
| (!shape->writable() ? JSPD_READONLY : 0)
| (!shape->configurable() ? JSPD_PERMANENT : 0);
pd->spare = 0;
if (shape->getter() == GetCallArg) {
if (shape->getter() == CallObject::getArgOp) {
pd->slot = shape->shortid();
pd->flags |= JSPD_ARGUMENT;
} else if (shape->getter() == GetCallVar) {
} else if (shape->getter() == CallObject::getVarOp) {
pd->slot = shape->shortid();
pd->flags |= JSPD_VARIABLE;
} else {
@ -928,48 +928,48 @@ JS_PutPropertyDescArray(JSContext *cx, JSPropertyDescArray *pda)
JS_PUBLIC_API(JSBool)
JS_SetDebuggerHandler(JSRuntime *rt, JSDebuggerHandler handler, void *closure)
{
rt->globalDebugHooks.debuggerHandler = handler;
rt->globalDebugHooks.debuggerHandlerData = closure;
rt->debugHooks.debuggerHandler = handler;
rt->debugHooks.debuggerHandlerData = closure;
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_SetSourceHandler(JSRuntime *rt, JSSourceHandler handler, void *closure)
{
rt->globalDebugHooks.sourceHandler = handler;
rt->globalDebugHooks.sourceHandlerData = closure;
rt->debugHooks.sourceHandler = handler;
rt->debugHooks.sourceHandlerData = closure;
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_SetExecuteHook(JSRuntime *rt, JSInterpreterHook hook, void *closure)
{
rt->globalDebugHooks.executeHook = hook;
rt->globalDebugHooks.executeHookData = closure;
rt->debugHooks.executeHook = hook;
rt->debugHooks.executeHookData = closure;
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_SetCallHook(JSRuntime *rt, JSInterpreterHook hook, void *closure)
{
rt->globalDebugHooks.callHook = hook;
rt->globalDebugHooks.callHookData = closure;
rt->debugHooks.callHook = hook;
rt->debugHooks.callHookData = closure;
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_SetThrowHook(JSRuntime *rt, JSThrowHook hook, void *closure)
{
rt->globalDebugHooks.throwHook = hook;
rt->globalDebugHooks.throwHookData = closure;
rt->debugHooks.throwHook = hook;
rt->debugHooks.throwHookData = closure;
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_SetDebugErrorHook(JSRuntime *rt, JSDebugErrorHook hook, void *closure)
{
rt->globalDebugHooks.debugErrorHook = hook;
rt->globalDebugHooks.debugErrorHookData = closure;
rt->debugHooks.debugErrorHook = hook;
rt->debugHooks.debugErrorHookData = closure;
return JS_TRUE;
}
@ -1086,25 +1086,7 @@ js_RevertVersion(JSContext *cx)
JS_PUBLIC_API(const JSDebugHooks *)
JS_GetGlobalDebugHooks(JSRuntime *rt)
{
return &rt->globalDebugHooks;
}
const JSDebugHooks js_NullDebugHooks = {};
JS_PUBLIC_API(JSDebugHooks *)
JS_SetContextDebugHooks(JSContext *cx, const JSDebugHooks *hooks)
{
JS_ASSERT(hooks);
JSDebugHooks *old = const_cast<JSDebugHooks *>(cx->debugHooks);
cx->debugHooks = hooks;
return old;
}
JS_PUBLIC_API(JSDebugHooks *)
JS_ClearContextDebugHooks(JSContext *cx)
{
return JS_SetContextDebugHooks(cx, &js_NullDebugHooks);
return &rt->debugHooks;
}
/************************************************************************/

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

@ -477,13 +477,6 @@ js_RevertVersion(JSContext *cx);
extern JS_PUBLIC_API(const JSDebugHooks *)
JS_GetGlobalDebugHooks(JSRuntime *rt);
extern JS_PUBLIC_API(JSDebugHooks *)
JS_SetContextDebugHooks(JSContext *cx, const JSDebugHooks *hooks);
/* Disable debug hooks for this context. */
extern JS_PUBLIC_API(JSDebugHooks *)
JS_ClearContextDebugHooks(JSContext *cx);
/**
* Start any profilers that are available and have been configured on for this
* platform. This is NOT thread safe.

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

@ -591,17 +591,17 @@ VersionSetXML(JSVersion version, bool enable)
JS_FRIEND_API(bool)
CanCallContextDebugHandler(JSContext *cx)
{
return cx->debugHooks && cx->debugHooks->debuggerHandler;
return !!cx->runtime->debugHooks.debuggerHandler;
}
JS_FRIEND_API(JSTrapStatus)
CallContextDebugHandler(JSContext *cx, JSScript *script, jsbytecode *bc, Value *rval)
{
if (!CanCallContextDebugHandler(cx))
if (!cx->runtime->debugHooks.debuggerHandler)
return JSTRAP_RETURN;
return cx->debugHooks->debuggerHandler(cx, script, bc, rval,
cx->debugHooks->debuggerHandlerData);
return cx->runtime->debugHooks.debuggerHandler(cx, script, bc, rval,
cx->runtime->debugHooks.debuggerHandlerData);
}
#ifdef JS_THREADSAFE

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

@ -101,21 +101,6 @@ using namespace js;
using namespace js::gc;
using namespace js::types;
JSBool
js_GetArgsValue(JSContext *cx, StackFrame *fp, Value *vp)
{
JSObject *argsobj;
if (fp->hasOverriddenArgs()) {
JS_ASSERT(fp->hasCallObj());
return fp->callObj().getProperty(cx, cx->runtime->atomState.argumentsAtom, vp);
}
argsobj = js_GetArgsObject(cx, fp);
if (!argsobj)
return JS_FALSE;
vp->setObject(*argsobj);
return JS_TRUE;
}
js::ArgumentsObject *
ArgumentsObject::create(JSContext *cx, uint32_t argc, JSObject &callee)
{
@ -148,7 +133,8 @@ ArgumentsObject::create(JSContext *cx, uint32_t argc, JSObject &callee)
return NULL;
data->callee.init(ObjectValue(callee));
InitValueRange(data->slots, argc, false);
for (HeapValue *vp = data->slots; vp != data->slots + argc; vp++)
vp->init(UndefinedValue());
/* We have everything needed to fill in the object, so make the object. */
JSObject *obj = JSObject::create(cx, FINALIZE_KIND, emptyArgumentsShape, type, NULL);
@ -182,7 +168,7 @@ struct STATIC_SKIP_INFERENCE PutArg
}
};
JSObject *
ArgumentsObject *
js_GetArgsObject(JSContext *cx, StackFrame *fp)
{
/*
@ -613,350 +599,6 @@ Class js::StrictArgumentsObjectClass = {
}
};
namespace js {
CallObject *
CreateFunCallObject(JSContext *cx, StackFrame *fp)
{
JS_ASSERT(fp->isNonEvalFunctionFrame());
JS_ASSERT(!fp->hasCallObj());
JSObject *scopeChain = &fp->scopeChain();
JS_ASSERT_IF(scopeChain->isWith() || scopeChain->isBlock() || scopeChain->isCall(),
scopeChain->getPrivate() != fp);
/*
* For a named function expression Call's parent points to an environment
* object holding function's name.
*/
if (JSAtom *lambdaName = CallObjectLambdaName(fp->fun())) {
scopeChain = DeclEnvObject::create(cx, fp);
if (!scopeChain)
return NULL;
if (!DefineNativeProperty(cx, scopeChain, ATOM_TO_JSID(lambdaName),
ObjectValue(fp->callee()), NULL, NULL,
JSPROP_PERMANENT | JSPROP_READONLY, 0, 0)) {
return NULL;
}
}
CallObject *callobj = CallObject::create(cx, fp->script(), *scopeChain, &fp->callee());
if (!callobj)
return NULL;
callobj->setStackFrame(fp);
fp->setScopeChainWithOwnCallObj(*callobj);
return callobj;
}
CallObject *
CreateEvalCallObject(JSContext *cx, StackFrame *fp)
{
CallObject *callobj = CallObject::create(cx, fp->script(), fp->scopeChain(), NULL);
if (!callobj)
return NULL;
callobj->setStackFrame(fp);
fp->setScopeChainWithOwnCallObj(*callobj);
return callobj;
}
} // namespace js
void
js_PutCallObject(StackFrame *fp)
{
CallObject &callobj = fp->callObj().asCall();
JS_ASSERT(callobj.maybeStackFrame() == fp);
JS_ASSERT_IF(fp->isEvalFrame(), fp->isStrictEvalFrame());
JS_ASSERT(fp->isEvalFrame() == callobj.isForEval());
/* Get the arguments object to snapshot fp's actual argument values. */
if (fp->hasArgsObj()) {
if (!fp->hasOverriddenArgs())
callobj.initArguments(ObjectValue(fp->argsObj()));
js_PutArgsObject(fp);
}
JSScript *script = fp->script();
Bindings &bindings = script->bindings;
if (callobj.isForEval()) {
JS_ASSERT(script->strictModeCode);
JS_ASSERT(bindings.countArgs() == 0);
/* This could be optimized as below, but keep it simple for now. */
callobj.copyValues(0, NULL, bindings.countVars(), fp->slots());
} else {
JSFunction *fun = fp->fun();
JS_ASSERT(script == callobj.getCalleeFunction()->script());
JS_ASSERT(script == fun->script());
uintN n = bindings.countArgsAndVars();
if (n > 0) {
uint32_t nvars = bindings.countVars();
uint32_t nargs = bindings.countArgs();
JS_ASSERT(fun->nargs == nargs);
JS_ASSERT(nvars + nargs == n);
JSScript *script = fun->script();
if (script->usesEval
#ifdef JS_METHODJIT
|| script->debugMode
#endif
) {
callobj.copyValues(nargs, fp->formalArgs(), nvars, fp->slots());
} else {
/*
* For each arg & var that is closed over, copy it from the stack
* into the call object. We use initArg/VarUnchecked because,
* when you call a getter on a call object, js_NativeGetInline
* caches the return value in the slot, so we can't assert that
* it's undefined.
*/
uint32_t nclosed = script->nClosedArgs;
for (uint32_t i = 0; i < nclosed; i++) {
uint32_t e = script->getClosedArg(i);
#ifdef JS_GC_ZEAL
callobj.setArg(e, fp->formalArg(e));
#else
callobj.initArgUnchecked(e, fp->formalArg(e));
#endif
}
nclosed = script->nClosedVars;
for (uint32_t i = 0; i < nclosed; i++) {
uint32_t e = script->getClosedVar(i);
#ifdef JS_GC_ZEAL
callobj.setVar(e, fp->slots()[e]);
#else
callobj.initVarUnchecked(e, fp->slots()[e]);
#endif
}
}
/*
* Update the args and vars for the active call if this is an outer
* function in a script nesting.
*/
types::TypeScriptNesting *nesting = script->nesting();
if (nesting && script->isOuterFunction) {
nesting->argArray = callobj.argArray();
nesting->varArray = callobj.varArray();
}
}
/* Clear private pointers to fp, which is about to go away. */
if (js_IsNamedLambda(fun)) {
JSObject &env = callobj.enclosingScope();
JS_ASSERT(env.asDeclEnv().maybeStackFrame() == fp);
env.setPrivate(NULL);
}
}
callobj.setStackFrame(NULL);
}
namespace js {
static JSBool
GetCallArguments(JSContext *cx, JSObject *obj, jsid id, Value *vp)
{
CallObject &callobj = obj->asCall();
StackFrame *fp = callobj.maybeStackFrame();
if (fp && !fp->hasOverriddenArgs()) {
JSObject *argsobj = js_GetArgsObject(cx, fp);
if (!argsobj)
return false;
vp->setObject(*argsobj);
} else {
*vp = callobj.getArguments();
}
return true;
}
static JSBool
SetCallArguments(JSContext *cx, JSObject *obj, jsid id, JSBool strict, Value *vp)
{
CallObject &callobj = obj->asCall();
if (StackFrame *fp = callobj.maybeStackFrame())
fp->setOverriddenArgs();
callobj.setArguments(*vp);
return true;
}
JSBool
GetCallArg(JSContext *cx, JSObject *obj, jsid id, Value *vp)
{
CallObject &callobj = obj->asCall();
JS_ASSERT((int16_t) JSID_TO_INT(id) == JSID_TO_INT(id));
uintN i = (uint16_t) JSID_TO_INT(id);
if (StackFrame *fp = callobj.maybeStackFrame())
*vp = fp->formalArg(i);
else
*vp = callobj.arg(i);
return true;
}
JSBool
SetCallArg(JSContext *cx, JSObject *obj, jsid id, JSBool strict, Value *vp)
{
CallObject &callobj = obj->asCall();
JS_ASSERT((int16_t) JSID_TO_INT(id) == JSID_TO_INT(id));
uintN i = (uint16_t) JSID_TO_INT(id);
if (StackFrame *fp = callobj.maybeStackFrame())
fp->formalArg(i) = *vp;
else
callobj.setArg(i, *vp);
JSFunction *fun = callobj.getCalleeFunction();
JSScript *script = fun->script();
if (!script->ensureHasTypes(cx))
return false;
TypeScript::SetArgument(cx, script, i, *vp);
return true;
}
JSBool
GetCallUpvar(JSContext *cx, JSObject *obj, jsid id, Value *vp)
{
CallObject &callobj = obj->asCall();
JS_ASSERT((int16_t) JSID_TO_INT(id) == JSID_TO_INT(id));
uintN i = (uint16_t) JSID_TO_INT(id);
*vp = callobj.getCallee()->toFunction()->getFlatClosureUpvar(i);
return true;
}
JSBool
SetCallUpvar(JSContext *cx, JSObject *obj, jsid id, JSBool strict, Value *vp)
{
CallObject &callobj = obj->asCall();
JS_ASSERT((int16_t) JSID_TO_INT(id) == JSID_TO_INT(id));
uintN i = (uint16_t) JSID_TO_INT(id);
callobj.getCallee()->toFunction()->setFlatClosureUpvar(i, *vp);
return true;
}
JSBool
GetCallVar(JSContext *cx, JSObject *obj, jsid id, Value *vp)
{
CallObject &callobj = obj->asCall();
JS_ASSERT((int16_t) JSID_TO_INT(id) == JSID_TO_INT(id));
uintN i = (uint16_t) JSID_TO_INT(id);
if (StackFrame *fp = callobj.maybeStackFrame())
*vp = fp->varSlot(i);
else
*vp = callobj.var(i);
return true;
}
JSBool
SetCallVar(JSContext *cx, JSObject *obj, jsid id, JSBool strict, Value *vp)
{
CallObject &callobj = obj->asCall();
JS_ASSERT((int16_t) JSID_TO_INT(id) == JSID_TO_INT(id));
uintN i = (uint16_t) JSID_TO_INT(id);
if (StackFrame *fp = callobj.maybeStackFrame())
fp->varSlot(i) = *vp;
else
callobj.setVar(i, *vp);
JSFunction *fun = callobj.getCalleeFunction();
JSScript *script = fun->script();
if (!script->ensureHasTypes(cx))
return false;
TypeScript::SetLocal(cx, script, i, *vp);
return true;
}
} // namespace js
static JSBool
call_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags, JSObject **objp)
{
JS_ASSERT(!obj->getProto());
if (!JSID_IS_ATOM(id))
return true;
JSObject *callee = obj->asCall().getCallee();
#ifdef DEBUG
if (callee) {
JSScript *script = callee->toFunction()->script();
JS_ASSERT(!script->bindings.hasBinding(cx, JSID_TO_ATOM(id)));
}
#endif
/*
* Resolve arguments so that we never store a particular Call object's
* arguments object reference in a Call prototype's |arguments| slot.
*
* Include JSPROP_ENUMERATE for consistency with all other Call object
* properties; see js::Bindings::add and js::Interpret's JSOP_DEFFUN
* rebinding-Call-property logic.
*/
if (callee && id == ATOM_TO_JSID(cx->runtime->atomState.argumentsAtom)) {
if (!DefineNativeProperty(cx, obj, id, UndefinedValue(),
GetCallArguments, SetCallArguments,
JSPROP_PERMANENT | JSPROP_SHARED | JSPROP_ENUMERATE,
0, 0, DNP_DONT_PURGE)) {
return false;
}
*objp = obj;
return true;
}
/* Control flow reaches here only if id was not resolved. */
return true;
}
static void
call_trace(JSTracer *trc, JSObject *obj)
{
JS_ASSERT(obj->isCall());
/* Mark any generator frame, as for arguments objects. */
#if JS_HAS_GENERATORS
StackFrame *fp = (StackFrame *) obj->getPrivate();
if (fp && fp->isFloatingGenerator())
MarkObject(trc, &js_FloatingFrameToGenerator(fp)->obj, "generator object");
#endif
}
JS_PUBLIC_DATA(Class) js::CallClass = {
"Call",
JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS |
JSCLASS_HAS_RESERVED_SLOTS(CallObject::RESERVED_SLOTS) |
JSCLASS_NEW_RESOLVE | JSCLASS_IS_ANONYMOUS,
JS_PropertyStub, /* addProperty */
JS_PropertyStub, /* delProperty */
JS_PropertyStub, /* getProperty */
JS_StrictPropertyStub, /* setProperty */
JS_EnumerateStub,
(JSResolveOp)call_resolve,
NULL, /* convert: Leave it NULL so we notice if calls ever escape */
NULL, /* finalize */
NULL, /* checkAccess */
NULL, /* call */
NULL, /* construct */
NULL, /* hasInstance */
call_trace
};
bool
StackFrame::getValidCalleeObject(JSContext *cx, Value *vp)
{

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

@ -362,30 +362,6 @@ js_PutCallObject(js::StackFrame *fp);
namespace js {
CallObject *
CreateFunCallObject(JSContext *cx, StackFrame *fp);
CallObject *
CreateEvalCallObject(JSContext *cx, StackFrame *fp);
extern JSBool
GetCallArg(JSContext *cx, JSObject *obj, jsid id, js::Value *vp);
extern JSBool
GetCallVar(JSContext *cx, JSObject *obj, jsid id, js::Value *vp);
extern JSBool
GetCallUpvar(JSContext *cx, JSObject *obj, jsid id, js::Value *vp);
extern JSBool
SetCallArg(JSContext *cx, JSObject *obj, jsid id, JSBool strict, js::Value *vp);
extern JSBool
SetCallVar(JSContext *cx, JSObject *obj, jsid id, JSBool strict, js::Value *vp);
extern JSBool
SetCallUpvar(JSContext *cx, JSObject *obj, jsid id, JSBool strict, js::Value *vp);
/*
* Function extended with reserved slots for use by various kinds of functions.
* Most functions do not have these extensions, but enough are that efficient
@ -415,9 +391,6 @@ JSFunction::toExtended() const
return static_cast<const js::FunctionExtended *>(this);
}
extern JSBool
js_GetArgsValue(JSContext *cx, js::StackFrame *fp, js::Value *vp);
/*
* Get the arguments object for the given frame. If the frame is strict mode
* code, its current arguments will be copied into the arguments object.
@ -428,7 +401,7 @@ js_GetArgsValue(JSContext *cx, js::StackFrame *fp, js::Value *vp);
* named parameter by synthesizing an arguments access at the start of the
* function.
*/
extern JSObject *
extern js::ArgumentsObject *
js_GetArgsObject(JSContext *cx, js::StackFrame *fp);
extern void

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

@ -2118,6 +2118,13 @@ GCMarker::GrayCallback(JSTracer *trc, void **thingp, JSGCTraceKind kind)
gcmarker->appendGrayRoot(*thingp, kind);
}
size_t
GCMarker::sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf) const
{
return stack.sizeOfExcludingThis(mallocSizeOf) +
grayRoots.sizeOfExcludingThis(mallocSizeOf);
}
void
SetMarkStackLimit(JSRuntime *rt, size_t limit)
{
@ -3078,7 +3085,7 @@ ValidateIncrementalMarking(JSContext *cx)
JSRuntime *rt = cx->runtime;
FullGCMarker *gcmarker = &rt->gcMarker;
/* Save existing mark bits */
/* Save existing mark bits. */
for (GCChunkSet::Range r(rt->gcChunkSet.all()); !r.empty(); r.popFront()) {
ChunkBitmap *bitmap = &r.front()->bitmap;
uintptr_t *entry = (uintptr_t *)js_malloc(sizeof(bitmap->bitmap));
@ -3090,6 +3097,11 @@ ValidateIncrementalMarking(JSContext *cx)
return;
}
/* Save the existing weakmaps. */
WeakMapVector weakmaps;
if (!WeakMapBase::saveWeakMapList(rt, weakmaps))
return;
/*
* After this point, the function should run to completion, so we shouldn't
* do anything fallible.
@ -3099,6 +3111,9 @@ ValidateIncrementalMarking(JSContext *cx)
js::gc::State state = rt->gcIncrementalState;
rt->gcIncrementalState = NO_INCREMENTAL;
/* As we're re-doing marking, we need to reset the weak map list. */
WeakMapBase::resetWeakMapList(rt);
JS_ASSERT(gcmarker->isDrained());
gcmarker->reset();
@ -3146,6 +3161,10 @@ ValidateIncrementalMarking(JSContext *cx)
memcpy(bitmap->bitmap, incBitmap.bitmap, sizeof(incBitmap.bitmap));
}
/* Restore the weak map list. */
WeakMapBase::resetWeakMapList(rt);
WeakMapBase::restoreWeakMapList(rt, weakmaps);
rt->gcIncrementalState = state;
}
#endif

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

@ -1690,6 +1690,14 @@ struct MarkStack {
limit = newStack + newcap;
return true;
}
size_t sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf) const {
size_t n = 0;
if (stack != ballast)
n += mallocSizeOf(stack);
n += mallocSizeOf(ballast);
return n;
}
};
/*
@ -1827,6 +1835,8 @@ struct GCMarker : public JSTracer {
static void GrayCallback(JSTracer *trc, void **thing, JSGCTraceKind kind);
size_t sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf) const;
MarkStack<uintptr_t> stack;
private:

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

@ -356,6 +356,41 @@ MarkValueRootRange(JSTracer *trc, size_t len, Value *vec, const char *name)
}
}
/*** Slot Marking ***/
void
MarkSlot(JSTracer *trc, HeapSlot *s, const char *name)
{
JS_SET_TRACING_NAME(trc, name);
MarkValueInternal(trc, s->unsafeGet());
}
void
MarkSlotRange(JSTracer *trc, size_t len, HeapSlot *vec, const char *name)
{
for (size_t i = 0; i < len; ++i) {
JS_SET_TRACING_INDEX(trc, name, i);
MarkValueInternal(trc, vec[i].unsafeGet());
}
}
void
MarkCrossCompartmentSlot(JSTracer *trc, HeapSlot *s, const char *name)
{
if (s->isMarkable()) {
Cell *cell = (Cell *)s->toGCThing();
JSRuntime *rt = trc->runtime;
if (rt->gcCurrentCompartment && cell->compartment() != rt->gcCurrentCompartment)
return;
/* In case we're called from a write barrier. */
if (rt->gcIncrementalCompartment && cell->compartment() != rt->gcIncrementalCompartment)
return;
MarkSlot(trc, s, name);
}
}
/*** Special Marking ***/
/*
@ -376,23 +411,6 @@ MarkValueUnbarriered(JSTracer *trc, Value *v, const char *name)
MarkValueInternal(trc, v);
}
void
MarkCrossCompartmentValue(JSTracer *trc, HeapValue *v, const char *name)
{
if (v->isMarkable()) {
Cell *cell = (Cell *)v->toGCThing();
JSRuntime *rt = trc->runtime;
if (rt->gcCurrentCompartment && cell->compartment() != rt->gcCurrentCompartment)
return;
/* In case we're called from a write barrier. */
if (rt->gcIncrementalCompartment && cell->compartment() != rt->gcIncrementalCompartment)
return;
MarkValue(trc, v, name);
}
}
/*** Push Mark Stack ***/
#define JS_COMPARTMENT_ASSERT(rt, thing) \
@ -896,21 +914,21 @@ PushArena(GCMarker *gcmarker, ArenaHeader *aheader)
using namespace js::gc;
struct ValueArrayLayout
struct SlotArrayLayout
{
union {
HeapValue *end;
HeapSlot *end;
js::Class *clasp;
};
union {
HeapValue *start;
HeapSlot *start;
uintptr_t index;
};
JSObject *obj;
static void staticAsserts() {
/* This should have the same layout as three mark stack items. */
JS_STATIC_ASSERT(sizeof(ValueArrayLayout) == 3 * sizeof(uintptr_t));
JS_STATIC_ASSERT(sizeof(SlotArrayLayout) == 3 * sizeof(uintptr_t));
}
};
@ -933,16 +951,16 @@ GCMarker::saveValueRanges()
uintptr_t tag = *--p & StackTagMask;
if (tag == ValueArrayTag) {
p -= 2;
ValueArrayLayout *arr = reinterpret_cast<ValueArrayLayout *>(p);
SlotArrayLayout *arr = reinterpret_cast<SlotArrayLayout *>(p);
JSObject *obj = arr->obj;
if (obj->getClass() == &ArrayClass) {
HeapValue *vp = obj->getDenseArrayElements();
HeapSlot *vp = obj->getDenseArrayElements();
JS_ASSERT(arr->start >= vp &&
arr->end == vp + obj->getDenseArrayInitializedLength());
arr->index = arr->start - vp;
} else {
HeapValue *vp = obj->fixedSlots();
HeapSlot *vp = obj->fixedSlots();
unsigned nfixed = obj->numFixedSlots();
if (arr->start >= vp && arr->start < vp + nfixed) {
JS_ASSERT(arr->end == vp + Min(nfixed, obj->slotSpan()));
@ -975,7 +993,7 @@ GCMarker::restoreValueArray(JSObject *obj, void **vpp, void **endp)
return false;
uint32_t initlen = obj->getDenseArrayInitializedLength();
HeapValue *vp = obj->getDenseArrayElements();
HeapSlot *vp = obj->getDenseArrayElements();
if (start < initlen) {
*vpp = vp + start;
*endp = vp + initlen;
@ -984,7 +1002,7 @@ GCMarker::restoreValueArray(JSObject *obj, void **vpp, void **endp)
*vpp = *endp = vp;
}
} else {
HeapValue *vp = obj->fixedSlots();
HeapSlot *vp = obj->fixedSlots();
unsigned nfixed = obj->numFixedSlots();
unsigned nslots = obj->slotSpan();
if (start < nfixed) {
@ -1011,7 +1029,7 @@ GCMarker::processMarkStackTop(SliceBudget &budget)
* object directly. It allows to eliminate the tail recursion and
* significantly improve the marking performance, see bug 641025.
*/
HeapValue *vp, *end;
HeapSlot *vp, *end;
JSObject *obj;
uintptr_t addr = stack.pop();
@ -1026,8 +1044,8 @@ GCMarker::processMarkStackTop(SliceBudget &budget)
uintptr_t addr3 = stack.pop();
JS_ASSERT(addr2 <= addr3);
JS_ASSERT((addr3 - addr2) % sizeof(Value) == 0);
vp = reinterpret_cast<HeapValue *>(addr2);
end = reinterpret_cast<HeapValue *>(addr3);
vp = reinterpret_cast<HeapSlot *>(addr2);
end = reinterpret_cast<HeapSlot *>(addr3);
goto scan_value_array;
}

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

@ -114,18 +114,26 @@ MarkValueRootRange(JSTracer *trc, Value *begin, Value *end, const char *name)
MarkValueRootRange(trc, end - begin, begin, name);
}
/*** Special Cases ***/
/*** Slot Marking ***/
/* Direct value access used by the write barriers and the methodjit */
void
MarkValueUnbarriered(JSTracer *trc, Value *v, const char *name);
MarkSlot(JSTracer *trc, HeapSlot *s, const char *name);
void
MarkSlotRange(JSTracer *trc, size_t len, HeapSlot *vec, const char *name);
/*
* Mark a value that may be in a different compartment from the compartment
* being GC'd. (Although it won't be marked if it's in the wrong compartment.)
*/
void
MarkCrossCompartmentValue(JSTracer *trc, HeapValue *v, const char *name);
MarkCrossCompartmentSlot(JSTracer *trc, HeapSlot *s, const char *name);
/*** Special Cases ***/
/* Direct value access used by the write barriers and the methodjit. */
void
MarkValueUnbarriered(JSTracer *trc, Value *v, const char *name);
/*
* MarkChildren<JSObject> is exposed solely for preWriteBarrier on

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

@ -1688,10 +1688,8 @@ types::MarkArgumentsCreated(JSContext *cx, JSScript *script)
*/
Value *sp = fp->base() + analysis->getCode(iter.pc()).stackDepth;
for (Value *vp = fp->slots(); vp < sp; vp++) {
if (vp->isParticularMagic(JS_LAZY_ARGUMENTS)) {
if (!js_GetArgsValue(cx, fp, vp))
vp->setNull();
}
if (vp->isParticularMagic(JS_LAZY_ARGUMENTS))
*vp = ObjectOrNullValue(js_GetArgsObject(cx, fp));
}
}
}
@ -2412,6 +2410,11 @@ ScriptAnalysis::addTypeBarrier(JSContext *cx, const jsbytecode *pc, TypeSet *tar
barrier = cx->typeLifoAlloc().new_<TypeBarrier>(target, type, (JSObject *) NULL, JSID_VOID);
if (!barrier) {
cx->compartment->types.setPendingNukeTypes(cx);
return;
}
barrier->next = code.typeBarriers;
code.typeBarriers = barrier;
}
@ -2438,6 +2441,11 @@ ScriptAnalysis::addSingletonTypeBarrier(JSContext *cx, const jsbytecode *pc, Typ
TypeBarrier *barrier = cx->typeLifoAlloc().new_<TypeBarrier>(target, Type::UndefinedType(),
singleton, singletonId);
if (!barrier) {
cx->compartment->types.setPendingNukeTypes(cx);
return;
}
barrier->next = code.typeBarriers;
code.typeBarriers = barrier;
}

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

@ -160,7 +160,7 @@ js::GetScopeChain(JSContext *cx, StackFrame *fp)
JSObject *limitBlock, *limitClone;
if (fp->isNonEvalFunctionFrame() && !fp->hasCallObj()) {
JS_ASSERT_IF(fp->scopeChain().isClonedBlock(), fp->scopeChain().getPrivate() != fp);
if (!CreateFunCallObject(cx, fp))
if (!CallObject::createForFunction(cx, fp))
return NULL;
/* We know we must clone everything on blockChain. */
@ -646,7 +646,7 @@ js::ExecuteKernel(JSContext *cx, JSScript *script, JSObject &scopeChain, const V
/* Give strict mode eval its own fresh lexical environment. */
StackFrame *fp = efg.fp();
if (fp->isStrictEvalFrame() && !CreateEvalCallObject(cx, fp))
if (fp->isStrictEvalFrame() && !CallObject::createForStrictEval(cx, fp))
return false;
Probes::startExecution(cx, script);
@ -1444,7 +1444,7 @@ js::Interpret(JSContext *cx, StackFrame *entryFrame, InterpMode interpMode)
#define CHECK_INTERRUPT_HANDLER() \
JS_BEGIN_MACRO \
if (cx->debugHooks->interruptHook) \
if (cx->runtime->debugHooks.interruptHook) \
ENABLE_INTERRUPTS(); \
JS_END_MACRO
@ -1591,12 +1591,12 @@ js::Interpret(JSContext *cx, StackFrame *entryFrame, InterpMode interpMode)
moreInterrupts = true;
}
JSInterruptHook hook = cx->debugHooks->interruptHook;
JSInterruptHook hook = cx->runtime->debugHooks.interruptHook;
if (hook || script->stepModeEnabled()) {
Value rval;
JSTrapStatus status = JSTRAP_CONTINUE;
if (hook)
status = hook(cx, script, regs.pc, &rval, cx->debugHooks->interruptHookData);
status = hook(cx, script, regs.pc, &rval, cx->runtime->debugHooks.interruptHookData);
if (status == JSTRAP_CONTINUE && script->stepModeEnabled())
status = Debugger::onSingleStep(cx, &rval);
switch (status) {
@ -1967,7 +1967,7 @@ BEGIN_CASE(JSOP_ITER)
{
JS_ASSERT(regs.sp > regs.fp()->base());
uint8_t flags = GET_UINT8(regs.pc);
if (!js_ValueToIterator(cx, flags, &regs.sp[-1]))
if (!ValueToIterator(cx, flags, &regs.sp[-1]))
goto error;
CHECK_INTERRUPT_HANDLER();
JS_ASSERT(!regs.sp[-1].isPrimitive());
@ -2001,7 +2001,7 @@ END_CASE(JSOP_ITERNEXT)
BEGIN_CASE(JSOP_ENDITER)
{
JS_ASSERT(regs.sp - 1 >= regs.fp()->base());
bool ok = !!js_CloseIterator(cx, &regs.sp[-1].toObject());
bool ok = CloseIterator(cx, &regs.sp[-1].toObject());
regs.sp--;
if (!ok)
goto error;
@ -3000,14 +3000,18 @@ BEGIN_CASE(JSOP_ARGUMENTS)
if (!script->ensureRanInference(cx))
goto error;
if (script->createdArgs) {
if (!js_GetArgsValue(cx, regs.fp(), &rval))
ArgumentsObject *arguments = js_GetArgsObject(cx, regs.fp());
if (!arguments)
goto error;
rval = ObjectValue(*arguments);
} else {
rval = MagicValue(JS_LAZY_ARGUMENTS);
}
} else {
if (!js_GetArgsValue(cx, regs.fp(), &rval))
ArgumentsObject *arguments = js_GetArgsObject(cx, regs.fp());
if (!arguments)
goto error;
rval = ObjectValue(*arguments);
}
PUSH_COPY(rval);
}
@ -3667,8 +3671,8 @@ BEGIN_CASE(JSOP_DEBUGGER)
{
JSTrapStatus st = JSTRAP_CONTINUE;
Value rval;
if (JSDebuggerHandler handler = cx->debugHooks->debuggerHandler)
st = handler(cx, script, regs.pc, &rval, cx->debugHooks->debuggerHandlerData);
if (JSDebuggerHandler handler = cx->runtime->debugHooks.debuggerHandler)
st = handler(cx, script, regs.pc, &rval, cx->runtime->debugHooks.debuggerHandlerData);
if (st == JSTRAP_CONTINUE)
st = Debugger::onDebuggerStatement(cx, &rval);
switch (st) {
@ -4227,13 +4231,13 @@ END_CASE(JSOP_ARRAYPUSH)
atoms = script->atoms;
/* Call debugger throw hook if set. */
if (cx->debugHooks->throwHook || !cx->compartment->getDebuggees().empty()) {
if (cx->runtime->debugHooks.throwHook || !cx->compartment->getDebuggees().empty()) {
Value rval;
JSTrapStatus st = Debugger::onExceptionUnwind(cx, &rval);
if (st == JSTRAP_CONTINUE) {
handler = cx->debugHooks->throwHook;
handler = cx->runtime->debugHooks.throwHook;
if (handler)
st = handler(cx, script, regs.pc, &rval, cx->debugHooks->throwHookData);
st = handler(cx, script, regs.pc, &rval, cx->runtime->debugHooks.throwHookData);
}
switch (st) {
@ -4330,13 +4334,10 @@ END_CASE(JSOP_ARRAYPUSH)
case JSTRY_ITER: {
/* This is similar to JSOP_ENDITER in the interpreter loop. */
JS_ASSERT(JSOp(*regs.pc) == JSOP_ENDITER);
Value v = cx->getPendingException();
cx->clearPendingException();
bool ok = js_CloseIterator(cx, &regs.sp[-1].toObject());
bool ok = UnwindIteratorForException(cx, &regs.sp[-1].toObject());
regs.sp -= 1;
if (!ok)
goto error;
cx->setPendingException(v);
}
}
} while (++tn != tnlimit);

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

@ -352,6 +352,22 @@ Debug_SetValueRangeToCrashOnTouch(HeapValue *vec, size_t len)
#endif
}
static JS_ALWAYS_INLINE void
Debug_SetSlotRangeToCrashOnTouch(HeapSlot *vec, size_t len)
{
#ifdef DEBUG
Debug_SetValueRangeToCrashOnTouch((Value *) vec, len);
#endif
}
static JS_ALWAYS_INLINE void
Debug_SetSlotRangeToCrashOnTouch(HeapSlot *begin, HeapSlot *end)
{
#ifdef DEBUG
Debug_SetValueRangeToCrashOnTouch((Value *) begin, end - begin);
#endif
}
} /* namespace js */
#endif /* jsinterp_h___ */

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

@ -829,7 +829,7 @@ Iterator(JSContext *cx, uintN argc, Value *vp)
bool keyonly = argc >= 2 ? js_ValueToBoolean(argv[1]) : false;
uintN flags = JSITER_OWNONLY | (keyonly ? 0 : (JSITER_FOREACH | JSITER_KEYVALUE));
*vp = argc >= 1 ? argv[0] : UndefinedValue();
return js_ValueToIterator(cx, flags, vp);
return ValueToIterator(cx, flags, vp);
}
JSBool
@ -871,12 +871,19 @@ static JSFunctionSpec iterator_methods[] = {
JS_FS_END
};
#if JS_HAS_GENERATORS
static JSBool
CloseGenerator(JSContext *cx, JSObject *genobj);
#endif
namespace js {
/*
* Call ToObject(v).__iterator__(keyonly) if ToObject(v).__iterator__ exists.
* Otherwise construct the default iterator.
*/
JS_FRIEND_API(JSBool)
js_ValueToIterator(JSContext *cx, uintN flags, Value *vp)
JSBool
ValueToIterator(JSContext *cx, uintN flags, Value *vp)
{
/* JSITER_KEYVALUE must always come with JSITER_FOREACH */
JS_ASSERT_IF(flags & JSITER_KEYVALUE, flags & JSITER_FOREACH);
@ -914,13 +921,8 @@ js_ValueToIterator(JSContext *cx, uintN flags, Value *vp)
return GetIterator(cx, obj, flags, vp);
}
#if JS_HAS_GENERATORS
static JSBool
CloseGenerator(JSContext *cx, JSObject *genobj);
#endif
JS_FRIEND_API(JSBool)
js_CloseIterator(JSContext *cx, JSObject *obj)
bool
CloseIterator(JSContext *cx, JSObject *obj)
{
cx->iterValue.setMagic(JS_NO_ITER_VALUE);
@ -950,6 +952,19 @@ js_CloseIterator(JSContext *cx, JSObject *obj)
return JS_TRUE;
}
bool
UnwindIteratorForException(JSContext *cx, JSObject *obj)
{
Value v = cx->getPendingException();
cx->clearPendingException();
if (!CloseIterator(cx, obj))
return false;
cx->setPendingException(v);
return true;
}
} // namespace js
/*
* Suppress enumeration of deleted properties. This function must be called
* when a property is deleted and there might be active enumerators.

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

@ -181,19 +181,22 @@ VectorToValueIterator(JSContext *cx, JSObject *obj, uintN flags, js::AutoIdVecto
bool
EnumeratedIdVectorToIterator(JSContext *cx, JSObject *obj, uintN flags, js::AutoIdVector &props, js::Value *vp);
}
/*
* Convert the value stored in *vp to its iteration object. The flags should
* contain JSITER_ENUMERATE if js_ValueToIterator is called when enumerating
* for-in semantics are required, and when the caller can guarantee that the
* iterator will never be exposed to scripts.
*/
extern JS_FRIEND_API(JSBool)
js_ValueToIterator(JSContext *cx, uintN flags, js::Value *vp);
extern JSBool
ValueToIterator(JSContext *cx, uintN flags, js::Value *vp);
extern JS_FRIEND_API(JSBool)
js_CloseIterator(JSContext *cx, JSObject *iterObj);
extern bool
CloseIterator(JSContext *cx, JSObject *iterObj);
extern bool
UnwindIteratorForException(JSContext *cx, JSObject *obj);
}
extern bool
js_SuppressDeletedProperty(JSContext *cx, JSObject *obj, jsid id);

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

@ -2753,7 +2753,7 @@ NewObject(JSContext *cx, Class *clasp, types::TypeObject *type, JSObject *parent
if (!shape)
return NULL;
HeapValue *slots;
HeapSlot *slots;
if (!PreallocateObjectDynamicSlots(cx, shape, &slots))
return NULL;
@ -3250,8 +3250,8 @@ struct JSObject::TradeGutsReserved {
int newbfixed;
Shape *newashape;
Shape *newbshape;
HeapValue *newaslots;
HeapValue *newbslots;
HeapSlot *newaslots;
HeapSlot *newbslots;
TradeGutsReserved(JSContext *cx)
: cx(cx), avals(cx), bvals(cx),
@ -3350,16 +3350,16 @@ JSObject::ReserveForTradeGuts(JSContext *cx, JSObject *a, JSObject *b,
unsigned bdynamic = dynamicSlotsCount(reserved.newbfixed, a->slotSpan());
if (adynamic) {
reserved.newaslots = (HeapValue *) cx->malloc_(sizeof(HeapValue) * adynamic);
reserved.newaslots = (HeapSlot *) cx->malloc_(sizeof(HeapSlot) * adynamic);
if (!reserved.newaslots)
return false;
Debug_SetValueRangeToCrashOnTouch(reserved.newaslots, adynamic);
Debug_SetSlotRangeToCrashOnTouch(reserved.newaslots, adynamic);
}
if (bdynamic) {
reserved.newbslots = (HeapValue *) cx->malloc_(sizeof(HeapValue) * bdynamic);
reserved.newbslots = (HeapSlot *) cx->malloc_(sizeof(HeapSlot) * bdynamic);
if (!reserved.newbslots)
return false;
Debug_SetValueRangeToCrashOnTouch(reserved.newbslots, bdynamic);
Debug_SetSlotRangeToCrashOnTouch(reserved.newbslots, bdynamic);
}
return true;
@ -3421,11 +3421,10 @@ JSObject::TradeGuts(JSContext *cx, JSObject *a, JSObject *b, TradeGutsReserved &
* Trigger post barriers for fixed slots. JSObject bits are barriered
* below, in common with the other case.
*/
JSCompartment *comp = cx->compartment;
for (size_t i = 0; i < a->numFixedSlots(); ++i) {
HeapValue *slotA = &a->getFixedSlotRef(i);
HeapValue *slotB = &b->getFixedSlotRef(i);
HeapValue::writeBarrierPost(*slotA, slotA);
HeapValue::writeBarrierPost(*slotB, slotB);
HeapSlot::writeBarrierPost(comp, a, i);
HeapSlot::writeBarrierPost(comp, b, i);
}
#endif
} else {
@ -3815,56 +3814,28 @@ js_InitClass(JSContext *cx, HandleObject obj, JSObject *protoProto,
ps, fs, static_ps, static_fs, ctorp, ctorKind);
}
void
JSObject::getSlotRange(size_t start, size_t length,
HeapValue **fixedStart, HeapValue **fixedEnd,
HeapValue **slotsStart, HeapValue **slotsEnd)
{
JS_ASSERT(!isDenseArray());
JS_ASSERT(slotInRange(start + length, SENTINEL_ALLOWED));
size_t fixed = numFixedSlots();
if (start < fixed) {
if (start + length < fixed) {
*fixedStart = &fixedSlots()[start];
*fixedEnd = &fixedSlots()[start + length];
*slotsStart = *slotsEnd = NULL;
} else {
size_t localCopy = fixed - start;
*fixedStart = &fixedSlots()[start];
*fixedEnd = &fixedSlots()[start + localCopy];
*slotsStart = &slots[0];
*slotsEnd = &slots[length - localCopy];
}
} else {
*fixedStart = *fixedEnd = NULL;
*slotsStart = &slots[start - fixed];
*slotsEnd = &slots[start - fixed + length];
}
}
void
JSObject::initSlotRange(size_t start, const Value *vector, size_t length)
{
JSCompartment *comp = compartment();
HeapValue *fixedStart, *fixedEnd, *slotsStart, *slotsEnd;
HeapSlot *fixedStart, *fixedEnd, *slotsStart, *slotsEnd;
getSlotRange(start, length, &fixedStart, &fixedEnd, &slotsStart, &slotsEnd);
for (HeapValue *vp = fixedStart; vp != fixedEnd; vp++)
vp->init(comp, *vector++);
for (HeapValue *vp = slotsStart; vp != slotsEnd; vp++)
vp->init(comp, *vector++);
for (HeapSlot *sp = fixedStart; sp != fixedEnd; sp++)
sp->init(comp, this, start++, *vector++);
for (HeapSlot *sp = slotsStart; sp != slotsEnd; sp++)
sp->init(comp, this, start++, *vector++);
}
void
JSObject::copySlotRange(size_t start, const Value *vector, size_t length)
{
JSCompartment *comp = compartment();
HeapValue *fixedStart, *fixedEnd, *slotsStart, *slotsEnd;
HeapSlot *fixedStart, *fixedEnd, *slotsStart, *slotsEnd;
getSlotRange(start, length, &fixedStart, &fixedEnd, &slotsStart, &slotsEnd);
for (HeapValue *vp = fixedStart; vp != fixedEnd; vp++)
vp->set(comp, *vector++);
for (HeapValue *vp = slotsStart; vp != slotsEnd; vp++)
vp->set(comp, *vector++);
for (HeapSlot *sp = fixedStart; sp != fixedEnd; sp++)
sp->set(comp, this, start++, *vector++);
for (HeapSlot *sp = slotsStart; sp != slotsEnd; sp++)
sp->set(comp, this, start++, *vector++);
}
inline void
@ -3873,20 +3844,10 @@ JSObject::invalidateSlotRange(size_t start, size_t length)
#ifdef DEBUG
JS_ASSERT(!isDenseArray());
size_t fixed = numFixedSlots();
/* No bounds checks, allocated space has been updated but not the shape. */
if (start < fixed) {
if (start + length < fixed) {
Debug_SetValueRangeToCrashOnTouch(fixedSlots() + start, length);
} else {
size_t localClear = fixed - start;
Debug_SetValueRangeToCrashOnTouch(fixedSlots() + start, localClear);
Debug_SetValueRangeToCrashOnTouch(slots, length - localClear);
}
} else {
Debug_SetValueRangeToCrashOnTouch(slots + start - fixed, length);
}
HeapSlot *fixedStart, *fixedEnd, *slotsStart, *slotsEnd;
getSlotRange(start, length, &fixedStart, &fixedEnd, &slotsStart, &slotsEnd);
Debug_SetSlotRangeToCrashOnTouch(fixedStart, fixedEnd);
Debug_SetSlotRangeToCrashOnTouch(slotsStart, slotsEnd);
#endif /* DEBUG */
}
@ -4006,24 +3967,24 @@ JSObject::growSlots(JSContext *cx, uint32_t oldCount, uint32_t newCount)
}
if (!oldCount) {
slots = (HeapValue *) cx->malloc_(newCount * sizeof(HeapValue));
slots = (HeapSlot *) cx->malloc_(newCount * sizeof(HeapSlot));
if (!slots)
return false;
Debug_SetValueRangeToCrashOnTouch(slots, newCount);
Debug_SetSlotRangeToCrashOnTouch(slots, newCount);
if (Probes::objectResizeActive())
Probes::resizeObject(cx, this, oldSize, newSize);
return true;
}
HeapValue *newslots = (HeapValue*) cx->realloc_(slots, oldCount * sizeof(HeapValue),
newCount * sizeof(HeapValue));
HeapSlot *newslots = (HeapSlot*) cx->realloc_(slots, oldCount * sizeof(HeapSlot),
newCount * sizeof(HeapSlot));
if (!newslots)
return false; /* Leave slots at its old size. */
bool changed = slots != newslots;
slots = newslots;
Debug_SetValueRangeToCrashOnTouch(slots + oldCount, newCount - oldCount);
Debug_SetSlotRangeToCrashOnTouch(slots + oldCount, newCount - oldCount);
/* Changes in the slots of global objects can trigger recompilation. */
if (changed && isGlobal())
@ -4063,7 +4024,7 @@ JSObject::shrinkSlots(JSContext *cx, uint32_t oldCount, uint32_t newCount)
JS_ASSERT(newCount >= SLOT_CAPACITY_MIN);
HeapValue *newslots = (HeapValue*) cx->realloc_(slots, newCount * sizeof(HeapValue));
HeapSlot *newslots = (HeapSlot *) cx->realloc_(slots, newCount * sizeof(HeapSlot));
if (!newslots)
return; /* Leave slots at its old size. */
@ -4136,7 +4097,7 @@ JSObject::growElements(JSContext *cx, uintN newcap)
newheader->capacity = actualCapacity;
elements = newheader->elements();
Debug_SetValueRangeToCrashOnTouch(elements + initlen, actualCapacity - initlen);
Debug_SetSlotRangeToCrashOnTouch(elements + initlen, actualCapacity - initlen);
if (Probes::objectResizeActive())
Probes::resizeObject(cx, this, oldSize, computedSizeOfThisSlotsElements());
@ -6538,8 +6499,6 @@ js_DumpStackFrame(JSContext *cx, StackFrame *start)
fprintf(stderr, " flags:");
if (fp->isConstructing())
fprintf(stderr, " constructing");
if (fp->hasOverriddenArgs())
fprintf(stderr, " overridden_args");
if (fp->isDebuggerFrame())
fprintf(stderr, " debugger");
if (fp->isEvalFrame())

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

@ -434,7 +434,7 @@ struct JSObject : public js::ObjectImpl
js::gc::AllocKind kind,
js::HandleShape shape,
js::HandleTypeObject type,
js::HeapValue *slots);
js::HeapSlot *slots);
/* Make a dense array object with the specified initial state. */
static inline JSObject *createDenseArray(JSContext *cx,
@ -546,9 +546,12 @@ struct JSObject : public js::ObjectImpl
* Get internal pointers to the range of values starting at start and
* running for length.
*/
void getSlotRange(size_t start, size_t length,
js::HeapValue **fixedStart, js::HeapValue **fixedEnd,
js::HeapValue **slotsStart, js::HeapValue **slotsEnd);
inline void getSlotRangeUnchecked(size_t start, size_t length,
js::HeapSlot **fixedStart, js::HeapSlot **fixedEnd,
js::HeapSlot **slotsStart, js::HeapSlot **slotsEnd);
inline void getSlotRange(size_t start, size_t length,
js::HeapSlot **fixedStart, js::HeapSlot **fixedEnd,
js::HeapSlot **slotsStart, js::HeapSlot **slotsEnd);
public:
/* Accessors for properties. */
@ -560,7 +563,7 @@ struct JSObject : public js::ObjectImpl
inline size_t dynamicSlotIndex(size_t slot);
/* Get a raw pointer to the object's properties. */
inline const js::HeapValue *getRawSlots();
inline const js::HeapSlot *getRawSlots();
/*
* Grow or shrink slots immediately before changing the slot span.
@ -620,14 +623,16 @@ struct JSObject : public js::ObjectImpl
bool slotInRange(uintN slot, SentinelAllowed sentinel = SENTINEL_NOT_ALLOWED) const;
#endif
js::HeapValue *getSlotAddressUnchecked(uintN slot) {
private:
js::HeapSlot *getSlotAddressUnchecked(uintN slot) {
size_t fixed = numFixedSlots();
if (slot < fixed)
return fixedSlots() + slot;
return slots + (slot - fixed);
}
js::HeapValue *getSlotAddress(uintN slot) {
public:
js::HeapSlot *getSlotAddress(uintN slot) {
/*
* This can be used to get the address of the end of the slots for the
* object, which may be necessary when fetching zero-length arrays of
@ -637,12 +642,12 @@ struct JSObject : public js::ObjectImpl
return getSlotAddressUnchecked(slot);
}
js::HeapValue &getSlotRef(uintN slot) {
js::HeapSlot &getSlotRef(uintN slot) {
JS_ASSERT(slotInRange(slot));
return *getSlotAddress(slot);
}
inline js::HeapValue &nativeGetSlotRef(uintN slot);
inline js::HeapSlot &nativeGetSlotRef(uintN slot);
const js::Value &getSlot(uintN slot) const {
JS_ASSERT(slotInRange(slot));
@ -663,12 +668,13 @@ struct JSObject : public js::ObjectImpl
inline void nativeSetSlotWithType(JSContext *cx, const js::Shape *shape, const js::Value &value);
inline const js::Value &getReservedSlot(uintN index) const;
inline js::HeapValue &getReservedSlotRef(uintN index);
inline js::HeapSlot &getReservedSlotRef(uintN index);
inline void initReservedSlot(uintN index, const js::Value &v);
inline void setReservedSlot(uintN index, const js::Value &v);
/* For slots which are known to always be fixed, due to the way they are allocated. */
js::HeapValue &getFixedSlotRef(uintN slot) {
js::HeapSlot &getFixedSlotRef(uintN slot) {
JS_ASSERT(slot < numFixedSlots());
return fixedSlots()[slot];
}
@ -834,7 +840,7 @@ struct JSObject : public js::ObjectImpl
inline void setDenseArrayLength(uint32_t length);
inline void setDenseArrayInitializedLength(uint32_t length);
inline void ensureDenseArrayInitializedLength(JSContext *cx, uintN index, uintN extra);
inline js::HeapValueArray getDenseArrayElements();
inline js::HeapSlotArray getDenseArrayElements();
inline const js::Value &getDenseArrayElement(uintN idx);
inline void setDenseArrayElement(uintN idx, const js::Value &val);
inline void initDenseArrayElement(uintN idx, const js::Value &val);

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

@ -101,7 +101,7 @@ JSObject::privateRef(uint32_t nfixed) const
*/
JS_ASSERT(nfixed == numFixedSlots());
JS_ASSERT(hasPrivate());
js::HeapValue *end = &fixedSlots()[nfixed];
js::HeapSlot *end = &fixedSlots()[nfixed];
return *reinterpret_cast<void**>(end);
}
@ -406,7 +406,7 @@ JSObject::canRemoveLastProperty()
&& previous->getObjectFlags() == lastProperty()->getObjectFlags();
}
inline const js::HeapValue *
inline const js::HeapSlot *
JSObject::getRawSlots()
{
JS_ASSERT(isGlobal());
@ -420,7 +420,7 @@ JSObject::getReservedSlot(uintN index) const
return getSlot(index);
}
inline js::HeapValue &
inline js::HeapSlot &
JSObject::getReservedSlotRef(uintN index)
{
JS_ASSERT(index < JSSLOT_FREE(getClass()));
@ -434,6 +434,13 @@ JSObject::setReservedSlot(uintN index, const js::Value &v)
setSlot(index, v);
}
inline void
JSObject::initReservedSlot(uintN index, const js::Value &v)
{
JS_ASSERT(index < JSSLOT_FREE(getClass()));
initSlot(index, v);
}
inline bool
JSObject::hasContiguousSlots(size_t start, size_t count) const
{
@ -449,7 +456,7 @@ inline void
JSObject::prepareSlotRangeForOverwrite(size_t start, size_t end)
{
for (size_t i = start; i < end; i++)
getSlotAddressUnchecked(i)->js::HeapValue::~HeapValue();
getSlotAddressUnchecked(i)->js::HeapSlot::~HeapSlot();
}
inline void
@ -458,7 +465,7 @@ JSObject::prepareElementRangeForOverwrite(size_t start, size_t end)
JS_ASSERT(isDenseArray());
JS_ASSERT(end <= getDenseArrayInitializedLength());
for (size_t i = start; i < end; i++)
elements[i].js::HeapValue::~HeapValue();
elements[i].js::HeapSlot::~HeapSlot();
}
inline uint32_t
@ -529,11 +536,11 @@ JSObject::ensureElements(JSContext *cx, uint32_t capacity)
return true;
}
inline js::HeapValueArray
inline js::HeapSlotArray
JSObject::getDenseArrayElements()
{
JS_ASSERT(isDenseArray());
return js::HeapValueArray(elements);
return js::HeapSlotArray(elements);
}
inline const js::Value &
@ -547,14 +554,14 @@ inline void
JSObject::setDenseArrayElement(uintN idx, const js::Value &val)
{
JS_ASSERT(isDenseArray() && idx < getDenseArrayInitializedLength());
elements[idx] = val;
elements[idx].set(this, idx, val);
}
inline void
JSObject::initDenseArrayElement(uintN idx, const js::Value &val)
{
JS_ASSERT(isDenseArray() && idx < getDenseArrayInitializedLength());
elements[idx].init(val);
elements[idx].init(this, idx, val);
}
inline void
@ -577,7 +584,7 @@ JSObject::copyDenseArrayElements(uintN dstStart, const js::Value *src, uintN cou
JS_ASSERT(dstStart + count <= getDenseArrayCapacity());
JSCompartment *comp = compartment();
for (unsigned i = 0; i < count; ++i)
elements[dstStart + i].set(comp, src[i]);
elements[dstStart + i].set(comp, this, dstStart + i, src[i]);
}
inline void
@ -586,7 +593,7 @@ JSObject::initDenseArrayElements(uintN dstStart, const js::Value *src, uintN cou
JS_ASSERT(dstStart + count <= getDenseArrayCapacity());
JSCompartment *comp = compartment();
for (unsigned i = 0; i < count; ++i)
elements[dstStart + i].init(comp, src[i]);
elements[dstStart + i].init(comp, this, dstStart + i, src[i]);
}
inline void
@ -607,20 +614,21 @@ JSObject::moveDenseArrayElements(uintN dstStart, uintN srcStart, uintN count)
* write barrier is invoked here on B, despite the fact that it exists in
* the array before and after the move.
*/
if (compartment()->needsBarrier()) {
JSCompartment *comp = compartment();
if (comp->needsBarrier()) {
if (dstStart < srcStart) {
js::HeapValue *dst = elements + dstStart;
js::HeapValue *src = elements + srcStart;
js::HeapSlot *dst = elements + dstStart;
js::HeapSlot *src = elements + srcStart;
for (unsigned i = 0; i < count; i++, dst++, src++)
*dst = *src;
dst->set(comp, this, dst - elements, *src);
} else {
js::HeapValue *dst = elements + dstStart + count - 1;
js::HeapValue *src = elements + srcStart + count - 1;
js::HeapSlot *dst = elements + dstStart + count - 1;
js::HeapSlot *src = elements + srcStart + count - 1;
for (unsigned i = 0; i < count; i++, dst--, src--)
*dst = *src;
dst->set(comp, this, dst - elements, *src);
}
} else {
memmove(elements + dstStart, elements + srcStart, count * sizeof(js::Value));
memmove(elements + dstStart, elements + srcStart, count * sizeof(js::HeapSlot));
}
}
@ -970,6 +978,42 @@ JSObject::isQName() const
|| hasClass(&js::AnyNameClass);
}
inline void
JSObject::getSlotRangeUnchecked(size_t start, size_t length,
js::HeapSlot **fixedStart, js::HeapSlot **fixedEnd,
js::HeapSlot **slotsStart, js::HeapSlot **slotsEnd)
{
JS_ASSERT(!isDenseArray());
size_t fixed = numFixedSlots();
if (start < fixed) {
if (start + length < fixed) {
*fixedStart = &fixedSlots()[start];
*fixedEnd = &fixedSlots()[start + length];
*slotsStart = *slotsEnd = NULL;
} else {
size_t localCopy = fixed - start;
*fixedStart = &fixedSlots()[start];
*fixedEnd = &fixedSlots()[start + localCopy];
*slotsStart = &slots[0];
*slotsEnd = &slots[length - localCopy];
}
} else {
*fixedStart = *fixedEnd = NULL;
*slotsStart = &slots[start - fixed];
*slotsEnd = &slots[start - fixed + length];
}
}
inline void
JSObject::getSlotRange(size_t start, size_t length,
js::HeapSlot **fixedStart, js::HeapSlot **fixedEnd,
js::HeapSlot **slotsStart, js::HeapSlot **slotsEnd)
{
JS_ASSERT(slotInRange(start + length, SENTINEL_ALLOWED));
getSlotRangeUnchecked(start, length, fixedStart, fixedEnd, slotsStart, slotsEnd);
}
inline void
JSObject::initializeSlotRange(size_t start, size_t length)
{
@ -977,24 +1021,20 @@ JSObject::initializeSlotRange(size_t start, size_t length)
* No bounds check, as this is used when the object's shape does not
* reflect its allocated slots (updateSlotsForSpan).
*/
JS_ASSERT(!isDenseArray());
size_t fixed = numFixedSlots();
if (start < fixed) {
if (start + length < fixed) {
js::InitValueRange(fixedSlots() + start, length, false);
} else {
size_t localClear = fixed - start;
js::InitValueRange(fixedSlots() + start, localClear, false);
js::InitValueRange(slots, length - localClear, false);
}
} else {
js::InitValueRange(slots + start - fixed, length, false);
}
js::HeapSlot *fixedStart, *fixedEnd, *slotsStart, *slotsEnd;
getSlotRangeUnchecked(start, length, &fixedStart, &fixedEnd, &slotsStart, &slotsEnd);
JSCompartment *comp = compartment();
size_t offset = start;
for (js::HeapSlot *sp = fixedStart; sp != fixedEnd; sp++)
sp->init(comp, this, offset++, js::UndefinedValue());
for (js::HeapSlot *sp = slotsStart; sp != slotsEnd; sp++)
sp->init(comp, this, offset++, js::UndefinedValue());
}
/* static */ inline JSObject *
JSObject::create(JSContext *cx, js::gc::AllocKind kind,
js::HandleShape shape, js::HandleTypeObject type, js::HeapValue *slots)
js::HandleShape shape, js::HandleTypeObject type, js::HeapSlot *slots)
{
/*
* Callers must use dynamicSlotsCount to size the initial slot array of the
@ -1102,7 +1142,7 @@ JSObject::slotSpan() const
return lastProperty()->slotSpan();
}
inline js::HeapValue &
inline js::HeapSlot &
JSObject::nativeGetSlotRef(uintN slot)
{
JS_ASSERT(isNative());
@ -1344,7 +1384,7 @@ inline JSBool
JSObject::getGenericAttributes(JSContext *cx, jsid id, uintN *attrsp)
{
js::GenericAttributesOp op = getOps()->getGenericAttributes;
return (op ? op : js_GetAttributes)(cx, this, id, attrsp);
return (op ? op : js_GetAttributes)(cx, this, id, attrsp);
}
inline JSBool
@ -1813,13 +1853,13 @@ NewObjectGCKind(JSContext *cx, js::Class *clasp)
* may or may not need dynamic slots.
*/
inline bool
PreallocateObjectDynamicSlots(JSContext *cx, Shape *shape, HeapValue **slots)
PreallocateObjectDynamicSlots(JSContext *cx, Shape *shape, HeapSlot **slots)
{
if (size_t count = JSObject::dynamicSlotsCount(shape->numFixedSlots(), shape->slotSpan())) {
*slots = (HeapValue *) cx->malloc_(count * sizeof(HeapValue));
*slots = (HeapSlot *) cx->malloc_(count * sizeof(HeapSlot));
if (!*slots)
return false;
Debug_SetValueRangeToCrashOnTouch(*slots, count);
Debug_SetSlotRangeToCrashOnTouch(*slots, count);
return true;
}
*slots = NULL;
@ -1969,7 +2009,7 @@ inline void
JSObject::setSlot(uintN slot, const js::Value &value)
{
JS_ASSERT(slotInRange(slot));
getSlotRef(slot).set(compartment(), value);
getSlotRef(slot).set(this, slot, value);
}
inline void
@ -1983,21 +2023,21 @@ JSObject::initSlot(uintN slot, const js::Value &value)
inline void
JSObject::initSlotUnchecked(uintN slot, const js::Value &value)
{
getSlotAddressUnchecked(slot)->init(value);
getSlotAddressUnchecked(slot)->init(this, slot, value);
}
inline void
JSObject::setFixedSlot(uintN slot, const js::Value &value)
{
JS_ASSERT(slot < numFixedSlots());
fixedSlots()[slot] = value;
fixedSlots()[slot].set(this, slot, value);
}
inline void
JSObject::initFixedSlot(uintN slot, const js::Value &value)
{
JS_ASSERT(slot < numFixedSlots());
fixedSlots()[slot].init(value);
fixedSlots()[slot].init(this, slot, value);
}
#endif /* jsobjinlines_h___ */

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

@ -59,7 +59,7 @@
using namespace js;
using namespace js::gc;
static inline HeapValue &
static inline HeapSlot &
GetCall(JSObject *proxy)
{
JS_ASSERT(IsFunctionProxy(proxy));
@ -74,7 +74,7 @@ GetConstruct(JSObject *proxy)
return proxy->getSlot(JSSLOT_PROXY_CONSTRUCT);
}
static inline HeapValue &
static inline HeapSlot &
GetFunctionProxyConstruct(JSObject *proxy)
{
JS_ASSERT(IsFunctionProxy(proxy));
@ -1248,12 +1248,12 @@ static void
proxy_TraceObject(JSTracer *trc, JSObject *obj)
{
GetProxyHandler(obj)->trace(trc, obj);
MarkCrossCompartmentValue(trc, &obj->getReservedSlotRef(JSSLOT_PROXY_PRIVATE), "private");
MarkCrossCompartmentValue(trc, &obj->getReservedSlotRef(JSSLOT_PROXY_EXTRA + 0), "extra0");
MarkCrossCompartmentValue(trc, &obj->getReservedSlotRef(JSSLOT_PROXY_EXTRA + 1), "extra1");
MarkCrossCompartmentSlot(trc, &obj->getReservedSlotRef(JSSLOT_PROXY_PRIVATE), "private");
MarkCrossCompartmentSlot(trc, &obj->getReservedSlotRef(JSSLOT_PROXY_EXTRA + 0), "extra0");
MarkCrossCompartmentSlot(trc, &obj->getReservedSlotRef(JSSLOT_PROXY_EXTRA + 1), "extra1");
if (IsFunctionProxy(obj)) {
MarkCrossCompartmentValue(trc, &GetCall(obj), "call");
MarkCrossCompartmentValue(trc, &GetFunctionProxyConstruct(obj), "construct");
MarkCrossCompartmentSlot(trc, &GetCall(obj), "call");
MarkCrossCompartmentSlot(trc, &GetFunctionProxyConstruct(obj), "construct");
}
}
@ -1261,8 +1261,8 @@ static void
proxy_TraceFunction(JSTracer *trc, JSObject *obj)
{
proxy_TraceObject(trc, obj);
MarkCrossCompartmentValue(trc, &GetCall(obj), "call");
MarkCrossCompartmentValue(trc, &GetFunctionProxyConstruct(obj), "construct");
MarkCrossCompartmentSlot(trc, &GetCall(obj), "call");
MarkCrossCompartmentSlot(trc, &GetFunctionProxyConstruct(obj), "construct");
}
static JSBool

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

@ -98,9 +98,9 @@ Bindings::lookup(JSContext *cx, JSAtom *name, uintN *indexp) const
if (indexp)
*indexp = shape->shortid();
if (shape->getter() == GetCallArg)
if (shape->getter() == CallObject::getArgOp)
return ARGUMENT;
if (shape->getter() == GetCallUpvar)
if (shape->getter() == CallObject::getUpvarOp)
return UPVAR;
return shape->writable() ? VARIABLE : CONSTANT;
@ -128,13 +128,13 @@ Bindings::add(JSContext *cx, JSAtom *name, BindingKind kind)
JS_ASSERT(nvars == 0);
JS_ASSERT(nupvars == 0);
indexp = &nargs;
getter = GetCallArg;
setter = SetCallArg;
getter = CallObject::getArgOp;
setter = CallObject::setArgOp;
slot += nargs;
} else if (kind == UPVAR) {
indexp = &nupvars;
getter = GetCallUpvar;
setter = SetCallUpvar;
getter = CallObject::getUpvarOp;
setter = CallObject::setUpvarOp;
slot = lastBinding->maybeSlot();
attrs |= JSPROP_SHARED;
} else {
@ -142,8 +142,8 @@ Bindings::add(JSContext *cx, JSAtom *name, BindingKind kind)
JS_ASSERT(nupvars == 0);
indexp = &nvars;
getter = GetCallVar;
setter = SetCallVar;
getter = CallObject::getVarOp;
setter = CallObject::setVarOp;
if (kind == CONSTANT)
attrs |= JSPROP_READONLY;
slot += nargs + nvars;
@ -248,9 +248,9 @@ Bindings::getLocalNameArray(JSContext *cx, Vector<JSAtom *> *namesp)
const Shape &shape = r.front();
uintN index = uint16_t(shape.shortid());
if (shape.getter() == GetCallArg) {
if (shape.getter() == CallObject::getArgOp) {
JS_ASSERT(index < nargs);
} else if (shape.getter() == GetCallUpvar) {
} else if (shape.getter() == CallObject::getUpvarOp) {
JS_ASSERT(index < nupvars);
index += nargs + nvars;
} else {
@ -262,7 +262,7 @@ Bindings::getLocalNameArray(JSContext *cx, Vector<JSAtom *> *namesp)
names[index] = JSID_TO_ATOM(shape.propid());
} else {
JS_ASSERT(JSID_IS_INT(shape.propid()));
JS_ASSERT(shape.getter() == GetCallArg);
JS_ASSERT(shape.getter() == CallObject::getArgOp);
names[index] = NULL;
}
}
@ -282,7 +282,7 @@ Bindings::lastArgument() const
const js::Shape *shape = lastVariable();
if (nvars > 0) {
while (shape->previous() && shape->getter() != GetCallArg)
while (shape->previous() && shape->getter() != CallObject::getArgOp)
shape = shape->previous();
}
return shape;
@ -295,7 +295,7 @@ Bindings::lastVariable() const
const js::Shape *shape = lastUpvar();
if (nupvars > 0) {
while (shape->getter() == GetCallUpvar)
while (shape->getter() == CallObject::getUpvarOp)
shape = shape->previous();
}
return shape;
@ -1433,10 +1433,10 @@ JS_FRIEND_API(void)
js_CallNewScriptHook(JSContext *cx, JSScript *script, JSFunction *fun)
{
JS_ASSERT(!script->callDestroyHook);
if (JSNewScriptHook hook = cx->debugHooks->newScriptHook) {
if (JSNewScriptHook hook = cx->runtime->debugHooks.newScriptHook) {
AutoKeepAtoms keep(cx->runtime);
hook(cx, script->filename, script->lineno, script, fun,
cx->debugHooks->newScriptHookData);
cx->runtime->debugHooks.newScriptHookData);
}
script->callDestroyHook = true;
}
@ -1447,8 +1447,8 @@ js_CallDestroyScriptHook(JSContext *cx, JSScript *script)
if (!script->callDestroyHook)
return;
if (JSDestroyScriptHook hook = cx->debugHooks->destroyScriptHook)
hook(cx, script, cx->debugHooks->destroyScriptHookData);
if (JSDestroyScriptHook hook = cx->runtime->debugHooks.destroyScriptHook)
hook(cx, script, cx->runtime->debugHooks.destroyScriptHookData);
script->callDestroyHook = false;
JS_ClearScriptTraps(cx, script);
}

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

@ -1099,7 +1099,7 @@ class TypedArrayTemplate
static void
obj_trace(JSTracer *trc, JSObject *obj)
{
MarkValue(trc, &obj->getFixedSlotRef(FIELD_BUFFER), "typedarray.buffer");
MarkSlot(trc, &obj->getFixedSlotRef(FIELD_BUFFER), "typedarray.buffer");
}
static JSBool

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

@ -286,6 +286,7 @@ typedef enum JSWhyMagic
JS_ARG_POISON, /* used in debug builds to catch tracing errors */
JS_SERIALIZE_NO_NODE, /* an empty subnode in the AST serializer */
JS_LAZY_ARGUMENTS, /* lazy arguments value on the stack */
JS_UNASSIGNED_ARGUMENTS, /* the initial value of callobj.arguments */
JS_IS_CONSTRUCTING, /* magic value passed to natives to indicate construction */
JS_GENERIC_MAGIC /* for local use */
} JSWhyMagic;

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

@ -102,6 +102,30 @@ WeakMapBase::resetWeakMapList(JSRuntime *rt)
}
}
bool
WeakMapBase::saveWeakMapList(JSRuntime *rt, WeakMapVector &vector)
{
WeakMapBase *m = rt->gcWeakMapList;
while (m) {
if (!vector.append(m))
return false;
m = m->next;
}
return true;
}
void
WeakMapBase::restoreWeakMapList(JSRuntime *rt, WeakMapVector &vector)
{
JS_ASSERT(!rt->gcWeakMapList);
for (WeakMapBase **p = vector.begin(); p != vector.end(); p++) {
WeakMapBase *m = *p;
JS_ASSERT(m->next == WeakMapNotInList);
m->next = rt->gcWeakMapList;
rt->gcWeakMapList = m;
}
}
} /* namespace js */
typedef WeakMap<HeapPtr<JSObject>, HeapValue> ObjectValueMap;

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше