This commit is contained in:
Kyle Huey 2011-07-06 09:17:52 -07:00
Родитель 80bbb705f9 b7858d4918
Коммит f51605d70a
177 изменённых файлов: 4951 добавлений и 1732 удалений

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

@ -54,8 +54,12 @@ EXTENSIONS = \
$(NULL)
define _INSTALL_EXTENSION
cd $(srcdir)/$(dir) && \
$(ZIP) -r9XD $(DISTROEXT)/$(dir).xpi *
$(NSINSTALL) -D $(dir) && \
$(PYTHON) $(MOZILLA_DIR)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $(srcdir)/$(dir)/install.rdf.in > $(dir)/install.rdf && \
cd $(dir) && \
$(ZIP) -r9XD $(DISTROEXT)/$(dir).xpi install.rdf && \
cd $(srcdir)/$(dir) && \
$(ZIP) -r9XD $(DISTROEXT)/$(dir).xpi * -x install.rdf.in
endef # do not remove the blank line!

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

@ -1,5 +1,7 @@
<?xml version="1.0"?>
#filter substitution
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
@ -13,7 +15,7 @@
<Description>
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
<em:minVersion>3.5</em:minVersion>
<em:maxVersion>6.0</em:maxVersion>
<em:maxVersion>@FIREFOX_VERSION@</em:maxVersion>
</Description>
</em:targetApplication>

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

