зеркало из https://github.com/mozilla/gecko-dev.git
Merge last green changeset from inbound to mozilla-central
This commit is contained in:
Коммит
2c4e2f7b62
|
@ -59,7 +59,7 @@ interface nsIAccessibleRelation;
|
|||
* Mozilla creates the implementations of nsIAccessible on demand.
|
||||
* See http://www.mozilla.org/projects/ui/accessibility for more information.
|
||||
*/
|
||||
[scriptable, uuid(e7c44e0d-736e-4ead-afee-b51f4b574020)]
|
||||
[scriptable, uuid(46d422d1-c92f-4536-bdef-f77bc8350ec7)]
|
||||
interface nsIAccessible : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -103,13 +103,6 @@ interface nsIAccessible : nsISupports
|
|||
*/
|
||||
readonly attribute long indexInParent;
|
||||
|
||||
/**
|
||||
* The innerHTML for the HTML element associated with this accessible if applicable.
|
||||
* This is a text string of all the markup inside the DOM
|
||||
* node, not including the start and end tag for the node.
|
||||
*/
|
||||
readonly attribute DOMString innerHTML;
|
||||
|
||||
/**
|
||||
* The DOM node this nsIAccessible is associated with.
|
||||
*/
|
||||
|
|
|
@ -101,7 +101,10 @@ AccEvent::GetNode()
|
|||
nsDocAccessible*
|
||||
AccEvent::GetDocAccessible()
|
||||
{
|
||||
nsINode *node = GetNode();
|
||||
if (mAccessible)
|
||||
return mAccessible->Document();
|
||||
|
||||
nsINode* node = GetNode();
|
||||
if (node)
|
||||
return GetAccService()->GetDocAccessible(node->OwnerDoc());
|
||||
|
||||
|
|
|
@ -596,6 +596,22 @@ nsAccessibilityService::UpdateText(nsIPresShell* aPresShell,
|
|||
document->UpdateText(aContent);
|
||||
}
|
||||
|
||||
void
|
||||
nsAccessibilityService::TreeViewChanged(nsIPresShell* aPresShell,
|
||||
nsIContent* aContent,
|
||||
nsITreeView* aView)
|
||||
{
|
||||
nsDocAccessible* document = GetDocAccessible(aPresShell->GetDocument());
|
||||
if (document) {
|
||||
nsAccessible* accessible = document->GetAccessible(aContent);
|
||||
if (accessible) {
|
||||
nsRefPtr<nsXULTreeAccessible> treeAcc = do_QueryObject(accessible);
|
||||
if (treeAcc)
|
||||
treeAcc->TreeViewChanged(aView);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsAccessibilityService::UpdateListBullet(nsIPresShell* aPresShell,
|
||||
nsIContent* aHTMLListItemContent,
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "nsIObserver.h"
|
||||
|
||||
class nsImageFrame;
|
||||
class nsITreeView;
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
@ -152,6 +153,12 @@ public:
|
|||
|
||||
virtual void UpdateText(nsIPresShell* aPresShell, nsIContent* aContent);
|
||||
|
||||
/**
|
||||
* Update XUL:tree accessible tree when treeview is changed.
|
||||
*/
|
||||
void TreeViewChanged(nsIPresShell* aPresShell, nsIContent* aContent,
|
||||
nsITreeView* aView);
|
||||
|
||||
/**
|
||||
* Update list bullet accessible.
|
||||
*/
|
||||
|
|
|
@ -263,17 +263,6 @@ nsAccessible::GetRootDocument(nsIAccessibleDocument **aRootDocument)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccessible::GetInnerHTML(nsAString& aInnerHTML)
|
||||
{
|
||||
aInnerHTML.Truncate();
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLElement> htmlElement = do_QueryInterface(mContent);
|
||||
NS_ENSURE_TRUE(htmlElement, NS_ERROR_NULL_POINTER);
|
||||
|
||||
return htmlElement->GetInnerHTML(aInnerHTML);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccessible::GetLanguage(nsAString& aLanguage)
|
||||
{
|
||||
|
|
|
@ -441,13 +441,6 @@ nsApplicationAccessible::GetRootDocument(nsIAccessibleDocument **aRootDocument)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsApplicationAccessible::GetInnerHTML(nsAString &aInnerHTML)
|
||||
{
|
||||
aInnerHTML.Truncate();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsApplicationAccessible::ScrollTo(PRUint32 aScrollType)
|
||||
{
|
||||
|
|
|
@ -73,7 +73,6 @@ public:
|
|||
NS_SCRIPTABLE NS_IMETHOD GetDOMNode(nsIDOMNode** aDOMNode);
|
||||
NS_SCRIPTABLE NS_IMETHOD GetDocument(nsIAccessibleDocument** aDocument);
|
||||
NS_SCRIPTABLE NS_IMETHOD GetRootDocument(nsIAccessibleDocument** aRootDocument);
|
||||
NS_SCRIPTABLE NS_IMETHOD GetInnerHTML(nsAString& aInnerHTML);
|
||||
NS_SCRIPTABLE NS_IMETHOD ScrollTo(PRUint32 aScrollType);
|
||||
NS_SCRIPTABLE NS_IMETHOD ScrollToPoint(PRUint32 aCoordinateType, PRInt32 aX, PRInt32 aY);
|
||||
NS_SCRIPTABLE NS_IMETHOD GetLanguage(nsAString& aLanguage);
|
||||
|
|
|
@ -229,8 +229,6 @@ const char* const docEvents[] = {
|
|||
"ValueChange",
|
||||
// capture AlertActive events (fired whenever alert pops up)
|
||||
"AlertActive",
|
||||
// add ourself as a TreeViewChanged listener (custom event fired in nsTreeBodyFrame.cpp)
|
||||
"TreeViewChanged",
|
||||
"TreeRowCountChanged",
|
||||
"TreeInvalidated",
|
||||
// add ourself as a OpenStateChange listener (custom event fired in tree.xml)
|
||||
|
@ -394,11 +392,6 @@ nsRootAccessible::ProcessDOMEvent(nsIDOMEvent* aDOMEvent)
|
|||
kNameSpaceID_XUL)) {
|
||||
treeAcc = do_QueryObject(accessible);
|
||||
if (treeAcc) {
|
||||
if (eventType.EqualsLiteral("TreeViewChanged")) {
|
||||
treeAcc->TreeViewChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
if (eventType.EqualsLiteral("TreeRowCountChanged")) {
|
||||
HandleTreeRowCountChangedEvent(aDOMEvent, treeAcc);
|
||||
return;
|
||||
|
|
|
@ -118,13 +118,6 @@ nsTextEquivUtils::AppendTextEquivFromContent(nsAccessible *aInitiatorAcc,
|
|||
|
||||
gInitiatorAcc = aInitiatorAcc;
|
||||
|
||||
nsIPresShell* shell = nsCoreUtils::GetPresShellFor(aContent);
|
||||
if (!shell) {
|
||||
NS_ASSERTION(true, "There is no presshell!");
|
||||
gInitiatorAcc = nsnull;
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
// If the given content is not visible or isn't accessible then go down
|
||||
// through the DOM subtree otherwise go down through accessible subtree and
|
||||
// calculate the flat string.
|
||||
|
@ -136,7 +129,7 @@ nsTextEquivUtils::AppendTextEquivFromContent(nsAccessible *aInitiatorAcc,
|
|||
|
||||
if (isVisible) {
|
||||
nsAccessible* accessible =
|
||||
GetAccService()->GetAccessible(aContent, shell);
|
||||
gInitiatorAcc->Document()->GetAccessible(aContent);
|
||||
if (accessible) {
|
||||
rv = AppendFromAccessible(accessible, aString);
|
||||
goThroughDOMSubtree = false;
|
||||
|
|
|
@ -357,7 +357,7 @@ GetNativeFromGeckoAccessible(nsIAccessible *anAccessible)
|
|||
if (mParent)
|
||||
return mParent;
|
||||
|
||||
nsCOMPtr<nsIAccessible> accessibleParent(mGeckoAccessible->GetUnignoredParent());
|
||||
nsAccessible* accessibleParent = mGeckoAccessible->GetUnignoredParent();
|
||||
if (accessibleParent) {
|
||||
id nativeParent = GetNativeFromGeckoAccessible(accessibleParent);
|
||||
if (nativeParent)
|
||||
|
|
|
@ -100,7 +100,7 @@ public: // construction, destruction
|
|||
* not returning their children.
|
||||
*/
|
||||
void GetUnignoredChildren(nsTArray<nsRefPtr<nsAccessibleWrap> >& aChildrenArray);
|
||||
virtual already_AddRefed<nsIAccessible> GetUnignoredParent();
|
||||
nsAccessible* GetUnignoredParent() const;
|
||||
|
||||
protected:
|
||||
|
||||
|
|
|
@ -281,21 +281,15 @@ nsAccessibleWrap::GetUnignoredChildren(nsTArray<nsRefPtr<nsAccessibleWrap> > &aC
|
|||
}
|
||||
}
|
||||
|
||||
already_AddRefed<nsIAccessible>
|
||||
nsAccessibleWrap::GetUnignoredParent()
|
||||
nsAccessible*
|
||||
nsAccessibleWrap::GetUnignoredParent() const
|
||||
{
|
||||
// Go up the chain to find a parent that is not ignored.
|
||||
nsAccessibleWrap* parentWrap = static_cast<nsAccessibleWrap*>(Parent());
|
||||
if (!parentWrap)
|
||||
return nsnull;
|
||||
while (parentWrap && parentWrap->IsIgnored())
|
||||
parentWrap = static_cast<nsAccessibleWrap*>(parentWrap->Parent());
|
||||
|
||||
// recursively return the parent, until we find one that is not ignored.
|
||||
if (parentWrap->IsIgnored())
|
||||
return parentWrap->GetUnignoredParent();
|
||||
|
||||
nsIAccessible *outValue = nsnull;
|
||||
NS_IF_ADDREF(outValue = parentWrap);
|
||||
|
||||
return outValue;
|
||||
return parentWrap;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -42,131 +42,131 @@
|
|||
#include "nsIAccessible.h"
|
||||
|
||||
static const NSString* AXRoles [] = {
|
||||
NSAccessibilityUnknownRole, // ROLE_NOTHING
|
||||
NSAccessibilityUnknownRole, // ROLE_TITLEBAR. (irrelevant on OS X; windows are always native.)
|
||||
NSAccessibilityMenuBarRole, // ROLE_MENUBAR. (irrelevant on OS X; the menubar will always be native and on the top of the screen.)
|
||||
NSAccessibilityScrollBarRole, // ROLE_SCROLLBAR. we might need to make this its own mozAccessible, to support the children objects (valueindicator, down/up buttons).
|
||||
NSAccessibilitySplitterRole, // ROLE_GRIP
|
||||
NSAccessibilityUnknownRole, // ROLE_SOUND. unused on OS X
|
||||
NSAccessibilityUnknownRole, // ROLE_CURSOR. unused on OS X
|
||||
NSAccessibilityUnknownRole, // ROLE_CARET. unused on OS X
|
||||
NSAccessibilityWindowRole, // ROLE_ALERT
|
||||
NSAccessibilityWindowRole, // ROLE_WINDOW. irrelevant on OS X; all window a11y is handled by the system.
|
||||
NSAccessibilityScrollAreaRole, // ROLE_INTERNAL_FRAME
|
||||
NSAccessibilityMenuRole, // ROLE_MENUPOPUP. the parent of menuitems
|
||||
NSAccessibilityMenuItemRole, // ROLE_MENUITEM.
|
||||
@"AXHelpTag", // ROLE_TOOLTIP. 10.4+ only, so we re-define the constant.
|
||||
NSAccessibilityGroupRole, // ROLE_APPLICATION. unused on OS X. the system will take care of this.
|
||||
@"AXWebArea", // ROLE_DOCUMENT
|
||||
NSAccessibilityGroupRole, // ROLE_PANE
|
||||
NSAccessibilityUnknownRole, // ROLE_CHART
|
||||
NSAccessibilityWindowRole, // ROLE_DIALOG. there's a dialog subrole.
|
||||
NSAccessibilityUnknownRole, // ROLE_BORDER. unused on OS X
|
||||
NSAccessibilityGroupRole, // ROLE_GROUPING
|
||||
NSAccessibilityUnknownRole, // ROLE_SEPARATOR
|
||||
NSAccessibilityToolbarRole, // ROLE_TOOLBAR
|
||||
NSAccessibilityUnknownRole, // ROLE_STATUSBAR. doesn't exist on OS X (a status bar is its parts; a progressbar, a label, etc.)
|
||||
NSAccessibilityGroupRole, // ROLE_TABLE
|
||||
NSAccessibilityGroupRole, // ROLE_COLUMNHEADER
|
||||
NSAccessibilityGroupRole, // ROLE_ROWHEADER
|
||||
NSAccessibilityColumnRole, // ROLE_COLUMN
|
||||
NSAccessibilityRowRole, // ROLE_ROW
|
||||
NSAccessibilityGroupRole, // ROLE_CELL
|
||||
@"AXLink", // ROLE_LINK. 10.4+ the attr first define in SDK 10.4, so we define it here too. ROLE_LINK
|
||||
@"AXHelpTag", // ROLE_HELPBALLOON
|
||||
NSAccessibilityUnknownRole, // ROLE_CHARACTER. unused on OS X
|
||||
NSAccessibilityListRole, // ROLE_LIST
|
||||
NSAccessibilityRowRole, // ROLE_LISTITEM
|
||||
NSAccessibilityOutlineRole, // ROLE_OUTLINE
|
||||
NSAccessibilityRowRole, // ROLE_OUTLINEITEM. XXX: use OutlineRow as subrole.
|
||||
NSAccessibilityRadioButtonRole, // ROLE_PAGETAB
|
||||
NSAccessibilityGroupRole, // ROLE_PROPERTYPAGE
|
||||
NSAccessibilityUnknownRole, // ROLE_INDICATOR
|
||||
NSAccessibilityImageRole, // ROLE_GRAPHIC
|
||||
NSAccessibilityStaticTextRole, // ROLE_STATICTEXT
|
||||
NSAccessibilityStaticTextRole, // ROLE_TEXT_LEAF
|
||||
NSAccessibilityButtonRole, // ROLE_PUSHBUTTON
|
||||
NSAccessibilityCheckBoxRole, // ROLE_CHECKBUTTON
|
||||
NSAccessibilityRadioButtonRole, // ROLE_RADIOBUTTON
|
||||
NSAccessibilityPopUpButtonRole, // ROLE_COMBOBOX
|
||||
NSAccessibilityPopUpButtonRole, // ROLE_DROPLIST.
|
||||
NSAccessibilityProgressIndicatorRole, // ROLE_PROGRESSBAR
|
||||
NSAccessibilityUnknownRole, // ROLE_DIAL
|
||||
NSAccessibilityUnknownRole, // ROLE_HOTKEYFIELD
|
||||
NSAccessibilitySliderRole, // ROLE_SLIDER
|
||||
NSAccessibilityIncrementorRole, // ROLE_SPINBUTTON. subroles: Increment/Decrement.
|
||||
NSAccessibilityUnknownRole, // ROLE_DIAGRAM
|
||||
NSAccessibilityUnknownRole, // ROLE_ANIMATION
|
||||
NSAccessibilityUnknownRole, // ROLE_EQUATION
|
||||
NSAccessibilityPopUpButtonRole, // ROLE_BUTTONDROPDOWN.
|
||||
NSAccessibilityMenuButtonRole, // ROLE_BUTTONMENU
|
||||
NSAccessibilityGroupRole, // ROLE_BUTTONDROPDOWNGRID
|
||||
NSAccessibilityUnknownRole, // ROLE_WHITESPACE
|
||||
NSAccessibilityTabGroupRole, // ROLE_PAGETABLIST
|
||||
NSAccessibilityUnknownRole, // ROLE_CLOCK. unused on OS X
|
||||
NSAccessibilityButtonRole, // ROLE_SPLITBUTTON
|
||||
NSAccessibilityUnknownRole, // ROLE_IPADDRESS
|
||||
NSAccessibilityStaticTextRole, // ROLE_ACCEL_LABEL
|
||||
NSAccessibilityUnknownRole, // ROLE_ARROW
|
||||
NSAccessibilityImageRole, // ROLE_CANVAS
|
||||
NSAccessibilityMenuItemRole, // ROLE_CHECK_MENU_ITEM
|
||||
NSAccessibilityColorWellRole, // ROLE_COLOR_CHOOSER
|
||||
NSAccessibilityUnknownRole, // ROLE_DATE_EDITOR
|
||||
NSAccessibilityImageRole, // ROLE_DESKTOP_ICON
|
||||
NSAccessibilityUnknownRole, // ROLE_DESKTOP_FRAME
|
||||
NSAccessibilityBrowserRole, // ROLE_DIRECTORY_PANE
|
||||
NSAccessibilityUnknownRole, // ROLE_FILE_CHOOSER. unused on OS X
|
||||
NSAccessibilityUnknownRole, // ROLE_FONT_CHOOSER
|
||||
NSAccessibilityUnknownRole, // ROLE_CHROME_WINDOW. unused on OS X
|
||||
NSAccessibilityGroupRole, // ROLE_GLASS_PANE
|
||||
NSAccessibilityUnknownRole, // ROLE_HTML_CONTAINER
|
||||
NSAccessibilityImageRole, // ROLE_ICON
|
||||
NSAccessibilityStaticTextRole, // ROLE_LABEL
|
||||
NSAccessibilityGroupRole, // ROLE_LAYERED_PANE
|
||||
NSAccessibilityGroupRole, // ROLE_OPTION_PANE
|
||||
NSAccessibilityTextFieldRole, // ROLE_PASSWORD_TEXT
|
||||
NSAccessibilityUnknownRole, // ROLE_POPUP_MENU. unused
|
||||
NSAccessibilityMenuItemRole, // ROLE_RADIO_MENU_ITEM
|
||||
NSAccessibilityGroupRole, // ROLE_ROOT_PANE
|
||||
NSAccessibilityScrollAreaRole, // ROLE_SCROLL_PANE
|
||||
NSAccessibilitySplitGroupRole, // ROLE_SPLIT_PANE
|
||||
NSAccessibilityUnknownRole, // ROLE_TABLE_COLUMN_HEADER
|
||||
NSAccessibilityUnknownRole, // ROLE_TABLE_ROW_HEADER
|
||||
NSAccessibilityMenuItemRole, // ROLE_TEAR_OFF_MENU_ITEM
|
||||
NSAccessibilityUnknownRole, // ROLE_TERMINAL
|
||||
NSAccessibilityGroupRole, // ROLE_TEXT_CONTAINER
|
||||
NSAccessibilityButtonRole, // ROLE_TOGGLE_BUTTON
|
||||
NSAccessibilityTableRole, // ROLE_TREE_TABLE
|
||||
NSAccessibilityUnknownRole, // ROLE_VIEWPORT
|
||||
NSAccessibilityGroupRole, // ROLE_HEADER
|
||||
NSAccessibilityGroupRole, // ROLE_FOOTER
|
||||
NSAccessibilityGroupRole, // ROLE_PARAGRAPH
|
||||
@"AXRuler", // ROLE_RULER. 10.4+ only, so we re-define the constant.
|
||||
NSAccessibilityUnknownRole, // ROLE_AUTOCOMPLETE
|
||||
NSAccessibilityTextFieldRole, // ROLE_EDITBAR
|
||||
NSAccessibilityTextFieldRole, // ROLE_ENTRY
|
||||
NSAccessibilityStaticTextRole, // ROLE_CAPTION
|
||||
NSAccessibilityScrollAreaRole, // ROLE_DOCUMENT_FRAME
|
||||
@"AXHeading", // ROLE_HEADING
|
||||
NSAccessibilityGroupRole, // ROLE_PAG
|
||||
NSAccessibilityGroupRole, // ROLE_SECTION
|
||||
NSAccessibilityUnknownRole, // ROLE_REDUNDANT_OBJECT
|
||||
NSAccessibilityGroupRole, // ROLE_FORM
|
||||
NSAccessibilityUnknownRole, // ROLE_IME
|
||||
NSAccessibilityUnknownRole, // ROLE_APP_ROOT. unused on OS X
|
||||
NSAccessibilityMenuItemRole, // ROLE_PARENT_MENUITEM
|
||||
NSAccessibilityGroupRole, // ROLE_CALENDAR
|
||||
NSAccessibilityMenuRole, // ROLE_COMBOBOX_LIST
|
||||
NSAccessibilityMenuItemRole, // ROLE_COMBOBOX_OPTION
|
||||
NSAccessibilityImageRole, // ROLE_IMAGE_MAP
|
||||
NSAccessibilityRowRole, // ROLE_OPTION
|
||||
NSAccessibilityRowRole, // ROLE_RICH_OPTION
|
||||
NSAccessibilityListRole, // ROLE_LISTBOX
|
||||
NSAccessibilityUnknownRole, // ROLE_FLAT_EQUATION
|
||||
NSAccessibilityGroupRole, // ROLE_GRID_CELL
|
||||
NSAccessibilityGroupRole, // ROLE_EMBEDDED_OBJECT
|
||||
NSAccessibilityGroupRole, // ROLE_NOTE
|
||||
NSAccessibilityGroupRole, // ROLE_FIGURE
|
||||
NSAccessibilityCheckBoxRole, // ROLE_CHECK_RICH_OPTION
|
||||
@"ROLE_LAST_ENTRY" // ROLE_LAST_ENTRY. bogus role that will never be shown (just marks the end of this array)!
|
||||
NSAccessibilityUnknownRole, // roles::NOTHING 0
|
||||
NSAccessibilityUnknownRole, // roles::TITLEBAR 1 Irrelevant on OS X; windows are always native.
|
||||
NSAccessibilityScrollBarRole, // roles::SCROLLBAR 3 We might need to make this its own mozAccessible, to support the children objects (valueindicator, down/up buttons).
|
||||
NSAccessibilityMenuBarRole, // roles::MENUBAR 2 Irrelevant on OS X; the menubar will always be native and on the top of the screen.
|
||||
NSAccessibilitySplitterRole, // roles::GRIP 4
|
||||
NSAccessibilityUnknownRole, // roles::SOUND 5 Unused on OS X.
|
||||
NSAccessibilityUnknownRole, // roles::CURSOR 6 Unused on OS X.
|
||||
NSAccessibilityUnknownRole, // roles::CARET 7 Unused on OS X.
|
||||
NSAccessibilityWindowRole, // roles::ALERT 8
|
||||
NSAccessibilityWindowRole, // roles::WINDOW 9 Irrelevant on OS X; all window a11y is handled by the system.
|
||||
NSAccessibilityScrollAreaRole, // roles::INTERNAL_FRAME 10
|
||||
NSAccessibilityMenuRole, // roles::MENUPOPUP 11 The parent of menuitems.
|
||||
NSAccessibilityMenuItemRole, // roles::MENUITEM 12
|
||||
@"AXHelpTag", // roles::TOOLTIP 13 10.4+ only, so we re-define the constant.
|
||||
NSAccessibilityGroupRole, // roles::APPLICATION 14 Unused on OS X. the system will take care of this.
|
||||
@"AXWebArea", // roles::DOCUMENT 15
|
||||
NSAccessibilityGroupRole, // roles::PANE 16
|
||||
NSAccessibilityUnknownRole, // roles::CHART 17
|
||||
NSAccessibilityWindowRole, // roles::DIALOG 18 There's a dialog subrole.
|
||||
NSAccessibilityUnknownRole, // roles::BORDER 19 Unused on OS X.
|
||||
NSAccessibilityGroupRole, // roles::GROUPING 20
|
||||
NSAccessibilityUnknownRole, // roles::SEPARATOR 21
|
||||
NSAccessibilityToolbarRole, // roles::TOOLBAR 22
|
||||
NSAccessibilityUnknownRole, // roles::STATUSBAR 23 Doesn't exist on OS X (a status bar is its parts; a progressbar, a label, etc.)
|
||||
NSAccessibilityGroupRole, // roles::TABLE 24
|
||||
NSAccessibilityGroupRole, // roles::COLUMNHEADER 25
|
||||
NSAccessibilityGroupRole, // roles::ROWHEADER 26
|
||||
NSAccessibilityColumnRole, // roles::COLUMN 27
|
||||
NSAccessibilityRowRole, // roles::ROW 28
|
||||
NSAccessibilityGroupRole, // roles::CELL 29
|
||||
@"AXLink", // roles::LINK 30 10.4+ the attr first define in SDK 10.4, so we define it here too. ROLE_LINK
|
||||
@"AXHelpTag", // roles::HELPBALLOON 31
|
||||
NSAccessibilityUnknownRole, // roles::CHARACTER 32 Unused on OS X.
|
||||
NSAccessibilityListRole, // roles::LIST 33
|
||||
NSAccessibilityRowRole, // roles::LISTITEM 34
|
||||
NSAccessibilityOutlineRole, // roles::OUTLINE 35
|
||||
NSAccessibilityRowRole, // roles::OUTLINEITEM 36 XXX: use OutlineRow as subrole.
|
||||
NSAccessibilityRadioButtonRole, // roles::PAGETAB 37
|
||||
NSAccessibilityGroupRole, // roles::PROPERTYPAGE 38
|
||||
NSAccessibilityUnknownRole, // roles::INDICATOR 39
|
||||
NSAccessibilityImageRole, // roles::GRAPHIC 40
|
||||
NSAccessibilityStaticTextRole, // roles::STATICTEXT 41
|
||||
NSAccessibilityStaticTextRole, // roles::TEXT_LEAF 42
|
||||
NSAccessibilityButtonRole, // roles::PUSHBUTTON 43
|
||||
NSAccessibilityCheckBoxRole, // roles::CHECKBUTTON 44
|
||||
NSAccessibilityRadioButtonRole, // roles::RADIOBUTTON 45
|
||||
NSAccessibilityPopUpButtonRole, // roles::COMBOBOX 46
|
||||
NSAccessibilityPopUpButtonRole, // roles::DROPLIST 47
|
||||
NSAccessibilityProgressIndicatorRole, // roles::PROGRESSBAR 48
|
||||
NSAccessibilityUnknownRole, // roles::DIAL 49
|
||||
NSAccessibilityUnknownRole, // roles::HOTKEYFIELD 50
|
||||
NSAccessibilitySliderRole, // roles::SLIDER 51
|
||||
NSAccessibilityIncrementorRole, // roles::SPINBUTTON 52 Subroles: Increment/Decrement.
|
||||
NSAccessibilityUnknownRole, // roles::DIAGRAM 53
|
||||
NSAccessibilityUnknownRole, // roles::ANIMATION 54
|
||||
NSAccessibilityUnknownRole, // roles::EQUATION 55
|
||||
NSAccessibilityPopUpButtonRole, // roles::BUTTONDROPDOWN 56
|
||||
NSAccessibilityMenuButtonRole, // roles::BUTTONMENU 57
|
||||
NSAccessibilityGroupRole, // roles::BUTTONDROPDOWNGRID 58
|
||||
NSAccessibilityUnknownRole, // roles::WHITESPACE 59
|
||||
NSAccessibilityTabGroupRole, // roles::PAGETABLIST 60
|
||||
NSAccessibilityUnknownRole, // roles::CLOCK 61 Unused on OS X
|
||||
NSAccessibilityButtonRole, // roles::SPLITBUTTON 62
|
||||
NSAccessibilityUnknownRole, // roles::IPADDRESS 63
|
||||
NSAccessibilityStaticTextRole, // roles::ACCEL_LABEL 64
|
||||
NSAccessibilityUnknownRole, // roles::ARROW 65
|
||||
NSAccessibilityImageRole, // roles::CANVAS 66
|
||||
NSAccessibilityMenuItemRole, // roles::CHECK_MENU_ITEM 67
|
||||
NSAccessibilityColorWellRole, // roles::COLOR_CHOOSER 68
|
||||
NSAccessibilityUnknownRole, // roles::DATE_EDITOR 69
|
||||
NSAccessibilityImageRole, // roles::DESKTOP_ICON 70
|
||||
NSAccessibilityUnknownRole, // roles::DESKTOP_FRAME 71
|
||||
NSAccessibilityBrowserRole, // roles::DIRECTORY_PANE 72
|
||||
NSAccessibilityUnknownRole, // roles::FILE_CHOOSER 73 Unused on OS X
|
||||
NSAccessibilityUnknownRole, // roles::FONT_CHOOSER 74
|
||||
NSAccessibilityUnknownRole, // roles::CHROME_WINDOW 75 Unused on OS X
|
||||
NSAccessibilityGroupRole, // roles::GLASS_PANE 76
|
||||
NSAccessibilityUnknownRole, // roles::HTML_CONTAINER 77
|
||||
NSAccessibilityImageRole, // roles::ICON 78
|
||||
NSAccessibilityStaticTextRole, // roles::LABEL 79
|
||||
NSAccessibilityGroupRole, // roles::LAYERED_PANE 80
|
||||
NSAccessibilityGroupRole, // roles::OPTION_PANE 81
|
||||
NSAccessibilityTextFieldRole, // roles::PASSWORD_TEXT 82
|
||||
NSAccessibilityUnknownRole, // roles::POPUP_MENU 83 Unused
|
||||
NSAccessibilityMenuItemRole, // roles::RADIO_MENU_ITEM 84
|
||||
NSAccessibilityGroupRole, // roles::ROOT_PANE 85
|
||||
NSAccessibilityScrollAreaRole, // roles::SCROLL_PANE 86
|
||||
NSAccessibilitySplitGroupRole, // roles::SPLIT_PANE 87
|
||||
NSAccessibilityUnknownRole, // roles::TABLE_COLUMN_HEADER 88
|
||||
NSAccessibilityUnknownRole, // roles::TABLE_ROW_HEADER 89
|
||||
NSAccessibilityMenuItemRole, // roles::TEAR_OFF_MENU_ITEM 90
|
||||
NSAccessibilityUnknownRole, // roles::TERMINAL 91
|
||||
NSAccessibilityGroupRole, // roles::TEXT_CONTAINER 92
|
||||
NSAccessibilityButtonRole, // roles::TOGGLE_BUTTON 93
|
||||
NSAccessibilityTableRole, // roles::TREE_TABLE 94
|
||||
NSAccessibilityUnknownRole, // roles::VIEWPORT 95
|
||||
NSAccessibilityGroupRole, // roles::HEADER 96
|
||||
NSAccessibilityGroupRole, // roles::FOOTER 97
|
||||
NSAccessibilityGroupRole, // roles::PARAGRAPH 98
|
||||
@"AXRuler", // roles::RULER 99 10.4+ only, so we re-define the constant.
|
||||
NSAccessibilityComboBoxRole, // roles::AUTOCOMPLETE 100
|
||||
NSAccessibilityTextFieldRole, // roles::EDITBAR 101
|
||||
NSAccessibilityTextFieldRole, // roles::ENTRY 102
|
||||
NSAccessibilityStaticTextRole, // roles::CAPTION 103
|
||||
NSAccessibilityScrollAreaRole, // roles::DOCUMENT_FRAME 104
|
||||
@"AXHeading", // roles::HEADING 105
|
||||
NSAccessibilityGroupRole, // roles::PAGE 106
|
||||
NSAccessibilityGroupRole, // roles::SECTION 107
|
||||
NSAccessibilityUnknownRole, // roles::REDUNDANT_OBJECT 108
|
||||
NSAccessibilityGroupRole, // roles::FORM 109
|
||||
NSAccessibilityUnknownRole, // roles::IME 110
|
||||
NSAccessibilityUnknownRole, // roles::APP_ROOT 111 Unused on OS X
|
||||
NSAccessibilityMenuItemRole, // roles::PARENT_MENUITEM 112
|
||||
NSAccessibilityGroupRole, // roles::CALENDAR 113
|
||||
NSAccessibilityMenuRole, // roles::COMBOBOX_LIST 114
|
||||
NSAccessibilityMenuItemRole, // roles::COMBOBOX_OPTION 115
|
||||
NSAccessibilityImageRole, // roles::IMAGE_MAP 116
|
||||
NSAccessibilityRowRole, // roles::OPTION 117
|
||||
NSAccessibilityRowRole, // roles::RICH_OPTION 118
|
||||
NSAccessibilityListRole, // roles::LISTBOX 119
|
||||
NSAccessibilityUnknownRole, // roles::FLAT_EQUATION 120
|
||||
NSAccessibilityGroupRole, // roles::GRID_CELL 121
|
||||
NSAccessibilityGroupRole, // roles::EMBEDDED_OBJECT 122
|
||||
NSAccessibilityGroupRole, // roles::NOTE 123
|
||||
NSAccessibilityGroupRole, // roles::FIGURE 124
|
||||
NSAccessibilityCheckBoxRole, // roles::CHECK_RICH_OPTION 125
|
||||
@"ROLE_LAST_ENTRY" // roles::LAST_ENTRY Bogus role that will never be shown (just marks the end of this array)!
|
||||
};
|
||||
|
|
|
@ -64,7 +64,7 @@ CAccessibleHyperlink::QueryInterface(REFIID iid, void** ppv)
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
return CAccessibleAction::QueryInterface(iid, ppv);
|
||||
return ia2AccessibleAction::QueryInterface(iid, ppv);
|
||||
}
|
||||
|
||||
// IAccessibleHyperlink
|
||||
|
|
|
@ -43,10 +43,10 @@
|
|||
|
||||
#include "nsISupports.h"
|
||||
|
||||
#include "CAccessibleAction.h"
|
||||
#include "ia2AccessibleAction.h"
|
||||
#include "AccessibleHyperlink.h"
|
||||
|
||||
class CAccessibleHyperlink: public CAccessibleAction,
|
||||
class CAccessibleHyperlink: public ia2AccessibleAction,
|
||||
public IAccessibleHyperlink
|
||||
{
|
||||
public:
|
||||
|
@ -55,7 +55,7 @@ public:
|
|||
STDMETHODIMP QueryInterface(REFIID, void**);
|
||||
|
||||
// IAccessibleAction
|
||||
FORWARD_IACCESSIBLEACTION(CAccessibleAction)
|
||||
FORWARD_IACCESSIBLEACTION(ia2AccessibleAction)
|
||||
|
||||
virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_anchor(
|
||||
/* [in] */ long index,
|
||||
|
|
|
@ -63,7 +63,7 @@ CPPSRCS = \
|
|||
nsHTMLTableAccessibleWrap.cpp \
|
||||
nsApplicationAccessibleWrap.cpp \
|
||||
nsWinUtils.cpp \
|
||||
CAccessibleAction.cpp \
|
||||
ia2AccessibleAction.cpp \
|
||||
CAccessibleImage.cpp \
|
||||
CAccessibleComponent.cpp \
|
||||
CAccessibleText.cpp \
|
||||
|
@ -92,7 +92,7 @@ EXPORTS = \
|
|||
nsHTMLImageAccessibleWrap.h \
|
||||
nsHTMLTableAccessibleWrap.h \
|
||||
nsApplicationAccessibleWrap.h \
|
||||
CAccessibleAction.h \
|
||||
ia2AccessibleAction.h \
|
||||
CAccessibleImage.h \
|
||||
CAccessibleComponent.h \
|
||||
CAccessibleText.h \
|
||||
|
|
|
@ -38,16 +38,16 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "CAccessibleAction.h"
|
||||
#include "ia2AccessibleAction.h"
|
||||
|
||||
#include "AccessibleAction_i.c"
|
||||
|
||||
#include "nsAccessible.h"
|
||||
#include "nsAccessibleWrap.h"
|
||||
|
||||
// IUnknown
|
||||
|
||||
STDMETHODIMP
|
||||
CAccessibleAction::QueryInterface(REFIID iid, void** ppv)
|
||||
ia2AccessibleAction::QueryInterface(REFIID iid, void** ppv)
|
||||
{
|
||||
*ppv = NULL;
|
||||
|
||||
|
@ -63,7 +63,7 @@ CAccessibleAction::QueryInterface(REFIID iid, void** ppv)
|
|||
// IAccessibleAction
|
||||
|
||||
STDMETHODIMP
|
||||
CAccessibleAction::nActions(long* aActionCount)
|
||||
ia2AccessibleAction::nActions(long* aActionCount)
|
||||
{
|
||||
__try {
|
||||
if (!aActionCount)
|
||||
|
@ -71,8 +71,8 @@ __try {
|
|||
|
||||
*aActionCount = 0;
|
||||
|
||||
nsRefPtr<nsAccessible> acc(do_QueryObject(this));
|
||||
if (!acc || acc->IsDefunct())
|
||||
nsAccessibleWrap* acc = static_cast<nsAccessibleWrap*>(this);
|
||||
if (acc->IsDefunct())
|
||||
return E_FAIL;
|
||||
|
||||
*aActionCount = acc->ActionCount();
|
||||
|
@ -83,11 +83,11 @@ __try {
|
|||
}
|
||||
|
||||
STDMETHODIMP
|
||||
CAccessibleAction::doAction(long aActionIndex)
|
||||
ia2AccessibleAction::doAction(long aActionIndex)
|
||||
{
|
||||
__try {
|
||||
nsCOMPtr<nsIAccessible> acc(do_QueryObject(this));
|
||||
if (!acc)
|
||||
nsAccessibleWrap* acc = static_cast<nsAccessibleWrap*>(this);
|
||||
if (acc->IsDefunct())
|
||||
return E_FAIL;
|
||||
|
||||
PRUint8 index = static_cast<PRUint8>(aActionIndex);
|
||||
|
@ -99,13 +99,13 @@ __try {
|
|||
}
|
||||
|
||||
STDMETHODIMP
|
||||
CAccessibleAction::get_description(long aActionIndex, BSTR *aDescription)
|
||||
ia2AccessibleAction::get_description(long aActionIndex, BSTR *aDescription)
|
||||
{
|
||||
__try {
|
||||
*aDescription = NULL;
|
||||
|
||||
nsCOMPtr<nsIAccessible> acc(do_QueryObject(this));
|
||||
if (!acc)
|
||||
nsAccessibleWrap* acc = static_cast<nsAccessibleWrap*>(this);
|
||||
if (acc->IsDefunct())
|
||||
return E_FAIL;
|
||||
|
||||
nsAutoString description;
|
||||
|
@ -126,7 +126,7 @@ __try {
|
|||
}
|
||||
|
||||
STDMETHODIMP
|
||||
CAccessibleAction::get_keyBinding(long aActionIndex, long aNumMaxBinding,
|
||||
ia2AccessibleAction::get_keyBinding(long aActionIndex, long aNumMaxBinding,
|
||||
BSTR **aKeyBinding,
|
||||
long *aNumBinding)
|
||||
{
|
||||
|
@ -142,8 +142,8 @@ __try {
|
|||
if (aActionIndex != 0 || aNumMaxBinding < 1)
|
||||
return E_INVALIDARG;
|
||||
|
||||
nsRefPtr<nsAccessible> acc(do_QueryObject(this));
|
||||
if (!acc || acc->IsDefunct())
|
||||
nsAccessibleWrap* acc = static_cast<nsAccessibleWrap*>(this);
|
||||
if (acc->IsDefunct())
|
||||
return E_FAIL;
|
||||
|
||||
// Expose keyboard shortcut if it's not exposed via MSAA keyboard shortcut.
|
||||
|
@ -176,13 +176,13 @@ __try {
|
|||
}
|
||||
|
||||
STDMETHODIMP
|
||||
CAccessibleAction::get_name(long aActionIndex, BSTR *aName)
|
||||
ia2AccessibleAction::get_name(long aActionIndex, BSTR *aName)
|
||||
{
|
||||
__try {
|
||||
*aName = NULL;
|
||||
|
||||
nsCOMPtr<nsIAccessible> acc(do_QueryObject(this));
|
||||
if (!acc)
|
||||
nsAccessibleWrap* acc = static_cast<nsAccessibleWrap*>(this);
|
||||
if (acc->IsDefunct())
|
||||
return E_FAIL;
|
||||
|
||||
nsAutoString name;
|
||||
|
@ -202,7 +202,7 @@ __try {
|
|||
}
|
||||
|
||||
STDMETHODIMP
|
||||
CAccessibleAction::get_localizedName(long aActionIndex, BSTR *aLocalizedName)
|
||||
ia2AccessibleAction::get_localizedName(long aActionIndex, BSTR *aLocalizedName)
|
||||
{
|
||||
__try {
|
||||
*aLocalizedName = NULL;
|
|
@ -45,7 +45,7 @@
|
|||
|
||||
#include "AccessibleAction.h"
|
||||
|
||||
class CAccessibleAction: public IAccessibleAction
|
||||
class ia2AccessibleAction: public IAccessibleAction
|
||||
{
|
||||
public:
|
||||
|
||||
|
@ -77,9 +77,6 @@ public:
|
|||
/* [in] */ long actionIndex,
|
||||
/* [retval][out] */ BSTR *localizedName);
|
||||
|
||||
// nsISupports
|
||||
NS_IMETHOD QueryInterface(const nsIID& uuid, void** result) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
|
@ -688,7 +688,7 @@ nsXULTreeAccessible::TreeViewInvalidated(PRInt32 aStartRow, PRInt32 aEndRow,
|
|||
}
|
||||
|
||||
void
|
||||
nsXULTreeAccessible::TreeViewChanged()
|
||||
nsXULTreeAccessible::TreeViewChanged(nsITreeView* aView)
|
||||
{
|
||||
if (IsDefunct())
|
||||
return;
|
||||
|
@ -704,7 +704,7 @@ nsXULTreeAccessible::TreeViewChanged()
|
|||
|
||||
// Clear cache.
|
||||
ClearCache(mAccessibleCache);
|
||||
mTree->GetView(getter_AddRefs(mTreeView));
|
||||
mTreeView = aView;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -146,7 +146,7 @@ public:
|
|||
/**
|
||||
* Invalidates children created for previous tree view.
|
||||
*/
|
||||
void TreeViewChanged();
|
||||
void TreeViewChanged(nsITreeView* aView);
|
||||
|
||||
protected:
|
||||
/**
|
||||
|
|
|
@ -3,13 +3,8 @@
|
|||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
|
||||
<!--
|
||||
Bug 368835 - fire TreeViewChanged/TreeRowCountChanged events.
|
||||
Bug 308564 - no accessibility events when data in a tree row changes.
|
||||
-->
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="DOM TreeViewChanged/TreeRowCountChanged and a11y name change events.">
|
||||
title="DOM TreeRowCountChanged and a11y name change events.">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
|
@ -28,20 +23,6 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
// Invoker's checkers
|
||||
|
||||
/**
|
||||
* Check TreeViewChanged event and run through accessible tree to ensure
|
||||
* it's created.
|
||||
*/
|
||||
function treeViewChangedChecker(aMsg)
|
||||
{
|
||||
this.type = "TreeViewChanged";
|
||||
this.target = gTree;
|
||||
this.getID = function getID()
|
||||
{
|
||||
return "TreeViewChanged";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check TreeRowCountChanged event.
|
||||
*/
|
||||
|
@ -120,7 +101,7 @@
|
|||
// Invokers
|
||||
|
||||
/**
|
||||
* Set tree view and process TreeViewChanged handler.
|
||||
* Set tree view.
|
||||
*/
|
||||
function setTreeView()
|
||||
{
|
||||
|
@ -132,7 +113,6 @@
|
|||
this.getID = function setTreeView_getID() { return "set tree view"; }
|
||||
|
||||
this.eventSeq = [
|
||||
new treeViewChangedChecker(),
|
||||
new invokerChecker(EVENT_REORDER, gTree)
|
||||
];
|
||||
};
|
||||
|
@ -298,6 +278,11 @@
|
|||
title="No accessibility events when data in a tree row changes.">
|
||||
Mozilla Bug 308564
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=739524"
|
||||
title="replace TreeViewChanged DOM event on direct call from XUL tree.">
|
||||
Mozilla Bug 739524
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
|
|
|
@ -306,10 +306,29 @@ var shell = {
|
|||
}
|
||||
}
|
||||
let idleTimeout = Services.prefs.getIntPref("power.screen.timeout");
|
||||
if (idleTimeout) {
|
||||
Services.idle.addIdleObserver(idleHandler, idleTimeout);
|
||||
power.addWakeLockListener(wakeLockHandler);
|
||||
let request = navigator.mozSettings.getLock().get("power.screen.timeout");
|
||||
request.onsuccess = function onSuccess() {
|
||||
idleTimeout = request.result["power.screen.timeout"] || idleTimeout;
|
||||
if (idleTimeout) {
|
||||
Services.idle.addIdleObserver(idleHandler, idleTimeout);
|
||||
power.addWakeLockListener(wakeLockHandler);
|
||||
}
|
||||
}
|
||||
request.onerror = function onError() {
|
||||
if (idleTimeout) {
|
||||
Services.idle.addIdleObserver(idleHandler, idleTimeout);
|
||||
power.addWakeLockListener(wakeLockHandler);
|
||||
}
|
||||
}
|
||||
// XXX We may override other's callback here, but this is the only
|
||||
// user of mozSettings in shell.js at this moment.
|
||||
navigator.mozSettings.onsettingchange = function onSettingChange(e) {
|
||||
if (e.settingName == "power.screen.timeout" && e.settingValue) {
|
||||
Services.idle.removeIdleObserver(idleHandler, idleTimeout);
|
||||
idleTimeout = e.settingValue;
|
||||
Services.idle.addIdleObserver(idleHandler, idleTimeout);
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
function nsBrowserAccess() {
|
||||
|
|
|
@ -178,26 +178,10 @@ enum {
|
|||
// Set if the node has had :hover selectors matched against it
|
||||
NODE_HAS_RELEVANT_HOVER_RULES = 0x00080000U,
|
||||
|
||||
// Two bits for the script-type ID. Not enough to represent all
|
||||
// nsIProgrammingLanguage values, but we don't care. In practice,
|
||||
// we can represent the ones we want, and we can fail the others at
|
||||
// runtime.
|
||||
NODE_SCRIPT_TYPE_OFFSET = 20,
|
||||
|
||||
NODE_SCRIPT_TYPE_SIZE = 2,
|
||||
|
||||
NODE_SCRIPT_TYPE_MASK = (1 << NODE_SCRIPT_TYPE_SIZE) - 1,
|
||||
|
||||
// Remaining bits are node type specific.
|
||||
NODE_TYPE_SPECIFIC_BITS_OFFSET =
|
||||
NODE_SCRIPT_TYPE_OFFSET + NODE_SCRIPT_TYPE_SIZE
|
||||
NODE_TYPE_SPECIFIC_BITS_OFFSET = 20
|
||||
};
|
||||
|
||||
PR_STATIC_ASSERT(PRUint32(nsIProgrammingLanguage::JAVASCRIPT) <=
|
||||
PRUint32(NODE_SCRIPT_TYPE_MASK));
|
||||
PR_STATIC_ASSERT(PRUint32(nsIProgrammingLanguage::PYTHON) <=
|
||||
PRUint32(NODE_SCRIPT_TYPE_MASK));
|
||||
|
||||
// Useful inline function for getting a node given an nsIContent and an
|
||||
// nsIDocument. Returns the first argument cast to nsINode if it is non-null,
|
||||
// otherwise returns the second (which may be null). We use type variables
|
||||
|
@ -291,8 +275,8 @@ private:
|
|||
|
||||
// IID for the nsINode interface
|
||||
#define NS_INODE_IID \
|
||||
{ 0x458300ed, 0xe418, 0x4577, \
|
||||
{ 0x89, 0xd7, 0xfe, 0xf1, 0x34, 0xf3, 0x52, 0x19 } }
|
||||
{ 0x772e7e52, 0xfadf, 0x4962, \
|
||||
{ 0x8d, 0x96, 0x58, 0xfe, 0x75, 0x68, 0xaf, 0xa8 } }
|
||||
|
||||
/**
|
||||
* An internal interface that abstracts some DOMNode-related parts that both
|
||||
|
@ -1043,22 +1027,6 @@ public:
|
|||
*/
|
||||
nsIDocument* GetOwnerDocument() const;
|
||||
|
||||
/**
|
||||
* The default script type (language) ID for this node.
|
||||
* All nodes must support fetching the default script language.
|
||||
*/
|
||||
virtual PRUint32 GetScriptTypeID() const
|
||||
{ return nsIProgrammingLanguage::JAVASCRIPT; }
|
||||
|
||||
/**
|
||||
* Not all nodes support setting a new default language.
|
||||
*/
|
||||
NS_IMETHOD SetScriptTypeID(PRUint32 aLang)
|
||||
{
|
||||
NS_NOTREACHED("SetScriptTypeID not implemented");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsresult Normalize();
|
||||
|
||||
/**
|
||||
|
|
|
@ -3104,22 +3104,6 @@ nsDocument::SetHeaderData(nsIAtom* aHeaderField, const nsAString& aData)
|
|||
CopyUTF16toUTF8(aData, mContentLanguage);
|
||||
}
|
||||
|
||||
// Set the default script-type on the root element.
|
||||
if (aHeaderField == nsGkAtoms::headerContentScriptType) {
|
||||
Element *root = GetRootElement();
|
||||
if (root) {
|
||||
// Get the script-type ID for this value.
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIScriptRuntime> runtime;
|
||||
rv = NS_GetScriptRuntime(aData, getter_AddRefs(runtime));
|
||||
if (NS_FAILED(rv) || runtime == nsnull) {
|
||||
NS_WARNING("The script-type is unknown");
|
||||
} else {
|
||||
root->SetScriptTypeID(runtime->GetScriptTypeID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (aHeaderField == nsGkAtoms::headerDefaultStyle) {
|
||||
// Only mess with our stylesheets if we don't have a lastStyleSheetSet, per
|
||||
// spec.
|
||||
|
|
|
@ -509,8 +509,6 @@ public:
|
|||
|
||||
NS_DECL_SIZEOF_EXCLUDING_THIS
|
||||
|
||||
using nsINode::GetScriptTypeID;
|
||||
|
||||
virtual void Reset(nsIChannel *aChannel, nsILoadGroup *aLoadGroup);
|
||||
virtual void ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup,
|
||||
nsIPrincipal* aPrincipal);
|
||||
|
|
|
@ -2500,9 +2500,6 @@ nsGenericElement::nsGenericElement(already_AddRefed<nsINodeInfo> aNodeInfo)
|
|||
kNameSpaceID_None)),
|
||||
"Bad NodeType in aNodeInfo");
|
||||
|
||||
// Set the default scriptID to JS - but skip SetScriptTypeID as it
|
||||
// does extra work we know isn't necessary here...
|
||||
SetFlags((nsIProgrammingLanguage::JAVASCRIPT << NODE_SCRIPT_TYPE_OFFSET));
|
||||
SetIsElement();
|
||||
}
|
||||
|
||||
|
@ -3724,30 +3721,6 @@ nsGenericElement::IsNodeOfType(PRUint32 aFlags) const
|
|||
return !(aFlags & ~eCONTENT);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
PRUint32
|
||||
nsGenericElement::GetScriptTypeID() const
|
||||
{
|
||||
PtrBits flags = GetFlags();
|
||||
|
||||
return (flags >> NODE_SCRIPT_TYPE_OFFSET) & NODE_SCRIPT_TYPE_MASK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGenericElement::SetScriptTypeID(PRUint32 aLang)
|
||||
{
|
||||
if ((aLang & NODE_SCRIPT_TYPE_MASK) != aLang) {
|
||||
NS_ERROR("script ID too large!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
/* SetFlags will just mask in the specific flags set, leaving existing
|
||||
ones alone. So we must clear all the bits first */
|
||||
UnsetFlags(NODE_SCRIPT_TYPE_MASK << NODE_SCRIPT_TYPE_OFFSET);
|
||||
SetFlags(aLang << NODE_SCRIPT_TYPE_OFFSET);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericElement::InsertChildAt(nsIContent* aKid,
|
||||
PRUint32 aIndex,
|
||||
|
@ -5162,9 +5135,8 @@ nsGenericElement::AddScriptEventListener(nsIAtom* aEventName,
|
|||
}
|
||||
|
||||
defer = defer && aDefer; // only defer if everyone agrees...
|
||||
PRUint32 lang = GetScriptTypeID();
|
||||
manager->AddScriptEventListener(aEventName, aValue, lang, defer,
|
||||
!nsContentUtils::IsChromeDoc(ownerDoc));
|
||||
manager->AddScriptEventListener(aEventName, aValue, nsIProgrammingLanguage::JAVASCRIPT,
|
||||
defer, !nsContentUtils::IsChromeDoc(ownerDoc));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -343,9 +343,6 @@ public:
|
|||
virtual bool IsNodeOfType(PRUint32 aFlags) const;
|
||||
virtual bool IsLink(nsIURI** aURI) const;
|
||||
|
||||
virtual PRUint32 GetScriptTypeID() const;
|
||||
NS_IMETHOD SetScriptTypeID(PRUint32 aLang);
|
||||
|
||||
virtual void DestroyContent();
|
||||
virtual void SaveSubtreeState();
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "nsIDOMNode.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMDocumentFragment.h"
|
||||
#include "nsIDOMDocumentType.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMText.h"
|
||||
|
@ -1526,6 +1527,26 @@ nsresult nsRange::CutContents(nsIDOMDocumentFragment** aFragment)
|
|||
nsCOMPtr<nsIDOMNode> endContainer = do_QueryInterface(mEndParent);
|
||||
PRInt32 endOffset = mEndOffset;
|
||||
|
||||
if (retval) {
|
||||
// For extractContents(), abort early if there's a doctype (bug 719533).
|
||||
// This can happen only if the common ancestor is a document, in which case
|
||||
// we just need to find its doctype child and check if that's in the range.
|
||||
nsCOMPtr<nsIDOMDocument> commonAncestorDocument(do_QueryInterface(commonAncestor));
|
||||
if (commonAncestorDocument) {
|
||||
nsCOMPtr<nsIDOMDocumentType> doctype;
|
||||
rv = commonAncestorDocument->GetDoctype(getter_AddRefs(doctype));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (doctype &&
|
||||
nsContentUtils::ComparePoints(startContainer, startOffset,
|
||||
doctype.get(), 0) < 0 &&
|
||||
nsContentUtils::ComparePoints(doctype.get(), 0,
|
||||
endContainer, endOffset) < 0) {
|
||||
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create and initialize a subtree iterator that will give
|
||||
// us all the subtrees within the range.
|
||||
|
||||
|
|
|
@ -429,8 +429,7 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
|||
// (which may come from a header or http-meta tag), or if there
|
||||
// is no root element, from the script global object.
|
||||
Element* rootElement = mDocument->GetRootElement();
|
||||
PRUint32 typeID = rootElement ? rootElement->GetScriptTypeID() :
|
||||
context->GetScriptTypeID();
|
||||
PRUint32 typeID = nsIProgrammingLanguage::JAVASCRIPT;
|
||||
PRUint32 version = 0;
|
||||
nsAutoString language, type, src;
|
||||
nsresult rv = NS_OK;
|
||||
|
@ -476,7 +475,7 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
|||
NS_WARNING("Failed to find a scripting language");
|
||||
typeID = nsIProgrammingLanguage::UNKNOWN;
|
||||
} else
|
||||
typeID = runtime->GetScriptTypeID();
|
||||
typeID = nsIProgrammingLanguage::JAVASCRIPT;
|
||||
}
|
||||
if (typeID != nsIProgrammingLanguage::UNKNOWN) {
|
||||
// Get the version string, and ensure the language supports it.
|
||||
|
@ -556,8 +555,6 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
|||
return false;
|
||||
}
|
||||
|
||||
scriptContent->SetScriptTypeID(typeID);
|
||||
|
||||
// Step 14. in the HTML5 spec
|
||||
|
||||
nsRefPtr<nsScriptLoadRequest> request;
|
||||
|
@ -886,8 +883,7 @@ nsScriptLoader::EvaluateScript(nsScriptLoadRequest* aRequest,
|
|||
|
||||
// Get the script-type to be used by this element.
|
||||
NS_ASSERTION(scriptContent, "no content - what is default script-type?");
|
||||
PRUint32 stid = scriptContent ? scriptContent->GetScriptTypeID() :
|
||||
nsIProgrammingLanguage::JAVASCRIPT;
|
||||
|
||||
// and make sure we are setup for this type of script.
|
||||
rv = globalObject->EnsureScriptEnvironment();
|
||||
if (NS_FAILED(rv))
|
||||
|
@ -925,20 +921,9 @@ nsScriptLoader::EvaluateScript(nsScriptLoadRequest* aRequest,
|
|||
mCurrentScript = oldCurrent;
|
||||
|
||||
JSContext *cx = nsnull; // Initialize this to keep GCC happy.
|
||||
if (stid == nsIProgrammingLanguage::JAVASCRIPT) {
|
||||
cx = context->GetNativeContext();
|
||||
::JS_BeginRequest(cx);
|
||||
NS_ASSERTION(!::JS_IsExceptionPending(cx),
|
||||
"JS_ReportPendingException wasn't called in EvaluateString");
|
||||
}
|
||||
|
||||
cx = context->GetNativeContext();
|
||||
JSAutoRequest ar(cx);
|
||||
context->SetProcessingScriptTag(oldProcessingScriptTag);
|
||||
|
||||
if (stid == nsIProgrammingLanguage::JAVASCRIPT) {
|
||||
NS_ASSERTION(!::JS_IsExceptionPending(cx),
|
||||
"JS_ReportPendingException wasn't called");
|
||||
::JS_EndRequest(cx);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -579,6 +579,7 @@ _TEST_FILES2 = \
|
|||
test_bug650386_redirect_307.html \
|
||||
file_bug650386_content.sjs \
|
||||
file_bug650386_report.sjs \
|
||||
test_bug719533.html \
|
||||
$(NULL)
|
||||
|
||||
_CHROME_FILES = \
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
<!doctype html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=719544
|
||||
-->
|
||||
<title>Test for Bug 719544</title>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=719544">Mozilla Bug 719544</a>
|
||||
<script>
|
||||
|
||||
/** Test for Bug 719544 **/
|
||||
var threw = false;
|
||||
var origLength = document.childNodes.length;
|
||||
try {
|
||||
var range = document.createRange();
|
||||
range.selectNodeContents(document);
|
||||
range.extractContents();
|
||||
} catch(e) {
|
||||
threw = true;
|
||||
is(Object.getPrototypeOf(e), DOMException.prototype,
|
||||
"Must throw DOMException");
|
||||
is(e.name, "HierarchyRequestError", "Must throw HierarchyRequestError");
|
||||
}
|
||||
ok(threw, "Must throw");
|
||||
is(document.childNodes.length, origLength, "Must preserve original children");
|
||||
|
||||
</script>
|
|
@ -1047,11 +1047,6 @@ nsEventListenerManager::GetJSEventListener(nsIAtom *aEventName, jsval *vp)
|
|||
}
|
||||
|
||||
nsIJSEventListener *listener = ls->GetJSListener();
|
||||
if (listener->GetEventContext()->GetScriptTypeID() !=
|
||||
nsIProgrammingLanguage::JAVASCRIPT) {
|
||||
// Not JS, so no point doing anything with it.
|
||||
return;
|
||||
}
|
||||
|
||||
if (ls->mHandlerIsString) {
|
||||
CompileEventHandlerInternal(ls, true, nsnull);
|
||||
|
|
|
@ -148,8 +148,10 @@ public:
|
|||
NS_ASSERTION(mStreams.IsEmpty(), "Stream(s) still open!");
|
||||
Truncate();
|
||||
NS_ASSERTION(mIndex.Length() == 0, "Blocks leaked?");
|
||||
mFileCache->Close();
|
||||
mFileCache = nsnull;
|
||||
if (mFileCache) {
|
||||
mFileCache->Close();
|
||||
mFileCache = nsnull;
|
||||
}
|
||||
MOZ_COUNT_DTOR(nsMediaCache);
|
||||
}
|
||||
|
||||
|
|
|
@ -271,9 +271,6 @@ nsXBLDocGlobalObject::SetContext(nsIScriptContext *aScriptContext)
|
|||
mScriptContext = nsnull;
|
||||
return;
|
||||
}
|
||||
NS_ASSERTION(aScriptContext->GetScriptTypeID() ==
|
||||
nsIProgrammingLanguage::JAVASCRIPT,
|
||||
"xbl is not multi-language");
|
||||
aScriptContext->WillInitializeContext();
|
||||
// NOTE: We init this context with a NULL global, so we automatically
|
||||
// hook up to the existing nsIScriptGlobalObject global setup by
|
||||
|
|
|
@ -288,10 +288,6 @@ nsXULElement::Create(nsXULPrototypeElement* aPrototype, nsINodeInfo *aNodeInfo,
|
|||
element->SetMayHaveStyle();
|
||||
}
|
||||
|
||||
NS_ASSERTION(aPrototype->mScriptTypeID != nsIProgrammingLanguage::UNKNOWN,
|
||||
"Need to know the language!");
|
||||
element->SetScriptTypeID(aPrototype->mScriptTypeID);
|
||||
|
||||
if (aIsScriptable) {
|
||||
// Check each attribute on the prototype to see if we need to do
|
||||
// any additional processing and hookup that would otherwise be
|
||||
|
@ -418,17 +414,12 @@ nsXULElement::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
|
|||
nsRefPtr<nsXULElement> element;
|
||||
if (mPrototype) {
|
||||
element = nsXULElement::Create(mPrototype, aNodeInfo, true);
|
||||
NS_ASSERTION(GetScriptTypeID() == mPrototype->mScriptTypeID,
|
||||
NS_ASSERTION(nsIProgrammingLanguage::JAVASCRIPT == mPrototype->mScriptTypeID,
|
||||
"Didn't get the default language from proto?");
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsINodeInfo> ni = aNodeInfo;
|
||||
element = new nsXULElement(ni.forget());
|
||||
if (element) {
|
||||
// If created from a prototype, we will already have the script
|
||||
// language specified by the proto - otherwise copy it directly
|
||||
element->SetScriptTypeID(GetScriptTypeID());
|
||||
}
|
||||
}
|
||||
|
||||
if (!element) {
|
||||
|
@ -1102,13 +1093,13 @@ nsXULElement::AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
|
|||
// the attribute isn't set yet.
|
||||
MaybeAddPopupListener(aName);
|
||||
if (nsContentUtils::IsEventAttributeName(aName, EventNameType_XUL) && aValue) {
|
||||
// If mPrototype->mScriptTypeID != GetScriptTypeID(), it means
|
||||
// If mPrototype->mScriptTypeID != nsIProgrammingLanguage::JAVASCRIPT, it means
|
||||
// we are resolving an overlay with a different default script
|
||||
// language. We can't defer compilation of those handlers as
|
||||
// we will have lost the script language (storing it on each
|
||||
// nsXULPrototypeAttribute is expensive!)
|
||||
bool defer = mPrototype == nsnull ||
|
||||
mPrototype->mScriptTypeID == GetScriptTypeID();
|
||||
mPrototype->mScriptTypeID == nsIProgrammingLanguage::JAVASCRIPT;
|
||||
if (aValue->Type() == nsAttrValue::eString) {
|
||||
AddScriptEventListener(aName, aValue->GetStringValue(), defer);
|
||||
} else {
|
||||
|
@ -2518,7 +2509,7 @@ nsXULElement::RecompileScriptEventListeners()
|
|||
// If we have a prototype, the node we are binding to should
|
||||
// have the same script-type - otherwise we will compile the
|
||||
// event handlers incorrectly.
|
||||
NS_ASSERTION(mPrototype->mScriptTypeID == GetScriptTypeID(),
|
||||
NS_ASSERTION(mPrototype->mScriptTypeID == nsIProgrammingLanguage::JAVASCRIPT,
|
||||
"Prototype and node confused about default language?");
|
||||
|
||||
count = mPrototype->mNumAttributes;
|
||||
|
|
|
@ -803,7 +803,7 @@ XULContentSinkImpl::SetElementScriptType(nsXULPrototypeElement* element,
|
|||
nsCOMPtr<nsIScriptRuntime> runtime;
|
||||
rv = NS_GetScriptRuntime(value, getter_AddRefs(runtime));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
element->mScriptTypeID = runtime->GetScriptTypeID();
|
||||
element->mScriptTypeID = nsIProgrammingLanguage::JAVASCRIPT;
|
||||
else {
|
||||
// probably just a bad language name (typo, etc)
|
||||
NS_WARNING("Failed to load the node's script language!");
|
||||
|
@ -1030,7 +1030,7 @@ XULContentSinkImpl::OpenScript(const PRUnichar** aAttributes,
|
|||
NS_WARNING("Failed to find a scripting language");
|
||||
langID = nsIProgrammingLanguage::UNKNOWN;
|
||||
} else
|
||||
langID = runtime->GetScriptTypeID();
|
||||
langID = nsIProgrammingLanguage::JAVASCRIPT;
|
||||
}
|
||||
|
||||
if (langID != nsIProgrammingLanguage::UNKNOWN) {
|
||||
|
|
|
@ -759,10 +759,6 @@ nsXULDocument::SynchronizeBroadcastListener(nsIDOMElement *aBroadcaster,
|
|||
nsCOMPtr<nsIContent> listener = do_QueryInterface(aListener);
|
||||
bool notify = mDocumentLoaded || mHandlingDelayedBroadcasters;
|
||||
|
||||
// We may be copying event handlers etc, so we must also copy
|
||||
// the script-type to the listener.
|
||||
listener->SetScriptTypeID(broadcaster->GetScriptTypeID());
|
||||
|
||||
if (aAttr.EqualsLiteral("*")) {
|
||||
PRUint32 count = broadcaster->GetAttrCount();
|
||||
nsTArray<nsAttrNameInfo> attributes(count);
|
||||
|
@ -3635,8 +3631,6 @@ nsXULDocument::ExecuteScript(nsIScriptContext * aContext, JSScript* aScriptObjec
|
|||
|
||||
NS_ENSURE_TRUE(mScriptGlobalObject, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
NS_ABORT_IF_FALSE(aContext->GetScriptTypeID() == nsIProgrammingLanguage::JAVASCRIPT,
|
||||
"Should have a JavaScript nsIScriptContext.");
|
||||
// Execute the precompiled script with the given version
|
||||
JSObject* global = mScriptGlobalObject->GetGlobalJSObject();
|
||||
return aContext->ExecuteScript(aScriptObject, global, nsnull, nsnull);
|
||||
|
@ -3946,14 +3940,7 @@ nsXULDocument::OverlayForwardReference::Resolve()
|
|||
if (!target)
|
||||
return eResolve_Later;
|
||||
|
||||
// While merging, set the default script language of the element to be
|
||||
// the language from the overlay - attributes will then be correctly
|
||||
// hooked up with the appropriate language (while child nodes ignore
|
||||
// the default language - they have it in their proto.
|
||||
PRUint32 oldDefLang = target->GetScriptTypeID();
|
||||
target->SetScriptTypeID(mOverlay->GetScriptTypeID());
|
||||
rv = Merge(target, mOverlay, notify);
|
||||
target->SetScriptTypeID(oldDefLang);
|
||||
if (NS_FAILED(rv)) return eResolve_Error;
|
||||
}
|
||||
|
||||
|
|
|
@ -159,7 +159,7 @@ nsDOMScriptObjectFactory::GetScriptRuntime(const nsAString &aLanguageName,
|
|||
return NS_ERROR_FACTORY_NOT_REGISTERED;
|
||||
}
|
||||
// And stash it away in our array for fast lookup by ID.
|
||||
PRUint32 lang_ndx = NS_STID_INDEX(lang->GetScriptTypeID());
|
||||
PRUint32 lang_ndx = NS_STID_INDEX(nsIProgrammingLanguage::JAVASCRIPT);
|
||||
if (mLanguageArray[lang_ndx] == nsnull) {
|
||||
mLanguageArray[lang_ndx] = lang;
|
||||
} else {
|
||||
|
@ -213,7 +213,7 @@ nsDOMScriptObjectFactory::GetIDForScriptType(const nsAString &aLanguageName,
|
|||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
*aScriptTypeID = languageRuntime->GetScriptTypeID();
|
||||
*aScriptTypeID = nsIProgrammingLanguage::JAVASCRIPT;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -123,7 +123,7 @@ public:
|
|||
}
|
||||
// Get the language ID.
|
||||
PRUint32 getScriptTypeID() const {
|
||||
return mContext->GetScriptTypeID();
|
||||
return nsIProgrammingLanguage::JAVASCRIPT;
|
||||
}
|
||||
protected:
|
||||
T* mObject;
|
||||
|
|
|
@ -9264,8 +9264,7 @@ nsGlobalWindow::RunTimeout(nsTimeout *aTimeout)
|
|||
|
||||
// Get the script context (a strong ref to prevent it going away)
|
||||
// for this timeout and ensure the script language is enabled.
|
||||
nsCOMPtr<nsIScriptContext> scx = GetScriptContextInternal(
|
||||
timeout->mScriptHandler->GetScriptTypeID());
|
||||
nsCOMPtr<nsIScriptContext> scx = GetContextInternal();
|
||||
|
||||
if (!scx) {
|
||||
// No context means this window was closed or never properly
|
||||
|
|
|
@ -76,8 +76,8 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIScriptContextPrincipal,
|
|||
NS_ISCRIPTCONTEXTPRINCIPAL_IID)
|
||||
|
||||
#define NS_ISCRIPTCONTEXT_IID \
|
||||
{ 0xdfaea249, 0xaaad, 0x48bd, \
|
||||
{ 0xb8, 0x04, 0x92, 0xad, 0x30, 0x88, 0xd0, 0xc6 } }
|
||||
{ 0xf1c8c13e, 0xc23b, 0x434e, \
|
||||
{ 0xa4, 0x77, 0xe0, 0x2f, 0xc3, 0x73, 0xf8, 0x71 } }
|
||||
|
||||
/* This MUST match JSVERSION_DEFAULT. This version stuff if we don't
|
||||
know what language we have is a little silly... */
|
||||
|
@ -92,9 +92,6 @@ class nsIScriptContext : public nsIScriptContextPrincipal
|
|||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISCRIPTCONTEXT_IID)
|
||||
|
||||
/* Get the ID of this language. */
|
||||
virtual PRUint32 GetScriptTypeID() = 0;
|
||||
|
||||
virtual void SetGlobalObject(nsIScriptGlobalObject* aGlobalObject) = 0;
|
||||
|
||||
/**
|
||||
|
|
|
@ -40,8 +40,8 @@
|
|||
#include "nsIScriptContext.h"
|
||||
|
||||
#define NS_ISCRIPTRUNTIME_IID \
|
||||
{ 0x2c8d774e, 0xb52a, 0x43ec, \
|
||||
{ 0x8e, 0xbc, 0x82, 0x75, 0xb9, 0x34, 0x20, 0x57 } }
|
||||
{ 0xb146580f, 0x55f7, 0x4d97, \
|
||||
{ 0x8a, 0xbb, 0x4a, 0x50, 0xb0, 0xa8, 0x04, 0x97 } }
|
||||
|
||||
/**
|
||||
* A singleton language environment for an application. Responsible for
|
||||
|
@ -52,10 +52,6 @@ class nsIScriptRuntime : public nsISupports
|
|||
{
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISCRIPTRUNTIME_IID)
|
||||
/*
|
||||
* Return the language ID of this script language
|
||||
*/
|
||||
virtual PRUint32 GetScriptTypeID() = 0;
|
||||
|
||||
/* Parses a "version string" for the language into a bit-mask used by
|
||||
* the language implementation. If the specified version is not supported
|
||||
|
|
|
@ -42,8 +42,8 @@
|
|||
class nsIArray;
|
||||
|
||||
#define NS_ISCRIPTTIMEOUTHANDLER_IID \
|
||||
{ 0xd60ec934, 0x0c75, 0x4777, \
|
||||
{ 0xba, 0x41, 0xb8, 0x2f, 0x37, 0xc9, 0x13, 0x56 } }
|
||||
{ 0xcaf520a5, 0x8078, 0x4cba, \
|
||||
{ 0x8a, 0xb9, 0xb6, 0x8a, 0x12, 0x43, 0x4f, 0x05 } }
|
||||
|
||||
/**
|
||||
* Abstraction of the script objects etc required to do timeouts in a
|
||||
|
@ -55,9 +55,6 @@ class nsIScriptTimeoutHandler : public nsISupports
|
|||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISCRIPTTIMEOUTHANDLER_IID)
|
||||
|
||||
// Get the script-type (language) implementing this timeout.
|
||||
virtual PRUint32 GetScriptTypeID() = 0;
|
||||
|
||||
// Get a script object for the language suitable for passing back to
|
||||
// the language's context as an event handler. If this returns nsnull,
|
||||
// GetHandlerText() will be called to get the string.
|
||||
|
|
|
@ -74,9 +74,6 @@ public:
|
|||
|
||||
virtual nsIScriptObjectPrincipal* GetObjectPrincipal();
|
||||
|
||||
virtual PRUint32 GetScriptTypeID()
|
||||
{ return nsIProgrammingLanguage::JAVASCRIPT; }
|
||||
|
||||
virtual void SetGlobalObject(nsIScriptGlobalObject* aGlobalObject)
|
||||
{
|
||||
mGlobalObjectRef = aGlobalObject;
|
||||
|
@ -329,10 +326,6 @@ public:
|
|||
// nsISupports
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
virtual PRUint32 GetScriptTypeID() {
|
||||
return nsIProgrammingLanguage::JAVASCRIPT;
|
||||
}
|
||||
|
||||
virtual already_AddRefed<nsIScriptContext> CreateContext();
|
||||
|
||||
virtual nsresult ParseVersion(const nsString &aVersionStr, PRUint32 *flags);
|
||||
|
|
|
@ -76,10 +76,6 @@ public:
|
|||
*aLineNo = mLineNo;
|
||||
}
|
||||
|
||||
virtual PRUint32 GetScriptTypeID() {
|
||||
return nsIProgrammingLanguage::JAVASCRIPT;
|
||||
}
|
||||
|
||||
virtual nsIArray *GetArgv() {
|
||||
return mArgv;
|
||||
}
|
||||
|
|
|
@ -110,9 +110,9 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsJSEventListener)
|
|||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsJSEventListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_MEMBER_CALLBACK(tmp->mContext->GetScriptTypeID(),
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_MEMBER_CALLBACK(nsIProgrammingLanguage::JAVASCRIPT,
|
||||
mScopeObject)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_MEMBER_CALLBACK(tmp->mContext->GetScriptTypeID(),
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_MEMBER_CALLBACK(nsIProgrammingLanguage::JAVASCRIPT,
|
||||
mHandler)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
|
@ -140,8 +140,7 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(nsJSEventListener)
|
|||
bool
|
||||
nsJSEventListener::IsBlackForCC()
|
||||
{
|
||||
if ((mContext && mContext->GetScriptTypeID() ==
|
||||
nsIProgrammingLanguage::JAVASCRIPT) &&
|
||||
if (mContext &&
|
||||
(!mScopeObject || !xpc_IsGrayGCThing(mScopeObject)) &&
|
||||
(!mHandler || !xpc_IsGrayGCThing(mHandler))) {
|
||||
nsIScriptGlobalObject* sgo =
|
||||
|
|
|
@ -77,6 +77,11 @@ BoxBlurHorizontal(unsigned char* aInput,
|
|||
int32_t boxSize = aLeftLobe + aRightLobe + 1;
|
||||
bool skipRectCoversWholeRow = 0 >= aSkipRect.x &&
|
||||
aWidth <= aSkipRect.XMost();
|
||||
if (boxSize == 1) {
|
||||
memcpy(aOutput, aInput, aWidth*aRows);
|
||||
return;
|
||||
}
|
||||
PRUint32 reciprocal = (PRUint64(1) << 32)/boxSize;
|
||||
|
||||
for (int32_t y = 0; y < aRows; y++) {
|
||||
// Check whether the skip rect intersects this row. If the skip
|
||||
|
@ -89,7 +94,7 @@ BoxBlurHorizontal(unsigned char* aInput,
|
|||
continue;
|
||||
}
|
||||
|
||||
int32_t alphaSum = 0;
|
||||
uint32_t alphaSum = 0;
|
||||
for (int32_t i = 0; i < boxSize; i++) {
|
||||
int32_t pos = i - aLeftLobe;
|
||||
// See assertion above; if aWidth is zero, then we would have no
|
||||
|
@ -123,7 +128,7 @@ BoxBlurHorizontal(unsigned char* aInput,
|
|||
int32_t last = max(tmp, 0);
|
||||
int32_t next = min(tmp + boxSize, aWidth - 1);
|
||||
|
||||
aOutput[aWidth * y + x] = alphaSum / boxSize;
|
||||
aOutput[aWidth * y + x] = (PRUint64(alphaSum)*reciprocal) >> 32;
|
||||
|
||||
alphaSum += aInput[aWidth * y + next] -
|
||||
aInput[aWidth * y + last];
|
||||
|
@ -150,6 +155,11 @@ BoxBlurVertical(unsigned char* aInput,
|
|||
int32_t boxSize = aTopLobe + aBottomLobe + 1;
|
||||
bool skipRectCoversWholeColumn = 0 >= aSkipRect.y &&
|
||||
aRows <= aSkipRect.YMost();
|
||||
if (boxSize == 1) {
|
||||
memcpy(aOutput, aInput, aWidth*aRows);
|
||||
return;
|
||||
}
|
||||
PRUint32 reciprocal = (PRUint64(1) << 32)/boxSize;
|
||||
|
||||
for (int32_t x = 0; x < aWidth; x++) {
|
||||
bool inSkipRectX = x >= aSkipRect.x &&
|
||||
|
@ -159,7 +169,7 @@ BoxBlurVertical(unsigned char* aInput,
|
|||
continue;
|
||||
}
|
||||
|
||||
int32_t alphaSum = 0;
|
||||
uint32_t alphaSum = 0;
|
||||
for (int32_t i = 0; i < boxSize; i++) {
|
||||
int32_t pos = i - aTopLobe;
|
||||
// See assertion above; if aRows is zero, then we would have no
|
||||
|
@ -189,7 +199,7 @@ BoxBlurVertical(unsigned char* aInput,
|
|||
int32_t last = max(tmp, 0);
|
||||
int32_t next = min(tmp + boxSize, aRows - 1);
|
||||
|
||||
aOutput[aWidth * y + x] = alphaSum/boxSize;
|
||||
aOutput[aWidth * y + x] = (PRUint64(alphaSum)*reciprocal) >> 32;
|
||||
|
||||
alphaSum += aInput[aWidth * next + x] -
|
||||
aInput[aWidth * last + x];
|
||||
|
|
|
@ -880,23 +880,21 @@ RasterImage::GetFrame(PRUint32 aWhichFrame,
|
|||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (mDecoded) {
|
||||
// If we have decoded data, and it is not a perfect match for what we are
|
||||
// looking for, we must discard to be able to generate the proper data.
|
||||
PRUint32 desiredDecodeFlags = aFlags & DECODE_FLAGS_MASK;
|
||||
if (desiredDecodeFlags != mFrameDecodeFlags) {
|
||||
// if we can't discard, then we're screwed; we have no way
|
||||
// to re-decode. Similarly if we aren't allowed to do a sync
|
||||
// decode.
|
||||
if (!(aFlags & FLAG_SYNC_DECODE))
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
if (!CanForciblyDiscard() || mDecoder || mAnim)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
ForceDiscard();
|
||||
|
||||
mFrameDecodeFlags = desiredDecodeFlags;
|
||||
}
|
||||
// If we have decoded data, and it is not a perfect match for what we are
|
||||
// looking for, we must discard to be able to generate the proper data.
|
||||
PRUint32 desiredDecodeFlags = aFlags & DECODE_FLAGS_MASK;
|
||||
if (desiredDecodeFlags != mFrameDecodeFlags) {
|
||||
// if we can't discard, then we're screwed; we have no way
|
||||
// to re-decode. Similarly if we aren't allowed to do a sync
|
||||
// decode.
|
||||
if (!(aFlags & FLAG_SYNC_DECODE))
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
if (!CanForciblyDiscard() || mDecoder || mAnim)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
ForceDiscard();
|
||||
|
||||
mFrameDecodeFlags = desiredDecodeFlags;
|
||||
}
|
||||
|
||||
// If the caller requested a synchronous decode, do it
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
// Debugger.prototype.wrap creates only one Debugger.Object instance for each debuggee object.
|
||||
var g = newGlobal('new-compartment');
|
||||
var dbg = new Debugger(g);
|
||||
|
||||
g.eval("var x = { 'now playing': 'Joy Division' };");
|
||||
g.eval("var y = { 'mood': 'bleak' };");
|
||||
|
||||
wx = dbg.wrap(g.x);
|
||||
assertEq(wx, dbg.wrap(g.x));
|
||||
assertEq(wx === g.x, false);
|
||||
assertEq("now playing" in wx, false);
|
||||
assertEq(wx.getOwnPropertyNames().indexOf("now playing"), 0);
|
||||
wx.commentary = "deconstruction";
|
||||
assertEq("deconstruction" in g.x, false);
|
||||
|
||||
wy = dbg.wrap(g.y);
|
||||
assertEq(wy === wx, false);
|
||||
wy.commentary = "reconstruction";
|
||||
assertEq(wx.commentary, "deconstruction");
|
||||
|
||||
// Separate debuggers get separate wrappers, but they both view the same underlying object.
|
||||
var dbg2 = new Debugger(g);
|
||||
w2x = dbg2.wrap(g.x);
|
||||
assertEq(wx === w2x, false);
|
||||
w2x.defineProperty("breadcrumb", { value: "pumpernickel" });
|
||||
assertEq(wx.getOwnPropertyDescriptor("breadcrumb").value, "pumpernickel");
|
||||
|
||||
// Trying to wrap things that aren't objects should pass them through unchanged.
|
||||
assertEq(dbg.wrap("foonting turlingdromes"), "foonting turlingdromes");
|
||||
assertEq(dbg.wrap(true), true);
|
||||
assertEq(dbg.wrap(false), false);
|
||||
assertEq(dbg.wrap(null), null);
|
||||
assertEq(dbg.wrap(1729), 1729);
|
||||
assertEq(dbg.wrap(undefined), undefined);
|
|
@ -188,7 +188,7 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
|
|||
for (unsigned i = 0; i < nargs; i++)
|
||||
escapedSlots[ArgSlot(i)] = true;
|
||||
} else {
|
||||
for (unsigned i = 0; i < script->nClosedArgs; i++) {
|
||||
for (uint32_t i = 0; i < script->nClosedArgs(); i++) {
|
||||
unsigned arg = script->getClosedArg(i);
|
||||
JS_ASSERT(arg < nargs);
|
||||
escapedSlots[ArgSlot(arg)] = true;
|
||||
|
@ -199,7 +199,7 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
|
|||
for (unsigned i = 0; i < script->nfixed; i++)
|
||||
escapedSlots[LocalSlot(script, i)] = true;
|
||||
} else {
|
||||
for (uint32_t i = 0; i < script->nClosedVars; i++) {
|
||||
for (uint32_t i = 0; i < script->nClosedVars(); i++) {
|
||||
unsigned local = script->getClosedVar(i);
|
||||
JS_ASSERT(local < script->nfixed);
|
||||
escapedSlots[LocalSlot(script, local)] = true;
|
||||
|
@ -218,13 +218,13 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
|
|||
isCompileable = true;
|
||||
|
||||
isInlineable = true;
|
||||
if (script->nClosedArgs || script->nClosedVars || heavyweight ||
|
||||
if (script->nClosedArgs() || script->nClosedVars() || heavyweight ||
|
||||
script->usesEval || script->mayNeedArgsObj() || cx->compartment->debugMode()) {
|
||||
isInlineable = false;
|
||||
}
|
||||
|
||||
modifiesArguments_ = false;
|
||||
if (script->nClosedArgs || heavyweight)
|
||||
if (script->nClosedArgs() || heavyweight)
|
||||
modifiesArguments_ = true;
|
||||
|
||||
canTrackVars = true;
|
||||
|
|
|
@ -764,7 +764,7 @@ JSRuntime::JSRuntime()
|
|||
gcGrayRootsTraceOp(NULL),
|
||||
gcGrayRootsData(NULL),
|
||||
autoGCRooters(NULL),
|
||||
scriptPCCounters(NULL),
|
||||
scriptAndCountsVector(NULL),
|
||||
NaNValue(UndefinedValue()),
|
||||
negativeInfinityValue(UndefinedValue()),
|
||||
positiveInfinityValue(UndefinedValue()),
|
||||
|
|
|
@ -104,9 +104,6 @@ class JaegerCompartment;
|
|||
class WeakMapBase;
|
||||
class InterpreterFrames;
|
||||
|
||||
class ScriptOpcodeCounts;
|
||||
struct ScriptOpcodeCountsPair;
|
||||
|
||||
/*
|
||||
* GetSrcNote cache to avoid O(n^2) growth in finding a source note for a
|
||||
* given pc in a script. We use the script->code pointer to tag the cache,
|
||||
|
@ -135,7 +132,7 @@ struct PendingProxyOperation {
|
|||
JSObject *object;
|
||||
};
|
||||
|
||||
typedef Vector<ScriptOpcodeCountsPair, 0, SystemAllocPolicy> ScriptOpcodeCountsVector;
|
||||
typedef Vector<ScriptAndCounts, 0, SystemAllocPolicy> ScriptAndCountsVector;
|
||||
|
||||
struct ConservativeGCData
|
||||
{
|
||||
|
@ -463,7 +460,7 @@ struct JSRuntime : js::RuntimeFriendFields
|
|||
js::AutoGCRooter *autoGCRooters;
|
||||
|
||||
/* Strong references on scripts held for PCCount profiling API. */
|
||||
js::ScriptOpcodeCountsVector *scriptPCCounters;
|
||||
js::ScriptAndCountsVector *scriptAndCountsVector;
|
||||
|
||||
/* Well-known numbers held for use by this runtime's contexts. */
|
||||
js::Value NaNValue;
|
||||
|
|
|
@ -1598,7 +1598,7 @@ extern JS_PUBLIC_API(void)
|
|||
JS_DumpPCCounts(JSContext *cx, JSScript *script)
|
||||
{
|
||||
#if defined(DEBUG)
|
||||
JS_ASSERT(script->pcCounters);
|
||||
JS_ASSERT(script->scriptCounts);
|
||||
|
||||
Sprinter sprinter(cx);
|
||||
if (!sprinter.init())
|
||||
|
@ -1641,7 +1641,7 @@ JS_DumpCompartmentPCCounts(JSContext *cx)
|
|||
{
|
||||
for (CellIter i(cx->compartment, gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
|
||||
JSScript *script = i.get<JSScript>();
|
||||
if (script->pcCounters)
|
||||
if (script->scriptCounts)
|
||||
JS_DumpPCCounts(cx, script);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2344,10 +2344,10 @@ MarkRuntime(JSTracer *trc, bool useSavedRoots = false)
|
|||
for (GCLocks::Range r = rt->gcLocksHash.all(); !r.empty(); r.popFront())
|
||||
gc_lock_traversal(r.front(), trc);
|
||||
|
||||
if (rt->scriptPCCounters) {
|
||||
ScriptOpcodeCountsVector &vec = *rt->scriptPCCounters;
|
||||
if (rt->scriptAndCountsVector) {
|
||||
ScriptAndCountsVector &vec = *rt->scriptAndCountsVector;
|
||||
for (size_t i = 0; i < vec.length(); i++)
|
||||
MarkScriptRoot(trc, &vec[i].script, "scriptPCCounters");
|
||||
MarkScriptRoot(trc, &vec[i].script, "scriptAndCountsVector");
|
||||
}
|
||||
|
||||
js_TraceAtomState(trc);
|
||||
|
@ -2366,11 +2366,11 @@ MarkRuntime(JSTracer *trc, bool useSavedRoots = false)
|
|||
c->watchpointMap->markAll(trc);
|
||||
}
|
||||
|
||||
/* Do not discard scripts with counters while profiling. */
|
||||
/* Do not discard scripts with counts while profiling. */
|
||||
if (rt->profilingScripts) {
|
||||
for (CellIterUnderGC i(c, FINALIZE_SCRIPT); !i.done(); i.next()) {
|
||||
JSScript *script = i.get<JSScript>();
|
||||
if (script->pcCounters) {
|
||||
if (script->scriptCounts) {
|
||||
MarkScriptRoot(trc, &script, "profilingScripts");
|
||||
JS_ASSERT(script == i.get<JSScript>());
|
||||
}
|
||||
|
@ -4496,12 +4496,12 @@ static void ReleaseAllJITCode(JSContext *cx)
|
|||
/*
|
||||
* There are three possible PCCount profiling states:
|
||||
*
|
||||
* 1. None: Neither scripts nor the runtime have counter information.
|
||||
* 2. Profile: Active scripts have counter information, the runtime does not.
|
||||
* 3. Query: Scripts do not have counter information, the runtime does.
|
||||
* 1. None: Neither scripts nor the runtime have count information.
|
||||
* 2. Profile: Active scripts have count information, the runtime does not.
|
||||
* 3. Query: Scripts do not have count information, the runtime does.
|
||||
*
|
||||
* When starting to profile scripts, counting begins immediately, with all JIT
|
||||
* code discarded and recompiled with counters as necessary. Active interpreter
|
||||
* code discarded and recompiled with counts as necessary. Active interpreter
|
||||
* frames will not begin profiling until they begin executing another script
|
||||
* (via a call or return).
|
||||
*
|
||||
|
@ -4518,18 +4518,18 @@ static void ReleaseAllJITCode(JSContext *cx)
|
|||
*/
|
||||
|
||||
static void
|
||||
ReleaseScriptPCCounters(JSContext *cx)
|
||||
ReleaseScriptCounts(JSContext *cx)
|
||||
{
|
||||
JSRuntime *rt = cx->runtime;
|
||||
JS_ASSERT(rt->scriptPCCounters);
|
||||
JS_ASSERT(rt->scriptAndCountsVector);
|
||||
|
||||
ScriptOpcodeCountsVector &vec = *rt->scriptPCCounters;
|
||||
ScriptAndCountsVector &vec = *rt->scriptAndCountsVector;
|
||||
|
||||
for (size_t i = 0; i < vec.length(); i++)
|
||||
vec[i].counters.destroy(cx);
|
||||
vec[i].scriptCounts.destroy(cx);
|
||||
|
||||
cx->delete_(rt->scriptPCCounters);
|
||||
rt->scriptPCCounters = NULL;
|
||||
cx->delete_(rt->scriptAndCountsVector);
|
||||
rt->scriptAndCountsVector = NULL;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
|
@ -4540,8 +4540,8 @@ StartPCCountProfiling(JSContext *cx)
|
|||
if (rt->profilingScripts)
|
||||
return;
|
||||
|
||||
if (rt->scriptPCCounters)
|
||||
ReleaseScriptPCCounters(cx);
|
||||
if (rt->scriptAndCountsVector)
|
||||
ReleaseScriptCounts(cx);
|
||||
|
||||
ReleaseAllJITCode(cx);
|
||||
|
||||
|
@ -4555,29 +4555,29 @@ StopPCCountProfiling(JSContext *cx)
|
|||
|
||||
if (!rt->profilingScripts)
|
||||
return;
|
||||
JS_ASSERT(!rt->scriptPCCounters);
|
||||
JS_ASSERT(!rt->scriptAndCountsVector);
|
||||
|
||||
ReleaseAllJITCode(cx);
|
||||
|
||||
ScriptOpcodeCountsVector *vec = cx->new_<ScriptOpcodeCountsVector>(SystemAllocPolicy());
|
||||
ScriptAndCountsVector *vec = cx->new_<ScriptAndCountsVector>(SystemAllocPolicy());
|
||||
if (!vec)
|
||||
return;
|
||||
|
||||
for (GCCompartmentsIter c(rt); !c.done(); c.next()) {
|
||||
for (CellIter i(c, FINALIZE_SCRIPT); !i.done(); i.next()) {
|
||||
JSScript *script = i.get<JSScript>();
|
||||
if (script->pcCounters && script->types) {
|
||||
ScriptOpcodeCountsPair info;
|
||||
if (script->scriptCounts && script->types) {
|
||||
ScriptAndCounts info;
|
||||
info.script = script;
|
||||
info.counters.steal(script->pcCounters);
|
||||
info.scriptCounts.steal(script->scriptCounts);
|
||||
if (!vec->append(info))
|
||||
info.counters.destroy(cx);
|
||||
info.scriptCounts.destroy(cx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rt->profilingScripts = false;
|
||||
rt->scriptPCCounters = vec;
|
||||
rt->scriptAndCountsVector = vec;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
|
@ -4585,11 +4585,11 @@ PurgePCCounts(JSContext *cx)
|
|||
{
|
||||
JSRuntime *rt = cx->runtime;
|
||||
|
||||
if (!rt->scriptPCCounters)
|
||||
if (!rt->scriptAndCountsVector)
|
||||
return;
|
||||
JS_ASSERT(!rt->profilingScripts);
|
||||
|
||||
ReleaseScriptPCCounters(cx);
|
||||
ReleaseScriptCounts(cx);
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
|
|
@ -1288,9 +1288,9 @@ js::Interpret(JSContext *cx, StackFrame *entryFrame, InterpMode interpMode)
|
|||
JS_ASSERT(!cx->compartment->activeAnalysis);
|
||||
|
||||
#if JS_THREADED_INTERP
|
||||
#define CHECK_PCCOUNT_INTERRUPTS() JS_ASSERT_IF(script->pcCounters, jumpTable == interruptJumpTable)
|
||||
#define CHECK_PCCOUNT_INTERRUPTS() JS_ASSERT_IF(script->scriptCounts, jumpTable == interruptJumpTable)
|
||||
#else
|
||||
#define CHECK_PCCOUNT_INTERRUPTS() JS_ASSERT_IF(script->pcCounters, switchMask == -1)
|
||||
#define CHECK_PCCOUNT_INTERRUPTS() JS_ASSERT_IF(script->scriptCounts, switchMask == -1)
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -1465,7 +1465,7 @@ js::Interpret(JSContext *cx, StackFrame *entryFrame, InterpMode interpMode)
|
|||
script = (s); \
|
||||
if (script->hasAnyBreakpointsOrStepMode()) \
|
||||
ENABLE_INTERRUPTS(); \
|
||||
if (script->pcCounters) \
|
||||
if (script->scriptCounts) \
|
||||
ENABLE_INTERRUPTS(); \
|
||||
JS_ASSERT_IF(interpMode == JSINTERP_SKIP_TRAP, \
|
||||
script->hasAnyBreakpointsOrStepMode()); \
|
||||
|
@ -1609,14 +1609,14 @@ js::Interpret(JSContext *cx, StackFrame *entryFrame, InterpMode interpMode)
|
|||
bool moreInterrupts = false;
|
||||
|
||||
if (cx->runtime->profilingScripts) {
|
||||
if (!script->pcCounters)
|
||||
script->initCounts(cx);
|
||||
if (!script->scriptCounts)
|
||||
script->initScriptCounts(cx);
|
||||
moreInterrupts = true;
|
||||
}
|
||||
|
||||
if (script->pcCounters) {
|
||||
OpcodeCounts counts = script->getCounts(regs.pc);
|
||||
counts.get(OpcodeCounts::BASE_INTERP)++;
|
||||
if (script->scriptCounts) {
|
||||
PCCounts counts = script->getPCCounts(regs.pc);
|
||||
counts.get(PCCounts::BASE_INTERP)++;
|
||||
moreInterrupts = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -229,7 +229,7 @@ static const char * countBaseNames[] = {
|
|||
"mjit_pics"
|
||||
};
|
||||
|
||||
JS_STATIC_ASSERT(JS_ARRAY_LENGTH(countBaseNames) == OpcodeCounts::BASE_COUNT);
|
||||
JS_STATIC_ASSERT(JS_ARRAY_LENGTH(countBaseNames) == PCCounts::BASE_LIMIT);
|
||||
|
||||
static const char * countAccessNames[] = {
|
||||
"infer_mono",
|
||||
|
@ -247,7 +247,7 @@ static const char * countAccessNames[] = {
|
|||
};
|
||||
|
||||
JS_STATIC_ASSERT(JS_ARRAY_LENGTH(countBaseNames) +
|
||||
JS_ARRAY_LENGTH(countAccessNames) == OpcodeCounts::ACCESS_COUNT);
|
||||
JS_ARRAY_LENGTH(countAccessNames) == PCCounts::ACCESS_LIMIT);
|
||||
|
||||
static const char * countElementNames[] = {
|
||||
"id_int",
|
||||
|
@ -262,7 +262,7 @@ static const char * countElementNames[] = {
|
|||
|
||||
JS_STATIC_ASSERT(JS_ARRAY_LENGTH(countBaseNames) +
|
||||
JS_ARRAY_LENGTH(countAccessNames) +
|
||||
JS_ARRAY_LENGTH(countElementNames) == OpcodeCounts::ELEM_COUNT);
|
||||
JS_ARRAY_LENGTH(countElementNames) == PCCounts::ELEM_LIMIT);
|
||||
|
||||
static const char * countPropertyNames[] = {
|
||||
"prop_static",
|
||||
|
@ -272,7 +272,7 @@ static const char * countPropertyNames[] = {
|
|||
|
||||
JS_STATIC_ASSERT(JS_ARRAY_LENGTH(countBaseNames) +
|
||||
JS_ARRAY_LENGTH(countAccessNames) +
|
||||
JS_ARRAY_LENGTH(countPropertyNames) == OpcodeCounts::PROP_COUNT);
|
||||
JS_ARRAY_LENGTH(countPropertyNames) == PCCounts::PROP_LIMIT);
|
||||
|
||||
static const char * countArithNames[] = {
|
||||
"arith_int",
|
||||
|
@ -282,29 +282,29 @@ static const char * countArithNames[] = {
|
|||
};
|
||||
|
||||
JS_STATIC_ASSERT(JS_ARRAY_LENGTH(countBaseNames) +
|
||||
JS_ARRAY_LENGTH(countArithNames) == OpcodeCounts::ARITH_COUNT);
|
||||
JS_ARRAY_LENGTH(countArithNames) == PCCounts::ARITH_LIMIT);
|
||||
|
||||
/* static */ const char *
|
||||
OpcodeCounts::countName(JSOp op, size_t which)
|
||||
PCCounts::countName(JSOp op, size_t which)
|
||||
{
|
||||
JS_ASSERT(which < numCounts(op));
|
||||
|
||||
if (which < BASE_COUNT)
|
||||
if (which < BASE_LIMIT)
|
||||
return countBaseNames[which];
|
||||
|
||||
if (accessOp(op)) {
|
||||
if (which < ACCESS_COUNT)
|
||||
return countAccessNames[which - BASE_COUNT];
|
||||
if (which < ACCESS_LIMIT)
|
||||
return countAccessNames[which - BASE_LIMIT];
|
||||
if (elementOp(op))
|
||||
return countElementNames[which - ACCESS_COUNT];
|
||||
return countElementNames[which - ACCESS_LIMIT];
|
||||
if (propertyOp(op))
|
||||
return countPropertyNames[which - ACCESS_COUNT];
|
||||
return countPropertyNames[which - ACCESS_LIMIT];
|
||||
JS_NOT_REACHED("bad op");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (arithOp(op))
|
||||
return countArithNames[which - BASE_COUNT];
|
||||
return countArithNames[which - BASE_LIMIT];
|
||||
|
||||
JS_NOT_REACHED("bad op");
|
||||
return NULL;
|
||||
|
@ -315,7 +315,7 @@ OpcodeCounts::countName(JSOp op, size_t which)
|
|||
JS_FRIEND_API(void)
|
||||
js_DumpPCCounts(JSContext *cx, JSScript *script, js::Sprinter *sp)
|
||||
{
|
||||
JS_ASSERT(script->pcCounters);
|
||||
JS_ASSERT(script->scriptCounts);
|
||||
|
||||
jsbytecode *pc = script->code;
|
||||
while (pc < script->code + script->length) {
|
||||
|
@ -327,8 +327,8 @@ js_DumpPCCounts(JSContext *cx, JSScript *script, js::Sprinter *sp)
|
|||
if (!js_Disassemble1(cx, script, pc, pc - script->code, true, sp))
|
||||
return;
|
||||
|
||||
size_t total = OpcodeCounts::numCounts(op);
|
||||
double *raw = script->getCounts(pc).rawCounts();
|
||||
size_t total = PCCounts::numCounts(op);
|
||||
double *raw = script->getPCCounts(pc).rawCounts();
|
||||
|
||||
Sprint(sp, " {");
|
||||
bool printed = false;
|
||||
|
@ -337,7 +337,7 @@ js_DumpPCCounts(JSContext *cx, JSScript *script, js::Sprinter *sp)
|
|||
if (val) {
|
||||
if (printed)
|
||||
Sprint(sp, ", ");
|
||||
Sprint(sp, "\"%s\": %.0f", OpcodeCounts::countName(op, i), val);
|
||||
Sprint(sp, "\"%s\": %.0f", PCCounts::countName(op, i), val);
|
||||
printed = true;
|
||||
}
|
||||
}
|
||||
|
@ -5997,10 +5997,10 @@ GetPCCountScriptCount(JSContext *cx)
|
|||
{
|
||||
JSRuntime *rt = cx->runtime;
|
||||
|
||||
if (!rt->scriptPCCounters)
|
||||
if (!rt->scriptAndCountsVector)
|
||||
return 0;
|
||||
|
||||
return rt->scriptPCCounters->length();
|
||||
return rt->scriptAndCountsVector->length();
|
||||
}
|
||||
|
||||
enum MaybeComma {NO_COMMA, COMMA};
|
||||
|
@ -6034,12 +6034,12 @@ GetPCCountScriptSummary(JSContext *cx, size_t index)
|
|||
{
|
||||
JSRuntime *rt = cx->runtime;
|
||||
|
||||
if (!rt->scriptPCCounters || index >= rt->scriptPCCounters->length()) {
|
||||
if (!rt->scriptAndCountsVector || index >= rt->scriptAndCountsVector->length()) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BUFFER_TOO_SMALL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ScriptOpcodeCountsPair info = (*rt->scriptPCCounters)[index];
|
||||
ScriptAndCounts info = (*rt->scriptAndCountsVector)[index];
|
||||
JSScript *script = info.script;
|
||||
|
||||
/*
|
||||
|
@ -6070,35 +6070,35 @@ GetPCCountScriptSummary(JSContext *cx, size_t index)
|
|||
}
|
||||
}
|
||||
|
||||
double baseTotals[OpcodeCounts::BASE_COUNT] = {0.0};
|
||||
double accessTotals[OpcodeCounts::ACCESS_COUNT - OpcodeCounts::BASE_COUNT] = {0.0};
|
||||
double elementTotals[OpcodeCounts::ELEM_COUNT - OpcodeCounts::ACCESS_COUNT] = {0.0};
|
||||
double propertyTotals[OpcodeCounts::PROP_COUNT - OpcodeCounts::ACCESS_COUNT] = {0.0};
|
||||
double arithTotals[OpcodeCounts::ARITH_COUNT - OpcodeCounts::BASE_COUNT] = {0.0};
|
||||
double baseTotals[PCCounts::BASE_LIMIT] = {0.0};
|
||||
double accessTotals[PCCounts::ACCESS_LIMIT - PCCounts::BASE_LIMIT] = {0.0};
|
||||
double elementTotals[PCCounts::ELEM_LIMIT - PCCounts::ACCESS_LIMIT] = {0.0};
|
||||
double propertyTotals[PCCounts::PROP_LIMIT - PCCounts::ACCESS_LIMIT] = {0.0};
|
||||
double arithTotals[PCCounts::ARITH_LIMIT - PCCounts::BASE_LIMIT] = {0.0};
|
||||
|
||||
for (unsigned i = 0; i < script->length; i++) {
|
||||
OpcodeCounts &counts = info.getCounts(script->code + i);
|
||||
PCCounts &counts = info.getPCCounts(script->code + i);
|
||||
if (!counts)
|
||||
continue;
|
||||
|
||||
JSOp op = (JSOp)script->code[i];
|
||||
unsigned numCounts = OpcodeCounts::numCounts(op);
|
||||
unsigned numCounts = PCCounts::numCounts(op);
|
||||
|
||||
for (unsigned j = 0; j < numCounts; j++) {
|
||||
double value = counts.get(j);
|
||||
if (j < OpcodeCounts::BASE_COUNT) {
|
||||
if (j < PCCounts::BASE_LIMIT) {
|
||||
baseTotals[j] += value;
|
||||
} else if (OpcodeCounts::accessOp(op)) {
|
||||
if (j < OpcodeCounts::ACCESS_COUNT)
|
||||
accessTotals[j - OpcodeCounts::BASE_COUNT] += value;
|
||||
else if (OpcodeCounts::elementOp(op))
|
||||
elementTotals[j - OpcodeCounts::ACCESS_COUNT] += value;
|
||||
else if (OpcodeCounts::propertyOp(op))
|
||||
propertyTotals[j - OpcodeCounts::ACCESS_COUNT] += value;
|
||||
} else if (PCCounts::accessOp(op)) {
|
||||
if (j < PCCounts::ACCESS_LIMIT)
|
||||
accessTotals[j - PCCounts::BASE_LIMIT] += value;
|
||||
else if (PCCounts::elementOp(op))
|
||||
elementTotals[j - PCCounts::ACCESS_LIMIT] += value;
|
||||
else if (PCCounts::propertyOp(op))
|
||||
propertyTotals[j - PCCounts::ACCESS_LIMIT] += value;
|
||||
else
|
||||
JS_NOT_REACHED("Bad opcode");
|
||||
} else if (OpcodeCounts::arithOp(op)) {
|
||||
arithTotals[j - OpcodeCounts::BASE_COUNT] += value;
|
||||
} else if (PCCounts::arithOp(op)) {
|
||||
arithTotals[j - PCCounts::BASE_LIMIT] += value;
|
||||
} else {
|
||||
JS_NOT_REACHED("Bad opcode");
|
||||
}
|
||||
|
@ -6138,7 +6138,7 @@ struct AutoDestroyPrinter
|
|||
};
|
||||
|
||||
static bool
|
||||
GetPCCountJSON(JSContext *cx, const ScriptOpcodeCountsPair &info, StringBuffer &buf)
|
||||
GetPCCountJSON(JSContext *cx, const ScriptAndCounts &info, StringBuffer &buf)
|
||||
{
|
||||
JSScript *script = info.script;
|
||||
|
||||
|
@ -6236,8 +6236,8 @@ GetPCCountJSON(JSContext *cx, const ScriptOpcodeCountsPair &info, StringBuffer &
|
|||
buf.append(str);
|
||||
}
|
||||
|
||||
OpcodeCounts &counts = info.getCounts(pc);
|
||||
unsigned numCounts = OpcodeCounts::numCounts(op);
|
||||
PCCounts &counts = info.getPCCounts(pc);
|
||||
unsigned numCounts = PCCounts::numCounts(op);
|
||||
|
||||
AppendJSONProperty(buf, "counts");
|
||||
buf.append('{');
|
||||
|
@ -6246,7 +6246,7 @@ GetPCCountJSON(JSContext *cx, const ScriptOpcodeCountsPair &info, StringBuffer &
|
|||
for (unsigned i = 0; i < numCounts; i++) {
|
||||
double value = counts.get(i);
|
||||
if (value > 0) {
|
||||
AppendJSONProperty(buf, OpcodeCounts::countName(op, i), comma);
|
||||
AppendJSONProperty(buf, PCCounts::countName(op, i), comma);
|
||||
comma = COMMA;
|
||||
NumberValueToStringBuffer(cx, DoubleValue(value), buf);
|
||||
}
|
||||
|
@ -6267,12 +6267,12 @@ GetPCCountScriptContents(JSContext *cx, size_t index)
|
|||
{
|
||||
JSRuntime *rt = cx->runtime;
|
||||
|
||||
if (!rt->scriptPCCounters || index >= rt->scriptPCCounters->length()) {
|
||||
if (!rt->scriptAndCountsVector || index >= rt->scriptAndCountsVector->length()) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BUFFER_TOO_SMALL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const ScriptOpcodeCountsPair &info = (*rt->scriptPCCounters)[index];
|
||||
const ScriptAndCounts &info = (*rt->scriptAndCountsVector)[index];
|
||||
JSScript *script = info.script;
|
||||
|
||||
StringBuffer buf(cx);
|
||||
|
|
|
@ -521,10 +521,10 @@ FlowsIntoNext(JSOp op)
|
|||
|
||||
/*
|
||||
* Counts accumulated for a single opcode in a script. The counts tracked vary
|
||||
* between opcodes, and this structure ensures that counts are accessed in
|
||||
* a coherent fashion.
|
||||
* between opcodes, and this structure ensures that counts are accessed in a
|
||||
* coherent fashion.
|
||||
*/
|
||||
class OpcodeCounts
|
||||
class PCCounts
|
||||
{
|
||||
friend struct ::JSScript;
|
||||
double *counts;
|
||||
|
@ -542,11 +542,11 @@ class OpcodeCounts
|
|||
BASE_METHODJIT_CODE,
|
||||
BASE_METHODJIT_PICS,
|
||||
|
||||
BASE_COUNT
|
||||
BASE_LIMIT
|
||||
};
|
||||
|
||||
enum AccessCounts {
|
||||
ACCESS_MONOMORPHIC = BASE_COUNT,
|
||||
ACCESS_MONOMORPHIC = BASE_LIMIT,
|
||||
ACCESS_DIMORPHIC,
|
||||
ACCESS_POLYMORPHIC,
|
||||
|
||||
|
@ -561,7 +561,7 @@ class OpcodeCounts
|
|||
ACCESS_STRING,
|
||||
ACCESS_OBJECT,
|
||||
|
||||
ACCESS_COUNT
|
||||
ACCESS_LIMIT
|
||||
};
|
||||
|
||||
static bool accessOp(JSOp op) {
|
||||
|
@ -577,7 +577,7 @@ class OpcodeCounts
|
|||
}
|
||||
|
||||
enum ElementCounts {
|
||||
ELEM_ID_INT = ACCESS_COUNT,
|
||||
ELEM_ID_INT = ACCESS_LIMIT,
|
||||
ELEM_ID_DOUBLE,
|
||||
ELEM_ID_OTHER,
|
||||
ELEM_ID_UNKNOWN,
|
||||
|
@ -587,7 +587,7 @@ class OpcodeCounts
|
|||
ELEM_OBJECT_DENSE,
|
||||
ELEM_OBJECT_OTHER,
|
||||
|
||||
ELEM_COUNT
|
||||
ELEM_LIMIT
|
||||
};
|
||||
|
||||
static bool elementOp(JSOp op) {
|
||||
|
@ -595,11 +595,11 @@ class OpcodeCounts
|
|||
}
|
||||
|
||||
enum PropertyCounts {
|
||||
PROP_STATIC = ACCESS_COUNT,
|
||||
PROP_STATIC = ACCESS_LIMIT,
|
||||
PROP_DEFINITE,
|
||||
PROP_OTHER,
|
||||
|
||||
PROP_COUNT
|
||||
PROP_LIMIT
|
||||
};
|
||||
|
||||
static bool propertyOp(JSOp op) {
|
||||
|
@ -607,12 +607,12 @@ class OpcodeCounts
|
|||
}
|
||||
|
||||
enum ArithCounts {
|
||||
ARITH_INT = BASE_COUNT,
|
||||
ARITH_INT = BASE_LIMIT,
|
||||
ARITH_DOUBLE,
|
||||
ARITH_OTHER,
|
||||
ARITH_UNKNOWN,
|
||||
|
||||
ARITH_COUNT
|
||||
ARITH_LIMIT
|
||||
};
|
||||
|
||||
static bool arithOp(JSOp op) {
|
||||
|
@ -623,14 +623,14 @@ class OpcodeCounts
|
|||
{
|
||||
if (accessOp(op)) {
|
||||
if (elementOp(op))
|
||||
return ELEM_COUNT;
|
||||
return ELEM_LIMIT;
|
||||
if (propertyOp(op))
|
||||
return PROP_COUNT;
|
||||
return ACCESS_COUNT;
|
||||
return PROP_LIMIT;
|
||||
return ACCESS_LIMIT;
|
||||
}
|
||||
if (arithOp(op))
|
||||
return ARITH_COUNT;
|
||||
return BASE_COUNT;
|
||||
return ARITH_LIMIT;
|
||||
return BASE_LIMIT;
|
||||
}
|
||||
|
||||
static const char *countName(JSOp op, size_t which);
|
||||
|
|
|
@ -405,15 +405,14 @@ js::XDRScript(XDRState<mode> *xdr, JSScript **scriptp, JSScript *parentScript)
|
|||
};
|
||||
|
||||
uint32_t length, lineno, nslots;
|
||||
uint32_t natoms, nsrcnotes, ntrynotes, nobjects, nregexps, nconsts, i;
|
||||
uint32_t prologLength, version, encodedClosedCount;
|
||||
uint16_t nClosedArgs = 0, nClosedVars = 0;
|
||||
uint32_t natoms, nsrcnotes, ntrynotes, nobjects, nregexps, nconsts, nClosedArgs, nClosedVars, i;
|
||||
uint32_t prologLength, version;
|
||||
uint32_t nTypeSets = 0;
|
||||
uint32_t scriptBits = 0;
|
||||
|
||||
JSContext *cx = xdr->cx();
|
||||
JSScript *script;
|
||||
nsrcnotes = ntrynotes = natoms = nobjects = nregexps = nconsts = 0;
|
||||
nsrcnotes = ntrynotes = natoms = nobjects = nregexps = nconsts = nClosedArgs = nClosedVars = 0;
|
||||
jssrcnote *notes = NULL;
|
||||
|
||||
/* XDR arguments, local vars, and upvars. */
|
||||
|
@ -533,18 +532,17 @@ js::XDRScript(XDRState<mode> *xdr, JSScript **scriptp, JSScript *parentScript)
|
|||
notes = script->notes();
|
||||
nsrcnotes = script->numNotes();
|
||||
|
||||
if (JSScript::isValidOffset(script->constsOffset))
|
||||
nconsts = script->consts()->length;
|
||||
if (JSScript::isValidOffset(script->objectsOffset))
|
||||
nobjects = script->objects()->length;
|
||||
if (JSScript::isValidOffset(script->regexpsOffset))
|
||||
nregexps = script->regexps()->length;
|
||||
if (JSScript::isValidOffset(script->trynotesOffset))
|
||||
ntrynotes = script->trynotes()->length;
|
||||
if (JSScript::isValidOffset(script->constOffset))
|
||||
nconsts = script->consts()->length;
|
||||
|
||||
nClosedArgs = script->nClosedArgs;
|
||||
nClosedVars = script->nClosedVars;
|
||||
encodedClosedCount = (nClosedArgs << 16) | nClosedVars;
|
||||
/* no globals when encoding; see assertion above */
|
||||
nClosedArgs = script->nClosedArgs();
|
||||
nClosedVars = script->nClosedVars();
|
||||
|
||||
nTypeSets = script->nTypeSets;
|
||||
|
||||
|
@ -597,7 +595,9 @@ js::XDRScript(XDRState<mode> *xdr, JSScript **scriptp, JSScript *parentScript)
|
|||
return JS_FALSE;
|
||||
if (!xdr->codeUint32(&nconsts))
|
||||
return JS_FALSE;
|
||||
if (!xdr->codeUint32(&encodedClosedCount))
|
||||
if (!xdr->codeUint32(&nClosedArgs))
|
||||
return JS_FALSE;
|
||||
if (!xdr->codeUint32(&nClosedVars))
|
||||
return JS_FALSE;
|
||||
if (!xdr->codeUint32(&nTypeSets))
|
||||
return JS_FALSE;
|
||||
|
@ -605,9 +605,6 @@ js::XDRScript(XDRState<mode> *xdr, JSScript **scriptp, JSScript *parentScript)
|
|||
return JS_FALSE;
|
||||
|
||||
if (mode == XDR_DECODE) {
|
||||
nClosedArgs = encodedClosedCount >> 16;
|
||||
nClosedVars = encodedClosedCount & 0xFFFF;
|
||||
|
||||
/* Note: version is packed into the 32b space with another 16b value. */
|
||||
JSVersion version_ = JSVersion(version & JS_BITMASK(16));
|
||||
JS_ASSERT((version_ & VersionFlags::FULL_MASK) == unsigned(version_));
|
||||
|
@ -715,11 +712,11 @@ js::XDRScript(XDRState<mode> *xdr, JSScript **scriptp, JSScript *parentScript)
|
|||
return false;
|
||||
}
|
||||
for (i = 0; i != nClosedArgs; ++i) {
|
||||
if (!xdr->codeUint32(&script->closedSlots[i]))
|
||||
if (!xdr->codeUint32(&script->closedArgs()->vector[i]))
|
||||
return false;
|
||||
}
|
||||
for (i = 0; i != nClosedVars; ++i) {
|
||||
if (!xdr->codeUint32(&script->closedSlots[nClosedArgs + i]))
|
||||
if (!xdr->codeUint32(&script->closedVars()->vector[i]))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -764,7 +761,7 @@ js::XDRScript(XDRState<mode> *xdr, JSScript **scriptp, JSScript *parentScript)
|
|||
|
||||
if (mode == XDR_DECODE) {
|
||||
if (cx->hasRunOption(JSOPTION_PCCOUNT))
|
||||
(void) script->initCounts(cx);
|
||||
(void) script->initScriptCounts(cx);
|
||||
*scriptp = script;
|
||||
}
|
||||
|
||||
|
@ -778,33 +775,33 @@ template bool
|
|||
js::XDRScript(XDRState<XDR_DECODE> *xdr, JSScript **scriptp, JSScript *parentScript);
|
||||
|
||||
bool
|
||||
JSScript::initCounts(JSContext *cx)
|
||||
JSScript::initScriptCounts(JSContext *cx)
|
||||
{
|
||||
JS_ASSERT(!pcCounters);
|
||||
JS_ASSERT(!scriptCounts);
|
||||
|
||||
size_t count = 0;
|
||||
size_t n = 0;
|
||||
|
||||
jsbytecode *pc, *next;
|
||||
for (pc = code; pc < code + length; pc = next) {
|
||||
count += OpcodeCounts::numCounts(JSOp(*pc));
|
||||
n += PCCounts::numCounts(JSOp(*pc));
|
||||
next = pc + GetBytecodeLength(pc);
|
||||
}
|
||||
|
||||
size_t bytes = (length * sizeof(OpcodeCounts)) + (count * sizeof(double));
|
||||
size_t bytes = (length * sizeof(PCCounts)) + (n * sizeof(double));
|
||||
char *cursor = (char *) cx->calloc_(bytes);
|
||||
if (!cursor)
|
||||
return false;
|
||||
|
||||
DebugOnly<char *> base = cursor;
|
||||
|
||||
pcCounters.counts = (OpcodeCounts *) cursor;
|
||||
cursor += length * sizeof(OpcodeCounts);
|
||||
scriptCounts.pcCountsVector = (PCCounts *) cursor;
|
||||
cursor += length * sizeof(PCCounts);
|
||||
|
||||
for (pc = code; pc < code + length; pc = next) {
|
||||
pcCounters.counts[pc - code].counts = (double *) cursor;
|
||||
size_t capacity = OpcodeCounts::numCounts(JSOp(*pc));
|
||||
scriptCounts.pcCountsVector[pc - code].counts = (double *) cursor;
|
||||
size_t capacity = PCCounts::numCounts(JSOp(*pc));
|
||||
#ifdef DEBUG
|
||||
pcCounters.counts[pc - code].capacity = capacity;
|
||||
scriptCounts.pcCountsVector[pc - code].capacity = capacity;
|
||||
#endif
|
||||
cursor += capacity * sizeof(double);
|
||||
next = pc + GetBytecodeLength(pc);
|
||||
|
@ -821,11 +818,11 @@ JSScript::initCounts(JSContext *cx)
|
|||
}
|
||||
|
||||
void
|
||||
JSScript::destroyCounts(JSContext *cx)
|
||||
JSScript::destroyScriptCounts(JSContext *cx)
|
||||
{
|
||||
if (pcCounters) {
|
||||
cx->free_(pcCounters.counts);
|
||||
pcCounters.counts = NULL;
|
||||
if (scriptCounts) {
|
||||
cx->free_(scriptCounts.pcCountsVector);
|
||||
scriptCounts.pcCountsVector = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -908,53 +905,102 @@ js::FreeScriptFilenames(JSCompartment *comp)
|
|||
}
|
||||
|
||||
/*
|
||||
* JSScript data structures memory alignment:
|
||||
* JSScript::data has a complex, manually-controlled, memory layout.
|
||||
*
|
||||
* JSScript
|
||||
* JSObjectArray script objects' descriptor if JSScript.objectsOffset != 0,
|
||||
* use script->objects() to access it.
|
||||
* JSObjectArray script regexps' descriptor if JSScript.regexpsOffset != 0,
|
||||
* use script->regexps() to access it.
|
||||
* JSTryNoteArray script try notes' descriptor if JSScript.tryNotesOffset
|
||||
* != 0, use script->trynotes() to access it.
|
||||
* JSAtom *a[] array of JSScript.natoms atoms pointed by
|
||||
* JSScript.atoms if any.
|
||||
* JSObject *o[] array of script->objects()->length objects if any
|
||||
* pointed by script->objects()->vector.
|
||||
* JSObject *r[] array of script->regexps()->length regexps if any
|
||||
* pointed by script->regexps()->vector.
|
||||
* JSTryNote t[] array of script->trynotes()->length try notes if any
|
||||
* pointed by script->trynotes()->vector.
|
||||
* jsbytecode b[] script bytecode pointed by JSScript.code.
|
||||
* jssrcnote s[] script source notes, use script->notes() to access it
|
||||
* First are some optional array headers. They are optional because they
|
||||
* often aren't needed, i.e. the corresponding arrays often have zero elements.
|
||||
* Each header has an offset in JSScript that indicates its location within
|
||||
* |data|; that offset is INVALID_OFFSET if the array header is not present.
|
||||
* Each header also has an accessor function in JSScript.
|
||||
*
|
||||
* The alignment avoids gaps between entries as alignment requirement for each
|
||||
* subsequent structure or array is the same or divides the alignment
|
||||
* requirement for the previous one.
|
||||
* Array type Array elements Offset Accessor
|
||||
* ---------- -------------- ------ --------
|
||||
* JSConstArray Consts constsOffset consts()
|
||||
* JSObjectArray Objects objectsOffset objects()
|
||||
* JSObjectArray Regexps regexpsOffset regexps()
|
||||
* JSTryNoteArray Try notes tryNotesOffset trynotes()
|
||||
* GlobalSlotArray Globals globalsOffset globals()
|
||||
* ClosedSlotArray ClosedArgs closedArgsOffset closedArgs()
|
||||
* ClosedSlotArray ClosedVars closedVarsOffset closedVars()
|
||||
*
|
||||
* The followings asserts checks that assuming that the alignment requirement
|
||||
* for JSObjectArray and JSTryNoteArray are sizeof(void *) and for JSTryNote
|
||||
* it is sizeof(uint32_t) as the structure consists of 3 uint32_t fields.
|
||||
* Then are the elements of several arrays.
|
||||
* - Most of these arrays have headers listed above (if present). For each of
|
||||
* these, the array pointer and the array length is stored in the header.
|
||||
* - The remaining arrays have pointers and lengths that are stored directly in
|
||||
* JSScript. This is because, unlike the others, they are nearly always
|
||||
* non-zero length and so the optional-header space optimization isn't
|
||||
* worthwhile.
|
||||
*
|
||||
* Array elements Pointed to by Length
|
||||
* -------------- ------------- ------
|
||||
* Consts consts()->vector consts()->length
|
||||
* Atoms atoms natoms
|
||||
* Objects objects()->vector objects()->length
|
||||
* Regexps regexps()->vector regexps()->length
|
||||
* Try notes trynotes()->vector trynotes()->length
|
||||
* Globals globals()->vector globals()->length
|
||||
* Closed args closedArgs()->vector closedArgs()->length
|
||||
* Closed vars closedVars()->vector closedVars()->length
|
||||
* Bytecodes code length
|
||||
* Source notes notes() numNotes() * sizeof(jssrcnote)
|
||||
*
|
||||
* IMPORTANT: This layout has two key properties.
|
||||
* - It ensures that everything has sufficient alignment; in particular, the
|
||||
* consts() elements need jsval alignment.
|
||||
* - It ensures there are no gaps between elements, which saves space and makes
|
||||
* manual layout easy. In particular, in the second part, arrays with larger
|
||||
* elements precede arrays with smaller elements.
|
||||
*
|
||||
* The following static assertions check these properties.
|
||||
*/
|
||||
JS_STATIC_ASSERT(sizeof(JSScript) % sizeof(void *) == 0);
|
||||
JS_STATIC_ASSERT(sizeof(JSObjectArray) % sizeof(void *) == 0);
|
||||
JS_STATIC_ASSERT(sizeof(JSTryNoteArray) == sizeof(JSObjectArray));
|
||||
JS_STATIC_ASSERT(sizeof(JSAtom *) == sizeof(JSObject *));
|
||||
JS_STATIC_ASSERT(sizeof(JSObject *) % sizeof(uint32_t) == 0);
|
||||
JS_STATIC_ASSERT(sizeof(JSTryNote) == 3 * sizeof(uint32_t));
|
||||
JS_STATIC_ASSERT(sizeof(uint32_t) % sizeof(jsbytecode) == 0);
|
||||
JS_STATIC_ASSERT(sizeof(jsbytecode) % sizeof(jssrcnote) == 0);
|
||||
|
||||
#define KEEPS_JSVAL_ALIGNMENT(T) \
|
||||
(JS_ALIGNMENT_OF(jsval) % JS_ALIGNMENT_OF(T) == 0 && \
|
||||
sizeof(T) % sizeof(jsval) == 0)
|
||||
|
||||
#define HAS_JSVAL_ALIGNMENT(T) \
|
||||
(JS_ALIGNMENT_OF(jsval) == JS_ALIGNMENT_OF(T) && \
|
||||
sizeof(T) == sizeof(jsval))
|
||||
|
||||
#define NO_PADDING_BETWEEN_ENTRIES(T1, T2) \
|
||||
(JS_ALIGNMENT_OF(T1) % JS_ALIGNMENT_OF(T2) == 0)
|
||||
|
||||
/*
|
||||
* These assertions ensure that there is no padding between the array headers,
|
||||
* and also that the consts() elements (which follow immediately afterward) are
|
||||
* jsval-aligned. (There is an assumption that |data| itself is jsval-aligned;
|
||||
* we check this below).
|
||||
*/
|
||||
JS_STATIC_ASSERT(KEEPS_JSVAL_ALIGNMENT(JSConstArray));
|
||||
JS_STATIC_ASSERT(KEEPS_JSVAL_ALIGNMENT(JSObjectArray)); /* there are two of these */
|
||||
JS_STATIC_ASSERT(KEEPS_JSVAL_ALIGNMENT(JSTryNoteArray));
|
||||
JS_STATIC_ASSERT(KEEPS_JSVAL_ALIGNMENT(GlobalSlotArray));
|
||||
JS_STATIC_ASSERT(KEEPS_JSVAL_ALIGNMENT(ClosedSlotArray)); /* there are two of these */
|
||||
|
||||
/* These assertions ensure there is no padding required between array elements. */
|
||||
JS_STATIC_ASSERT(HAS_JSVAL_ALIGNMENT(HeapValue));
|
||||
JS_STATIC_ASSERT(NO_PADDING_BETWEEN_ENTRIES(HeapValue, JSAtom *));
|
||||
JS_STATIC_ASSERT(NO_PADDING_BETWEEN_ENTRIES(JSAtom *, HeapPtrObject));
|
||||
JS_STATIC_ASSERT(NO_PADDING_BETWEEN_ENTRIES(HeapPtrObject, HeapPtrObject));
|
||||
JS_STATIC_ASSERT(NO_PADDING_BETWEEN_ENTRIES(HeapPtrObject, JSTryNote));
|
||||
JS_STATIC_ASSERT(NO_PADDING_BETWEEN_ENTRIES(JSTryNote, GlobalSlotArray::Entry));
|
||||
JS_STATIC_ASSERT(NO_PADDING_BETWEEN_ENTRIES(GlobalSlotArray::Entry, uint32_t));
|
||||
JS_STATIC_ASSERT(NO_PADDING_BETWEEN_ENTRIES(uint32_t, uint32_t));
|
||||
JS_STATIC_ASSERT(NO_PADDING_BETWEEN_ENTRIES(uint32_t, jsbytecode));
|
||||
JS_STATIC_ASSERT(NO_PADDING_BETWEEN_ENTRIES(jsbytecode, jssrcnote));
|
||||
|
||||
/*
|
||||
* Check that uint8_t offsets is enough to reach any optional array allocated
|
||||
* after JSScript. For that we check that the maximum possible offset for
|
||||
* JSConstArray, that last optional array, still fits 1 byte and do not
|
||||
* coincide with INVALID_OFFSET.
|
||||
* within |data|. For that we check that the maximum possible offset for the
|
||||
* closedVars array -- the last optional array -- still fits in 1 byte and does
|
||||
* not coincide with INVALID_OFFSET.
|
||||
*/
|
||||
JS_STATIC_ASSERT(sizeof(JSObjectArray) +
|
||||
JS_STATIC_ASSERT(sizeof(JSConstArray) +
|
||||
sizeof(JSObjectArray) +
|
||||
sizeof(JSObjectArray) +
|
||||
sizeof(JSTryNoteArray) +
|
||||
sizeof(js::GlobalSlotArray)
|
||||
sizeof(js::GlobalSlotArray) +
|
||||
sizeof(js::ClosedSlotArray)
|
||||
< JSScript::INVALID_OFFSET);
|
||||
JS_STATIC_ASSERT(JSScript::INVALID_OFFSET <= 255);
|
||||
|
||||
|
@ -964,7 +1010,11 @@ JSScript::NewScript(JSContext *cx, uint32_t length, uint32_t nsrcnotes, uint32_t
|
|||
uint32_t ntrynotes, uint32_t nconsts, uint32_t nglobals,
|
||||
uint16_t nClosedArgs, uint16_t nClosedVars, uint32_t nTypeSets, JSVersion version)
|
||||
{
|
||||
size_t size = sizeof(JSAtom *) * natoms;
|
||||
size_t size = 0;
|
||||
|
||||
if (nconsts != 0)
|
||||
size += sizeof(JSConstArray) + nconsts * sizeof(Value);
|
||||
size += sizeof(JSAtom *) * natoms;
|
||||
if (nobjects != 0)
|
||||
size += sizeof(JSObjectArray) + nobjects * sizeof(JSObject *);
|
||||
if (nregexps != 0)
|
||||
|
@ -973,24 +1023,13 @@ JSScript::NewScript(JSContext *cx, uint32_t length, uint32_t nsrcnotes, uint32_t
|
|||
size += sizeof(JSTryNoteArray) + ntrynotes * sizeof(JSTryNote);
|
||||
if (nglobals != 0)
|
||||
size += sizeof(GlobalSlotArray) + nglobals * sizeof(GlobalSlotArray::Entry);
|
||||
uint32_t totalClosed = nClosedArgs + nClosedVars;
|
||||
if (totalClosed != 0)
|
||||
size += totalClosed * sizeof(uint32_t);
|
||||
if (nClosedArgs != 0)
|
||||
size += sizeof(ClosedSlotArray) + nClosedArgs * sizeof(uint32_t);
|
||||
if (nClosedVars != 0)
|
||||
size += sizeof(ClosedSlotArray) + nClosedVars * sizeof(uint32_t);
|
||||
|
||||
/*
|
||||
* To esnure jsval alignment for the const array we place it immediately
|
||||
* after JSSomethingArray structs as their sizes all divide sizeof(jsval).
|
||||
* This works as long as the data itself is allocated with proper
|
||||
* alignment which we ensure below.
|
||||
*/
|
||||
JS_STATIC_ASSERT(sizeof(JSObjectArray) % sizeof(jsval) == 0);
|
||||
JS_STATIC_ASSERT(sizeof(JSTryNoteArray) % sizeof(jsval) == 0);
|
||||
JS_STATIC_ASSERT(sizeof(GlobalSlotArray) % sizeof(jsval) == 0);
|
||||
JS_STATIC_ASSERT(sizeof(JSConstArray) % sizeof(jsval) == 0);
|
||||
if (nconsts != 0)
|
||||
size += sizeof(JSConstArray) + nconsts * sizeof(Value);
|
||||
|
||||
size += length * sizeof(jsbytecode) + nsrcnotes * sizeof(jssrcnote);
|
||||
size += length * sizeof(jsbytecode);
|
||||
size += nsrcnotes * sizeof(jssrcnote);
|
||||
|
||||
/*
|
||||
* We assume that calloc aligns on sizeof(Value) if the size we ask to
|
||||
|
@ -1008,15 +1047,18 @@ JSScript::NewScript(JSContext *cx, uint32_t length, uint32_t nsrcnotes, uint32_t
|
|||
}
|
||||
|
||||
PodZero(script);
|
||||
#ifdef JS_CRASH_DIAGNOSTICS
|
||||
script->cookie1[0] = script->cookie2[0] = JS_SCRIPT_COOKIE;
|
||||
#endif
|
||||
script->data = data;
|
||||
script->length = length;
|
||||
script->version = version;
|
||||
new (&script->bindings) Bindings(cx);
|
||||
|
||||
uint8_t *cursor = data;
|
||||
if (nconsts != 0) {
|
||||
script->constsOffset = uint8_t(cursor - data);
|
||||
cursor += sizeof(JSConstArray);
|
||||
} else {
|
||||
script->constsOffset = JSScript::INVALID_OFFSET;
|
||||
}
|
||||
if (nobjects != 0) {
|
||||
script->objectsOffset = uint8_t(cursor - data);
|
||||
cursor += sizeof(JSObjectArray);
|
||||
|
@ -1041,19 +1083,19 @@ JSScript::NewScript(JSContext *cx, uint32_t length, uint32_t nsrcnotes, uint32_t
|
|||
} else {
|
||||
script->globalsOffset = JSScript::INVALID_OFFSET;
|
||||
}
|
||||
JS_ASSERT(cursor - data < 0xFF);
|
||||
if (nconsts != 0) {
|
||||
script->constOffset = uint8_t(cursor - data);
|
||||
cursor += sizeof(JSConstArray);
|
||||
if (nClosedArgs != 0) {
|
||||
script->closedArgsOffset = uint8_t(cursor - data);
|
||||
cursor += sizeof(ClosedSlotArray);
|
||||
} else {
|
||||
script->constOffset = JSScript::INVALID_OFFSET;
|
||||
script->closedArgsOffset = JSScript::INVALID_OFFSET;
|
||||
}
|
||||
JS_ASSERT(cursor - data < 0xFF);
|
||||
if (nClosedVars != 0) {
|
||||
script->closedVarsOffset = uint8_t(cursor - data);
|
||||
cursor += sizeof(ClosedSlotArray);
|
||||
} else {
|
||||
script->closedVarsOffset = JSScript::INVALID_OFFSET;
|
||||
}
|
||||
|
||||
JS_STATIC_ASSERT(sizeof(JSObjectArray) +
|
||||
sizeof(JSObjectArray) +
|
||||
sizeof(JSTryNoteArray) +
|
||||
sizeof(GlobalSlotArray) < 0xFF);
|
||||
|
||||
|
||||
if (nconsts != 0) {
|
||||
JS_ASSERT(reinterpret_cast<uintptr_t>(cursor) % sizeof(jsval) == 0);
|
||||
|
@ -1096,11 +1138,16 @@ JSScript::NewScript(JSContext *cx, uint32_t length, uint32_t nsrcnotes, uint32_t
|
|||
cursor += nglobals * sizeof(script->globals()->vector[0]);
|
||||
}
|
||||
|
||||
if (totalClosed != 0) {
|
||||
script->nClosedArgs = nClosedArgs;
|
||||
script->nClosedVars = nClosedVars;
|
||||
script->closedSlots = reinterpret_cast<uint32_t *>(cursor);
|
||||
cursor += totalClosed * sizeof(uint32_t);
|
||||
if (nClosedArgs != 0) {
|
||||
script->closedArgs()->length = nClosedArgs;
|
||||
script->closedArgs()->vector = reinterpret_cast<uint32_t *>(cursor);
|
||||
cursor += nClosedArgs * sizeof(script->closedArgs()->vector[0]);
|
||||
}
|
||||
|
||||
if (nClosedVars != 0) {
|
||||
script->closedVars()->length = nClosedVars;
|
||||
script->closedVars()->vector = reinterpret_cast<uint32_t *>(cursor);
|
||||
cursor += nClosedVars * sizeof(script->closedVars()->vector[0]);
|
||||
}
|
||||
|
||||
JS_ASSERT(nTypeSets <= UINT16_MAX);
|
||||
|
@ -1232,12 +1279,10 @@ JSScript::NewScriptFromEmitter(JSContext *cx, BytecodeEmitter *bce)
|
|||
bce->globalUses.length());
|
||||
}
|
||||
|
||||
if (script->nClosedArgs)
|
||||
PodCopy<uint32_t>(script->closedSlots, &bce->closedArgs[0], script->nClosedArgs);
|
||||
if (script->nClosedVars) {
|
||||
PodCopy<uint32_t>(&script->closedSlots[script->nClosedArgs], &bce->closedVars[0],
|
||||
script->nClosedVars);
|
||||
}
|
||||
if (nClosedArgs)
|
||||
PodCopy<uint32_t>(script->closedArgs()->vector, &bce->closedArgs[0], nClosedArgs);
|
||||
if (nClosedVars)
|
||||
PodCopy<uint32_t>(script->closedVars()->vector, &bce->closedVars[0], nClosedVars);
|
||||
|
||||
script->bindings.transfer(cx, &bce->bindings);
|
||||
|
||||
|
@ -1289,7 +1334,7 @@ JSScript::NewScriptFromEmitter(JSContext *cx, BytecodeEmitter *bce)
|
|||
}
|
||||
|
||||
if (cx->hasRunOption(JSOPTION_PCCOUNT))
|
||||
(void) script->initCounts(cx);
|
||||
(void) script->initScriptCounts(cx);
|
||||
|
||||
return script;
|
||||
}
|
||||
|
@ -1346,25 +1391,9 @@ js_CallDestroyScriptHook(JSContext *cx, JSScript *script)
|
|||
JS_ClearScriptTraps(cx, script);
|
||||
}
|
||||
|
||||
#ifdef JS_CRASH_DIAGNOSTICS
|
||||
|
||||
void
|
||||
JSScript::CheckScript(JSScript *prev)
|
||||
{
|
||||
if (cookie1[0] != JS_SCRIPT_COOKIE || cookie2[0] != JS_SCRIPT_COOKIE) {
|
||||
crash::StackBuffer<sizeof(JSScript), 0x87> buf1(this);
|
||||
crash::StackBuffer<sizeof(JSScript), 0x88> buf2(prev);
|
||||
JS_OPT_ASSERT(false);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* JS_CRASH_DIAGNOSTICS */
|
||||
|
||||
void
|
||||
JSScript::finalize(JSContext *cx, bool background)
|
||||
{
|
||||
CheckScript(NULL);
|
||||
|
||||
js_CallDestroyScriptHook(cx, this);
|
||||
|
||||
JS_ASSERT_IF(principals, originPrincipals);
|
||||
|
@ -1380,7 +1409,7 @@ JSScript::finalize(JSContext *cx, bool background)
|
|||
mjit::ReleaseScriptCode(cx, this);
|
||||
#endif
|
||||
|
||||
destroyCounts(cx);
|
||||
destroyScriptCounts(cx);
|
||||
|
||||
if (sourceMap)
|
||||
cx->free_(sourceMap);
|
||||
|
@ -1633,12 +1662,6 @@ js::CloneScript(JSContext *cx, JSScript *script)
|
|||
return newScript;
|
||||
}
|
||||
|
||||
void
|
||||
JSScript::copyClosedSlotsTo(JSScript *other)
|
||||
{
|
||||
js_memcpy(other->closedSlots, closedSlots, nClosedArgs + nClosedVars);
|
||||
}
|
||||
|
||||
bool
|
||||
JSScript::ensureHasDebug(JSContext *cx)
|
||||
{
|
||||
|
@ -1805,8 +1828,6 @@ JSScript::clearTraps(JSContext *cx)
|
|||
void
|
||||
JSScript::markChildren(JSTracer *trc)
|
||||
{
|
||||
CheckScript(NULL);
|
||||
|
||||
JS_ASSERT_IF(trc->runtime->gcCheckCompartment,
|
||||
compartment() == trc->runtime->gcCheckCompartment);
|
||||
|
||||
|
@ -1825,7 +1846,7 @@ JSScript::markChildren(JSTracer *trc)
|
|||
MarkObjectRange(trc, objarray->length, objarray->vector, "objects");
|
||||
}
|
||||
|
||||
if (JSScript::isValidOffset(constOffset)) {
|
||||
if (JSScript::isValidOffset(constsOffset)) {
|
||||
JSConstArray *constarray = consts();
|
||||
MarkValueRange(trc, constarray->length, constarray->vector, "consts");
|
||||
}
|
||||
|
|
|
@ -101,6 +101,11 @@ struct GlobalSlotArray {
|
|||
uint32_t length;
|
||||
};
|
||||
|
||||
struct ClosedSlotArray {
|
||||
uint32_t *vector; /* array of closed slots */
|
||||
uint32_t length; /* count of closed slots */
|
||||
};
|
||||
|
||||
struct Shape;
|
||||
|
||||
enum BindingKind { NONE, ARGUMENT, VARIABLE, CONSTANT };
|
||||
|
@ -276,27 +281,32 @@ namespace js {
|
|||
|
||||
namespace analyze { class ScriptAnalysis; }
|
||||
|
||||
class ScriptOpcodeCounts
|
||||
class ScriptCounts
|
||||
{
|
||||
friend struct ::JSScript;
|
||||
friend struct ScriptOpcodeCountsPair;
|
||||
OpcodeCounts *counts;
|
||||
friend struct ScriptAndCounts;
|
||||
/*
|
||||
* This points to a single block that holds an array of PCCounts followed
|
||||
* by an array of doubles. Each element in the PCCounts array has a
|
||||
* pointer into the array of doubles.
|
||||
*/
|
||||
PCCounts *pcCountsVector;
|
||||
|
||||
public:
|
||||
|
||||
ScriptOpcodeCounts() : counts(NULL) {
|
||||
ScriptCounts() : pcCountsVector(NULL) {
|
||||
}
|
||||
|
||||
inline void destroy(JSContext *cx);
|
||||
|
||||
void steal(ScriptOpcodeCounts &other) {
|
||||
void steal(ScriptCounts &other) {
|
||||
*this = other;
|
||||
js::PodZero(&other);
|
||||
}
|
||||
|
||||
// Boolean conversion, for 'if (counters) ...'
|
||||
// Boolean conversion, for 'if (scriptCounts) ...'
|
||||
operator void*() const {
|
||||
return counts;
|
||||
return pcCountsVector;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -329,46 +339,124 @@ static const uint32_t JS_SCRIPT_COOKIE = 0xc00cee;
|
|||
|
||||
struct JSScript : public js::gc::Cell
|
||||
{
|
||||
/*
|
||||
* Two successively less primitive ways to make a new JSScript. The first
|
||||
* does *not* call a non-null cx->runtime->newScriptHook -- only the second,
|
||||
* NewScriptFromEmitter, calls this optional debugger hook.
|
||||
*
|
||||
* The NewScript function can't know whether the script it creates belongs
|
||||
* to a function, or is top-level or eval code, but the debugger wants access
|
||||
* to the newly made script's function, if any -- so callers of NewScript
|
||||
* are responsible for notifying the debugger after successfully creating any
|
||||
* kind (function or other) of new JSScript.
|
||||
*/
|
||||
static JSScript *NewScript(JSContext *cx, uint32_t length, uint32_t nsrcnotes, uint32_t natoms,
|
||||
uint32_t nobjects, uint32_t nregexps,
|
||||
uint32_t ntrynotes, uint32_t nconsts, uint32_t nglobals,
|
||||
uint16_t nClosedArgs, uint16_t nClosedVars, uint32_t nTypeSets,
|
||||
JSVersion version);
|
||||
private:
|
||||
static const uint32_t stepFlagMask = 0x80000000U;
|
||||
static const uint32_t stepCountMask = 0x7fffffffU;
|
||||
|
||||
static JSScript *NewScriptFromEmitter(JSContext *cx, js::BytecodeEmitter *bce);
|
||||
/*
|
||||
* We order fields according to their size in order to avoid wasting space
|
||||
* for alignment.
|
||||
*/
|
||||
|
||||
#ifdef JS_CRASH_DIAGNOSTICS
|
||||
/*
|
||||
* Make sure that the cookie size does not affect the GC alignment
|
||||
* requirements.
|
||||
*/
|
||||
uint32_t cookie1[Cell::CellSize / sizeof(uint32_t)];
|
||||
#endif
|
||||
/* Larger-than-word-sized fields. */
|
||||
|
||||
public:
|
||||
js::Bindings bindings; /* names of top-level variables in this script
|
||||
(and arguments if this is a function script) */
|
||||
|
||||
/* Word-sized fields. */
|
||||
|
||||
public:
|
||||
jsbytecode *code; /* bytecodes and their immediate operands */
|
||||
uint8_t *data; /* pointer to variable-length data array */
|
||||
uint8_t *data; /* pointer to variable-length data array (see
|
||||
comment above NewScript() for details) */
|
||||
|
||||
const char *filename; /* source filename or null */
|
||||
JSAtom **atoms; /* maps immediate index to literal struct */
|
||||
|
||||
JSPrincipals *principals;/* principals for this script */
|
||||
JSPrincipals *originPrincipals; /* see jsapi.h 'originPrincipals' comment */
|
||||
|
||||
jschar *sourceMap; /* source map file or null */
|
||||
|
||||
/*
|
||||
* A global object for the script.
|
||||
* - All scripts returned by JSAPI functions (JS_CompileScript,
|
||||
* JS_CompileUTF8File, etc.) have a non-null globalObject.
|
||||
* - A function script has a globalObject if the function comes from a
|
||||
* compile-and-go script.
|
||||
* - Temporary scripts created by obj_eval, JS_EvaluateScript, and
|
||||
* similar functions never have the globalObject field set; for such
|
||||
* scripts the global should be extracted from the JS frame that
|
||||
* execute scripts.
|
||||
*/
|
||||
js::HeapPtr<js::GlobalObject, JSScript*> globalObject;
|
||||
|
||||
/* Execution and profiling information for JIT code in the script. */
|
||||
js::ScriptCounts scriptCounts;
|
||||
|
||||
/* Persistent type information retained across GCs. */
|
||||
js::types::TypeScript *types;
|
||||
|
||||
#ifdef JS_METHODJIT
|
||||
// Fast-cached pointers to make calls faster. These are also used to
|
||||
// quickly test whether there is JIT code; a NULL value means no
|
||||
// compilation has been attempted. A JS_UNJITTABLE_SCRIPT value means
|
||||
// compilation failed. Any value is the arity-check entry point.
|
||||
void *jitArityCheckNormal;
|
||||
void *jitArityCheckCtor;
|
||||
|
||||
js::mjit::JITScript *jitNormal; /* Extra JIT info for normal scripts */
|
||||
js::mjit::JITScript *jitCtor; /* Extra JIT info for constructors */
|
||||
#endif
|
||||
|
||||
private:
|
||||
js::DebugScript *debug;
|
||||
js::HeapPtrFunction function_;
|
||||
|
||||
size_t useCount; /* Number of times the script has been called
|
||||
* or has had backedges taken. Reset if the
|
||||
* script's JIT code is forcibly discarded. */
|
||||
#if JS_BITS_PER_WORD == 32
|
||||
void *padding_;
|
||||
#endif
|
||||
|
||||
/* 32-bit fields. */
|
||||
|
||||
public:
|
||||
uint32_t length; /* length of code vector */
|
||||
|
||||
uint32_t lineno; /* base line number of script */
|
||||
|
||||
uint32_t mainOffset; /* offset of main entry point from code, after
|
||||
predef'ing prolog */
|
||||
|
||||
uint32_t natoms; /* length of atoms array */
|
||||
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* Unique identifier within the compartment for this script, used for
|
||||
* printing analysis information.
|
||||
*/
|
||||
uint32_t id_;
|
||||
private:
|
||||
uint32_t idpad;
|
||||
public:
|
||||
#endif
|
||||
|
||||
/* 16-bit fields. */
|
||||
|
||||
private:
|
||||
uint16_t version; /* JS version under which script was compiled */
|
||||
|
||||
public:
|
||||
uint16_t nfixed; /* number of slots besides stack operands in
|
||||
slot array */
|
||||
|
||||
uint16_t nTypeSets; /* number of type sets used in this script for
|
||||
dynamic type monitoring */
|
||||
|
||||
uint16_t nslots; /* vars plus maximum stack depth */
|
||||
uint16_t staticLevel;/* static level for display maintenance */
|
||||
|
||||
/* 8-bit fields. */
|
||||
|
||||
/*
|
||||
* Offsets to various array structures from the end of this script, or
|
||||
* JSScript::INVALID_OFFSET if the array has length 0.
|
||||
*/
|
||||
public:
|
||||
uint8_t constsOffset; /* offset to the array of constants */
|
||||
uint8_t objectsOffset; /* offset to the array of nested function,
|
||||
block, scope, xml and one-time regexps
|
||||
objects */
|
||||
|
@ -376,15 +464,12 @@ struct JSScript : public js::gc::Cell
|
|||
regexps */
|
||||
uint8_t trynotesOffset; /* offset to the array of try notes */
|
||||
uint8_t globalsOffset; /* offset to the array of global slots */
|
||||
uint8_t constOffset; /* offset to the array of constants */
|
||||
uint8_t closedArgsOffset; /* offset to the array of closed args */
|
||||
uint8_t closedVarsOffset; /* offset to the array of closed vars */
|
||||
|
||||
uint16_t nTypeSets; /* number of type sets used in this script for
|
||||
dynamic type monitoring */
|
||||
/* 1-bit fields. */
|
||||
|
||||
uint32_t lineno; /* base line number of script */
|
||||
|
||||
uint32_t mainOffset; /* offset of main entry point from code, after
|
||||
predef'ing prolog */
|
||||
public:
|
||||
bool noScriptRval:1; /* no need for result value of last
|
||||
expression statement */
|
||||
bool savedCallerFun:1; /* can call getCallerFunction() */
|
||||
|
@ -428,7 +513,28 @@ struct JSScript : public js::gc::Cell
|
|||
bool mayNeedArgsObj_:1;
|
||||
bool analyzedArgsUsage_:1;
|
||||
bool needsArgsObj_:1;
|
||||
|
||||
/* End of fields. Start methods. */
|
||||
|
||||
/*
|
||||
* Two successively less primitive ways to make a new JSScript. The first
|
||||
* does *not* call a non-null cx->runtime->newScriptHook -- only the second,
|
||||
* NewScriptFromEmitter, calls this optional debugger hook.
|
||||
*
|
||||
* The NewScript function can't know whether the script it creates belongs
|
||||
* to a function, or is top-level or eval code, but the debugger wants access
|
||||
* to the newly made script's function, if any -- so callers of NewScript
|
||||
* are responsible for notifying the debugger after successfully creating any
|
||||
* kind (function or other) of new JSScript.
|
||||
*/
|
||||
public:
|
||||
static JSScript *NewScript(JSContext *cx, uint32_t length, uint32_t nsrcnotes, uint32_t natoms,
|
||||
uint32_t nobjects, uint32_t nregexps,
|
||||
uint32_t ntrynotes, uint32_t nconsts, uint32_t nglobals,
|
||||
uint16_t nClosedArgs, uint16_t nClosedVars, uint32_t nTypeSets,
|
||||
JSVersion version);
|
||||
static JSScript *NewScriptFromEmitter(JSContext *cx, js::BytecodeEmitter *bce);
|
||||
|
||||
bool mayNeedArgsObj() const { return mayNeedArgsObj_; }
|
||||
bool analyzedArgsUsage() const { return analyzedArgsUsage_; }
|
||||
bool needsArgsObj() const { JS_ASSERT(analyzedArgsUsage()); return needsArgsObj_; }
|
||||
|
@ -439,51 +545,8 @@ struct JSScript : public js::gc::Cell
|
|||
mayNeedArgsObj_ = true;
|
||||
}
|
||||
|
||||
uint32_t natoms; /* length of atoms array */
|
||||
uint16_t nslots; /* vars plus maximum stack depth */
|
||||
uint16_t staticLevel;/* static level for display maintenance */
|
||||
|
||||
uint16_t nClosedArgs; /* number of args which are closed over. */
|
||||
uint16_t nClosedVars; /* number of vars which are closed over. */
|
||||
|
||||
const char *filename; /* source filename or null */
|
||||
JSAtom **atoms; /* maps immediate index to literal struct */
|
||||
private:
|
||||
size_t useCount; /* Number of times the script has been called
|
||||
* or has had backedges taken. Reset if the
|
||||
* script's JIT code is forcibly discarded. */
|
||||
public:
|
||||
js::Bindings bindings; /* names of top-level variables in this script
|
||||
(and arguments if this is a function script) */
|
||||
JSPrincipals *principals;/* principals for this script */
|
||||
JSPrincipals *originPrincipals; /* see jsapi.h 'originPrincipals' comment */
|
||||
jschar *sourceMap; /* source map file or null */
|
||||
|
||||
/*
|
||||
* A global object for the script.
|
||||
* - All scripts returned by JSAPI functions (JS_CompileScript,
|
||||
* JS_CompileUTF8File, etc.) have a non-null globalObject.
|
||||
* - A function script has a globalObject if the function comes from a
|
||||
* compile-and-go script.
|
||||
* - Temporary scripts created by obj_eval, JS_EvaluateScript, and
|
||||
* similar functions never have the globalObject field set; for such
|
||||
* scripts the global should be extracted from the JS frame that
|
||||
* execute scripts.
|
||||
*/
|
||||
js::HeapPtr<js::GlobalObject, JSScript*> globalObject;
|
||||
|
||||
/* Hash table chaining for JSCompartment::evalCache. */
|
||||
JSScript *&evalHashLink() { return *globalObject.unsafeGetUnioned(); }
|
||||
|
||||
uint32_t *closedSlots; /* vector of closed slots; args first, then vars. */
|
||||
|
||||
/* Execution and profiling information for JIT code in the script. */
|
||||
js::ScriptOpcodeCounts pcCounters;
|
||||
|
||||
private:
|
||||
js::DebugScript *debug;
|
||||
js::HeapPtrFunction function_;
|
||||
public:
|
||||
JSScript *&evalHashLink() { return *globalObject.unsafeGetUnioned(); }
|
||||
|
||||
/*
|
||||
* Original compiled function for the script, if it has a function.
|
||||
|
@ -492,36 +555,12 @@ struct JSScript : public js::gc::Cell
|
|||
JSFunction *function() const { return function_; }
|
||||
void setFunction(JSFunction *fun);
|
||||
|
||||
#ifdef JS_CRASH_DIAGNOSTICS
|
||||
/* All diagnostic fields must be multiples of Cell::CellSize. */
|
||||
uint32_t cookie2[Cell::CellSize / sizeof(uint32_t)];
|
||||
|
||||
void CheckScript(JSScript *prev);
|
||||
#else
|
||||
void CheckScript(JSScript *prev) {}
|
||||
#endif /* !JS_CRASH_DIAGNOSTICS */
|
||||
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* Unique identifier within the compartment for this script, used for
|
||||
* printing analysis information.
|
||||
*/
|
||||
uint32_t id_;
|
||||
uint32_t idpad;
|
||||
unsigned id();
|
||||
#else
|
||||
unsigned id() { return 0; }
|
||||
#endif
|
||||
|
||||
/* Persistent type information retained across GCs. */
|
||||
js::types::TypeScript *types;
|
||||
|
||||
#if JS_BITS_PER_WORD == 32
|
||||
private:
|
||||
void *padding_;
|
||||
public:
|
||||
#endif
|
||||
|
||||
/* Ensure the script has a TypeScript. */
|
||||
inline bool ensureHasTypes(JSContext *cx);
|
||||
|
||||
|
@ -564,18 +603,6 @@ struct JSScript : public js::gc::Cell
|
|||
bool makeAnalysis(JSContext *cx);
|
||||
public:
|
||||
|
||||
#ifdef JS_METHODJIT
|
||||
// Fast-cached pointers to make calls faster. These are also used to
|
||||
// quickly test whether there is JIT code; a NULL value means no
|
||||
// compilation has been attempted. A JS_UNJITTABLE_SCRIPT value means
|
||||
// compilation failed. Any value is the arity-check entry point.
|
||||
void *jitArityCheckNormal;
|
||||
void *jitArityCheckCtor;
|
||||
|
||||
js::mjit::JITScript *jitNormal; /* Extra JIT info for normal scripts */
|
||||
js::mjit::JITScript *jitCtor; /* Extra JIT info for constructors */
|
||||
#endif
|
||||
|
||||
#ifdef JS_METHODJIT
|
||||
bool hasJITCode() {
|
||||
return jitNormal || jitCtor;
|
||||
|
@ -600,17 +627,15 @@ struct JSScript : public js::gc::Cell
|
|||
* MethodJIT.cpp.)
|
||||
*/
|
||||
size_t sizeOfJitScripts(JSMallocSizeOfFun mallocSizeOf);
|
||||
|
||||
#endif
|
||||
|
||||
/* Counter accessors. */
|
||||
js::OpcodeCounts getCounts(jsbytecode *pc) {
|
||||
js::PCCounts getPCCounts(jsbytecode *pc) {
|
||||
JS_ASSERT(size_t(pc - code) < length);
|
||||
return pcCounters.counts[pc - code];
|
||||
return scriptCounts.pcCountsVector[pc - code];
|
||||
}
|
||||
|
||||
bool initCounts(JSContext *cx);
|
||||
void destroyCounts(JSContext *cx);
|
||||
bool initScriptCounts(JSContext *cx);
|
||||
void destroyScriptCounts(JSContext *cx);
|
||||
|
||||
jsbytecode *main() {
|
||||
return code + mainOffset;
|
||||
|
@ -632,6 +657,11 @@ struct JSScript : public js::gc::Cell
|
|||
static const uint8_t INVALID_OFFSET = 0xFF;
|
||||
static bool isValidOffset(uint8_t offset) { return offset != INVALID_OFFSET; }
|
||||
|
||||
JSConstArray *consts() {
|
||||
JS_ASSERT(isValidOffset(constsOffset));
|
||||
return reinterpret_cast<JSConstArray *>(data + constsOffset);
|
||||
}
|
||||
|
||||
JSObjectArray *objects() {
|
||||
JS_ASSERT(isValidOffset(objectsOffset));
|
||||
return reinterpret_cast<JSObjectArray *>(data + objectsOffset);
|
||||
|
@ -652,9 +682,22 @@ struct JSScript : public js::gc::Cell
|
|||
return reinterpret_cast<js::GlobalSlotArray *>(data + globalsOffset);
|
||||
}
|
||||
|
||||
JSConstArray *consts() {
|
||||
JS_ASSERT(isValidOffset(constOffset));
|
||||
return reinterpret_cast<JSConstArray *>(data + constOffset);
|
||||
js::ClosedSlotArray *closedArgs() {
|
||||
JS_ASSERT(isValidOffset(closedArgsOffset));
|
||||
return reinterpret_cast<js::ClosedSlotArray *>(data + closedArgsOffset);
|
||||
}
|
||||
|
||||
js::ClosedSlotArray *closedVars() {
|
||||
JS_ASSERT(isValidOffset(closedVarsOffset));
|
||||
return reinterpret_cast<js::ClosedSlotArray *>(data + closedVarsOffset);
|
||||
}
|
||||
|
||||
uint32_t nClosedArgs() {
|
||||
return isValidOffset(closedArgsOffset) ? closedArgs()->length : 0;
|
||||
}
|
||||
|
||||
uint32_t nClosedVars() {
|
||||
return isValidOffset(closedVarsOffset) ? closedVars()->length : 0;
|
||||
}
|
||||
|
||||
JSAtom *getAtom(size_t index) {
|
||||
|
@ -695,21 +738,18 @@ struct JSScript : public js::gc::Cell
|
|||
inline bool isEmpty() const;
|
||||
|
||||
uint32_t getClosedArg(uint32_t index) {
|
||||
JS_ASSERT(index < nClosedArgs);
|
||||
return closedSlots[index];
|
||||
js::ClosedSlotArray *arr = closedArgs();
|
||||
JS_ASSERT(index < arr->length);
|
||||
return arr->vector[index];
|
||||
}
|
||||
|
||||
uint32_t getClosedVar(uint32_t index) {
|
||||
JS_ASSERT(index < nClosedVars);
|
||||
return closedSlots[nClosedArgs + index];
|
||||
js::ClosedSlotArray *arr = closedVars();
|
||||
JS_ASSERT(index < arr->length);
|
||||
return arr->vector[index];
|
||||
}
|
||||
|
||||
void copyClosedSlotsTo(JSScript *other);
|
||||
|
||||
private:
|
||||
static const uint32_t stepFlagMask = 0x80000000U;
|
||||
static const uint32_t stepCountMask = 0x7fffffffU;
|
||||
|
||||
/*
|
||||
* Attempt to recompile with or without single-stepping support, as directed
|
||||
* by stepModeEnabled().
|
||||
|
@ -813,31 +853,17 @@ SweepScriptFilenames(JSCompartment *comp);
|
|||
extern void
|
||||
FreeScriptFilenames(JSCompartment *comp);
|
||||
|
||||
struct ScriptOpcodeCountsPair
|
||||
struct ScriptAndCounts
|
||||
{
|
||||
JSScript *script;
|
||||
ScriptOpcodeCounts counters;
|
||||
ScriptCounts scriptCounts;
|
||||
|
||||
OpcodeCounts &getCounts(jsbytecode *pc) const {
|
||||
PCCounts &getPCCounts(jsbytecode *pc) const {
|
||||
JS_ASSERT(unsigned(pc - script->code) < script->length);
|
||||
return counters.counts[pc - script->code];
|
||||
return scriptCounts.pcCountsVector[pc - script->code];
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef JS_CRASH_DIAGNOSTICS
|
||||
|
||||
void
|
||||
CheckScript(JSScript *script, JSScript *prev);
|
||||
|
||||
#else
|
||||
|
||||
inline void
|
||||
CheckScript(JSScript *script, JSScript *prev)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* !JS_CRASH_DIAGNOSTICS */
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
/*
|
||||
|
|
|
@ -139,10 +139,9 @@ CurrentScriptFileLineOrigin(JSContext *cx, const char **file, unsigned *linenop,
|
|||
}
|
||||
|
||||
inline void
|
||||
ScriptOpcodeCounts::destroy(JSContext *cx)
|
||||
ScriptCounts::destroy(JSContext *cx)
|
||||
{
|
||||
if (counts)
|
||||
cx->free_(counts);
|
||||
cx->free_(pcCountsVector);
|
||||
}
|
||||
|
||||
} // namespace js
|
||||
|
|
|
@ -65,6 +65,17 @@ js_memcpy(void *dst_, const void *src_, size_t len)
|
|||
#ifdef __cplusplus
|
||||
namespace js {
|
||||
|
||||
template <class T>
|
||||
struct AlignmentTestStruct
|
||||
{
|
||||
char c;
|
||||
T t;
|
||||
};
|
||||
|
||||
/* This macro determines the alignment requirements of a type. */
|
||||
#define JS_ALIGNMENT_OF(t_) \
|
||||
(sizeof(js::AlignmentTestStruct<t_>) - sizeof(t_))
|
||||
|
||||
template <class T>
|
||||
class AlignedPtrAndFlag
|
||||
{
|
||||
|
|
|
@ -1366,28 +1366,28 @@ static const JSC::MacroAssembler::RegisterID JSParamReg_Argc = JSC::MIPSRegiste
|
|||
return jump;
|
||||
}
|
||||
|
||||
/* Add the value stored in 'value' to the accumulator 'counter'. */
|
||||
void addCounter(const double *value, double *counter, RegisterID scratch)
|
||||
/* Add the value stored in 'value' to the accumulator 'count'. */
|
||||
void addCount(const double *value, double *count, RegisterID scratch)
|
||||
{
|
||||
loadDouble(value, Registers::FPConversionTemp);
|
||||
move(ImmPtr(counter), scratch);
|
||||
move(ImmPtr(count), scratch);
|
||||
addDouble(Address(scratch), Registers::FPConversionTemp);
|
||||
storeDouble(Registers::FPConversionTemp, Address(scratch));
|
||||
}
|
||||
|
||||
/* Add one to the accumulator 'counter'. */
|
||||
void bumpCounter(double *counter, RegisterID scratch)
|
||||
/* Add one to the accumulator |count|. */
|
||||
void bumpCount(double *count, RegisterID scratch)
|
||||
{
|
||||
addCounter(&oneDouble, counter, scratch);
|
||||
addCount(&oneDouble, count, scratch);
|
||||
}
|
||||
|
||||
/* Bump the stub call count for script/pc if they are being counted. */
|
||||
void bumpStubCounter(JSScript *script, jsbytecode *pc, RegisterID scratch)
|
||||
void bumpStubCount(JSScript *script, jsbytecode *pc, RegisterID scratch)
|
||||
{
|
||||
if (script->pcCounters) {
|
||||
OpcodeCounts counts = script->getCounts(pc);
|
||||
double *counter = &counts.get(OpcodeCounts::BASE_METHODJIT_STUBS);
|
||||
bumpCounter(counter, scratch);
|
||||
if (script->scriptCounts) {
|
||||
PCCounts counts = script->getPCCounts(pc);
|
||||
double *count = &counts.get(PCCounts::BASE_METHODJIT_STUBS);
|
||||
bumpCount(count, scratch);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -404,8 +404,8 @@ mjit::Compiler::scanInlineCalls(uint32_t index, uint32_t depth)
|
|||
CompileStatus
|
||||
mjit::Compiler::pushActiveFrame(JSScript *script, uint32_t argc)
|
||||
{
|
||||
if (cx->runtime->profilingScripts && !script->pcCounters)
|
||||
script->initCounts(cx);
|
||||
if (cx->runtime->profilingScripts && !script->scriptCounts)
|
||||
script->initScriptCounts(cx);
|
||||
|
||||
ActiveFrame *newa = OffTheBooks::new_<ActiveFrame>(cx);
|
||||
if (!newa) {
|
||||
|
@ -538,7 +538,7 @@ mjit::Compiler::performCompilation()
|
|||
CHECK_STATUS(scanInlineCalls(CrossScriptSSA::OUTER_FRAME, 0));
|
||||
CHECK_STATUS(pushActiveFrame(outerScript, 0));
|
||||
|
||||
if (outerScript->pcCounters || Probes::wantNativeAddressInfo(cx)) {
|
||||
if (outerScript->scriptCounts || Probes::wantNativeAddressInfo(cx)) {
|
||||
size_t length = ssa.frameLength(ssa.numFrames() - 1);
|
||||
pcLengths = (PCLengthEntry *) OffTheBooks::calloc_(sizeof(pcLengths[0]) * length);
|
||||
if (!pcLengths)
|
||||
|
@ -1375,11 +1375,8 @@ mjit::Compiler::finishThisUp()
|
|||
if (chunkIndex == 0) {
|
||||
jit->invokeEntry = result;
|
||||
if (script->function()) {
|
||||
jit->arityCheckEntry = stubCode.locationOf(arityLabel).executableAddress();
|
||||
jit->argsCheckEntry = stubCode.locationOf(argsCheckLabel).executableAddress();
|
||||
jit->fastEntry = fullCode.locationOf(invokeLabel).executableAddress();
|
||||
void *&addr = isConstructing ? script->jitArityCheckCtor : script->jitArityCheckNormal;
|
||||
addr = jit->arityCheckEntry;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2117,12 +2114,12 @@ mjit::Compiler::generateMethod()
|
|||
}
|
||||
|
||||
Label codeStart = masm.label();
|
||||
bool countersUpdated = false;
|
||||
bool countsUpdated = false;
|
||||
bool arithUpdated = false;
|
||||
|
||||
JSValueType arithFirstUseType = JSVAL_TYPE_UNKNOWN;
|
||||
JSValueType arithSecondUseType = JSVAL_TYPE_UNKNOWN;
|
||||
if (script->pcCounters && !!(js_CodeSpec[op].format & JOF_ARITH)) {
|
||||
if (script->scriptCounts && !!(js_CodeSpec[op].format & JOF_ARITH)) {
|
||||
if (GetUseCount(script, PC - script->code) == 1) {
|
||||
FrameEntry *use = frame.peek(-1);
|
||||
/*
|
||||
|
@ -2142,12 +2139,12 @@ mjit::Compiler::generateMethod()
|
|||
}
|
||||
|
||||
/*
|
||||
* Update PC counters for jump opcodes at their start, so that we don't
|
||||
* Update PC counts for jump opcodes at their start, so that we don't
|
||||
* miss them when taking the jump. This is delayed for other opcodes,
|
||||
* as we want to skip updating for ops we didn't generate any code for.
|
||||
*/
|
||||
if (script->pcCounters && JOF_OPTYPE(op) == JOF_JUMP)
|
||||
updatePCCounters(PC, &codeStart, &countersUpdated);
|
||||
if (script->scriptCounts && JOF_OPTYPE(op) == JOF_JUMP)
|
||||
updatePCCounts(PC, &codeStart, &countsUpdated);
|
||||
|
||||
/**********************
|
||||
* BEGIN COMPILER OPS *
|
||||
|
@ -2182,8 +2179,8 @@ mjit::Compiler::generateMethod()
|
|||
END_CASE(JSOP_POPV)
|
||||
|
||||
BEGIN_CASE(JSOP_RETURN)
|
||||
if (script->pcCounters)
|
||||
updatePCCounters(PC, &codeStart, &countersUpdated);
|
||||
if (script->scriptCounts)
|
||||
updatePCCounts(PC, &codeStart, &countsUpdated);
|
||||
emitReturn(frame.peek(-1));
|
||||
fallthrough = false;
|
||||
END_CASE(JSOP_RETURN)
|
||||
|
@ -2338,8 +2335,8 @@ mjit::Compiler::generateMethod()
|
|||
BEGIN_CASE(JSOP_EQ)
|
||||
BEGIN_CASE(JSOP_NE)
|
||||
{
|
||||
if (script->pcCounters) {
|
||||
updateArithCounters(PC, NULL, arithFirstUseType, arithSecondUseType);
|
||||
if (script->scriptCounts) {
|
||||
updateArithCounts(PC, NULL, arithFirstUseType, arithSecondUseType);
|
||||
arithUpdated = true;
|
||||
}
|
||||
|
||||
|
@ -2352,8 +2349,8 @@ mjit::Compiler::generateMethod()
|
|||
/* Get jump target, if any. */
|
||||
jsbytecode *target = NULL;
|
||||
if (fused != JSOP_NOP) {
|
||||
if (script->pcCounters)
|
||||
updatePCCounters(PC, &codeStart, &countersUpdated);
|
||||
if (script->scriptCounts)
|
||||
updatePCCounts(PC, &codeStart, &countsUpdated);
|
||||
target = next + GET_JUMP_OFFSET(next);
|
||||
fixDoubleTypes(target);
|
||||
}
|
||||
|
@ -2575,8 +2572,8 @@ mjit::Compiler::generateMethod()
|
|||
|
||||
BEGIN_CASE(JSOP_GETELEM)
|
||||
BEGIN_CASE(JSOP_CALLELEM)
|
||||
if (script->pcCounters)
|
||||
updateElemCounters(PC, frame.peek(-2), frame.peek(-1));
|
||||
if (script->scriptCounts)
|
||||
updateElemCounts(PC, frame.peek(-2), frame.peek(-1));
|
||||
if (!jsop_getelem())
|
||||
return Compile_Error;
|
||||
END_CASE(JSOP_GETELEM)
|
||||
|
@ -2587,8 +2584,8 @@ mjit::Compiler::generateMethod()
|
|||
|
||||
BEGIN_CASE(JSOP_SETELEM)
|
||||
{
|
||||
if (script->pcCounters)
|
||||
updateElemCounters(PC, frame.peek(-3), frame.peek(-2));
|
||||
if (script->scriptCounts)
|
||||
updateElemCounts(PC, frame.peek(-3), frame.peek(-2));
|
||||
jsbytecode *next = &PC[JSOP_SETELEM_LENGTH];
|
||||
bool pop = (JSOp(*next) == JSOP_POP && !analysis->jumpTarget(next));
|
||||
if (!jsop_setelem(pop))
|
||||
|
@ -2625,9 +2622,9 @@ mjit::Compiler::generateMethod()
|
|||
done = true;
|
||||
else if (status != Compile_InlineAbort)
|
||||
return status;
|
||||
if (script->pcCounters) {
|
||||
if (script->scriptCounts) {
|
||||
/* Code generated while inlining has been accounted for. */
|
||||
updatePCCounters(PC, &codeStart, &countersUpdated);
|
||||
updatePCCounts(PC, &codeStart, &countsUpdated);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2714,8 +2711,8 @@ mjit::Compiler::generateMethod()
|
|||
* double types, as we don't track types of slots in scripts with
|
||||
* switch statements (could be fixed).
|
||||
*/
|
||||
if (script->pcCounters)
|
||||
updatePCCounters(PC, &codeStart, &countersUpdated);
|
||||
if (script->scriptCounts)
|
||||
updatePCCounts(PC, &codeStart, &countsUpdated);
|
||||
#if defined JS_CPU_ARM /* Need to implement jump(BaseIndex) for ARM */
|
||||
frame.syncAndKillEverything();
|
||||
masm.move(ImmPtr(PC), Registers::ArgReg1);
|
||||
|
@ -2734,8 +2731,8 @@ mjit::Compiler::generateMethod()
|
|||
END_CASE(JSOP_TABLESWITCH)
|
||||
|
||||
BEGIN_CASE(JSOP_LOOKUPSWITCH)
|
||||
if (script->pcCounters)
|
||||
updatePCCounters(PC, &codeStart, &countersUpdated);
|
||||
if (script->scriptCounts)
|
||||
updatePCCounts(PC, &codeStart, &countsUpdated);
|
||||
frame.syncAndForgetEverything();
|
||||
masm.move(ImmPtr(PC), Registers::ArgReg1);
|
||||
|
||||
|
@ -2763,8 +2760,8 @@ mjit::Compiler::generateMethod()
|
|||
|
||||
BEGIN_CASE(JSOP_STRICTEQ)
|
||||
BEGIN_CASE(JSOP_STRICTNE)
|
||||
if (script->pcCounters) {
|
||||
updateArithCounters(PC, NULL, arithFirstUseType, arithSecondUseType);
|
||||
if (script->scriptCounts) {
|
||||
updateArithCounts(PC, NULL, arithFirstUseType, arithSecondUseType);
|
||||
arithUpdated = true;
|
||||
}
|
||||
jsop_stricteq(op);
|
||||
|
@ -2778,8 +2775,8 @@ mjit::Compiler::generateMethod()
|
|||
BEGIN_CASE(JSOP_MOREITER)
|
||||
{
|
||||
/* At the byte level, this is always fused with IFNE or IFNEX. */
|
||||
if (script->pcCounters)
|
||||
updatePCCounters(PC, &codeStart, &countersUpdated);
|
||||
if (script->scriptCounts)
|
||||
updatePCCounts(PC, &codeStart, &countsUpdated);
|
||||
jsbytecode *target = &PC[JSOP_MOREITER_LENGTH];
|
||||
JSOp next = JSOp(*target);
|
||||
JS_ASSERT(next == JSOP_IFNE);
|
||||
|
@ -2904,7 +2901,7 @@ mjit::Compiler::generateMethod()
|
|||
BEGIN_CASE(JSOP_DECARG)
|
||||
BEGIN_CASE(JSOP_ARGINC)
|
||||
BEGIN_CASE(JSOP_ARGDEC)
|
||||
if (script->pcCounters) {
|
||||
if (script->scriptCounts) {
|
||||
restoreVarType();
|
||||
FrameEntry *fe = frame.getArg(GET_SLOTNO(PC));
|
||||
if (fe->isTypeKnown())
|
||||
|
@ -2914,9 +2911,9 @@ mjit::Compiler::generateMethod()
|
|||
if (!jsop_arginc(op, GET_SLOTNO(PC)))
|
||||
return Compile_Retry;
|
||||
|
||||
if (script->pcCounters) {
|
||||
if (script->scriptCounts) {
|
||||
FrameEntry *fe = frame.getArg(GET_SLOTNO(PC));
|
||||
updateArithCounters(PC, fe, arithFirstUseType, JSVAL_TYPE_INT32);
|
||||
updateArithCounts(PC, fe, arithFirstUseType, JSVAL_TYPE_INT32);
|
||||
arithUpdated = true;
|
||||
}
|
||||
END_CASE(JSOP_ARGDEC)
|
||||
|
@ -2925,7 +2922,7 @@ mjit::Compiler::generateMethod()
|
|||
BEGIN_CASE(JSOP_DECLOCAL)
|
||||
BEGIN_CASE(JSOP_LOCALINC)
|
||||
BEGIN_CASE(JSOP_LOCALDEC)
|
||||
if (script->pcCounters) {
|
||||
if (script->scriptCounts) {
|
||||
restoreVarType();
|
||||
FrameEntry *fe = frame.getLocal(GET_SLOTNO(PC));
|
||||
if (fe->isTypeKnown())
|
||||
|
@ -2935,9 +2932,9 @@ mjit::Compiler::generateMethod()
|
|||
if (!jsop_localinc(op, GET_SLOTNO(PC)))
|
||||
return Compile_Retry;
|
||||
|
||||
if (script->pcCounters) {
|
||||
if (script->scriptCounts) {
|
||||
FrameEntry *fe = frame.getLocal(GET_SLOTNO(PC));
|
||||
updateArithCounters(PC, fe, arithFirstUseType, JSVAL_TYPE_INT32);
|
||||
updateArithCounts(PC, fe, arithFirstUseType, JSVAL_TYPE_INT32);
|
||||
arithUpdated = true;
|
||||
}
|
||||
END_CASE(JSOP_LOCALDEC)
|
||||
|
@ -3117,8 +3114,8 @@ mjit::Compiler::generateMethod()
|
|||
END_CASE(JSOP_UINT24)
|
||||
|
||||
BEGIN_CASE(JSOP_STOP)
|
||||
if (script->pcCounters)
|
||||
updatePCCounters(PC, &codeStart, &countersUpdated);
|
||||
if (script->scriptCounts)
|
||||
updatePCCounts(PC, &codeStart, &countsUpdated);
|
||||
emitReturn(NULL);
|
||||
goto done;
|
||||
END_CASE(JSOP_STOP)
|
||||
|
@ -3195,7 +3192,7 @@ mjit::Compiler::generateMethod()
|
|||
}
|
||||
}
|
||||
|
||||
if (script->pcCounters) {
|
||||
if (script->scriptCounts) {
|
||||
size_t length = masm.size() - masm.distanceOf(codeStart);
|
||||
bool typesUpdated = false;
|
||||
|
||||
|
@ -3204,12 +3201,12 @@ mjit::Compiler::generateMethod()
|
|||
FrameEntry *pushed = NULL;
|
||||
if (PC == lastPC + GetBytecodeLength(lastPC))
|
||||
pushed = frame.peek(-1);
|
||||
updateArithCounters(lastPC, pushed, arithFirstUseType, arithSecondUseType);
|
||||
updateArithCounts(lastPC, pushed, arithFirstUseType, arithSecondUseType);
|
||||
typesUpdated = true;
|
||||
}
|
||||
|
||||
/* Update information about the result type of access operations. */
|
||||
if (OpcodeCounts::accessOp(op) &&
|
||||
if (PCCounts::accessOp(op) &&
|
||||
op != JSOP_SETPROP && op != JSOP_SETELEM) {
|
||||
FrameEntry *fe = (GetDefCount(script, lastPC - script->code) == 1)
|
||||
? frame.peek(-1)
|
||||
|
@ -3218,9 +3215,9 @@ mjit::Compiler::generateMethod()
|
|||
typesUpdated = true;
|
||||
}
|
||||
|
||||
if (countersUpdated || typesUpdated || length != 0) {
|
||||
if (!countersUpdated)
|
||||
updatePCCounters(lastPC, &codeStart, &countersUpdated);
|
||||
if (countsUpdated || typesUpdated || length != 0) {
|
||||
if (!countsUpdated)
|
||||
updatePCCounts(lastPC, &codeStart, &countsUpdated);
|
||||
|
||||
if (pcLengths) {
|
||||
/* Fill in the amount of inline code generated for the op. */
|
||||
|
@ -3246,9 +3243,9 @@ mjit::Compiler::generateMethod()
|
|||
#undef BEGIN_CASE
|
||||
|
||||
void
|
||||
mjit::Compiler::updatePCCounters(jsbytecode *pc, Label *start, bool *updated)
|
||||
mjit::Compiler::updatePCCounts(jsbytecode *pc, Label *start, bool *updated)
|
||||
{
|
||||
JS_ASSERT(script->pcCounters);
|
||||
JS_ASSERT(script->scriptCounts);
|
||||
|
||||
/*
|
||||
* Bump the METHODJIT count for the opcode, read the METHODJIT_CODE_LENGTH
|
||||
|
@ -3267,18 +3264,18 @@ mjit::Compiler::updatePCCounters(jsbytecode *pc, Label *start, bool *updated)
|
|||
RegisterID reg = Registers::ReturnReg;
|
||||
masm.storePtr(reg, frame.addressOfTop());
|
||||
|
||||
OpcodeCounts counts = script->getCounts(pc);
|
||||
PCCounts counts = script->getPCCounts(pc);
|
||||
|
||||
double *code = &counts.get(OpcodeCounts::BASE_METHODJIT_CODE);
|
||||
double *code = &counts.get(PCCounts::BASE_METHODJIT_CODE);
|
||||
double *codeLength = &pcLengths[offset].codeLength;
|
||||
masm.addCounter(codeLength, code, reg);
|
||||
masm.addCount(codeLength, code, reg);
|
||||
|
||||
double *pics = &counts.get(OpcodeCounts::BASE_METHODJIT_PICS);
|
||||
double *pics = &counts.get(PCCounts::BASE_METHODJIT_PICS);
|
||||
double *picsLength = &pcLengths[offset].picsLength;
|
||||
masm.addCounter(picsLength, pics, reg);
|
||||
masm.addCount(picsLength, pics, reg);
|
||||
|
||||
double *counter = &counts.get(OpcodeCounts::BASE_METHODJIT);
|
||||
masm.bumpCounter(counter, reg);
|
||||
double *count = &counts.get(PCCounts::BASE_METHODJIT);
|
||||
masm.bumpCount(count, reg);
|
||||
|
||||
/* Reload the base register's original value. */
|
||||
masm.loadPtr(frame.addressOfTop(), reg);
|
||||
|
@ -3310,10 +3307,10 @@ HasPayloadType(types::TypeSet *types)
|
|||
void
|
||||
mjit::Compiler::updatePCTypes(jsbytecode *pc, FrameEntry *fe)
|
||||
{
|
||||
JS_ASSERT(script->pcCounters);
|
||||
JS_ASSERT(script->scriptCounts);
|
||||
|
||||
/*
|
||||
* Get a temporary register, as for updatePCCounters. Don't overlap with
|
||||
* Get a temporary register, as for updatePCCounts. Don't overlap with
|
||||
* the backing store for the entry's type tag, if there is one.
|
||||
*/
|
||||
RegisterID reg = Registers::ReturnReg;
|
||||
|
@ -3323,75 +3320,75 @@ mjit::Compiler::updatePCTypes(jsbytecode *pc, FrameEntry *fe)
|
|||
}
|
||||
masm.push(reg);
|
||||
|
||||
OpcodeCounts counts = script->getCounts(pc);
|
||||
PCCounts counts = script->getPCCounts(pc);
|
||||
|
||||
/* Update the counters for pushed type tags and possible access types. */
|
||||
/* Update the counts for pushed type tags and possible access types. */
|
||||
if (fe->isTypeKnown()) {
|
||||
masm.bumpCounter(&counts.get(OpcodeCounts::ACCESS_MONOMORPHIC), reg);
|
||||
OpcodeCounts::AccessCounts counter = OpcodeCounts::ACCESS_OBJECT;
|
||||
masm.bumpCount(&counts.get(PCCounts::ACCESS_MONOMORPHIC), reg);
|
||||
PCCounts::AccessCounts count = PCCounts::ACCESS_OBJECT;
|
||||
switch (fe->getKnownType()) {
|
||||
case JSVAL_TYPE_UNDEFINED: counter = OpcodeCounts::ACCESS_UNDEFINED; break;
|
||||
case JSVAL_TYPE_NULL: counter = OpcodeCounts::ACCESS_NULL; break;
|
||||
case JSVAL_TYPE_BOOLEAN: counter = OpcodeCounts::ACCESS_BOOLEAN; break;
|
||||
case JSVAL_TYPE_INT32: counter = OpcodeCounts::ACCESS_INT32; break;
|
||||
case JSVAL_TYPE_DOUBLE: counter = OpcodeCounts::ACCESS_DOUBLE; break;
|
||||
case JSVAL_TYPE_STRING: counter = OpcodeCounts::ACCESS_STRING; break;
|
||||
case JSVAL_TYPE_OBJECT: counter = OpcodeCounts::ACCESS_OBJECT; break;
|
||||
case JSVAL_TYPE_UNDEFINED: count = PCCounts::ACCESS_UNDEFINED; break;
|
||||
case JSVAL_TYPE_NULL: count = PCCounts::ACCESS_NULL; break;
|
||||
case JSVAL_TYPE_BOOLEAN: count = PCCounts::ACCESS_BOOLEAN; break;
|
||||
case JSVAL_TYPE_INT32: count = PCCounts::ACCESS_INT32; break;
|
||||
case JSVAL_TYPE_DOUBLE: count = PCCounts::ACCESS_DOUBLE; break;
|
||||
case JSVAL_TYPE_STRING: count = PCCounts::ACCESS_STRING; break;
|
||||
case JSVAL_TYPE_OBJECT: count = PCCounts::ACCESS_OBJECT; break;
|
||||
default:;
|
||||
}
|
||||
if (counter)
|
||||
masm.bumpCounter(&counts.get(counter), reg);
|
||||
if (count)
|
||||
masm.bumpCount(&counts.get(count), reg);
|
||||
} else {
|
||||
types::TypeSet *types = frame.extra(fe).types;
|
||||
if (types && HasPayloadType(types))
|
||||
masm.bumpCounter(&counts.get(OpcodeCounts::ACCESS_DIMORPHIC), reg);
|
||||
masm.bumpCount(&counts.get(PCCounts::ACCESS_DIMORPHIC), reg);
|
||||
else
|
||||
masm.bumpCounter(&counts.get(OpcodeCounts::ACCESS_POLYMORPHIC), reg);
|
||||
masm.bumpCount(&counts.get(PCCounts::ACCESS_POLYMORPHIC), reg);
|
||||
|
||||
frame.loadTypeIntoReg(fe, reg);
|
||||
|
||||
Jump j = masm.testUndefined(Assembler::NotEqual, reg);
|
||||
masm.bumpCounter(&counts.get(OpcodeCounts::ACCESS_UNDEFINED), reg);
|
||||
masm.bumpCount(&counts.get(PCCounts::ACCESS_UNDEFINED), reg);
|
||||
frame.loadTypeIntoReg(fe, reg);
|
||||
j.linkTo(masm.label(), &masm);
|
||||
|
||||
j = masm.testNull(Assembler::NotEqual, reg);
|
||||
masm.bumpCounter(&counts.get(OpcodeCounts::ACCESS_NULL), reg);
|
||||
masm.bumpCount(&counts.get(PCCounts::ACCESS_NULL), reg);
|
||||
frame.loadTypeIntoReg(fe, reg);
|
||||
j.linkTo(masm.label(), &masm);
|
||||
|
||||
j = masm.testBoolean(Assembler::NotEqual, reg);
|
||||
masm.bumpCounter(&counts.get(OpcodeCounts::ACCESS_BOOLEAN), reg);
|
||||
masm.bumpCount(&counts.get(PCCounts::ACCESS_BOOLEAN), reg);
|
||||
frame.loadTypeIntoReg(fe, reg);
|
||||
j.linkTo(masm.label(), &masm);
|
||||
|
||||
j = masm.testInt32(Assembler::NotEqual, reg);
|
||||
masm.bumpCounter(&counts.get(OpcodeCounts::ACCESS_INT32), reg);
|
||||
masm.bumpCount(&counts.get(PCCounts::ACCESS_INT32), reg);
|
||||
frame.loadTypeIntoReg(fe, reg);
|
||||
j.linkTo(masm.label(), &masm);
|
||||
|
||||
j = masm.testDouble(Assembler::NotEqual, reg);
|
||||
masm.bumpCounter(&counts.get(OpcodeCounts::ACCESS_DOUBLE), reg);
|
||||
masm.bumpCount(&counts.get(PCCounts::ACCESS_DOUBLE), reg);
|
||||
frame.loadTypeIntoReg(fe, reg);
|
||||
j.linkTo(masm.label(), &masm);
|
||||
|
||||
j = masm.testString(Assembler::NotEqual, reg);
|
||||
masm.bumpCounter(&counts.get(OpcodeCounts::ACCESS_STRING), reg);
|
||||
masm.bumpCount(&counts.get(PCCounts::ACCESS_STRING), reg);
|
||||
frame.loadTypeIntoReg(fe, reg);
|
||||
j.linkTo(masm.label(), &masm);
|
||||
|
||||
j = masm.testObject(Assembler::NotEqual, reg);
|
||||
masm.bumpCounter(&counts.get(OpcodeCounts::ACCESS_OBJECT), reg);
|
||||
masm.bumpCount(&counts.get(PCCounts::ACCESS_OBJECT), reg);
|
||||
frame.loadTypeIntoReg(fe, reg);
|
||||
j.linkTo(masm.label(), &masm);
|
||||
}
|
||||
|
||||
/* Update the counter for accesses with type barriers. */
|
||||
/* Update the count for accesses with type barriers. */
|
||||
if (js_CodeSpec[*pc].format & JOF_TYPESET) {
|
||||
double *counter = &counts.get(hasTypeBarriers(pc)
|
||||
? OpcodeCounts::ACCESS_BARRIER
|
||||
: OpcodeCounts::ACCESS_NOBARRIER);
|
||||
masm.bumpCounter(counter, reg);
|
||||
double *count = &counts.get(hasTypeBarriers(pc)
|
||||
? PCCounts::ACCESS_BARRIER
|
||||
: PCCounts::ACCESS_NOBARRIER);
|
||||
masm.bumpCount(count, reg);
|
||||
}
|
||||
|
||||
/* Reload the base register's original value. */
|
||||
|
@ -3399,16 +3396,16 @@ mjit::Compiler::updatePCTypes(jsbytecode *pc, FrameEntry *fe)
|
|||
}
|
||||
|
||||
void
|
||||
mjit::Compiler::updateArithCounters(jsbytecode *pc, FrameEntry *fe,
|
||||
JSValueType firstUseType, JSValueType secondUseType)
|
||||
mjit::Compiler::updateArithCounts(jsbytecode *pc, FrameEntry *fe,
|
||||
JSValueType firstUseType, JSValueType secondUseType)
|
||||
{
|
||||
JS_ASSERT(script->pcCounters);
|
||||
JS_ASSERT(script->scriptCounts);
|
||||
|
||||
RegisterID reg = Registers::ReturnReg;
|
||||
masm.push(reg);
|
||||
|
||||
/*
|
||||
* What counter we bump for arithmetic expressions depend on the
|
||||
* What count we bump for arithmetic expressions depend on the
|
||||
* known types of its operands.
|
||||
*
|
||||
* ARITH_INT: operands are known ints, result is int
|
||||
|
@ -3418,76 +3415,76 @@ mjit::Compiler::updateArithCounters(jsbytecode *pc, FrameEntry *fe,
|
|||
* ARITH_UNKNOWN: operands are polymorphic
|
||||
*/
|
||||
|
||||
OpcodeCounts::ArithCounts counter;
|
||||
PCCounts::ArithCounts count;
|
||||
if (firstUseType == JSVAL_TYPE_INT32 && secondUseType == JSVAL_TYPE_INT32 &&
|
||||
(!fe || fe->isNotType(JSVAL_TYPE_DOUBLE))) {
|
||||
counter = OpcodeCounts::ARITH_INT;
|
||||
count = PCCounts::ARITH_INT;
|
||||
} else if (firstUseType == JSVAL_TYPE_INT32 || firstUseType == JSVAL_TYPE_DOUBLE ||
|
||||
secondUseType == JSVAL_TYPE_INT32 || secondUseType == JSVAL_TYPE_DOUBLE) {
|
||||
counter = OpcodeCounts::ARITH_DOUBLE;
|
||||
count = PCCounts::ARITH_DOUBLE;
|
||||
} else if (firstUseType != JSVAL_TYPE_UNKNOWN && secondUseType != JSVAL_TYPE_UNKNOWN &&
|
||||
(!fe || fe->isTypeKnown())) {
|
||||
counter = OpcodeCounts::ARITH_OTHER;
|
||||
count = PCCounts::ARITH_OTHER;
|
||||
} else {
|
||||
counter = OpcodeCounts::ARITH_UNKNOWN;
|
||||
count = PCCounts::ARITH_UNKNOWN;
|
||||
}
|
||||
|
||||
masm.bumpCounter(&script->getCounts(pc).get(counter), reg);
|
||||
masm.bumpCount(&script->getPCCounts(pc).get(count), reg);
|
||||
masm.pop(reg);
|
||||
}
|
||||
|
||||
void
|
||||
mjit::Compiler::updateElemCounters(jsbytecode *pc, FrameEntry *obj, FrameEntry *id)
|
||||
mjit::Compiler::updateElemCounts(jsbytecode *pc, FrameEntry *obj, FrameEntry *id)
|
||||
{
|
||||
JS_ASSERT(script->pcCounters);
|
||||
JS_ASSERT(script->scriptCounts);
|
||||
|
||||
RegisterID reg = Registers::ReturnReg;
|
||||
masm.push(reg);
|
||||
|
||||
OpcodeCounts counts = script->getCounts(pc);
|
||||
PCCounts counts = script->getPCCounts(pc);
|
||||
|
||||
OpcodeCounts::ElementCounts counter;
|
||||
PCCounts::ElementCounts count;
|
||||
if (id->isTypeKnown()) {
|
||||
switch (id->getKnownType()) {
|
||||
case JSVAL_TYPE_INT32: counter = OpcodeCounts::ELEM_ID_INT; break;
|
||||
case JSVAL_TYPE_DOUBLE: counter = OpcodeCounts::ELEM_ID_DOUBLE; break;
|
||||
default: counter = OpcodeCounts::ELEM_ID_OTHER; break;
|
||||
case JSVAL_TYPE_INT32: count = PCCounts::ELEM_ID_INT; break;
|
||||
case JSVAL_TYPE_DOUBLE: count = PCCounts::ELEM_ID_DOUBLE; break;
|
||||
default: count = PCCounts::ELEM_ID_OTHER; break;
|
||||
}
|
||||
} else {
|
||||
counter = OpcodeCounts::ELEM_ID_UNKNOWN;
|
||||
count = PCCounts::ELEM_ID_UNKNOWN;
|
||||
}
|
||||
masm.bumpCounter(&counts.get(counter), reg);
|
||||
masm.bumpCount(&counts.get(count), reg);
|
||||
|
||||
if (obj->mightBeType(JSVAL_TYPE_OBJECT)) {
|
||||
types::TypeSet *types = frame.extra(obj).types;
|
||||
if (types && !types->hasObjectFlags(cx, types::OBJECT_FLAG_NON_TYPED_ARRAY) &&
|
||||
types->getTypedArrayType(cx) != TypedArray::TYPE_MAX) {
|
||||
counter = OpcodeCounts::ELEM_OBJECT_TYPED;
|
||||
count = PCCounts::ELEM_OBJECT_TYPED;
|
||||
} else if (types && !types->hasObjectFlags(cx, types::OBJECT_FLAG_NON_DENSE_ARRAY)) {
|
||||
if (!types->hasObjectFlags(cx, types::OBJECT_FLAG_NON_PACKED_ARRAY))
|
||||
counter = OpcodeCounts::ELEM_OBJECT_PACKED;
|
||||
count = PCCounts::ELEM_OBJECT_PACKED;
|
||||
else
|
||||
counter = OpcodeCounts::ELEM_OBJECT_DENSE;
|
||||
count = PCCounts::ELEM_OBJECT_DENSE;
|
||||
} else {
|
||||
counter = OpcodeCounts::ELEM_OBJECT_OTHER;
|
||||
count = PCCounts::ELEM_OBJECT_OTHER;
|
||||
}
|
||||
masm.bumpCounter(&counts.get(counter), reg);
|
||||
masm.bumpCount(&counts.get(count), reg);
|
||||
} else {
|
||||
masm.bumpCounter(&counts.get(OpcodeCounts::ELEM_OBJECT_OTHER), reg);
|
||||
masm.bumpCount(&counts.get(PCCounts::ELEM_OBJECT_OTHER), reg);
|
||||
}
|
||||
|
||||
masm.pop(reg);
|
||||
}
|
||||
|
||||
void
|
||||
mjit::Compiler::bumpPropCounter(jsbytecode *pc, int counter)
|
||||
mjit::Compiler::bumpPropCount(jsbytecode *pc, int count)
|
||||
{
|
||||
/* Don't accumulate counts for property ops fused with other ops. */
|
||||
if (!(js_CodeSpec[*pc].format & JOF_PROP))
|
||||
return;
|
||||
RegisterID reg = Registers::ReturnReg;
|
||||
masm.push(reg);
|
||||
masm.bumpCounter(&script->getCounts(pc).get(counter), reg);
|
||||
masm.bumpCount(&script->getPCCounts(pc).get(count), reg);
|
||||
masm.pop(reg);
|
||||
}
|
||||
|
||||
|
@ -3828,7 +3825,7 @@ mjit::Compiler::emitStubCall(void *ptr, DataLabelPtr *pinline)
|
|||
{
|
||||
JaegerSpew(JSpew_Insns, " ---- CALLING STUB ---- \n");
|
||||
|
||||
masm.bumpStubCounter(script, PC, Registers::tempCallReg());
|
||||
masm.bumpStubCount(script, PC, Registers::tempCallReg());
|
||||
|
||||
Call cl = masm.fallibleVMCall(cx->typeInferenceEnabled(),
|
||||
ptr, outerPC(), pinline, frame.totalDepth());
|
||||
|
@ -4809,8 +4806,8 @@ mjit::Compiler::jsop_setprop_slow(PropertyName *name)
|
|||
INLINE_STUBCALL(STRICT_VARIANT(stubs::SetName), REJOIN_FALLTHROUGH);
|
||||
JS_STATIC_ASSERT(JSOP_SETNAME_LENGTH == JSOP_SETPROP_LENGTH);
|
||||
frame.shimmy(1);
|
||||
if (script->pcCounters)
|
||||
bumpPropCounter(PC, OpcodeCounts::PROP_OTHER);
|
||||
if (script->scriptCounts)
|
||||
bumpPropCount(PC, PCCounts::PROP_OTHER);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -4829,8 +4826,8 @@ mjit::Compiler::jsop_getprop_slow(PropertyName *name, bool forPrototype)
|
|||
frame.pop();
|
||||
frame.pushSynced(JSVAL_TYPE_UNKNOWN);
|
||||
|
||||
if (script->pcCounters)
|
||||
bumpPropCounter(PC, OpcodeCounts::PROP_OTHER);
|
||||
if (script->scriptCounts)
|
||||
bumpPropCount(PC, PCCounts::PROP_OTHER);
|
||||
}
|
||||
|
||||
#ifdef JS_MONOIC
|
||||
|
@ -4897,8 +4894,8 @@ mjit::Compiler::jsop_getprop(PropertyName *name, JSValueType knownType,
|
|||
frame.learnType(fe, JSVAL_TYPE_INT32, false);
|
||||
frame.pop();
|
||||
frame.pushCopyOf(fe);
|
||||
if (script->pcCounters)
|
||||
bumpPropCounter(PC, OpcodeCounts::PROP_STATIC);
|
||||
if (script->scriptCounts)
|
||||
bumpPropCount(PC, PCCounts::PROP_STATIC);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -4927,8 +4924,8 @@ mjit::Compiler::jsop_getprop(PropertyName *name, JSValueType knownType,
|
|||
masm.loadPtr(Address(reg, JSObject::offsetOfElements()), result);
|
||||
masm.load32(Address(result, ObjectElements::offsetOfLength()), result);
|
||||
frame.pushTypedPayload(JSVAL_TYPE_INT32, result);
|
||||
if (script->pcCounters)
|
||||
bumpPropCounter(PC, OpcodeCounts::PROP_DEFINITE);
|
||||
if (script->scriptCounts)
|
||||
bumpPropCount(PC, PCCounts::PROP_DEFINITE);
|
||||
if (!isObject)
|
||||
stubcc.rejoin(Changes(1));
|
||||
return true;
|
||||
|
@ -4953,8 +4950,8 @@ mjit::Compiler::jsop_getprop(PropertyName *name, JSValueType knownType,
|
|||
frame.pop();
|
||||
masm.loadPayload(Address(reg, TypedArray::lengthOffset()), reg);
|
||||
frame.pushTypedPayload(JSVAL_TYPE_INT32, reg);
|
||||
if (script->pcCounters)
|
||||
bumpPropCounter(PC, OpcodeCounts::PROP_DEFINITE);
|
||||
if (script->scriptCounts)
|
||||
bumpPropCount(PC, PCCounts::PROP_DEFINITE);
|
||||
if (!isObject)
|
||||
stubcc.rejoin(Changes(1));
|
||||
return true;
|
||||
|
@ -4967,8 +4964,8 @@ mjit::Compiler::jsop_getprop(PropertyName *name, JSValueType knownType,
|
|||
if (types->isLazyArguments(cx)) {
|
||||
frame.pop();
|
||||
frame.pushWord(Address(JSFrameReg, StackFrame::offsetOfNumActual()), JSVAL_TYPE_INT32);
|
||||
if (script->pcCounters)
|
||||
bumpPropCounter(PC, OpcodeCounts::PROP_DEFINITE);
|
||||
if (script->scriptCounts)
|
||||
bumpPropCount(PC, PCCounts::PROP_DEFINITE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -4991,8 +4988,8 @@ mjit::Compiler::jsop_getprop(PropertyName *name, JSValueType knownType,
|
|||
frame.pop();
|
||||
frame.push(ObjectValue(*singleton));
|
||||
|
||||
if (script->pcCounters && cx->typeInferenceEnabled())
|
||||
bumpPropCounter(PC, OpcodeCounts::PROP_STATIC);
|
||||
if (script->scriptCounts && cx->typeInferenceEnabled())
|
||||
bumpPropCount(PC, PCCounts::PROP_STATIC);
|
||||
|
||||
if (testObject)
|
||||
stubcc.rejoin(Changes(1));
|
||||
|
@ -5008,8 +5005,8 @@ mjit::Compiler::jsop_getprop(PropertyName *name, JSValueType knownType,
|
|||
frame.learnType(fe, knownType, false);
|
||||
frame.pop();
|
||||
frame.pushCopyOf(fe);
|
||||
if (script->pcCounters)
|
||||
bumpPropCounter(PC, OpcodeCounts::PROP_STATIC);
|
||||
if (script->scriptCounts)
|
||||
bumpPropCount(PC, PCCounts::PROP_STATIC);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -5056,8 +5053,8 @@ mjit::Compiler::jsop_getprop(PropertyName *name, JSValueType knownType,
|
|||
RegisterID reg = frame.tempRegForData(top);
|
||||
frame.pop();
|
||||
|
||||
if (script->pcCounters)
|
||||
bumpPropCounter(PC, OpcodeCounts::PROP_DEFINITE);
|
||||
if (script->scriptCounts)
|
||||
bumpPropCount(PC, PCCounts::PROP_DEFINITE);
|
||||
|
||||
Address address(reg, JSObject::getFixedSlotOffset(slot));
|
||||
BarrierState barrier = pushAddressMaybeBarrier(address, knownType, false);
|
||||
|
@ -5075,8 +5072,8 @@ mjit::Compiler::jsop_getprop(PropertyName *name, JSValueType knownType,
|
|||
return true;
|
||||
}
|
||||
|
||||
if (script->pcCounters)
|
||||
bumpPropCounter(PC, OpcodeCounts::PROP_OTHER);
|
||||
if (script->scriptCounts)
|
||||
bumpPropCount(PC, PCCounts::PROP_OTHER);
|
||||
|
||||
/*
|
||||
* These two must be loaded first. The objReg because the string path
|
||||
|
@ -5437,8 +5434,8 @@ mjit::Compiler::jsop_getprop_dispatch(PropertyName *name)
|
|||
frame.pop();
|
||||
frame.pushTypedPayload(JSVAL_TYPE_OBJECT, pushreg);
|
||||
|
||||
if (script->pcCounters)
|
||||
bumpPropCounter(PC, OpcodeCounts::PROP_DEFINITE);
|
||||
if (script->scriptCounts)
|
||||
bumpPropCount(PC, PCCounts::PROP_DEFINITE);
|
||||
|
||||
stubcc.rejoin(Changes(2));
|
||||
return true;
|
||||
|
@ -5540,14 +5537,14 @@ mjit::Compiler::jsop_setprop(PropertyName *name, bool popGuaranteed)
|
|||
frame.shimmy(1);
|
||||
if (!isObject)
|
||||
stubcc.rejoin(Changes(1));
|
||||
if (script->pcCounters)
|
||||
bumpPropCounter(PC, OpcodeCounts::PROP_DEFINITE);
|
||||
if (script->scriptCounts)
|
||||
bumpPropCount(PC, PCCounts::PROP_DEFINITE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (script->pcCounters)
|
||||
bumpPropCounter(PC, OpcodeCounts::PROP_OTHER);
|
||||
if (script->scriptCounts)
|
||||
bumpPropCount(PC, PCCounts::PROP_OTHER);
|
||||
|
||||
JSOp op = JSOp(*PC);
|
||||
|
||||
|
|
|
@ -564,12 +564,12 @@ private:
|
|||
CompileStatus finishThisUp();
|
||||
CompileStatus pushActiveFrame(JSScript *script, uint32_t argc);
|
||||
void popActiveFrame();
|
||||
void updatePCCounters(jsbytecode *pc, Label *start, bool *updated);
|
||||
void updatePCCounts(jsbytecode *pc, Label *start, bool *updated);
|
||||
void updatePCTypes(jsbytecode *pc, FrameEntry *fe);
|
||||
void updateArithCounters(jsbytecode *pc, FrameEntry *fe,
|
||||
void updateArithCounts(jsbytecode *pc, FrameEntry *fe,
|
||||
JSValueType firstUseType, JSValueType secondUseType);
|
||||
void updateElemCounters(jsbytecode *pc, FrameEntry *obj, FrameEntry *id);
|
||||
void bumpPropCounter(jsbytecode *pc, int counter);
|
||||
void updateElemCounts(jsbytecode *pc, FrameEntry *obj, FrameEntry *id);
|
||||
void bumpPropCount(jsbytecode *pc, int count);
|
||||
|
||||
/* Analysis helpers. */
|
||||
CompileStatus prepareInferenceTypes(JSScript *script, ActiveFrame *a);
|
||||
|
|
|
@ -1362,7 +1362,6 @@ JITScript::destroyChunk(JSContext *cx, unsigned chunkIndex, bool resetUses)
|
|||
|
||||
invokeEntry = NULL;
|
||||
fastEntry = NULL;
|
||||
arityCheckEntry = NULL;
|
||||
argsCheckEntry = NULL;
|
||||
|
||||
if (script->jitNormal == this)
|
||||
|
|
|
@ -806,7 +806,6 @@ struct JITScript
|
|||
|
||||
void *invokeEntry; /* invoke address */
|
||||
void *fastEntry; /* cached entry, fastest */
|
||||
void *arityCheckEntry; /* arity check address */
|
||||
void *argsCheckEntry; /* arguments check address */
|
||||
|
||||
/* List of inline caches jumping to the fastEntry. */
|
||||
|
|
|
@ -626,7 +626,7 @@ class CallCompiler : public BaseCompiler
|
|||
masm.storePtr(ImmPtr((void *) ic.frameSize.rejoinState(f.pc(), false)),
|
||||
FrameAddress(offsetof(VMFrame, stubRejoin)));
|
||||
|
||||
masm.bumpStubCounter(f.script(), f.pc(), Registers::tempCallReg());
|
||||
masm.bumpStubCount(f.script(), f.pc(), Registers::tempCallReg());
|
||||
|
||||
/* Try and compile. On success we get back the nmap pointer. */
|
||||
void *compilePtr = JS_FUNC_TO_DATA_PTR(void *, stubs::CompileFunction);
|
||||
|
@ -850,7 +850,7 @@ class CallCompiler : public BaseCompiler
|
|||
|
||||
/* N.B. After this call, the frame will have a dynamic frame size. */
|
||||
if (ic.frameSize.isDynamic()) {
|
||||
masm.bumpStubCounter(f.script(), f.pc(), Registers::tempCallReg());
|
||||
masm.bumpStubCount(f.script(), f.pc(), Registers::tempCallReg());
|
||||
masm.fallibleVMCall(cx->typeInferenceEnabled(),
|
||||
JS_FUNC_TO_DATA_PTR(void *, ic::SplatApplyArgs),
|
||||
f.regs.pc, NULL, initialFrameDepth);
|
||||
|
@ -858,7 +858,7 @@ class CallCompiler : public BaseCompiler
|
|||
|
||||
Registers tempRegs = Registers::tempCallRegMask();
|
||||
RegisterID t0 = tempRegs.takeAnyReg().reg();
|
||||
masm.bumpStubCounter(f.script(), f.pc(), t0);
|
||||
masm.bumpStubCount(f.script(), f.pc(), t0);
|
||||
|
||||
int32_t storeFrameDepth = ic.frameSize.isStatic() ? initialFrameDepth : -1;
|
||||
masm.setupFallibleABICall(cx->typeInferenceEnabled(), f.regs.pc, storeFrameDepth);
|
||||
|
|
|
@ -1078,7 +1078,7 @@ class GetPropCompiler : public PICStubCompiler
|
|||
}
|
||||
|
||||
RegisterID t0 = tempRegs.takeAnyReg().reg();
|
||||
masm.bumpStubCounter(f.script(), f.pc(), t0);
|
||||
masm.bumpStubCount(f.script(), f.pc(), t0);
|
||||
|
||||
/*
|
||||
* Initialize vp, which is either a slot in the object (the holder,
|
||||
|
|
|
@ -179,7 +179,7 @@ JSC::MacroAssembler::Call
|
|||
StubCompiler::emitStubCall(void *ptr, RejoinState rejoin, Uses uses, int32_t slots)
|
||||
{
|
||||
JaegerSpew(JSpew_Insns, " ---- BEGIN SLOW CALL CODE ---- \n");
|
||||
masm.bumpStubCounter(cc.script, cc.PC, Registers::tempCallReg());
|
||||
masm.bumpStubCount(cc.script, cc.PC, Registers::tempCallReg());
|
||||
DataLabelPtr inlinePatch;
|
||||
Call cl = masm.fallibleVMCall(cx->typeInferenceEnabled(),
|
||||
ptr, cc.outerPC(), &inlinePatch, slots);
|
||||
|
|
|
@ -2115,6 +2115,29 @@ Debugger::findScripts(JSContext *cx, unsigned argc, Value *vp)
|
|||
return true;
|
||||
}
|
||||
|
||||
JSBool
|
||||
Debugger::wrap(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
REQUIRE_ARGC("Debugger.prototype.wrap", 1);
|
||||
THIS_DEBUGGER(cx, argc, vp, "wrap", args, dbg);
|
||||
|
||||
/* Wrapping a non-object returns the value unchanged. */
|
||||
if (!args[0].isObject()) {
|
||||
args.rval() = args[0];
|
||||
return true;
|
||||
}
|
||||
|
||||
JSObject *obj = dbg->unwrapDebuggeeArgument(cx, args[0]);
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
args.rval() = args[0];
|
||||
if (!dbg->wrapDebuggeeValue(cx, &args.rval()))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
JSPropertySpec Debugger::properties[] = {
|
||||
JS_PSGS("enabled", Debugger::getEnabled, Debugger::setEnabled, 0),
|
||||
JS_PSGS("onDebuggerStatement", Debugger::getOnDebuggerStatement,
|
||||
|
@ -2136,6 +2159,7 @@ JSFunctionSpec Debugger::methods[] = {
|
|||
JS_FN("getNewestFrame", Debugger::getNewestFrame, 0, 0),
|
||||
JS_FN("clearAllBreakpoints", Debugger::clearAllBreakpoints, 1, 0),
|
||||
JS_FN("findScripts", Debugger::findScripts, 1, 0),
|
||||
JS_FN("wrap", Debugger::wrap, 1, 0),
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
|
|
|
@ -201,6 +201,7 @@ class Debugger {
|
|||
static JSBool getNewestFrame(JSContext *cx, unsigned argc, Value *vp);
|
||||
static JSBool clearAllBreakpoints(JSContext *cx, unsigned argc, Value *vp);
|
||||
static JSBool findScripts(JSContext *cx, unsigned argc, Value *vp);
|
||||
static JSBool wrap(JSContext *cx, unsigned argc, Value *vp);
|
||||
static JSBool construct(JSContext *cx, unsigned argc, Value *vp);
|
||||
static JSPropertySpec properties[];
|
||||
static JSFunctionSpec methods[];
|
||||
|
|
|
@ -99,7 +99,7 @@ js_PutCallObject(StackFrame *fp)
|
|||
* caches the return value in the slot, so we can't assert that
|
||||
* it's undefined.
|
||||
*/
|
||||
uint32_t nclosed = script->nClosedArgs;
|
||||
uint32_t nclosed = script->nClosedArgs();
|
||||
for (uint32_t i = 0; i < nclosed; i++) {
|
||||
uint32_t e = script->getClosedArg(i);
|
||||
#ifdef JS_GC_ZEAL
|
||||
|
@ -109,7 +109,7 @@ js_PutCallObject(StackFrame *fp)
|
|||
#endif
|
||||
}
|
||||
|
||||
nclosed = script->nClosedVars;
|
||||
nclosed = script->nClosedVars();
|
||||
for (uint32_t i = 0; i < nclosed; i++) {
|
||||
uint32_t e = script->getClosedVar(i);
|
||||
#ifdef JS_GC_ZEAL
|
||||
|
|
|
@ -103,6 +103,9 @@
|
|||
#include "nsRenderingContext.h"
|
||||
#include "nsIScriptableRegion.h"
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
#include "nsAccessibilityService.h"
|
||||
#endif
|
||||
#ifdef IBMBIDI
|
||||
#include "nsBidiUtils.h"
|
||||
#endif
|
||||
|
@ -519,6 +522,11 @@ nsTreeBodyFrame::SetView(nsITreeView * aView)
|
|||
|
||||
nsIContent *treeContent = GetBaseElement();
|
||||
if (treeContent) {
|
||||
#ifdef ACCESSIBILITY
|
||||
nsAccessibilityService* accService = nsIPresShell::AccService();
|
||||
if (accService)
|
||||
accService->TreeViewChanged(PresContext()->GetPresShell(), treeContent, mView);
|
||||
#endif
|
||||
FireDOMEvent(NS_LITERAL_STRING("TreeViewChanged"), treeContent);
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,6 @@ import org.mozilla.gecko.gfx.IntSize;
|
|||
import org.mozilla.gecko.gfx.Layer;
|
||||
import org.mozilla.gecko.gfx.LayerController;
|
||||
import org.mozilla.gecko.gfx.LayerView;
|
||||
import org.mozilla.gecko.gfx.PlaceholderLayerClient;
|
||||
import org.mozilla.gecko.gfx.RectUtils;
|
||||
import org.mozilla.gecko.gfx.SurfaceTextureLayer;
|
||||
import org.mozilla.gecko.gfx.ViewportMetrics;
|
||||
|
@ -112,10 +111,7 @@ abstract public class GeckoApp
|
|||
public static final String ACTION_LOAD = "org.mozilla.gecko.LOAD";
|
||||
public static final String ACTION_UPDATE = "org.mozilla.gecko.UPDATE";
|
||||
public static final String ACTION_INIT_PW = "org.mozilla.gecko.INIT_PW";
|
||||
public static final String SAVED_STATE_URI = "uri";
|
||||
public static final String SAVED_STATE_TITLE = "title";
|
||||
public static final String SAVED_STATE_VIEWPORT = "viewport";
|
||||
public static final String SAVED_STATE_SCREEN = "screen";
|
||||
public static final String SAVED_STATE_SESSION = "session";
|
||||
|
||||
StartupMode mStartupMode = null;
|
||||
|
@ -142,15 +138,11 @@ abstract public class GeckoApp
|
|||
public Favicons mFavicons;
|
||||
|
||||
private static LayerController mLayerController;
|
||||
private static PlaceholderLayerClient mPlaceholderLayerClient;
|
||||
private static GeckoLayerClient mLayerClient;
|
||||
private AboutHomeContent mAboutHomeContent;
|
||||
private static AbsoluteLayout mPluginContainer;
|
||||
|
||||
public String mLastTitle;
|
||||
public String mLastSnapshotUri;
|
||||
public String mLastViewport;
|
||||
public byte[] mLastScreen;
|
||||
private int mOwnActivityDepth = 0;
|
||||
private boolean mRestoreSession = false;
|
||||
private boolean mInitialized = false;
|
||||
|
@ -546,54 +538,11 @@ abstract public class GeckoApp
|
|||
if (outState == null)
|
||||
outState = new Bundle();
|
||||
|
||||
new SessionSnapshotRunnable(null).run();
|
||||
|
||||
outState.putString(SAVED_STATE_TITLE, mLastTitle);
|
||||
outState.putString(SAVED_STATE_VIEWPORT, mLastViewport);
|
||||
outState.putByteArray(SAVED_STATE_SCREEN, mLastScreen);
|
||||
outState.putBoolean(SAVED_STATE_SESSION, true);
|
||||
}
|
||||
|
||||
public class SessionSnapshotRunnable implements Runnable {
|
||||
Tab mThumbnailTab;
|
||||
SessionSnapshotRunnable(Tab thumbnailTab) {
|
||||
mThumbnailTab = thumbnailTab;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
if (mLayerClient == null)
|
||||
return;
|
||||
|
||||
synchronized (mLayerClient) {
|
||||
if (!Tabs.getInstance().isSelectedTab(mThumbnailTab))
|
||||
return;
|
||||
|
||||
HistoryEntry lastHistoryEntry = mThumbnailTab.getLastHistoryEntry();
|
||||
if (lastHistoryEntry == null)
|
||||
return;
|
||||
|
||||
ViewportMetrics viewportMetrics = mLayerClient.getGeckoViewportMetrics();
|
||||
// If we don't have viewport metrics, the screenshot won't be right so bail
|
||||
if (viewportMetrics == null)
|
||||
return;
|
||||
|
||||
String viewportJSON = viewportMetrics.toJSON();
|
||||
// If the title, uri and viewport haven't changed, the old screenshot is probably valid
|
||||
// Ordering of .equals() below is important since mLast* variables may be null
|
||||
if (viewportJSON.equals(mLastViewport) &&
|
||||
lastHistoryEntry.mTitle.equals(mLastTitle) &&
|
||||
lastHistoryEntry.mUri.equals(mLastSnapshotUri))
|
||||
return;
|
||||
|
||||
mLastViewport = viewportJSON;
|
||||
mLastTitle = lastHistoryEntry.mTitle;
|
||||
mLastSnapshotUri = lastHistoryEntry.mUri;
|
||||
getAndProcessThumbnailForTab(mThumbnailTab, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void getAndProcessThumbnailForTab(final Tab tab, boolean forceBigSceenshot) {
|
||||
void getAndProcessThumbnailForTab(final Tab tab) {
|
||||
boolean isSelectedTab = Tabs.getInstance().isSelectedTab(tab);
|
||||
final Bitmap bitmap = isSelectedTab ? mLayerClient.getBitmap() : null;
|
||||
|
||||
|
@ -609,12 +558,10 @@ abstract public class GeckoApp
|
|||
return;
|
||||
}
|
||||
|
||||
mLastScreen = null;
|
||||
View view = mLayerController.getView();
|
||||
int sw = forceBigSceenshot ? view.getWidth() : tab.getMinScreenshotWidth();
|
||||
int sh = forceBigSceenshot ? view.getHeight(): tab.getMinScreenshotHeight();
|
||||
int dw = forceBigSceenshot ? sw : tab.getThumbnailWidth();
|
||||
int dh = forceBigSceenshot ? sh : tab.getThumbnailHeight();
|
||||
int sw = tab.getMinScreenshotWidth();
|
||||
int sh = tab.getMinScreenshotHeight();
|
||||
int dw = tab.getThumbnailWidth();
|
||||
int dh = tab.getThumbnailHeight();
|
||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createScreenshotEvent(tab.getId(), sw, sh, dw, dh));
|
||||
}
|
||||
}
|
||||
|
@ -626,7 +573,6 @@ abstract public class GeckoApp
|
|||
bitmap.compress(Bitmap.CompressFormat.PNG, 0, bos);
|
||||
compressed = bos.toByteArray();
|
||||
}
|
||||
mLastScreen = compressed;
|
||||
}
|
||||
|
||||
if ("about:home".equals(thumbnailTab.getURL())) {
|
||||
|
@ -1254,11 +1200,6 @@ abstract public class GeckoApp
|
|||
Tabs.getInstance().notifyListeners(tab, Tabs.TabEvents.STOP);
|
||||
}
|
||||
});
|
||||
|
||||
if (Tabs.getInstance().isSelectedTab(tab)) {
|
||||
Runnable r = new SessionSnapshotRunnable(tab);
|
||||
GeckoAppShell.getHandler().postDelayed(r, 500);
|
||||
}
|
||||
}
|
||||
|
||||
void handleShowToast(final String message, final String duration) {
|
||||
|
@ -1619,8 +1560,6 @@ abstract public class GeckoApp
|
|||
Log.w(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - onCreate");
|
||||
if (savedInstanceState != null) {
|
||||
mLastTitle = savedInstanceState.getString(SAVED_STATE_TITLE);
|
||||
mLastViewport = savedInstanceState.getString(SAVED_STATE_VIEWPORT);
|
||||
mLastScreen = savedInstanceState.getByteArray(SAVED_STATE_SCREEN);
|
||||
mRestoreSession = savedInstanceState.getBoolean(SAVED_STATE_SESSION);
|
||||
}
|
||||
|
||||
|
@ -1663,8 +1602,6 @@ abstract public class GeckoApp
|
|||
if (m.find()) {
|
||||
mProfile = GeckoProfile.get(this, m.group(1));
|
||||
mLastTitle = null;
|
||||
mLastViewport = null;
|
||||
mLastScreen = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1748,11 +1685,8 @@ abstract public class GeckoApp
|
|||
mLayerController = new LayerController(this);
|
||||
View v = mLayerController.getView();
|
||||
|
||||
mPlaceholderLayerClient = new PlaceholderLayerClient(mLayerController, mLastViewport);
|
||||
if (!mPlaceholderLayerClient.loadScreenshot()) {
|
||||
// Instead of flickering the checkerboard, show a white screen until Gecko paints
|
||||
v.setBackgroundColor(Color.WHITE);
|
||||
}
|
||||
// Instead of flickering the checkerboard, show a white screen until Gecko paints
|
||||
v.setBackgroundColor(Color.WHITE);
|
||||
|
||||
mGeckoLayout.addView(v, 0);
|
||||
}
|
||||
|
@ -2041,9 +1975,6 @@ abstract public class GeckoApp
|
|||
{
|
||||
Log.i(LOGTAG, "pause");
|
||||
|
||||
Runnable r = new SessionSnapshotRunnable(null);
|
||||
GeckoAppShell.getHandler().post(r);
|
||||
|
||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createPauseEvent(mOwnActivityDepth));
|
||||
// The user is navigating away from this activity, but nothing
|
||||
// has come to the foreground yet; for Gecko, we may want to
|
||||
|
@ -2823,9 +2754,6 @@ abstract public class GeckoApp
|
|||
|
||||
|
||||
private void connectGeckoLayerClient() {
|
||||
if (mPlaceholderLayerClient != null)
|
||||
mPlaceholderLayerClient.destroy();
|
||||
|
||||
LayerController layerController = getLayerController();
|
||||
layerController.setLayerClient(mLayerClient);
|
||||
}
|
||||
|
|
|
@ -135,7 +135,6 @@ FENNEC_JAVA_FILES = \
|
|||
gfx/LayerView.java \
|
||||
gfx/NinePatchTileLayer.java \
|
||||
gfx/PanningPerfAPI.java \
|
||||
gfx/PlaceholderLayerClient.java \
|
||||
gfx/PointUtils.java \
|
||||
gfx/RectUtils.java \
|
||||
gfx/ScrollbarLayer.java \
|
||||
|
|
|
@ -310,7 +310,7 @@ public class Tabs implements GeckoEventListener {
|
|||
final Tab tab = iterator.next();
|
||||
GeckoAppShell.getHandler().post(new Runnable() {
|
||||
public void run() {
|
||||
GeckoApp.mAppContext.getAndProcessThumbnailForTab(tab, false);
|
||||
GeckoApp.mAppContext.getAndProcessThumbnailForTab(tab);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -211,8 +211,12 @@ public class GeckoLayerClient implements GeckoEventResponder,
|
|||
mLayerController.abortPanZoomAnimation();
|
||||
break;
|
||||
case PAGE_SIZE:
|
||||
// adjust the page dimensions to account for differences in zoom
|
||||
// between the rendered content (which is what Gecko tells us)
|
||||
// and our zoom level (which may have diverged).
|
||||
float scaleFactor = oldMetrics.zoomFactor / messageMetrics.getZoomFactor();
|
||||
newMetrics = new ViewportMetrics(oldMetrics);
|
||||
newMetrics.setPageSize(messageMetrics.getPageSize());
|
||||
newMetrics.setPageSize(messageMetrics.getPageSize().scale(scaleFactor));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,129 +0,0 @@
|
|||
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Android code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009-2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Patrick Walton <pcwalton@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.gecko.gfx;
|
||||
|
||||
import org.mozilla.gecko.GeckoApp;
|
||||
import org.mozilla.gecko.GeckoAppShell;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.util.Log;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* A stand-in for Gecko that renders cached content of the previous page. We use this until Gecko
|
||||
* is up, then we hand off control to it.
|
||||
*/
|
||||
public class PlaceholderLayerClient {
|
||||
private static final String LOGTAG = "PlaceholderLayerClient";
|
||||
|
||||
private final LayerController mLayerController;
|
||||
|
||||
private ViewportMetrics mViewport;
|
||||
private boolean mViewportUnknown;
|
||||
private int mWidth, mHeight, mFormat;
|
||||
private ByteBuffer mBuffer;
|
||||
|
||||
public PlaceholderLayerClient(LayerController controller, String lastViewport) {
|
||||
mLayerController = controller;
|
||||
|
||||
mViewportUnknown = true;
|
||||
if (lastViewport != null) {
|
||||
try {
|
||||
JSONObject viewportObject = new JSONObject(lastViewport);
|
||||
mViewport = new ViewportMetrics(viewportObject);
|
||||
mViewportUnknown = false;
|
||||
} catch (JSONException e) {
|
||||
Log.e(LOGTAG, "Error parsing saved viewport!");
|
||||
mViewport = new ViewportMetrics();
|
||||
}
|
||||
} else {
|
||||
mViewport = new ViewportMetrics();
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
if (mBuffer != null) {
|
||||
GeckoAppShell.freeDirectBuffer(mBuffer);
|
||||
mBuffer = null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean loadScreenshot() {
|
||||
if (GeckoApp.mAppContext.mLastScreen == null)
|
||||
return false;
|
||||
|
||||
Bitmap bitmap = BitmapFactory.decodeStream(new ByteArrayInputStream(GeckoApp.mAppContext.mLastScreen));
|
||||
if (bitmap == null)
|
||||
return false;
|
||||
|
||||
Bitmap.Config config = bitmap.getConfig();
|
||||
|
||||
mWidth = bitmap.getWidth();
|
||||
mHeight = bitmap.getHeight();
|
||||
mFormat = CairoUtils.bitmapConfigToCairoFormat(config);
|
||||
|
||||
int bpp = CairoUtils.bitsPerPixelForCairoFormat(mFormat) / 8;
|
||||
mBuffer = GeckoAppShell.allocateDirectBuffer(mWidth * mHeight * bpp);
|
||||
|
||||
bitmap.copyPixelsToBuffer(mBuffer.asIntBuffer());
|
||||
|
||||
if (mViewportUnknown) {
|
||||
mViewport.setPageSize(new FloatSize(mWidth, mHeight));
|
||||
mLayerController.setPageSize(mViewport.getPageSize());
|
||||
}
|
||||
|
||||
BufferedCairoImage image = new BufferedCairoImage(mBuffer, mWidth, mHeight, mFormat);
|
||||
SingleTileLayer tileLayer = new SingleTileLayer(image);
|
||||
|
||||
tileLayer.beginTransaction(); // calling thread irrelevant; nobody else has a ref to tileLayer yet
|
||||
try {
|
||||
Point origin = PointUtils.round(mViewport.getOrigin());
|
||||
tileLayer.setPosition(new Rect(origin.x, origin.y, origin.x + mWidth, origin.y + mHeight));
|
||||
} finally {
|
||||
tileLayer.endTransaction();
|
||||
}
|
||||
|
||||
mLayerController.setRoot(tileLayer);
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -534,6 +534,9 @@ public class PanZoomController
|
|||
mX.displace();
|
||||
mY.displace();
|
||||
PointF displacement = getDisplacement();
|
||||
if (FloatUtils.fuzzyEquals(displacement.x, 0.0f) && FloatUtils.fuzzyEquals(displacement.y, 0.0f)) {
|
||||
return;
|
||||
}
|
||||
if (! mSubscroller.scrollBy(displacement)) {
|
||||
synchronized (mController) {
|
||||
mController.scrollBy(displacement);
|
||||
|
|
|
@ -97,23 +97,6 @@ interface nsIApplicationCacheNamespace : nsISupports
|
|||
readonly attribute ACString data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback for asynchronized methods for nsIApplicationCache.
|
||||
*/
|
||||
[scriptable, uuid(062c8061-7c31-44a4-bd8d-302772e4a7eb)]
|
||||
interface nsIApplicationCacheAsyncCallback : nsISupports
|
||||
{
|
||||
const long APP_CACHE_REQUEST_SUCCESS = 0;
|
||||
const long APP_CACHE_REQUEST_ERROR = 1;
|
||||
|
||||
/**
|
||||
* Callback function with result code. It should be a nsresult.
|
||||
*
|
||||
* @param aState is an error code, one of APP_CACHE_REQUEST_*.
|
||||
*/
|
||||
void handleAsyncCompletion(in PRUint32 aState);
|
||||
};
|
||||
|
||||
/**
|
||||
* Application caches store resources for offline use. Each
|
||||
* application cache has a unique client ID for use with
|
||||
|
@ -204,11 +187,6 @@ interface nsIApplicationCache : nsISupports
|
|||
*/
|
||||
void discard();
|
||||
|
||||
/**
|
||||
* Discard this application cache in asynchronized.
|
||||
*/
|
||||
void discardAsync([optional] in nsIApplicationCacheAsyncCallback aCallback);
|
||||
|
||||
/**
|
||||
* Adds item types to a given entry.
|
||||
*/
|
||||
|
|
|
@ -59,10 +59,8 @@
|
|||
#include "nsIVariant.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
#include "mozIStoragePendingStatement.h"
|
||||
#include "mozIStorageService.h"
|
||||
#include "mozIStorageStatement.h"
|
||||
#include "mozIStorageStatementCallback.h"
|
||||
#include "mozIStorageFunction.h"
|
||||
#include "mozStorageHelper.h"
|
||||
|
||||
|
@ -135,11 +133,6 @@ class EvictionObserver
|
|||
nsOfflineCacheEvictionFunction *evictionFunction)
|
||||
: mDB(db), mEvictionFunction(evictionFunction)
|
||||
{
|
||||
if (mEvictionFunction->AddObserver() != 1) {
|
||||
// not first observer
|
||||
return;
|
||||
}
|
||||
|
||||
mDB->ExecuteSimpleSQL(
|
||||
NS_LITERAL_CSTRING("CREATE TEMP TRIGGER cache_on_delete AFTER DELETE"
|
||||
" ON moz_cache FOR EACH ROW BEGIN SELECT"
|
||||
|
@ -151,11 +144,6 @@ class EvictionObserver
|
|||
|
||||
~EvictionObserver()
|
||||
{
|
||||
if (mEvictionFunction->RemoveObserver() != 0) {
|
||||
// not last observer
|
||||
return;
|
||||
}
|
||||
|
||||
mDB->ExecuteSimpleSQL(
|
||||
NS_LITERAL_CSTRING("DROP TRIGGER cache_on_delete;"));
|
||||
mEvictionFunction->Reset();
|
||||
|
@ -186,157 +174,6 @@ DCacheHash(const char * key)
|
|||
return (PRUint64(nsDiskCache::Hash(key, 0)) << 32) | nsDiskCache::Hash(key, 0x7416f295);
|
||||
}
|
||||
|
||||
/**
|
||||
* EvictAsyncHandler
|
||||
*/
|
||||
class EvictAsyncHandler : public mozIStorageStatementCallback
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_MOZISTORAGESTATEMENTCALLBACK
|
||||
|
||||
EvictAsyncHandler();
|
||||
~EvictAsyncHandler();
|
||||
|
||||
nsresult Init(const char *aClientID,
|
||||
nsIApplicationCacheAsyncCallback *aCallback,
|
||||
mozIStorageConnection *aDB,
|
||||
nsOfflineCacheEvictionFunction *aEvictionFunction) {
|
||||
mClientID = NS_strdup(aClientID);
|
||||
if (mClientID == NULL)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
mCallback = aCallback;
|
||||
mDB = aDB;
|
||||
mEvictionFunction = aEvictionFunction;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult Start() {
|
||||
mEvictionObserver = new EvictionObserver(mDB, mEvictionFunction);
|
||||
HandleCompletion(mozIStorageStatementCallback::REASON_FINISHED);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
void ReportError() {
|
||||
mCallback->HandleAsyncCompletion(nsIApplicationCacheAsyncCallback::APP_CACHE_REQUEST_ERROR);
|
||||
}
|
||||
|
||||
void ReportSuccess() {
|
||||
mCallback->HandleAsyncCompletion(nsIApplicationCacheAsyncCallback::APP_CACHE_REQUEST_SUCCESS);
|
||||
}
|
||||
|
||||
private:
|
||||
const char *mClientID;
|
||||
nsCOMPtr<mozIStorageConnection> mDB;
|
||||
nsCOMPtr<nsIApplicationCacheAsyncCallback> mCallback;
|
||||
nsRefPtr<nsOfflineCacheEvictionFunction> mEvictionFunction;
|
||||
EvictionObserver *mEvictionObserver;
|
||||
|
||||
/* Current step in the receipt to complete a eviction. */
|
||||
int mStep;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(EvictAsyncHandler, mozIStorageStatementCallback)
|
||||
|
||||
EvictAsyncHandler::EvictAsyncHandler() :
|
||||
mClientID(NULL), mEvictionFunction(NULL), mStep(0)
|
||||
{
|
||||
}
|
||||
|
||||
EvictAsyncHandler::~EvictAsyncHandler() {
|
||||
if (mClientID)
|
||||
NS_Free((void *)mClientID);
|
||||
if (mEvictionObserver)
|
||||
delete mEvictionObserver;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
EvictAsyncHandler::HandleResult(mozIStorageResultSet *aResultSet) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
EvictAsyncHandler::HandleError(mozIStorageError *aError) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsresult
|
||||
EvictEntriesSteps(mozIStorageConnection *mDB,
|
||||
const char *clientID,
|
||||
int step,
|
||||
mozIStorageStatement **aStatement);
|
||||
|
||||
NS_IMETHODIMP
|
||||
EvictAsyncHandler::HandleCompletion(unsigned short aReason) {
|
||||
if (aReason != mozIStorageStatementCallback::REASON_FINISHED) {
|
||||
mCallback->HandleAsyncCompletion(nsIApplicationCacheAsyncCallback::APP_CACHE_REQUEST_ERROR);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<mozIStorageStatement> statement;
|
||||
rv = EvictEntriesSteps(mDB, mClientID, mStep++, getter_AddRefs(statement));
|
||||
if (NS_FAILED(rv)) {
|
||||
ReportError();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (statement) {
|
||||
nsCOMPtr<mozIStoragePendingStatement> pending;
|
||||
rv = statement->ExecuteAsync(this, getter_AddRefs(pending));
|
||||
if (NS_FAILED(rv)) {
|
||||
ReportError();
|
||||
}
|
||||
} else {
|
||||
// Complete the eviction, no more commands.
|
||||
mEvictionObserver->Apply();
|
||||
ReportSuccess();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* RemoveFilesAsync removes files in a separated thread.
|
||||
*/
|
||||
class RemoveFilesAsync : public nsRunnable
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @param aItems is an array of nsIFile to remove.
|
||||
*/
|
||||
RemoveFilesAsync(nsCOMArray<nsIFile> &aItems) :
|
||||
mItems(aItems) {}
|
||||
~RemoveFilesAsync();
|
||||
|
||||
NS_IMETHOD Run();
|
||||
|
||||
private:
|
||||
nsCOMArray<nsIFile> mItems;
|
||||
nsCOMPtr<nsIThread> mIOThread;
|
||||
};
|
||||
|
||||
RemoveFilesAsync::~RemoveFilesAsync() {
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RemoveFilesAsync::Run() {
|
||||
for (PRInt32 i = 0; i < mItems.Count(); i++) {
|
||||
#if defined(PR_LOGGING)
|
||||
nsCAutoString path;
|
||||
mItems[i]->GetNativePath(path);
|
||||
LOG((" removing %s\n", path.get()));
|
||||
#endif
|
||||
|
||||
mItems[i]->Remove(false);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* nsOfflineCacheEvictionFunction
|
||||
*/
|
||||
|
@ -404,17 +241,16 @@ nsOfflineCacheEvictionFunction::Apply()
|
|||
{
|
||||
LOG(("nsOfflineCacheEvictionFunction::Apply\n"));
|
||||
|
||||
if (!mIOThread) {
|
||||
nsresult rv;
|
||||
for (PRInt32 i = 0; i < mItems.Count(); i++) {
|
||||
#if defined(PR_LOGGING)
|
||||
nsCAutoString path;
|
||||
mItems[i]->GetNativePath(path);
|
||||
LOG((" removing %s\n", path.get()));
|
||||
#endif
|
||||
|
||||
rv = NS_NewThread(getter_AddRefs(mIOThread));
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "fail to create a new thread");
|
||||
mItems[i]->Remove(false);
|
||||
}
|
||||
|
||||
nsCOMPtr<RemoveFilesAsync> removeFiles = new RemoveFilesAsync(mItems);
|
||||
NS_ASSERTION(removeFiles, "fail to instantiate RemoveFilesAsync");
|
||||
mIOThread->Dispatch(removeFiles, NS_DISPATCH_NORMAL);
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
|
@ -863,22 +699,6 @@ nsApplicationCache::Discard()
|
|||
return mDevice->EvictEntries(mClientID.get());
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsApplicationCache::DiscardAsync(nsIApplicationCacheAsyncCallback *aCallback)
|
||||
{
|
||||
NS_ENSURE_TRUE(mValid, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_TRUE(mDevice, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
mValid = false;
|
||||
|
||||
if (mDevice->IsActiveCache(mGroup, mClientID))
|
||||
{
|
||||
mDevice->DeactivateGroup(mGroup);
|
||||
}
|
||||
|
||||
return mDevice->EvictEntriesAsync(mClientID.get(), aCallback);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsApplicationCache::MarkEntry(const nsACString &key,
|
||||
PRUint32 typeBits)
|
||||
|
@ -1912,102 +1732,82 @@ nsOfflineCacheDevice::Visit(nsICacheVisitor *visitor)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
static const char *sEvictCmdsClientID[] = {
|
||||
"DELETE FROM moz_cache WHERE ClientID=? AND Flags = 0;",
|
||||
"DELETE FROM moz_cache_groups WHERE ActiveClientID=?;",
|
||||
"DELETE FROM moz_cache_namespaces WHERE ClientID=?",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *sEvictCmds[] = {
|
||||
"DELETE FROM moz_cache WHERE Flags = 0;",
|
||||
"DELETE FROM moz_cache_groups;",
|
||||
"DELETE FROM moz_cache_namespaces;",
|
||||
NULL
|
||||
};
|
||||
|
||||
/**
|
||||
* Create SQL statement for every step of eviction of cache entries.
|
||||
*
|
||||
* @param mDB is the database connection used for the eviction.
|
||||
* @param clientID is the clientID of cache entries being evicting.
|
||||
* @param step is the number of current step. (start from 0)
|
||||
* @param statement is a pointer to return the stathement.
|
||||
*/
|
||||
static nsresult
|
||||
EvictEntriesSteps(mozIStorageConnection *mDB,
|
||||
const char *clientID,
|
||||
int step,
|
||||
mozIStorageStatement **aStatement)
|
||||
{
|
||||
const char **cmds = clientID ? sEvictCmdsClientID : sEvictCmds;
|
||||
const char *cmd = cmds[step];
|
||||
|
||||
if (cmd == NULL) {
|
||||
*aStatement = NULL;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// called to evict all entries matching the given clientID.
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<mozIStorageStatement> statement;
|
||||
rv = mDB->CreateStatement(nsDependentCString(cmd),
|
||||
getter_AddRefs(statement));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (clientID) {
|
||||
rv = statement->BindUTF8StringByIndex(0, nsDependentCString(clientID));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
*aStatement = statement.forget().get();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsOfflineCacheDevice::EvictEntries(const char *clientID)
|
||||
{
|
||||
LOG(("nsOfflineCacheDevice::EvictEntries [cid=%s]\n",
|
||||
clientID ? clientID : ""));
|
||||
|
||||
int step = 0;
|
||||
nsresult rv = NS_OK;;
|
||||
// called to evict all entries matching the given clientID.
|
||||
|
||||
// need trigger to fire user defined function after a row is deleted
|
||||
// so we can delete the corresponding data file.
|
||||
EvictionObserver evictionObserver(mDB, mEvictionFunction);
|
||||
|
||||
nsCOMPtr<mozIStorageStatement> statement;
|
||||
while (1) {
|
||||
rv = EvictEntriesSteps(mDB, clientID, step++, getter_AddRefs(statement));
|
||||
if (NS_FAILED(rv)) break;
|
||||
nsresult rv;
|
||||
if (clientID)
|
||||
{
|
||||
rv = mDB->CreateStatement(NS_LITERAL_CSTRING("DELETE FROM moz_cache WHERE ClientID=? AND Flags = 0;"),
|
||||
getter_AddRefs(statement));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!statement) break; // finish
|
||||
rv = statement->BindUTF8StringByIndex(0, nsDependentCString(clientID));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
statement->Execute();
|
||||
if (NS_FAILED(rv)) break;
|
||||
rv = statement->Execute();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mDB->CreateStatement(NS_LITERAL_CSTRING("DELETE FROM moz_cache_groups WHERE ActiveClientID=?;"),
|
||||
getter_AddRefs(statement));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = statement->BindUTF8StringByIndex(0, nsDependentCString(clientID));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = statement->Execute();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = mDB->CreateStatement(NS_LITERAL_CSTRING("DELETE FROM moz_cache WHERE Flags = 0;"),
|
||||
getter_AddRefs(statement));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = statement->Execute();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mDB->CreateStatement(NS_LITERAL_CSTRING("DELETE FROM moz_cache_groups;"),
|
||||
getter_AddRefs(statement));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = statement->Execute();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
evictionObserver.Apply();
|
||||
|
||||
return rv;
|
||||
}
|
||||
statement = nsnull;
|
||||
// Also evict any namespaces associated with this clientID.
|
||||
if (clientID)
|
||||
{
|
||||
rv = mDB->CreateStatement(NS_LITERAL_CSTRING("DELETE FROM moz_cache_namespaces WHERE ClientID=?"),
|
||||
getter_AddRefs(statement));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsresult
|
||||
nsOfflineCacheDevice::EvictEntriesAsync(const char *clientID,
|
||||
nsIApplicationCacheAsyncCallback *aCallback)
|
||||
{
|
||||
LOG(("nsOfflineCacheDevice::EvictEntriesAsync [cid=%s]\n",
|
||||
clientID ? clientID : ""));
|
||||
rv = statement->BindUTF8StringByIndex(0, nsDependentCString(clientID));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = mDB->CreateStatement(NS_LITERAL_CSTRING("DELETE FROM moz_cache_namespaces;"),
|
||||
getter_AddRefs(statement));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
EvictAsyncHandler *evictAsyncHandler = new EvictAsyncHandler();
|
||||
if (evictAsyncHandler == NULL)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
rv = statement->Execute();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
evictAsyncHandler->Init(clientID, aCallback, mDB, mEvictionFunction);
|
||||
evictAsyncHandler->Start();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -77,21 +77,14 @@ public:
|
|||
|
||||
nsOfflineCacheEvictionFunction(nsOfflineCacheDevice *device)
|
||||
: mDevice(device)
|
||||
, mObserverCount(0)
|
||||
{}
|
||||
|
||||
void Reset() { mItems.Clear(); }
|
||||
void Apply();
|
||||
|
||||
int AddObserver() { return ++mObserverCount; }
|
||||
int RemoveObserver() { return --mObserverCount; }
|
||||
|
||||
private:
|
||||
nsOfflineCacheDevice *mDevice;
|
||||
nsCOMArray<nsIFile> mItems;
|
||||
nsCOMPtr<nsIThread> mIOThread;
|
||||
|
||||
int mObserverCount;
|
||||
|
||||
};
|
||||
|
||||
|
@ -138,9 +131,6 @@ public:
|
|||
|
||||
virtual nsresult EvictEntries(const char * clientID);
|
||||
|
||||
virtual nsresult EvictEntriesAsync(const char * clientID,
|
||||
nsIApplicationCacheAsyncCallback *aCallback);
|
||||
|
||||
/* Entry ownership */
|
||||
nsresult GetOwnerDomains(const char * clientID,
|
||||
PRUint32 * count,
|
||||
|
|
|
@ -42,4 +42,3 @@
|
|||
*/
|
||||
|
||||
#error "Do not include this header file."
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
NSS_3_13_3_RTM
|
||||
NSS_3_13_4_BETA1
|
||||
|
|
|
@ -1 +1 @@
|
|||
NSS_3_13_3_RTM
|
||||
NSS_3_13_4_BETA1
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
/*
|
||||
* Tool for converting builtin CA certs.
|
||||
*
|
||||
* $Id: addbuiltin.c,v 1.16 2011/04/13 00:10:21 rrelyea%redhat.com Exp $
|
||||
* $Id: addbuiltin.c,v 1.17 2012/03/10 12:10:44 kaie%kuix.de Exp $
|
||||
*/
|
||||
|
||||
#include "nssrenam.h"
|
||||
|
@ -91,14 +91,115 @@ static const SEC_ASN1Template serialTemplate[] = {
|
|||
{ 0 }
|
||||
};
|
||||
|
||||
void print_crl_info(CERTName *name, SECItem *serial)
|
||||
{
|
||||
PRBool saveWrapeState = SECU_GetWrapEnabled();
|
||||
SECU_EnableWrap(PR_FALSE);
|
||||
|
||||
SECU_PrintNameQuotesOptional(stdout, name, "# Issuer", 0, PR_FALSE);
|
||||
printf("\n");
|
||||
|
||||
SECU_PrintInteger(stdout, serial, "# Serial Number", 0);
|
||||
|
||||
SECU_EnableWrap(saveWrapeState);
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
ConvertCertificate(SECItem *sdder, char *nickname, CERTCertTrust *trust)
|
||||
ConvertCRLEntry(SECItem *sdder, PRInt32 crlentry, char *nickname)
|
||||
{
|
||||
int rv;
|
||||
PRArenaPool *arena = NULL;
|
||||
CERTSignedCrl *newCrl = NULL;
|
||||
CERTCrlEntry *entry;
|
||||
|
||||
CERTName *name = NULL;
|
||||
SECItem *derName = NULL;
|
||||
SECItem *serial = NULL;
|
||||
|
||||
rv = SEC_ERROR_NO_MEMORY;
|
||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
if (!arena)
|
||||
return rv;
|
||||
|
||||
newCrl = CERT_DecodeDERCrlWithFlags(arena, sdder, SEC_CRL_TYPE,
|
||||
CRL_DECODE_DEFAULT_OPTIONS);
|
||||
if (!newCrl)
|
||||
return SECFailure;
|
||||
|
||||
name = &newCrl->crl.name;
|
||||
derName = &newCrl->crl.derName;
|
||||
|
||||
if (newCrl->crl.entries != NULL) {
|
||||
PRInt32 iv = 0;
|
||||
while ((entry = newCrl->crl.entries[iv++]) != NULL) {
|
||||
if (crlentry == iv) {
|
||||
serial = &entry->serialNumber;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!name || !derName || !serial)
|
||||
return SECFailure;
|
||||
|
||||
printf("\n# Distrust \"%s\"\n",nickname);
|
||||
print_crl_info(name, serial);
|
||||
|
||||
printf("CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST\n");
|
||||
printf("CKA_TOKEN CK_BBOOL CK_TRUE\n");
|
||||
printf("CKA_PRIVATE CK_BBOOL CK_FALSE\n");
|
||||
printf("CKA_MODIFIABLE CK_BBOOL CK_FALSE\n");
|
||||
printf("CKA_LABEL UTF8 \"%s\"\n",nickname);
|
||||
|
||||
printf("CKA_ISSUER MULTILINE_OCTAL\n");
|
||||
dumpbytes(derName->data,derName->len);
|
||||
printf("END\n");
|
||||
printf("CKA_SERIAL_NUMBER MULTILINE_OCTAL\n");
|
||||
printf("\\002\\%03o", serial->len); /* 002: type integer; len >=3 digits */
|
||||
dumpbytes(serial->data,serial->len);
|
||||
printf("END\n");
|
||||
|
||||
printf("CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED\n");
|
||||
printf("CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED\n");
|
||||
printf("CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED\n");
|
||||
printf("CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE\n");
|
||||
|
||||
PORT_FreeArena (arena, PR_FALSE);
|
||||
return rv;
|
||||
}
|
||||
|
||||
void print_info(SECItem *sdder, CERTCertificate *c)
|
||||
{
|
||||
PRBool saveWrapeState = SECU_GetWrapEnabled();
|
||||
SECU_EnableWrap(PR_FALSE);
|
||||
|
||||
SECU_PrintNameQuotesOptional(stdout, &c->issuer, "# Issuer", 0, PR_FALSE);
|
||||
printf("\n");
|
||||
|
||||
SECU_PrintInteger(stdout, &c->serialNumber, "# Serial Number", 0);
|
||||
|
||||
SECU_PrintNameQuotesOptional(stdout, &c->subject, "# Subject", 0, PR_FALSE);
|
||||
printf("\n");
|
||||
|
||||
SECU_PrintTimeChoice(stdout, &c->validity.notBefore, "# Not Valid Before", 0);
|
||||
SECU_PrintTimeChoice(stdout, &c->validity.notAfter, "# Not Valid After ", 0);
|
||||
|
||||
SECU_PrintFingerprints(stdout, sdder, "# Fingerprint", 0);
|
||||
|
||||
SECU_EnableWrap(saveWrapeState);
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
ConvertCertificate(SECItem *sdder, char *nickname, CERTCertTrust *trust,
|
||||
PRBool excludeCert, PRBool excludeHash)
|
||||
{
|
||||
SECStatus rv = SECSuccess;
|
||||
CERTCertificate *cert;
|
||||
unsigned char sha1_hash[SHA1_LENGTH];
|
||||
unsigned char md5_hash[MD5_LENGTH];
|
||||
SECItem *serial = NULL;
|
||||
PRBool step_up = PR_FALSE;
|
||||
const char *trust_info;
|
||||
|
||||
cert = CERT_DecodeDERCertificate(sdder, PR_FALSE, nickname);
|
||||
if (!cert) {
|
||||
|
@ -108,42 +209,56 @@ ConvertCertificate(SECItem *sdder, char *nickname, CERTCertTrust *trust)
|
|||
if (!serial) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (!excludeCert) {
|
||||
printf("\n#\n# Certificate \"%s\"\n#\n",nickname);
|
||||
print_info(sdder, cert);
|
||||
printf("CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE\n");
|
||||
printf("CKA_TOKEN CK_BBOOL CK_TRUE\n");
|
||||
printf("CKA_PRIVATE CK_BBOOL CK_FALSE\n");
|
||||
printf("CKA_MODIFIABLE CK_BBOOL CK_FALSE\n");
|
||||
printf("CKA_LABEL UTF8 \"%s\"\n",nickname);
|
||||
printf("CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509\n");
|
||||
printf("CKA_SUBJECT MULTILINE_OCTAL\n");
|
||||
dumpbytes(cert->derSubject.data,cert->derSubject.len);
|
||||
printf("END\n");
|
||||
printf("CKA_ID UTF8 \"0\"\n");
|
||||
printf("CKA_ISSUER MULTILINE_OCTAL\n");
|
||||
dumpbytes(cert->derIssuer.data,cert->derIssuer.len);
|
||||
printf("END\n");
|
||||
printf("CKA_SERIAL_NUMBER MULTILINE_OCTAL\n");
|
||||
dumpbytes(serial->data,serial->len);
|
||||
printf("END\n");
|
||||
printf("CKA_VALUE MULTILINE_OCTAL\n");
|
||||
dumpbytes(sdder->data,sdder->len);
|
||||
printf("END\n");
|
||||
}
|
||||
|
||||
if ((trust->sslFlags | trust->emailFlags | trust->objectSigningFlags)
|
||||
== CERTDB_TERMINAL_RECORD)
|
||||
trust_info = "Distrust";
|
||||
else
|
||||
trust_info = "Trust for";
|
||||
|
||||
printf("\n# %s \"%s\"\n", trust_info, nickname);
|
||||
print_info(sdder, cert);
|
||||
|
||||
printf("\n#\n# Certificate \"%s\"\n#\n",nickname);
|
||||
printf("CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE\n");
|
||||
printf("CKA_TOKEN CK_BBOOL CK_TRUE\n");
|
||||
printf("CKA_PRIVATE CK_BBOOL CK_FALSE\n");
|
||||
printf("CKA_MODIFIABLE CK_BBOOL CK_FALSE\n");
|
||||
printf("CKA_LABEL UTF8 \"%s\"\n",nickname);
|
||||
printf("CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509\n");
|
||||
printf("CKA_SUBJECT MULTILINE_OCTAL\n");
|
||||
dumpbytes(cert->derSubject.data,cert->derSubject.len);
|
||||
printf("END\n");
|
||||
printf("CKA_ID UTF8 \"0\"\n");
|
||||
printf("CKA_ISSUER MULTILINE_OCTAL\n");
|
||||
dumpbytes(cert->derIssuer.data,cert->derIssuer.len);
|
||||
printf("END\n");
|
||||
printf("CKA_SERIAL_NUMBER MULTILINE_OCTAL\n");
|
||||
dumpbytes(serial->data,serial->len);
|
||||
printf("END\n");
|
||||
printf("CKA_VALUE MULTILINE_OCTAL\n");
|
||||
dumpbytes(sdder->data,sdder->len);
|
||||
printf("END\n");
|
||||
|
||||
PK11_HashBuf(SEC_OID_SHA1, sha1_hash, sdder->data, sdder->len);
|
||||
PK11_HashBuf(SEC_OID_MD5, md5_hash, sdder->data, sdder->len);
|
||||
printf("\n# Trust for Certificate \"%s\"\n",nickname);
|
||||
printf("CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST\n");
|
||||
printf("CKA_TOKEN CK_BBOOL CK_TRUE\n");
|
||||
printf("CKA_PRIVATE CK_BBOOL CK_FALSE\n");
|
||||
printf("CKA_MODIFIABLE CK_BBOOL CK_FALSE\n");
|
||||
printf("CKA_LABEL UTF8 \"%s\"\n",nickname);
|
||||
printf("CKA_CERT_SHA1_HASH MULTILINE_OCTAL\n");
|
||||
dumpbytes(sha1_hash,SHA1_LENGTH);
|
||||
printf("END\n");
|
||||
printf("CKA_CERT_MD5_HASH MULTILINE_OCTAL\n");
|
||||
dumpbytes(md5_hash,MD5_LENGTH);
|
||||
printf("END\n");
|
||||
|
||||
if (!excludeHash) {
|
||||
PK11_HashBuf(SEC_OID_SHA1, sha1_hash, sdder->data, sdder->len);
|
||||
printf("CKA_CERT_SHA1_HASH MULTILINE_OCTAL\n");
|
||||
dumpbytes(sha1_hash,SHA1_LENGTH);
|
||||
printf("END\n");
|
||||
PK11_HashBuf(SEC_OID_MD5, md5_hash, sdder->data, sdder->len);
|
||||
printf("CKA_CERT_MD5_HASH MULTILINE_OCTAL\n");
|
||||
dumpbytes(md5_hash,MD5_LENGTH);
|
||||
printf("END\n");
|
||||
}
|
||||
|
||||
printf("CKA_ISSUER MULTILINE_OCTAL\n");
|
||||
dumpbytes(cert->derIssuer.data,cert->derIssuer.len);
|
||||
|
@ -153,11 +268,11 @@ ConvertCertificate(SECItem *sdder, char *nickname, CERTCertTrust *trust)
|
|||
printf("END\n");
|
||||
|
||||
printf("CKA_TRUST_SERVER_AUTH CK_TRUST %s\n",
|
||||
getTrustString(trust->sslFlags));
|
||||
getTrustString(trust->sslFlags));
|
||||
printf("CKA_TRUST_EMAIL_PROTECTION CK_TRUST %s\n",
|
||||
getTrustString(trust->emailFlags));
|
||||
getTrustString(trust->emailFlags));
|
||||
printf("CKA_TRUST_CODE_SIGNING CK_TRUST %s\n",
|
||||
getTrustString(trust->objectSigningFlags));
|
||||
getTrustString(trust->objectSigningFlags));
|
||||
#ifdef notdef
|
||||
printf("CKA_TRUST_CLIENT_AUTH CK_TRUST CKT_NSS_TRUSTED\n");
|
||||
printf("CKA_TRUST_DIGITAL_SIGNATURE CK_TRUST CKT_NSS_TRUSTED_DELEGATOR\n");
|
||||
|
@ -167,10 +282,10 @@ ConvertCertificate(SECItem *sdder, char *nickname, CERTCertTrust *trust)
|
|||
printf("CKA_TRUST_KEY_AGREEMENT CK_TRUST CKT_NSS_TRUSTED_DELEGATOR\n");
|
||||
printf("CKA_TRUST_KEY_CERT_SIGN CK_TRUST CKT_NSS_TRUSTED_DELEGATOR\n");
|
||||
#endif
|
||||
|
||||
step_up = (trust->sslFlags & CERTDB_GOVT_APPROVED_CA);
|
||||
printf("CKA_TRUST_STEP_UP_APPROVED CK_BBOOL %s\n",
|
||||
trust->sslFlags & CERTDB_GOVT_APPROVED_CA ?
|
||||
"CK_TRUE" : "CK_FALSE");
|
||||
|
||||
step_up ? "CK_TRUE" : "CK_FALSE");
|
||||
|
||||
PORT_Free(sdder->data);
|
||||
return(rv);
|
||||
|
@ -215,7 +330,7 @@ void printheader() {
|
|||
"#\n"
|
||||
"# ***** END LICENSE BLOCK *****\n"
|
||||
"#\n"
|
||||
"CVS_ID \"@(#) $RCSfile: addbuiltin.c,v $ $Revision: 1.16 $ $Date: 2011/04/13 00:10:21 $\"\n"
|
||||
"CVS_ID \"@(#) $RCSfile: addbuiltin.c,v $ $Revision: 1.17 $ $Date: 2012/03/10 12:10:44 $\"\n"
|
||||
"\n"
|
||||
"#\n"
|
||||
"# certdata.txt\n"
|
||||
|
@ -285,41 +400,71 @@ void printheader() {
|
|||
|
||||
static void Usage(char *progName)
|
||||
{
|
||||
fprintf(stderr, "%s -n nickname -t trust [-i certfile]\n", progName);
|
||||
fprintf(stderr, "%s -t trust -n nickname [-i certfile] [-c] [-h]\n", progName);
|
||||
fprintf(stderr,
|
||||
"\tRead a der-encoded cert from certfile or stdin, and output\n"
|
||||
"\tit to stdout in a format suitable for the builtin root module.\n"
|
||||
"\tExample: %s -n MyCA -t \"C,C,C\" -i myca.der >> certdata.txt\n"
|
||||
"\t(pipe through atob if the cert is b64-encoded)\n", progName);
|
||||
fprintf(stderr, "%-15s nickname to assign to builtin cert.\n",
|
||||
"-n nickname");
|
||||
"\tExample: %s -n MyCA -t \"C,C,C\" -i myca.der >> certdata.txt\n",
|
||||
progName);
|
||||
fprintf(stderr, "%s -D -n label [-i certfile]\n", progName);
|
||||
fprintf(stderr,
|
||||
"\tRead a der-encoded cert from certfile or stdin, and output\n"
|
||||
"\ta distrust record.\n"
|
||||
"\t(-D is equivalent to -t p,p,p -c -h)\n");
|
||||
fprintf(stderr, "%s -C -e crl-entry-number -n label [-i crlfile]\n", progName);
|
||||
fprintf(stderr,
|
||||
"\tRead a CRL from crlfile or stdin, and output\n"
|
||||
"\ta distrust record (issuer+serial).\n"
|
||||
"\t(-C implies -c -h)\n");
|
||||
fprintf(stderr, "%-15s trust flags (cCTpPuw).\n", "-t trust");
|
||||
fprintf(stderr, "%-15s file to read (default stdin)\n", "-i certfile");
|
||||
fprintf(stderr, "%-15s nickname to assign to builtin cert, or\n",
|
||||
"-n nickname");
|
||||
fprintf(stderr, "%-15s a label for the distrust record.\n", "");
|
||||
fprintf(stderr, "%-15s exclude the certificate (only add a trust record)\n", "-c");
|
||||
fprintf(stderr, "%-15s exclude hash from trust record\n", "-h");
|
||||
fprintf(stderr, "%-15s (useful to distrust any matching issuer/serial)\n", "");
|
||||
fprintf(stderr, "%-15s (not allowed when adding positive trust)\n", "");
|
||||
fprintf(stderr, "%-15s a CRL entry number, as shown by \"crlutil -S\"\n", "-e");
|
||||
fprintf(stderr, "%-15s input file to read (default stdin)\n", "-i file");
|
||||
fprintf(stderr, "%-15s (pipe through atob if the cert is b64-encoded)\n", "");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
enum {
|
||||
opt_Input = 0,
|
||||
opt_Nickname,
|
||||
opt_Trust
|
||||
opt_Trust,
|
||||
opt_Distrust,
|
||||
opt_ExcludeCert,
|
||||
opt_ExcludeHash,
|
||||
opt_DistrustCRL,
|
||||
opt_CRLEnry
|
||||
};
|
||||
|
||||
static secuCommandFlag addbuiltin_options[] =
|
||||
{
|
||||
{ /* opt_Input */ 'i', PR_TRUE, 0, PR_FALSE },
|
||||
{ /* opt_Nickname */ 'n', PR_TRUE, 0, PR_FALSE },
|
||||
{ /* opt_Trust */ 't', PR_TRUE, 0, PR_FALSE }
|
||||
{ /* opt_Input */ 'i', PR_TRUE, 0, PR_FALSE },
|
||||
{ /* opt_Nickname */ 'n', PR_TRUE, 0, PR_FALSE },
|
||||
{ /* opt_Trust */ 't', PR_TRUE, 0, PR_FALSE },
|
||||
{ /* opt_Distrust */ 'D', PR_FALSE, 0, PR_FALSE },
|
||||
{ /* opt_ExcludeCert */ 'c', PR_FALSE, 0, PR_FALSE },
|
||||
{ /* opt_ExcludeHash */ 'h', PR_FALSE, 0, PR_FALSE },
|
||||
{ /* opt_DistrustCRL */ 'C', PR_FALSE, 0, PR_FALSE },
|
||||
{ /* opt_CRLEnry */ 'e', PR_TRUE, 0, PR_FALSE },
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
SECStatus rv;
|
||||
char *nickname;
|
||||
char *trusts;
|
||||
char *nickname = NULL;
|
||||
char *trusts = NULL;
|
||||
char *progName;
|
||||
PRFileDesc *infile;
|
||||
CERTCertTrust trust = { 0 };
|
||||
SECItem derCert = { 0 };
|
||||
SECItem derItem = { 0 };
|
||||
PRInt32 crlentry = 0;
|
||||
PRInt32 mutuallyExclusiveOpts = 0;
|
||||
PRBool decodeTrust = PR_FALSE;
|
||||
|
||||
secuCommand addbuiltin = { 0 };
|
||||
addbuiltin.numOptions = sizeof(addbuiltin_options)/sizeof(secuCommandFlag);
|
||||
|
@ -332,12 +477,40 @@ int main(int argc, char **argv)
|
|||
|
||||
if (rv != SECSuccess)
|
||||
Usage(progName);
|
||||
|
||||
if (addbuiltin.options[opt_Trust].activated)
|
||||
++mutuallyExclusiveOpts;
|
||||
if (addbuiltin.options[opt_Distrust].activated)
|
||||
++mutuallyExclusiveOpts;
|
||||
if (addbuiltin.options[opt_DistrustCRL].activated)
|
||||
++mutuallyExclusiveOpts;
|
||||
|
||||
if (!addbuiltin.options[opt_Nickname].activated &&
|
||||
!addbuiltin.options[opt_Trust].activated) {
|
||||
fprintf(stderr, "%s: you must specify both a nickname and trust.\n",
|
||||
progName);
|
||||
Usage(progName);
|
||||
if (mutuallyExclusiveOpts != 1) {
|
||||
fprintf(stderr, "%s: you must specify exactly one of -t or -D or -C\n",
|
||||
progName);
|
||||
Usage(progName);
|
||||
}
|
||||
|
||||
if (addbuiltin.options[opt_DistrustCRL].activated) {
|
||||
if (!addbuiltin.options[opt_CRLEnry].activated) {
|
||||
fprintf(stderr, "%s: you must specify the CRL entry number.\n",
|
||||
progName);
|
||||
Usage(progName);
|
||||
}
|
||||
else {
|
||||
crlentry = atoi(addbuiltin.options[opt_CRLEnry].arg);
|
||||
if (crlentry < 1) {
|
||||
fprintf(stderr, "%s: The CRL entry number must be > 0.\n",
|
||||
progName);
|
||||
Usage(progName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!addbuiltin.options[opt_Nickname].activated) {
|
||||
fprintf(stderr, "%s: you must specify parameter -n (a nickname or a label).\n",
|
||||
progName);
|
||||
Usage(progName);
|
||||
}
|
||||
|
||||
if (addbuiltin.options[opt_Input].activated) {
|
||||
|
@ -365,24 +538,56 @@ int main(int argc, char **argv)
|
|||
}
|
||||
|
||||
nickname = strdup(addbuiltin.options[opt_Nickname].arg);
|
||||
trusts = strdup(addbuiltin.options[opt_Trust].arg);
|
||||
|
||||
|
||||
NSS_NoDB_Init(NULL);
|
||||
|
||||
rv = CERT_DecodeTrustString(&trust, trusts);
|
||||
if (rv) {
|
||||
fprintf(stderr, "%s: incorrectly formatted trust string.\n", progName);
|
||||
Usage(progName);
|
||||
if (addbuiltin.options[opt_Distrust].activated ||
|
||||
addbuiltin.options[opt_DistrustCRL].activated) {
|
||||
addbuiltin.options[opt_ExcludeCert].activated = PR_TRUE;
|
||||
addbuiltin.options[opt_ExcludeHash].activated = PR_TRUE;
|
||||
}
|
||||
|
||||
if (addbuiltin.options[opt_Distrust].activated) {
|
||||
trusts = strdup("p,p,p");
|
||||
decodeTrust = PR_TRUE;
|
||||
}
|
||||
else if (addbuiltin.options[opt_Trust].activated) {
|
||||
trusts = strdup(addbuiltin.options[opt_Trust].arg);
|
||||
decodeTrust = PR_TRUE;
|
||||
}
|
||||
|
||||
if (decodeTrust) {
|
||||
rv = CERT_DecodeTrustString(&trust, trusts);
|
||||
if (rv) {
|
||||
fprintf(stderr, "%s: incorrectly formatted trust string.\n", progName);
|
||||
Usage(progName);
|
||||
}
|
||||
}
|
||||
|
||||
if (addbuiltin.options[opt_Trust].activated &&
|
||||
addbuiltin.options[opt_ExcludeHash].activated) {
|
||||
if ((trust.sslFlags | trust.emailFlags | trust.objectSigningFlags)
|
||||
!= CERTDB_TERMINAL_RECORD) {
|
||||
fprintf(stderr, "%s: Excluding the hash only allowed with distrust.\n", progName);
|
||||
Usage(progName);
|
||||
}
|
||||
}
|
||||
|
||||
SECU_FileToItem(&derCert, infile);
|
||||
SECU_FileToItem(&derItem, infile);
|
||||
|
||||
/*printheader();*/
|
||||
|
||||
rv = ConvertCertificate(&derCert, nickname, &trust);
|
||||
if (rv) {
|
||||
fprintf(stderr, "%s: failed to convert certificate.\n", progName);
|
||||
exit(1);
|
||||
|
||||
if (addbuiltin.options[opt_DistrustCRL].activated) {
|
||||
rv = ConvertCRLEntry(&derItem, crlentry, nickname);
|
||||
}
|
||||
else {
|
||||
rv = ConvertCertificate(&derItem, nickname, &trust,
|
||||
addbuiltin.options[opt_ExcludeCert].activated,
|
||||
addbuiltin.options[opt_ExcludeHash].activated);
|
||||
if (rv) {
|
||||
fprintf(stderr, "%s: failed to convert certificate.\n", progName);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (NSS_Shutdown() != SECSuccess) {
|
||||
|
|
|
@ -1171,7 +1171,7 @@ static void luC(enum usage_level ul, const char *command)
|
|||
"%-20s Create netscape cert type extension. Possible keywords:\n"
|
||||
"%-20s \"sslClient\", \"sslServer\", \"smime\", \"objectSigning\",\n"
|
||||
"%-20s \"sslCA\", \"smimeCA\", \"objectSigningCA\", \"critical\".\n",
|
||||
" -5 | -nsCertType keyword,keyword,... ", "", "", "");
|
||||
" -5 | --nsCertType keyword,keyword,... ", "", "", "");
|
||||
FPS "%-20s \n"
|
||||
"%-20s Create extended key usage extension. Possible keywords:\n"
|
||||
"%-20s \"serverAuth\", \"clientAuth\",\"codeSigning\",\n"
|
||||
|
|
|
@ -313,6 +313,37 @@ SECStatus ImportCRL (CERTCertDBHandle *certHandle, char *url, int type,
|
|||
return (rv);
|
||||
}
|
||||
|
||||
SECStatus DumpCRL(PRFileDesc *inFile)
|
||||
{
|
||||
int rv;
|
||||
PRArenaPool *arena = NULL;
|
||||
CERTSignedCrl *newCrl = NULL;
|
||||
|
||||
SECItem crlDER;
|
||||
crlDER.data = NULL;
|
||||
|
||||
/* Read in the entire file specified with the -f argument */
|
||||
rv = SECU_ReadDERFromFile(&crlDER, inFile, PR_FALSE);
|
||||
if (rv != SECSuccess) {
|
||||
SECU_PrintError(progName, "unable to read input file");
|
||||
return (SECFailure);
|
||||
}
|
||||
|
||||
rv = SEC_ERROR_NO_MEMORY;
|
||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
if (!arena)
|
||||
return rv;
|
||||
|
||||
newCrl = CERT_DecodeDERCrlWithFlags(arena, &crlDER, SEC_CRL_TYPE,
|
||||
CRL_DECODE_DEFAULT_OPTIONS);
|
||||
if (!newCrl)
|
||||
return SECFailure;
|
||||
|
||||
SECU_PrintCRLInfo (stdout, &newCrl->crl, "CRL file contents", 0);
|
||||
|
||||
PORT_FreeArena (arena, PR_FALSE);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static CERTCertificate*
|
||||
FindSigningCert(CERTCertDBHandle *certHandle, CERTSignedCrl *signCrl,
|
||||
|
@ -756,6 +787,7 @@ static void Usage(char *progName)
|
|||
fprintf(stderr,
|
||||
"Usage: %s -L [-n nickname] [-d keydir] [-P dbprefix] [-t crlType]\n"
|
||||
" %s -D -n nickname [-d keydir] [-P dbprefix]\n"
|
||||
" %s -S -i crl\n"
|
||||
" %s -I -i crl -t crlType [-u url] [-d keydir] [-P dbprefix] [-B] "
|
||||
"[-p pwd-file] -w [pwd-string]\n"
|
||||
" %s -E -t crlType [-d keydir] [-P dbprefix]\n"
|
||||
|
@ -763,7 +795,7 @@ static void Usage(char *progName)
|
|||
" %s -G|-M -c crl-init-file -n nickname [-i crl] [-u url] "
|
||||
"[-d keydir] [-P dbprefix] [-Z alg] ] [-p pwd-file] -w [pwd-string] "
|
||||
"[-a] [-B]\n",
|
||||
progName, progName, progName, progName, progName, progName);
|
||||
progName, progName, progName, progName, progName, progName, progName);
|
||||
|
||||
fprintf (stderr, "%-15s List CRL\n", "-L");
|
||||
fprintf(stderr, "%-20s Specify the nickname of the CA certificate\n",
|
||||
|
@ -788,6 +820,10 @@ static void Usage(char *progName)
|
|||
"-d keydir");
|
||||
fprintf(stderr, "%-20s Cert & Key database prefix (default is \"\")\n",
|
||||
"-P dbprefix");
|
||||
|
||||
fprintf (stderr, "%-15s Show contents of a CRL file (without database)\n", "-S");
|
||||
fprintf(stderr, "%-20s Specify the file which contains the CRL to show\n",
|
||||
"-i crl");
|
||||
|
||||
fprintf (stderr, "%-15s Import a CRL to the cert database\n", "-I");
|
||||
fprintf(stderr, "%-20s Specify the file which contains the CRL to import\n",
|
||||
|
@ -835,15 +871,14 @@ static void Usage(char *progName)
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
SECItem privKeyDER;
|
||||
CERTCertDBHandle *certHandle;
|
||||
FILE *certFile;
|
||||
PRFileDesc *inFile;
|
||||
PRFileDesc *inCrlInitFile = NULL;
|
||||
int generateCRL;
|
||||
int modifyCRL;
|
||||
int listCRL;
|
||||
int importCRL;
|
||||
int showFileCRL;
|
||||
int deleteCRL;
|
||||
int rv;
|
||||
char *nickName;
|
||||
|
@ -872,17 +907,15 @@ int main(int argc, char **argv)
|
|||
progName = progName ? progName+1 : argv[0];
|
||||
|
||||
rv = 0;
|
||||
deleteCRL = importCRL = listCRL = generateCRL = modifyCRL = 0;
|
||||
certFile = NULL;
|
||||
deleteCRL = importCRL = listCRL = generateCRL = modifyCRL = showFileCRL = 0;
|
||||
inFile = NULL;
|
||||
nickName = url = NULL;
|
||||
privKeyDER.data = NULL;
|
||||
certHandle = NULL;
|
||||
crlType = SEC_CRL_TYPE;
|
||||
/*
|
||||
* Parse command line arguments
|
||||
*/
|
||||
optstate = PL_CreateOptState(argc, argv, "sqBCDGILMTEP:f:d:i:h:n:p:t:u:r:aZ:o:c:");
|
||||
optstate = PL_CreateOptState(argc, argv, "sqBCDGILMSTEP:f:d:i:h:n:p:t:u:r:aZ:o:c:");
|
||||
while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
|
||||
switch (optstate->option) {
|
||||
case '?':
|
||||
|
@ -916,6 +949,10 @@ int main(int argc, char **argv)
|
|||
case 'I':
|
||||
importCRL = 1;
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
showFileCRL = 1;
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
case 'L':
|
||||
|
@ -987,10 +1024,7 @@ int main(int argc, char **argv)
|
|||
break;
|
||||
|
||||
case 't': {
|
||||
char *type;
|
||||
|
||||
type = strdup(optstate->value);
|
||||
crlType = atoi (type);
|
||||
crlType = atoi(optstate->value);
|
||||
if (crlType != SEC_CRL_TYPE && crlType != SEC_KRL_TYPE) {
|
||||
PR_fprintf(PR_STDERR, "%s: invalid crl type\n", progName);
|
||||
PL_DestroyOptState(optstate);
|
||||
|
@ -1018,12 +1052,13 @@ int main(int argc, char **argv)
|
|||
|
||||
if (deleteCRL && !nickName) Usage (progName);
|
||||
if (importCRL && !inFile) Usage (progName);
|
||||
if (showFileCRL && !inFile) Usage (progName);
|
||||
if ((generateCRL && !nickName) ||
|
||||
(modifyCRL && !inFile && !nickName)) Usage (progName);
|
||||
if (!(listCRL || deleteCRL || importCRL || generateCRL ||
|
||||
if (!(listCRL || deleteCRL || importCRL || showFileCRL || generateCRL ||
|
||||
modifyCRL || test || erase)) Usage (progName);
|
||||
|
||||
if (listCRL) {
|
||||
if (listCRL || showFileCRL) {
|
||||
readonly = PR_TRUE;
|
||||
}
|
||||
|
||||
|
@ -1031,12 +1066,18 @@ int main(int argc, char **argv)
|
|||
|
||||
PK11_SetPasswordFunc(SECU_GetModulePassword);
|
||||
|
||||
secstatus = NSS_Initialize(SECU_ConfigDirectory(NULL), dbPrefix, dbPrefix,
|
||||
"secmod.db", readonly ? NSS_INIT_READONLY : 0);
|
||||
if (secstatus != SECSuccess) {
|
||||
SECU_PrintPRandOSError(progName);
|
||||
return -1;
|
||||
if (showFileCRL) {
|
||||
NSS_NoDB_Init(NULL);
|
||||
}
|
||||
else {
|
||||
secstatus = NSS_Initialize(SECU_ConfigDirectory(NULL), dbPrefix, dbPrefix,
|
||||
"secmod.db", readonly ? NSS_INIT_READONLY : 0);
|
||||
if (secstatus != SECSuccess) {
|
||||
SECU_PrintPRandOSError(progName);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
SECU_RegisterDynamicOids();
|
||||
|
||||
certHandle = CERT_GetDefaultCertDB();
|
||||
|
@ -1059,6 +1100,9 @@ int main(int argc, char **argv)
|
|||
else if (importCRL) {
|
||||
rv = ImportCRL (certHandle, url, crlType, inFile, importOptions,
|
||||
decodeOptions, &pwdata);
|
||||
}
|
||||
else if (showFileCRL) {
|
||||
rv = DumpCRL (inFile);
|
||||
} else if (generateCRL || modifyCRL) {
|
||||
if (!inCrlInitFile)
|
||||
inCrlInitFile = PR_STDIN;
|
||||
|
|
|
@ -86,6 +86,19 @@ static char consoleName[] = {
|
|||
#include "nssutil.h"
|
||||
#include "ssl.h"
|
||||
|
||||
static PRBool wrapEnabled = PR_TRUE;
|
||||
|
||||
void
|
||||
SECU_EnableWrap(PRBool enable)
|
||||
{
|
||||
wrapEnabled = enable;
|
||||
}
|
||||
|
||||
PRBool
|
||||
SECU_GetWrapEnabled()
|
||||
{
|
||||
return wrapEnabled;
|
||||
}
|
||||
|
||||
void
|
||||
SECU_PrintErrMsg(FILE *out, int level, char *progName, char *msg, ...)
|
||||
|
@ -789,11 +802,15 @@ SECU_PrintAsHex(FILE *out, SECItem *data, const char *m, int level)
|
|||
unsigned int limit = 15;
|
||||
|
||||
if ( m ) {
|
||||
SECU_Indent(out, level); fprintf(out, "%s:\n", m);
|
||||
SECU_Indent(out, level); fprintf(out, "%s:", m);
|
||||
level++;
|
||||
if (wrapEnabled)
|
||||
fprintf(out, "\n");
|
||||
}
|
||||
|
||||
if (wrapEnabled) {
|
||||
SECU_Indent(out, level); column = level*INDENT_MULT;
|
||||
}
|
||||
|
||||
SECU_Indent(out, level); column = level*INDENT_MULT;
|
||||
if (!data->len) {
|
||||
fprintf(out, "(empty)\n");
|
||||
return;
|
||||
|
@ -826,7 +843,8 @@ SECU_PrintAsHex(FILE *out, SECItem *data, const char *m, int level)
|
|||
column += 2;
|
||||
break;
|
||||
}
|
||||
if (column > 76 || (i % 16 == limit)) {
|
||||
if (wrapEnabled &&
|
||||
(column > 76 || (i % 16 == limit))) {
|
||||
secu_Newline(out);
|
||||
SECU_Indent(out, level);
|
||||
column = level*INDENT_MULT;
|
||||
|
@ -849,7 +867,7 @@ SECU_PrintAsHex(FILE *out, SECItem *data, const char *m, int level)
|
|||
} else {
|
||||
column = 77;
|
||||
}
|
||||
if (column > 76) {
|
||||
if (wrapEnabled && column > 76) {
|
||||
secu_Newline(out);
|
||||
SECU_Indent(out, level); column = level*INDENT_MULT;
|
||||
}
|
||||
|
@ -975,7 +993,8 @@ SECU_PrintInteger(FILE *out, SECItem *i, char *m, int level)
|
|||
}
|
||||
|
||||
static void
|
||||
secu_PrintRawString(FILE *out, SECItem *si, const char *m, int level)
|
||||
secu_PrintRawStringQuotesOptional(FILE *out, SECItem *si, const char *m,
|
||||
int level, PRBool quotes)
|
||||
{
|
||||
int column;
|
||||
unsigned int i;
|
||||
|
@ -988,11 +1007,13 @@ secu_PrintRawString(FILE *out, SECItem *si, const char *m, int level)
|
|||
SECU_Indent(out, level);
|
||||
column = level*INDENT_MULT;
|
||||
}
|
||||
fprintf(out, "\""); column++;
|
||||
if (quotes) {
|
||||
fprintf(out, "\""); column++;
|
||||
}
|
||||
|
||||
for (i = 0; i < si->len; i++) {
|
||||
unsigned char val = si->data[i];
|
||||
if (column > 76) {
|
||||
if (wrapEnabled && column > 76) {
|
||||
secu_Newline(out);
|
||||
SECU_Indent(out, level); column = level*INDENT_MULT;
|
||||
}
|
||||
|
@ -1000,12 +1021,21 @@ secu_PrintRawString(FILE *out, SECItem *si, const char *m, int level)
|
|||
fprintf(out,"%c", printable[val]); column++;
|
||||
}
|
||||
|
||||
fprintf(out, "\""); column++;
|
||||
if (column != level*INDENT_MULT || column > 76) {
|
||||
if (quotes) {
|
||||
fprintf(out, "\""); column++;
|
||||
}
|
||||
if (wrapEnabled &&
|
||||
(column != level*INDENT_MULT || column > 76)) {
|
||||
secu_Newline(out);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
secu_PrintRawString(FILE *out, SECItem *si, const char *m, int level)
|
||||
{
|
||||
secu_PrintRawStringQuotesOptional(out, si, m, level, PR_TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
SECU_PrintString(FILE *out, SECItem *si, char *m, int level)
|
||||
{
|
||||
|
@ -2409,7 +2439,8 @@ SECU_PrintRDN(FILE *out, CERTRDN *rdn, const char *msg, int level)
|
|||
}
|
||||
|
||||
void
|
||||
SECU_PrintName(FILE *out, CERTName *name, const char *msg, int level)
|
||||
SECU_PrintNameQuotesOptional(FILE *out, CERTName *name, const char *msg,
|
||||
int level, PRBool quotes)
|
||||
{
|
||||
char *nameStr = NULL;
|
||||
char *str;
|
||||
|
@ -2430,7 +2461,7 @@ SECU_PrintName(FILE *out, CERTName *name, const char *msg, int level)
|
|||
my.data = (unsigned char *)str;
|
||||
my.len = PORT_Strlen(str);
|
||||
#if 1
|
||||
secu_PrintRawString(out, &my, msg, level);
|
||||
secu_PrintRawStringQuotesOptional(out, &my, msg, level, quotes);
|
||||
#else
|
||||
SECU_Indent(out, level); fprintf(out, "%s: ", msg);
|
||||
fprintf(out, str);
|
||||
|
@ -2439,6 +2470,12 @@ SECU_PrintName(FILE *out, CERTName *name, const char *msg, int level)
|
|||
PORT_Free(nameStr);
|
||||
}
|
||||
|
||||
void
|
||||
SECU_PrintName(FILE *out, CERTName *name, const char *msg, int level)
|
||||
{
|
||||
SECU_PrintNameQuotesOptional(out, name, msg, level, PR_TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
printflags(char *trusts, unsigned int flags)
|
||||
{
|
||||
|
@ -2753,8 +2790,15 @@ SECU_PrintFingerprints(FILE *out, SECItem *derCert, char *m, int level)
|
|||
fpItem.data = fingerprint;
|
||||
fpItem.len = MD5_LENGTH;
|
||||
fpStr = CERT_Hexify(&fpItem, 1);
|
||||
SECU_Indent(out, level); fprintf(out, "%s (MD5):\n", m);
|
||||
SECU_Indent(out, level+1); fprintf(out, "%s\n", fpStr);
|
||||
SECU_Indent(out, level); fprintf(out, "%s (MD5):", m);
|
||||
if (wrapEnabled) {
|
||||
fprintf(out, "\n");
|
||||
SECU_Indent(out, level+1);
|
||||
}
|
||||
else {
|
||||
fprintf(out, " ");
|
||||
}
|
||||
fprintf(out, "%s\n", fpStr);
|
||||
PORT_Free(fpStr);
|
||||
fpStr = NULL;
|
||||
if (rv != SECSuccess && !err)
|
||||
|
@ -2766,10 +2810,18 @@ SECU_PrintFingerprints(FILE *out, SECItem *derCert, char *m, int level)
|
|||
fpItem.data = fingerprint;
|
||||
fpItem.len = SHA1_LENGTH;
|
||||
fpStr = CERT_Hexify(&fpItem, 1);
|
||||
SECU_Indent(out, level); fprintf(out, "%s (SHA1):\n", m);
|
||||
SECU_Indent(out, level+1); fprintf(out, "%s\n", fpStr);
|
||||
SECU_Indent(out, level); fprintf(out, "%s (SHA1):", m);
|
||||
if (wrapEnabled) {
|
||||
fprintf(out, "\n");
|
||||
SECU_Indent(out, level+1);
|
||||
}
|
||||
else {
|
||||
fprintf(out, " ");
|
||||
}
|
||||
fprintf(out, "%s\n", fpStr);
|
||||
PORT_Free(fpStr);
|
||||
fprintf(out, "\n");
|
||||
if (wrapEnabled)
|
||||
fprintf(out, "\n");
|
||||
|
||||
if (err)
|
||||
PORT_SetError(err);
|
||||
|
@ -2907,7 +2959,7 @@ SECU_PrintCRLInfo(FILE *out, CERTCrl *crl, char *m, int level)
|
|||
if (crl->entries != NULL) {
|
||||
iv = 0;
|
||||
while ((entry = crl->entries[iv++]) != NULL) {
|
||||
sprintf(om, "Entry (%x):\n", iv);
|
||||
sprintf(om, "Entry %d (0x%x):\n", iv, iv);
|
||||
SECU_Indent(out, level + 1); fputs(om, out);
|
||||
SECU_PrintInteger(out, &(entry->serialNumber), "Serial Number",
|
||||
level + 2);
|
||||
|
|
|
@ -168,6 +168,9 @@ SECU_GetClientAuthData(void *arg, PRFileDesc *fd,
|
|||
struct CERTCertificateStr **pRetCert,
|
||||
struct SECKEYPrivateKeyStr **pRetKey);
|
||||
|
||||
extern PRBool SECU_GetWrapEnabled();
|
||||
extern void SECU_EnableWrap(PRBool enable);
|
||||
|
||||
/* print out an error message */
|
||||
extern void SECU_PrintError(char *progName, char *msg, ...);
|
||||
|
||||
|
@ -313,6 +316,9 @@ extern void SECU_PrintPrivKeyUsagePeriodExtension(FILE *out, SECItem *value,
|
|||
extern void SECU_PrintExtensions(FILE *out, CERTCertExtension **extensions,
|
||||
char *msg, int level);
|
||||
|
||||
extern void SECU_PrintNameQuotesOptional(FILE *out, CERTName *name,
|
||||
const char *msg, int level,
|
||||
PRBool quotes);
|
||||
extern void SECU_PrintName(FILE *out, CERTName *name, const char *msg,
|
||||
int level);
|
||||
extern void SECU_PrintRDN(FILE *out, CERTRDN *rdn, const char *msg, int level);
|
||||
|
|
|
@ -803,6 +803,8 @@ PRBool enableSessionTickets = PR_FALSE;
|
|||
PRBool enableCompression = PR_FALSE;
|
||||
PRBool failedToNegotiateName = PR_FALSE;
|
||||
static char *virtServerNameArray[MAX_VIRT_SERVER_NAME_ARRAY_INDEX];
|
||||
static int virtServerNameIndex = 1;
|
||||
|
||||
|
||||
static const char stopCmd[] = { "GET /stop " };
|
||||
static const char getCmd[] = { "GET " };
|
||||
|
@ -1706,10 +1708,12 @@ server_main(
|
|||
}
|
||||
}
|
||||
|
||||
rv = SSL_SNISocketConfigHook(model_sock, mySSLSNISocketConfig,
|
||||
(void*)&virtServerNameArray);
|
||||
if (rv != SECSuccess) {
|
||||
errExit("error enabling SNI extension ");
|
||||
if (virtServerNameIndex >1) {
|
||||
rv = SSL_SNISocketConfigHook(model_sock, mySSLSNISocketConfig,
|
||||
(void*)&virtServerNameArray);
|
||||
if (rv != SECSuccess) {
|
||||
errExit("error enabling SNI extension ");
|
||||
}
|
||||
}
|
||||
|
||||
for (kea = kt_rsa; kea < kt_kea_size; kea++) {
|
||||
|
@ -1935,7 +1939,6 @@ main(int argc, char **argv)
|
|||
SSL3Statistics *ssl3stats;
|
||||
PRUint32 i;
|
||||
secuPWData pwdata = { PW_NONE, 0 };
|
||||
int virtServerNameIndex = 1;
|
||||
char *expectedHostNameVal = NULL;
|
||||
|
||||
tmp = strrchr(argv[0], '/');
|
||||
|
|
|
@ -750,7 +750,7 @@ main(int argc, char **argv)
|
|||
|
||||
/* -P certdb name prefix */
|
||||
if (symKeyUtil.options[opt_dbPrefix].activated)
|
||||
certPrefix = strdup(symKeyUtil.options[opt_dbPrefix].arg);
|
||||
certPrefix = symKeyUtil.options[opt_dbPrefix].arg;
|
||||
|
||||
/* Check number of commands entered. */
|
||||
commandsEntered = 0;
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
/*
|
||||
* Certificate handling code
|
||||
*
|
||||
* $Id: certdb.c,v 1.120 2011/11/17 00:20:20 bsmith%mozilla.com Exp $
|
||||
* $Id: certdb.c,v 1.121 2012/03/23 03:25:57 wtc%google.com Exp $
|
||||
*/
|
||||
|
||||
#include "nssilock.h"
|
||||
|
@ -596,6 +596,20 @@ cert_ComputeCertType(CERTCertificate *cert)
|
|||
nsCertType |= NS_CERT_TYPE_SSL_SERVER;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Treat certs with step-up OID as also having SSL server type.
|
||||
* COMODO needs this behaviour until June 2020. See Bug 737802.
|
||||
*/
|
||||
if (findOIDinOIDSeqByTagNum(extKeyUsage,
|
||||
SEC_OID_NS_KEY_USAGE_GOVT_APPROVED) ==
|
||||
SECSuccess){
|
||||
if (basicConstraintPresent == PR_TRUE &&
|
||||
(basicConstraint.isCA)) {
|
||||
nsCertType |= NS_CERT_TYPE_SSL_CA;
|
||||
} else {
|
||||
nsCertType |= NS_CERT_TYPE_SSL_SERVER;
|
||||
}
|
||||
}
|
||||
if (findOIDinOIDSeqByTagNum(extKeyUsage,
|
||||
SEC_OID_EXT_KEY_USAGE_CLIENT_AUTH) ==
|
||||
SECSuccess){
|
||||
|
|
|
@ -631,7 +631,7 @@ CERT_FindCertByDERCert(CERTCertDBHandle *handle, SECItem *derCert)
|
|||
|
||||
static CERTCertificate *
|
||||
common_FindCertByNicknameOrEmailAddrForUsage(CERTCertDBHandle *handle,
|
||||
char *name,
|
||||
const char *name,
|
||||
PRBool anyUsage,
|
||||
SECCertUsage lookingForUsage)
|
||||
{
|
||||
|
|
|
@ -1426,8 +1426,8 @@ struct fake_PKIX_PL_CertStruct {
|
|||
/* This needs to be part of the PKIX_PL_* */
|
||||
/* This definitely needs to go away, and be replaced with
|
||||
a real accessor function in PKIX */
|
||||
CERTCertificate *
|
||||
cert_NSSCertFromPKIXCert(const PKIX_PL_Cert *pkix_cert, void *plContext)
|
||||
static CERTCertificate *
|
||||
cert_NSSCertFromPKIXCert(const PKIX_PL_Cert *pkix_cert)
|
||||
{
|
||||
struct fake_PKIX_PL_CertStruct *fcert = NULL;
|
||||
|
||||
|
@ -2217,10 +2217,12 @@ do {
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
error = PKIX_TrustAnchor_GetTrustedCert( trustAnchor, &trustAnchorCert,
|
||||
plContext);
|
||||
if (error != NULL) {
|
||||
goto cleanup;
|
||||
if (trustAnchor != NULL) {
|
||||
error = PKIX_TrustAnchor_GetTrustedCert( trustAnchor, &trustAnchorCert,
|
||||
plContext);
|
||||
if (error != NULL) {
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PKIX_OBJECT_LEAK_TEST
|
||||
|
@ -2231,8 +2233,12 @@ do {
|
|||
|
||||
oparam = cert_pkix_FindOutputParam(paramsOut, cert_po_trustAnchor);
|
||||
if (oparam != NULL) {
|
||||
oparam->value.pointer.cert =
|
||||
cert_NSSCertFromPKIXCert(trustAnchorCert,plContext);
|
||||
if (trustAnchorCert != NULL) {
|
||||
oparam->value.pointer.cert =
|
||||
cert_NSSCertFromPKIXCert(trustAnchorCert);
|
||||
} else {
|
||||
oparam->value.pointer.cert = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
error = PKIX_BuildResult_GetCertChain( buildResult, &builtCertList,
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
* Implementation of OCSP services, for both client and server.
|
||||
* (XXX, really, mostly just for client right now, but intended to do both.)
|
||||
*
|
||||
* $Id: ocsp.c,v 1.67 2011/08/10 12:31:52 kaie%kuix.de Exp $
|
||||
* $Id: ocsp.c,v 1.69 2012/03/14 22:26:53 wtc%google.com Exp $
|
||||
*/
|
||||
|
||||
#include "prerror.h"
|
||||
|
@ -296,7 +296,7 @@ SECStatus
|
|||
SEC_RegisterDefaultHttpClient(const SEC_HttpClientFcn *fcnTable)
|
||||
{
|
||||
if (!OCSP_Global.monitor) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
|
@ -315,7 +315,7 @@ CERT_RegisterAlternateOCSPAIAInfoCallBack(
|
|||
CERT_StringFromCertFcn old;
|
||||
|
||||
if (!OCSP_Global.monitor) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
|
@ -991,7 +991,7 @@ const SEC_HttpClientFcn *SEC_GetRegisteredHttpClient()
|
|||
const SEC_HttpClientFcn *retval;
|
||||
|
||||
if (!OCSP_Global.monitor) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -2700,10 +2700,10 @@ ocsp_GetResponseSignature(CERTOCSPResponse *response)
|
|||
if (NULL == response->responseBytes) {
|
||||
return NULL;
|
||||
}
|
||||
PORT_Assert(response->responseBytes != NULL);
|
||||
PORT_Assert(response->responseBytes->responseTypeTag
|
||||
== SEC_OID_PKIX_OCSP_BASIC_RESPONSE);
|
||||
|
||||
if (response->responseBytes->responseTypeTag
|
||||
!= SEC_OID_PKIX_OCSP_BASIC_RESPONSE) {
|
||||
return NULL;
|
||||
}
|
||||
basic = response->responseBytes->decodedResponse.basic;
|
||||
PORT_Assert(basic != NULL);
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* $Id: secvfy.c,v 1.25 2011/10/22 14:35:42 wtc%google.com Exp $ */
|
||||
/* $Id: secvfy.c,v 1.28 2012/02/25 14:32:45 kaie%kuix.de Exp $ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "cryptohi.h"
|
||||
|
@ -300,11 +300,13 @@ sec_DecodeSigAlg(const SECKEYPublicKey *key, SECOidTag sigAlg,
|
|||
return SECFailure;
|
||||
}
|
||||
rv = SEC_QuickDERDecodeItem(arena, &oid, hashParameterTemplate, param);
|
||||
if (rv != SECSuccess) {
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
if (rv == SECSuccess) {
|
||||
*hashalg = SECOID_FindOIDTag(&oid);
|
||||
}
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
if (rv != SECSuccess) {
|
||||
return rv;
|
||||
}
|
||||
*hashalg = SECOID_FindOIDTag(&oid);
|
||||
/* only accept hash algorithms */
|
||||
if (HASH_GetHashTypeByOidTag(*hashalg) == HASH_AlgNULL) {
|
||||
/* error set by HASH_GetHashTypeByOidTag */
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* $Id: blapi.h,v 1.43 2011/10/29 23:28:45 wtc%google.com Exp $ */
|
||||
/* $Id: blapi.h,v 1.45 2012/03/28 22:38:27 rrelyea%redhat.com Exp $ */
|
||||
|
||||
#ifndef _BLAPI_H_
|
||||
#define _BLAPI_H_
|
||||
|
@ -212,8 +212,13 @@ extern SECStatus DH_NewKey(DHParams * params,
|
|||
** the prime. If successful, derivedSecret->data is set
|
||||
** to the address of the newly allocated buffer containing the derived
|
||||
** secret, and derivedSecret->len is the size of the secret produced.
|
||||
** The size of the secret produced will never be larger than the length
|
||||
** of the prime, and it may be smaller than maxOutBytes.
|
||||
** The size of the secret produced will depend on the value of outBytes.
|
||||
** If outBytes is 0, the key length will be all the significant bytes of
|
||||
** the derived secret (leading zeros are dropped). This length could be less
|
||||
** than the length of the prime. If outBytes is nonzero, the length of the
|
||||
** produced key will be outBytes long. If the key is truncated, the most
|
||||
** significant bytes are truncated. If it is expanded, zero bytes are added
|
||||
** at the beginning.
|
||||
** It is the caller's responsibility to free the allocated buffer
|
||||
** containing the derived secret.
|
||||
*/
|
||||
|
@ -221,7 +226,7 @@ extern SECStatus DH_Derive(SECItem * publicValue,
|
|||
SECItem * prime,
|
||||
SECItem * privateValue,
|
||||
SECItem * derivedSecret,
|
||||
unsigned int maxOutBytes);
|
||||
unsigned int outBytes);
|
||||
|
||||
/*
|
||||
** KEA_CalcKey returns octet string with the private key for a dual
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* $Id: blapit.h,v 1.25 2012/01/13 16:53:15 emaldona%redhat.com Exp $ */
|
||||
/* $Id: blapit.h,v 1.26 2012/03/28 22:35:14 rrelyea%redhat.com Exp $ */
|
||||
|
||||
#ifndef _BLAPIT_H_
|
||||
#define _BLAPIT_H_
|
||||
|
@ -142,7 +142,7 @@
|
|||
#define RSA_MAX_MODULUS_BITS 8192
|
||||
#define RSA_MAX_EXPONENT_BITS 64
|
||||
#define DH_MIN_P_BITS 128
|
||||
#define DH_MAX_P_BITS 2236
|
||||
#define DH_MAX_P_BITS 3072
|
||||
|
||||
/*
|
||||
* The FIPS 186 algorithm for generating primes P and Q allows only 9
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
* Diffie-Hellman parameter generation, key generation, and secret derivation.
|
||||
* KEA secret generation and verification.
|
||||
*
|
||||
* $Id: dh.c,v 1.9 2010/07/20 01:26:02 wtc%google.com Exp $
|
||||
* $Id: dh.c,v 1.10 2012/03/28 22:35:14 rrelyea%redhat.com Exp $
|
||||
*/
|
||||
#ifdef FREEBL_NO_DEPEND
|
||||
#include "stubs.h"
|
||||
|
@ -215,7 +215,7 @@ DH_Derive(SECItem *publicValue,
|
|||
SECItem *prime,
|
||||
SECItem *privateValue,
|
||||
SECItem *derivedSecret,
|
||||
unsigned int maxOutBytes)
|
||||
unsigned int outBytes)
|
||||
{
|
||||
mp_int p, Xa, Yb, ZZ;
|
||||
mp_err err = MP_OKAY;
|
||||
|
@ -251,15 +251,24 @@ DH_Derive(SECItem *publicValue,
|
|||
/* grab the derived secret */
|
||||
err = mp_to_unsigned_octets(&ZZ, secret, len);
|
||||
if (err >= 0) err = MP_OKAY;
|
||||
/* Take minimum of bytes requested and bytes in derived secret,
|
||||
** if maxOutBytes is 0 take all of the bytes from the derived secret.
|
||||
/*
|
||||
** if outBytes is 0 take all of the bytes from the derived secret.
|
||||
** if outBytes is not 0 take exactly outBytes from the derived secret, zero
|
||||
** pad at the beginning if necessary, and truncate beginning bytes
|
||||
** if necessary.
|
||||
*/
|
||||
if (maxOutBytes > 0)
|
||||
nb = PR_MIN(len, maxOutBytes);
|
||||
if (outBytes > 0)
|
||||
nb = outBytes;
|
||||
else
|
||||
nb = len;
|
||||
SECITEM_AllocItem(NULL, derivedSecret, nb);
|
||||
memcpy(derivedSecret->data, secret, nb);
|
||||
if (len < nb) {
|
||||
unsigned int offset = nb - len;
|
||||
memset(derivedSecret->data, 0, offset);
|
||||
memcpy(derivedSecret->data + offset, secret, len);
|
||||
} else {
|
||||
memcpy(derivedSecret->data, secret + len - nb, nb);
|
||||
}
|
||||
cleanup:
|
||||
mp_clear(&p);
|
||||
mp_clear(&Xa);
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче