Merge services-central and mozilla-central

This commit is contained in:
Philipp von Weitershausen 2011-10-05 17:05:11 -07:00
commit 9185ef9317
62 changed files with 918 additions and 590 deletions

View File

@ -70,6 +70,7 @@
#include "nsImageFrame.h"
#include "nsILink.h"
#include "nsIObserverService.h"
#include "nsLayoutUtils.h"
#include "nsNPAPIPluginInstance.h"
#include "nsISupportsUtils.h"
#include "nsObjectFrame.h"
@ -1012,15 +1013,14 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
if (isHTML && content->Tag() == nsGkAtoms::map) {
// Create hyper text accessible for HTML map if it is used to group links
// (see http://www.w3.org/TR/WCAG10-HTML-TECHS/#group-bypass). If the HTML
// map doesn't have 'name' attribute (or has empty name attribute) then we
// suppose it is used for links grouping. Otherwise we think it is used in
// conjuction with HTML image element and in this case we don't create any
// accessible for it and don't walk into it. The accessibles for HTML area
// (nsHTMLAreaAccessible) the map contains are attached as children of the
// appropriate accessible for HTML image (nsHTMLImageAccessible).
nsAutoString name;
content->GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
if (!name.IsEmpty()) {
// map rect is empty then it is used for links grouping. Otherwise it should
// be used in conjunction with HTML image element and in this case we don't
// create any accessible for it and don't walk into it. The accessibles for
// HTML area (nsHTMLAreaAccessible) the map contains are attached as
// children of the appropriate accessible for HTML image
// (nsHTMLImageAccessible).
if (nsLayoutUtils::GetAllInFlowRectsUnion(weakFrame,
weakFrame->GetParent()).IsEmpty()) {
if (aIsSubtreeHidden)
*aIsSubtreeHidden = true;

View File

@ -65,6 +65,7 @@ _TEST_FILES =\
test_img.html \
test_invalidationlist.html \
test_list.html \
test_map.html \
test_media.html \
test_select.html \
test_tabbox.xul \

View File

@ -0,0 +1,83 @@
<!DOCTYPE html>
<html>
<head>
<title>HTML map accessible tree tests</title>
<link rel="stylesheet" type="text/css"
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="../common.js"></script>
<script type="application/javascript"
src="../role.js"></script>
<script type="application/javascript">
function doTest()
{
// map used as imagemap, not accessible
var accTree =
{ SECTION: [ ] };
testAccessibleTree("imagemapcontainer", accTree);
// map group
accTree =
{ PARAGRAPH: [
{ PARAGRAPH: [
{ TEXT_LEAF: [ ] },
{ LINK: [
{ TEXT_LEAF: [ ] }
] },
{ TEXT_LEAF: [ ] },
{ LINK: [
{ TEXT_LEAF: [ ] }
] },
{ TEXT_LEAF: [ ] }
] }
] };
testAccessibleTree("mapgroup", accTree);
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
</script>
</head>
<body>
<a target="_blank"
title="Map used for grouping is not accessible under certain circumstances"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=627718">
Mozilla Bug 627718
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<div id="imagemapcontainer">
<map name="atoz_map">
<area href="http://www.bbc.co.uk/radio4/atoz/index.shtml#b"
coords="17,0,30,14" alt="b" shape="rect">
<area href="http://www.bbc.co.uk/radio4/atoz/index.shtml#a"
coords="0,0,13,14" alt="a" shape="rect">
</map>
</div>
<img id="imgmap" width="447" height="15"
usemap="#atoz_map"
src="../letters.gif">
<map id="mapgroup" title="Navigation Bar" name="mapgroup">
<p>
[<a href="#how">Bypass navigation bar</a>]
[<a href="home.html">Home</a>]
</p>
</map>
</body>
</html>

View File

@ -27,7 +27,6 @@ export MOZILLA_OFFICIAL=1
export MOZ_TELEMETRY_REPORTING=1
# PGO
mk_add_options MOZ_PGO=1
mk_add_options PROFILE_GEN_SCRIPT='$(PYTHON) @MOZ_OBJDIR@/_profile/pgo/profileserver.py 10'
# Enable parallel compiling

View File

@ -22,7 +22,6 @@ ac_add_options --enable-debug-symbols="-gdwarf-2"
export MOZILLA_OFFICIAL=1
# PGO
mk_add_options MOZ_PGO=1
mk_add_options PROFILE_GEN_SCRIPT='$(PYTHON) @MOZ_OBJDIR@/_profile/pgo/profileserver.py 10'
# Enable parallel compiling

View File

@ -19,7 +19,6 @@ export MOZ_DEBUG_SYMBOLS=1
ac_add_options --enable-debug-symbols="-gdwarf-2"
# PGO
mk_add_options MOZ_PGO=1
mk_add_options PROFILE_GEN_SCRIPT='$(PYTHON) @MOZ_OBJDIR@/_profile/pgo/profileserver.py 10'
# Needed to enable breakpad in application.ini

View File

@ -30,7 +30,7 @@ ac_add_options --enable-debug-symbols="-gdwarf-2"
export MOZILLA_OFFICIAL=1
export MOZ_TELEMETRY_REPORTING=1
mk_add_options MOZ_PGO=1
mk_add_options PROFILE_GEN_SCRIPT='$(PYTHON) @MOZ_OBJDIR@/_profile/pgo/profileserver.py'
# Enable parallel compiling

View File

@ -27,7 +27,6 @@ export MOZILLA_OFFICIAL=1
export MOZ_TELEMETRY_REPORTING=1
# PGO
mk_add_options MOZ_PGO=1
mk_add_options PROFILE_GEN_SCRIPT='$(PYTHON) @MOZ_OBJDIR@/_profile/pgo/profileserver.py 10'
# Enable parallel compiling

View File

@ -19,7 +19,6 @@ export MOZ_DEBUG_SYMBOLS=1
ac_add_options --enable-debug-symbols="-gdwarf-2"
# PGO
mk_add_options MOZ_PGO=1
mk_add_options PROFILE_GEN_SCRIPT='$(PYTHON) @MOZ_OBJDIR@/_profile/pgo/profileserver.py 10'
# Needed to enable breakpad in application.ini

View File

@ -30,7 +30,7 @@ ac_add_options --enable-debug-symbols="-gdwarf-2"
export MOZILLA_OFFICIAL=1
export MOZ_TELEMETRY_REPORTING=1
mk_add_options MOZ_PGO=1
mk_add_options PROFILE_GEN_SCRIPT='$(PYTHON) @MOZ_OBJDIR@/_profile/pgo/profileserver.py'
# Enable parallel compiling

View File

@ -2027,6 +2027,10 @@ case "$target" in
MKCSHLIB='$(CC) $(CFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -o $@'
MOZ_OPTIMIZE_FLAGS="-O3"
_PEDANTIC=
# Due to performance regressions, statically disable jemalloc on 10.5. See bug 414946.
if test "$HAVE_64BIT_OS"; then
MOZ_MEMORY=1
fi
CFLAGS="$CFLAGS -fno-common"
CXXFLAGS="$CXXFLAGS -fno-common"
DLL_SUFFIX=".dylib"
@ -6859,7 +6863,7 @@ if test "$GNU_CC" -a "$GCC_USE_GNU_LD" -a -n "$MOZ_DEBUG_FLAGS"; then
fi
else
dnl We really don't expect to get here, but just in case
AC_ERROR([couldn't compile a simple C file])
GC_SECTIONS_BREAKS_DEBUG_RANGES="no, but it's broken in some other way"
fi
rm -rf conftest*])
if test "$GC_SECTIONS_BREAKS_DEBUG_RANGES" = no; then

View File

@ -3682,6 +3682,27 @@ nsCanvasRenderingContext2DAzure::DrawImage(nsIDOMElement *imgElt, float a1,
imgSize = gfxIntSize(mWidth, mHeight);
}
// Special case for Canvas, which could be an Azure canvas!
if (canvas) {
if (canvas->CountContexts() == 1) {
nsICanvasRenderingContextInternal *srcCanvas = canvas->GetContextAtIndex(0);
// This might not be an Azure canvas!
if (srcCanvas) {
srcSurf = srcCanvas->GetSurfaceSnapshot();
if (srcSurf && mCanvasElement) {
// Do security check here.
CanvasUtils::DoDrawImageSecurityCheck(HTMLCanvasElement(),
content->NodePrincipal(), canvas->IsWriteOnly(),
false);
imgSize = gfxIntSize(srcSurf->GetSize().width, srcSurf->GetSize().height);
}
}
}
}
if (!srcSurf) {
// The canvas spec says that drawImage should draw the first frame
// of animated images

View File

@ -77,6 +77,12 @@ export:: sqlite-version.h
endif
endif
ifeq (Darwin,$(OS_TARGET))
# On OSX, with jemalloc enabled, having sqlite linked against mozutils
# causes crashes in NSS standalone tools.
MOZ_UTILS_LDFLAGS =
endif
# XXX Force -O2 optimisation on Mac because using the default -O3 causes
# crashes. See bug 676499.
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))

View File

@ -22,16 +22,14 @@
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-feature android:name="android.hardware.location" android:required="false"/>
<uses-feature android:name="android.hardware.location.gps" android:required="false"/>
<uses-feature android:name="android.hardware.touchscreen"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-feature android:name="android.hardware.camera" android:required="false"/>
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
<application android:label="@MOZ_APP_DISPLAYNAME@"
android:icon="@drawable/icon"

View File

@ -697,11 +697,11 @@ public class GeckoAppShell
// "Installs" an application by creating a shortcut
static void createShortcut(String aTitle, String aURI, String aIconData, String aType) {
Log.w("GeckoAppJava", "createShortcut for " + aURI + " [" + aTitle + "]");
Log.w("GeckoAppJava", "createShortcut for " + aURI + " [" + aTitle + "] > " + aType);
// the intent to be launched by the shortcut
Intent shortcutIntent = new Intent();
if (aType == "webapp") {
if (aType.equalsIgnoreCase("webapp")) {
shortcutIntent.setAction("org.mozilla.gecko.WEBAPP");
shortcutIntent.putExtra("args", "--webapp=" + aURI);
} else {
@ -1548,7 +1548,12 @@ public class GeckoAppShell
}
try {
sCamera = android.hardware.Camera.open(aCamera);
// no front/back camera before API level 9
if (Build.VERSION.SDK_INT >= 9)
sCamera = android.hardware.Camera.open(aCamera);
else
sCamera = android.hardware.Camera.open();
android.hardware.Camera.Parameters params = sCamera.getParameters();
params.setPreviewFormat(ImageFormat.NV21);
@ -1579,7 +1584,7 @@ public class GeckoAppShell
bufferSize = size.width * size.height;
}
}
sCamera.setParameters(params);
sCameraBuffer = new byte[(bufferSize * 12) / 8];
sCamera.addCallbackBuffer(sCameraBuffer);

View File

@ -41,6 +41,9 @@
package @ANDROID_PACKAGE_NAME@;
import java.io.*;
import java.util.*;
import org.json.*;
import org.mozilla.gecko.*;
@ -58,60 +61,9 @@ import android.graphics.*;
public class LauncherShortcuts extends ListActivity {
public static final String CREATE_SHORTCUT = "org.mozilla.gecko.CREATE_SHORTCUT";
public class LauncherCursorAdapter extends SimpleCursorAdapter {
private Cursor _cursor;
private Context _context;
public LauncherCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
// Using the older, deprecated constructor so we can work on API < 11
super(context, layout, c, from, to);
_cursor = c;
_context = context;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
ImageView imageView = (ImageView) view.findViewById(R.id.favicon);
String favicon = cursor.getString(3);
byte[] raw = Base64.decode(favicon.substring(22), Base64.DEFAULT);
Bitmap bitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeByteArray(raw, 0, raw.length), 48, 48, true);
imageView.setImageBitmap(bitmap);
super.bindView(view, context, cursor);
}
}
private Cursor getCursor(Context context) {
File home = new File(context.getFilesDir(), "mozilla");
if (!home.exists())
return null;
File profile = null;
String[] files = home.list();
for (int i = 0; i < files.length; i++) {
if (files[i].endsWith(".default")) {
profile = new File(home, files[i]);
break;
}
}
if (profile == null)
return null;
File webapps = new File(profile, "webapps.sqlite");
if (!webapps.exists())
return null;
Log.i("LauncherShortcuts", "Opening: " + webapps.getPath());
mDb = SQLiteDatabase.openDatabase(webapps.getPath(), null, SQLiteDatabase.OPEN_READONLY | SQLiteDatabase.NO_LOCALIZED_COLLATORS);
return mDb.rawQuery("SELECT rowid as _id, title, uri, icon FROM webapps", null);
}
private Cursor mCursor;
private SQLiteDatabase mDb;
private ArrayList <HashMap<String, String>> mWebappsList;
private File mWebappsFolder;
@Override
public void onCreate(Bundle savedInstanceState) {
@ -123,41 +75,46 @@ public class LauncherShortcuts extends ListActivity {
final String action = intent.getAction();
if (Intent.ACTION_CREATE_SHORTCUT.equals(action)) {
mCursor = getCursor(this);
if (mCursor != null) {
// After selecting an item, the empty view can flash on screen. Clear
// the text so we don't see it.
TextView emptyText = (TextView)findViewById(android.R.id.empty);
emptyText.setText("");
// Load the list using a custom adapter so we can create the bitmaps
ListAdapter adapter = new LauncherCursorAdapter(
this,
R.layout.launch_app_listitem,
mCursor,
new String[] {"title"},
new int[] {R.id.title}
);
setListAdapter(adapter);
}
// Doing it as a background task, as it involves file access
new FetchWebApps().execute();
}
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
mCursor.moveToPosition(position);
HashMap<String, String> map = mWebappsList.get((int) id);
String uri = map.get("uri").toString();
String title = map.get("title").toString();
String appKey = map.get("appKey").toString();
String favicon = map.get("favicon").toString();
File manifestFile = new File(mWebappsFolder, appKey + "/manifest.json");
// Parse the contents into a string
String manifestJson = new String();
try {
BufferedReader in = new BufferedReader(new FileReader(manifestFile));
String line = new String();
while ((line = in.readLine()) != null) {
manifestJson += line;
}
} catch (IOException e) { }
try {
JSONObject manifest = (JSONObject) new JSONTokener(manifestJson).nextValue();
uri += manifest.getString("launch_path");
} catch (JSONException e) { }
Intent shortcutintent = new Intent("org.mozilla.gecko.WEBAPP");
shortcutintent.setClass(this, App.class);
shortcutintent.putExtra("args", "--webapp=" + mCursor.getString(2));
shortcutintent.putExtra("args", "--webapp=" + uri);
Intent intent = new Intent();
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, mCursor.getString(1));
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, title);
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutintent);
String favicon = mCursor.getString(3);
byte[] raw = Base64.decode(favicon.substring(22), Base64.DEFAULT);
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int size;
@ -172,13 +129,104 @@ public class LauncherShortcuts extends ListActivity {
size = 72;
}
Bitmap bitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeByteArray(raw, 0, raw.length), size, size, true);
Bitmap bitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeFile(favicon), size, size, true);
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, bitmap);
// Now, return the result to the launcher
setResult(RESULT_OK, intent);
mDb.close();
mCursor.close();
finish();
}
private class FetchWebApps extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... unused) {
mWebappsList = null;
Context context = getApplicationContext();
File home = new File(context.getFilesDir(), "mozilla");
if (!home.exists())
home = new File(context.getExternalFilesDir(null).getPath(), "mozilla");
if (!home.exists())
return null;
File profile = null;
String[] files = home.list();
for (String file : files) {
if (file.endsWith(".default")) {
profile = new File(home, file);
break;
}
}
if (profile == null)
return null;
// Save the folder path to be used during click event
mWebappsFolder = new File(profile, "webapps");
if (!mWebappsFolder.exists())
return null;
File webapps = new File(mWebappsFolder, "webapps.json");
if (!webapps.exists())
return null;
// Parse the contents into a string
String webappsJson = new String();
try {
BufferedReader in = new BufferedReader(new FileReader(webapps));
String line = new String();
while ((line = in.readLine()) != null) {
webappsJson += line;
}
} catch (IOException e) { }
if (webappsJson.length() == 0)
return null;
mWebappsList = new ArrayList<HashMap<String, String>>();
try {
JSONObject webApps = (JSONObject) new JSONTokener(webappsJson).nextValue();
Iterator<Object> appKeys = webApps.keys();
HashMap<String, String> map;
while (appKeys.hasNext()) {
String appKey = appKeys.next().toString();
JSONObject app = webApps.getJSONObject(appKey);
map = new HashMap<String, String>();
map.put("appKey", appKey);
map.put("favicon", mWebappsFolder.getPath() + "/" + appKey + "/icon.png");
map.put("title", app.getString("title"));
map.put("uri", app.getString("appURI"));
mWebappsList.add(map);
}
} catch (JSONException e) {}
return null;
}
@Override
protected void onPostExecute(Void unused) {
if (mWebappsList != null) {
TextView emptyText = (TextView)findViewById(android.R.id.empty);
emptyText.setText("");
setListAdapter(new SimpleAdapter(
LauncherShortcuts.this,
mWebappsList,
R.layout.launch_app_listitem,
new String[] { "favicon", "title" },
new int[] { R.id.favicon, R.id.title }
));
}
}
}
}