@ -643,6 +643,9 @@ var Scratchpad = {
this._tabCharacter = expandtab ? (new Array(tabsize + 1)).join(" ") : "\t";
this.textbox.style.MozTabSize = tabsize;
// Force LTR direction (otherwise the textbox inherits the locale direction)
this.textbox.style.direction = "ltr";
this.insertIntro();
// Make the Tab key work.

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

@ -191,9 +191,8 @@ function folderToJSON(aItemId) {
* like dates.
*/
function compareJSON(aNodeJSON_1, aNodeJSON_2) {
let JSON = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON);
node1 = JSON.decode(aNodeJSON_1);
node2 = JSON.decode(aNodeJSON_2);
let node1 = JSON.parse(aNodeJSON_1);
let node2 = JSON.parse(aNodeJSON_2);
// List of properties we should not compare (expected to be different).
const SKIP_PROPS = ["dateAdded", "lastModified", "id"];

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

@ -92,6 +92,10 @@ ifdef WIN32_OLD_STYLE_JEMALLOC
DEFINES += -DWIN32_OLD_STYLE_JEMALLOC=1
endif
ifneq (,$(filter aurora beta,$(MOZ_UPDATE_CHANNEL)))
DEFINES += -DSHIP_FEEDBACK=1
endif
ifdef MOZ_PKG_MANIFEST_P
MOZ_PKG_MANIFEST = package-manifest

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

@ -10,12 +10,6 @@
#filter substitution
#if MOZ_UPDATE_CHANNEL == aurora
#define SHIP_FEEDBACK
#elif MOZ_UPDATE_CHANNEL == beta
#define SHIP_FEEDBACK
#endif
#ifdef XP_MACOSX
; Mac bundle stuff
@APPNAME@/Contents/Info.plist

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

@ -3,11 +3,6 @@
# These files are in alphabetical order, except that files removed only on
# certain platforms are after all of the regular files and obsolete Talkback and
# Inspector files are at the very end.
#if MOZ_UPDATE_CHANNEL == aurora
#define SHIP_FEEDBACK
#elif MOZ_UPDATE_CHANNEL == beta
#define SHIP_FEEDBACK
#endif
.autoreg
@DLL_PREFIX@jsj@DLL_SUFFIX@
@DLL_PREFIX@sqlite3@DLL_SUFFIX@
@ -960,6 +955,7 @@ xpicleanup@BIN_SUFFIX@
modules/PluralForm.jsm
modules/PopupNotifications.jsm
modules/PropertyPanel.jsm
modules/reflect.jsm
modules/Services.jsm
modules/services-sync/auth.js
modules/services-sync/base_records/collection.js

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

@ -215,9 +215,7 @@ nsFrameMessageManager::GetParamsForMessage(nsAString& aMessageName,
if (argc >= 2) {
jsval v = argv[1];
if (JS_TryJSON(ctx, &v)) {
JS_Stringify(ctx, &v, nsnull, JSVAL_NULL, JSONCreator, &aJSON);
}
JS_Stringify(ctx, &v, nsnull, JSVAL_NULL, JSONCreator, &aJSON);
}
return NS_OK;
}
@ -455,8 +453,7 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
funval, 1, argv.jsval_addr(), &rval);
if (aJSONRetVal) {
nsString json;
if (JS_TryJSON(ctx, &rval) &&
JS_Stringify(ctx, &rval, nsnull, JSVAL_NULL,
if (JS_Stringify(ctx, &rval, nsnull, JSVAL_NULL,
JSONCreator, &json)) {
aJSONRetVal->AppendElement(json);
}

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

@ -1314,11 +1314,12 @@ void
nsScriptLoader::PreloadURI(nsIURI *aURI, const nsAString &aCharset,
const nsAString &aType)
{
nsRefPtr<nsScriptLoadRequest> request = new nsScriptLoadRequest(nsnull, 0);
if (!request) {
// Check to see if scripts has been turned off.
if (!mEnabled || !mDocument->IsScriptEnabled()) {
return;
}
nsRefPtr<nsScriptLoadRequest> request = new nsScriptLoadRequest(nsnull, 0);
request->mURI = aURI;
request->mIsInline = PR_FALSE;
request->mLoading = PR_TRUE;

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

@ -23,6 +23,18 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=666604
SimpleTest.waitForExplicitFinish();
function hitEventLoop(times, next)
{
if (times == 0) {
next();
return;
}
SimpleTest.executeSoon(function() {
hitEventLoop(times - 1, next);
});
}
var activationListener;
function dispatchClick(target, ctrl) {
@ -71,7 +83,7 @@ function test3() {
test4();
}
dispatchClick(testlink, true);
setTimeout(test4, 1000);
hitEventLoop(10, test4);
}
function test4() {
@ -81,7 +93,7 @@ function test4() {
test5();
}
dispatchReturn(testlink, true);
setTimeout(test5, 1000);
hitEventLoop(10, test5);
}
function test5() {
@ -102,18 +114,36 @@ function test6() {
dispatchDOMActivate(testlink);
}
var oldPref;
function test7() {
oldPref = SpecialPowers.getBoolPref("dom.disable_open_during_load");
SpecialPowers.setBoolPref("dom.disable_open_during_load", false);
testlink.href = "javascript:opener.activationListener(); window.close();";
testlink.target = "_blank";
activationListener =
function() {
ok(true, "Click() should activate a link");
setTimeout(test9, 0);
setTimeout(test8, 0);
}
testlink.click();
}
function test8() {
SpecialPowers.setBoolPref("dom.disable_open_during_load", true);
testlink.href = "javascript:opener.activationListener(); window.close();";
testlink.target = "_blank";
activationListener =
function() {
ok(false, "Click() should not activate a link");
setTimeout(test9, 0);
}
testlink.click();
hitEventLoop(10, test9);
}
function test9() {
SpecialPowers.setBoolPref("dom.disable_open_during_load", oldPref);
SimpleTest.finish();
}

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

@ -907,6 +907,8 @@ nsHTMLInputElement::AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
UpdateTooLongValidityState();
} else if (aName == nsGkAtoms::pattern) {
UpdatePatternMismatchValidityState();
} else if (aName == nsGkAtoms::multiple) {
UpdateTypeMismatchValidityState();
}
UpdateEditableState(aNotify);

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

@ -241,7 +241,6 @@ _TEST_FILES = \
test_bug297761.html \
file_bug297761.html \
test_bug607145.html \
test_bug601061.html \
test_bug596511.html \
reflect.js \
test_bug611189.html \
@ -262,7 +261,6 @@ _TEST_FILES = \
test_bug622558.html \
test_bug622597.html \
test_bug636336.html \
test_bug630889.html \
test_bug610212.html \
test_bug633058.html \
test_bug641219.html \

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

@ -58,6 +58,7 @@ _TEST_FILES = \
test_label_control_attribute.html \
test_output_element.html \
test_button_attributes_reflection.html \
test_textarea_attributes_reflection.html \
$(NULL)
libs:: $(_TEST_FILES)

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

@ -21,11 +21,13 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=551670
/** Test for Bug 551670 **/
// .type
reflectLimitedEnumerated(document.createElement("button"),
"type",
[ "submit", "reset", "button" ],
[ "this-is-probably-a-wrong-type", "", "tulip" ],
"submit");
reflectLimitedEnumerated({
element: document.createElement("button"),
attribute: "type",
validValues: [ "submit", "reset", "button" ],
invalidValues: [ "this-is-probably-a-wrong-type", "", "tulip" ],
defaultValue: "submit",
});
</script>
</pre>

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

@ -1,38 +1,44 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=551670
-->
<head>
<title>Test for Bug 551670</title>
<title>Test for HTMLInputElement attributes reflection</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="../reflect.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=551670">Mozilla Bug 551670</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 551670 **/
/** Test for HTMLInputElement attributes reflection **/
// TODO: maybe make those reflections be tested against all input types.
// .accept
reflectString(document.createElement("input"), "accept",
[ "audio/*", "video/*", "image/*", "image/png",
"application/msword", "appplication/pdf" ]);
reflectString({
element: document.createElement("input"),
attribute: "accept",
otherValues: [ "audio/*", "video/*", "image/*", "image/png",
"application/msword", "appplication/pdf" ],
});
// .alt
reflectString(document.createElement("input"), "alt");
reflectString({
element: document.createElement("input"),
attribute: "alt",
});
// .autocomplete
reflectLimitedEnumerated(document.createElement("input"), "autocomplete",
[ "on", "off" ], [ "", "default", "foo", "tulip" ]);
reflectLimitedEnumerated({
element: document.createElement("input"),
attribute: "autocomplete",
validValues: [ "on", "off" ],
invalidValues: [ "", "default", "foo", "tulip" ],
});
// TODO: autofocus (boolean)
// TODO: defaultChecked (boolean)
@ -44,21 +50,32 @@ reflectLimitedEnumerated(document.createElement("input"), "autocomplete",
// TODO: formAction (URL)
// .formEnctype
reflectLimitedEnumerated(document.createElement("input"), "formEnctype",
[ "application/x-www-form-urlencoded",
"multipart/form-data", "text/plain" ],
[ "", "foo", "tulip", "multipart/foo" ],
"application/x-www-form-urlencoded");
reflectLimitedEnumerated({
element: document.createElement("input"),
attribute: "formEnctype",
validValues: [ "application/x-www-form-urlencoded", "multipart/form-data",
"text/plain" ],
invalidValues: [ "", "foo", "tulip", "multipart/foo" ],
defaultValue: "application/x-www-form-urlencoded"
});
// .formMethod
reflectLimitedEnumerated(document.createElement("input"), "formMethod",
[ "get", "post" ], [ "", "foo", "tulip" ], "get");
reflectLimitedEnumerated({
element: document.createElement("input"),
attribute: "formMethod",
validValues: [ "get", "post" ],
invalidValues: [ "", "foo", "tulip" ],
defaultValue: "get"
});
// TODO: formNoValidate (boolean)
// .formTarget
reflectString(document.createElement("input"), "formTarget",
[ "_blank", "_self", "_parent", "_top" ]);
reflectString({
element: document.createElement("input"),
attribute: "formTarget",
otherValues: [ "_blank", "_self", "_parent", "_top" ],
});
// TODO: height (non-negative integer)
// TODO: indeterminate (boolean)
@ -69,35 +86,60 @@ reflectString(document.createElement("input"), "formTarget",
// TODO: multiple (boolean)
// .name
reflectString(document.createElement("input"), "name",
[ "isindex", "_charset_" ]);
reflectString({
element: document.createElement("input"),
attribute: "name",
otherValues: [ "isindex", "_charset_" ],
});
// .pattern
reflectString(document.createElement("input"), "pattern",
[ "[0-9][A-Z]{3}" ]);
reflectString({
element: document.createElement("input"),
attribute: "pattern",
otherValues: [ "[0-9][A-Z]{3}" ],
});
// .placeholder
reflectString(document.createElement("input"), "placeholder",
[ "foo\nbar", "foo\rbar", "foo\r\nbar" ]);
reflectString({
element: document.createElement("input"),
attribute: "placeholder",
otherValues: [ "foo\nbar", "foo\rbar", "foo\r\nbar" ],
});
// TODO: readOnly (boolean)
// TODO: required (boolean)
// TODO: size (unsigned long)
// .size
reflectUnsignedInt({
element: document.createElement("input"),
attribute: "size",
nonZero: true,
defaultValue: 20,
});
// TODO: src (URL)
// TODO: step (not implemented)
// .type
reflectLimitedEnumerated(document.createElement("input"),
"type",
[ "hidden", "text", "search", "tel", "url", "email",
"password", "checkbox", "radio", "file", "submit",
"image", "reset", "button" ],
[ "this-is-probably-a-wrong-type", "", "tulip" ],
"text",
[ "datetime", "date", "month", "week", "time",
"datetime-local", "number", "range", "color" ]);
reflectLimitedEnumerated({
element: document.createElement("input"),
attribute: "type",
validValues: [ "hidden", "text", "search", "tel", "url", "email", "password",
"checkbox", "radio", "file", "submit", "image", "reset",
"button" ],
invalidValues: [ "this-is-probably-a-wrong-type", "", "tulip" ],
defaultValue: "text",
unsupportedValues: [ "datetime", "date", "month", "week", "time",
"datetime-local", "number", "range", "color" ]
});
// .defaultValue
reflectString({
element: document.createElement("input"),
attribute: { idl: "defaultValue", content: "value" },
otherValues: [ "foo\nbar", "foo\rbar", "foo\r\nbar" ],
});
// TODO: defaultValue (reflects @value)
// .value doesn't reflect a content attribute.
// TODO: valueAsDate (not implemented)
// TODO: valueAsNumber (not implemented)

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

@ -2,20 +2,17 @@
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=555559
https://bugzilla.mozilla.org/show_bug.cgi?id=668817
-->
<head>
<title>Test for Bug 555559</title>
<title>Test for &lt;input type='email'&gt; validity</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<style>
input { background-color: rgb(0,0,0) !important; }
input:valid { background-color: rgb(0,255,0) !important; }
input:invalid { background-color: rgb(255,0,0) !important; }
</style>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=555559">Mozilla Bug 555559</a>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=668817">Mozilla Bug 668817</a>
<p id="display"></p>
<div id="content" style="display: none">
<form>
@ -25,9 +22,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=555559
<pre id="test">
<script type="application/javascript">
/** Test for Bug 555559 **/
// More checks are done in test_bug551670.html.
/** Test for <input type='email'> validity **/
var gInvalid = false;
@ -47,8 +42,7 @@ function checkValidEmailAddress(element)
ok(!gInvalid, "The invalid event should not have been thrown");
is(element.validationMessage, '',
"Validation message should be the empty string");
is(window.getComputedStyle(element, null).getPropertyValue('background-color'),
"rgb(0, 255, 0)", ":valid pseudo-class should apply");
ok(element.mozMatchesSelector(":valid"), ":valid pseudo-class should apply");
}
function checkInvalidEmailAddress(element)
@ -61,180 +55,133 @@ function checkInvalidEmailAddress(element)
ok(gInvalid, "The invalid event should have been thrown");
is(element.validationMessage, "Please enter an email address.",
"Validation message is not valid");
is(window.getComputedStyle(element, null).getPropertyValue('background-color'),
"rgb(255, 0, 0)", ":invalid pseudo-class should apply");
ok(element.mozMatchesSelector(":invalid"), ":invalid pseudo-class should apply");
}
function testEmailAddress(aElement, aValue, aMultiple, aValidity)
{
aElement.multiple = aMultiple;
aElement.value = aValue;
if (aValidity) {
checkValidEmailAddress(aElement);
} else {
checkInvalidEmailAddress(aElement);
}
}
var email = document.forms[0].elements[0];
is(email.type, 'email', "email state should be recognized");
// This is not really a valid email address
// but it should not be considered as invalid.
email.value = '';
checkValidEmailAddress(email);
// Simple values, checking the e-mail syntax validity.
var values = [
[ '', true ], // The empty string shouldn't be considered as invalid.
[ 'foo@bar.com', true ],
[ ' foo@bar.com', false ],
[ 'foo@bar.com ', false ],
[ 'tulip', false ],
// Some checks on the user part of the address.
[ '@bar.com', false ],
[ 'f\noo@bar.com', true ],
[ 'f\roo@bar.com', true ],
[ 'f\r\noo@bar.com', true ],
// Some checks for the domain part.
[ 'foo@bar', true ],
[ 'foo@b', true ],
[ 'foo@', false ],
[ 'foo@bar.', false ],
[ 'foo@foo.bar', true ],
[ 'foo@foo..bar', false ],
[ 'foo@.bar', false ],
[ 'foo@tulip.foo.bar', true ],
[ 'foo@tulip.foo-bar', true ],
[ 'foo@1.2', true ],
[ 'foo@127.0.0.1', true ],
[ 'foo@1.2.3', true ],
[ 'foo@b\nar.com', true ],
[ 'foo@b\rar.com', true ],
[ 'foo@b\r\nar.com', true ],
[ 'foo@.', false ],
];
email.value = 'foo@bar.com';
checkValidEmailAddress(email);
// Multiple values, we don't check e-mail validity, only multiple stuff.
var multipleValues = [
[ 'foo@bar.com, foo@bar.com', true ],
[ 'foo@bar.com,foo@bar.com', true ],
[ 'foo@bar.com,foo@bar.com,foo@bar.com', true ],
[ ' foo@bar.com , foo@bar.com ', true ],
[ '\tfoo@bar.com\t,\tfoo@bar.com\t', true ],
[ '\rfoo@bar.com\r,\rfoo@bar.com\r', true ],
[ '\nfoo@bar.com\n,\nfoo@bar.com\n', true ],
[ '\ffoo@bar.com\f,\ffoo@bar.com\f', true ],
[ '\t foo@bar.com\r,\nfoo@bar.com\f', true ],
[ 'foo@b,ar.com,foo@bar.com', false ],
[ 'foo@bar.com,foo@bar.com,', false ],
[ ' foo@bar.com , foo@bar.com , ', false ],
[ ',foo@bar.com,foo@bar.com', false ],
[ ',foo@bar.com,foo@bar.com', false ],
[ 'foo@bar.com,,,foo@bar.com', false ],
[ 'foo@bar.com;foo@bar.com', false ],
[ '<foo@bar.com>, <foo@bar.com>', false ],
[ 'foo@bar, foo@bar.com', true ],
[ 'foo@bar.com, foo', false ],
[ 'foo, foo@bar.com', false ],
];
email.value = ' foo@bar.com';
checkInvalidEmailAddress(email);
email.value = 'foo@bar.com ';
checkInvalidEmailAddress(email);
email.value = 'tulip';
checkInvalidEmailAddress(email);
// Some checks on the user part of the address.
email.value = '@bar.com';
checkInvalidEmailAddress(email);
/* Additional username checks. */
var legalCharacters = "abcdefghijklmnopqrstuvwxyz";
legalCharacters += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
legalCharacters += "0123456789";
legalCharacters += "!#$%&'*+-/=?^_`{|}~.";
for each (c in legalCharacters)
{
email.value = c + '@bar.com';
checkValidEmailAddress(email);
// Add all username legal characters individually to the list.
for each (c in legalCharacters) {
values.push([c + "@bar.com", true]);
}
// Add the concatenation of all legal characters too.
values.push([legalCharacters + "@bar.com", true]);
// Add username illegal characters, the same way.
var illegalCharacters = "()<>[]:;@\\, \t";
for each (c in illegalCharacters) {
values.push([illegalCharacters + "@bar.com", false]);
}
email.value = legalCharacters + '@bar.com';
checkValidEmailAddress(email);
/* Additional domain checks. */
// Checking stripped characters.
email.value = 'f\noo@bar.com';
checkValidEmailAddress(email);
legalCharacters = "abcdefghijklmnopqrstuvwxyz";
legalCharacters += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
legalCharacters += "0123456789";
legalCharacters += "-";
email.value = 'f\roo@bar.com';
checkValidEmailAddress(email);
// Add domain legal characters (except '.' because it's special).
for each (c in legalCharacters) {
values.push(["foo@foo.bar" + c, true]);
}
// Add the concatenation of all legal characters too.
values.push(["foo@bar.com" + legalCharacters, true]);
// Testing some illegal characters.
var illegalCharacters = "()<>[]:;@\, \t";
for each (c in illegalCharacters)
{
email.value = c + '@bar.com';
checkInvalidEmailAddress(email);
// Add domain illegal characters.
illegalCharacters = "()<>[]:;@\\,!#$%&'*+/=?^_`{|}~ \t";
for each (c in illegalCharacters) {
values.push(['foo@foo.bar' + c, false]);
}
// Some checks on the domain part of the address.
email.value = 'foo@bar';
checkValidEmailAddress(email);
values.forEach(function([value, valid]) {
testEmailAddress(email, value, false, valid);
});
email.value = 'foo@b';
checkValidEmailAddress(email);
multipleValues.forEach(function([value, valid]) {
testEmailAddress(email, value, true, valid);
});
email.value = 'foo@';
// Make sure setting multiple changes the value.
email.multiple = false;
email.value = "foo@bar.com, foo@bar.com";
checkInvalidEmailAddress(email);
email.value = 'foo@bar.';
checkInvalidEmailAddress(email);
email.value = 'foo@foo.bar';
checkValidEmailAddress(email);
email.value = 'foo@foo..bar';
checkInvalidEmailAddress(email);
email.value = 'foo@.bar';
checkInvalidEmailAddress(email);
email.value = 'foo@tulip.foo.bar';
checkValidEmailAddress(email);
email.value = 'foo@tulip.foo-bar';
checkValidEmailAddress(email);
email.value = 'foo@1.2';
checkValidEmailAddress(email);
email.value = 'foo@127.0.0.1';
checkValidEmailAddress(email);
email.value = 'foo@1.2.3.';
checkInvalidEmailAddress(email);
// Checking stripped characters.
email.value = 'foo@b\nar.com';
checkValidEmailAddress(email);
email.value = 'foo@b\rar.com';
checkValidEmailAddress(email);
// Testing some illegal characters.
illegalCharacters = "()<>[]:;@\,!#$%&'*+/=?^_`{|}~ \t";
for each (c in illegalCharacters)
{
email.value = 'foo@foo.bar' + c;
checkInvalidEmailAddress(email);
}
// Testing multiple: we are not going to re-test email validity, just multiple.
email.multiple = true;
email.value = 'foo@bar.com, foo@bar.com';
checkValidEmailAddress(email);
email.value = 'foo@bar.com,foo@bar.com';
checkValidEmailAddress(email);
email.value = 'foo@bar.com,foo@bar.com,foo@bar.com';
checkValidEmailAddress(email);
email.value = ' foo@bar.com , foo@bar.com ';
checkValidEmailAddress(email);
email.value = '\tfoo@bar.com\t,\tfoo@bar.com\t';
checkValidEmailAddress(email);
email.value = '\rfoo@bar.com\r,\rfoo@bar.com\r';
checkValidEmailAddress(email);
email.value = '\nfoo@bar.com\n,\nfoo@bar.com\n';
checkValidEmailAddress(email);
email.value = '\ffoo@bar.com\f,\ffoo@bar.com\f';
checkValidEmailAddress(email);
email.value = '\t foo@bar.com\r,\nfoo@bar.com\f';
checkValidEmailAddress(email);
email.value = 'foo@b,ar.com,foo@bar.com';
checkInvalidEmailAddress(email);
email.value = 'foo@bar.com,foo@bar.com,';
checkInvalidEmailAddress(email);
email.value = ' foo@bar.com , foo@bar.com , ';
checkInvalidEmailAddress(email);
email.value = ',foo@bar.com,foo@bar.com';
checkInvalidEmailAddress(email);
email.value = ',foo@bar.com,foo@bar.com';
checkInvalidEmailAddress(email);
email.value = 'foo@bar.com,,,foo@bar.com';
checkInvalidEmailAddress(email);
email.value = 'foo@bar.com;foo@bar.com';
checkInvalidEmailAddress(email);
email.value = '<foo@bar.com>, <foo@bar.com>';
checkInvalidEmailAddress(email);
email.value = 'foo@bar, foo@bar.com';
checkValidEmailAddress(email);
email.value = 'foo@bar.com, foo';
checkInvalidEmailAddress(email);
email.value = 'foo, foo@bar.com';
checkInvalidEmailAddress(email);
</script>
</pre>
</body>

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

@ -0,0 +1,36 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for HTMLTextAreaElement attributes reflection</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="../reflect.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<pre id="test">
<script type="application/javascript">
/** Test for HTMLTextAreaElement attributes reflection **/
var textarea = document.createElement("textarea");
reflectUnsignedInt({
element: textarea,
attribute: "rows",
nonZero: true,
defaultValue: 2,
});
reflectUnsignedInt({
element: textarea,
attribute: "cols",
nonZero: true,
defaultValue: 20,
});
</script>
</pre>
</body>
</html>

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

@ -8,47 +8,58 @@
* http://www.whatwg.org/html/#reflecting-content-attributes-in-idl-attributes
*
* Do not forget to add these line at the beginning of each new reflect* method:
* ok(aAttr in aElement, aAttr + " should be an IDL attribute of this element");
* is(typeof aElement[aAttr], <type>, aAttr + " IDL attribute should be a <type>");
* ok(attr in element, attr + " should be an IDL attribute of this element");
* is(typeof element[attr], <type>, attr + " IDL attribute should be a <type>");
*/
/**
* Checks that a given attribute is correctly reflected as a string.
*
* @param aElement Element node to test
* @param aAttr String name of the attribute
* @param aOtherValues Array other values to test in addition of the default ones [optional]
* @param aParameters Object object containing the parameters, which are:
* - element Element node to test
* - attribute String name of the attribute
* OR
* attribute Object object containing two attributes, 'content' and 'idl'
* - otherValues Array [optional] other values to test in addition of the default ones
*/
function reflectString(aElement, aAttr, aOtherValues)
function reflectString(aParameters)
{
var otherValues = aOtherValues !== undefined ? aOtherValues : [];
var element = aParameters.element;
var contentAttr = typeof aParameters.attribute === "string"
? aParameters.attribute : aParameters.attribute.content;
var idlAttr = typeof aParameters.attribute === "string"
? aParameters.attribute : aParameters.attribute.idl;
var otherValues = aParameters.otherValues !== undefined
? aParameters.otherValues : [];
ok(aAttr in aElement, aAttr + " should be an IDL attribute of this element");
is(typeof aElement[aAttr], "string", aAttr + " IDL attribute should be a string");
ok(idlAttr in element,
idlAttr + " should be an IDL attribute of this element");
is(typeof element[idlAttr], "string",
idlAttr + " IDL attribute should be a string");
// Tests when the attribute isn't set.
is(aElement.getAttribute(aAttr), null,
"When not set, the content attribute should be undefined.");
is(aElement[aAttr], "",
is(element.getAttribute(contentAttr), null,
"When not set, the content attribute should be null.");
is(element[idlAttr], "",
"When not set, the IDL attribute should return the empty string");
/**
* TODO: as long as null stringification doesn't fallow the webidl specs,
* don't add it to the loop below and keep it here.
* TODO: as long as null stringification doesn't follow the WebIDL
* specifications, don't add it to the loop below and keep it here.
*/
aElement.setAttribute(aAttr, null);
todo_is(aElement.getAttribute(aAttr), "null",
element.setAttribute(contentAttr, null);
todo_is(element.getAttribute(contentAttr), "null",
"null should have been stringified to 'null'");
todo_is(aElement[aAttr], "null",
todo_is(element[idlAttr], "null",
"null should have been stringified to 'null'");
aElement.removeAttribute(aAttr);
element.removeAttribute(contentAttr);
aElement[aAttr] = null;
todo_is(aElement.getAttribute(aAttr), "null",
element[idlAttr] = null;
todo_is(element.getAttribute(contentAttr), "null",
"null should have been stringified to 'null'");
todo_is(aElement[aAttr], "null",
todo_is(element[idlAttr], "null",
"null should have been stringified to 'null'");
aElement.removeAttribute(aAttr);
element.removeAttribute(contentAttr);
// Tests various strings.
var stringsToTest = [
@ -57,7 +68,8 @@ function reflectString(aElement, aAttr, aOtherValues)
[ "null", "null" ],
[ "undefined", "undefined" ],
[ "foo", "foo" ],
[ aAttr, aAttr ],
[ contentAttr, contentAttr ],
[ idlAttr, idlAttr ],
// TODO: uncomment this when null stringification will follow the specs.
// [ null, "null" ],
[ undefined, "undefined" ],
@ -80,77 +92,86 @@ function reflectString(aElement, aAttr, aOtherValues)
otherValues.forEach(function(v) { stringsToTest.push([v, v]) });
stringsToTest.forEach(function([v, r]) {
aElement.setAttribute(aAttr, v);
is(aElement[aAttr], r,
element.setAttribute(contentAttr, v);
is(element[idlAttr], r,
"IDL attribute should return the value it has been set to.");
is(aElement.getAttribute(aAttr), r,
is(element.getAttribute(contentAttr), r,
"Content attribute should return the value it has been set to.");
aElement.removeAttribute(aAttr);
element.removeAttribute(contentAttr);
aElement[aAttr] = v;
is(aElement[aAttr], r,
element[idlAttr] = v;
is(element[idlAttr], r,
"IDL attribute should return the value it has been set to.");
is(aElement.getAttribute(aAttr), r,
is(element.getAttribute(contentAttr), r,
"Content attribute should return the value it has been set to.");
aElement.removeAttribute(aAttr);
element.removeAttribute(contentAttr);
});
// Tests after removeAttribute() is called. Should be equivalent with not set.
is(aElement.getAttribute(aAttr), null,
"When not set, the content attribute should be undefined.");
is(aElement[aAttr], "",
is(element.getAttribute(contentAttr), null,
"When not set, the content attribute should be null.");
is(element[idlAttr], "",
"When not set, the IDL attribute should return the empty string");
}
/**
* Checks that a given attribute name for a given element is correctly reflected
* as an unsigned int.
*
* @param aParameters Object object containing the parameters, which are:
* - element Element node to test on
* - attribute String name of the attribute
* - nonZero Boolean whether the attribute should be non-null
* - defaultValue Integer [optional] default value, if different from the default one
*/
function reflectUnsignedInt(aElement, aAttr, aNonNull, aDefault)
function reflectUnsignedInt(aParameters)
{
function checkGetter(aElement, aAttr, aValue)
{
is(aElement[aAttr], aValue, "." + aAttr + " should be equals " + aValue);
is(aElement.getAttribute(aAttr), aValue,
"@" + aAttr + " should be equals " + aValue);
}
var element = aParameters.element;
var attr = aParameters.attribute;
var nonZero = aParameters.nonZero;
var defaultValue = aParameters.defaultValue;
if (!aDefault) {
if (aNonNull) {
aDefault = 1;
if (defaultValue === undefined) {
if (nonZero) {
defaultValue = 1;
} else {
aDefault = 0;
defaultValue = 0;
}
}
ok(aAttr in aElement, aAttr + " should be an IDL attribute of this element");
is(typeof aElement[aAttr], "number", aAttr + " IDL attribute should be a string");
ok(attr in element, attr + " should be an IDL attribute of this element");
is(typeof element[attr], "number", attr + " IDL attribute should be a number");
// Check default value.
is(aElement[aAttr], aDefault, "default value should be " + aDefault);
ok(!aElement.hasAttribute(aAttr), aAttr + " shouldn't be present");
is(element[attr], defaultValue, "default value should be " + defaultValue);
ok(!element.hasAttribute(attr), attr + " shouldn't be present");
var values = [ 1, 3, 42, 2147483647 ];
for each (var value in values) {
aElement[aAttr] = value;
checkGetter(aElement, aAttr, value);
}
element[attr] = value;
is(element[attr], value, "." + attr + " should be equals " + value);
is(element.getAttribute(attr), value,
"@" + attr + " should be equals " + value);
for each (var value in values) {
aElement.setAttribute(aAttr, value);
checkGetter(aElement, aAttr, value);
element.setAttribute(attr, value);
is(element[attr], value, "." + attr + " should be equals " + value);
is(element.getAttribute(attr), value,
"@" + attr + " should be equals " + value);
}
// -3000000000 is equivalent to 1294967296 when using the IDL attribute.
aElement[aAttr] = -3000000000;
checkGetter(aElement, aAttr, 1294967296);
element[attr] = -3000000000;
is(element[attr], 1294967296, "." + attr + " should be equals to 1294967296");
is(element.getAttribute(attr), 1294967296,
"@" + attr + " should be equals to 1294967296");
// When setting the content atribute, it's a string so it will be unvalid.
aElement.setAttribute(aAttr, -3000000000);
is(aElement.getAttribute(aAttr), -3000000000,
"@" + aAttr + " should be equals to " + -3000000000);
is(aElement[aAttr], aDefault,
"." + aAttr + " should be equals to " + aDefault);
element.setAttribute(attr, -3000000000);
is(element.getAttribute(attr), -3000000000,
"@" + attr + " should be equals to " + -3000000000);
is(element[attr], defaultValue,
"." + attr + " should be equals to " + defaultValue);
var nonValidValues = [
/* invalid value, value in the unsigned int range */
@ -160,148 +181,156 @@ function reflectUnsignedInt(aElement, aAttr, aNonNull, aDefault)
];
for each (var values in nonValidValues) {
aElement[aAttr] = values[0];
is(aElement.getAttribute(aAttr), values[1],
"@" + aAttr + " should be equals to " + values[1]);
is(aElement[aAttr], aDefault,
"." + aAttr + " should be equals to " + aDefault);
element[attr] = values[0];
is(element.getAttribute(attr), values[1],
"@" + attr + " should be equals to " + values[1]);
is(element[attr], defaultValue,
"." + attr + " should be equals to " + defaultValue);
}
for each (var values in nonValidValues) {
aElement.setAttribute(aAttr, values[0]);
is(aElement.getAttribute(aAttr), values[0],
"@" + aAttr + " should be equals to " + values[0]);
is(aElement[aAttr], aDefault,
"." + aAttr + " should be equals to " + aDefault);
element.setAttribute(attr, values[0]);
is(element.getAttribute(attr), values[0],
"@" + attr + " should be equals to " + values[0]);
is(element[attr], defaultValue,
"." + attr + " should be equals to " + defaultValue);
}
// Setting to 0 should throw an error if aNonNull is true.
// Setting to 0 should throw an error if nonZero is true.
var caught = false;
try {
aElement[aAttr] = 0;
element[attr] = 0;
} catch(e) {
caught = true;
is(e.code, DOMException.INDEX_SIZE_ERR, "exception should be INDEX_SIZE_ERR");
}
if (aNonNull) {
if (nonZero) {
ok(caught, "an exception should have been caught");
} else {
ok(!caught, "no exception should have been caught");
}
// If 0 is set in @aAttr, it will be ignored when calling .aAttr.
aElement.setAttribute(aAttr, 0);
is(aElement.getAttribute(aAttr), 0, "@" + aAttr + " should be equals to 0");
if (aNonNull) {
is(aElement[aAttr], aDefault,
"." + aAttr + " should be equals to " + aDefault);
// If 0 is set in @attr, it will be ignored when calling .attr.
element.setAttribute(attr, 0);
is(element.getAttribute(attr), 0, "@" + attr + " should be equals to 0");
if (nonZero) {
is(element[attr], defaultValue,
"." + attr + " should be equals to " + defaultValue);
} else {
is(aElement[aAttr], 0, "." + aAttr + " should be equals to 0");
is(element[attr], 0, "." + attr + " should be equals to 0");
}
}
/**
* @param aElement Element node to test on
* @param aAttr String name of the attribute
* @param aValidValues Array valid values we support
* @param aInvalidValues Array invalid values
* @param aDefaultValue String default value when no valid value is set [optional]
* @param aUnsupportedValues Array valid values we do not support [optional]
* Checks that a given attribute is correctly reflected as limited to known
* values enumerated attribute.
*
* @param aParameters Object object containing the parameters, which are:
* - element Element node to test on
* - attribute String name of the attribute
* - validValues Array valid values we support
* - invalidValues Array invalid values
* - defaultValue String [optional] default value when no valid value is set
* - unsupportedValues Array [optional] valid values we do not support
*/
function reflectLimitedEnumerated(aElement, aAttr, aValidValues, aInvalidValues,
aDefaultValue, aUnsupportedValues)
function reflectLimitedEnumerated(aParameters)
{
var defaultValue = aDefaultValue !== undefined ? aDefaultValue : "";
var unsupportedValues = aUnsupportedValues !== undefined ? aUnsupportedValues
: [];
var element = aParameters.element;
var attr = aParameters.attribute;
var validValues = aParameters.validValues;
var invalidValues = aParameters.invalidValues;
var defaultValue = aParameters.defaultValue !== undefined
? aParameters.defaultValue : "";
var unsupportedValues = aParameters.unsupportedValues !== undefined
? aParameters.unsupportedValues : [];
ok(aAttr in aElement, aAttr + " should be an IDL attribute of this element");
is(typeof aElement[aAttr], "string", aAttr + " IDL attribute should be a string");
ok(attr in element, attr + " should be an IDL attribute of this element");
is(typeof element[attr], "string", attr + " IDL attribute should be a string");
// Explicitly check the default value.
aElement.removeAttribute(aAttr);
is(aElement[aAttr], defaultValue,
element.removeAttribute(attr);
is(element[attr], defaultValue,
"When no attribute is set, the value should be the default value.");
// Check valid values.
aValidValues.forEach(function (v) {
aElement.setAttribute(aAttr, v);
is(aElement[aAttr], v,
v + " should be accepted as a valid value for " + aAttr);
is(aElement.getAttribute(aAttr), v,
validValues.forEach(function (v) {
element.setAttribute(attr, v);
is(element[attr], v,
v + " should be accepted as a valid value for " + attr);
is(element.getAttribute(attr), v,
"Content attribute should return the value it has been set to.");
aElement.removeAttribute(aAttr);
element.removeAttribute(attr);
aElement.setAttribute(aAttr, v.toUpperCase());
is(aElement[aAttr], v,
element.setAttribute(attr, v.toUpperCase());
is(element[attr], v,
"Enumerated attributes should be case-insensitive.");
is(aElement.getAttribute(aAttr), v.toUpperCase(),
is(element.getAttribute(attr), v.toUpperCase(),
"Content attribute should not be lower-cased.");
aElement.removeAttribute(aAttr);
element.removeAttribute(attr);
aElement[aAttr] = v;
is(aElement[aAttr], v,
v + " should be accepted as a valid value for " + aAttr);
is(aElement.getAttribute(aAttr), v,
element[attr] = v;
is(element[attr], v,
v + " should be accepted as a valid value for " + attr);
is(element.getAttribute(attr), v,
"Content attribute should return the value it has been set to.");
aElement.removeAttribute(aAttr);
element.removeAttribute(attr);
aElement[aAttr] = v.toUpperCase();
is(aElement[aAttr], v,
element[attr] = v.toUpperCase();
is(element[attr], v,
"Enumerated attributes should be case-insensitive.");
is(aElement.getAttribute(aAttr), v.toUpperCase(),
is(element.getAttribute(attr), v.toUpperCase(),
"Content attribute should not be lower-cased.");
aElement.removeAttribute(aAttr);
element.removeAttribute(attr);
});
// Check invalid values.
aInvalidValues.forEach(function (v) {
aElement.setAttribute(aAttr, v);
is(aElement[aAttr], defaultValue,
invalidValues.forEach(function (v) {
element.setAttribute(attr, v);
is(element[attr], defaultValue,
"When the content attribute is set to an invalid value, the default value should be returned.");
is(aElement.getAttribute(aAttr), v,
is(element.getAttribute(attr), v,
"Content attribute should not have been changed.");
aElement.removeAttribute(aAttr);
element.removeAttribute(attr);
aElement[aAttr] = v;
is(aElement[aAttr], defaultValue,
element[attr] = v;
is(element[attr], defaultValue,
"When the value is set to an invalid value, the default value should be returned.");
is(aElement.getAttribute(aAttr), v,
is(element.getAttribute(attr), v,
"Content attribute should not have been changed.");
aElement.removeAttribute(aAttr);
element.removeAttribute(attr);
});
// Check valid values we currently do not support.
// Basically, it's like the checks for the valid values but with some todo's.
unsupportedValues.forEach(function (v) {
aElement.setAttribute(aAttr, v);
todo_is(aElement[aAttr], v,
v + " should be accepted as a valid value for " + aAttr);
is(aElement.getAttribute(aAttr), v,
element.setAttribute(attr, v);
todo_is(element[attr], v,
v + " should be accepted as a valid value for " + attr);
is(element.getAttribute(attr), v,
"Content attribute should return the value it has been set to.");
aElement.removeAttribute(aAttr);
element.removeAttribute(attr);
aElement.setAttribute(aAttr, v.toUpperCase());
todo_is(aElement[aAttr], v,
element.setAttribute(attr, v.toUpperCase());
todo_is(element[attr], v,
"Enumerated attributes should be case-insensitive.");
is(aElement.getAttribute(aAttr), v.toUpperCase(),
is(element.getAttribute(attr), v.toUpperCase(),
"Content attribute should not be lower-cased.");
aElement.removeAttribute(aAttr);
element.removeAttribute(attr);
aElement[aAttr] = v;
todo_is(aElement[aAttr], v,
v + " should be accepted as a valid value for " + aAttr);
is(aElement.getAttribute(aAttr), v,
element[attr] = v;
todo_is(element[attr], v,
v + " should be accepted as a valid value for " + attr);
is(element.getAttribute(attr), v,
"Content attribute should return the value it has been set to.");
aElement.removeAttribute(aAttr);
element.removeAttribute(attr);
aElement[aAttr] = v.toUpperCase();
todo_is(aElement[aAttr], v,
element[attr] = v.toUpperCase();
todo_is(element[attr], v,
"Enumerated attributes should be case-insensitive.");
is(aElement.getAttribute(aAttr), v.toUpperCase(),
is(element.getAttribute(attr), v.toUpperCase(),
"Content attribute should not be lower-cased.");
aElement.removeAttribute(aAttr);
element.removeAttribute(attr);
});
}

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

@ -1,26 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=601061
-->
<head>
<title>Test for Bug 601061</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="reflect.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=601061">Mozilla Bug 601061</a>
<p id="display"></p>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 601061 **/
reflectUnsignedInt(document.createElement("input"), "size", true, 20);
</script>
</pre>
</body>
</html>

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

@ -22,8 +22,20 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=610212
/** Test for Bug 610212 **/
var canvas = document.createElement('canvas');
reflectUnsignedInt(canvas, "width", false, 300);
reflectUnsignedInt(canvas, "height", false, 150);
reflectUnsignedInt({
element: canvas,
attribute: "width",
nonZero: false,
defaultValue: 300,
});
reflectUnsignedInt({
element: canvas,
attribute: "height",
nonZero: false,
defaultValue: 150,
});
</script>
</pre>

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

@ -1,28 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=630889
-->
<head>
<title>Test for Bug 630889</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="reflect.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=630889">Mozilla Bug 630889</a>
<p id="display"></p>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 630889 **/
var textarea = document.createElement('textarea');
reflectUnsignedInt(textarea, "rows", true, 2);
reflectUnsignedInt(textarea, "cols", true, 20);
</script>
</pre>
</body>
</html>

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

@ -19,12 +19,13 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=660663
<pre id="test">
<script type="application/javascript">
/** Test for Bug 660663 **/
reflectLimitedEnumerated(document.createElement("div"),
"dir",
["ltr", "rtl"],
["cheesecake", ""],
undefined, // There is no default value.
["auto"]);
reflectLimitedEnumerated({
element: document.createElement("div"),
attribute: "dir",
validValues: ["ltr", "rtl"],
invalidValues: ["cheesecake", ""],
unsupportedValues: ["auto"]
});
</script>
</pre>
</body>

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

@ -95,24 +95,27 @@ ConsoleAPI.prototype = {
// We need to return an actual content object here, instead of a wrapped
// chrome object. This allows things like console.log.bind() to work.
let sandbox = Cu.Sandbox(aWindow);
let contentObject = Cu.evalInSandbox(
"(function(x) {\
var bind = Function.bind;\
var obj = {\
log: bind.call(x.log, x),\
info: bind.call(x.info, x),\
warn: bind.call(x.warn, x),\
error: bind.call(x.error, x),\
debug: bind.call(x.debug, x),\
trace: bind.call(x.trace, x),\
__noSuchMethod__: function() {}\
};\
Object.defineProperty(obj, '__mozillaConsole__', { value: true });\
return obj;\
})", sandbox)(chromeObject);
let contentObj = Cu.createObjectIn(aWindow);
function genPropDesc(fun) {
return { enumerable: true, configurable: true, writable: true,
value: chromeObject[fun].bind(chromeObject) };
}
const properties = {
log: genPropDesc('log'),
info: genPropDesc('info'),
warn: genPropDesc('warn'),
error: genPropDesc('error'),
debug: genPropDesc('debug'),
trace: genPropDesc('trace'),
__noSuchMethod__: { enumerable: true, configurable: true, writable: true,
value: function() {} },
__mozillaConsole__: { value: true }
};
return contentObject;
Object.defineProperties(contentObj, properties);
Cu.makeObjectPropsNormal(contentObj);
return contentObj;
},
/**

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

@ -52,18 +52,14 @@ interface nsIScriptGlobalObject;
/**
* Encode and decode JSON text.
*/
[scriptable, uuid(a4d68b4e-0c0b-4c7c-b540-ef2f9834171f)]
[scriptable, uuid(98f12947-5eac-4512-8325-7c9e6a9d8509)]
interface nsIJSON : nsISupports
{
AString encode(/* in JSObject value */);
void encodeToStream(in nsIOutputStream stream,
in string charset,
in boolean writeBOM
/* in JSObject value */);
void /* JSObject */ decode(in AString str);
void /* JSObject */ decodeFromStream(in nsIInputStream stream,
in long contentLength);
@ -79,15 +75,17 @@ interface nsIJSON : nsISupports
*
* This method is provided only as a temporary transition path for users of
* the old code who depended on the ability to decode leniently; new users
* should use the non-legacy decoding methods.
* should use JSON.parse.
*
* This method must only be called from script.
*
* @param str the string to parse
*/
void /* JSObject */ legacyDecode(in AString str);
void /* jsval */ legacyDecode(in AString str);
/* Identical to legacyDecode, but decode the contents of stream. */
void /* JSObject */ legacyDecodeFromStream(in nsIInputStream stream,
in long contentLength);
void /* jsval */ legacyDecodeFromStream(in nsIInputStream stream,
in long contentLength);
/* Identical to legacyDecode, but decode into a jsval. */
// Make sure you GCroot the result of this function before using it.

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

@ -75,34 +75,6 @@ nsJSON::~nsJSON()
{
}
//
// AString encode(in JSObject value, [optional] in JSObject whitelist);
//
NS_IMETHODIMP
nsJSON::Encode(nsAString &aJSON)
{
// This function should only be called from JS.
nsresult rv;
nsJSONWriter writer;
rv = EncodeInternal(&writer);
// FIXME: bug 408838. Get exception types sorted out
if (NS_SUCCEEDED(rv) || rv == NS_ERROR_INVALID_ARG) {
rv = NS_OK;
// if we didn't consume anything, it's not JSON, so return null
if (!writer.DidWrite()) {
aJSON.Truncate();
aJSON.SetIsVoid(PR_TRUE);
} else {
writer.FlushBuffer();
aJSON.Append(writer.mOutputString);
}
}
return rv;
}
static const char UTF8BOM[] = "\xEF\xBB\xBF";
static const char UTF16LEBOM[] = "\xFF\xFE";
static const char UTF16BEBOM[] = "\xFE\xFF";
@ -247,35 +219,22 @@ nsJSON::EncodeInternal(nsJSONWriter *writer)
rv = cc->GetArgc(&argc);
NS_ENSURE_SUCCESS(rv, rv);
// Now fish for the JS arguments. If it's a call to encode, we'll
// want the first two arguments. If it's a call to encodeToStream,
// we'll want the fourth and fifth;
PRUint32 firstArg = writer->mStream ? 3 : 0;
// Now fish for the JS arguments. We want the fourth and fifth arguments to
// encodeToStream.
NS_ABORT_IF_FALSE(writer->mStream != NULL, "should have a stream");
PRUint32 firstArg = 3;
// Get the object we're going to serialize.
JSObject *inputObj = nsnull;
jsval *argv = nsnull;
rv = cc->GetArgvPtr(&argv);
NS_ENSURE_SUCCESS(rv, rv);
if (argc <= firstArg ||
!(JSVAL_IS_OBJECT(argv[firstArg]) &&
(inputObj = JSVAL_TO_OBJECT(argv[firstArg])))) {
// return if it's not something we can deal with
return NS_ERROR_INVALID_ARG;
}
// If the argument wasn't provided, there's nothing to serialize.
if (argc <= firstArg)
return NS_OK;
jsval *vp = &argv[firstArg];
JSBool ok = JS_TryJSON(cx, vp);
JSType type;
if (!(ok && !JSVAL_IS_PRIMITIVE(*vp) &&
(type = JS_TypeOfValue(cx, *vp)) != JSTYPE_FUNCTION &&
type != JSTYPE_XML)) {
return NS_ERROR_INVALID_ARG;
}
ok = JS_Stringify(cx, vp, NULL, JSVAL_NULL, WriteCallback, writer);
if (!ok)
if (!JS_Stringify(cx, vp, NULL, JSVAL_NULL, WriteCallback, writer))
return NS_ERROR_FAILURE;
return NS_OK;
@ -392,20 +351,6 @@ nsJSONWriter::WriteToStream(nsIOutputStream *aStream,
return rv;
}
NS_IMETHODIMP
nsJSON::Decode(const nsAString& json)
{
const PRUnichar *data;
PRUint32 len = NS_StringGetData(json, &data);
nsCOMPtr<nsIInputStream> stream;
nsresult rv = NS_NewByteInputStream(getter_AddRefs(stream),
(const char*) data,
len * sizeof(PRUnichar),
NS_ASSIGNMENT_DEPEND);
NS_ENSURE_SUCCESS(rv, rv);
return DecodeInternal(stream, len, PR_FALSE);
}
NS_IMETHODIMP
nsJSON::DecodeFromStream(nsIInputStream *aStream, PRInt32 aContentLength)
{

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

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

@ -17,22 +17,6 @@ if (!outputDir.exists()) {
do_throw(outputName + " is not a directory?")
}
function testStringEncode()
{
do_check_eq(nativeJSON.encode(), null);
// useless roots are dropped
do_check_eq(nativeJSON.encode(null), null);
do_check_eq(nativeJSON.encode(""), null);
do_check_eq(nativeJSON.encode(undefined), null);
do_check_eq(nativeJSON.encode(5), null);
do_check_eq(nativeJSON.encode(function(){}), null);
do_check_eq(nativeJSON.encode(dump), null);
// All other testing should occur in js/src/tests/ecma_5/JSON/ using
// the otherwise-exactly-identical JSON.stringify.
}
function testOutputStreams() {
function writeToFile(obj, charset, writeBOM) {
var jsonFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
@ -87,25 +71,8 @@ function testOutputStreams() {
outputDir.remove(true);
}
function throwingToJSON() {
var a = {
"b": 1,
"c": 2,
toJSON: function() { throw("uh oh"); }
}
try {
var y = nativeJSON.encode(a);
throw "didn't throw";
} catch (ex) {
do_check_eq(ex, "uh oh");
}
}
function run_test()
{
testStringEncode();
throwingToJSON();
testOutputStreams();
}

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

@ -3,6 +3,5 @@ head =
tail =
[test_decodeFromStream.js]
[test_decode_long_input.js]
[test_encode.js]

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

@ -461,23 +461,21 @@ reverse_range (hb_buffer_t *buffer,
unsigned int start,
unsigned int end)
{
unsigned int i, j;
for (i = start, j = end - 1; i < j; i++, j--) {
hb_glyph_info_t t;
t = buffer->info[i];
buffer->info[i] = buffer->info[j];
buffer->info[j] = t;
hb_glyph_info_t *i = buffer->info + start;
hb_glyph_info_t *j = buffer->info + end - 1;
while (i < j) {
hb_glyph_info_t t = *i;
*i++ = *j;
*j-- = t;
}
if (buffer->pos) {
for (i = 0, j = end - 1; i < j; i++, j--) {
hb_glyph_position_t t;
t = buffer->pos[i];
buffer->pos[i] = buffer->pos[j];
buffer->pos[j] = t;
hb_glyph_position_t *ii = buffer->pos + start;
hb_glyph_position_t *jj = buffer->pos + end - 1;
while (ii < jj) {
hb_glyph_position_t tt = *ii;
*ii++ = *jj;
*jj-- = tt;
}
}
}

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

@ -44,8 +44,9 @@
#include "nsIDirectoryEnumerator.h"
#include "nsDirectoryServiceDefs.h"
#include "nsUnicharUtils.h"
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
#include "mozilla/Preferences.h"
using namespace mozilla;
#define INTL_HYPHENATIONALIAS_PREFIX "intl.hyphenation-alias."
@ -225,30 +226,25 @@ nsHyphenationManager::LoadPatternListFromDir(nsIFile *aDir)
void
nsHyphenationManager::LoadAliases()
{
nsresult rv;
nsCOMPtr<nsIPrefBranch> prefBranch =
do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv)) {
nsIPrefBranch* prefRootBranch = Preferences::GetRootBranch();
if (!prefRootBranch) {
return;
}
PRUint32 prefCount;
char **prefNames;
rv = prefBranch->GetChildList(INTL_HYPHENATIONALIAS_PREFIX,
&prefCount, &prefNames);
nsresult rv = prefRootBranch->GetChildList(INTL_HYPHENATIONALIAS_PREFIX,
&prefCount, &prefNames);
if (NS_SUCCEEDED(rv) && prefCount > 0) {
for (PRUint32 i = 0; i < prefCount; ++i) {
char *prefValue;
rv = prefBranch->GetCharPref(prefNames[i], &prefValue);
if (NS_SUCCEEDED(rv)) {
nsAdoptingCString value = Preferences::GetCString(prefNames[i]);
if (value) {
nsCAutoString alias(prefNames[i]);
alias.Cut(0, strlen(INTL_HYPHENATIONALIAS_PREFIX));
ToLowerCase(alias);
nsCAutoString value(prefValue);
ToLowerCase(value);
nsCOMPtr<nsIAtom> aliasAtom = do_GetAtom(alias);
nsCOMPtr<nsIAtom> valueAtom = do_GetAtom(value);
mHyphAliases.Put(aliasAtom, valueAtom);
NS_Free(prefValue);
}
}
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(prefCount, prefNames);

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

@ -45,9 +45,6 @@
#include "nsIPlatformCharset.h"
#include "nsPosixLocale.h"
#include "nsCOMPtr.h"
#include "nsIPrefBranch.h"
#include "nsIPrefService.h"
#include "nsIPrefLocalizedString.h"
#include "nsUnicharUtils.h"
#include "nsCRT.h"
//#define DEBUG_UNIX_COLLATION

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

@ -531,6 +531,15 @@ else
SDK_LIBRARY = $(SHARED_LIBRARY)
endif
# for compiler bug (http://support.microsoft.com/kb/982107) for MSVC x64
ifdef _MSC_VER
ifneq (,$(filter 1400 1500,$(_MSC_VER)))
ifeq ($(OS_TEST),x86_64)
ASFILES += jswin64.asm
endif
endif
endif
include $(topsrcdir)/config/config.mk
EXTRA_DSO_LDOPTS += $(NSPR_LIBS)

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

@ -1011,7 +1011,7 @@
/* The JIT is enabled by default on all x86, x64-64, ARM & MIPS platforms. */
#if !defined(ENABLE_JIT) \
&& (WTF_CPU_X86 || WTF_CPU_X86_64 || WTF_CPU_ARM || WTF_CPU_MIPS) \
&& (WTF_CPU_X86 || WTF_CPU_X86_64 || WTF_CPU_ARM || WTF_CPU_MIPS || WTF_CPU_SPARC32) \
&& (WTF_OS_DARWIN || !WTF_COMPILER_GCC || GCC_VERSION_AT_LEAST(4, 1, 0)) \
&& !WTF_OS_WINCE
#define ENABLE_JIT 1

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

@ -301,12 +301,14 @@ class AtomDecls
bool addHoist(JSAtom *atom, JSDefinition *defn);
/* Updating the definition for an entry that is known to exist is infallible. */
void update(JSAtom *atom, JSDefinition *defn) {
void updateFirst(JSAtom *atom, JSDefinition *defn) {
JS_ASSERT(map);
AtomDOHMap::Ptr p = map->lookup(atom);
JS_ASSERT(p);
JS_ASSERT(!p.value().isHeader());
p.value() = DefnOrHeader(defn);
if (p.value().isHeader())
p.value().header()->defn = defn;
else
p.value() = DefnOrHeader(defn);
}
/* Remove the node at the head of the chain for |atom|. */

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

@ -0,0 +1,3 @@
for (var x in x)
let(x) {}
function x() {}

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

@ -0,0 +1,4 @@
var x;
for (var a = 0; a < 8; a++) {
Function.prototype()
}

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

@ -0,0 +1,7 @@
var caught = false;
try {
evalcx("eval(\"throw<x/>\")", Function.a)
} catch (e) {
caught = true;
}
assertEq(caught, true);

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

@ -0,0 +1 @@
assertEq(["a"].map(escape)[0], ["a"].map(function(s) {return escape(s);})[0]);

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

@ -75,8 +75,12 @@
*
* "Rhino is not a member of the Monkey family"
*
* Before adding a new MSG_DEF at the end, look for JSMSG_UNUSED<n> free
* index placeholders in the middle of the list.
* When removing MSG_DEFs, convert them to JSMSG_UNUSED<n> placeholders:
*
* MSG_DEF(JSMSG_UNUSED7, 7, 0, JSEXN_NONE, "")
*
* Before adding a new MSG_DEF at the end, look for existing JSMSG_UNUSED<n>
* free index placeholders in the middle of the list.
*/
MSG_DEF(JSMSG_NOT_AN_ERROR, 0, 0, JSEXN_NONE, "<Error #0 is reserved>")
@ -140,7 +144,7 @@ MSG_DEF(JSMSG_BAD_CLASS_RANGE, 57, 0, JSEXN_SYNTAXERR, "invalid range in
MSG_DEF(JSMSG_BAD_REGEXP_FLAG, 58, 1, JSEXN_SYNTAXERR, "invalid regular expression flag {0}")
MSG_DEF(JSMSG_NO_INPUT, 59, 5, JSEXN_SYNTAXERR, "no input for /{0}/{1}{2}{3}{4}")
MSG_DEF(JSMSG_CANT_OPEN, 60, 2, JSEXN_ERR, "can't open {0}: {1}")
MSG_DEF(JSMSG_BAD_STRING_MASK, 61, 1, JSEXN_ERR, "invalid string escape mask {0}")
MSG_DEF(JSMSG_UNUSED61, 61, 0, JSEXN_NONE, "")
MSG_DEF(JSMSG_UNMATCHED_RIGHT_PAREN, 62, 0, JSEXN_SYNTAXERR, "unmatched ) in regular expression")
MSG_DEF(JSMSG_END_OF_DATA, 63, 0, JSEXN_INTERNALERR, "unexpected end of data")
MSG_DEF(JSMSG_SEEK_BEYOND_START, 64, 0, JSEXN_INTERNALERR, "illegal seek beyond start")

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

@ -61,6 +61,7 @@ CPPSRCS = \
testDefineProperty.cpp \
testExtendedEq.cpp \
testFuncCallback.cpp \
testFunctionProperties.cpp \
testGCChunkAlloc.cpp \
testGetPropertyDefault.cpp \
testIntString.cpp \

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

@ -73,8 +73,8 @@ BEGIN_TEST(testCustomIterator_bug612523)
"j;", &result);
CHECK(JSVAL_IS_INT(result));
CHECK(JSVAL_TO_INT(result) == 100);
CHECK(count == 101);
CHECK_EQUAL(JSVAL_TO_INT(result), 100);
CHECK_EQUAL(count, 101);
return true;
}

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

@ -26,8 +26,8 @@ BEGIN_TEST(testDebugger_bug519719)
"function f(g) { for (var i = 0; i < 9; i++) call(g); }\n"
"f(Math.sin);\n" // record loop, starting in f
"f(Math.cos);\n"); // side exit in f -> call
CHECK(callCount[0] == 20);
CHECK(callCount[1] == 20);
CHECK_EQUAL(callCount[0], 20);
CHECK_EQUAL(callCount[1], 20);
return true;
}
END_TEST(testDebugger_bug519719)

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

@ -61,37 +61,46 @@ BEGIN_TEST(testFuncCallback_bug507012)
// Check whether JS_Execute() tracking works
EXEC("42");
CHECK(enters == 1 && leaves == 1 && depth == 0);
CHECK_EQUAL(enters, 1);
CHECK_EQUAL(leaves, 1);
CHECK_EQUAL(depth, 0);
interpreted = enters = leaves = depth = 0;
// Check whether the basic function tracking works
EXEC("f(1)");
CHECK(enters == 1+1 && leaves == 1+1 && depth == 0);
CHECK_EQUAL(enters, 1+1);
CHECK_EQUAL(leaves, 1+1);
CHECK_EQUAL(depth, 0);
// Can we switch to a different callback?
enters = 777;
JS_SetFunctionCallback(cx, funcTransition2);
EXEC("f(1)");
CHECK(called2 && enters == 777);
CHECK(called2);
CHECK_EQUAL(enters, 777);
// Check whether we can turn off function tracing
JS_SetFunctionCallback(cx, NULL);
EXEC("f(1)");
CHECK(enters == 777);
CHECK_EQUAL(enters, 777);
interpreted = enters = leaves = depth = 0;
// Check nested invocations
JS_SetFunctionCallback(cx, funcTransition);
enters = leaves = depth = 0;
EXEC("f(3)");
CHECK(enters == 1+3 && leaves == 1+3 && depth == 0);
CHECK_EQUAL(enters, 1+3);
CHECK_EQUAL(leaves, 1+3);
CHECK_EQUAL(depth, 0);
interpreted = enters = leaves = depth = 0;
// Check calls invoked while running on trace
EXEC("function g () { ++x; }");
interpreted = enters = leaves = depth = 0;
EXEC("for (i = 0; i < 50; ++i) { g(); }");
CHECK(enters == 1+50 && leaves == 1+50 && depth == 0);
CHECK_EQUAL(enters, 1+50);
CHECK_EQUAL(leaves, 1+50);
CHECK_EQUAL(depth, 0);
// If this fails, it means that the code was interpreted rather
// than trace-JITted, and so is not testing what it's supposed to
@ -111,13 +120,18 @@ BEGIN_TEST(testFuncCallback_bug507012)
interpreted = enters = leaves = depth = overlays = 0;
EXEC("42.5");
CHECK(enters == 1);
CHECK(leaves == 1);
CHECK(depth == 0);
CHECK(overlays == enters + leaves);
CHECK_EQUAL(enters, 1);
CHECK_EQUAL(leaves, 1);
CHECK_EQUAL(depth, 0);
CHECK_EQUAL(overlays, enters + leaves);
interpreted = enters = leaves = depth = overlays = 0;
#endif
// Uncomment this to validate whether you're hitting all runmodes (interp,
// tjit, mjit, ...?) Unfortunately, that still doesn't cover all
// transitions between the various runmodes, but it's a start.
//JS_DumpAllProfiles(cx);
return true;
}
@ -131,7 +145,7 @@ JSContext *createContext()
{
JSContext *cx = JSAPITest::createContext();
if (cx)
JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_JIT);
JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_JIT | JSOPTION_METHODJIT | JSOPTION_PCCOUNT);
return cx;
}

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

@ -0,0 +1,23 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sw=4 et tw=99:
*/
#include "tests.h"
BEGIN_TEST(testFunctionProperties)
{
jsvalRoot x(cx);
EVAL("(function f() {})", x.addr());
JSObject *obj = JSVAL_TO_OBJECT(x.value());
jsvalRoot y(cx);
CHECK(JS_GetProperty(cx, obj, "arguments", y.addr()));
CHECK_SAME(y, JSVAL_NULL);
CHECK(JS_GetProperty(cx, obj, "caller", y.addr()));
CHECK_SAME(y, JSVAL_NULL);
return true;
}
END_TEST(testFunctionProperties)

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

@ -80,7 +80,7 @@ BEGIN_TEST(testGCChunkAlloc)
/* Check that we get OOM. */
CHECK(!ok);
CHECK(!JS_IsExceptionPending(cx));
CHECK(errorCount == 1);
CHECK_EQUAL(errorCount, 1);
CHECK(!customGCChunkAllocator.pool[0]);
CHECK(!customGCChunkAllocator.pool[1]);
JS_GC(cx);
@ -92,7 +92,7 @@ BEGIN_TEST(testGCChunkAlloc)
" array.push({});"
" }"
"})();", root.addr());
CHECK(errorCount == 1);
CHECK_EQUAL(errorCount, 1);
return true;
}

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

@ -60,7 +60,7 @@ BEGIN_TEST(testIsAboutToBeFinalized_bug528645)
--checkPointersStaticStrings;
}
}
CHECK(checkPointersStaticStrings == 0);
CHECK_EQUAL(checkPointersStaticStrings, 0);
free(checkPointers);
checkPointers = NULL;

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

@ -57,7 +57,7 @@ BEGIN_TEST(testNewObject_1)
CHECK(JS_IsArrayObject(cx, obj));
jsuint len;
CHECK(JS_GetArrayLength(cx, obj, &len));
CHECK(len == 0);
CHECK_EQUAL(len, 0);
// With one argument.
argv[0] = INT_TO_JSVAL(4);
@ -66,7 +66,7 @@ BEGIN_TEST(testNewObject_1)
rt = OBJECT_TO_JSVAL(obj);
CHECK(JS_IsArrayObject(cx, obj));
CHECK(JS_GetArrayLength(cx, obj, &len));
CHECK(len == 4);
CHECK_EQUAL(len, 4);
// With N arguments.
for (size_t i = 0; i < N; i++)
@ -76,7 +76,7 @@ BEGIN_TEST(testNewObject_1)
rt = OBJECT_TO_JSVAL(obj);
CHECK(JS_IsArrayObject(cx, obj));
CHECK(JS_GetArrayLength(cx, obj, &len));
CHECK(len == N);
CHECK_EQUAL(len, N);
CHECK(JS_GetElement(cx, obj, N - 1, &v));
CHECK_SAME(v, INT_TO_JSVAL(N - 1));

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

@ -29,7 +29,7 @@ BEGIN_TEST(testPropCache_bug505798)
EXEC("var arr = [x, y];\n"
"for (var i = 0; i < arr.length; i++)\n"
" arr[i].p = 1;\n");
CHECK(g_counter == 1);
CHECK_EQUAL(g_counter, 1);
return true;
}
END_TEST(testPropCache_bug505798)

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

@ -24,15 +24,15 @@ BEGIN_TEST(testGetRegExpFlags)
EVAL("/foopy/", val.addr());
obj = JSVAL_TO_OBJECT(val.value());
CHECK(JS_GetRegExpFlags(cx, obj) == 0);
CHECK_EQUAL(JS_GetRegExpFlags(cx, obj), 0);
EVAL("/foopy/g", val.addr());
obj = JSVAL_TO_OBJECT(val.value());
CHECK(JS_GetRegExpFlags(cx, obj) == JSREG_GLOB);
CHECK_EQUAL(JS_GetRegExpFlags(cx, obj), JSREG_GLOB);
EVAL("/foopy/gi", val.addr());
obj = JSVAL_TO_OBJECT(val.value());
CHECK(JS_GetRegExpFlags(cx, obj) == (JSREG_FOLD | JSREG_GLOB));
CHECK_EQUAL(JS_GetRegExpFlags(cx, obj), (JSREG_FOLD | JSREG_GLOB));
return true;
}

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

@ -22,14 +22,14 @@ BEGIN_TEST(testRegExpInstanceProperties)
JS_GC(cx);
CHECK(regexpProto->getCompartment()->initialRegExpShape == NULL);
CHECK_EQUAL(regexpProto->getCompartment()->initialRegExpShape, NULL);
jsval regexp;
EVAL("/foopy/", &regexp);
JSObject *robj = JSVAL_TO_OBJECT(regexp);
CHECK(robj->lastProperty());
CHECK(robj->getCompartment()->initialRegExpShape == robj->lastProperty());
CHECK_EQUAL(robj->getCompartment()->initialRegExpShape, robj->lastProperty());
return true;
}

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

@ -42,9 +42,9 @@ BEGIN_TEST(testResolveRecursion)
/* Start the essence of the test via invoking the first resolve hook. */
jsval v;
EVAL("obj1.x", &v);
CHECK(v == JSVAL_FALSE);
CHECK(resolveEntryCount == 4);
CHECK(resolveExitCount == 4);
CHECK_SAME(v, JSVAL_FALSE);
CHECK_EQUAL(resolveEntryCount, 4);
CHECK_EQUAL(resolveExitCount, 4);
return true;
}
@ -69,9 +69,9 @@ struct AutoIncrCounters {
bool
doResolve(JSObject *obj, jsid id, uintN flags, JSObject **objp)
{
CHECK(resolveExitCount == 0);
CHECK_EQUAL(resolveExitCount, 0);
AutoIncrCounters incr(this);
CHECK(obj == obj1 || obj == obj2);
CHECK_EQUAL(obj, obj1 || obj == obj2);
CHECK(JSID_IS_STRING(id));
@ -81,31 +81,31 @@ doResolve(JSObject *obj, jsid id, uintN flags, JSObject **objp)
if (JS_FlatStringEqualsAscii(str, "x")) {
if (obj == obj1) {
/* First resolve hook invocation. */
CHECK(resolveEntryCount == 1);
CHECK_EQUAL(resolveEntryCount, 1);
EVAL("obj2.y = true", &v);
CHECK(v == JSVAL_TRUE);
CHECK_SAME(v, JSVAL_TRUE);
CHECK(JS_DefinePropertyById(cx, obj, id, JSVAL_FALSE, NULL, NULL, 0));
*objp = obj;
return true;
}
if (obj == obj2) {
CHECK(resolveEntryCount == 4);
CHECK_EQUAL(resolveEntryCount, 4);
*objp = NULL;
return true;
}
} else if (JS_FlatStringEqualsAscii(str, "y")) {
if (obj == obj2) {
CHECK(resolveEntryCount == 2);
CHECK_EQUAL(resolveEntryCount, 2);
CHECK(JS_DefinePropertyById(cx, obj, id, JSVAL_NULL, NULL, NULL, 0));
EVAL("obj1.x", &v);
CHECK(JSVAL_IS_VOID(v));
EVAL("obj1.y", &v);
CHECK(v == JSVAL_ZERO);
CHECK_SAME(v, JSVAL_ZERO);
*objp = obj;
return true;
}
if (obj == obj1) {
CHECK(resolveEntryCount == 3);
CHECK_EQUAL(resolveEntryCount, 3);
EVAL("obj1.x", &v);
CHECK(JSVAL_IS_VOID(v));
EVAL("obj1.y", &v);
@ -115,7 +115,7 @@ doResolve(JSObject *obj, jsid id, uintN flags, JSObject **objp)
EVAL("obj2.x", &v);
CHECK(JSVAL_IS_VOID(v));
EVAL("obj1.y = 0", &v);
CHECK(v == JSVAL_ZERO);
CHECK_SAME(v, JSVAL_ZERO);
*objp = obj;
return true;
}

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

@ -22,7 +22,7 @@ BEGIN_TEST(testStringBuffer_finishString)
JSAtom *finishedAtom = buffer.finishAtom();
CHECK(finishedAtom);
CHECK(atom == finishedAtom);
CHECK_EQUAL(atom, finishedAtom);
return true;
}
END_TEST(testStringBuffer_finishString)

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

@ -37,7 +37,7 @@ BEGIN_TEST(testTrap_gc)
jsvalRoot v2(cx);
CHECK(JS_ExecuteScript(cx, global, scriptObj, v2.addr()));
CHECK(JSVAL_IS_OBJECT(v2));
CHECK(emptyTrapCallCount == 0);
CHECK_EQUAL(emptyTrapCallCount, 0);
// Disable JIT for debugging
JS_SetOptions(cx, JS_GetOptions(cx) & ~JSOPTION_JIT);
@ -70,7 +70,7 @@ BEGIN_TEST(testTrap_gc)
// execute
CHECK(JS_ExecuteScript(cx, global, scriptObj, v2.addr()));
CHECK(emptyTrapCallCount == 11);
CHECK_EQUAL(emptyTrapCallCount, 11);
JS_GC(cx);

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

@ -11,10 +11,10 @@ BEGIN_TEST(testUTF8_bug589917)
size_t utf8_len = sizeof(output_buffer);
CHECK(JS_EncodeCharacters(cx, surrogate_pair, 2, output_buffer, &utf8_len));
CHECK(utf8_len == 4);
CHECK_EQUAL(utf8_len, 4);
CHECK(JS_EncodeCharacters(cx, surrogate_pair, 2, NULL, &utf8_len));
CHECK(utf8_len == 4);
CHECK_EQUAL(utf8_len, 4);
return true;
}

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

@ -101,9 +101,9 @@ struct VersionFixture : public JSAPITest
}
bool toggleXML(bool shouldEnable) {
CHECK(hasXML() == !shouldEnable);
CHECK_EQUAL(hasXML(), !shouldEnable);
JS_ToggleOptions(cx, JSOPTION_XML);
CHECK(hasXML() == shouldEnable);
CHECK_EQUAL(hasXML(), shouldEnable);
return true;
}
@ -218,13 +218,13 @@ END_FIXTURE_TEST(VersionFixture, testOptionsAreUsedForVersionFlags)
BEGIN_FIXTURE_TEST(VersionFixture, testEntryLosesOverride)
{
EXEC("overrideVersion15(); evalScriptVersion16('checkOverride(false); captureVersion()');");
CHECK(captured == JSVERSION_1_6);
CHECK_EQUAL(captured, JSVERSION_1_6);
/*
* Override gets propagated to default version as non-override when you leave the VM's execute
* call.
*/
CHECK(JS_GetVersion(cx) == JSVERSION_1_5);
CHECK_EQUAL(JS_GetVersion(cx), JSVERSION_1_5);
CHECK(!cx->isVersionOverridden());
return true;
}
@ -238,28 +238,28 @@ END_FIXTURE_TEST(VersionFixture, testEntryLosesOverride)
*/
BEGIN_FIXTURE_TEST(VersionFixture, testReturnLosesOverride)
{
CHECK(JS_GetVersion(cx) == JSVERSION_ECMA_5);
CHECK_EQUAL(JS_GetVersion(cx), JSVERSION_ECMA_5);
EXEC(
"checkOverride(false);"
"evalScriptVersion16('overrideVersion15();');"
"checkOverride(false);"
"captureVersion();"
);
CHECK(captured == JSVERSION_ECMA_5);
CHECK_EQUAL(captured, JSVERSION_ECMA_5);
return true;
}
END_FIXTURE_TEST(VersionFixture, testReturnLosesOverride)
BEGIN_FIXTURE_TEST(VersionFixture, testEvalPropagatesOverride)
{
CHECK(JS_GetVersion(cx) == JSVERSION_ECMA_5);
CHECK_EQUAL(JS_GetVersion(cx), JSVERSION_ECMA_5);
EXEC(
"checkOverride(false);"
"eval('overrideVersion15();');"
"checkOverride(true);"
"captureVersion();"
);
CHECK(captured == JSVERSION_1_5);
CHECK_EQUAL(captured, JSVERSION_1_5);
return true;
}
END_FIXTURE_TEST(VersionFixture, testEvalPropagatesOverride)

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

@ -172,7 +172,7 @@ class JSAPITest
fail(bytes, filename, lineno);
}
JSAPITestString toSource(jsval v) {
JSAPITestString jsvalToSource(jsval v) {
JSString *str = JS_ValueToSource(cx, v);
if (str) {
JSAutoByteString bytes(cx, str);
@ -183,9 +183,75 @@ class JSAPITest
return JSAPITestString("<<error converting value to string>>");
}
#define CHECK_SAME(actual, expected) \
JSAPITestString toSource(long v) {
char buf[40];
sprintf(buf, "%ld", v);
return JSAPITestString(buf);
}
JSAPITestString toSource(unsigned long v) {
char buf[40];
sprintf(buf, "%lu", v);
return JSAPITestString(buf);
}
JSAPITestString toSource(long long v) {
char buf[40];
sprintf(buf, "%lld", v);
return JSAPITestString(buf);
}
JSAPITestString toSource(unsigned long long v) {
char buf[40];
sprintf(buf, "%llu", v);
return JSAPITestString(buf);
}
JSAPITestString toSource(unsigned int v) {
return toSource((unsigned long)v);
}
JSAPITestString toSource(int v) {
return toSource((long)v);
}
JSAPITestString toSource(bool v) {
return JSAPITestString(v ? "true" : "false");
}
JSAPITestString toSource(JSAtom *v) {
return jsvalToSource(STRING_TO_JSVAL((JSString*)v));
}
JSAPITestString toSource(JSVersion v) {
return JSAPITestString(JS_VersionToString(v));
}
template<typename T>
bool checkEqual(const T &actual, const T &expected,
const char *actualExpr, const char *expectedExpr,
const char *filename, int lineno) {
return (actual == expected) ||
fail(JSAPITestString("CHECK_EQUAL failed: expected (") +
expectedExpr + ") = " + toSource(expected) +
", got (" + actualExpr + ") = " + toSource(actual), filename, lineno);
}
// There are many cases where the static types of 'actual' and 'expected'
// are not identical, and C++ is understandably cautious about automatic
// coercions. So catch those cases and forcibly coerce, then use the
// identical-type specialization. This may do bad things if the types are
// actually *not* compatible.
template<typename T, typename U>
bool checkEqual(const T &actual, const U &expected,
const char *actualExpr, const char *expectedExpr,
const char *filename, int lineno) {
return checkEqual(U(actual), expected, actualExpr, expectedExpr, filename, lineno);
}
#define CHECK_EQUAL(actual, expected) \
do { \
if (!checkSame(actual, expected, #actual, #expected, __FILE__, __LINE__)) \
if (!checkEqual(actual, expected, #actual, #expected, __FILE__, __LINE__)) \
return false; \
} while (false)
@ -196,9 +262,15 @@ class JSAPITest
return (JS_SameValue(cx, actual, expected, &same) && same) ||
fail(JSAPITestString("CHECK_SAME failed: expected JS_SameValue(cx, ") +
actualExpr + ", " + expectedExpr + "), got !JS_SameValue(cx, " +
toSource(actual) + ", " + toSource(expected) + ")", filename, lineno);
jsvalToSource(actual) + ", " + jsvalToSource(expected) + ")", filename, lineno);
}
#define CHECK_SAME(actual, expected) \
do { \
if (!checkSame(actual, expected, #actual, #expected, __FILE__, __LINE__)) \
return false; \
} while (false)
#define CHECK(expr) \
do { \
if (!(expr)) \

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

@ -4092,14 +4092,6 @@ JS_SetArrayLength(JSContext *cx, JSObject *obj, jsuint length)
return js_SetLengthProperty(cx, obj, length);
}
JS_PUBLIC_API(JSBool)
JS_HasArrayLength(JSContext *cx, JSObject *obj, jsuint *lengthp)
{
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj);
return js_HasLengthProperty(cx, obj, lengthp);
}
JS_PUBLIC_API(JSBool)
JS_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
jsval *vp, uintN *attrsp)
@ -5505,17 +5497,13 @@ JS_Stringify(JSContext *cx, jsval *vp, JSObject *replacer, jsval space,
Value spacev = Valueify(space);
if (!js_Stringify(cx, Valueify(vp), replacer, spacev, sb))
return false;
if (sb.empty()) {
JSAtom *nullAtom = cx->runtime->atomState.nullAtom;
return callback(nullAtom->chars(), nullAtom->length(), data);
}
return callback(sb.begin(), sb.length(), data);
}
JS_PUBLIC_API(JSBool)
JS_TryJSON(JSContext *cx, jsval *vp)
{
CHECK_REQUEST(cx);
assertSameCompartment(cx, *vp);
return js_TryJSON(cx, Valueify(vp));
}
JS_PUBLIC_API(JSBool)
JS_ParseJSON(JSContext *cx, const jschar *chars, uint32 len, jsval *vp)
{
@ -5770,7 +5758,7 @@ JS_NewRegExpObject(JSContext *cx, JSObject *obj, char *bytes, size_t length, uin
if (!chars)
return NULL;
RegExpStatics *res = RegExpStatics::extractFrom(obj->asGlobal());
JSObject *reobj = RegExp::createObject(cx, res, chars, length, flags);
JSObject *reobj = RegExp::createObject(cx, res, chars, length, flags, NULL);
cx->free_(chars);
return reobj;
}
@ -5780,7 +5768,7 @@ JS_NewUCRegExpObject(JSContext *cx, JSObject *obj, jschar *chars, size_t length,
{
CHECK_REQUEST(cx);
RegExpStatics *res = RegExpStatics::extractFrom(obj->asGlobal());
return RegExp::createObject(cx, res, chars, length, flags);
return RegExp::createObject(cx, res, chars, length, flags, NULL);
}
JS_PUBLIC_API(void)
@ -5826,7 +5814,7 @@ JS_NewRegExpObjectNoStatics(JSContext *cx, char *bytes, size_t length, uintN fla
jschar *chars = InflateString(cx, bytes, &length);
if (!chars)
return NULL;
JSObject *obj = RegExp::createObjectNoStatics(cx, chars, length, flags);
JSObject *obj = RegExp::createObjectNoStatics(cx, chars, length, flags, NULL);
cx->free_(chars);
return obj;
}
@ -5835,7 +5823,7 @@ JS_PUBLIC_API(JSObject *)
JS_NewUCRegExpObjectNoStatics(JSContext *cx, jschar *chars, size_t length, uintN flags)
{
CHECK_REQUEST(cx);
return RegExp::createObjectNoStatics(cx, chars, length, flags);
return RegExp::createObjectNoStatics(cx, chars, length, flags, NULL);
}
JS_PUBLIC_API(JSBool)

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

@ -1140,6 +1140,12 @@ JS_GetGlobalForObject(JSContext *cx, JSObject *obj);
extern JS_PUBLIC_API(JSObject *)
JS_GetGlobalForScopeChain(JSContext *cx);
/*
* Initialize the 'Reflect' object on a global object.
*/
extern JS_PUBLIC_API(JSObject *)
JS_InitReflect(JSContext *cx, JSObject *global);
#ifdef JS_HAS_CTYPES
/*
* Initialize the 'ctypes' object on a global variable 'obj'. The 'ctypes'
@ -2470,9 +2476,6 @@ JS_GetArrayLength(JSContext *cx, JSObject *obj, jsuint *lengthp);
extern JS_PUBLIC_API(JSBool)
JS_SetArrayLength(JSContext *cx, JSObject *obj, jsuint length);
extern JS_PUBLIC_API(JSBool)
JS_HasArrayLength(JSContext *cx, JSObject *obj, jsuint *lengthp);
extern JS_PUBLIC_API(JSBool)
JS_DefineElement(JSContext *cx, JSObject *obj, jsint index, jsval value,
JSPropertyOp getter, JSStrictPropertyOp setter, uintN attrs);
@ -3306,12 +3309,6 @@ JS_PUBLIC_API(JSBool)
JS_Stringify(JSContext *cx, jsval *vp, JSObject *replacer, jsval space,
JSONWriteCallback callback, void *data);
/*
* Retrieve a toJSON function. If found, set vp to its result.
*/
JS_PUBLIC_API(JSBool)
JS_TryJSON(JSContext *cx, jsval *vp);
/*
* JSON.parse as specified by ES5.
*/

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

@ -179,40 +179,6 @@ js_StringIsIndex(JSLinearString *str, jsuint *indexp)
return false;
}
static bool
ValueToLength(JSContext *cx, Value* vp, jsuint* plength)
{
if (vp->isInt32()) {
int32_t i = vp->toInt32();
if (i < 0)
goto error;
*plength = (jsuint)(i);
return true;
}
jsdouble d;
if (!ValueToNumber(cx, *vp, &d))
goto error;
if (JSDOUBLE_IS_NaN(d))
goto error;
jsuint length;
length = (jsuint) d;
if (d != (jsdouble) length)
goto error;
*plength = length;
return true;
error:
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_BAD_ARRAY_LENGTH);
return false;
}
JSBool
js_GetLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp)
{
@ -556,23 +522,6 @@ js_SetLengthProperty(JSContext *cx, JSObject *obj, jsdouble length)
return obj->setProperty(cx, id, &v, false);
}
JSBool
js_HasLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp)
{
JSErrorReporter older = JS_SetErrorReporter(cx, NULL);
AutoValueRooter tvr(cx);
jsid id = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
JSBool ok = obj->getProperty(cx, id, tvr.addr());
JS_SetErrorReporter(cx, older);
if (!ok)
return false;
if (!ValueToLength(cx, tvr.addr(), lengthp))
return false;
return true;
}
/*
* Since SpiderMonkey supports cross-class prototype-based delegation, we have
* to be careful about the length getter and setter being called on an object
@ -595,20 +544,26 @@ array_length_getter(JSContext *cx, JSObject *obj, jsid id, Value *vp)
static JSBool
array_length_setter(JSContext *cx, JSObject *obj, jsid id, JSBool strict, Value *vp)
{
jsuint newlen, oldlen, gap, index;
Value junk;
if (!obj->isArray()) {
jsid lengthId = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
return obj->defineProperty(cx, lengthId, *vp, NULL, NULL, JSPROP_ENUMERATE);
}
if (!ValueToLength(cx, vp, &newlen))
uint32 newlen;
if (!ValueToECMAUint32(cx, *vp, &newlen))
return false;
oldlen = obj->getArrayLength();
jsdouble d;
if (!ValueToNumber(cx, *vp, &d))
return false;
if (d != newlen) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_ARRAY_LENGTH);
return false;
}
uint32 oldlen = obj->getArrayLength();
if (oldlen == newlen)
return true;
@ -658,12 +613,14 @@ array_length_setter(JSContext *cx, JSObject *obj, jsid id, JSBool strict, Value
/* Protect iter against GC under JSObject::deleteProperty. */
AutoObjectRooter tvr(cx, iter);
gap = oldlen - newlen;
jsuint gap = oldlen - newlen;
for (;;) {
if (!JS_CHECK_OPERATION_LIMIT(cx) || !JS_NextProperty(cx, iter, &id))
return false;
if (JSID_IS_VOID(id))
break;
jsuint index;
Value junk;
if (js_IdIsIndex(id, &index) && index - newlen < gap &&
!obj->deleteProperty(cx, id, &junk, false)) {
return false;
@ -2104,8 +2061,10 @@ array_push1_dense(JSContext* cx, JSObject* obj, const Value &v, Value *rval)
}
JS_ALWAYS_INLINE JSBool
ArrayCompPushImpl(JSContext *cx, JSObject *obj, const Value &v)
NewbornArrayPushImpl(JSContext *cx, JSObject *obj, const Value &v)
{
JS_ASSERT(!v.isMagic());
uint32 length = obj->getArrayLength();
if (obj->isSlowArray()) {
/* This can happen in one evil case. See bug 630377. */
@ -2117,45 +2076,34 @@ ArrayCompPushImpl(JSContext *cx, JSObject *obj, const Value &v)
JS_ASSERT(obj->isDenseArray());
JS_ASSERT(length <= obj->getDenseArrayCapacity());
if (length == obj->getDenseArrayCapacity()) {
if (length > JS_ARGS_LENGTH_MAX) {
JS_ReportErrorNumberUC(cx, js_GetErrorMessage, NULL,
JSMSG_ARRAY_INIT_TOO_BIG);
return false;
}
if (length == obj->getDenseArrayCapacity() && !obj->ensureSlots(cx, length + 1))
return false;
/*
* An array comprehension cannot add holes to the array. So we can use
* ensureSlots instead of ensureDenseArrayElements.
*/
if (!obj->ensureSlots(cx, length + 1))
return false;
}
obj->setArrayLength(length + 1);
obj->setDenseArrayElement(length, v);
return true;
}
JSBool
js_ArrayCompPush(JSContext *cx, JSObject *obj, const Value &vp)
js_NewbornArrayPush(JSContext *cx, JSObject *obj, const Value &vp)
{
return ArrayCompPushImpl(cx, obj, vp);
return NewbornArrayPushImpl(cx, obj, vp);
}
#ifdef JS_TRACER
JSBool JS_FASTCALL
js_ArrayCompPush_tn(JSContext *cx, JSObject *obj, ValueArgType v)
js_NewbornArrayPush_tn(JSContext *cx, JSObject *obj, ValueArgType v)
{
TraceMonitor *tm = JS_TRACE_MONITOR_ON_TRACE(cx);
if (!ArrayCompPushImpl(cx, obj, ValueArgToConstRef(v))) {
if (!NewbornArrayPushImpl(cx, obj, ValueArgToConstRef(v))) {
SetBuiltinError(tm);
return JS_FALSE;
}
return WasBuiltinSuccessful(tm);
}
JS_DEFINE_CALLINFO_3(extern, BOOL_FAIL, js_ArrayCompPush_tn, CONTEXT, OBJECT,
JS_DEFINE_CALLINFO_3(extern, BOOL_FAIL, js_NewbornArrayPush_tn, CONTEXT, OBJECT,
VALUE, 0, nanojit::ACCSET_STORE_ANY)
#endif
@ -2547,8 +2495,6 @@ array_concat(JSContext *cx, uintN argc, Value *vp)
length = 0;
}
AutoValueRooter tvr(cx);
/* Loop over [0, argc] to concat args into nobj, expanding all Arrays. */
for (uintN i = 0; i <= argc; i++) {
if (!JS_CHECK_OPERATION_LIMIT(cx))
@ -2556,29 +2502,22 @@ array_concat(JSContext *cx, uintN argc, Value *vp)
const Value &v = p[i];
if (v.isObject()) {
aobj = &v.toObject();
if (aobj->isArray() ||
(aobj->isWrapper() && aobj->unwrap()->isArray())) {
jsid id = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
if (!aobj->getProperty(cx, id, tvr.addr()))
return false;
if (aobj->isArray() || (aobj->isWrapper() && aobj->unwrap()->isArray())) {
jsuint alength;
if (!ValueToLength(cx, tvr.addr(), &alength))
if (!js_GetLengthProperty(cx, aobj, &alength))
return false;
for (jsuint slot = 0; slot < alength; slot++) {
for (uint32 slot = 0; slot < alength; slot++) {
JSBool hole;
if (!JS_CHECK_OPERATION_LIMIT(cx) ||
!GetElement(cx, aobj, slot, &hole, tvr.addr())) {
Value tmp;
if (!JS_CHECK_OPERATION_LIMIT(cx) || !GetElement(cx, aobj, slot, &hole, &tmp))
return false;
}
/*
* Per ECMA 262, 15.4.4.4, step 9, ignore nonexistent
* properties.
*/
if (!hole &&
!SetArrayElement(cx, nobj, length+slot, tvr.value())) {
if (!hole && !SetArrayElement(cx, nobj, length + slot, tmp))
return false;
}
}
length += alength;
continue;
@ -3046,29 +2985,42 @@ static JSFunctionSpec array_static_methods[] = {
JS_FS_END
};
/* ES5 15.4.2 */
JSBool
js_Array(JSContext *cx, uintN argc, Value *vp)
{
JSObject *obj;
if (argc == 0) {
obj = NewDenseEmptyArray(cx);
} else if (argc > 1) {
obj = NewDenseCopiedArray(cx, argc, vp + 2);
} else if (!vp[2].isNumber()) {
obj = NewDenseCopiedArray(cx, 1, vp + 2);
} else {
jsuint length;
if (!ValueToLength(cx, vp + 2, &length))
return JS_FALSE;
obj = NewDenseUnallocatedArray(cx, length);
if (argc != 1 || !vp[2].isNumber()) {
JSObject *obj = (argc == 0)
? NewDenseEmptyArray(cx)
: NewDenseCopiedArray(cx, argc, vp + 2);
if (!obj)
return false;
vp->setObject(*obj);
return true;
}
if (!obj)
return JS_FALSE;
vp->setObject(*obj);
uint32 length;
if (vp[2].isInt32()) {
int32_t i = vp[2].toInt32();
if (i < 0) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_ARRAY_LENGTH);
return false;
}
length = uint32(i);
} else {
jsdouble d = vp[2].toDouble();
length = js_DoubleToECMAUint32(d);
if (d != jsdouble(length)) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_ARRAY_LENGTH);
return false;
}
}
return JS_TRUE;
JSObject *obj = NewDenseUnallocatedArray(cx, length);
if (!obj)
return false;
vp->setObject(*obj);
return true;
}
JSObject *

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

@ -193,9 +193,6 @@ js_GetLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp);
extern JSBool
js_SetLengthProperty(JSContext *cx, JSObject *obj, jsdouble length);
extern JSBool
js_HasLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp);
namespace js {
extern JSBool
@ -253,8 +250,15 @@ extern JSBool
js_ArrayInfo(JSContext *cx, uintN argc, jsval *vp);
#endif
/*
* Append the given (non-hole) value to the end of an array. The array must be
* a newborn array -- that is, one which has not been exposed to script for
* arbitrary manipulation. (This method optimizes on the assumption that
* extending the array to accommodate the element will never make the array
* sparse, which requires that the array be completely filled.)
*/
extern JSBool
js_ArrayCompPush(JSContext *cx, JSObject *obj, const js::Value &vp);
js_NewbornArrayPush(JSContext *cx, JSObject *obj, const js::Value &v);
JSBool
js_PrototypeHasIndexedProperties(JSContext *cx, JSObject *obj);

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

@ -581,7 +581,7 @@ JS_DECLARE_CALLINFO(NewDenseEmptyArray)
JS_DECLARE_CALLINFO(NewDenseAllocatedArray)
JS_DECLARE_CALLINFO(NewDenseUnallocatedArray)
}
JS_DECLARE_CALLINFO(js_ArrayCompPush_tn)
JS_DECLARE_CALLINFO(js_NewbornArrayPush_tn)
JS_DECLARE_CALLINFO(js_EnsureDenseArrayCapacity)
/* Defined in jsbuiltins.cpp. */

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

@ -771,7 +771,7 @@ JSStructuredCloneReader::startRead(Value *vp)
const jschar *chars = str->getChars(context());
if (!chars)
return false;
JSObject *obj = RegExp::createObjectNoStatics(context(), chars, length, data);
JSObject *obj = RegExp::createObjectNoStatics(context(), chars, length, data, NULL);
if (!obj)
return false;
vp->setObject(*obj);

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

@ -1934,37 +1934,6 @@ class AutoReleaseNullablePtr {
~AutoReleaseNullablePtr() { if (ptr) cx->free_(ptr); }
};
class AutoLocalNameArray {
public:
explicit AutoLocalNameArray(JSContext *cx, JSFunction *fun
JS_GUARD_OBJECT_NOTIFIER_PARAM)
: context(cx),
mark(JS_ARENA_MARK(&cx->tempPool)),
names(fun->script()->bindings.getLocalNameArray(cx, &cx->tempPool)),
count(fun->script()->bindings.countLocalNames())
{
JS_GUARD_OBJECT_NOTIFIER_INIT;
}
~AutoLocalNameArray() {
JS_ARENA_RELEASE(&context->tempPool, mark);
}
operator bool() const { return !!names; }
uint32 length() const { return count; }
const jsuword &operator [](unsigned i) const { return names[i]; }
private:
JSContext *context;
void *mark;
jsuword *names;
uint32 count;
JS_DECL_USE_GUARD_OBJECT_NOTIFIER
};
template <class RefCountable>
class AlreadyIncRefed
{

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

@ -547,7 +547,7 @@ struct JS_FRIEND_API(JSCompartment) {
* executing. cx must be a context on the current thread.
*/
static inline bool
JS_ON_TRACE(JSContext *cx)
JS_ON_TRACE(const JSContext *cx)
{
#ifdef JS_TRACER
if (JS_THREAD_DATA(cx)->onTraceCompartment)

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

@ -70,6 +70,7 @@
#include "jsnum.h"
#include "jsobj.h"
#include "jsstr.h"
#include "jslibmath.h"
#include "jsobjinlines.h"

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

@ -127,8 +127,6 @@ ScriptDebugPrologue(JSContext *cx, StackFrame *fp)
if (JSInterpreterHook hook = cx->debugHooks->callHook)
fp->setHookData(hook(cx, Jsvalify(fp), true, 0, cx->debugHooks->callHookData));
}
Probes::enterJSFun(cx, fp->maybeFun(), fp->script());
}
bool
@ -136,8 +134,6 @@ ScriptDebugEpilogue(JSContext *cx, StackFrame *fp, bool okArg)
{
JSBool ok = okArg;
Probes::exitJSFun(cx, fp->maybeFun(), fp->script());
if (void *hookData = fp->maybeHookData()) {
if (fp->isFramePushedByExecute()) {
if (JSInterpreterHook hook = cx->debugHooks->executeHook)
@ -1367,8 +1363,22 @@ JS_FunctionHasLocalNames(JSContext *cx, JSFunction *fun)
extern JS_PUBLIC_API(jsuword *)
JS_GetFunctionLocalNameArray(JSContext *cx, JSFunction *fun, void **markp)
{
Vector<JSAtom *> localNames(cx);
if (!fun->script()->bindings.getLocalNameArray(cx, &localNames))
return NULL;
/* Munge data into the API this method implements. Avert your eyes! */
*markp = JS_ARENA_MARK(&cx->tempPool);
return fun->script()->bindings.getLocalNameArray(cx, &cx->tempPool);
jsuword *names;
JS_ARENA_ALLOCATE_CAST(names, jsuword *, &cx->tempPool, localNames.length() * sizeof *names);
if (!names) {
js_ReportOutOfMemory(cx);
return NULL;
}
memcpy(names, localNames.begin(), localNames.length() * sizeof(jsuword));
return names;
}
extern JS_PUBLIC_API(JSAtom *)
@ -1578,6 +1588,7 @@ JS_GetValidFrameCalleeObject(JSContext *cx, JSStackFrame *fp, jsval *vp)
if (!Valueify(fp)->getValidCalleeObject(cx, &v))
return false;
*vp = v.isObject() ? Jsvalify(v) : JSVAL_VOID;
*vp = Jsvalify(v);
return true;
}

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

@ -1427,7 +1427,7 @@ bool
StackFrame::getValidCalleeObject(JSContext *cx, Value *vp)
{
if (!isFunctionFrame()) {
vp->setUndefined();
vp->setNull();
return true;
}
@ -1560,6 +1560,9 @@ fun_getProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp)
/* Find fun's top-most activation record. */
StackFrame *fp = js_GetTopStackFrame(cx);
if (!fp)
return true;
while (!fp->isFunctionFrame() || fp->fun() != fun) {
fp = fp->prev();
if (!fp)
@ -1572,9 +1575,11 @@ fun_getProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp)
NULL, JSMSG_DEPRECATED_USAGE, js_arguments_str)) {
return false;
}
if (!js_GetArgsValue(cx, fp, vp))
return false;
} else if (JSID_IS_ATOM(id, cx->runtime->atomState.callerAtom)) {
return js_GetArgsValue(cx, fp, vp);
}
if (JSID_IS_ATOM(id, cx->runtime->atomState.callerAtom)) {
if (!fp->prev())
return true;
@ -1582,26 +1587,29 @@ fun_getProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp)
if (frame && !frame->getValidCalleeObject(cx, vp))
return false;
if (vp->isObject()) {
JSObject &caller = vp->toObject();
if (!vp->isObject()) {
JS_ASSERT(vp->isNull());
return true;
}
/* Censor the caller if it is from another compartment. */
if (caller.compartment() != cx->compartment) {
vp->setNull();
} else if (caller.isFunction()) {
JSFunction *callerFun = caller.getFunctionPrivate();
if (callerFun->isInterpreted() && callerFun->inStrictMode()) {
JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR, js_GetErrorMessage, NULL,
JSMSG_CALLER_IS_STRICT);
return false;
}
/* Censor the caller if it is from another compartment. */
JSObject &caller = vp->toObject();
if (caller.compartment() != cx->compartment) {
vp->setNull();
} else if (caller.isFunction()) {
JSFunction *callerFun = caller.getFunctionPrivate();
if (callerFun->isInterpreted() && callerFun->inStrictMode()) {
JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR, js_GetErrorMessage, NULL,
JSMSG_CALLER_IS_STRICT);
return false;
}
}
} else {
JS_NOT_REACHED("fun_getProperty");
return true;
}
return true;
JS_NOT_REACHED("fun_getProperty");
return false;
}

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

@ -906,7 +906,7 @@ Execute(JSContext *cx, JSScript *script, JSObject &scopeChain, const Value &this
AutoPreserveEnumerators preserve(cx);
JSBool ok = RunScript(cx, script, fp);
if (result)
if (result && ok)
*result = fp->returnValue();
Probes::stopExecution(cx, script);
@ -4077,6 +4077,8 @@ BEGIN_CASE(JSOP_FUNAPPLY)
JSObject *callee;
JSFunction *fun;
/* Don't bother trying to fast-path calls to scripted non-constructors. */
if (!IsFunctionObject(args.calleev(), &callee, &fun) || !fun->isInterpretedConstructor()) {
if (construct) {
if (!InvokeConstructor(cx, args))
@ -4588,12 +4590,12 @@ BEGIN_CASE(JSOP_CALLUPVAR_DBG)
jsid id;
JSAtom *atom;
{
AutoLocalNameArray names(cx, fun);
if (!names)
Vector<JSAtom *> names(cx);
if (!fun->script()->bindings.getLocalNameArray(cx, &names))
goto error;
uintN index = fun->script()->bindings.countArgsAndVars() + GET_UINT16(regs.pc);
atom = JS_LOCAL_NAME_TO_ATOM(names[index]);
atom = names[index];
id = ATOM_TO_JSID(atom);
if (!js_FindProperty(cx, id, &obj, &obj2, &prop))
@ -5961,7 +5963,7 @@ BEGIN_CASE(JSOP_ARRAYPUSH)
JS_ASSERT(script->nfixed <= slot);
JS_ASSERT(slot < script->nslots);
JSObject *obj = &regs.fp()->slots()[slot].toObject();
if (!js_ArrayCompPush(cx, obj, regs.sp[-1]))
if (!js_NewbornArrayPush(cx, obj, regs.sp[-1]))
goto error;
regs.sp--;
}
@ -6245,7 +6247,16 @@ END_CASE(JSOP_ARRAYPUSH)
# endif
#endif
JS_ASSERT_IF(!regs.fp()->isGeneratorFrame(), !js_IsActiveWithOrBlock(cx, &regs.fp()->scopeChain(), 0));
JS_ASSERT_IF(!regs.fp()->isGeneratorFrame(),
!js_IsActiveWithOrBlock(cx, &regs.fp()->scopeChain(), 0));
#ifdef JS_METHODJIT
/*
* This path is used when it's guaranteed the method can be finished
* inside the JIT.
*/
leave_on_safe_point:
#endif
return interpReturnOK;
@ -6256,15 +6267,6 @@ END_CASE(JSOP_ARRAYPUSH)
js_ReportIsNotDefined(cx, printable.ptr());
}
goto error;
/*
* This path is used when it's guaranteed the method can be finished
* inside the JIT.
*/
#if defined(JS_METHODJIT)
leave_on_safe_point:
#endif
return interpReturnOK;
}
} /* namespace js */

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

@ -353,14 +353,17 @@ ScriptPrologue(JSContext *cx, StackFrame *fp)
fp->functionThis().setObject(*obj);
}
Probes::enterJSFun(cx, fp->maybeFun(), fp->script());
if (cx->compartment->debugMode)
ScriptDebugPrologue(cx, fp);
return true;
}
inline bool
ScriptEpilogue(JSContext *cx, StackFrame *fp, bool ok)
{
Probes::exitJSFun(cx, fp->maybeFun(), fp->script());
if (cx->compartment->debugMode)
ok = ScriptDebugEpilogue(cx, fp, ok);

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

@ -65,6 +65,12 @@ extern double js_copysign(double, double);
#define js_copysign copysign
#endif
#if defined(_M_X64) && _MSC_VER <= 1500
// This is a workaround for fmod bug (http://support.microsoft.com/kb/982107)
extern "C" double js_myfmod(double x, double y);
#define fmod js_myfmod
#endif
/* Consistency wrapper for platform deviations in fmod() */
static inline double
js_fmod(double d, double d2)

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

@ -70,6 +70,7 @@
#include "jsstr.h"
#include "jstracer.h"
#include "jsvector.h"
#include "jslibmath.h"
#include "jsinterpinlines.h"
#include "jsnuminlines.h"

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

@ -2519,19 +2519,18 @@ obj_create(JSContext *cx, uintN argc, Value *vp)
return JS_FALSE;
}
if (JSObject *proto = v.toObjectOrNull()) {
if (proto->isXML()) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_XML_PROTO_FORBIDDEN);
return false;
}
JSObject *proto = v.toObjectOrNull();
if (proto && proto->isXML()) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_XML_PROTO_FORBIDDEN);
return false;
}
/*
* Use the callee's global as the parent of the new object to avoid dynamic
* scoping (i.e., using the caller's global).
*/
JSObject *obj = NewNonFunction<WithProto::Given>(cx, &js_ObjectClass, v.toObjectOrNull(),
vp->toObject().getGlobal());
JSObject *obj = NewNonFunction<WithProto::Given>(cx, &js_ObjectClass, proto,
vp->toObject().getGlobal());
if (!obj)
return JS_FALSE;
vp->setObject(*obj); /* Root and prepare for eventual return. */

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

@ -137,25 +137,6 @@ js_json_stringify(JSContext *cx, uintN argc, Value *vp)
return true;
}
JSBool
js_TryJSON(JSContext *cx, Value *vp)
{
if (!vp->isObject())
return true;
JSObject *obj = &vp->toObject();
Value fval;
jsid id = ATOM_TO_JSID(cx->runtime->atomState.toJSONAtom);
if (!js_GetMethod(cx, obj, id, JSGET_NO_METHOD_BARRIER, &fval))
return false;
if (js_IsCallable(fval)) {
if (!ExternalInvoke(cx, ObjectValue(*obj), fval, 0, NULL, vp))
return false;
}
return true;
}
static inline bool IsQuoteSpecialCharacter(jschar c)
{
JS_STATIC_ASSERT('\b' < ' ');

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

@ -55,8 +55,6 @@ extern JSBool
js_Stringify(JSContext *cx, js::Value *vp, JSObject *replacer, js::Value space,
js::StringBuffer &sb);
extern JSBool js_TryJSON(JSContext *cx, js::Value *vp);
/* Aargh, Windows. */
#ifdef STRICT
#undef STRICT

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

@ -584,7 +584,7 @@ JSONParser::parse(Value *vp)
case FinishArrayElement: {
Value v = valueStack.popCopy();
if (!js_ArrayCompPush(cx, &valueStack.back().toObject(), v))
if (!js_NewbornArrayPush(cx, &valueStack.back().toObject(), v))
return false;
token = advanceAfterArrayElement();
if (token == Comma) {

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

@ -849,7 +849,7 @@ struct JSPrinter {
jsbytecode *dvgfence; /* DecompileExpression fencepost */
jsbytecode **pcstack; /* DecompileExpression modeled stack */
JSFunction *fun; /* interpreted function */
jsuword *localNames; /* argument and variable names */
Vector<JSAtom *> *localNames; /* argument and variable names */
};
JSPrinter *
@ -873,8 +873,8 @@ js_NewPrinter(JSContext *cx, const char *name, JSFunction *fun,
jp->fun = fun;
jp->localNames = NULL;
if (fun && fun->isInterpreted() && fun->script()->bindings.hasLocalNames()) {
jp->localNames = fun->script()->bindings.getLocalNameArray(cx, &jp->pool);
if (!jp->localNames) {
jp->localNames = cx->new_<Vector<JSAtom *> >(cx);
if (!jp->localNames || !fun->script()->bindings.getLocalNameArray(cx, jp->localNames)) {
js_DestroyPrinter(jp);
return NULL;
}
@ -886,6 +886,7 @@ void
js_DestroyPrinter(JSPrinter *jp)
{
JS_FinishArenaPool(&jp->pool);
Foreground::delete_(jp->localNames);
jp->sprinter.context->free_(jp);
}
@ -1379,11 +1380,9 @@ DecompileSwitch(SprintStack *ss, TableEntry *table, uintN tableLength,
static JSAtom *
GetArgOrVarAtom(JSPrinter *jp, uintN slot)
{
JSAtom *name;
LOCAL_ASSERT_RV(jp->fun, NULL);
LOCAL_ASSERT_RV(slot < jp->fun->script()->bindings.countLocalNames(), NULL);
name = JS_LOCAL_NAME_TO_ATOM(jp->localNames[slot]);
JSAtom *name = (*jp->localNames)[slot];
#if !JS_HAS_DESTRUCTURING
LOCAL_ASSERT_RV(name, NULL);
#endif
@ -2925,8 +2924,12 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
if (!jp->localNames) {
JS_ASSERT(fun == jp->fun);
jp->localNames =
jp->fun->script()->bindings.getLocalNameArray(cx, &jp->pool);
jp->localNames = cx->new_<Vector<JSAtom *> >(cx);
if (!jp->localNames ||
!jp->fun->script()->bindings.getLocalNameArray(cx, jp->localNames))
{
return NULL;
}
}
uintN index = GET_UINT16(pc);
@ -4098,7 +4101,8 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
sn = js_GetSrcNote(jp->script, pc);
if (sn && SN_TYPE(sn) == SRC_GENEXP) {
void *mark;
jsuword *innerLocalNames, *outerLocalNames;
Vector<JSAtom *> *innerLocalNames;
Vector<JSAtom *> *outerLocalNames;
JSScript *inner, *outer;
SprintStack ss2;
JSFunction *outerfun;
@ -4113,10 +4117,12 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
*/
mark = JS_ARENA_MARK(&cx->tempPool);
if (fun->script()->bindings.hasLocalNames()) {
innerLocalNames =
fun->script()->bindings.getLocalNameArray(cx, &cx->tempPool);
if (!innerLocalNames)
innerLocalNames = cx->new_<Vector<JSAtom *> >(cx);
if (!innerLocalNames ||
fun->script()->bindings.getLocalNameArray(cx, innerLocalNames))
{
return NULL;
}
} else {
innerLocalNames = NULL;
}

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

@ -1821,13 +1821,12 @@ Compiler::compileFunctionBody(JSContext *cx, JSFunction *fun, JSPrincipals *prin
* NB: do not use AutoLocalNameArray because it will release space
* allocated from cx->tempPool by DefineArg.
*/
jsuword *names = funcg.bindings.getLocalNameArray(cx, &cx->tempPool);
if (!names) {
Vector<JSAtom *> names(cx);
if (!funcg.bindings.getLocalNameArray(cx, &names)) {
fn = NULL;
} else {
for (uintN i = 0; i < nargs; i++) {
JSAtom *name = JS_LOCAL_NAME_TO_ATOM(names[i]);
if (!DefineArg(fn, name, i, &funcg)) {
if (!DefineArg(fn, names[i], i, &funcg)) {
fn = NULL;
break;
}
@ -3077,9 +3076,9 @@ Parser::functionDef(JSAtom *funAtom, FunctionType type, FunctionSyntaxKind kind)
}
if (bodyLevel) {
tc->decls.update(funAtom, (JSDefinition *) pn);
tc->decls.updateFirst(funAtom, (JSDefinition *) pn);
pn->pn_defn = true;
pn->dn_uses = dn; /* dn->dn_uses is now pn_link */
pn->dn_uses = dn; /* dn->dn_uses is now pn_link */
if (!MakeDefIntoUse(dn, pn, funAtom, tc))
return NULL;
@ -6676,12 +6675,20 @@ class CompExprTransplanter {
/*
* A helper for lazily checking for the presence of illegal |yield| or |arguments|
* tokens inside of generator expressions.
* tokens inside of generator expressions. This must be done lazily since we don't
* know whether we're in a generator expression until we see the "for" token after
* we've already parsed the body expression.
*
* Use when entering a parenthesized context. If the nested expression is followed
* by a |for| token (indicating that the parenthesized expression is a generator
* expression), use the checkValidBody() method to see if any illegal tokens were
* found.
* Use in any context which may turn out to be inside a generator expression. This
* includes parenthesized expressions and argument lists, and it includes the tail
* of generator expressions.
*
* The guard will keep track of any |yield| or |arguments| tokens that occur while
* parsing the body. As soon as the parser reaches the end of the body expression,
* call endBody() to reset the context's state, and then immediately call:
*
* - checkValidBody() if this *did* turn out to be a generator expression
* - maybeNoteGenerator() if this *did not* turn out to be a generator expression
*/
class GenexpGuard {
JSTreeContext *tc;
@ -6703,6 +6710,7 @@ class GenexpGuard {
void endBody();
bool checkValidBody(JSParseNode *pn);
bool maybeNoteGenerator();
};
void
@ -6711,6 +6719,13 @@ GenexpGuard::endBody()
tc->parenDepth--;
}
/*
* Check whether a |yield| or |arguments| token has been encountered in the
* body expression, and if so, report an error.
*
* Call this after endBody() when determining that the body *was* in a
* generator expression.
*/
bool
GenexpGuard::checkValidBody(JSParseNode *pn)
{
@ -6733,6 +6748,27 @@ GenexpGuard::checkValidBody(JSParseNode *pn)
return true;
}
/*
* Check whether a |yield| token has been encountered in the body expression,
* and if so, note that the current function is a generator function.
*
* Call this after endBody() when determining that the body *was not* in a
* generator expression.
*/
bool
GenexpGuard::maybeNoteGenerator()
{
if (tc->yieldCount > 0) {
tc->flags |= TCF_FUN_IS_GENERATOR;
if (!tc->inFunction()) {
tc->parser->reportErrorNumber(NULL, JSREPORT_ERROR, JSMSG_BAD_RETURN_OR_YIELD,
js_yield_str);
return false;
}
}
return true;
}
/*
* Any definitions nested within the comprehension expression of a generator
* expression must move "down" one static level, which of course increases the
@ -6874,33 +6910,42 @@ CompExprTransplanter::transplant(JSParseNode *pn)
if (genexp && PN_OP(dn) != JSOP_CALLEE) {
JS_ASSERT(!tc->decls.lookupFirst(atom));
if (dn->pn_pos < root->pn_pos || dn->isPlaceholder()) {
if (dn->pn_pos >= root->pn_pos) {
tc->parent->lexdeps->remove(atom);
} else {
JSDefinition *dn2 = (JSDefinition *)NameNode::create(atom, tc);
if (!dn2)
return false;
if (dn->pn_pos < root->pn_pos) {
/*
* The variable originally appeared to be a use of a
* definition or placeholder outside the generator, but now
* we know it is scoped within the comprehension tail's
* clauses. Make it (along with any other uses within the
* generator) a use of a new placeholder in the generator's
* lexdeps.
*/
AtomDefnAddPtr p = tc->lexdeps->lookupForAdd(atom);
JSDefinition *dn2 = MakePlaceholder(p, pn, tc);
if (!dn2)
return false;
dn2->pn_pos = root->pn_pos;
dn2->pn_type = TOK_NAME;
dn2->pn_op = JSOP_NOP;
dn2->pn_defn = true;
dn2->pn_dflags |= PND_PLACEHOLDER;
dn2->pn_pos = root->pn_pos;
JSParseNode **pnup = &dn->dn_uses;
JSParseNode *pnu;
while ((pnu = *pnup) != NULL && pnu->pn_pos >= root->pn_pos) {
pnu->pn_lexdef = dn2;
dn2->pn_dflags |= pnu->pn_dflags & PND_USE2DEF_FLAGS;
pnup = &pnu->pn_link;
}
dn2->dn_uses = dn->dn_uses;
dn->dn_uses = *pnup;
*pnup = NULL;
dn = dn2;
/*
* Change all uses of |dn| that lie within the generator's
* |yield| expression into uses of dn2.
*/
JSParseNode **pnup = &dn->dn_uses;
JSParseNode *pnu;
while ((pnu = *pnup) != NULL && pnu->pn_pos >= root->pn_pos) {
pnu->pn_lexdef = dn2;
dn2->pn_dflags |= pnu->pn_dflags & PND_USE2DEF_FLAGS;
pnup = &pnu->pn_link;
}
dn2->dn_uses = dn->dn_uses;
dn->dn_uses = *pnup;
*pnup = NULL;
} else if (dn->isPlaceholder()) {
/*
* The variable first occurs free in the 'yield' expression;
* move the existing placeholder node (and all its uses)
* from the parent's lexdeps into the generator's lexdeps.
*/
tc->parent->lexdeps->remove(atom);
if (!tc->lexdeps->put(atom, dn))
return false;
}
@ -7055,8 +7100,12 @@ Parser::comprehensionTail(JSParseNode *kid, uintN blockid, bool isGenexp,
guard.endBody();
if (isGenexp && !guard.checkValidBody(pn2))
if (isGenexp) {
if (!guard.checkValidBody(pn2))
return NULL;
} else if (!guard.maybeNoteGenerator()) {
return NULL;
}
switch (tt) {
#if JS_HAS_DESTRUCTURING
@ -7107,9 +7156,6 @@ Parser::comprehensionTail(JSParseNode *kid, uintN blockid, bool isGenexp,
pnp = &pn2->pn_kid2;
}
if (!maybeNoteGenerator())
return NULL;
pn2 = UnaryNode::create(tc);
if (!pn2)
return NULL;
@ -7229,27 +7275,6 @@ static const char js_generator_str[] = "generator";
#endif /* JS_HAS_GENERATOR_EXPRS */
#endif /* JS_HAS_GENERATORS */
/*
* Check whether a |yield| token has been encountered since the last reset point
* (the creation of the tree context or the current GenexpGuard), and if so,
* note that the current function is a generator function.
*
* Call this after the current GenexpGuard has determined whether it was inside
* of a generator expression.
*/
bool
Parser::maybeNoteGenerator()
{
if (tc->yieldCount > 0) {
tc->flags |= TCF_FUN_IS_GENERATOR;
if (!tc->inFunction()) {
reportErrorNumber(NULL, JSREPORT_ERROR, JSMSG_BAD_RETURN_OR_YIELD, js_yield_str);
return false;
}
}
return true;
}
JSBool
Parser::argumentList(JSParseNode *listNode)
{
@ -7263,10 +7288,8 @@ Parser::argumentList(JSParseNode *listNode)
JSParseNode *argNode = assignExpr();
if (!argNode)
return JS_FALSE;
if (arg0) {
if (arg0)
guard.endBody();
arg0 = false;
}
#if JS_HAS_GENERATORS
if (argNode->pn_type == TOK_YIELD &&
@ -7289,14 +7312,16 @@ Parser::argumentList(JSParseNode *listNode)
js_generator_str);
return JS_FALSE;
}
}
} else
#endif
if (arg0 && !guard.maybeNoteGenerator())
return JS_FALSE;
arg0 = false;
listNode->append(argNode);
} while (tokenStream.matchToken(TOK_COMMA));
if (!maybeNoteGenerator())
return JS_FALSE;
if (tokenStream.getToken() != TOK_RP) {
reportErrorNumber(NULL, JSREPORT_ERROR, JSMSG_PAREN_AFTER_ARGS);
return JS_FALSE;
@ -8807,12 +8832,14 @@ Parser::primaryExpr(TokenKind tt, JSBool afterDot)
obj = RegExp::createObject(context, context->regExpStatics(),
tokenStream.getTokenbuf().begin(),
tokenStream.getTokenbuf().length(),
tokenStream.currentToken().t_reflags);
tokenStream.currentToken().t_reflags,
&tokenStream);
} else {
obj = RegExp::createObjectNoStatics(context,
tokenStream.getTokenbuf().begin(),
tokenStream.getTokenbuf().length(),
tokenStream.currentToken().t_reflags);
tokenStream.currentToken().t_reflags,
&tokenStream);
}
if (!obj)
@ -8898,10 +8925,10 @@ Parser::parenExpr(JSBool *genexp)
pn->pn_pos.end = tokenStream.currentToken().pos.end;
*genexp = JS_TRUE;
}
}
} else
#endif /* JS_HAS_GENERATOR_EXPRS */
if (!maybeNoteGenerator())
if (!guard.maybeNoteGenerator())
return NULL;
return pn;

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

@ -1145,8 +1145,6 @@ struct Parser : private js::AutoGCRooter
inline bool reportErrorNumber(JSParseNode *pn, uintN flags, uintN errorNumber, ...);
private:
bool maybeNoteGenerator();
/*
* JS parsers, from lowest to highest precedence.
*

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

@ -190,9 +190,6 @@ Probes::startExecution(JSContext *cx, JSScript *script)
JAVASCRIPT_EXECUTE_START((script->filename ? (char *)script->filename : nullName),
script->lineno);
#endif
#ifdef MOZ_TRACE_JSCALLS
cx->doFunctionCallback(NULL, script, 1);
#endif
}
inline void
@ -203,9 +200,6 @@ Probes::stopExecution(JSContext *cx, JSScript *script)
JAVASCRIPT_EXECUTE_DONE((script->filename ? (char *)script->filename : nullName),
script->lineno);
#endif
#ifdef MOZ_TRACE_JSCALLS
cx->doFunctionCallback(NULL, script, 0);
#endif
}
/*

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

@ -75,32 +75,30 @@ JS_PROTO(RegExp, 10, js_InitRegExpClass)
JS_PROTO(XML, 11, XML_INIT)
JS_PROTO(Namespace, 12, NAMESPACE_INIT)
JS_PROTO(QName, 13, QNAME_INIT)
JS_PROTO(Reflect, 14, js_InitReflectClass)
JS_PROTO(ASTNode, 15, js_InitReflectClass)
JS_PROTO(Error, 16, js_InitExceptionClasses)
JS_PROTO(InternalError, 17, js_InitExceptionClasses)
JS_PROTO(EvalError, 18, js_InitExceptionClasses)
JS_PROTO(RangeError, 19, js_InitExceptionClasses)
JS_PROTO(ReferenceError, 20, js_InitExceptionClasses)
JS_PROTO(SyntaxError, 21, js_InitExceptionClasses)
JS_PROTO(TypeError, 22, js_InitExceptionClasses)
JS_PROTO(URIError, 23, js_InitExceptionClasses)
JS_PROTO(Generator, 24, GENERATOR_INIT)
JS_PROTO(Iterator, 25, js_InitIteratorClasses)
JS_PROTO(StopIteration, 26, js_InitIteratorClasses)
JS_PROTO(ArrayBuffer, 27, js_InitTypedArrayClasses)
JS_PROTO(Int8Array, 28, js_InitTypedArrayClasses)
JS_PROTO(Uint8Array, 29, js_InitTypedArrayClasses)
JS_PROTO(Int16Array, 30, js_InitTypedArrayClasses)
JS_PROTO(Uint16Array, 31, js_InitTypedArrayClasses)
JS_PROTO(Int32Array, 32, js_InitTypedArrayClasses)
JS_PROTO(Uint32Array, 33, js_InitTypedArrayClasses)
JS_PROTO(Float32Array, 34, js_InitTypedArrayClasses)
JS_PROTO(Float64Array, 35, js_InitTypedArrayClasses)
JS_PROTO(Uint8ClampedArray, 36, js_InitTypedArrayClasses)
JS_PROTO(Proxy, 37, js_InitProxyClass)
JS_PROTO(AnyName, 38, js_InitNullClass)
JS_PROTO(WeakMap, 39, js_InitWeakMapClass)
JS_PROTO(Error, 14, js_InitExceptionClasses)
JS_PROTO(InternalError, 15, js_InitExceptionClasses)
JS_PROTO(EvalError, 16, js_InitExceptionClasses)
JS_PROTO(RangeError, 17, js_InitExceptionClasses)
JS_PROTO(ReferenceError, 18, js_InitExceptionClasses)
JS_PROTO(SyntaxError, 19, js_InitExceptionClasses)
JS_PROTO(TypeError, 20, js_InitExceptionClasses)
JS_PROTO(URIError, 21, js_InitExceptionClasses)
JS_PROTO(Generator, 22, GENERATOR_INIT)
JS_PROTO(Iterator, 23, js_InitIteratorClasses)
JS_PROTO(StopIteration, 24, js_InitIteratorClasses)
JS_PROTO(ArrayBuffer, 25, js_InitTypedArrayClasses)
JS_PROTO(Int8Array, 26, js_InitTypedArrayClasses)
JS_PROTO(Uint8Array, 27, js_InitTypedArrayClasses)
JS_PROTO(Int16Array, 28, js_InitTypedArrayClasses)
JS_PROTO(Uint16Array, 29, js_InitTypedArrayClasses)
JS_PROTO(Int32Array, 30, js_InitTypedArrayClasses)
JS_PROTO(Uint32Array, 31, js_InitTypedArrayClasses)
JS_PROTO(Float32Array, 32, js_InitTypedArrayClasses)
JS_PROTO(Float64Array, 33, js_InitTypedArrayClasses)
JS_PROTO(Uint8ClampedArray, 34, js_InitTypedArrayClasses)
JS_PROTO(Proxy, 35, js_InitProxyClass)
JS_PROTO(AnyName, 36, js_InitNullClass)
JS_PROTO(WeakMap, 37, js_InitWeakMapClass)
#undef XML_INIT
#undef NAMESPACE_INIT

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

@ -907,29 +907,20 @@ bool
NodeBuilder::tryStatement(Value body, NodeVector &catches, Value finally,
TokenPos *pos, Value *dst)
{
Value handler;
Value handlers;
Value cb = callbacks[AST_TRY_STMT];
if (!cb.isNull()) {
return newArray(catches, &handler) &&
callback(cb, body, handler, opt(finally), pos, dst);
return newArray(catches, &handlers) &&
callback(cb, body, handlers, opt(finally), pos, dst);
}
switch (catches.length()) {
case 0:
handler.setNull();
break;
case 1:
handler = catches[0];
break;
default:
if (!newArray(catches, &handler))
return false;
}
if (!newArray(catches, &handlers))
return false;
return newNode(AST_TRY_STMT, pos,
"block", body,
"handler", handler,
"handlers", handlers,
"finalizer", finally,
dst);
}
@ -3148,20 +3139,6 @@ ASTSerializer::functionBody(JSParseNode *pn, TokenPos *pos, Value *dst)
} /* namespace js */
/* Reflect class */
Class js_ReflectClass = {
js_Reflect_str,
JSCLASS_HAS_CACHED_PROTO(JSProto_Reflect),
PropertyStub,
PropertyStub,
PropertyStub,
StrictPropertyStub,
EnumerateStub,
ResolveStub,
ConvertStub
};
static JSBool
reflect_parse(JSContext *cx, uint32 argc, jsval *vp)
{
@ -3285,14 +3262,16 @@ static JSFunctionSpec static_methods[] = {
};
JSObject *
js_InitReflectClass(JSContext *cx, JSObject *obj)
JS_BEGIN_EXTERN_C
JS_PUBLIC_API(JSObject *)
JS_InitReflect(JSContext *cx, JSObject *obj)
{
JSObject *Reflect = NewNonFunction<WithProto::Class>(cx, &js_ReflectClass, NULL, obj);
JSObject *Reflect = NewNonFunction<WithProto::Class>(cx, &js_ObjectClass, NULL, obj);
if (!Reflect)
return NULL;
if (!JS_DefineProperty(cx, obj, js_Reflect_str, OBJECT_TO_JSVAL(Reflect),
if (!JS_DefineProperty(cx, obj, "Reflect", OBJECT_TO_JSVAL(Reflect),
JS_PropertyStub, JS_StrictPropertyStub, 0)) {
return NULL;
}
@ -3300,7 +3279,7 @@ js_InitReflectClass(JSContext *cx, JSObject *obj)
if (!JS_DefineFunctions(cx, Reflect, static_methods))
return NULL;
MarkStandardClassInitializedNoProto(obj, &js_ReflectClass);
return Reflect;
}
JS_END_EXTERN_C

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

@ -130,10 +130,5 @@ extern char const *nodeTypeNames[];
} /* namespace js */
extern js::Class js_ReflectClass;
extern JSObject *
js_InitReflectClass(JSContext *cx, JSObject *obj);
#endif /* jsreflect_h___ */

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

@ -53,6 +53,7 @@
#include "jsnum.h"
#include "jsobj.h"
#include "jsregexp.h"
#include "jsscan.h"
#include "jsstr.h"
#include "jsvector.h"
@ -161,7 +162,8 @@ js_CloneRegExpObject(JSContext *cx, JSObject *obj, JSObject *proto)
* This regex is lacking flags from the statics, so we must recompile with the new
* flags instead of increffing.
*/
AlreadyIncRefed<RegExp> clone = RegExp::create(cx, re->getSource(), origFlags | staticsFlags);
AlreadyIncRefed<RegExp> clone = RegExp::create(cx, re->getSource(),
origFlags | staticsFlags, NULL);
if (!clone)
return NULL;
re = clone.get();
@ -191,15 +193,18 @@ js_ObjectIsRegExp(JSObject *obj)
*/
void
RegExp::reportYarrError(JSContext *cx, JSC::Yarr::ErrorCode error)
RegExp::reportYarrError(JSContext *cx, TokenStream *ts, JSC::Yarr::ErrorCode error)
{
switch (error) {
case JSC::Yarr::NoError:
JS_NOT_REACHED("Called reportYarrError with value for no error");
return;
#define COMPILE_EMSG(__code, __msg) \
case JSC::Yarr::__code: \
JS_ReportErrorFlagsAndNumberUC(cx, JSREPORT_ERROR, js_GetErrorMessage, NULL, __msg); \
#define COMPILE_EMSG(__code, __msg) \
case JSC::Yarr::__code: \
if (ts) \
ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, __msg); \
else \
JS_ReportErrorFlagsAndNumberUC(cx, JSREPORT_ERROR, js_GetErrorMessage, NULL, __msg); \
return
COMPILE_EMSG(PatternTooLarge, JSMSG_REGEXP_TOO_COMPLEX);
COMPILE_EMSG(QuantifierOutOfOrder, JSMSG_BAD_QUANTIFIER);
@ -256,14 +261,14 @@ RegExp::parseFlags(JSContext *cx, JSString *flagStr, uintN *flagsOut)
}
AlreadyIncRefed<RegExp>
RegExp::createFlagged(JSContext *cx, JSString *str, JSString *opt)
RegExp::createFlagged(JSContext *cx, JSString *str, JSString *opt, TokenStream *ts)
{
if (!opt)
return create(cx, str, 0);
return create(cx, str, 0, ts);
uintN flags = 0;
if (!parseFlags(cx, opt, &flags))
return AlreadyIncRefed<RegExp>(NULL);
return create(cx, str, flags);
return create(cx, str, flags, ts);
}
const Shape *
@ -426,7 +431,7 @@ js_XDRRegExpObject(JSXDRState *xdr, JSObject **objp)
* be from the malloc-allocated GC-invisible re. So we must anchor.
*/
JS::Anchor<JSString *> anchor(source);
AlreadyIncRefed<RegExp> re = RegExp::create(xdr->cx, source, flagsword);
AlreadyIncRefed<RegExp> re = RegExp::create(xdr->cx, source, flagsword, NULL);
if (!re)
return false;
if (!obj->initRegExp(xdr->cx, re.get()))
@ -567,7 +572,7 @@ static bool
SwapRegExpInternals(JSContext *cx, JSObject *obj, Value *rval, JSString *str, uint32 flags = 0)
{
flags |= cx->regExpStatics()->getFlags();
AlreadyIncRefed<RegExp> re = RegExp::create(cx, str, flags);
AlreadyIncRefed<RegExp> re = RegExp::create(cx, str, flags, NULL);
if (!re)
return false;
SwapObjectRegExp(cx, obj, re);
@ -824,7 +829,7 @@ js_InitRegExpClass(JSContext *cx, JSObject *global)
if (!proto)
return NULL;
AlreadyIncRefed<RegExp> re = RegExp::create(cx, cx->runtime->emptyString, 0);
AlreadyIncRefed<RegExp> re = RegExp::create(cx, cx->runtime->emptyString, 0, NULL);
if (!re)
return NULL;
#ifdef DEBUG

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

@ -132,10 +132,10 @@ class RegExp
Foreground::delete_<JSC::Yarr::BytecodePattern>(byteCode);
}
bool compileHelper(JSContext *cx, JSLinearString &pattern);
bool compile(JSContext *cx);
bool compileHelper(JSContext *cx, JSLinearString &pattern, TokenStream *ts);
bool compile(JSContext *cx, TokenStream *ts);
static const uint32 allFlags = JSREG_FOLD | JSREG_GLOB | JSREG_MULTILINE | JSREG_STICKY;
void reportYarrError(JSContext *cx, JSC::Yarr::ErrorCode error);
void reportYarrError(JSContext *cx, TokenStream *ts, JSC::Yarr::ErrorCode error);
static inline bool initArena(JSContext *cx);
static inline void checkMatchPairs(JSString *input, int *buf, size_t matchItemCount);
static JSObject *createResult(JSContext *cx, JSString *input, int *buf, size_t matchItemCount);
@ -174,10 +174,10 @@ class RegExp
/* Factories */
static AlreadyIncRefed<RegExp> create(JSContext *cx, JSString *source, uint32 flags);
static AlreadyIncRefed<RegExp> create(JSContext *cx, JSString *source, uint32 flags, TokenStream *ts);
/* Would overload |create|, but |0| resolves ambiguously against pointer and uint. */
static AlreadyIncRefed<RegExp> createFlagged(JSContext *cx, JSString *source, JSString *flags);
static AlreadyIncRefed<RegExp> createFlagged(JSContext *cx, JSString *source, JSString *flags, TokenStream *ts);
/*
* Create an object with new regular expression internals.
@ -186,9 +186,9 @@ class RegExp
* execution, as opposed to during something like XDR.
*/
static JSObject *createObject(JSContext *cx, RegExpStatics *res, const jschar *chars,
size_t length, uint32 flags);
size_t length, uint32 flags, TokenStream *ts);
static JSObject *createObjectNoStatics(JSContext *cx, const jschar *chars, size_t length,
uint32 flags);
uint32 flags, TokenStream *ts);
static RegExp *extractFrom(JSObject *obj);
/* Mutators */
@ -407,7 +407,7 @@ RegExp::executeInternal(JSContext *cx, RegExpStatics *res, JSString *inputstr,
}
inline AlreadyIncRefed<RegExp>
RegExp::create(JSContext *cx, JSString *source, uint32 flags)
RegExp::create(JSContext *cx, JSString *source, uint32 flags, TokenStream *ts)
{
typedef AlreadyIncRefed<RegExp> RetType;
JSLinearString *flatSource = source->ensureLinear(cx);
@ -416,7 +416,7 @@ RegExp::create(JSContext *cx, JSString *source, uint32 flags)
RegExp *self = cx->new_<RegExp>(flatSource, flags, cx->compartment);
if (!self)
return RetType(NULL);
if (!self->compile(cx)) {
if (!self->compile(cx, ts)) {
Foreground::delete_(self);
return RetType(NULL);
}
@ -425,14 +425,14 @@ RegExp::create(JSContext *cx, JSString *source, uint32 flags)
inline JSObject *
RegExp::createObject(JSContext *cx, RegExpStatics *res, const jschar *chars, size_t length,
uint32 flags)
uint32 flags, TokenStream *ts)
{
uint32 staticsFlags = res->getFlags();
return createObjectNoStatics(cx, chars, length, flags | staticsFlags);
return createObjectNoStatics(cx, chars, length, flags | staticsFlags, ts);
}
inline JSObject *
RegExp::createObjectNoStatics(JSContext *cx, const jschar *chars, size_t length, uint32 flags)
RegExp::createObjectNoStatics(JSContext *cx, const jschar *chars, size_t length, uint32 flags, TokenStream *ts)
{
JS_ASSERT((flags & allFlags) == flags);
JSString *str = js_NewStringCopyN(cx, chars, length);
@ -444,7 +444,7 @@ RegExp::createObjectNoStatics(JSContext *cx, const jschar *chars, size_t length,
* could be from the malloc-allocated GC-invisible re. So we must anchor.
*/
JS::Anchor<JSString *> anchor(str);
AlreadyIncRefed<RegExp> re = RegExp::create(cx, str, flags);
AlreadyIncRefed<RegExp> re = RegExp::create(cx, str, flags, ts);
if (!re)
return NULL;
JSObject *obj = NewBuiltinClassInstance(cx, &js_RegExpClass);
@ -469,12 +469,12 @@ EnableYarrJIT(JSContext *cx)
}
inline bool
RegExp::compileHelper(JSContext *cx, JSLinearString &pattern)
RegExp::compileHelper(JSContext *cx, JSLinearString &pattern, TokenStream *ts)
{
JSC::Yarr::ErrorCode yarrError;
JSC::Yarr::YarrPattern yarrPattern(pattern, ignoreCase(), multiline(), &yarrError);
if (yarrError) {
reportYarrError(cx, yarrError);
reportYarrError(cx, ts, yarrError);
return false;
}
parenCount = yarrPattern.m_numSubpatterns;
@ -498,14 +498,14 @@ RegExp::compileHelper(JSContext *cx, JSLinearString &pattern)
}
inline bool
RegExp::compile(JSContext *cx)
RegExp::compile(JSContext *cx, TokenStream *ts)
{
/* Flatten source early for the rest of compilation. */
if (!source->ensureLinear(cx))
return false;
if (!sticky())
return compileHelper(cx, *source);
return compileHelper(cx, *source, ts);
/*
* The sticky case we implement hackily by prepending a caret onto the front
@ -524,7 +524,7 @@ RegExp::compile(JSContext *cx)
JSLinearString *fakeySource = sb.finishString();
if (!fakeySource)
return false;
return compileHelper(cx, *fakeySource);
return compileHelper(cx, *fakeySource, ts);
}
inline bool

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

@ -166,32 +166,28 @@ Bindings::add(JSContext *cx, JSAtom *name, BindingKind kind)
return true;
}
jsuword *
Bindings::getLocalNameArray(JSContext *cx, JSArenaPool *pool)
bool
Bindings::getLocalNameArray(JSContext *cx, Vector<JSAtom *> *namesp)
{
JS_ASSERT(lastBinding);
JS_ASSERT(lastBinding);
JS_ASSERT(hasLocalNames());
JS_ASSERT(hasLocalNames());
Vector<JSAtom *> &names = *namesp;
JS_ASSERT(names.empty());
uintN n = countLocalNames();
jsuword *names;
JS_ASSERT(SIZE_MAX / size_t(n) > sizeof *names);
JS_ARENA_ALLOCATE_CAST(names, jsuword *, pool, size_t(n) * sizeof *names);
if (!names) {
js_ReportOutOfMemory(cx);
return NULL;
}
if (!names.growByUninitialized(n))
return false;
#ifdef DEBUG
for (uintN i = 0; i != n; i++)
names[i] = 0xdeadbeef;
JSAtom * const POISON = reinterpret_cast<JSAtom *>(0xdeadbeef);
for (uintN i = 0; i < n; i++)
names[i] = POISON;
#endif
for (Shape::Range r = lastBinding; !r.empty(); r.popFront()) {
const Shape &shape = r.front();
uintN index = uint16(shape.shortid);
jsuword constFlag = 0;
if (shape.getter() == GetCallArg) {
JS_ASSERT(index < nargs);
@ -201,27 +197,23 @@ Bindings::getLocalNameArray(JSContext *cx, JSArenaPool *pool)
} else {
JS_ASSERT(index < nvars);
index += nargs;
if (!shape.writable())
constFlag = 1;
}
JSAtom *atom;
if (JSID_IS_ATOM(shape.propid)) {
atom = JSID_TO_ATOM(shape.propid);
names[index] = JSID_TO_ATOM(shape.propid);
} else {
JS_ASSERT(JSID_IS_INT(shape.propid));
JS_ASSERT(shape.getter() == GetCallArg);
atom = NULL;
names[index] = NULL;
}
names[index] = jsuword(atom);
}
#ifdef DEBUG
for (uintN i = 0; i != n; i++)
JS_ASSERT(names[i] != 0xdeadbeef);
for (uintN i = 0; i < n; i++)
JS_ASSERT(names[i] != POISON);
#endif
return names;
return true;
}
const Shape *
@ -394,26 +386,16 @@ js_XDRScript(JSXDRState *xdr, JSScript **scriptp)
return false;
}
jsuword *names;
Vector<JSAtom *> names(cx);
if (xdr->mode == JSXDR_ENCODE) {
names = script->bindings.getLocalNameArray(cx, &cx->tempPool);
if (!names)
if (!script->bindings.getLocalNameArray(cx, &names))
return false;
PodZero(bitmap, bitmapLength);
for (uintN i = 0; i < nameCount; i++) {
if (i < nargs
? JS_LOCAL_NAME_TO_ATOM(names[i]) != NULL
: JS_LOCAL_NAME_IS_CONST(names[i]))
{
if (i < nargs && names[i])
bitmap[i >> JS_BITS_PER_UINT32_LOG2] |= JS_BIT(i & (JS_BITS_PER_UINT32 - 1));
}
}
}
#ifdef __GNUC__
else {
names = NULL; /* quell GCC uninitialized warning */
}
#endif
for (uintN i = 0; i < bitmapLength; ++i) {
if (!JS_XDRUint32(xdr, &bitmap[i]))
return false;
@ -428,14 +410,14 @@ js_XDRScript(JSXDRState *xdr, JSScript **scriptp)
if (!bindings.addDestructuring(cx, &dummy))
return false;
} else {
JS_ASSERT(!JS_LOCAL_NAME_TO_ATOM(names[i]));
JS_ASSERT(!names[i]);
}
continue;
}
JSAtom *name;
if (xdr->mode == JSXDR_ENCODE)
name = JS_LOCAL_NAME_TO_ATOM(names[i]);
name = names[i];
if (!js_XDRAtom(xdr, &name))
return false;
if (xdr->mode == JSXDR_DECODE) {

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

@ -266,24 +266,15 @@ class Bindings {
}
/*
* Function and macros to work with local names as an array of words.
* getLocalNameArray returns the array, or null if we are out of memory.
* This function must be called only when hasLocalNames().
* This method returns the local variable, argument, etc. names used by a
* script. This function must be called only when hasLocalNames().
*
* The supplied pool is used to allocate the returned array, so the caller
* is obligated to mark and release to free it.
*
* The elements of the array with index less than nargs correspond to the
* the names of arguments. An index >= nargs addresses a var binding. Use
* JS_LOCAL_NAME_TO_ATOM to convert array's element to an atom pointer.
* This pointer can be null when the element is for an argument
* The elements of the vector with index less than nargs correspond to the
* the names of arguments. An index >= nargs addresses a var binding.
* The name at an element will be null when the element is for an argument
* corresponding to a destructuring pattern.
*
* If nameWord does not name an argument, use JS_LOCAL_NAME_IS_CONST to
* check if nameWord corresponds to the const declaration.
*/
jsuword *
getLocalNameArray(JSContext *cx, JSArenaPool *pool);
bool getLocalNameArray(JSContext *cx, Vector<JSAtom *> *namesp);
/*
* Returns the slot where the sharp array is stored, or a value < 0 if no
@ -353,9 +344,7 @@ class Bindings {
* oldest (i.e., last or right-most to first or left-most in source order).
*
* Sometimes iteration order must be from oldest to youngest, however. For
* such cases, use js::Bindings::getLocalNameArray. The RAII class
* js::AutoLocalNameArray, defined in jscntxt.h, should be used where
* possible instead of direct calls to getLocalNameArray.
* such cases, use js::Bindings::getLocalNameArray.
*/
const js::Shape *lastArgument() const;
const js::Shape *lastVariable() const;

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

@ -148,68 +148,17 @@ static uint32
Utf8ToOneUcs4Char(const uint8 *utf8Buffer, int utf8Length);
/*
* Contributions from the String class to the set of methods defined for the
* global object. escape and unescape used to be defined in the Mocha library,
* but as ECMA decided to spec them, they've been moved to the core engine
* and made ECMA-compliant. (Incomplete escapes are interpreted as literal
* characters by unescape.)
* Global string methods
*/
/*
* Stuff to emulate the old libmocha escape, which took a second argument
* giving the type of escape to perform. Retained for compatibility, and
* copied here to avoid reliance on net.h, mkparse.c/NET_EscapeBytes.
*/
#define URL_XALPHAS ((uint8) 1)
#define URL_XPALPHAS ((uint8) 2)
#define URL_PATH ((uint8) 4)
static const uint8 urlCharType[256] =
/* Bit 0 xalpha -- the alphas
* Bit 1 xpalpha -- as xalpha but
* converts spaces to plus and plus to %20
* Bit 2 ... path -- as xalphas but doesn't escape '/'
*/
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1x */
0,0,0,0,0,0,0,0,0,0,7,4,0,7,7,4, /* 2x !"#$%&'()*+,-./ */
7,7,7,7,7,7,7,7,7,7,0,0,0,0,0,0, /* 3x 0123456789:;<=>? */
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, /* 4x @ABCDEFGHIJKLMNO */
7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,7, /* 5X PQRSTUVWXYZ[\]^_ */
0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, /* 6x `abcdefghijklmno */
7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,0, /* 7X pqrstuvwxyz{\}~ DEL */
0, };
/* This matches the ECMA escape set when mask is 7 (default.) */
#define IS_OK(C, mask) (urlCharType[((uint8) (C))] & (mask))
/* See ECMA-262 Edition 3 B.2.1 */
JSBool
js_str_escape(JSContext *cx, uintN argc, Value *vp, Value *rval)
/* ES5 B.2.1 */
static JSBool
str_escape(JSContext *cx, uintN argc, Value *vp)
{
const char digits[] = {'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
jsint mask = URL_XALPHAS | URL_XPALPHAS | URL_PATH;
if (argc > 1) {
double d;
if (!ValueToNumber(cx, vp[3], &d))
return JS_FALSE;
if (!JSDOUBLE_IS_FINITE(d) ||
(mask = (jsint)d) != d ||
mask & ~(URL_XALPHAS | URL_XPALPHAS | URL_PATH))
{
char numBuf[12];
JS_snprintf(numBuf, sizeof numBuf, "%lx", (unsigned long) mask);
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_BAD_STRING_MASK, numBuf);
return JS_FALSE;
}
}
JSLinearString *str = ArgToRootedString(cx, argc, vp, 0);
if (!str)
return JS_FALSE;
@ -217,19 +166,38 @@ js_str_escape(JSContext *cx, uintN argc, Value *vp, Value *rval)
size_t length = str->length();
const jschar *chars = str->chars();
static const uint8 shouldPassThrough[256] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,1, /* !"#$%&'()*+,-./ */
1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, /* 0123456789:;<=>? */
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* @ABCDEFGHIJKLMNO */
1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1, /* PQRSTUVWXYZ[\]^_ */
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* `abcdefghijklmno */
1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, /* pqrstuvwxyz{\}~ DEL */
};
/* In step 7, exactly 69 characters should pass through unencoded. */
#ifdef DEBUG
int count = 0;
for (uint i = 0; i < sizeof(shouldPassThrough); i++) {
if (shouldPassThrough[i]) {
count++;
}
}
JS_ASSERT(count == 69);
#endif
/* Take a first pass and see how big the result string will need to be. */
size_t newlength = length;
for (size_t i = 0; i < length; i++) {
jschar ch;
if ((ch = chars[i]) < 128 && IS_OK(ch, mask))
jschar ch = chars[i];
if (ch < 128 && shouldPassThrough[ch])
continue;
if (ch < 256) {
if (mask == URL_XPALPHAS && ch == ' ')
continue; /* The character will be encoded as '+' */
newlength += 2; /* The character will be encoded as %XX */
} else {
newlength += 5; /* The character will be encoded as %uXXXX */
}
/* The character will be encoded as %XX or %uXXXX. */
newlength += (ch < 256) ? 2 : 5;
/*
* This overflow test works because newlength is incremented by at
@ -251,17 +219,13 @@ js_str_escape(JSContext *cx, uintN argc, Value *vp, Value *rval)
return JS_FALSE;
size_t i, ni;
for (i = 0, ni = 0; i < length; i++) {
jschar ch;
if ((ch = chars[i]) < 128 && IS_OK(ch, mask)) {
jschar ch = chars[i];
if (ch < 128 && shouldPassThrough[ch]) {
newchars[ni++] = ch;
} else if (ch < 256) {
if (mask == URL_XPALPHAS && ch == ' ') {
newchars[ni++] = '+'; /* convert spaces to pluses */
} else {
newchars[ni++] = '%';
newchars[ni++] = digits[ch >> 4];
newchars[ni++] = digits[ch & 0xF];
}
newchars[ni++] = '%';
newchars[ni++] = digits[ch >> 4];
newchars[ni++] = digits[ch & 0xF];
} else {
newchars[ni++] = '%';
newchars[ni++] = 'u';
@ -279,18 +243,11 @@ js_str_escape(JSContext *cx, uintN argc, Value *vp, Value *rval)
cx->free_(newchars);
return JS_FALSE;
}
rval->setString(retstr);
vp->setString(retstr);
return JS_TRUE;
}
#undef IS_OK
static JSBool
str_escape(JSContext *cx, uintN argc, Value *vp)
{
return js_str_escape(cx, argc, vp, vp);
}
/* See ECMA-262 Edition 3 B.2.2 */
/* ES5 B.2.2 */
static JSBool
str_unescape(JSContext *cx, uintN argc, Value *vp)
{
@ -309,6 +266,7 @@ str_unescape(JSContext *cx, uintN argc, Value *vp)
while (i < length) {
jschar ch = chars[i++];
if (ch == '%') {
/* Incomplete escapes are interpreted as literal characters. */
if (i + 1 < length &&
JS7_ISHEX(chars[i]) && JS7_ISHEX(chars[i + 1]))
{
@ -1460,7 +1418,7 @@ class RegExpGuard
}
JS_ASSERT(patstr);
AlreadyIncRefed<RegExp> re = RegExp::createFlagged(cx, patstr, opt);
AlreadyIncRefed<RegExp> re = RegExp::createFlagged(cx, patstr, opt, NULL);
if (!re)
return NULL;
rep.reset(re);

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

@ -486,10 +486,6 @@ DeflateStringToUTF8Buffer(JSContext *cx, const jschar *chars,
} /* namespace js */
/* Export a few natives and a helper to other files in SpiderMonkey. */
extern JSBool
js_str_escape(JSContext *cx, uintN argc, js::Value *argv, js::Value *rval);
/*
* The String.prototype.replace fast-native entry point is exported for joined
* function optimization in js{interp,tracer}.cpp.

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

@ -3652,23 +3652,22 @@ TraceRecorder::importImpl(Address addr, const void* p, JSValueType t,
#ifdef DEBUG
char name[64];
JS_ASSERT(strlen(prefix) < 11);
void* mark = NULL;
jsuword* localNames = NULL;
Vector<JSAtom *> localNames(cx);
const char* funName = NULL;
JSAutoByteString funNameBytes;
if (*prefix == 'a' || *prefix == 'v') {
mark = JS_ARENA_MARK(&cx->tempPool);
JSFunction *fun = fp->fun();
Bindings &bindings = fun->script()->bindings;
if (bindings.hasLocalNames())
localNames = bindings.getLocalNameArray(cx, &cx->tempPool);
if (bindings.hasLocalNames()) {
JS_ASSERT(bindings.getLocalNameArray(cx, &localNames));
}
funName = fun->atom
? js_AtomToPrintableString(cx, fun->atom, &funNameBytes)
: "<anonymous>";
}
if (!strcmp(prefix, "argv")) {
if (index < fp->numFormalArgs()) {
JSAtom *atom = JS_LOCAL_NAME_TO_ATOM(localNames[index]);
JSAtom *atom = localNames[index];
JSAutoByteString atomBytes;
JS_snprintf(name, sizeof name, "$%s.%s", funName,
js_AtomToPrintableString(cx, atom, &atomBytes));
@ -3676,7 +3675,7 @@ TraceRecorder::importImpl(Address addr, const void* p, JSValueType t,
JS_snprintf(name, sizeof name, "$%s.<arg%d>", funName, index);
}
} else if (!strcmp(prefix, "vars")) {
JSAtom *atom = JS_LOCAL_NAME_TO_ATOM(localNames[fp->numFormalArgs() + index]);
JSAtom *atom = localNames[fp->numFormalArgs() + index];
JSAutoByteString atomBytes;
JS_snprintf(name, sizeof name, "$%s.%s", funName,
js_AtomToPrintableString(cx, atom, &atomBytes));
@ -3684,8 +3683,6 @@ TraceRecorder::importImpl(Address addr, const void* p, JSValueType t,
JS_snprintf(name, sizeof name, "$%s%d", prefix, index);
}
if (mark)
JS_ARENA_RELEASE(&cx->tempPool, mark);
w.name(ins, name);
debug_only_printf(LC_TMTracer, "import vp=%p name=%s type=%c\n",
@ -13750,6 +13747,10 @@ TraceRecorder::interpretedFunctionCall(Value& fval, JSFunction* fun, uintN argc,
if (fval.toObject().getGlobal() != globalObj)
RETURN_STOP("JSOP_CALL or JSOP_NEW crosses global scopes");
JS_ASSERT(fun->isInterpreted());
if (!fun->isInterpretedConstructor())
RETURN_STOP("Non-interpreted constructors get called via Invoke");
StackFrame* const fp = cx->fp();
if (constructing) {
@ -16268,7 +16269,7 @@ TraceRecorder::record_JSOP_ARRAYPUSH()
enterDeepBailCall();
LIns *args[] = { elt_ins, array_ins, cx_ins };
pendingGuardCondition = w.call(&js_ArrayCompPush_tn_ci, args);
pendingGuardCondition = w.call(&js_NewbornArrayPush_tn_ci, args);
leaveDeepBailCall();
return ARECORD_CONTINUE;

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

@ -61,6 +61,7 @@
#include "jsbit.h"
#include "jsvector.h"
#include "jstypedarray.h"
#include "jsutil.h"
#include "jsobjinlines.h"
#include "jstypedarrayinlines.h"
@ -105,10 +106,16 @@ ValueIsLength(JSContext *cx, const Value &v, jsuint *len)
* access. It can be created explicitly and passed to a TypedArray, or
* can be created implicitly by constructing a TypedArray with a size.
*/
/**
* Walks up the prototype chain to find the actual ArrayBuffer data.
* This MAY return NULL. Callers should always use js_IsArrayBuffer()
* first.
*/
JSObject *
ArrayBuffer::getArrayBuffer(JSObject *obj)
{
while (!js_IsArrayBuffer(obj))
while (obj && !js_IsArrayBuffer(obj))
obj = obj->getProto();
return obj;
}
@ -117,6 +124,10 @@ JSBool
ArrayBuffer::prop_getByteLength(JSContext *cx, JSObject *obj, jsid id, Value *vp)
{
JSObject *arrayBuffer = getArrayBuffer(obj);
if (!arrayBuffer) {
vp->setInt32(0);
return true;
}
vp->setInt32(jsint(ArrayBuffer::getByteLength(arrayBuffer)));
return true;
}
@ -157,7 +168,7 @@ static JSObject *
DelegateObject(JSContext *cx, JSObject *obj)
{
if (!obj->getPrivate()) {
JSObject *delegate = NewNonFunction<WithProto::Class>(cx, &js_ObjectClass, NULL, NULL);
JSObject *delegate = NewNonFunction<WithProto::Given>(cx, &js_ObjectClass, obj->getProto(), NULL);
obj->setPrivate(delegate);
return delegate;
}
@ -230,8 +241,11 @@ ArrayBuffer::obj_lookupProperty(JSContext *cx, JSObject *obj, jsid id,
if (!delegateResult)
return false;
if (*propp != NULL)
if (*propp != NULL) {
if (*objp == delegate)
*objp = obj;
return true;
}
JSObject *proto = obj->getProto();
if (!proto) {
@ -277,6 +291,29 @@ ArrayBuffer::obj_setProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp, J
if (JSID_IS_ATOM(id, cx->runtime->atomState.byteLengthAtom))
return true;
if (JSID_IS_ATOM(id, cx->runtime->atomState.protoAtom)) {
if (!vp->isObjectOrNull())
return JS_TRUE;
JSObject *pobj = vp->toObjectOrNull();
JSObject *delegate = DelegateObject(cx, obj);
if (!delegate)
return false;
// save the old prototype
JSObject *oldDelegateProto = delegate->getProto();
if (!SetProto(cx, delegate, pobj, true))
return false;
if (!SetProto(cx, obj, pobj, true)) {
// restore proto on delegate
JS_ALWAYS_TRUE(SetProto(cx, delegate, oldDelegateProto, true));
return false;
}
return true;
}
JSObject *delegate = DelegateObject(cx, obj);
if (!delegate)
return false;

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

@ -85,15 +85,46 @@ namespace js {
//
// bool keyMarked(Key &k)
// bool valueMarked(Value &v)
// Return true if k/v has been marked as reachable by the collector, false otherwise.
// void markKey(Key &k, const char *description)
// void markValue(Value &v, const char *description)
// Mark k/v as reachable by the collector, using trc. Use description to identify
// k/v in debugging. (markKey is used only for non-marking tracers, other code
// using the GC heap tracing functions to map the heap for some purpose or other.)
// Return true if k/v has been marked as live by the garbage collector.
//
// If omitted, this parameter defaults to js::DefaultMarkPolicy<Key, Value>, a policy
// template with the obvious definitions for some typical SpiderMonkey type combinations.
// bool markEntryIfLive(Key &k, Value &v)
// If a table entry whose key is k should be retained, ensure its key and
// value are marked. Return true if any previously unmarked objects
// became marked.
//
// To ensure that the WeakMap's behavior isn't visibly affected by
// garbage collection, this should leave k unmarked only when no key
// matching k could ever be produced after this GC cycle completes ---
// removing entries whose keys this function leaves unmarked should never
// make future lookups fail.
//
// A typical definition of markIteratively would be:
//
// if (keyMarked(k) && !valueMarked(v)) {
// markObject(*v, "WeakMap entry value");
// return true;
// }
// return false;
//
// This meets the above constraint when, for example, Key is JSObject *:
// if k isn't marked, it won't exist once the collection cycle completes,
// and thus can't be supplied as a key.
//
// Note that this may mark entries where keyMarked(k) is not initially
// true. For example, you could have a table whose keys match when the
// values of one of their properties are equal: k1.x === k2.x. An entry
// in such a table could be live even when its key is not marked. The
// markEntryIfLive function for such a table would generally mark both k and v.
//
// void markEntry(Key &k, Value &v)
// Mark the table entry's key and value, k and v, as reachable by the
// collector. WeakMap uses this function for non-marking tracers: other
// code using the GC heap tracing functions to map the heap for some
// purpose or other.
//
// If omitted, the MarkPolicy parameter defaults to js::DefaultMarkPolicy<Key,
// Value>, a policy template with the obvious definitions for some typical
// SpiderMonkey type combinations.
// A policy template holding default marking algorithms for common type combinations. This
// provides default types for WeakMap's MarkPolicy template parameter.
@ -163,34 +194,38 @@ class WeakMap : public HashMap<Key, Value, HashPolicy, RuntimeAllocPolicy>, publ
private:
void nonMarkingTrace(JSTracer *tracer) {
MarkPolicy t(tracer);
for (Range r = Base::all(); !r.empty(); r.popFront()) {
t.markKey(r.front().key, "WeakMap entry key");
t.markValue(r.front().value, "WeakMap entry value");
}
for (Range r = Base::all(); !r.empty(); r.popFront())
t.markEntry(r.front().key, r.front().value);
}
bool markIteratively(JSTracer *tracer) {
MarkPolicy t(tracer);
bool markedAny = false;
for (Range r = Base::all(); !r.empty(); r.popFront()) {
/* If the key is alive, mark the value if needed. */
if (!t.valueMarked(r.front().value) && t.keyMarked(r.front().key)) {
t.markValue(r.front().value, "WeakMap entry with live key");
/* If the entry is live, ensure its key and value are marked. */
if (t.markEntryIfLive(r.front().key, r.front().value)) {
/* We revived a value with children, we have to iterate again. */
markedAny = true;
}
JS_ASSERT_IF(t.keyMarked(r.front().key), t.valueMarked(r.front().value));
}
return markedAny;
}
void sweep(JSTracer *tracer) {
MarkPolicy t(tracer);
/* Remove all entries whose keys remain unmarked. */
for (Enum e(*this); !e.empty(); e.popFront()) {
if (!t.keyMarked(e.front().key))
e.removeFront();
}
#if DEBUG
// Once we've swept, all edges should stay within the known-live part of the graph.
/*
* Once we've swept, all remaining edges should stay within the
* known-live part of the graph.
*/
for (Range r = Base::all(); !r.empty(); r.popFront()) {
JS_ASSERT(t.keyMarked(r.front().key));
JS_ASSERT(t.valueMarked(r.front().value));
@ -212,11 +247,16 @@ class DefaultMarkPolicy<JSObject *, Value> {
return !IsAboutToBeFinalized(tracer->context, v.toGCThing());
return true;
}
void markKey(JSObject *k, const char *description) {
js::gc::MarkObject(tracer, *k, description);
bool markEntryIfLive(JSObject *k, const Value &v) {
if (keyMarked(k) && !valueMarked(v)) {
js::gc::MarkValue(tracer, v, "WeakMap entry value");
return true;
}
return false;
}
void markValue(const Value &v, const char *description) {
js::gc::MarkValue(tracer, v, description);
void markEntry(JSObject *k, const Value &v) {
js::gc::MarkObject(tracer, *k, "WeakMap entry key");
js::gc::MarkValue(tracer, v, "WeakMap entry value");
}
};

49
js/src/jswin64.asm Normal file
Просмотреть файл

@ -0,0 +1,49 @@
; ***** 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.org code.
;
; The Initial Developer of the Original Code is The Mozilla Foundation.
; Portions created by the Initial Developer are Copyright (C) 2011
; the Initial Developer. All Rights Reserved.
;
; Contributor(s):
; Makoto Kato <m_kato@ga2.so-net.ne.jp> (Original Author)
;
; Alternatively, the contents of this file may be used under the terms of
; either the GNU General Public License Version 2 or later (the "GPL"), or
; the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
; in which case the provisions of the GPL or the LGPL are applicable instead
; of those above. If you wish to allow use of your version of this file only
; under the terms of either the GPL or the LGPL, and not to allow others to
; use your version of this file under the terms of the MPL, indicate your
; decision by deleting the provisions above and replace them with the notice
; and other provisions required by the GPL or the LGPL. If you do not delete
; the provisions above, a recipient may use your version of this file under
; the terms of any one of the MPL, the GPL or the LGPL.
;
; ***** END LICENSE BLOCK *****
.CODE
extern fmod:PROC
; This is a workaround for KB982107 (http://support.microsoft.com/kb/982107)
js_myfmod PROC FRAME
.ENDPROLOG
fnclex
jmp fmod
js_myfmod ENDP
END

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

@ -122,6 +122,14 @@ JSWrapper::getPropertyDescriptor(JSContext *cx, JSObject *wrapper, jsid id,
static bool
GetOwnPropertyDescriptor(JSContext *cx, JSObject *obj, jsid id, uintN flags, JSPropertyDescriptor *desc)
{
// If obj is a proxy, we can do better than just guessing. This is
// important for certain types of wrappers that wrap other wrappers.
if (obj->isProxy()) {
return JSProxy::getOwnPropertyDescriptor(cx, obj, id,
flags & JSRESOLVE_ASSIGNING,
Valueify(desc));
}
if (!JS_GetPropertyDescriptorById(cx, obj, id, flags, desc))
return false;
if (desc->obj != obj)
@ -133,7 +141,7 @@ bool
JSWrapper::getOwnPropertyDescriptor(JSContext *cx, JSObject *wrapper, jsid id, bool set,
PropertyDescriptor *desc)
{
desc->obj= NULL; // default result if we refuse to perform this action
desc->obj = NULL; // default result if we refuse to perform this action
CHECKED(GetOwnPropertyDescriptor(cx, wrappedObject(wrapper), id, JSRESOLVE_QUALIFIED,
Jsvalify(desc)), set ? SET : GET);
}

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

@ -222,7 +222,7 @@ JS_XDRFindClassById(JSXDRState *xdr, uint32 id);
* before deserialization of bytecode. If the saved version does not match
* the current version, abort deserialization and invalidate the file.
*/
#define JSXDR_BYTECODE_VERSION (0xb973c0de - 88)
#define JSXDR_BYTECODE_VERSION (0xb973c0de - 89)
/*
* Library-private functions.

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

@ -379,8 +379,10 @@ mjit::Compiler::generatePrologue()
if (isConstructing)
constructThis();
if (debugMode() || Probes::callTrackingActive(cx))
if (debugMode())
INLINE_STUBCALL(stubs::ScriptDebugPrologue);
else if (Probes::callTrackingActive(cx))
INLINE_STUBCALL(stubs::ScriptProbeOnlyPrologue);
return Compile_Okay;
}

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

@ -546,16 +546,30 @@ stubs::CreateThis(VMFrame &f, JSObject *proto)
void JS_FASTCALL
stubs::ScriptDebugPrologue(VMFrame &f)
{
Probes::enterJSFun(f.cx, f.fp()->maybeFun(), f.fp()->script());
js::ScriptDebugPrologue(f.cx, f.fp());
}
void JS_FASTCALL
stubs::ScriptDebugEpilogue(VMFrame &f)
{
Probes::exitJSFun(f.cx, f.fp()->maybeFun(), f.fp()->script());
if (!js::ScriptDebugEpilogue(f.cx, f.fp(), JS_TRUE))
THROW();
}
void JS_FASTCALL
stubs::ScriptProbeOnlyPrologue(VMFrame &f)
{
Probes::enterJSFun(f.cx, f.fp()->fun(), f.fp()->script());
}
void JS_FASTCALL
stubs::ScriptProbeOnlyEpilogue(VMFrame &f)
{
Probes::exitJSFun(f.cx, f.fp()->fun(), f.fp()->script());
}
#ifdef JS_TRACER
/*

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

@ -73,6 +73,8 @@ void * JS_FASTCALL UncachedCall(VMFrame &f, uint32 argc);
void JS_FASTCALL Eval(VMFrame &f, uint32 argc);
void JS_FASTCALL ScriptDebugPrologue(VMFrame &f);
void JS_FASTCALL ScriptDebugEpilogue(VMFrame &f);
void JS_FASTCALL ScriptProbeOnlyPrologue(VMFrame &f);
void JS_FASTCALL ScriptProbeOnlyEpilogue(VMFrame &f);
/*
* Result struct for UncachedXHelper.

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

@ -1 +1 @@
8eec2117b714ec754c483b681acb3737f63b994c
4cc8b8ebd44b989e08935ed8ffae7e9cb4eb4ae9

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

@ -283,7 +283,6 @@ namespace nanojit
InsSet incoming(_alloc); // running list of incoming edges into the block
bool last = true; // true, when we're processing the last instruction of a block
LIns* priorBlock = 0; // prior block that was just processed.
LIns* priorIns = 0; // last instruction encountered
LirReader rdr(finalIns());
LIns* ins = rdr.read();
@ -323,8 +322,6 @@ namespace nanojit
n.insert(ins);
if ( _alt.containsKey(ins) )
incoming.put(ins,true);
priorIns = ins;
}
}

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

@ -2319,16 +2319,15 @@ DisassembleValue(JSContext *cx, jsval v, bool lines, bool recursive, Sprinter *s
if (script->bindings.hasUpvars()) {
Sprint(sp, "\nupvars: {\n");
void *mark = JS_ARENA_MARK(&cx->tempPool);
jsuword *localNames = script->bindings.getLocalNameArray(cx, &cx->tempPool);
if (!localNames)
Vector<JSAtom *> localNames(cx);
if (!script->bindings.getLocalNameArray(cx, &localNames))
return false;
JSUpvarArray *uva = script->upvars();
uintN upvar_base = script->bindings.countArgsAndVars();
for (uint32 i = 0, n = uva->length; i < n; i++) {
JSAtom *atom = JS_LOCAL_NAME_TO_ATOM(localNames[upvar_base + i]);
JSAtom *atom = localNames[upvar_base + i];
UpvarCookie cookie = uva->vector[i];
JSAutoByteString printable;
if (js_AtomToPrintableString(cx, atom, &printable)) {
@ -2337,7 +2336,6 @@ DisassembleValue(JSContext *cx, jsval v, bool lines, bool recursive, Sprinter *s
}
}
JS_ARENA_RELEASE(&cx->tempPool, mark);
Sprint(sp, "}");
}
}
@ -3295,24 +3293,6 @@ split_enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
return JS_TRUE;
}
static JSBool
ResolveClass(JSContext *cx, JSObject *obj, jsid id, JSBool *resolved)
{
if (!JS_ResolveStandardClass(cx, obj, id, resolved))
return JS_FALSE;
if (!*resolved) {
if (JSID_IS_ATOM(id, CLASS_ATOM(cx, Reflect))) {
if (!IsStandardClassResolved(obj, &js_ReflectClass) &&
!js_InitReflectClass(cx, obj))
return JS_FALSE;
*resolved = JS_TRUE;
}
}
return JS_TRUE;
}
static JSBool
split_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags, JSObject **objp)
{
@ -3335,7 +3315,7 @@ split_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags, JSObject **obj
if (!(flags & JSRESOLVE_ASSIGNING)) {
JSBool resolved;
if (!ResolveClass(cx, obj, id, &resolved))
if (!JS_ResolveStandardClass(cx, obj, id, &resolved))
return JS_FALSE;
if (resolved) {
@ -3567,7 +3547,7 @@ sandbox_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
JS_ValueToBoolean(cx, v, &b);
if (b && (flags & JSRESOLVE_ASSIGNING) == 0) {
if (!ResolveClass(cx, obj, id, &resolved))
if (!JS_ResolveStandardClass(cx, obj, id, &resolved))
return JS_FALSE;
if (resolved) {
*objp = obj;
@ -3654,13 +3634,15 @@ EvalInContext(JSContext *cx, uintN argc, jsval *vp)
return false;
}
*vp = OBJECT_TO_JSVAL(sobj);
if (srclen == 0)
if (srclen == 0) {
JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(sobj));
return true;
}
JSStackFrame *fp = JS_GetScriptedCaller(cx, NULL);
JSScript *script = JS_GetFrameScript(cx, fp);
jsbytecode *pc = JS_GetFramePC(cx, fp);
jsval rval;
{
JSAutoEnterCompartment ac;
uintN flags;
@ -3681,11 +3663,16 @@ EvalInContext(JSContext *cx, uintN argc, jsval *vp)
if (!JS_EvaluateUCScript(cx, sobj, src, srclen,
script->filename,
JS_PCToLineNumber(cx, script, pc),
vp)) {
&rval)) {
return false;
}
}
return cx->compartment->wrap(cx, Valueify(vp));
if (!cx->compartment->wrap(cx, Valueify(&rval)))
return false;
JS_SET_RVAL(cx, vp, rval);
return true;
}
static JSBool
@ -5669,7 +5656,7 @@ global_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
#ifdef LAZY_STANDARD_CLASSES
JSBool resolved;
if (!ResolveClass(cx, obj, id, &resolved))
if (!JS_ResolveStandardClass(cx, obj, id, &resolved))
return JS_FALSE;
if (resolved) {
*objp = obj;
@ -5931,6 +5918,8 @@ NewGlobalObject(JSContext *cx, CompartmentKind compartment)
if (!JS_InitCTypesClass(cx, glob))
return NULL;
#endif
if (!JS_InitReflect(cx, glob))
return NULL;
if (!JS::RegisterPerfMeasurement(cx, glob))
return NULL;
if (!JS_DefineFunctions(cx, glob, shell_functions) ||

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