View File

@ -59,12 +59,33 @@
#define ARCH_CPU_ARMEL 1
#define ARCH_CPU_32_BITS 1
#define WCHAR_T_IS_UNSIGNED 1
#elif defined(__powerpc64__)
#define ARCH_CPU_PPC64 1
#define ARCH_CPU_64_BITS 1
#elif defined(__ppc__) || defined(__powerpc__)
#define ARCH_CPU_PPC 1
#define ARCH_CPU_32_BITS 1
#elif defined(__sparc64__)
#define ARCH_CPU_SPARC 1
#define ARCH_CPU_64_BITS 1
#elif defined(__sparc__)
#define ARCH_CPU_SPARC 1
#define ARCH_CPU_32_BITS 1
#elif defined(__mips__)
#define ARCH_CPU_MIPS 1
#define ARCH_CPU_32_BITS 1
#elif defined(__hppa__)
#define ARCH_CPU_HPPA 1
#define ARCH_CPU_32_BITS 1
#elif defined(__ia64__)
#define ARCH_CPU_IA64 1
#define ARCH_CPU_64_BITS 1
#elif defined(__s390x__)
#define ARCH_CPU_S390X 1
#define ARCH_CPU_64_BITS 1
#elif defined(__s390__)
#define ARCH_CPU_S390 1
#define ARCH_CPU_32_BITS 1
#else
#error Please add support for your architecture in build/build_config.h
#endif

View File

@ -195,7 +195,7 @@ struct ParamTraits<unsigned long long> {
};
#endif
#if !(defined(OS_MACOSX) || defined(OS_OPENBSD) || defined(OS_WIN) || (defined(OS_LINUX) && defined(ARCH_CPU_64_BITS)))
#if !(defined(OS_MACOSX) || defined(OS_OPENBSD) || defined(OS_WIN) || (defined(OS_LINUX) && defined(ARCH_CPU_64_BITS)) || defined(ARCH_CPU_S390))
// There size_t is a synonym for |unsigned long| ...
template <>
struct ParamTraits<size_t> {

View File

@ -2937,10 +2937,11 @@ private:
{
// A base of esp or r12 would be interpreted as a sib, so force a sib with no index & put the base in there.
#if WTF_CPU_X86_64
if ((base == hasSib) || (base == hasSib2)) {
if ((base == hasSib) || (base == hasSib2))
#else
if (base == hasSib) {
if (base == hasSib)
#endif
{
if (!offset) // No need to check if the base is noBase, since we know it is hasSib!
putModRmSib(ModRmMemoryNoDisp, reg, base, noIndex, 0);
else if (CAN_SIGN_EXTEND_8_32(offset)) {
@ -2971,10 +2972,11 @@ private:
{
// A base of esp or r12 would be interpreted as a sib, so force a sib with no index & put the base in there.
#if WTF_CPU_X86_64
if ((base == hasSib) || (base == hasSib2)) {
if ((base == hasSib) || (base == hasSib2))
#else
if (base == hasSib) {
if (base == hasSib)
#endif
{
putModRmSib(ModRmMemoryDisp32, reg, base, noIndex, 0);
m_buffer.putIntUnchecked(offset);
} else {

View File

@ -0,0 +1,4 @@
var s = 'abcdFF0123456789012345fail';
s = s.replace("abcd", "0123456789012345678901234567890123456789012FF");
s = s.replace("FF0123456789012345fail", "ok");
assertEq(s, '0123456789012345678901234567890123456789012FFok');

View File

@ -2,16 +2,18 @@
var g1 = newGlobal('same-compartment');
var g2 = newGlobal('new-compartment');
var scriptedProxy = Proxy.create(
{ getOwnPropertyDescriptor: function() assertEq(true,false),
getPropertyDescriptor: function() assertEq(true,false),
getOwnPropertyNames: function() assertEq(true,false),
getPropertyNames: function() assertEq(true,false),
defineProperty: function() assertEq(true,false),
delete: function() assertEq(true,false),
fix: function() assertEq(true,false), },
Object.prototype
);
var proxyStr = "Proxy.create( "+
" { getOwnPropertyDescriptor: function() assertEq(true,false), "+
" getPropertyDescriptor: function() assertEq(true,false), "+
" getOwnPropertyNames: function() assertEq(true,false), "+
" getPropertyNames: function() assertEq(true,false), "+
" defineProperty: function() assertEq(true,false), "+
" delete: function() assertEq(true,false), "+
" fix: function() assertEq(true,false), }, "+
" Object.prototype "+
"); ";
var proxy1 = g1.eval(proxyStr);
var proxy2 = g2.eval(proxyStr);
function test(str, f) {
"use strict";
@ -40,7 +42,16 @@ function test(str, f) {
assertEq(threw, true);
threw = false;
try {
f(scriptedProxy);
f(proxy1);
} catch (e) {
assertEq(Object.prototype.toString.call(e), "[object Error]");
assertEq(e.name, "TypeError");
threw = true;
}
assertEq(threw, true);
threw = false;
try {
f(proxy2);
} catch (e) {
assertEq(Object.prototype.toString.call(e), "[object Error]");
assertEq(e.name, "TypeError");

View File

@ -1323,13 +1323,20 @@ JS_LeaveCrossCompartmentCall(JSCrossCompartmentCall *call)
bool
JSAutoEnterCompartment::enter(JSContext *cx, JSObject *target)
{
JS_ASSERT(!call);
JS_ASSERT(state == STATE_UNENTERED);
if (cx->compartment == target->compartment()) {
call = reinterpret_cast<JSCrossCompartmentCall*>(1);
state = STATE_SAME_COMPARTMENT;
return true;
}
call = JS_EnterCrossCompartmentCall(cx, target);
return call != NULL;
JS_STATIC_ASSERT(sizeof(bytes) == sizeof(AutoCompartment));
CHECK_REQUEST(cx);
AutoCompartment *call = new (bytes) AutoCompartment(cx, target);
if (call->enter()) {
state = STATE_OTHER_COMPARTMENT;
return true;
}
return false;
}
void
@ -1338,6 +1345,15 @@ JSAutoEnterCompartment::enterAndIgnoreErrors(JSContext *cx, JSObject *target)
(void) enter(cx, target);
}
JSAutoEnterCompartment::~JSAutoEnterCompartment()
{
if (state == STATE_OTHER_COMPARTMENT) {
AutoCompartment* ac = reinterpret_cast<AutoCompartment*>(bytes);
CHECK_REQUEST(ac->context);
ac->~AutoCompartment();
}
}
namespace JS {
bool

View File

@ -2214,27 +2214,41 @@ JS_END_EXTERN_C
class JS_PUBLIC_API(JSAutoEnterCompartment)
{
JSCrossCompartmentCall *call;
/*
* This is a poor man's Maybe<AutoCompartment>, because we don't have
* access to the AutoCompartment definition here. We statically assert in
* jsapi.cpp that we have the right size here.
*/
#if !defined(_MSC_VER) && !defined(__arm__)
void* bytes[13];
#else
void* bytes[sizeof(void*) == 4 ? 16 : 13];
#endif
/*
* This object may be in one of three states. If enter() or
* enterAndIgnoreErrors() hasn't been called, it's in STATE_UNENTERED.
* Otherwise, if we were asked to enter into the current compartment, our
* state is STATE_SAME_COMPARTMENT. If we actually created an
* AutoCompartment and entered another compartment, our state is
* STATE_OTHER_COMPARTMENT.
*/
enum State {
STATE_UNENTERED,
STATE_SAME_COMPARTMENT,
STATE_OTHER_COMPARTMENT
} state;
public:
JSAutoEnterCompartment() : call(NULL) {}
JSAutoEnterCompartment() : state(STATE_UNENTERED) {}
bool enter(JSContext *cx, JSObject *target);
void enterAndIgnoreErrors(JSContext *cx, JSObject *target);
bool entered() const { return call != NULL; }
bool entered() const { return state != STATE_UNENTERED; }
~JSAutoEnterCompartment() {
if (call && call != reinterpret_cast<JSCrossCompartmentCall*>(1))
JS_LeaveCrossCompartmentCall(call);
}
void swap(JSAutoEnterCompartment &other) {
JSCrossCompartmentCall *tmp = call;
call = other.call;
other.call = tmp;
}
~JSAutoEnterCompartment();
};
JS_BEGIN_EXTERN_C

View File

@ -1442,7 +1442,7 @@ array_toSource(JSContext *cx, uintN argc, Value *vp)
if (!obj)
return false;
if (!obj->isArray())
return HandleNonGenericMethodClassMismatch(cx, args, &ArrayClass);
return HandleNonGenericMethodClassMismatch(cx, args, array_toSource, &ArrayClass);
ArraySharpDetector detector(cx);
if (!detector.init(obj))

View File

@ -84,7 +84,7 @@ bool_toSource(JSContext *cx, uintN argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
bool b, ok;
if (!BoxedPrimitiveMethodGuard(cx, args, &b, &ok))
if (!BoxedPrimitiveMethodGuard(cx, args, bool_toSource, &b, &ok))
return ok;
char buf[32];
@ -103,7 +103,7 @@ bool_toString(JSContext *cx, uintN argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
bool b, ok;
if (!BoxedPrimitiveMethodGuard<bool>(cx, args, &b, &ok))
if (!BoxedPrimitiveMethodGuard<bool>(cx, args, bool_toString, &b, &ok))
return ok;
args.rval().setString(cx->runtime->atomState.booleanAtoms[b ? 1 : 0]);
@ -116,7 +116,7 @@ bool_valueOf(JSContext *cx, uintN argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
bool b, ok;
if (!BoxedPrimitiveMethodGuard(cx, args, &b, &ok))
if (!BoxedPrimitiveMethodGuard(cx, args, bool_valueOf, &b, &ok))
return ok;
args.rval().setBoolean(b);

View File

@ -1420,7 +1420,7 @@ date_getTime(JSContext *cx, uintN argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &DateClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, date_getTime, &DateClass, &ok);
if (!obj)
return ok;
@ -1434,7 +1434,7 @@ date_getYear(JSContext *cx, uintN argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &DateClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, date_getYear, &DateClass, &ok);
if (!obj)
return ok;
@ -1459,7 +1459,7 @@ date_getFullYear(JSContext *cx, uintN argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &DateClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, date_getFullYear, &DateClass, &ok);
if (!obj)
return ok;
@ -1476,7 +1476,7 @@ date_getUTCFullYear(JSContext *cx, uintN argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &DateClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, date_getUTCFullYear, &DateClass, &ok);
if (!obj)
return ok;
@ -1494,7 +1494,7 @@ date_getMonth(JSContext *cx, uintN argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &DateClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, date_getMonth, &DateClass, &ok);
if (!obj)
return ok;
@ -1511,7 +1511,7 @@ date_getUTCMonth(JSContext *cx, uintN argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &DateClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, date_getUTCMonth, &DateClass, &ok);
if (!obj)
return ok;
@ -1529,7 +1529,7 @@ date_getDate(JSContext *cx, uintN argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &DateClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, date_getDate, &DateClass, &ok);
if (!obj)
return ok;
@ -1546,7 +1546,7 @@ date_getUTCDate(JSContext *cx, uintN argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &DateClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, date_getUTCDate, &DateClass, &ok);
if (!obj)
return ok;
@ -1564,7 +1564,7 @@ date_getDay(JSContext *cx, uintN argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &DateClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, date_getDay, &DateClass, &ok);
if (!obj)
return ok;
@ -1581,7 +1581,7 @@ date_getUTCDay(JSContext *cx, uintN argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &DateClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, date_getUTCDay, &DateClass, &ok);
if (!obj)
return ok;
@ -1599,7 +1599,7 @@ date_getHours(JSContext *cx, uintN argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &DateClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, date_getHours, &DateClass, &ok);
if (!obj)
return ok;
@ -1616,7 +1616,7 @@ date_getUTCHours(JSContext *cx, uintN argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &DateClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, date_getUTCHours, &DateClass, &ok);
if (!obj)
return ok;
@ -1634,7 +1634,7 @@ date_getMinutes(JSContext *cx, uintN argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &DateClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, date_getMinutes, &DateClass, &ok);
if (!obj)
return ok;
@ -1651,7 +1651,7 @@ date_getUTCMinutes(JSContext *cx, uintN argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &DateClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, date_getUTCMinutes, &DateClass, &ok);
if (!obj)
return ok;
@ -1671,7 +1671,7 @@ date_getUTCSeconds(JSContext *cx, uintN argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &DateClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, date_getUTCSeconds, &DateClass, &ok);
if (!obj)
return ok;
@ -1690,7 +1690,7 @@ date_getUTCMilliseconds(JSContext *cx, uintN argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &DateClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, date_getUTCMilliseconds, &DateClass, &ok);
if (!obj)
return ok;
@ -1708,7 +1708,7 @@ date_getTimezoneOffset(JSContext *cx, uintN argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &DateClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, date_getTimezoneOffset, &DateClass, &ok);
if (!obj)
return ok;
@ -1734,7 +1734,7 @@ date_setTime(JSContext *cx, uintN argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &DateClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, date_setTime, &DateClass, &ok);
if (!obj)
return ok;
@ -1751,12 +1751,12 @@ date_setTime(JSContext *cx, uintN argc, Value *vp)
}
static JSBool
date_makeTime(JSContext *cx, uintN maxargs, JSBool local, uintN argc, Value *vp)
date_makeTime(JSContext *cx, Native native, uintN maxargs, JSBool local, uintN argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &DateClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, native, &DateClass, &ok);
if (!obj)
return ok;
@ -1839,58 +1839,58 @@ date_makeTime(JSContext *cx, uintN maxargs, JSBool local, uintN argc, Value *vp)
static JSBool
date_setMilliseconds(JSContext *cx, uintN argc, Value *vp)
{
return date_makeTime(cx, 1, JS_TRUE, argc, vp);
return date_makeTime(cx, date_setMilliseconds, 1, JS_TRUE, argc, vp);
}
static JSBool
date_setUTCMilliseconds(JSContext *cx, uintN argc, Value *vp)
{
return date_makeTime(cx, 1, JS_FALSE, argc, vp);
return date_makeTime(cx, date_setUTCMilliseconds, 1, JS_FALSE, argc, vp);
}
static JSBool
date_setSeconds(JSContext *cx, uintN argc, Value *vp)
{
return date_makeTime(cx, 2, JS_TRUE, argc, vp);
return date_makeTime(cx, date_setSeconds, 2, JS_TRUE, argc, vp);
}
static JSBool
date_setUTCSeconds(JSContext *cx, uintN argc, Value *vp)
{
return date_makeTime(cx, 2, JS_FALSE, argc, vp);
return date_makeTime(cx, date_setUTCSeconds, 2, JS_FALSE, argc, vp);
}
static JSBool
date_setMinutes(JSContext *cx, uintN argc, Value *vp)
{
return date_makeTime(cx, 3, JS_TRUE, argc, vp);
return date_makeTime(cx, date_setMinutes, 3, JS_TRUE, argc, vp);
}
static JSBool
date_setUTCMinutes(JSContext *cx, uintN argc, Value *vp)
{
return date_makeTime(cx, 3, JS_FALSE, argc, vp);
return date_makeTime(cx, date_setUTCMinutes, 3, JS_FALSE, argc, vp);
}
static JSBool
date_setHours(JSContext *cx, uintN argc, Value *vp)
{
return date_makeTime(cx, 4, JS_TRUE, argc, vp);
return date_makeTime(cx, date_setHours, 4, JS_TRUE, argc, vp);
}
static JSBool
date_setUTCHours(JSContext *cx, uintN argc, Value *vp)
{
return date_makeTime(cx, 4, JS_FALSE, argc, vp);
return date_makeTime(cx, date_setUTCHours, 4, JS_FALSE, argc, vp);
}
static JSBool
date_makeDate(JSContext *cx, uintN maxargs, JSBool local, uintN argc, Value *vp)
date_makeDate(JSContext *cx, Native native, uintN maxargs, JSBool local, uintN argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &DateClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, native, &DateClass, &ok);
if (!obj)
return ok;
@ -1962,37 +1962,37 @@ date_makeDate(JSContext *cx, uintN maxargs, JSBool local, uintN argc, Value *vp)
static JSBool
date_setDate(JSContext *cx, uintN argc, Value *vp)
{
return date_makeDate(cx, 1, JS_TRUE, argc, vp);
return date_makeDate(cx, date_setDate, 1, JS_TRUE, argc, vp);
}
static JSBool
date_setUTCDate(JSContext *cx, uintN argc, Value *vp)
{
return date_makeDate(cx, 1, JS_FALSE, argc, vp);
return date_makeDate(cx, date_setUTCDate, 1, JS_FALSE, argc, vp);
}
static JSBool
date_setMonth(JSContext *cx, uintN argc, Value *vp)
{
return date_makeDate(cx, 2, JS_TRUE, argc, vp);
return date_makeDate(cx, date_setMonth, 2, JS_TRUE, argc, vp);
}
static JSBool
date_setUTCMonth(JSContext *cx, uintN argc, Value *vp)
{
return date_makeDate(cx, 2, JS_FALSE, argc, vp);
return date_makeDate(cx, date_setUTCMonth, 2, JS_FALSE, argc, vp);
}
static JSBool
date_setFullYear(JSContext *cx, uintN argc, Value *vp)
{
return date_makeDate(cx, 3, JS_TRUE, argc, vp);
return date_makeDate(cx, date_setFullYear, 3, JS_TRUE, argc, vp);
}
static JSBool
date_setUTCFullYear(JSContext *cx, uintN argc, Value *vp)
{
return date_makeDate(cx, 3, JS_FALSE, argc, vp);
return date_makeDate(cx, date_setUTCFullYear, 3, JS_FALSE, argc, vp);
}
static JSBool
@ -2001,7 +2001,7 @@ date_setYear(JSContext *cx, uintN argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &DateClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, date_setYear, &DateClass, &ok);
if (!obj)
return ok;
@ -2073,11 +2073,11 @@ print_iso_string(char* buf, size_t size, jsdouble utctime)
}
static JSBool
date_utc_format(JSContext *cx, CallArgs args,
date_utc_format(JSContext *cx, Native native, CallArgs args,
void (*printFunc)(char*, size_t, jsdouble))
{
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &DateClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, native, &DateClass, &ok);
if (!obj)
return ok;
@ -2105,13 +2105,13 @@ date_utc_format(JSContext *cx, CallArgs args,
static JSBool
date_toGMTString(JSContext *cx, uintN argc, Value *vp)
{
return date_utc_format(cx, CallArgsFromVp(argc, vp), print_gmt_string);
return date_utc_format(cx, date_toGMTString, CallArgsFromVp(argc, vp), print_gmt_string);
}
static JSBool
date_toISOString(JSContext *cx, uintN argc, Value *vp)
{
return date_utc_format(cx, CallArgsFromVp(argc, vp), print_iso_string);
return date_utc_format(cx, date_toISOString, CallArgsFromVp(argc, vp), print_iso_string);
}
/* ES5 15.9.5.44. */
@ -2352,12 +2352,12 @@ ToLocaleHelper(JSContext *cx, CallReceiver call, JSObject *obj, const char *form
* after calling date_toLocaleHelper, even if it returns 'true'.
*/
static JSBool
date_toLocaleHelper(JSContext *cx, uintN argc, Value *vp, const char *format)
date_toLocaleHelper(JSContext *cx, uintN argc, Value *vp, Native native, const char *format)
{
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &DateClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, native, &DateClass, &ok);
if (!obj)
return ok;
@ -2365,13 +2365,13 @@ date_toLocaleHelper(JSContext *cx, uintN argc, Value *vp, const char *format)
}
static JSBool
date_toLocaleString(JSContext *cx, uintN argc, Value *vp)
date_toLocaleStringHelper(JSContext *cx, Native native, uintN argc, Value *vp)
{
/*
* Use '%#c' for windows, because '%c' is backward-compatible and non-y2k
* with msvc; '%#c' requests that a full year be used in the result string.
*/
return date_toLocaleHelper(cx, argc, vp,
return date_toLocaleHelper(cx, argc, vp, native,
#if defined(_WIN32) && !defined(__MWERKS__)
"%#c"
#else
@ -2380,6 +2380,12 @@ date_toLocaleString(JSContext *cx, uintN argc, Value *vp)
);
}
static JSBool
date_toLocaleString(JSContext *cx, uintN argc, Value *vp)
{
return date_toLocaleStringHelper(cx, date_toLocaleString, argc, vp);
}
static JSBool
date_toLocaleDateString(JSContext *cx, uintN argc, Value *vp)
{
@ -2387,7 +2393,7 @@ date_toLocaleDateString(JSContext *cx, uintN argc, Value *vp)
* Use '%#x' for windows, because '%x' is backward-compatible and non-y2k
* with msvc; '%#x' requests that a full year be used in the result string.
*/
return date_toLocaleHelper(cx, argc, vp,
return date_toLocaleHelper(cx, argc, vp, date_toLocaleDateString,
#if defined(_WIN32) && !defined(__MWERKS__)
"%#x"
#else
@ -2399,19 +2405,19 @@ date_toLocaleDateString(JSContext *cx, uintN argc, Value *vp)
static JSBool
date_toLocaleTimeString(JSContext *cx, uintN argc, Value *vp)
{
return date_toLocaleHelper(cx, argc, vp, "%X");
return date_toLocaleHelper(cx, argc, vp, date_toLocaleTimeString, "%X");
}
static JSBool
date_toLocaleFormat(JSContext *cx, uintN argc, Value *vp)
{
if (argc == 0)
return date_toLocaleString(cx, argc, vp);
return date_toLocaleStringHelper(cx, date_toLocaleFormat, argc, vp);
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &DateClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, date_toLocaleFormat, &DateClass, &ok);
if (!obj)
return ok;
@ -2433,7 +2439,7 @@ date_toTimeString(JSContext *cx, uintN argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &DateClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, date_toTimeString, &DateClass, &ok);
if (!obj)
return ok;
@ -2446,7 +2452,7 @@ date_toDateString(JSContext *cx, uintN argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &DateClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, date_toDateString, &DateClass, &ok);
if (!obj)
return ok;
@ -2463,7 +2469,7 @@ date_toSource(JSContext *cx, uintN argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &DateClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, date_toSource, &DateClass, &ok);
if (!obj)
return ok;
@ -2497,7 +2503,7 @@ date_toString(JSContext *cx, uintN argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &DateClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, date_toString, &DateClass, &ok);
if (!obj)
return ok;

View File

@ -178,34 +178,6 @@ JS_SetSingleStepMode(JSContext *cx, JSScript *script, JSBool singleStep)
return script->setStepModeFlag(cx, singleStep);
}
jsbytecode *
js_UntrapScriptCode(JSContext *cx, JSScript *script)
{
jsbytecode *code = script->code;
BreakpointSiteMap &sites = script->compartment()->breakpointSites;
for (BreakpointSiteMap::Range r = sites.all(); !r.empty(); r.popFront()) {
BreakpointSite *site = r.front().value;
if (site->script == script && size_t(site->pc - script->code) < script->length) {
if (code == script->code) {
size_t nbytes = script->length * sizeof(jsbytecode);
jssrcnote *notes = script->notes();
jssrcnote *sn;
for (sn = notes; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn))
continue;
nbytes += (sn - notes + 1) * sizeof *sn;
code = (jsbytecode *) cx->malloc_(nbytes);
if (!code)
break;
memcpy(code, script->code, nbytes);
GetGSNCache(cx)->purge();
}
code[site->pc - script->code] = site->realOpcode;
}
}
return code;
}
JS_PUBLIC_API(JSBool)
JS_SetTrap(JSContext *cx, JSScript *script, jsbytecode *pc, JSTrapHandler handler, jsval closure)
{

View File

@ -142,14 +142,6 @@ JS_SetDebugMode(JSContext *cx, JSBool debug);
extern JS_PUBLIC_API(JSBool)
JS_SetSingleStepMode(JSContext *cx, JSScript *script, JSBool singleStep);
/*
* Unexported library-private helper used to unpatch all traps in a script.
* Returns script->code if script has no traps, else a JS_malloc'ed copy of
* script->code which the caller must JS_free, or null on JS_malloc OOM.
*/
extern jsbytecode *
js_UntrapScriptCode(JSContext *cx, JSScript *script);
/* The closure argument will be marked. */
extern JS_PUBLIC_API(JSBool)
JS_SetTrap(JSContext *cx, JSScript *script, jsbytecode *pc,

View File

@ -713,7 +713,7 @@ iterator_next(JSContext *cx, uintN argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &IteratorClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, iterator_next, &IteratorClass, &ok);
if (!obj)
return ok;
@ -1335,14 +1335,14 @@ CloseGenerator(JSContext *cx, JSObject *obj)
* Common subroutine of generator_(next|send|throw|close) methods.
*/
static JSBool
generator_op(JSContext *cx, JSGeneratorOp op, Value *vp, uintN argc)
generator_op(JSContext *cx, Native native, JSGeneratorOp op, Value *vp, uintN argc)
{
LeaveTrace(cx);
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &GeneratorClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, native, &GeneratorClass, &ok);
if (!obj)
return ok;
@ -1399,25 +1399,25 @@ generator_op(JSContext *cx, JSGeneratorOp op, Value *vp, uintN argc)
static JSBool
generator_send(JSContext *cx, uintN argc, Value *vp)
{
return generator_op(cx, JSGENOP_SEND, vp, argc);
return generator_op(cx, generator_send, JSGENOP_SEND, vp, argc);
}
static JSBool
generator_next(JSContext *cx, uintN argc, Value *vp)
{
return generator_op(cx, JSGENOP_NEXT, vp, argc);
return generator_op(cx, generator_next, JSGENOP_NEXT, vp, argc);
}
static JSBool
generator_throw(JSContext *cx, uintN argc, Value *vp)
{
return generator_op(cx, JSGENOP_THROW, vp, argc);
return generator_op(cx, generator_throw, JSGENOP_THROW, vp, argc);
}
static JSBool
generator_close(JSContext *cx, uintN argc, Value *vp)
{
return generator_op(cx, JSGENOP_CLOSE, vp, argc);
return generator_op(cx, generator_close, JSGENOP_CLOSE, vp, argc);
}
static JSFunctionSpec generator_methods[] = {

View File

@ -605,7 +605,7 @@ num_toSource(JSContext *cx, uintN argc, Value *vp)
double d;
bool ok;
if (!BoxedPrimitiveMethodGuard(cx, args, &d, &ok))
if (!BoxedPrimitiveMethodGuard(cx, args, num_toSource, &d, &ok))
return ok;
ToCStringBuf cbuf;
@ -712,14 +712,14 @@ IntToCString(ToCStringBuf *cbuf, jsint i, jsint base = 10)
static JSString * JS_FASTCALL
js_NumberToStringWithBase(JSContext *cx, jsdouble d, jsint base);
static JSBool
num_toString(JSContext *cx, uintN argc, Value *vp)
static JS_ALWAYS_INLINE bool
num_toStringHelper(JSContext *cx, Native native, uintN argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
double d;
bool ok;
if (!BoxedPrimitiveMethodGuard(cx, args, &d, &ok))
if (!BoxedPrimitiveMethodGuard(cx, args, native, &d, &ok))
return ok;
int32 base = 10;
@ -738,10 +738,16 @@ num_toString(JSContext *cx, uintN argc, Value *vp)
JSString *str = js_NumberToStringWithBase(cx, d, base);
if (!str) {
JS_ReportOutOfMemory(cx);
return JS_FALSE;
return false;
}
args.rval().setString(str);
return JS_TRUE;
return true;
}
static JSBool
num_toString(JSContext *cx, uintN argc, Value *vp)
{
return num_toStringHelper(cx, num_toString, argc, vp);
}
static JSBool
@ -760,7 +766,7 @@ num_toLocaleString(JSContext *cx, uintN argc, Value *vp)
* Create the string, move back to bytes to make string twiddling
* a bit easier and so we can insert platform charset seperators.
*/
if (!num_toString(cx, 0, vp))
if (!num_toStringHelper(cx, num_toLocaleString, 0, vp))
return JS_FALSE;
JS_ASSERT(vp->isString());
JSAutoByteString numBytes(cx, vp->toString());
@ -870,7 +876,7 @@ js_num_valueOf(JSContext *cx, uintN argc, Value *vp)
double d;
bool ok;
if (!BoxedPrimitiveMethodGuard(cx, args, &d, &ok))
if (!BoxedPrimitiveMethodGuard(cx, args, js_num_valueOf, &d, &ok))
return ok;
args.rval().setNumber(d);
@ -881,7 +887,7 @@ js_num_valueOf(JSContext *cx, uintN argc, Value *vp)
#define MAX_PRECISION 100
static JSBool
num_to(JSContext *cx, JSDToStrMode zeroArgMode, JSDToStrMode oneArgMode,
num_to(JSContext *cx, Native native, JSDToStrMode zeroArgMode, JSDToStrMode oneArgMode,
jsint precisionMin, jsint precisionMax, jsint precisionOffset,
CallArgs args)
{
@ -891,7 +897,7 @@ num_to(JSContext *cx, JSDToStrMode zeroArgMode, JSDToStrMode oneArgMode,
double d;
bool ok;
if (!BoxedPrimitiveMethodGuard(cx, args, &d, &ok))
if (!BoxedPrimitiveMethodGuard(cx, args, native, &d, &ok))
return ok;
double precision;
@ -930,23 +936,23 @@ num_to(JSContext *cx, JSDToStrMode zeroArgMode, JSDToStrMode oneArgMode,
static JSBool
num_toFixed(JSContext *cx, uintN argc, Value *vp)
{
return num_to(cx, DTOSTR_FIXED, DTOSTR_FIXED, -20, MAX_PRECISION, 0,
return num_to(cx, num_toFixed, DTOSTR_FIXED, DTOSTR_FIXED, -20, MAX_PRECISION, 0,
CallArgsFromVp(argc, vp));
}
static JSBool
num_toExponential(JSContext *cx, uintN argc, Value *vp)
{
return num_to(cx, DTOSTR_STANDARD_EXPONENTIAL, DTOSTR_EXPONENTIAL, 0, MAX_PRECISION, 1,
CallArgsFromVp(argc, vp));
return num_to(cx, num_toExponential, DTOSTR_STANDARD_EXPONENTIAL, DTOSTR_EXPONENTIAL, 0,
MAX_PRECISION, 1, CallArgsFromVp(argc, vp));
}
static JSBool
num_toPrecision(JSContext *cx, uintN argc, Value *vp)
{
if (argc == 0 || vp[2].isUndefined())
return num_toString(cx, 0, vp);
return num_to(cx, DTOSTR_STANDARD, DTOSTR_PRECISION, 1, MAX_PRECISION, 0,
return num_toStringHelper(cx, num_toPrecision, 0, vp);
return num_to(cx, num_toPrecision, DTOSTR_STANDARD, DTOSTR_PRECISION, 1, MAX_PRECISION, 0,
CallArgsFromVp(argc, vp));
}

View File

@ -7090,14 +7090,12 @@ js::ReportIncompatibleMethod(JSContext *cx, CallReceiver call, Class *clasp)
}
bool
js::HandleNonGenericMethodClassMismatch(JSContext *cx, CallArgs args, Class *clasp)
js::HandleNonGenericMethodClassMismatch(JSContext *cx, CallArgs args, Native native, Class *clasp)
{
if (args.thisv().isObject()) {
JSObject &thisObj = args.thisv().toObject();
if (thisObj.isProxy()) {
Native native = args.callee().getFunctionPrivate()->native();
if (thisObj.isProxy())
return Proxy::nativeCall(cx, &thisObj, clasp, native, args);
}
}
ReportIncompatibleMethod(cx, args, clasp);

View File

@ -2206,7 +2206,7 @@ ReportIncompatibleMethod(JSContext *cx, CallReceiver call, Class *clasp);
* any effectful operations are performed.
*/
inline JSObject *
NonGenericMethodGuard(JSContext *cx, CallArgs args, Class *clasp, bool *ok);
NonGenericMethodGuard(JSContext *cx, CallArgs args, Native native, Class *clasp, bool *ok);
/*
* NonGenericMethodGuard tests args.thisv's class using 'clasp'. If more than
@ -2216,7 +2216,7 @@ NonGenericMethodGuard(JSContext *cx, CallArgs args, Class *clasp, bool *ok);
* for error reporting (clasp->name).
*/
extern bool
HandleNonGenericMethodClassMismatch(JSContext *cx, CallArgs args, Class *clasp);
HandleNonGenericMethodClassMismatch(JSContext *cx, CallArgs args, Native native, Class *clasp);
/*
* Implement the extraction of a primitive from a value as needed for the
@ -2227,7 +2227,7 @@ HandleNonGenericMethodClassMismatch(JSContext *cx, CallArgs args, Class *clasp);
*/
template <typename T>
inline bool
BoxedPrimitiveMethodGuard(JSContext *cx, CallArgs args, T *v, bool *ok);
BoxedPrimitiveMethodGuard(JSContext *cx, CallArgs args, Native native, T *v, bool *ok);
} /* namespace js */

View File

@ -1734,7 +1734,7 @@ class PrimitiveBehavior<double> {
} /* namespace detail */
inline JSObject *
NonGenericMethodGuard(JSContext *cx, CallArgs args, Class *clasp, bool *ok)
NonGenericMethodGuard(JSContext *cx, CallArgs args, Native native, Class *clasp, bool *ok)
{
const Value &thisv = args.thisv();
if (thisv.isObject()) {
@ -1745,13 +1745,13 @@ NonGenericMethodGuard(JSContext *cx, CallArgs args, Class *clasp, bool *ok)
}
}
*ok = HandleNonGenericMethodClassMismatch(cx, args, clasp);
*ok = HandleNonGenericMethodClassMismatch(cx, args, native, clasp);
return NULL;
}
template <typename T>
inline bool
BoxedPrimitiveMethodGuard(JSContext *cx, CallArgs args, T *v, bool *ok)
BoxedPrimitiveMethodGuard(JSContext *cx, CallArgs args, Native native, T *v, bool *ok)
{
typedef detail::PrimitiveBehavior<T> Behavior;
@ -1761,7 +1761,7 @@ BoxedPrimitiveMethodGuard(JSContext *cx, CallArgs args, T *v, bool *ok)
return true;
}
if (!NonGenericMethodGuard(cx, args, Behavior::getClass(), ok))
if (!NonGenericMethodGuard(cx, args, native, Behavior::getClass(), ok))
return false;
*v = Behavior::extract(thisv.toObject().getPrimitiveThis());

View File

@ -71,6 +71,8 @@
#include "jsstaticcheck.h"
#include "jsvector.h"
#include "vm/Debugger.h"
#include "jscntxtinlines.h"
#include "jsobjinlines.h"
#include "jsopcodeinlines.h"
@ -236,48 +238,57 @@ js_GetEnterBlockStackDefs(JSContext *cx, JSScript *script, jsbytecode *pc)
return OBJ_BLOCK_COUNT(cx, obj);
}
class AutoScriptUntrapper {
JSContext *cx;
JSScript *script;
jsbytecode *origPC;
jsbytecode *newPC;
#ifdef DEBUG
bool assertionBefore;
#endif
AutoScriptUntrapper::AutoScriptUntrapper()
: origScript(NULL), origCode(NULL)
{}
public:
AutoScriptUntrapper(JSContext *cx, JSScript *script, jsbytecode **pc)
: cx(cx), script(script), origPC(*pc)
#ifdef DEBUG
, assertionBefore(false)
#endif
{
jsbytecode *newCode = js_UntrapScriptCode(cx, script);
if (newCode == script->code) {
// No change needed
newPC = origPC;
} else {
*pc = newPC = origPC + (newCode - script->code);
script->code = newCode;
#ifdef DEBUG
assertionBefore = cx->stackIterAssertionEnabled;
cx->stackIterAssertionEnabled = false;
#endif
bool
AutoScriptUntrapper::untrap(JSContext *cx, JSScript *script)
{
JS_ASSERT(!origScript && !origCode);
BreakpointSiteMap &sites = script->compartment()->breakpointSites;
for (BreakpointSiteMap::Range r = sites.all(); !r.empty(); r.popFront()) {
BreakpointSite *site = r.front().value;
if (site->script == script) {
JS_ASSERT(size_t(site->pc - script->code) < script->length);
if (size_t(site->pc - script->code) >= script->length)
continue;
ptrdiff_t off = site->pc - script->code;
if (script->code[off] == site->realOpcode)
continue;
if (!origCode && !saveOriginal(script))
return false;
script->code[site->pc - script->code] = site->realOpcode;
}
}
~AutoScriptUntrapper()
{
ptrdiff_t delta = newPC - origPC;
if (delta) {
jsbytecode *oldCode = script->code - delta;
cx->free_(script->code);
script->code = oldCode;
#ifdef DEBUG
cx->stackIterAssertionEnabled = assertionBefore;
#endif
}
if (origCode)
GetGSNCache(cx)->purge();
return true;
}
bool
AutoScriptUntrapper::saveOriginal(JSScript *script)
{
nbytes = script->length * sizeof(jsbytecode);
origCode = (jsbytecode *) OffTheBooks::malloc_(nbytes);
if (!origCode)
return false;
memcpy(origCode, script->code, nbytes);
origScript = script;
return true;
}
AutoScriptUntrapper::~AutoScriptUntrapper()
{
JS_ASSERT(!!origCode == !!origScript);
if (origCode) {
memcpy(origScript->code, origCode, nbytes);
Foreground::free_(origCode);
}
};
}
#ifdef DEBUG
@ -437,20 +448,11 @@ JS_FRIEND_API(uintN)
js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
uintN loc, JSBool lines, Sprinter *sp)
{
JSOp op;
const JSCodeSpec *cs;
ptrdiff_t len, off, jmplen;
uint32 type;
JSAtom *atom;
uintN index;
JSObject *obj;
jsval v;
jsint i;
JSPCCounters& counts(script->pcCounters);
AutoScriptUntrapper untrapper;
if (!untrapper.untrap(cx, script))
return 0;
AutoScriptUntrapper untrapper(cx, script, &pc);
op = (JSOp)*pc;
JSOp op = (JSOp)*pc;
if (op >= JSOP_LIMIT) {
char numBuf1[12], numBuf2[12];
JS_snprintf(numBuf1, sizeof numBuf1, "%d", op);
@ -459,10 +461,10 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
JSMSG_BYTECODE_TOO_BIG, numBuf1, numBuf2);
return 0;
}
cs = &js_CodeSpec[op];
len = (ptrdiff_t) cs->length;
const JSCodeSpec *cs = &js_CodeSpec[op];
ptrdiff_t len = (ptrdiff_t) cs->length;
Sprint(sp, "%05u:", loc);
if (counts) {
if (JSPCCounters &counts = script->pcCounters) {
ptrdiff_t start = Sprint(sp, "%.0f", counts.get(0, loc));
for (size_t i = 1; i < JSPCCounters::NUM_COUNTERS; ++i)
Sprint(sp, "/%.0f", counts.get(i, loc));
@ -480,8 +482,8 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
if (lines)
Sprint(sp, "%4u", JS_PCToLineNumber(cx, script, pc));
Sprint(sp, " %s", js_CodeName[op]);
type = JOF_TYPE(cs->format);
switch (type) {
switch (uint32 type = JOF_TYPE(cs->format)) {
case JOF_BYTE:
// Scan the trynotes to find the associated catch block
// and make the try opcode look like a jump instruction
@ -503,23 +505,27 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
break;
case JOF_JUMP:
case JOF_JUMPX:
off = GetJumpOffset(pc, pc);
case JOF_JUMPX: {
ptrdiff_t off = GetJumpOffset(pc, pc);
Sprint(sp, " %u (%+d)", loc + (intN) off, (intN) off);
break;
}
case JOF_ATOM:
case JOF_OBJECT:
case JOF_REGEXP:
index = js_GetIndexFromBytecode(cx, script, pc, 0);
case JOF_REGEXP: {
uintN index = js_GetIndexFromBytecode(cx, script, pc, 0);
jsval v;
if (type == JOF_ATOM) {
if (op == JSOP_DOUBLE) {
v = script->getConst(index);
} else {
JSAtom *atom;
JS_GET_SCRIPT_ATOM(script, pc, index, atom);
v = STRING_TO_JSVAL(atom);
}
} else {
JSObject *obj;
if (type == JOF_OBJECT) {
/* Don't call obj.toSource if analysis/inference is active. */
if (cx->compartment->activeAnalysis) {
@ -539,16 +545,7 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
Sprint(sp, " %s", bytes.ptr());
}
break;
case JOF_UINT16PAIR:
i = (jsint)GET_UINT16(pc);
Sprint(sp, " %d", i);
pc += UINT16_LEN;
/* FALL THROUGH */
case JOF_UINT16:
i = (jsint)GET_UINT16(pc);
goto print_int;
}
case JOF_TABLESWITCH:
case JOF_TABLESWITCHX:
@ -556,10 +553,9 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
jsbytecode *pc2;
jsint i, low, high;
jmplen = (type == JOF_TABLESWITCH) ? JUMP_OFFSET_LEN
: JUMPX_OFFSET_LEN;
ptrdiff_t jmplen = (type == JOF_TABLESWITCH) ? JUMP_OFFSET_LEN : JUMPX_OFFSET_LEN;
pc2 = pc;
off = GetJumpOffset(pc, pc2);
ptrdiff_t off = GetJumpOffset(pc, pc2);
pc2 += jmplen;
low = GET_JUMP_OFFSET(pc2);
pc2 += JUMP_OFFSET_LEN;
@ -581,10 +577,9 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
jsbytecode *pc2;
jsatomid npairs;
jmplen = (type == JOF_LOOKUPSWITCH) ? JUMP_OFFSET_LEN
: JUMPX_OFFSET_LEN;
ptrdiff_t jmplen = (type == JOF_LOOKUPSWITCH) ? JUMP_OFFSET_LEN : JUMPX_OFFSET_LEN;
pc2 = pc;
off = GetJumpOffset(pc, pc2);
ptrdiff_t off = GetJumpOffset(pc, pc2);
pc2 += jmplen;
npairs = GET_UINT16(pc2);
pc2 += UINT16_LEN;
@ -616,13 +611,14 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
case JOF_SLOTATOM:
case JOF_SLOTOBJECT: {
Sprint(sp, " %u", GET_SLOTNO(pc));
index = js_GetIndexFromBytecode(cx, script, pc, SLOTNO_LEN);
uintN index = js_GetIndexFromBytecode(cx, script, pc, SLOTNO_LEN);
jsval v;
if (type == JOF_SLOTATOM) {
JSAtom *atom;
JS_GET_SCRIPT_ATOM(script, pc, index, atom);
v = STRING_TO_JSVAL(atom);
} else {
obj = script->getObject(index);
v = OBJECT_TO_JSVAL(obj);
v = OBJECT_TO_JSVAL(script->getObject(index));
}
JSAutoByteString bytes;
@ -632,6 +628,19 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
break;
}
{
int i;
case JOF_UINT16PAIR:
i = (jsint)GET_UINT16(pc);
Sprint(sp, " %d", i);
pc += UINT16_LEN;
/* FALL THROUGH */
case JOF_UINT16:
i = (jsint)GET_UINT16(pc);
goto print_int;
case JOF_UINT24:
JS_ASSERT(op == JSOP_UINT24 || op == JSOP_NEWARRAY);
i = (jsint)GET_UINT24(pc);
@ -651,6 +660,7 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
print_int:
Sprint(sp, " %d", i);
break;
}
default: {
char numBuf[12];
@ -4809,20 +4819,17 @@ static JSBool
DecompileCode(JSPrinter *jp, JSScript *script, jsbytecode *pc, uintN len,
uintN pcdepth)
{
uintN depth, i;
SprintStack ss;
JSContext *cx;
JSScript *oldscript;
char *last;
JSContext *cx = jp->sprinter.context;
AutoScriptUntrapper untrapper;
if (!untrapper.untrap(cx, script))
return false;
depth = StackDepth(script);
uintN depth = StackDepth(script);
JS_ASSERT(pcdepth <= depth);
cx = jp->sprinter.context;
AutoScriptUntrapper untrapper(cx, script, &pc);
/* Initialize a sprinter for use with the offset stack. */
LifoAllocScope las(&cx->tempLifoAlloc());
SprintStack ss;
if (!InitSprintStack(cx, &ss, jp, depth))
return false;
@ -4839,20 +4846,21 @@ DecompileCode(JSPrinter *jp, JSScript *script, jsbytecode *pc, uintN len,
*/
ss.top = pcdepth;
if (pcdepth != 0) {
for (i = 0; i < pcdepth; i++) {
for (uintN i = 0; i < pcdepth; i++) {
ss.offsets[i] = -2 - (ptrdiff_t)i;
ss.opcodes[i] = *jp->pcstack[i];
}
}
/* Call recursive subroutine to do the hard work. */
oldscript = jp->script;
JSScript *oldscript = jp->script;
jp->script = script;
bool ok = Decompile(&ss, pc, len, JSOP_NOP) != NULL;
jp->script = oldscript;
/* If the given code didn't empty the stack, do it now. */
if (ok && ss.top) {
char *last;
do {
last = OFF2STR(&ss.sprinter, PopOff(&ss, JSOP_POP));
} while (ss.top > pcdepth);
@ -4934,13 +4942,7 @@ js_DecompileFunctionBody(JSPrinter *jp)
JSBool
js_DecompileFunction(JSPrinter *jp)
{
JSFunction *fun;
uintN i;
JSAtom *param;
jsbytecode *pc, *endpc;
JSBool ok;
fun = jp->fun;
JSFunction *fun = jp->fun;
JS_ASSERT(fun);
JS_ASSERT(!jp->script);
@ -4974,10 +4976,12 @@ js_DecompileFunction(JSPrinter *jp)
#endif
/* Print the parameters. */
pc = script->main();
AutoScriptUntrapper untrapper(jp->sprinter.context, script, &pc);
endpc = pc + script->length;
ok = JS_TRUE;
jsbytecode *pc = script->main();
AutoScriptUntrapper untrapper;
if (!untrapper.untrap(jp->sprinter.context, script))
return JS_FALSE;;
jsbytecode *endpc = pc + script->length;
JSBool ok = JS_TRUE;
#if JS_HAS_DESTRUCTURING
ss.printer = NULL;
@ -4985,11 +4989,11 @@ js_DecompileFunction(JSPrinter *jp)
LifoAllocScope las(&jp->sprinter.context->tempLifoAlloc());
#endif
for (i = 0; i < fun->nargs; i++) {
for (uintN i = 0; i < fun->nargs; i++) {
if (i > 0)
js_puts(jp, ", ");
param = GetArgOrVarAtom(jp, i);
JSAtom *param = GetArgOrVarAtom(jp, i);
#if JS_HAS_DESTRUCTURING
#define LOCAL_ASSERT(expr) LOCAL_ASSERT_RV(expr, JS_FALSE)
@ -5183,40 +5187,27 @@ static char *
DecompileExpression(JSContext *cx, JSScript *script, JSFunction *fun,
jsbytecode *pc)
{
JSOp op;
const JSCodeSpec *cs;
jsbytecode *begin, *end;
jssrcnote *sn;
ptrdiff_t len;
jsbytecode **pcstack;
intN pcdepth;
JSPrinter *jp;
char *name;
JS_ASSERT(script->code <= pc && pc < script->code + script->length);
AutoScriptUntrapper untrapper;
if (!untrapper.untrap(cx, script))
return NULL;
pcstack = NULL;
AutoScriptUntrapper untrapper(cx, script, &pc);
op = (JSOp) *pc;
JSOp op = (JSOp) *pc;
/* None of these stack-writing ops generates novel values. */
JS_ASSERT(op != JSOP_CASE && op != JSOP_CASEX &&
op != JSOP_DUP && op != JSOP_DUP2);
/* JSOP_PUSH is used to generate undefined for group assignment holes. */
if (op == JSOP_PUSH) {
name = JS_strdup(cx, js_undefined_str);
goto out;
}
if (op == JSOP_PUSH)
return JS_strdup(cx, js_undefined_str);
/*
* |this| could convert to a very long object initialiser, so cite it by
* its keyword name instead.
*/
if (op == JSOP_THIS) {
name = JS_strdup(cx, js_this_str);
goto out;
}
if (op == JSOP_THIS)
return JS_strdup(cx, js_this_str);
/*
* JSOP_BINDNAME is special: it generates a value, the base object of a
@ -5224,25 +5215,21 @@ DecompileExpression(JSContext *cx, JSScript *script, JSFunction *fun,
* js_DecompileValueGenerator, the name being bound is irrelevant. Just
* fall back to the base object.
*/
if (op == JSOP_BINDNAME) {
name = FAILED_EXPRESSION_DECOMPILER;
goto out;
}
if (op == JSOP_BINDNAME)
return FAILED_EXPRESSION_DECOMPILER;
/* NAME ops are self-contained, others require left or right context. */
cs = &js_CodeSpec[op];
begin = pc;
end = pc + cs->length;
const JSCodeSpec *cs = &js_CodeSpec[op];
jsbytecode *begin = pc;
jsbytecode *end = pc + cs->length;
switch (JOF_MODE(cs->format)) {
case JOF_PROP:
case JOF_ELEM:
case JOF_XMLNAME:
case 0:
sn = js_GetSrcNote(script, pc);
if (!sn) {
name = FAILED_EXPRESSION_DECOMPILER;
goto out;
}
case 0: {
jssrcnote *sn = js_GetSrcNote(script, pc);
if (!sn)
return FAILED_EXPRESSION_DECOMPILER;
switch (SN_TYPE(sn)) {
case SRC_PCBASE:
begin -= js_GetSrcNoteOffset(sn, 0);
@ -5252,48 +5239,46 @@ DecompileExpression(JSContext *cx, JSScript *script, JSFunction *fun,
begin += cs->length;
break;
default:
name = FAILED_EXPRESSION_DECOMPILER;
goto out;
return FAILED_EXPRESSION_DECOMPILER;
}
break;
}
default:;
}
len = end - begin;
if (len <= 0) {
name = FAILED_EXPRESSION_DECOMPILER;
goto out;
}
ptrdiff_t len = end - begin;
if (len <= 0)
return FAILED_EXPRESSION_DECOMPILER;
pcstack = (jsbytecode **)
cx->malloc_(StackDepth(script) * sizeof *pcstack);
if (!pcstack) {
name = NULL;
goto out;
}
MUST_FLOW_THROUGH("out");
pcdepth = ReconstructPCStack(cx, script, begin, pcstack);
if (pcdepth < 0) {
name = FAILED_EXPRESSION_DECOMPILER;
goto out;
}
name = NULL;
jp = js_NewPrinter(cx, "js_DecompileValueGenerator", fun, 0,
false, false, false);
if (jp) {
jp->dvgfence = end;
jp->pcstack = pcstack;
if (DecompileCode(jp, script, begin, (uintN) len, (uintN) pcdepth)) {
name = (jp->sprinter.base) ? jp->sprinter.base : (char *) "";
name = JS_strdup(cx, name);
struct Guard {
jsbytecode **pcstack;
JSPrinter *printer;
Guard() : pcstack(NULL), printer(NULL) {}
~Guard() {
if (printer)
js_DestroyPrinter(printer);
Foreground::free_(pcstack);
}
js_DestroyPrinter(jp);
}
} g;
out:
cx->free_(pcstack);
return name;
g.pcstack = (jsbytecode **)OffTheBooks::malloc_(StackDepth(script) * sizeof *g.pcstack);
if (!g.pcstack)
return NULL;
intN pcdepth = ReconstructPCStack(cx, script, begin, g.pcstack);
if (pcdepth < 0)
return FAILED_EXPRESSION_DECOMPILER;
g.printer = js_NewPrinter(cx, "js_DecompileValueGenerator", fun, 0, false, false, false);
if (!g.printer)
return NULL;
g.printer->dvgfence = end;
g.printer->pcstack = g.pcstack;
if (!DecompileCode(g.printer, script, begin, (uintN) len, (uintN) pcdepth))
return NULL;
const char *name = (g.printer->sprinter.base) ? g.printer->sprinter.base : "";
return JS_strdup(cx, name);
}
uintN

View File

@ -563,6 +563,24 @@ FlowsIntoNext(JSOp op)
op != JSOP_GOTO && op != JSOP_GOTOX && op != JSOP_RETSUB;
}
/*
* AutoScriptUntrapper mutates the given script in place to replace JSOP_TRAP
* opcodes with the original opcode they replaced. The destructor mutates the
* script back into its original state.
*/
class AutoScriptUntrapper
{
JSContext *cx;
JSScript *origScript;
jsbytecode *origCode;
size_t nbytes;
bool saveOriginal(JSScript *script);
public:
AutoScriptUntrapper();
bool untrap(JSContext *cx, JSScript *script);
~AutoScriptUntrapper();
};
}
#endif

View File

@ -562,7 +562,7 @@ regexp_toString(JSContext *cx, uintN argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &RegExpClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, regexp_toString, &RegExpClass, &ok);
if (!obj)
return ok;
@ -625,8 +625,6 @@ SwapRegExpInternals(JSContext *cx, JSObject *obj, Value *rval, JSString *str, ui
return true;
}
enum ExecType { RegExpExec, RegExpTest };
/*
* ES5 15.10.6.2 (and 15.10.6.3, which calls 15.10.6.2).
*
@ -634,13 +632,13 @@ enum ExecType { RegExpExec, RegExpTest };
* |execType| to perform this optimization.
*/
static JSBool
ExecuteRegExp(JSContext *cx, ExecType execType, uintN argc, Value *vp)
ExecuteRegExp(JSContext *cx, Native native, uintN argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
/* Step 1. */
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &RegExpClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, native, &RegExpClass, &ok);
if (!obj)
return ok;
@ -684,7 +682,7 @@ ExecuteRegExp(JSContext *cx, ExecType execType, uintN argc, Value *vp)
/* Steps 8-21. */
size_t lastIndexInt(i);
if (!re->execute(cx, res, input, &lastIndexInt, execType == RegExpTest, &args.rval()))
if (!re->execute(cx, res, input, &lastIndexInt, native == js_regexp_test, &args.rval()))
return false;
/* Step 11 (with sticky extension). */
@ -702,14 +700,14 @@ ExecuteRegExp(JSContext *cx, ExecType execType, uintN argc, Value *vp)
JSBool
js_regexp_exec(JSContext *cx, uintN argc, Value *vp)
{
return ExecuteRegExp(cx, RegExpExec, argc, vp);
return ExecuteRegExp(cx, js_regexp_exec, argc, vp);
}
/* ES5 15.10.6.3. */
JSBool
js_regexp_test(JSContext *cx, uintN argc, Value *vp)
{
if (!ExecuteRegExp(cx, RegExpTest, argc, vp))
if (!ExecuteRegExp(cx, js_regexp_test, argc, vp))
return false;
if (!vp->isTrue())
vp->setBoolean(false);
@ -789,7 +787,7 @@ regexp_compile(JSContext *cx, uintN argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &RegExpClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, regexp_compile, &RegExpClass, &ok);
if (!obj)
return ok;

View File

@ -335,7 +335,6 @@ js_XDRScript(JSXDRState *xdr, JSScript **scriptp)
{
JSScript *oldscript;
JSBool ok;
jsbytecode *code;
uint32 length, lineno, nslots;
uint32 natoms, nsrcnotes, ntrynotes, nobjects, nregexps, nconsts, i;
uint32 prologLength, version, encodedClosedCount;
@ -576,18 +575,13 @@ js_XDRScript(JSXDRState *xdr, JSScript **scriptp)
* DECODE case to destroy script.
*/
oldscript = xdr->script;
code = script->code;
if (xdr->mode == JSXDR_ENCODE) {
code = js_UntrapScriptCode(cx, script);
if (!code)
goto error;
}
AutoScriptUntrapper untrapper;
if (xdr->mode == JSXDR_ENCODE && !untrapper.untrap(cx, script))
goto error;
xdr->script = script;
ok = JS_XDRBytes(xdr, (char *) code, length * sizeof(jsbytecode));
if (code != script->code)
cx->free_(code);
ok = JS_XDRBytes(xdr, (char *)script->code, length * sizeof(jsbytecode));
if (!ok)
goto error;

View File

@ -460,7 +460,7 @@ str_toSource(JSContext *cx, uintN argc, Value *vp)
JSString *str;
bool ok;
if (!BoxedPrimitiveMethodGuard(cx, args, &str, &ok))
if (!BoxedPrimitiveMethodGuard(cx, args, str_toSource, &str, &ok))
return ok;
str = js_QuoteString(cx, str, '"');
@ -508,7 +508,7 @@ js_str_toString(JSContext *cx, uintN argc, Value *vp)
JSString *str;
bool ok;
if (!BoxedPrimitiveMethodGuard(cx, args, &str, &ok))
if (!BoxedPrimitiveMethodGuard(cx, args, js_str_toString, &str, &ok))
return ok;
args.rval().setString(str);
@ -1007,26 +1007,19 @@ RopeMatch(JSContext *cx, JSString *textstr, const jschar *pat, jsuint patlen, js
/* Absolute offset from the beginning of the logical string textstr. */
jsint pos = 0;
// TODO: consider branching to a simple loop if patlen == 1
for (JSLinearString **outerp = strs.begin(); outerp != strs.end(); ++outerp) {
/* First try to match without spanning two nodes. */
/* Try to find a match within 'outer'. */
JSLinearString *outer = *outerp;
const jschar *chars = outer->chars();
size_t len = outer->length();
jsint matchResult = StringMatch(chars, len, pat, patlen);
if (matchResult != -1) {
/* Matched! */
*match = pos + matchResult;
return true;
}
/* Test the overlap. */
JSLinearString **innerp = outerp;
/*
* Start searching at the first place where StringMatch wouldn't have
* found the match.
*/
/* Try to find a match starting in 'outer' and running into other nodes. */
const jschar *const text = chars + (patlen > len ? 0 : len - patlen + 1);
const jschar *const textend = chars + len;
const jschar p0 = *pat;
@ -1035,6 +1028,7 @@ RopeMatch(JSContext *cx, JSString *textstr, const jschar *pat, jsuint patlen, js
for (const jschar *t = text; t != textend; ) {
if (*t++ != p0)
continue;
JSLinearString **innerp = outerp;
const jschar *ttend = textend;
for (const jschar *pp = p1, *tt = t; pp != patend; ++pp, ++tt) {
while (tt == ttend) {

View File

@ -1386,7 +1386,7 @@ class TypedArrayTemplate
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, fastClass(), &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, fun_subarray, fastClass(), &ok);
if (!obj)
return ok;
@ -1439,7 +1439,7 @@ class TypedArrayTemplate
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, fastClass(), &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, fun_set, fastClass(), &ok);
if (!obj)
return ok;

View File

@ -105,7 +105,7 @@ WeakMap_has(JSContext *cx, uintN argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &WeakMapClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, WeakMap_has, &WeakMapClass, &ok);
if (!obj)
return ok;
@ -136,7 +136,7 @@ WeakMap_get(JSContext *cx, uintN argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &WeakMapClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, WeakMap_get, &WeakMapClass, &ok);
if (!obj)
return ok;
@ -167,7 +167,7 @@ WeakMap_delete(JSContext *cx, uintN argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &WeakMapClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, WeakMap_delete, &WeakMapClass, &ok);
if (!obj)
return ok;
@ -199,7 +199,7 @@ WeakMap_set(JSContext *cx, uintN argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
bool ok;
JSObject *obj = NonGenericMethodGuard(cx, args, &WeakMapClass, &ok);
JSObject *obj = NonGenericMethodGuard(cx, args, WeakMap_set, &WeakMapClass, &ok);
if (!obj)
return ok;

View File

@ -739,7 +739,7 @@ CrossCompartmentWrapper::nativeCall(JSContext *cx, JSObject *wrapper, Class *cla
JS_ASSERT_IF(!srcArgs.calleev().isUndefined(),
srcArgs.callee().getFunctionPrivate()->native() == native);
JS_ASSERT(&srcArgs.thisv().toObject() == wrapper);
JS_ASSERT(!UnwrapObject(wrapper)->isProxy());
JS_ASSERT(!UnwrapObject(wrapper)->isCrossCompartmentWrapper());
JSObject *wrapped = wrappedObject(wrapper);
AutoCompartment call(cx, wrapped);

View File

@ -36,6 +36,8 @@ namespace WTF {
#if WTF_CPU_SPARC
#define MINIMUM_BUMP_POOL_SIZE 0x2000
#elif WTF_CPU_IA64
#define MINIMUM_BUMP_POOL_SIZE 0x4000
#else
#define MINIMUM_BUMP_POOL_SIZE 0x1000
#endif

View File

@ -55,6 +55,8 @@
#include "nsIServiceManager.h"
#include "nsIPercentHeightObserver.h"
#include "nsLayoutUtils.h"
#include "nsPlaceholderFrame.h"
#include "nsFrameManager.h"
#include "mozilla/Preferences.h"
#ifdef IBMBIDI
#include "nsBidiUtils.h"
@ -847,7 +849,7 @@ static bool AreAllEarlierInFlowFramesEmpty(nsIFrame* aFrame,
// cbrs->frame is the actual containing block
void
nsHTMLReflowState::CalculateHypotheticalBox(nsPresContext* aPresContext,
nsIFrame* aPlaceholderFrame,
nsPlaceholderFrame* aPlaceholderFrame,
nsIFrame* aContainingBlock,
nscoord aBlockLeftContentEdge,
nscoord aBlockContentWidth,
@ -930,17 +932,12 @@ nsHTMLReflowState::CalculateHypotheticalBox(nsPresContext* aPresContext,
nsLayoutUtils::GetAsBlock(aContainingBlock->GetContentInsertionFrame());
if (blockFrame) {
nscoord blockYOffset = blockFrame->GetOffsetTo(aContainingBlock).y;
bool isValid;
nsBlockInFlowLineIterator iter(blockFrame, aPlaceholderFrame, &isValid);
if (!isValid) {
const nsLineBox* lineBox = aPlaceholderFrame->GetCachedLineBox();
if (!lineBox) {
// Give up. We're probably dealing with somebody using
// position:absolute inside native-anonymous content anyway.
aHypotheticalBox.mTop = placeholderOffset.y;
} else {
NS_ASSERTION(iter.GetContainer() == blockFrame,
"Found placeholder in wrong block!");
nsBlockFrame::line_iterator lineBox = iter.GetLine();
// How we determine the hypothetical box depends on whether the element
// would have been inline-level or block-level
if (mStyleDisplay->IsOriginalDisplayInlineOutside()) {
@ -954,10 +951,10 @@ nsHTMLReflowState::CalculateHypotheticalBox(nsPresContext* aPresContext,
// have been just before this line.
// XXXbz the line box is not fully reflowed yet if our
// containing block is relatively positioned...
if (lineBox != iter.End()) {
bool allEmpty = true;
if (!lineBox->IsValidCachedIsEmpty() || !lineBox->CachedIsEmpty()) {
nsIFrame * firstFrame = lineBox->mFirstChild;
bool found = false;
bool allEmpty = true;
while (firstFrame) { // See bug 223064
allEmpty = AreAllEarlierInFlowFramesEmpty(firstFrame,
aPlaceholderFrame, &found);
@ -966,20 +963,17 @@ nsHTMLReflowState::CalculateHypotheticalBox(nsPresContext* aPresContext,
firstFrame = firstFrame->GetNextSibling();
}
NS_ASSERTION(firstFrame, "Couldn't find placeholder!");
}
if (allEmpty) {
// The top of the hypothetical box is the top of the line
// containing the placeholder, since there is nothing in the
// line before our placeholder except empty frames.
aHypotheticalBox.mTop = lineBox->mBounds.y + blockYOffset;
} else {
// The top of the hypothetical box is just below the line
// containing the placeholder.
aHypotheticalBox.mTop = lineBox->mBounds.YMost() + blockYOffset;
}
if (allEmpty) {
// The top of the hypothetical box is the top of the line
// containing the placeholder, since there is nothing in the
// line before our placeholder except empty frames.
aHypotheticalBox.mTop = lineBox->mBounds.y + blockYOffset;
} else {
// Just use the placeholder's y-offset wrt the containing block
aHypotheticalBox.mTop = placeholderOffset.y;
// The top of the hypothetical box is just below the line
// containing the placeholder.
aHypotheticalBox.mTop = lineBox->mBounds.YMost() + blockYOffset;
}
}
}
@ -1105,9 +1099,10 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsPresContext* aPresContext,
"Why are we here?");
// Get the placeholder frame
nsIFrame* placeholderFrame;
nsPlaceholderFrame* placeholderFrame;
placeholderFrame = aPresContext->PresShell()->GetPlaceholderFrameFor(frame);
placeholderFrame =
aPresContext->PresShell()->FrameManager()->GetPlaceholderFrameFor(frame);
NS_ASSERTION(nsnull != placeholderFrame, "no placeholder frame");
// If both 'left' and 'right' are 'auto' or both 'top' and 'bottom' are

View File

@ -49,6 +49,7 @@ class nsRenderingContext;
class nsFloatManager;
class nsLineLayout;
class nsIPercentHeightObserver;
class nsPlaceholderFrame;
struct nsStyleDisplay;
struct nsStyleVisibility;
@ -511,7 +512,7 @@ protected:
nscoord& aCBWidth);
void CalculateHypotheticalBox(nsPresContext* aPresContext,
nsIFrame* aPlaceholderFrame,
nsPlaceholderFrame* aPlaceholderFrame,
nsIFrame* aContainingBlock,
nscoord aBlockLeftContentEdge,
nscoord aBlockContentWidth,

View File

@ -289,7 +289,7 @@ nsLineBox::IsEmpty() const
}
bool
nsLineBox::CachedIsEmpty()
nsLineBox::CachedIsEmpty() const
{
if (mFlags.mDirty) {
return IsEmpty();

View File

@ -486,14 +486,14 @@ public:
// Call this only while in Reflow() for the block the line belongs
// to, only between reflowing the line (or sliding it, if we skip
// reflowing it) and the end of reflowing the block.
bool CachedIsEmpty();
bool CachedIsEmpty() const;
void InvalidateCachedIsEmpty() {
mFlags.mEmptyCacheValid = PR_FALSE;
}
// For debugging purposes
bool IsValidCachedIsEmpty() {
bool IsValidCachedIsEmpty() const {
return mFlags.mEmptyCacheValid;
}
@ -514,8 +514,8 @@ public:
PRUint32 mLineWrapped: 1;
PRUint32 mInvalidateTextRuns : 1;
PRUint32 mResizeReflowOptimizationDisabled: 1; // default 0 = means that the opt potentially applies to this line. 1 = never skip reflowing this line for a resize reflow
PRUint32 mEmptyCacheValid: 1;
PRUint32 mEmptyCacheState: 1;
mutable PRUint32 mEmptyCacheValid: 1;
mutable PRUint32 mEmptyCacheState: 1;
// mHasBullet indicates that this is an inline line whose block's
// bullet is adjacent to this line and non-empty.
PRUint32 mHasBullet : 1;

View File

@ -145,6 +145,15 @@ nsPlaceholderFrame::Reflow(nsPresContext* aPresContext,
aDesiredSize.width = 0;
aDesiredSize.height = 0;
// Cache our line box.
mCachedLineBox = nsnull;
if (aReflowState.mLineLayout) {
nsLineList::iterator* line = aReflowState.mLineLayout->GetLine();
if (line) {
mCachedLineBox = line->get();
}
}
aStatus = NS_FRAME_COMPLETE;
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
return NS_OK;

View File

@ -69,6 +69,8 @@
#include "nsFrame.h"
#include "nsGkAtoms.h"
class nsLineBox;
nsIFrame* NS_NewPlaceholderFrame(nsIPresShell* aPresShell,
nsStyleContext* aContext,
nsFrameState aTypeBit);
@ -200,8 +202,17 @@ public:
return outOfFlow;
}
// GetCachedLineBox is only OK to call if you're sure this
// placeholder has has Reflow() called since any changes to the
// frame tree that could have affected which line box the
// placeholder is in.
const nsLineBox* GetCachedLineBox() const {
return mCachedLineBox;
}
protected:
nsIFrame* mOutOfFlowFrame;
nsLineBox* mCachedLineBox;
};
#endif /* nsPlaceholderFrame_h___ */

View File

@ -0,0 +1,13 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<svg xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id="pattern" width="200" height="200" patternUnits="userSpaceOnUse">
<circle cx="100" cy="100" r="100" fill="lime" />
</pattern>
</defs>
<rect width="200" height="200" fill="url(#pattern)" />
<circle cx="100" cy="100" r="100" fill="none" stroke="lime" stroke-width="2" shape-rendering="crispEdges" />
</svg>

After

Width:  |  Height:  |  Size: 505 B

View File

@ -0,0 +1,13 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<svg xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id="pattern" width="5" height="5" patternUnits="userSpaceOnUse" patternTransform="scale(-40)">
<circle cx="2.5" cy="2.5" r="2.5" fill="lime" />
</pattern>
</defs>
<rect width="200" height="200" fill="url(#pattern)" />
<circle cx="100" cy="100" r="100" fill="none" stroke="lime" stroke-width="2" shape-rendering="crispEdges" />
</svg>

After

Width:  |  Height:  |  Size: 531 B

View File

@ -176,6 +176,7 @@ fails-if(Android&&layersOpenGL) == path-04.svg pass.svg
== pattern-live-01a.svg pattern-live-01-ref.svg
== pattern-live-01b.svg pattern-live-01-ref.svg
== pattern-live-01c.svg pattern-live-01-ref.svg
== pattern-scale-01.svg pattern-scale-01-ref.svg
== pattern-transform-presence-01.svg pattern-transform-presence-01-ref.svg
== polygon-marker-01.svg pass.svg
== polygon-points-negative-01.svg pass.svg

View File

@ -261,8 +261,10 @@ nsSVGPatternFrame::PaintPattern(gfxASurface** surface,
bool resultOverflows;
gfxIntSize surfaceSize =
nsSVGUtils::ConvertToSurfaceSize(gfxSize(patternWidth, patternHeight),
&resultOverflows);
nsSVGUtils::ConvertToSurfaceSize(
gfxSize(patternWidth * fabs(patternMatrix->xx),
patternHeight * fabs(patternMatrix->yy)),
&resultOverflows);
// 0 disables rendering, < 0 is an error
if (surfaceSize.width <= 0 || surfaceSize.height <= 0)

View File

@ -1293,13 +1293,14 @@ static void _malloc_postfork(void);
* again, and need to dynamically account for this. By simply leaving
* malloc_zone_t alone, we don't quite deal with the problem, because there
* remain calls to jemalloc through the mozalloc interface. We check this
* dynamically on each allocation, using the CHECK_DARWIN macro.
* dynamically on each allocation, using the CHECK_DARWIN macro and
* osx_use_jemalloc.
*
*
* [1] Mozilla is built as a universal binary on Mac, supporting i386 and
* x86_64. The i386 target is built using the 10.5 SDK, even if it runs on
* 10.6. The x86_64 target is built using the 10.6 SDK, even if it runs on
* 10.7 or later.
* 10.7 or later, or 10.5.
*
* FIXME:
* When later versions of OSX come out (10.8 and up), we need to check their
@ -1313,6 +1314,9 @@ static void _malloc_postfork(void);
#define SNOW_LEOPARD_MALLOC_ZONE_T_VERSION 6
#define LION_MALLOC_ZONE_T_VERSION 8
static bool osx_use_jemalloc = false;
/*
* Avoid lots of casts below by allowing access to l_jemalloc_zone through a
* malloc_zone_t pointer.
@ -1332,10 +1336,6 @@ static void szone2ozone(malloc_zone_t *zone, size_t size);
static size_t zone_version_size(int version);
#endif
/* On unknown future versions of OSX, dynamically decide not to use jemalloc. */
static bool use_jemalloc = false;
/*
* End function prototypes.
*/
@ -5832,14 +5832,20 @@ MALLOC_OUT:
*/
default_zone = malloc_default_zone();
/* Don't use jemalloc on as-yet-unreleased versions of OSX. */
use_jemalloc = (default_zone->version <= LION_MALLOC_ZONE_T_VERSION);
/*
* We only use jemalloc with the 10.6 SDK:
* - With the 10.5 SDK, madvise doesn't work, leading to a 20% memory
* usage regression (bug 670492).
* - With the 10.7 SDK, jemalloc causes the browser to hang (bug 670175).
*/
osx_use_jemalloc = (default_zone->version == SNOW_LEOPARD_MALLOC_ZONE_T_VERSION);
/* Allow us dynamically turn off jemalloc for testing. */
if (getenv("NO_MAC_JEMALLOC"))
use_jemalloc = false;
osx_use_jemalloc = false;
if (use_jemalloc) {
if (osx_use_jemalloc) {
size_t size;
/* Register the custom zone. */
@ -5937,23 +5943,17 @@ wrap(strdup)(const char *src) {
#endif
/*
* We are not able to assume that we can replace the OSX allocator with
* jemalloc on future unreleased versions of OSX. Despite this, we call
* jemalloc functions directly from mozalloc. Since it's pretty dangerous to
* mix the allocators, we need to call the OSX allocators from the functions
* below, when use_jemalloc is not (dynamically) set.
* Even though we compile with MOZ_MEMORY, we may have to dynamically decide
* not to use jemalloc, as discussed above. However, we call jemalloc
* functions directly from mozalloc. Since it's pretty dangerous to mix the
* allocators, we need to call the OSX allocators from the functions below,
* when osx_use_jemalloc is not (dynamically) set.
*
* We call memalign from mozalloc, but the 10.5 SDK doesn't have a memalign
* function to forward the call to. However, use_jemalloc will _always_ be true
* on 10.5, so we just omit these checks statically. This allows us to build
* successfully on 10.5, and also makes it undetectably faster.
*
* FIXME:
* This may lead to problems when using 32-bit plugins with a 64-bit process,
* on OSX 10.8 or higher.
* memalign is unavailable on Leopard, so we can't dynamically do this there.
* However, we don't use jemalloc on Leopard, so we can ignore this.
*/
#if defined(MOZ_MEMORY_DARWIN) && !defined(__i386__)
#define DARWIN_ONLY(A) if (!use_jemalloc) { A; }
#define DARWIN_ONLY(A) if (!osx_use_jemalloc) { A; }
#else
#define DARWIN_ONLY(A)
#endif

View File

@ -25,7 +25,7 @@
%define margin_snormal 0.64mozmm
%define margin_small 0.42mozmm
%define margin_tiny 0.21mozmm
%define margin_xtiny 0.11mozmm
%define margin_xtiny 0.15mozmm
%define padding_xlarge 3.39mozmm
%define padding_large 2.54mozmm

View File

@ -52,7 +52,7 @@
%define margin_snormal 0.64mozmm
%define margin_small 0.42mozmm
%define margin_tiny 0.21mozmm
%define margin_xtiny 0.11mozmm
%define margin_xtiny 0.15mozmm
%define padding_xlarge 3.39mozmm
%define padding_large 2.54mozmm

View File

@ -79,7 +79,7 @@
%define margin_snormal 0.64mozmm
%define margin_small 0.42mozmm
%define margin_tiny 0.21mozmm
%define margin_xtiny 0.11mozmm
%define margin_xtiny 0.15mozmm
%define padding_xxxlarge 13.35mozmm
%define padding_xxlarge 7.938mozmm

Binary file not shown.

Before

Width:  |  Height:  |  Size: 962 B

After

Width:  |  Height:  |  Size: 692 B

View File

@ -532,7 +532,7 @@ menulist {
color: @color_text_button@ !important;
background-color: @color_background_button@;
margin: @margin_normal@;
padding: @padding_xnormal@;
padding: @padding_xsmall@ @padding_xnormal@;
border-width: 0;
border-radius: 0;
}

View File

@ -68,6 +68,8 @@ static CameraStreamImpl* mCamera1 = NULL;
*/
void CameraStreamImpl::transmitFrame(JNIEnv *env, jbyteArray *data) {
if (!mCallback)
return;
jboolean isCopy;
jbyte* jFrame = env->GetByteArrayElements(*data, &isCopy);
PRUint32 length = env->GetArrayLength(*data);

View File

@ -1 +1 @@
http://hg.mozilla.org/projects/addon-sdk/archive/9f45975c909d.tar.bz2
http://hg.mozilla.org/projects/addon-sdk/archive/8633b650f648.tar.bz2

View File

@ -481,10 +481,30 @@ protected:
bool mKeyPressDispatched;
// Whether keypress event was consumed by web contents or chrome contents.
bool mKeyPressHandled;
// Whether the key event causes other key events via IME or something.
bool mCausedOtherKeyEvents;
KeyEventState() : mKeyEvent(nsnull)
{
Clear();
}
KeyEventState(NSEvent* aNativeKeyEvent) : mKeyEvent(nsnull)
{
Clear();
Set(aNativeKeyEvent);
}
KeyEventState(const KeyEventState &aOther) : mKeyEvent(nsnull)
{
Clear();
if (aOther.mKeyEvent) {
mKeyEvent = [aOther.mKeyEvent retain];
}
mKeyDownHandled = aOther.mKeyDownHandled;
mKeyPressDispatched = aOther.mKeyPressDispatched;
mKeyPressHandled = aOther.mKeyPressHandled;
mCausedOtherKeyEvents = aOther.mCausedOtherKeyEvents;
}
~KeyEventState()
@ -508,6 +528,7 @@ protected:
mKeyDownHandled = false;
mKeyPressDispatched = false;
mKeyPressHandled = false;
mCausedOtherKeyEvents = false;
}
bool KeyDownOrPressHandled()
@ -529,15 +550,74 @@ protected:
~AutoKeyEventStateCleaner()
{
mHandler->mCurrentKeyEvent.Clear();
mHandler->RemoveCurrentKeyEvent();
}
private:
TextInputHandlerBase* mHandler;
nsRefPtr<TextInputHandlerBase> mHandler;
};
// XXX If keydown event was nested, the key event is overwritten by newer
// event. This is wrong behavior. Some IMEs are making such situation.
KeyEventState mCurrentKeyEvent;
/**
* mCurrentKeyEvents stores all key events which are being processed.
* When we call interpretKeyEvents, IME may generate other key events.
* mCurrentKeyEvents[0] is the latest key event.
*/
nsTArray<KeyEventState*> mCurrentKeyEvents;
/**
* mFirstKeyEvent must be used for first key event. This member prevents
* memory fragmentation for most key events.
*/
KeyEventState mFirstKeyEvent;
/**
* PushKeyEvent() adds the current key event to mCurrentKeyEvents.
*/
KeyEventState* PushKeyEvent(NSEvent* aNativeKeyEvent)
{
PRUint32 nestCount = mCurrentKeyEvents.Length();
for (PRUint32 i = 0; i < nestCount; i++) {
// When the key event is caused by another key event, all key events
// which are being handled should be marked as "consumed".
mCurrentKeyEvents[i]->mCausedOtherKeyEvents = true;
}
KeyEventState* keyEvent = nsnull;
if (nestCount == 0) {
mFirstKeyEvent.Set(aNativeKeyEvent);
keyEvent = &mFirstKeyEvent;
} else {
keyEvent = new KeyEventState(aNativeKeyEvent);
}
return *mCurrentKeyEvents.AppendElement(keyEvent);
}
/**
* RemoveCurrentKeyEvent() removes the current key event from
* mCurrentKeyEvents.
*/
void RemoveCurrentKeyEvent()
{
NS_ASSERTION(mCurrentKeyEvents.Length() > 0,
"RemoveCurrentKeyEvent() is called unexpectedly");
KeyEventState* keyEvent = GetCurrentKeyEvent();
mCurrentKeyEvents.RemoveElementAt(mCurrentKeyEvents.Length() - 1);
if (keyEvent == &mFirstKeyEvent) {
keyEvent->Clear();
} else {
delete keyEvent;
}
}
/**
* GetCurrentKeyEvent() returns current processing key event.
*/
KeyEventState* GetCurrentKeyEvent()
{
if (mCurrentKeyEvents.Length() == 0) {
return nsnull;
}
return mCurrentKeyEvents[mCurrentKeyEvents.Length() - 1];
}
/**
* IsPrintableChar() checks whether the unicode character is
@ -1119,7 +1199,8 @@ public:
*/
bool KeyPressWasHandled()
{
return mCurrentKeyEvent.mKeyPressHandled;
KeyEventState* currentKeyEvent = GetCurrentKeyEvent();
return currentKeyEvent && currentKeyEvent->mKeyPressHandled;
}
protected:

View File

@ -997,7 +997,7 @@ TextInputHandler::HandleKeyDownEvent(NSEvent* aNativeEvent)
nsRefPtr<nsChildView> kungFuDeathGrip(mWidget);
mCurrentKeyEvent.Set(aNativeEvent);
KeyEventState* currentKeyEvent = PushKeyEvent(aNativeEvent);
AutoKeyEventStateCleaner remover(this);
BOOL nonDeadKeyPress = [[aNativeEvent characters] length] > 0;
@ -1015,12 +1015,12 @@ TextInputHandler::HandleKeyDownEvent(NSEvent* aNativeEvent)
}
#endif // #ifndef NP_NO_CARBON
mCurrentKeyEvent.mKeyDownHandled = DispatchEvent(keydownEvent);
currentKeyEvent->mKeyDownHandled = DispatchEvent(keydownEvent);
if (Destroyed()) {
PR_LOG(gLog, PR_LOG_ALWAYS,
("%p TextInputHandler::HandleKeyDownEvent, "
"widget was destroyed by keydown event", this));
return mCurrentKeyEvent.KeyDownOrPressHandled();
return currentKeyEvent->KeyDownOrPressHandled();
}
// The key down event may have shifted the focus, in which
@ -1030,7 +1030,7 @@ TextInputHandler::HandleKeyDownEvent(NSEvent* aNativeEvent)
PR_LOG(gLog, PR_LOG_ALWAYS,
("%p TextInputHandler::HandleKeyDownEvent, "
"view lost focus by keydown event", this));
return mCurrentKeyEvent.KeyDownOrPressHandled();
return currentKeyEvent->KeyDownOrPressHandled();
}
// If this is the context menu key command, send a context menu key event.
@ -1052,31 +1052,7 @@ TextInputHandler::HandleKeyDownEvent(NSEvent* aNativeEvent)
Destroyed() ? " and widget was destroyed" : ""));
[mView maybeInitContextMenuTracking];
// Bail, there is nothing else to do here.
return (cmEventHandled || mCurrentKeyEvent.KeyDownOrPressHandled());
}
nsKeyEvent keypressEvent(true, NS_KEY_PRESS, mWidget);
InitKeyEvent(aNativeEvent, keypressEvent);
// if this is a non-letter keypress, or the control key is down,
// dispatch the keydown to gecko, so that we trap delete,
// control-letter combinations etc before Cocoa tries to use
// them for keybindings.
// XXX This is wrong. IME may be handle the non-letter keypress event as
// its owning shortcut key. See bug 477291.
if ((!keypressEvent.isChar || keypressEvent.isControl) &&
!IsIMEComposing()) {
if (mCurrentKeyEvent.mKeyDownHandled) {
keypressEvent.flags |= NS_EVENT_FLAG_NO_DEFAULT;
}
mCurrentKeyEvent.mKeyPressHandled = DispatchEvent(keypressEvent);
mCurrentKeyEvent.mKeyPressDispatched = true;
if (Destroyed()) {
PR_LOG(gLog, PR_LOG_ALWAYS,
("%p TextInputHandler::HandleKeyDownEvent, "
"widget was destroyed by keypress event", this));
return mCurrentKeyEvent.KeyDownOrPressHandled();
}
return (cmEventHandled || currentKeyEvent->KeyDownOrPressHandled());
}
}
@ -1098,7 +1074,7 @@ TextInputHandler::HandleKeyDownEvent(NSEvent* aNativeEvent)
PR_LOG(gLog, PR_LOG_ALWAYS,
("%p TextInputHandler::HandleKeyDownEvent, widget was destroyed",
this));
return mCurrentKeyEvent.KeyDownOrPressHandled();
return currentKeyEvent->KeyDownOrPressHandled();
}
PR_LOG(gLog, PR_LOG_ALWAYS,
@ -1106,7 +1082,7 @@ TextInputHandler::HandleKeyDownEvent(NSEvent* aNativeEvent)
"IsIMEComposing()=%s",
this, TrueOrFalse(wasComposing), TrueOrFalse(IsIMEComposing())));
if (!mCurrentKeyEvent.mKeyPressDispatched && nonDeadKeyPress &&
if (!currentKeyEvent->mKeyPressDispatched && nonDeadKeyPress &&
!wasComposing && !IsIMEComposing()) {
nsKeyEvent keypressEvent(true, NS_KEY_PRESS, mWidget);
InitKeyEvent(aNativeEvent, keypressEvent);
@ -1124,10 +1100,11 @@ TextInputHandler::HandleKeyDownEvent(NSEvent* aNativeEvent)
// our default action for this key.
if (!(interpretKeyEventsCalled &&
IsNormalCharInputtingEvent(keypressEvent))) {
if (mCurrentKeyEvent.mKeyDownHandled) {
if (currentKeyEvent->mKeyDownHandled ||
currentKeyEvent->mCausedOtherKeyEvents) {
keypressEvent.flags |= NS_EVENT_FLAG_NO_DEFAULT;
}
mCurrentKeyEvent.mKeyPressHandled = DispatchEvent(keypressEvent);
currentKeyEvent->mKeyPressHandled = DispatchEvent(keypressEvent);
PR_LOG(gLog, PR_LOG_ALWAYS,
("%p TextInputHandler::HandleKeyDownEvent, keypress event dispatched",
this));
@ -1139,9 +1116,9 @@ TextInputHandler::HandleKeyDownEvent(NSEvent* aNativeEvent)
PR_LOG(gLog, PR_LOG_ALWAYS,
("%p TextInputHandler::HandleKeyDownEvent, "
"keydown handled=%s, keypress handled=%s",
this, TrueOrFalse(mCurrentKeyEvent.mKeyDownHandled),
TrueOrFalse(mCurrentKeyEvent.mKeyPressHandled)));
return mCurrentKeyEvent.KeyDownOrPressHandled();
this, TrueOrFalse(currentKeyEvent->mKeyDownHandled),
TrueOrFalse(currentKeyEvent->mKeyPressHandled)));
return currentKeyEvent->KeyDownOrPressHandled();
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(false);
}
@ -1312,13 +1289,17 @@ TextInputHandler::InsertText(NSAttributedString *aAttrString)
return;
}
KeyEventState* currentKeyEvent = GetCurrentKeyEvent();
PR_LOG(gLog, PR_LOG_ALWAYS,
("%p TextInputHandler::InsertText, aAttrString=\"%s\", "
"IsIMEComposing()=%s, IgnoreIMEComposition()=%s, "
"keyevent=%p, keypressDispatched=%s",
this, GetCharacters([aAttrString string]), TrueOrFalse(IsIMEComposing()),
TrueOrFalse(IgnoreIMEComposition()), mCurrentKeyEvent.mKeyEvent,
TrueOrFalse(mCurrentKeyEvent.mKeyPressDispatched)));
TrueOrFalse(IgnoreIMEComposition()),
currentKeyEvent ? currentKeyEvent->mKeyEvent : nsnull,
currentKeyEvent ?
TrueOrFalse(currentKeyEvent->mKeyPressDispatched) : "N/A"));
if (IgnoreIMEComposition()) {
return;
@ -1337,7 +1318,7 @@ TextInputHandler::InsertText(NSAttributedString *aAttrString)
// Don't let the same event be fired twice when hitting
// enter/return! (Bug 420502)
if (mCurrentKeyEvent.mKeyPressDispatched) {
if (currentKeyEvent && currentKeyEvent->mKeyPressDispatched) {
return;
}
@ -1359,8 +1340,8 @@ TextInputHandler::InsertText(NSAttributedString *aAttrString)
EventRecord carbonEvent;
#endif // #ifndef NP_NO_CARBON
if (mCurrentKeyEvent.mKeyEvent) {
NSEvent* keyEvent = mCurrentKeyEvent.mKeyEvent;
if (currentKeyEvent) {
NSEvent* keyEvent = currentKeyEvent->mKeyEvent;
// XXX The ASCII characters inputting mode of egbridge (Japanese IME)
// might send the keyDown event with wrong keyboard layout if other
@ -1373,7 +1354,7 @@ TextInputHandler::InsertText(NSAttributedString *aAttrString)
}
#endif // #ifndef NP_NO_CARBON
if (mCurrentKeyEvent.mKeyDownHandled) {
if (currentKeyEvent->mKeyDownHandled) {
keypressEvent.flags |= NS_EVENT_FLAG_NO_DEFAULT;
}
@ -1400,9 +1381,9 @@ TextInputHandler::InsertText(NSAttributedString *aAttrString)
// Note: mWidget might have become null here. Don't count on it from here on.
if (mCurrentKeyEvent.mKeyEvent) {
mCurrentKeyEvent.mKeyPressHandled = keyPressHandled;
mCurrentKeyEvent.mKeyPressDispatched = true;
if (currentKeyEvent) {
currentKeyEvent->mKeyPressHandled = keyPressHandled;
currentKeyEvent->mKeyPressDispatched = true;
}
NS_OBJC_END_TRY_ABORT_BLOCK;
@ -1411,13 +1392,38 @@ TextInputHandler::InsertText(NSAttributedString *aAttrString)
bool
TextInputHandler::DoCommandBySelector(const char* aSelector)
{
nsRefPtr<nsChildView> kungFuDeathGrip(mWidget);
KeyEventState* currentKeyEvent = GetCurrentKeyEvent();
PR_LOG(gLog, PR_LOG_ALWAYS,
("%p TextInputHandler::DoCommandBySelector, aSelector=\"%s\", "
"Destroyed()=%s, keypressHandled=%s",
"Destroyed()=%s, keypressHandled=%s, causedOtherKeyEvents=%s",
this, aSelector ? aSelector : "", TrueOrFalse(Destroyed()),
TrueOrFalse(mCurrentKeyEvent.mKeyPressHandled)));
currentKeyEvent ?
TrueOrFalse(currentKeyEvent->mKeyPressHandled) : "N/A",
currentKeyEvent ?
TrueOrFalse(currentKeyEvent->mCausedOtherKeyEvents) : "N/A"));
return !Destroyed() && mCurrentKeyEvent.mKeyPressHandled;
if (currentKeyEvent && !currentKeyEvent->mKeyPressDispatched) {
nsKeyEvent keypressEvent(true, NS_KEY_PRESS, mWidget);
InitKeyEvent(currentKeyEvent->mKeyEvent, keypressEvent);
if (currentKeyEvent->mKeyDownHandled ||
currentKeyEvent->mCausedOtherKeyEvents) {
keypressEvent.flags |= NS_EVENT_FLAG_NO_DEFAULT;
}
currentKeyEvent->mKeyPressHandled = DispatchEvent(keypressEvent);
currentKeyEvent->mKeyPressDispatched = true;
PR_LOG(gLog, PR_LOG_ALWAYS,
("%p TextInputHandler::DoCommandBySelector, keypress event "
"dispatched, Destroyed()=%s, keypressHandled=%s",
this, TrueOrFalse(Destroyed()),
TrueOrFalse(currentKeyEvent->mKeyPressHandled)));
}
return !Destroyed() && currentKeyEvent &&
(currentKeyEvent->mKeyPressHandled ||
currentKeyEvent->mCausedOtherKeyEvents);
}