Compare commits
2 Commits
HttpConnec
...
regalloc_c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1c43d4984f | ||
|
|
cfe021ff88 |
@@ -1,27 +0,0 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape 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/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
|
||||
# XP way of doing the build date.
|
||||
# 1998091509 = 1998, September, 15th, 9am local time zone
|
||||
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime;
|
||||
# localtime returns year minus 1900
|
||||
$year = $year + 1900;
|
||||
printf("#define PRODUCT_VERSION \"%04d%02d%02d\"\n", $year, 1+$mon, $mday);
|
||||
@@ -1,90 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Alec Flett <alecf@netscape.com>
|
||||
*/
|
||||
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsICategoryManager.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsXPIDLString.h"
|
||||
|
||||
#include "nsContentHTTPStartup.h"
|
||||
#include "nsIHttpProtocolHandler.h"
|
||||
#include "gbdate.h"
|
||||
|
||||
#define PRODUCT_NAME "Gecko"
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsContentHTTPStartup,nsIObserver)
|
||||
|
||||
nsresult
|
||||
nsContentHTTPStartup::Observe( nsISupports *aSubject,
|
||||
const PRUnichar *aTopic,
|
||||
const PRUnichar *aData)
|
||||
{
|
||||
if (nsCRT::strcmp(aTopic, NS_HTTP_STARTUP_TOPIC) != 0)
|
||||
return NS_OK;
|
||||
|
||||
nsresult rv = nsnull;
|
||||
|
||||
nsCOMPtr<nsIHttpProtocolHandler> http(do_QueryInterface(aSubject));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = http->SetProduct(PRODUCT_NAME);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = http->SetProductSub((char*) PRODUCT_VERSION);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsContentHTTPStartup::RegisterHTTPStartup()
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsICategoryManager>
|
||||
catMan(do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv));
|
||||
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsXPIDLCString previousEntry;
|
||||
rv = catMan->AddCategoryEntry(NS_HTTP_STARTUP_CATEGORY,
|
||||
"Content UserAgent Setter",
|
||||
NS_CONTENTHTTPSTARTUP_CONTRACTID,
|
||||
PR_TRUE, PR_TRUE,
|
||||
getter_Copies(previousEntry));
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsContentHTTPStartup::UnregisterHTTPStartup()
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsICategoryManager>
|
||||
catMan(do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv));
|
||||
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,121 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#ifndef nsXMLDocument_h___
|
||||
#define nsXMLDocument_h___
|
||||
|
||||
#include "nsMarkupDocument.h"
|
||||
#include "nsIXMLDocument.h"
|
||||
#include "nsIHTMLContentContainer.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIHttpEventSink.h"
|
||||
|
||||
class nsIParser;
|
||||
class nsIDOMNode;
|
||||
class nsICSSLoader;
|
||||
class nsIURI;
|
||||
|
||||
class nsXMLDocument : public nsMarkupDocument,
|
||||
public nsIXMLDocument,
|
||||
public nsIHTMLContentContainer,
|
||||
public nsIInterfaceRequestor,
|
||||
public nsIHttpEventSink
|
||||
{
|
||||
public:
|
||||
nsXMLDocument();
|
||||
virtual ~nsXMLDocument();
|
||||
|
||||
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
|
||||
|
||||
NS_IMETHOD_(nsrefcnt) AddRef(void);
|
||||
NS_IMETHOD_(nsrefcnt) Release(void);
|
||||
|
||||
NS_IMETHOD Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup);
|
||||
|
||||
NS_IMETHOD GetContentType(nsAWritableString& aContentType) const;
|
||||
|
||||
NS_IMETHOD StartDocumentLoad(const char* aCommand,
|
||||
nsIChannel* channel,
|
||||
nsILoadGroup* aLoadGroup,
|
||||
nsISupports* aContainer,
|
||||
nsIStreamListener **aDocListener,
|
||||
PRBool aReset = PR_TRUE);
|
||||
|
||||
NS_IMETHOD EndLoad();
|
||||
|
||||
NS_IMETHOD GetBaseTarget(nsAWritableString &aBaseTarget);
|
||||
NS_IMETHOD SetBaseTarget(const nsAReadableString &aBaseTarget);
|
||||
|
||||
// nsIDOMNode interface
|
||||
NS_IMETHOD CloneNode(PRBool aDeep, nsIDOMNode** aReturn);
|
||||
|
||||
// nsIDOMDocument interface
|
||||
NS_IMETHOD GetDoctype(nsIDOMDocumentType** aDocumentType);
|
||||
NS_IMETHOD CreateCDATASection(const nsAReadableString& aData, nsIDOMCDATASection** aReturn);
|
||||
NS_IMETHOD CreateEntityReference(const nsAReadableString& aName, nsIDOMEntityReference** aReturn);
|
||||
NS_IMETHOD CreateProcessingInstruction(const nsAReadableString& aTarget, const nsAReadableString& aData, nsIDOMProcessingInstruction** aReturn);
|
||||
NS_IMETHOD CreateElement(const nsAReadableString& aTagName,
|
||||
nsIDOMElement** aReturn);
|
||||
NS_IMETHOD ImportNode(nsIDOMNode* aImportedNode,
|
||||
PRBool aDeep,
|
||||
nsIDOMNode** aReturn);
|
||||
NS_IMETHOD CreateElementNS(const nsAReadableString& aNamespaceURI,
|
||||
const nsAReadableString& aQualifiedName,
|
||||
nsIDOMElement** aReturn);
|
||||
NS_IMETHOD CreateAttributeNS(const nsAReadableString& aNamespaceURI,
|
||||
const nsAReadableString& aQualifiedName,
|
||||
nsIDOMAttr** aReturn);
|
||||
NS_IMETHOD GetElementById(const nsAReadableString& aElementId,
|
||||
nsIDOMElement** aReturn);
|
||||
NS_IMETHOD Load(const nsAReadableString& aUrl);
|
||||
|
||||
// nsIXMLDocument interface
|
||||
NS_IMETHOD SetDefaultStylesheets(nsIURI* aUrl);
|
||||
NS_IMETHOD SetTitle(const PRUnichar *aTitle);
|
||||
|
||||
// nsIHTMLContentContainer
|
||||
NS_IMETHOD GetAttributeStyleSheet(nsIHTMLStyleSheet** aResult);
|
||||
NS_IMETHOD GetInlineStyleSheet(nsIHTMLCSSStyleSheet** aResult);
|
||||
NS_IMETHOD GetCSSLoader(nsICSSLoader*& aLoader);
|
||||
|
||||
// nsIInterfaceRequestor
|
||||
NS_IMETHOD GetInterface(const nsIID& aIID, void** aSink);
|
||||
|
||||
// nsIHTTPEventSink
|
||||
NS_DECL_NSIHTTPEVENTSINK
|
||||
|
||||
protected:
|
||||
virtual void InternalAddStyleSheet(nsIStyleSheet* aSheet); // subclass hook for sheet ordering
|
||||
virtual void InternalInsertStyleSheetAt(nsIStyleSheet* aSheet, PRInt32 aIndex);
|
||||
|
||||
// For HTML elements in our content model
|
||||
// XXX This is not clean, but is there a better way?
|
||||
nsIHTMLStyleSheet* mAttrStyleSheet;
|
||||
nsIHTMLCSSStyleSheet* mInlineStyleSheet;
|
||||
nsString mBaseTarget;
|
||||
|
||||
nsIParser *mParser;
|
||||
nsICSSLoader* mCSSLoader;
|
||||
};
|
||||
|
||||
|
||||
#endif // nsXMLDocument_h___
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
134
mozilla/ef/Compiler/RegisterAllocator/BitSet.cpp
Normal file
134
mozilla/ef/Compiler/RegisterAllocator/BitSet.cpp
Normal file
@@ -0,0 +1,134 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "BitSet.h"
|
||||
|
||||
// Return the next bit after index set to true or -1 if none.
|
||||
//
|
||||
Int32 BitSet::nextOne(Int32 pos) const
|
||||
{
|
||||
++pos;
|
||||
|
||||
if (pos < 0 || Uint32(pos) >= universeSize)
|
||||
return -1;
|
||||
|
||||
Uint32 offset = getWordOffset(pos);
|
||||
Uint8 index = getBitOffset(pos);
|
||||
Word* ptr = &word[offset];
|
||||
Word currentWord = *ptr++ >> index;
|
||||
|
||||
if (currentWord != Word(0)) {
|
||||
while ((currentWord & Word(1)) == 0) {
|
||||
++index;
|
||||
currentWord >>= 1;
|
||||
}
|
||||
return (offset << nBitsInWordLog2) + index;
|
||||
}
|
||||
|
||||
Word* limit = &word[getSizeInWords(universeSize)];
|
||||
while (ptr < limit) {
|
||||
++offset;
|
||||
currentWord = *ptr++;
|
||||
if (currentWord != Word(0)) {
|
||||
index = 0;
|
||||
while ((currentWord & Word(1)) == 0) {
|
||||
++index;
|
||||
currentWord >>= 1;
|
||||
}
|
||||
return (offset << nBitsInWordLog2) + index;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Return the next bit after index set to false or -1 if none.
|
||||
//
|
||||
Int32 BitSet::nextZero(Int32 pos) const
|
||||
{
|
||||
++pos;
|
||||
|
||||
if (pos < 0 || Uint32(pos) >= universeSize)
|
||||
return -1;
|
||||
|
||||
Uint32 offset = getWordOffset(pos);
|
||||
Uint8 index = getBitOffset(pos);
|
||||
Word* ptr = &word[offset];
|
||||
Word currentWord = *ptr++ >> index;
|
||||
|
||||
if (currentWord != Word(~0)) {
|
||||
for (; index < nBitsInWord; ++index) {
|
||||
if ((currentWord & Word(1)) == 0) {
|
||||
Int32 ret = (offset << nBitsInWordLog2) + index;
|
||||
return (Uint32(ret) < universeSize) ? ret : -1;
|
||||
}
|
||||
currentWord >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
Word* limit = &word[getSizeInWords(universeSize)];
|
||||
while (ptr < limit) {
|
||||
++offset;
|
||||
currentWord = *ptr++;
|
||||
if (currentWord != Word(~0)) {
|
||||
for (index = 0; index < nBitsInWord; ++index) {
|
||||
if ((currentWord & Word(1)) == 0) {
|
||||
Int32 ret = (offset << nBitsInWordLog2) + index;
|
||||
return (Uint32(ret) < universeSize) ? ret : -1;
|
||||
}
|
||||
currentWord >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
|
||||
// Print the set.
|
||||
//
|
||||
void BitSet::printPretty(LogModuleObject log)
|
||||
{
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("[ "));
|
||||
|
||||
for (Int32 i = firstOne(); i != -1; i = nextOne(i)) {
|
||||
Int32 currentBit = i;
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%d", currentBit));
|
||||
|
||||
Int32 nextBit = nextOne(currentBit);
|
||||
if (nextBit != currentBit + 1) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (" "));
|
||||
continue;
|
||||
}
|
||||
|
||||
while ((nextBit != -1) && (nextBit == (currentBit + 1))) {
|
||||
currentBit = nextBit;
|
||||
nextBit = nextOne(nextBit);
|
||||
}
|
||||
|
||||
if (currentBit > (i+1))
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("-%d ", currentBit));
|
||||
else
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (" %d ", currentBit));
|
||||
|
||||
i = currentBit;
|
||||
}
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("]\n"));
|
||||
}
|
||||
|
||||
#endif // DEBUG_LOG
|
||||
195
mozilla/ef/Compiler/RegisterAllocator/BitSet.h
Normal file
195
mozilla/ef/Compiler/RegisterAllocator/BitSet.h
Normal file
@@ -0,0 +1,195 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _BITSET_H_
|
||||
#define _BITSET_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "LogModule.h"
|
||||
#include "Pool.h"
|
||||
#include <string.h>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// BitSet -
|
||||
|
||||
class BitSet
|
||||
{
|
||||
private:
|
||||
|
||||
#if (PR_BITS_PER_WORD == 64)
|
||||
typedef Uint64 Word;
|
||||
#elif (PR_BITS_PER_WORD == 32)
|
||||
typedef Uint32 Word;
|
||||
#endif
|
||||
|
||||
static const nBitsInWord = PR_BITS_PER_WORD;
|
||||
static const nBytesInWord = PR_BYTES_PER_WORD;
|
||||
static const nBitsInWordLog2 = PR_BITS_PER_WORD_LOG2;
|
||||
static const nBytesInWordLog2 = PR_BYTES_PER_WORD_LOG2;
|
||||
|
||||
// Return the number of Word need to store the universe.
|
||||
static Uint32 getSizeInWords(Uint32 sizeOfUniverse) {return (sizeOfUniverse + (nBitsInWord - 1)) >> nBitsInWordLog2;}
|
||||
// Return the given element offset in its containing Word.
|
||||
static Uint32 getBitOffset(Uint32 element) {return element & (nBitsInWord - 1);}
|
||||
// Return the Word offset for the given element int the universe.
|
||||
static Uint32 getWordOffset(Uint32 element) {return element >> nBitsInWordLog2;}
|
||||
// Return the mask for the given bit index.
|
||||
static Word getMask(Uint8 index) {return Word(1) << index;}
|
||||
|
||||
private:
|
||||
|
||||
Uint32 universeSize; // Size of the universe
|
||||
Word* word; // universe memory.
|
||||
|
||||
private:
|
||||
|
||||
// No copy constructor.
|
||||
BitSet(const BitSet&);
|
||||
|
||||
// Check if the given set's universe is of the same size than this universe.
|
||||
void checkUniverseCompatibility(const BitSet& set) const {assert(set.universeSize == universeSize);}
|
||||
// Check if pos is valid for this set's universe.
|
||||
void checkMember(Int32 pos) const {assert(pos >=0 && Uint32(pos) < universeSize);}
|
||||
|
||||
public:
|
||||
|
||||
// Create a bitset of universeSize bits.
|
||||
BitSet(Pool& pool, Uint32 universeSize) : universeSize(universeSize) {word = new(pool) Word[getSizeInWords(universeSize)]; clear();}
|
||||
|
||||
// Return the size of this bitset.
|
||||
Uint32 getSize() const {return universeSize;}
|
||||
|
||||
// Clear the bitset.
|
||||
void clear() {memset(word, 0x00, getSizeInWords(universeSize) << nBytesInWordLog2);}
|
||||
// Clear the bit at index.
|
||||
void clear(Uint32 index) {checkMember(index); word[getWordOffset(index)] &= ~getMask(index);}
|
||||
// Set the bitset.
|
||||
void set() {memset(word, 0xFF, getSizeInWords(universeSize) << nBytesInWordLog2);}
|
||||
// Set the bit at index.
|
||||
void set(Uint32 index) {checkMember(index); word[getWordOffset(index)] |= getMask(index);}
|
||||
// Return true if the bit at index is set.
|
||||
bool test(Uint32 index) const {checkMember(index); return (word[getWordOffset(index)] & getMask(index)) != 0;}
|
||||
// Union with the given bitset.
|
||||
inline void or(const BitSet& set);
|
||||
// Intersection with the given bitset.
|
||||
inline void and(const BitSet& set);
|
||||
// Difference with the given bitset.
|
||||
inline void difference(const BitSet& set);
|
||||
// Copy set.
|
||||
inline BitSet& operator = (const BitSet& set);
|
||||
// Return true if the bitset are identical.
|
||||
friend bool operator == (const BitSet& set1, const BitSet& set2);
|
||||
// Return true if the bitset are different.
|
||||
friend bool operator != (const BitSet& set1, const BitSet& set2);
|
||||
|
||||
// Logical operators.
|
||||
BitSet& operator |= (const BitSet& set) {or(set); return *this;}
|
||||
BitSet& operator &= (const BitSet& set) {and(set); return *this;}
|
||||
BitSet& operator -= (const BitSet& set) {difference(set); return *this;}
|
||||
|
||||
// Return the first bit at set to true or -1 if none.
|
||||
Int32 firstOne() const {return nextOne(-1);}
|
||||
// Return the next bit after index set to true or -1 if none.
|
||||
Int32 nextOne(Int32 pos) const;
|
||||
// Return the first bit at set to false or -1 if none.
|
||||
Int32 firstZero() const {return nextZero(-1);}
|
||||
// Return the next bit after index set to false or -1 if none.
|
||||
Int32 nextZero(Int32 pos) const;
|
||||
|
||||
// Iterator to conform with the set API.
|
||||
typedef Int32 iterator;
|
||||
// Return true if the walk is ordered.
|
||||
static bool isOrdered() {return true;}
|
||||
// Return the iterator for the first element of this set.
|
||||
iterator begin() const {return firstOne();}
|
||||
// Return the next iterator.
|
||||
iterator advance(iterator pos) const {return nextOne(pos);}
|
||||
// Return true if the iterator is at the end of the set.
|
||||
bool done(iterator pos) const {return pos == -1;}
|
||||
// Return the element corresponding to the given iterator.
|
||||
Uint32 get(iterator pos) const {return pos;}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
// Print the set.
|
||||
void printPretty(LogModuleObject log);
|
||||
#endif // DEBUG_LOG
|
||||
};
|
||||
|
||||
// Union with the given bitset.
|
||||
//
|
||||
inline void BitSet::or(const BitSet& set)
|
||||
{
|
||||
checkUniverseCompatibility(set);
|
||||
Word* src = set.word;
|
||||
Word* dst = word;
|
||||
Word* limit = &src[getSizeInWords(universeSize)];
|
||||
|
||||
while (src < limit)
|
||||
*dst++ |= *src++;
|
||||
}
|
||||
|
||||
// Intersection with the given bitset.
|
||||
//
|
||||
inline void BitSet::and(const BitSet& set)
|
||||
{
|
||||
checkUniverseCompatibility(set);
|
||||
Word* src = set.word;
|
||||
Word* dst = word;
|
||||
Word* limit = &src[getSizeInWords(universeSize)];
|
||||
|
||||
while (src < limit)
|
||||
*dst++ &= *src++;
|
||||
}
|
||||
|
||||
// Difference with the given bitset.
|
||||
//
|
||||
inline void BitSet::difference(const BitSet& set)
|
||||
{
|
||||
checkUniverseCompatibility(set);
|
||||
Word* src = set.word;
|
||||
Word* dst = word;
|
||||
Word* limit = &src[getSizeInWords(universeSize)];
|
||||
|
||||
while (src < limit)
|
||||
*dst++ &= ~*src++;
|
||||
}
|
||||
|
||||
// Copy the given set into this set.
|
||||
//
|
||||
inline BitSet& BitSet::operator = (const BitSet& set)
|
||||
{
|
||||
checkUniverseCompatibility(set);
|
||||
if (this != &set)
|
||||
memcpy(word, set.word, getSizeInWords(universeSize) << nBytesInWordLog2);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Return true if the given set is identical to this set.
|
||||
inline bool operator == (const BitSet& set1, const BitSet& set2)
|
||||
{
|
||||
set1.checkUniverseCompatibility(set2);
|
||||
|
||||
if (&set1 == &set2)
|
||||
return true;
|
||||
|
||||
return memcmp(set1.word, set2.word, BitSet::getSizeInWords(set1.universeSize) << BitSet::nBytesInWordLog2) == 0;
|
||||
}
|
||||
|
||||
inline bool operator != (const BitSet& set1, const BitSet& set2) {return !(set1 == set2);}
|
||||
|
||||
#endif // _BITSET_H
|
||||
159
mozilla/ef/Compiler/RegisterAllocator/Coalescing.h
Normal file
159
mozilla/ef/Compiler/RegisterAllocator/Coalescing.h
Normal file
@@ -0,0 +1,159 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _COALESCING_H_
|
||||
#define _COALESCING_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "Pool.h"
|
||||
#include "RegisterPressure.h"
|
||||
#include "InterferenceGraph.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Instruction.h"
|
||||
#include "SparseSet.h"
|
||||
#include "RegisterAllocator.h"
|
||||
#include "RegisterAllocatorTools.h"
|
||||
|
||||
#if 1
|
||||
// Performing an ultra conservative coalescing meens that when we look at
|
||||
// candidates (source,destination) for coalescing we need to make sure
|
||||
// that the combined interference of the source and destination register
|
||||
// will not exceed the total number of register available for the register
|
||||
// class.
|
||||
#define ULTRA_CONSERVATIVE_COALESCING
|
||||
#else
|
||||
// If we are not doing an ultra conservative coalescing we have to make sure
|
||||
// that the total number of neighbor whose degree is greater than the total
|
||||
// number of register is not greater than the total number of register.
|
||||
#undef ULTRA_CONSERVATIVE_COALESCING
|
||||
#endif
|
||||
|
||||
template <class RegisterPressure>
|
||||
struct Coalescing
|
||||
{
|
||||
static bool coalesce(RegisterAllocator& registerAllocator);
|
||||
};
|
||||
|
||||
template <class RegisterPressure>
|
||||
bool Coalescing<RegisterPressure>::coalesce(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
Pool& pool = registerAllocator.pool;
|
||||
|
||||
// Initialize the lookup table
|
||||
//
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
RegisterName* newRange = new RegisterName[2 * rangeCount];
|
||||
RegisterName* coalescedRange = &newRange[rangeCount];
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
|
||||
init(coalescedRange, rangeCount);
|
||||
|
||||
SparseSet interferences(pool, rangeCount);
|
||||
InterferenceGraph<RegisterPressure>& iGraph = registerAllocator.iGraph;
|
||||
bool removedInstructions = false;
|
||||
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
ControlNode** nodes = controlGraph.lndList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
|
||||
// Walk the nodes in the loop nesting depth list.
|
||||
for (Int32 n = nNodes - 1; n >= 0; n--) {
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
|
||||
InstructionList::iterator it = instructions.begin();
|
||||
while (!instructions.done(it)) {
|
||||
Instruction& instruction = instructions.get(it);
|
||||
it = instructions.advance(it);
|
||||
|
||||
if ((instruction.getFlags() & ifCopy) != 0) {
|
||||
assert(instruction.getInstructionUseBegin() != instruction.getInstructionUseEnd() && instruction.getInstructionUseBegin()[0].isRegister());
|
||||
assert(instruction.getInstructionDefineBegin() != instruction.getInstructionDefineEnd() && instruction.getInstructionDefineBegin()[0].isRegister());
|
||||
|
||||
RegisterName source = findRoot(name2range[instruction.getInstructionUseBegin()[0].getRegisterName()], coalescedRange);
|
||||
RegisterName destination = findRoot(name2range[instruction.getInstructionDefineBegin()[0].getRegisterName()], coalescedRange);
|
||||
|
||||
if (source == destination) {
|
||||
instruction.remove();
|
||||
} else if (!iGraph.interfere(source, destination)) {
|
||||
InterferenceVector* sourceVector = iGraph.getInterferenceVector(source);
|
||||
InterferenceVector* destinationVector = iGraph.getInterferenceVector(destination);
|
||||
|
||||
#ifdef ULTRA_CONSERVATIVE_COALESCING
|
||||
interferences.clear();
|
||||
|
||||
InterferenceVector* vector;
|
||||
for (vector = sourceVector; vector != NULL; vector = vector->next) {
|
||||
RegisterName* neighbors = vector->neighbors;
|
||||
for (Uint32 i = 0; i < vector->count; i++)
|
||||
interferences.set(findRoot(neighbors[i], coalescedRange));
|
||||
}
|
||||
for (vector = destinationVector; vector != NULL; vector = vector->next) {
|
||||
RegisterName* neighbors = vector->neighbors;
|
||||
for (Uint32 i = 0; i < vector->count; i++)
|
||||
interferences.set(findRoot(neighbors[i], coalescedRange));
|
||||
}
|
||||
|
||||
Uint32 count = interferences.getSize();
|
||||
#else // ULTRA_CONSERVATIVE_COALESCING
|
||||
trespass("not implemented");
|
||||
Uint32 count = 0;
|
||||
#endif // ULTRA_CONSERVATIVE_COALESCING
|
||||
|
||||
if (count < 6 /* FIX: should get the number from the class */) {
|
||||
// Update the interferences vector.
|
||||
if (sourceVector == NULL) {
|
||||
iGraph.setInterferenceVector(source, destinationVector);
|
||||
sourceVector = destinationVector;
|
||||
} else if (destinationVector == NULL)
|
||||
iGraph.setInterferenceVector(destination, sourceVector);
|
||||
else {
|
||||
InterferenceVector* last = NULL;
|
||||
for (InterferenceVector* v = sourceVector; v != NULL; v = v->next)
|
||||
last = v;
|
||||
assert(last);
|
||||
last->next = destinationVector;
|
||||
iGraph.setInterferenceVector(destination, sourceVector);
|
||||
}
|
||||
// Update the interference matrix.
|
||||
for (InterferenceVector* v = sourceVector; v != NULL; v = v->next) {
|
||||
RegisterName* neighbors = v->neighbors;
|
||||
for (Uint32 i = 0; i < v->count; i++) {
|
||||
RegisterName neighbor = findRoot(neighbors[i], coalescedRange);
|
||||
iGraph.setInterference(neighbor, source);
|
||||
iGraph.setInterference(neighbor, destination);
|
||||
}
|
||||
}
|
||||
|
||||
instruction.remove();
|
||||
coalescedRange[source] = destination;
|
||||
removedInstructions = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
registerAllocator.rangeCount = compress(registerAllocator.name2range, coalescedRange, registerAllocator.nameCount, rangeCount);
|
||||
delete newRange;
|
||||
|
||||
return removedInstructions;
|
||||
}
|
||||
|
||||
#endif // _COALESCING_H_
|
||||
283
mozilla/ef/Compiler/RegisterAllocator/Coloring.cpp
Normal file
283
mozilla/ef/Compiler/RegisterAllocator/Coloring.cpp
Normal file
@@ -0,0 +1,283 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef NEW_LAURENTM_CODE
|
||||
|
||||
#include "Coloring.h"
|
||||
#include "VirtualRegister.h"
|
||||
#include "FastBitSet.h"
|
||||
#include "FastBitMatrix.h"
|
||||
#include "CpuInfo.h"
|
||||
|
||||
bool Coloring::
|
||||
assignRegisters(FastBitMatrix& interferenceMatrix)
|
||||
{
|
||||
PRUint32 *stackPtr = new(pool) PRUint32[vRegManager.count()];
|
||||
|
||||
return select(interferenceMatrix, stackPtr, simplify(interferenceMatrix, stackPtr));
|
||||
}
|
||||
|
||||
PRInt32 Coloring::
|
||||
getLowestSpillCostRegister(FastBitSet& bitset)
|
||||
{
|
||||
PRInt32 lowest = bitset.firstOne();
|
||||
if (lowest != -1)
|
||||
{
|
||||
Flt32 cost = vRegManager.getVirtualRegister(lowest).spillInfo.spillCost;
|
||||
for (PRInt32 r = bitset.nextOne(lowest); r != -1; r = bitset.nextOne(r))
|
||||
{
|
||||
VirtualRegister& vReg = vRegManager.getVirtualRegister(r);
|
||||
if (!vReg.spillInfo.infiniteSpillCost && (vReg.spillInfo.spillCost < cost))
|
||||
{
|
||||
cost = vReg.spillInfo.spillCost;
|
||||
lowest = r;
|
||||
}
|
||||
}
|
||||
}
|
||||
return lowest;
|
||||
}
|
||||
|
||||
PRUint32* Coloring::
|
||||
simplify(FastBitMatrix interferenceMatrix, PRUint32* stackPtr)
|
||||
{
|
||||
// first we construct the sets low and high. low contains all nodes of degree
|
||||
// inferior to the number of register available on the processor. All the
|
||||
// nodes with an high degree and a finite spill cost are placed in high.
|
||||
// Nodes of high degree and infinite spill cost are not included in either sets.
|
||||
|
||||
PRUint32 nRegisters = vRegManager.count();
|
||||
FastBitSet low(pool, nRegisters);
|
||||
FastBitSet high(pool, nRegisters);
|
||||
FastBitSet stack(pool, nRegisters);
|
||||
|
||||
for (VirtualRegisterManager::iterator i = vRegManager.begin(); !vRegManager.done(i); i = vRegManager.advance(i))
|
||||
{
|
||||
VirtualRegister& vReg = vRegManager.getVirtualRegister(i);
|
||||
|
||||
if (vReg.getClass() == vrcStackSlot)
|
||||
{
|
||||
stack.set(i);
|
||||
vReg.colorRegister(nRegisters);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (vReg.colorInfo.interferenceDegree < NUMBER_OF_REGISTERS)
|
||||
low.set(i);
|
||||
else // if (!vReg.spillInfo.infiniteSpillCost)
|
||||
high.set(i);
|
||||
|
||||
// Set coloring info.
|
||||
vReg.spillInfo.willSpill = false;
|
||||
|
||||
switch(vReg.getClass())
|
||||
{
|
||||
case vrcInteger:
|
||||
vReg.colorRegister(LAST_GREGISTER + 1);
|
||||
break;
|
||||
case vrcFloatingPoint:
|
||||
case vrcFixedPoint:
|
||||
vReg.colorRegister(LAST_FPREGISTER + 1);
|
||||
break;
|
||||
default:
|
||||
PR_ASSERT(false); // Cannot happen.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// push the stack registers
|
||||
PRInt32 j;
|
||||
for (j = stack.firstOne(); j != -1; j = stack.nextOne(j))
|
||||
*stackPtr++ = j;
|
||||
|
||||
// simplify
|
||||
while (true)
|
||||
{
|
||||
PRInt32 r;
|
||||
while ((r = getLowestSpillCostRegister(low)) != -1)
|
||||
{
|
||||
VirtualRegister& vReg = vRegManager.getVirtualRegister(r);
|
||||
|
||||
/* update low and high */
|
||||
FastBitSet inter(interferenceMatrix.getRow(r), nRegisters);
|
||||
for (j = inter.firstOne(); j != -1; j = inter.nextOne(j))
|
||||
{
|
||||
VirtualRegister& neighbor = vRegManager.getVirtualRegister(j);
|
||||
// if the new interference degree of one of his neighbor becomes
|
||||
// NUMBER_OF_REGISTERS - 1 then it is added to the set 'low'.
|
||||
|
||||
PRUint32 maxInterference = 0;
|
||||
switch (neighbor.getClass())
|
||||
{
|
||||
case vrcInteger:
|
||||
maxInterference = NUMBER_OF_GREGISTERS;
|
||||
break;
|
||||
case vrcFloatingPoint:
|
||||
case vrcFixedPoint:
|
||||
maxInterference = NUMBER_OF_FPREGISTERS;
|
||||
break;
|
||||
default:
|
||||
PR_ASSERT(false);
|
||||
}
|
||||
if ((vRegManager.getVirtualRegister(j).colorInfo.interferenceDegree-- == maxInterference))
|
||||
{
|
||||
high.clear(j);
|
||||
low.set(j);
|
||||
}
|
||||
vReg.colorInfo.interferenceDegree--;
|
||||
interferenceMatrix.clear(r, j);
|
||||
interferenceMatrix.clear(j, r);
|
||||
}
|
||||
low.clear(r);
|
||||
|
||||
// Push this register.
|
||||
*stackPtr++ = r;
|
||||
}
|
||||
if ((r = getLowestSpillCostRegister(high)) != -1)
|
||||
{
|
||||
high.clear(r);
|
||||
low.set(r);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
return stackPtr;
|
||||
}
|
||||
|
||||
bool Coloring::
|
||||
select(FastBitMatrix& interferenceMatrix, PRUint32* stackBase, PRUint32* stackPtr)
|
||||
{
|
||||
PRUint32 nRegisters = vRegManager.count();
|
||||
FastBitSet usedRegisters(NUMBER_OF_REGISTERS + 1); // usedRegisters if used for both GR & FPR.
|
||||
FastBitSet preColoredRegisters(NUMBER_OF_REGISTERS + 1);
|
||||
FastBitSet usedStack(nRegisters + 1);
|
||||
bool success = true;
|
||||
Int32 lastUsedSSR = -1;
|
||||
|
||||
// select
|
||||
while (stackPtr != stackBase)
|
||||
{
|
||||
// Pop one register.
|
||||
PRUint32 r = *--stackPtr;
|
||||
VirtualRegister& vReg = vRegManager.getVirtualRegister(r);
|
||||
|
||||
FastBitSet neighbors(interferenceMatrix.getRow(r), nRegisters);
|
||||
|
||||
if (vReg.getClass() == vrcStackSlot)
|
||||
// Stack slots coloring.
|
||||
{
|
||||
usedStack.clear();
|
||||
|
||||
for (PRInt32 i = neighbors.firstOne(); i != -1; i = neighbors.nextOne(i))
|
||||
usedStack.set(vRegManager.getVirtualRegister(i).getColor());
|
||||
|
||||
Int32 color = usedStack.firstZero();
|
||||
vReg.colorRegister(color);
|
||||
if (color > lastUsedSSR)
|
||||
lastUsedSSR = color;
|
||||
}
|
||||
else
|
||||
// Integer & Floating point register coloring.
|
||||
{
|
||||
usedRegisters.clear();
|
||||
preColoredRegisters.clear();
|
||||
|
||||
for (PRInt32 i = neighbors.firstOne(); i != -1; i = neighbors.nextOne(i))
|
||||
{
|
||||
VirtualRegister& nvReg = vRegManager.getVirtualRegister(i);
|
||||
usedRegisters.set(nvReg.getColor());
|
||||
if (nvReg.isPreColored())
|
||||
preColoredRegisters.set(nvReg.getPreColor());
|
||||
}
|
||||
if (vReg.hasSpecialInterference)
|
||||
usedRegisters |= vReg.specialInterference;
|
||||
|
||||
PRInt8 c = -1;
|
||||
PRInt8 maxColor = 0;
|
||||
PRInt8 firstColor = 0;
|
||||
switch (vReg.getClass())
|
||||
{
|
||||
case vrcInteger:
|
||||
firstColor = FIRST_GREGISTER;
|
||||
maxColor = LAST_GREGISTER;
|
||||
break;
|
||||
case vrcFloatingPoint:
|
||||
case vrcFixedPoint:
|
||||
firstColor = FIRST_FPREGISTER;
|
||||
maxColor = LAST_FPREGISTER;
|
||||
break;
|
||||
default:
|
||||
PR_ASSERT(false);
|
||||
}
|
||||
|
||||
if (vReg.isPreColored())
|
||||
{
|
||||
c = vReg.getPreColor();
|
||||
if (usedRegisters.test(c))
|
||||
c = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (c = usedRegisters.nextZero(firstColor - 1); (c >= 0) && (c <= maxColor) && (preColoredRegisters.test(c));
|
||||
c = usedRegisters.nextZero(c)) {}
|
||||
}
|
||||
|
||||
if ((c >= 0) && (c <= maxColor))
|
||||
{
|
||||
vReg.colorRegister(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
VirtualRegister& stackRegister = vRegManager.newVirtualRegister(vrcStackSlot);
|
||||
vReg.equivalentRegister[vrcStackSlot] = &stackRegister;
|
||||
vReg.spillInfo.willSpill = true;
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (success)
|
||||
{
|
||||
for (VirtualRegisterManager::iterator i = vRegManager.begin(); !vRegManager.done(i); i = vRegManager.advance(i))
|
||||
{
|
||||
VirtualRegister& vReg = vRegManager.getVirtualRegister(i);
|
||||
switch (vReg.getClass())
|
||||
{
|
||||
case vrcInteger:
|
||||
if (vReg.getColor() > LAST_GREGISTER)
|
||||
PR_ASSERT(false);
|
||||
break;
|
||||
case vrcFloatingPoint:
|
||||
case vrcFixedPoint:
|
||||
#if NUMBER_OF_FPREGISTERS != 0
|
||||
if (vReg.getColor() > LAST_FPREGISTER)
|
||||
PR_ASSERT(false);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
vRegManager.nUsedStackSlots = lastUsedSSR + 1;
|
||||
return success;
|
||||
}
|
||||
#endif // NEW_LAURENTM_CODE
|
||||
284
mozilla/ef/Compiler/RegisterAllocator/Coloring.h
Normal file
284
mozilla/ef/Compiler/RegisterAllocator/Coloring.h
Normal file
@@ -0,0 +1,284 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Instruction.h"
|
||||
#include "RegisterAllocator.h"
|
||||
#include "VirtualRegister.h"
|
||||
#include "InterferenceGraph.h"
|
||||
#include "SparseSet.h"
|
||||
#include "Spilling.h"
|
||||
#include "Splits.h"
|
||||
|
||||
UT_EXTERN_LOG_MODULE(RegAlloc);
|
||||
|
||||
template <class RegisterPressure>
|
||||
class Coloring
|
||||
{
|
||||
private:
|
||||
static RegisterName* simplify(RegisterAllocator& registerAllocator, RegisterName* coloringStack);
|
||||
static bool select(RegisterAllocator& registerAllocator, RegisterName* coloringStack, RegisterName* coloringStackPtr);
|
||||
|
||||
public:
|
||||
static bool color(RegisterAllocator& registerAllocator);
|
||||
static void finalColoring(RegisterAllocator& registerAllocator);
|
||||
};
|
||||
|
||||
|
||||
template <class RegisterPressure>
|
||||
void Coloring<RegisterPressure>::finalColoring(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
RegisterName* color = registerAllocator.color;
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
|
||||
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
usePtr->setRegisterName(color[name2range[usePtr->getRegisterName()]]);
|
||||
#ifdef DEBUG
|
||||
RegisterID rid = usePtr->getRegisterID();
|
||||
setColoredRegister(rid);
|
||||
usePtr->setRegisterID(rid);
|
||||
#endif // DEBUG
|
||||
}
|
||||
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister()) {
|
||||
definePtr->setRegisterName(color[name2range[definePtr->getRegisterName()]]);
|
||||
#ifdef DEBUG
|
||||
RegisterID rid = definePtr->getRegisterID();
|
||||
setColoredRegister(rid);
|
||||
definePtr->setRegisterID(rid);
|
||||
#endif // DEBUG
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
bool Coloring<RegisterPressure>::select(RegisterAllocator& registerAllocator, RegisterName* coloringStack, RegisterName* coloringStackPtr)
|
||||
{
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
RegisterName* color = new RegisterName[rangeCount];
|
||||
registerAllocator.color = color;
|
||||
|
||||
for (Uint32 r = 1; r < rangeCount; r++)
|
||||
color[r] = RegisterName(6); // FIX;
|
||||
|
||||
// Color the preColored registers.
|
||||
//
|
||||
VirtualRegisterManager& vrManager = registerAllocator.vrManager;
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
PreColoredRegister* machineEnd = vrManager.getMachineRegistersEnd();
|
||||
for (PreColoredRegister* machinePtr = vrManager.getMachineRegistersBegin(); machinePtr < machineEnd; machinePtr++)
|
||||
if (machinePtr->id != invalidID) {
|
||||
color[name2range[getName(machinePtr->id)]] = machinePtr->color;
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\twill preColor range %d as %d\n", name2range[getName(machinePtr->id)], machinePtr->color));
|
||||
}
|
||||
|
||||
SpillCost* cost = registerAllocator.spillCost;
|
||||
Pool& pool = registerAllocator.pool;
|
||||
SparseSet& spill = *new(pool) SparseSet(pool, rangeCount);
|
||||
registerAllocator.willSpill = &spill;
|
||||
SparseSet neighborColors(pool, 6); // FIX
|
||||
InterferenceGraph<RegisterPressure>& iGraph = registerAllocator.iGraph;
|
||||
|
||||
bool coloringFailed = false;
|
||||
while (coloringStackPtr > coloringStack) {
|
||||
RegisterName range = *--coloringStackPtr;
|
||||
|
||||
if (!cost[range].infinite && cost[range].cost < 0) {
|
||||
coloringFailed = true;
|
||||
spill.set(range);
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tfailed to color %d, will spill.\n", range));
|
||||
} else {
|
||||
neighborColors.clear();
|
||||
|
||||
for (InterferenceVector* vector = iGraph.getInterferenceVector(range); vector != NULL; vector = vector->next)
|
||||
for (Int32 i = vector->count - 1; i >= 0; --i) {
|
||||
RegisterName neighborColor = color[vector->neighbors[i]];
|
||||
if (neighborColor < 6) // FIX
|
||||
neighborColors.set(neighborColor);
|
||||
}
|
||||
|
||||
if (neighborColors.getSize() == 6) { // FIX
|
||||
coloringFailed = true;
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tfailed to color %d, ", range));
|
||||
|
||||
if (!Splits<RegisterPressure>::findSplit(registerAllocator, color, range)) {
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("will spill.\n"));
|
||||
spill.set(range);
|
||||
} else
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("will split.\n"));
|
||||
} else {
|
||||
for (Uint32 i = 0; i < 6; i++) // FIX
|
||||
if (!neighborColors.test(i)) {
|
||||
fprintf(stdout, "\twill color %d as %d\n", range, i);
|
||||
color[range] = RegisterName(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
if (coloringFailed) {
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("Coloring failed:\n"));
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\twill spill: "));
|
||||
spill.printPretty(UT_LOG_MODULE(RegAlloc));
|
||||
} else {
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("Coloring succeeded:\n"));
|
||||
for (Uint32 i = 1; i < rangeCount; i++)
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\trange %d colored as %d\n", i, color[i]));
|
||||
}
|
||||
#endif
|
||||
|
||||
return !coloringFailed;
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
RegisterName* Coloring<RegisterPressure>::simplify(RegisterAllocator& registerAllocator, RegisterName* coloringStack)
|
||||
{
|
||||
InterferenceGraph<RegisterPressure>& iGraph = registerAllocator.iGraph;
|
||||
SpillCost* spillCost = registerAllocator.spillCost;
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
|
||||
Uint32* degree = new Uint32[rangeCount];
|
||||
for (RegisterName i = RegisterName(1); i < rangeCount; i = RegisterName(i + 1)) {
|
||||
InterferenceVector* vector = iGraph.getInterferenceVector(i);
|
||||
degree[i] = (vector != NULL) ? vector->count : 0;
|
||||
}
|
||||
|
||||
Pool& pool = registerAllocator.pool;
|
||||
SparseSet low(pool, rangeCount);
|
||||
SparseSet high(pool, rangeCount);
|
||||
SparseSet highInfinite(pool, rangeCount);
|
||||
SparseSet preColored(pool, rangeCount);
|
||||
|
||||
// Get the precolored registers.
|
||||
//
|
||||
VirtualRegisterManager& vrManager = registerAllocator.vrManager;
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
PreColoredRegister* machineEnd = vrManager.getMachineRegistersEnd();
|
||||
for (PreColoredRegister* machinePtr = vrManager.getMachineRegistersBegin(); machinePtr < machineEnd; machinePtr++)
|
||||
if (machinePtr->id != invalidID)
|
||||
preColored.set(name2range[getName(machinePtr->id)]);
|
||||
|
||||
// Insert the live ranges in the sets.
|
||||
//
|
||||
for (Uint32 range = 1; range < rangeCount; range++)
|
||||
if (!preColored.test(range))
|
||||
if (degree[range] < 6) // FIX
|
||||
low.set(range);
|
||||
else if (!spillCost[range].infinite)
|
||||
high.set(range);
|
||||
else
|
||||
highInfinite.set(range);
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("Coloring sets:\n\tlow = "));
|
||||
low.printPretty(UT_LOG_MODULE(RegAlloc));
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\thigh = "));
|
||||
high.printPretty(UT_LOG_MODULE(RegAlloc));
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\thighInfinite = "));
|
||||
highInfinite.printPretty(UT_LOG_MODULE(RegAlloc));
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tpreColored = "));
|
||||
preColored.printPretty(UT_LOG_MODULE(RegAlloc));
|
||||
#endif // DEBUG_LOG
|
||||
|
||||
RegisterName* coloringStackPtr = coloringStack;
|
||||
|
||||
while (low.getSize() != 0 || high.getSize() != 0) {
|
||||
while (low.getSize() != 0) {
|
||||
RegisterName range = RegisterName(low.getOne());
|
||||
low.clear(range);
|
||||
*coloringStackPtr++ = range;
|
||||
|
||||
for (InterferenceVector* vector = iGraph.getInterferenceVector(range); vector != NULL; vector = vector->next)
|
||||
for (Int32 i = (vector->count - 1); i >= 0; --i) {
|
||||
RegisterName neighbor = vector->neighbors[i];
|
||||
degree[neighbor]--;
|
||||
|
||||
if (degree[neighbor] < 6) // FIX
|
||||
if (high.test(neighbor)) {
|
||||
high.clear(neighbor);
|
||||
low.set(neighbor);
|
||||
} else if (highInfinite.test(neighbor)) {
|
||||
highInfinite.clear(neighbor);
|
||||
low.set(neighbor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (high.getSize() != 0) {
|
||||
RegisterName best = RegisterName(high.getOne());
|
||||
double bestCost = spillCost[best].cost;
|
||||
double bestDegree = degree[best];
|
||||
|
||||
// Choose the next best candidate.
|
||||
//
|
||||
for (SparseSet::iterator i = high.begin(); !high.done(i); i = high.advance(i)) {
|
||||
RegisterName range = RegisterName(high.get(i));
|
||||
double thisCost = spillCost[range].cost;
|
||||
double thisDegree = degree[range];
|
||||
|
||||
if (thisCost * bestDegree < bestCost * thisDegree) {
|
||||
best = range;
|
||||
bestCost = thisCost;
|
||||
bestDegree = thisDegree;
|
||||
}
|
||||
}
|
||||
|
||||
high.clear(best);
|
||||
low.set(best);
|
||||
}
|
||||
}
|
||||
assert(highInfinite.getSize() == 0);
|
||||
|
||||
delete degree;
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("Coloring stack:\n\t"));
|
||||
for (RegisterName* sp = coloringStack; sp < coloringStackPtr; ++sp)
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("%d ", *sp));
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\n"));
|
||||
#endif // DEBUG_LOG
|
||||
|
||||
return coloringStackPtr;
|
||||
}
|
||||
|
||||
|
||||
template <class RegisterPressure>
|
||||
bool Coloring<RegisterPressure>::color(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
RegisterName* coloringStack = new RegisterName[registerAllocator.rangeCount];
|
||||
return select(registerAllocator, coloringStack, simplify(registerAllocator, coloringStack));
|
||||
}
|
||||
212
mozilla/ef/Compiler/RegisterAllocator/DominatorGraph.cpp
Normal file
212
mozilla/ef/Compiler/RegisterAllocator/DominatorGraph.cpp
Normal file
@@ -0,0 +1,212 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include <string.h>
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
|
||||
#include "DominatorGraph.h"
|
||||
|
||||
DominatorGraph::DominatorGraph(ControlGraph& controlGraph) : controlGraph(controlGraph)
|
||||
{
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
GtoV = new Uint32[nNodes + 1];
|
||||
VtoG = new Uint32[nNodes + 1];
|
||||
|
||||
Uint32 v = 1;
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
VtoG[v] = n;
|
||||
GtoV[n] = v++;
|
||||
}
|
||||
|
||||
// Initialize all the 1-based arrays.
|
||||
//
|
||||
parent = new Uint32[v];
|
||||
semi = new Uint32[v];
|
||||
vertex = new Uint32[v];
|
||||
label = new Uint32[v];
|
||||
size = new Uint32[v];
|
||||
ancestor = new Uint32[v];
|
||||
child = new Uint32[v];
|
||||
dom = new Uint32[v];
|
||||
bucket = new DGLinkedList*[v];
|
||||
|
||||
memset(semi, '\0', v * sizeof(Uint32));
|
||||
memset(bucket, '\0', v * sizeof(DGLinkedList*));
|
||||
|
||||
vCount = v;
|
||||
|
||||
build();
|
||||
|
||||
delete parent;
|
||||
delete semi;
|
||||
delete vertex;
|
||||
delete label;
|
||||
delete size;
|
||||
delete ancestor;
|
||||
delete child;
|
||||
delete dom;
|
||||
delete bucket;
|
||||
}
|
||||
|
||||
Uint32 DominatorGraph::DFS(Uint32 vx, Uint32 n)
|
||||
{
|
||||
semi[vx] = ++n;
|
||||
vertex[n] = label[vx] = vx;
|
||||
ancestor[vx] = child[vx] = 0;
|
||||
size[vx] = 1;
|
||||
|
||||
|
||||
ControlNode& node = *controlGraph.dfsList[VtoG[vx]];
|
||||
ControlEdge* successorEnd = node.getSuccessorsEnd();
|
||||
for (ControlEdge* successorPtr = node.getSuccessorsBegin(); successorPtr < successorEnd; successorPtr++) {
|
||||
Uint32 w = GtoV[successorPtr->getTarget().dfsNum];
|
||||
if (semi[w] == 0) {
|
||||
parent[w] = vx;
|
||||
n = DFS(w, n);
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
void DominatorGraph::LINK(Uint32 vx, Uint32 w)
|
||||
{
|
||||
Uint32 s = w;
|
||||
|
||||
while (semi[label[w]] < semi[label[child[s]]]) {
|
||||
if (size[s] + size[child[child[s]]] >= (size[child[s]] << 1)) {
|
||||
ancestor[child[s]] = s;
|
||||
child[s] = child[child[s]];
|
||||
} else {
|
||||
size[child[s]] = size[s];
|
||||
s = ancestor[s] = child[s];
|
||||
}
|
||||
}
|
||||
label[s] = label[w];
|
||||
size[vx] += size[w];
|
||||
if(size[vx] < (size[w] << 1)) {
|
||||
Uint32 t = s;
|
||||
s = child[vx];
|
||||
child[vx] = t;
|
||||
}
|
||||
while( s != 0 ) {
|
||||
ancestor[s] = vx;
|
||||
s = child[s];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DominatorGraph::COMPRESS(Uint32 vx)
|
||||
{
|
||||
if(ancestor[ancestor[vx]] != 0) {
|
||||
COMPRESS(ancestor[vx]);
|
||||
if(semi[label[ancestor[vx]]] < semi[label[vx]])
|
||||
label[vx] = label[ancestor[vx]];
|
||||
ancestor[vx] = ancestor[ancestor[vx]];
|
||||
}
|
||||
}
|
||||
|
||||
Uint32 DominatorGraph::EVAL(Uint32 vx)
|
||||
{
|
||||
if(ancestor[vx] == 0)
|
||||
return label[vx];
|
||||
COMPRESS(vx);
|
||||
return (semi[label[ancestor[vx]]] >= semi[label[vx]]) ? label[vx] : label[ancestor[vx]];
|
||||
}
|
||||
|
||||
void DominatorGraph::build()
|
||||
{
|
||||
Uint32 n = DFS(GtoV[0], 0);
|
||||
size[0] = label[0] = semi[0];
|
||||
|
||||
for (Uint32 i = n; i >= 2; i--) {
|
||||
Uint32 w = vertex[i];
|
||||
|
||||
ControlNode& node = *controlGraph.dfsList[VtoG[w]];
|
||||
const DoublyLinkedList<ControlEdge>& predecessors = node.getPredecessors();
|
||||
for (DoublyLinkedList<ControlEdge>::iterator p = predecessors.begin(); !predecessors.done(p); p = predecessors.advance(p)) {
|
||||
Uint32 vx = GtoV[predecessors.get(p).getSource().dfsNum];
|
||||
Uint32 u = EVAL(vx);
|
||||
|
||||
if(semi[u] < semi[w])
|
||||
semi[w] = semi[u];
|
||||
}
|
||||
|
||||
DGLinkedList* elem = new DGLinkedList();
|
||||
elem->next = bucket[vertex[semi[w]]];
|
||||
elem->index = w;
|
||||
bucket[vertex[semi[w]]] = elem;
|
||||
|
||||
LINK(parent[w], w);
|
||||
|
||||
elem = bucket[parent[w]];
|
||||
while(elem != NULL) {
|
||||
Uint32 vx = elem->index;
|
||||
Uint32 u = EVAL(vx);
|
||||
dom[vx] = (semi[u] < semi[vx]) ? u : parent[w];
|
||||
elem = elem->next;
|
||||
}
|
||||
}
|
||||
|
||||
memset(size, '\0', n * sizeof(Uint32));
|
||||
Pool& pool = controlGraph.pool;
|
||||
nodes = new(pool) DGNode[n];
|
||||
|
||||
for(Uint32 j = 2; j <= n; j++) {
|
||||
Uint32 w = vertex[j];
|
||||
Uint32 d = dom[w];
|
||||
if(d != vertex[semi[w]]) {
|
||||
d = dom[d];
|
||||
dom[w] = d;
|
||||
}
|
||||
size[d]++;
|
||||
}
|
||||
dom[GtoV[0]] = 0;
|
||||
|
||||
for (Uint32 k = 1; k <= n; k++) {
|
||||
DGNode& node = nodes[VtoG[k]];
|
||||
Uint32 count = size[k];
|
||||
node.successorsEnd = node.successorsBegin = (count) ? new(pool) Uint32[count] : (Uint32*) 0;
|
||||
}
|
||||
|
||||
for (Uint32 l = 2; l <= n; l++)
|
||||
*(nodes[VtoG[dom[l]]].successorsEnd)++ = VtoG[l];
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
void DominatorGraph::printPretty(LogModuleObject log)
|
||||
{
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Dominator Graph:\n"));
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
for (Uint32 i = 0; i < nNodes; i++) {
|
||||
DGNode& node = nodes[i];
|
||||
if (node.successorsBegin != node.successorsEnd) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\tN%d dominates ", i));
|
||||
for (Uint32* successorsPtr = node.successorsBegin; successorsPtr < node.successorsEnd; successorsPtr++)
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("N%d ", *successorsPtr));
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // DEBUG_LOG
|
||||
|
||||
|
||||
|
||||
80
mozilla/ef/Compiler/RegisterAllocator/DominatorGraph.h
Normal file
80
mozilla/ef/Compiler/RegisterAllocator/DominatorGraph.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _DOMINATOR_GRAPH_H_
|
||||
#define _DOMINATOR_GRAPH_H_
|
||||
|
||||
#include "LogModule.h"
|
||||
|
||||
class ControlGraph;
|
||||
|
||||
struct DGNode
|
||||
{
|
||||
Uint32* successorsBegin;
|
||||
Uint32* successorsEnd;
|
||||
};
|
||||
|
||||
struct DGLinkedList
|
||||
{
|
||||
DGLinkedList* next;
|
||||
Uint32 index;
|
||||
};
|
||||
|
||||
class DominatorGraph
|
||||
{
|
||||
private:
|
||||
|
||||
ControlGraph& controlGraph;
|
||||
|
||||
Uint32 vCount;
|
||||
|
||||
Uint32* VtoG;
|
||||
Uint32* GtoV;
|
||||
Uint32* parent;
|
||||
Uint32* semi;
|
||||
Uint32* vertex;
|
||||
Uint32* label;
|
||||
Uint32* size;
|
||||
Uint32* ancestor;
|
||||
Uint32* child;
|
||||
Uint32* dom;
|
||||
DGLinkedList** bucket;
|
||||
DGNode* nodes;
|
||||
|
||||
private:
|
||||
|
||||
void build();
|
||||
|
||||
Uint32 DFS(Uint32 vx, Uint32 n);
|
||||
void LINK(Uint32 vx, Uint32 w);
|
||||
void COMPRESS(Uint32 vx);
|
||||
Uint32 EVAL(Uint32 vx);
|
||||
|
||||
public:
|
||||
|
||||
DominatorGraph(ControlGraph& controlGraph);
|
||||
|
||||
Uint32* getSuccessorsBegin(Uint32 n) const {return nodes[n].successorsBegin;}
|
||||
Uint32* getSuccessorsEnd(Uint32 n) const {return nodes[n].successorsEnd;}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
void printPretty(LogModuleObject log);
|
||||
#endif // DEBUG_LOG
|
||||
};
|
||||
|
||||
#endif // _DOMINATOR_GRAPH_H_
|
||||
20
mozilla/ef/Compiler/RegisterAllocator/HashSet.cpp
Normal file
20
mozilla/ef/Compiler/RegisterAllocator/HashSet.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "HashSet.h"
|
||||
97
mozilla/ef/Compiler/RegisterAllocator/HashSet.h
Normal file
97
mozilla/ef/Compiler/RegisterAllocator/HashSet.h
Normal file
@@ -0,0 +1,97 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _HASH_SET_H_
|
||||
#define _HASH_SET_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "Pool.h"
|
||||
#include <string.h>
|
||||
|
||||
struct HashSetElement
|
||||
{
|
||||
Uint32 index;
|
||||
HashSetElement* next;
|
||||
};
|
||||
|
||||
class HashSet
|
||||
{
|
||||
private:
|
||||
|
||||
static const hashSize = 64;
|
||||
|
||||
// Return the hash code for the given element index.
|
||||
static Uint32 getHashCode(Uint32 index) {return index & (hashSize - 1);} // Could be better !
|
||||
|
||||
private:
|
||||
|
||||
Pool& allocationPool;
|
||||
HashSetElement** bucket;
|
||||
HashSetElement* free;
|
||||
|
||||
private:
|
||||
|
||||
// No copy constructor.
|
||||
HashSet(const HashSet&);
|
||||
// No copy operator.
|
||||
void operator = (const HashSet&);
|
||||
|
||||
public:
|
||||
|
||||
// Create a new HashSet.
|
||||
inline HashSet(Pool& pool, Uint32 universeSize);
|
||||
|
||||
// Clear the hashset.
|
||||
void clear();
|
||||
// Clear the element for the given index.
|
||||
void clear(Uint32 index);
|
||||
// Set the element for the given index.
|
||||
void set(Uint32 index);
|
||||
// Return true if the element at index is a member.
|
||||
bool test(Uint32 index) const;
|
||||
// Union with the given hashset.
|
||||
inline void or(const HashSet& set);
|
||||
// Intersection with the given hashset.
|
||||
inline void and(const HashSet& set);
|
||||
// Difference with the given hashset.
|
||||
inline void difference(const HashSet& set);
|
||||
|
||||
// Logical operators.
|
||||
HashSet& operator |= (const HashSet& set) {or(set); return *this;}
|
||||
HashSet& operator &= (const HashSet& set) {and(set); return *this;}
|
||||
HashSet& operator -= (const HashSet& set) {difference(set); return *this;}
|
||||
|
||||
// Iterator to conform with the set API.
|
||||
typedef HashSetElement* iterator;
|
||||
// Return the iterator for the first element of this set.
|
||||
iterator begin() const;
|
||||
// Return the next iterator.
|
||||
iterator advance(iterator pos) const;
|
||||
// Return true if the iterator is at the end of the set.
|
||||
bool done(iterator pos) const {return pos == NULL;}
|
||||
};
|
||||
|
||||
|
||||
inline HashSet::HashSet(Pool& pool, Uint32 /*universeSize*/)
|
||||
: allocationPool(pool), free(NULL)
|
||||
{
|
||||
bucket = new(pool) HashSetElement*[hashSize];
|
||||
memset(bucket, '\0', sizeof(HashSetElement*));
|
||||
}
|
||||
|
||||
#endif // _HASH_SET_H_
|
||||
213
mozilla/ef/Compiler/RegisterAllocator/IndexedPool.h
Normal file
213
mozilla/ef/Compiler/RegisterAllocator/IndexedPool.h
Normal file
@@ -0,0 +1,213 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _INDEXED_POOL_H_
|
||||
#define _INDEXED_POOL_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// IndexedPool<IndexedObjectSubclass> is an indexed pool of objects. The
|
||||
// template parameter 'IndexedObjectSubclass' must be a subclass of the struct
|
||||
// IndexedObject.
|
||||
//
|
||||
// When the indexed pool is ask to allocate and initialize a new object (using
|
||||
// the operator new(anIndexedPool) it will zero the memory used to store the
|
||||
// object and initialize the field 'index' of this object to its position in
|
||||
// the pool.
|
||||
//
|
||||
// An object allocated by the indexed pool can be freed by calling the method
|
||||
// IndexedPool::release(IndexedElement& objectIndex).
|
||||
//
|
||||
// example:
|
||||
//
|
||||
// IndexedPool<IndexedElement> elementPool;
|
||||
//
|
||||
// IndexedElement& element1 = *new(elementPool) IndexedElement();
|
||||
// IndexedElement& element2 = *new(elementPool) IndexedElement();
|
||||
//
|
||||
// indexedPool.release(element1);
|
||||
// IndexedElement& element3 = *new(elementPool) IndexedElement();
|
||||
//
|
||||
// At this point element1 is no longer a valid object, element2 is at
|
||||
// index 2 and element3 is at index 1.
|
||||
//
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// IndexedObject -
|
||||
//
|
||||
|
||||
template<class Object>
|
||||
struct IndexedObject
|
||||
{
|
||||
Uint32 index; // Index in the pool.
|
||||
Object* next; // Used to link IndexedObject together.
|
||||
|
||||
Uint32 getIndex() {return index;}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// IndexedPool<IndexedObject> -
|
||||
//
|
||||
|
||||
template <class IndexedObject>
|
||||
class IndexedPool
|
||||
{
|
||||
private:
|
||||
|
||||
static const blockSize = 4; // Size of one block.
|
||||
|
||||
Uint32 nBlocks; // Number of blocks in the pool.
|
||||
IndexedObject** block; // Array of block pointers.
|
||||
IndexedObject* freeObjects; // Chained list of free IndexedObjects.
|
||||
Uint32 nextIndex; // Index of the next free object in the last block.
|
||||
|
||||
private:
|
||||
|
||||
void allocateAnotherBlock();
|
||||
IndexedObject& newObject();
|
||||
|
||||
public:
|
||||
|
||||
IndexedPool() : nBlocks(0), block(NULL), freeObjects(NULL), nextIndex(1) {}
|
||||
~IndexedPool();
|
||||
|
||||
IndexedObject& get(Uint32 index) const;
|
||||
void release(IndexedObject& object);
|
||||
|
||||
void setSize(Uint32 size) {assert(size < nextIndex); nextIndex = size;}
|
||||
|
||||
// Return the universe size.
|
||||
Uint32 getSize() {return nextIndex;}
|
||||
|
||||
friend void* operator new(size_t, IndexedPool<IndexedObject>& pool); // Needs to call newObject().
|
||||
};
|
||||
|
||||
// Free all the memory allocated for this object.
|
||||
//
|
||||
template <class IndexedObject>
|
||||
IndexedPool<IndexedObject>::~IndexedPool()
|
||||
{
|
||||
for (Uint32 n = 0; n < nBlocks; n++)
|
||||
free(&((IndexedObject **) &block[n][n*blockSize])[-(n + 1)]);
|
||||
}
|
||||
|
||||
// Release the given. This object will be iserted in the chained
|
||||
// list of free IndexedObjects. To minimize the fragmentation the chained list
|
||||
// is ordered by ascending indexes.
|
||||
//
|
||||
template <class IndexedObject>
|
||||
void IndexedPool<IndexedObject>::release(IndexedObject& object)
|
||||
{
|
||||
Uint32 index = object.index;
|
||||
IndexedObject* list = freeObjects;
|
||||
|
||||
assert(&object == &get(index)); // Make sure that object is owned by this pool.
|
||||
|
||||
if (list == NULL) { // The list is empty.
|
||||
freeObjects = &object;
|
||||
object.next = NULL;
|
||||
} else { // The list contains at least 1 element.
|
||||
if (index < list->index) { // insert as first element.
|
||||
freeObjects = &object;
|
||||
object.next = list;
|
||||
} else { // Find this object's place.
|
||||
while ((list->next) != NULL && (list->next->index < index))
|
||||
list = list->next;
|
||||
|
||||
object.next = list->next;
|
||||
list->next = &object;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// Sanity check to be sure that the list is correctly ordered.
|
||||
for (IndexedObject* obj = freeObjects; obj != NULL; obj = obj->next)
|
||||
if (obj->next != NULL)
|
||||
assert(obj->index < obj->next->index);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Create a new block of IndexedObjects. We will allocate the memory to
|
||||
// store IndexedPool::blockSize IndexedObject and the new Array of block
|
||||
// pointers.
|
||||
// The newly created IndexedObjects will not be initialized.
|
||||
//
|
||||
template <class IndexedObject>
|
||||
void IndexedPool<IndexedObject>::allocateAnotherBlock()
|
||||
{
|
||||
void* memory = (void *) malloc((nBlocks + 1) * sizeof(Uint32) + blockSize * sizeof(IndexedObject));
|
||||
|
||||
memcpy(memory, block, nBlocks * sizeof(Uint32));
|
||||
|
||||
block = (IndexedObject **) memory;
|
||||
IndexedObject* objects = (IndexedObject *) &block[nBlocks + 1];
|
||||
|
||||
block[nBlocks] = &objects[-(nBlocks * blockSize)];
|
||||
nBlocks++;
|
||||
}
|
||||
|
||||
// Return the IndexedObject at the position 'index' in the pool.
|
||||
//
|
||||
template <class IndexedObject>
|
||||
IndexedObject& IndexedPool<IndexedObject>::get(Uint32 index) const
|
||||
{
|
||||
Uint32 blockIndex = index / blockSize;
|
||||
assert(blockIndex < nBlocks);
|
||||
|
||||
return block[blockIndex][index];
|
||||
}
|
||||
|
||||
// Return the reference of an unused object in the pool.
|
||||
//
|
||||
template <class IndexedObject>
|
||||
IndexedObject& IndexedPool<IndexedObject>::newObject()
|
||||
{
|
||||
if (freeObjects != NULL) {
|
||||
IndexedObject& newObject = *freeObjects;
|
||||
freeObjects = newObject.next;
|
||||
return newObject;
|
||||
}
|
||||
|
||||
Uint32 nextIndex = this->nextIndex++;
|
||||
Uint32 blockIndex = nextIndex / blockSize;
|
||||
|
||||
while (blockIndex >= nBlocks)
|
||||
allocateAnotherBlock();
|
||||
|
||||
IndexedObject& newObject = block[blockIndex][nextIndex];
|
||||
newObject.index = nextIndex;
|
||||
|
||||
return newObject;
|
||||
}
|
||||
|
||||
// Return the address of the next unsused object in the given
|
||||
// indexed pool. The field index of the newly allocated object
|
||||
// will be initialized to the corresponding index of this object
|
||||
// in the pool.
|
||||
//
|
||||
template <class IndexedObject>
|
||||
void* operator new(size_t size, IndexedPool<IndexedObject>& pool)
|
||||
{
|
||||
assert(size == sizeof(IndexedObject));
|
||||
return (void *) &pool.newObject();
|
||||
}
|
||||
|
||||
#endif // _INDEXED_POOL_H_
|
||||
258
mozilla/ef/Compiler/RegisterAllocator/InterferenceGraph.h
Normal file
258
mozilla/ef/Compiler/RegisterAllocator/InterferenceGraph.h
Normal file
@@ -0,0 +1,258 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _INTERFERENCE_GRAPH_H_
|
||||
#define _INTERFERENCE_GRAPH_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "Primitives.h"
|
||||
#include "Instruction.h"
|
||||
#include "VirtualRegister.h"
|
||||
#include "RegisterPressure.h"
|
||||
#include "SparseSet.h"
|
||||
#include <string.h>
|
||||
|
||||
struct InterferenceVector
|
||||
{
|
||||
Uint32 count;
|
||||
InterferenceVector* next;
|
||||
RegisterName* neighbors;
|
||||
|
||||
InterferenceVector() : count(0), next(NULL) {}
|
||||
};
|
||||
|
||||
class RegisterAllocator;
|
||||
|
||||
template <class RegisterPressure>
|
||||
class InterferenceGraph
|
||||
{
|
||||
private:
|
||||
|
||||
RegisterAllocator& registerAllocator;
|
||||
|
||||
RegisterPressure::Set* interferences;
|
||||
InterferenceVector** vector;
|
||||
Uint32* offset;
|
||||
Uint32 rangeCount;
|
||||
|
||||
private:
|
||||
|
||||
// No copy constructor.
|
||||
InterferenceGraph(const InterferenceGraph&);
|
||||
// No copy operator.
|
||||
void operator = (const InterferenceGraph&);
|
||||
|
||||
// Check if reg is a member of the universe.
|
||||
void checkMember(RegisterName name) {assert(name < rangeCount);}
|
||||
// Return the edge index for the interference between name1 and name2.
|
||||
Uint32 getEdgeIndex(RegisterName name1, RegisterName name2);
|
||||
|
||||
public:
|
||||
InterferenceGraph(RegisterAllocator& registerAllocator) : registerAllocator(registerAllocator) {}
|
||||
|
||||
// Calculate the interferences.
|
||||
void build();
|
||||
// Return true if reg1 and reg2 interfere.
|
||||
bool interfere(RegisterName name1, RegisterName name2);
|
||||
// Return the interference vector for the given register or NULL if there is none.
|
||||
InterferenceVector* getInterferenceVector(RegisterName name) {return vector[name];}
|
||||
// Set the interference between name1 and name2.
|
||||
void setInterference(RegisterName name1, RegisterName name2);
|
||||
// Set the interference vector for the given register.
|
||||
void setInterferenceVector(RegisterName name, InterferenceVector* v) {vector[name] = v;}
|
||||
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
// Print the interferences.
|
||||
void printPretty(LogModuleObject log);
|
||||
#endif // DEBUG_LOG
|
||||
};
|
||||
|
||||
template <class RegisterPressure>
|
||||
void InterferenceGraph<RegisterPressure>::build()
|
||||
{
|
||||
Pool& pool = registerAllocator.pool;
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
this->rangeCount = rangeCount;
|
||||
|
||||
// Initialize the structures.
|
||||
//
|
||||
offset = new(pool) Uint32[rangeCount + 1];
|
||||
vector = new(pool) InterferenceVector*[rangeCount];
|
||||
memset(vector, '\0', sizeof(InterferenceVector*) * rangeCount);
|
||||
|
||||
Uint32 o = 0;
|
||||
offset[0] = 0;
|
||||
for (Uint32 i = 1; i <= rangeCount; ++i) {
|
||||
offset[i] = o;
|
||||
o += i;
|
||||
}
|
||||
|
||||
interferences = new(pool) RegisterPressure::Set(pool, (rangeCount * rangeCount) / 2);
|
||||
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
LivenessInfo<RegisterPressure> liveness = Liveness<RegisterPressure>::analysis(controlGraph, rangeCount, name2range);
|
||||
registerAllocator.liveness = liveness;
|
||||
SparseSet currentLive(pool, rangeCount);
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
ControlNode& node = *nodes[n];
|
||||
currentLive = liveness.liveOut[n];
|
||||
|
||||
InstructionList& instructions = node.getInstructions();
|
||||
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useBegin = instruction.getInstructionUseBegin();
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
InstructionUse* usePtr;
|
||||
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
InstructionDefine* definePtr;
|
||||
|
||||
// Handle the copy instruction to avoid unnecessary interference between the 2 registers.
|
||||
if ((instruction.getFlags() & ifCopy) != 0) {
|
||||
assert(useBegin != useEnd && useBegin[0].isRegister());
|
||||
currentLive.clear(name2range[useBegin[0].getRegisterName()]);
|
||||
}
|
||||
|
||||
// Create the interferences.
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister()) {
|
||||
RegisterName define = name2range[definePtr->getRegisterName()];
|
||||
|
||||
for (SparseSet::iterator e = currentLive.begin(); !currentLive.done(e); e = currentLive.advance(e)) {
|
||||
RegisterName live = RegisterName(currentLive.get(e));
|
||||
|
||||
if ((live != define) && !interfere(live, define) && registerAllocator.canInterfere(live, define)) {
|
||||
|
||||
if (vector[define] == NULL)
|
||||
vector[define] = new(pool) InterferenceVector();
|
||||
vector[define]->count++;
|
||||
|
||||
if (vector[live] == NULL)
|
||||
vector[live] = new(pool) InterferenceVector();
|
||||
vector[live]->count++;
|
||||
|
||||
setInterference(live, define);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now update the liveness.
|
||||
//
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
currentLive.clear(name2range[definePtr->getRegisterName()]);
|
||||
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister())
|
||||
currentLive.set(name2range[usePtr->getRegisterName()]);
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate the memory to store the interferences.
|
||||
//
|
||||
for (Uint32 e = 0; e < rangeCount; e++)
|
||||
if (vector[e] != NULL) {
|
||||
InterferenceVector& v = *vector[e];
|
||||
v.neighbors = new(pool) RegisterName[v.count];
|
||||
v.count = 0;
|
||||
}
|
||||
|
||||
// Initialize the edges.
|
||||
//
|
||||
if (RegisterPressure::Set::isOrdered()) {
|
||||
RegisterName name1 = RegisterName(0);
|
||||
|
||||
for (RegisterPressure::Set::iterator i = interferences->begin(); !interferences->done(i); i = interferences->advance(i)) {
|
||||
Uint32 interferenceIndex = interferences->get(i);
|
||||
|
||||
while(interferenceIndex >= offset[name1 + 1])
|
||||
name1 = RegisterName(name1 + 1);
|
||||
|
||||
assert((interferenceIndex >= offset[name1]) && (interferenceIndex < offset[name1 + 1]));
|
||||
|
||||
RegisterName name2 = RegisterName(interferenceIndex - offset[name1]);
|
||||
|
||||
assert(interfere(name1, name2));
|
||||
|
||||
InterferenceVector& vector1 = *vector[name1];
|
||||
vector1.neighbors[vector1.count++] = name2;
|
||||
|
||||
InterferenceVector& vector2 = *vector[name2];
|
||||
vector2.neighbors[vector2.count++] = name1;
|
||||
}
|
||||
} else {
|
||||
trespass("not Implemented"); // FIX: need one more pass to initialize the vectors.
|
||||
}
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
Uint32 InterferenceGraph<RegisterPressure>::getEdgeIndex(RegisterName name1, RegisterName name2)
|
||||
{
|
||||
checkMember(name1); checkMember(name2);
|
||||
assert(name1 != name2); // This is not possible.
|
||||
return (name1 < name2) ? offset[name2] + name1 : offset[name1] + name2;
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
void InterferenceGraph<RegisterPressure>::setInterference(RegisterName name1, RegisterName name2)
|
||||
{
|
||||
interferences->set(getEdgeIndex(name1, name2));
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
bool InterferenceGraph<RegisterPressure>::interfere(RegisterName name1, RegisterName name2)
|
||||
{
|
||||
return interferences->test(getEdgeIndex(name1, name2));
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
template <class RegisterPressure>
|
||||
void InterferenceGraph<RegisterPressure>::printPretty(LogModuleObject log)
|
||||
{
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Interference Vectors:\n"));
|
||||
for (Uint32 i = 1; i < rangeCount; i++) {
|
||||
if (vector[i] != NULL) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\tvr%d: (", i));
|
||||
for (InterferenceVector* v = vector[i]; v != NULL; v = v->next)
|
||||
for (Uint32 j = 0; j < v->count; j++) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%d", v->neighbors[j]));
|
||||
if (v->next != NULL || j != (v->count - 1))
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (","));
|
||||
}
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (")\n"));
|
||||
}
|
||||
}
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Interference Matrix:\n"));
|
||||
for (RegisterName name1 = RegisterName(1); name1 < rangeCount; name1 = RegisterName(name1 + 1)) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\t%d:\t", name1));
|
||||
for (RegisterName name2 = RegisterName(1); name2 < rangeCount; name2 = RegisterName(name2 + 1))
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%c", ((name1 != name2) && interfere(name1, name2)) ? '1' : '0'));
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_LOG
|
||||
|
||||
#endif // _INTERFERENCE_GRAPH_H_
|
||||
87
mozilla/ef/Compiler/RegisterAllocator/LiveRange.h
Normal file
87
mozilla/ef/Compiler/RegisterAllocator/LiveRange.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _LIVE_RANGE_H_
|
||||
#define _LIVE_RANGE_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Primitives.h"
|
||||
#include "Instruction.h"
|
||||
#include "RegisterAllocator.h"
|
||||
#include "RegisterAllocatorTools.h"
|
||||
|
||||
template <class RegisterPressure>
|
||||
struct LiveRange
|
||||
{
|
||||
static void build(RegisterAllocator& registerAllocator);
|
||||
};
|
||||
|
||||
template <class RegisterPressure>
|
||||
void LiveRange<RegisterPressure>::build(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
// Intialize the lookup table.
|
||||
//
|
||||
Uint32 nameCount = registerAllocator.nameCount;
|
||||
RegisterName* nameTable = new(registerAllocator.pool) RegisterName[2*nameCount];
|
||||
RegisterName* rangeName = &nameTable[nameCount];
|
||||
|
||||
init(rangeName, nameCount);
|
||||
|
||||
// Walk the graph.
|
||||
//
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
SparseSet destination(registerAllocator.pool, nameCount);
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
|
||||
|
||||
destination.clear();
|
||||
for (InstructionList::iterator i = phiNodes.begin(); !phiNodes.done(i); i = phiNodes.advance(i)) {
|
||||
Instruction& phiNode = phiNodes.get(i);
|
||||
assert(phiNode.getInstructionDefineBegin() != phiNode.getInstructionDefineEnd() && phiNode.getInstructionDefineBegin()[0].isRegister());
|
||||
destination.set(findRoot(phiNode.getInstructionDefineBegin()[0].getRegisterName(), rangeName));
|
||||
}
|
||||
|
||||
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
|
||||
Instruction& phiNode = phiNodes.get(p);
|
||||
|
||||
assert(phiNode.getInstructionDefineBegin() != phiNode.getInstructionDefineEnd() && phiNode.getInstructionDefineBegin()[0].isRegister());
|
||||
RegisterName destinationName = phiNode.getInstructionDefineBegin()[0].getRegisterName();
|
||||
RegisterName destinationRoot = findRoot(destinationName, rangeName);
|
||||
|
||||
InstructionUse* useEnd = phiNode.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = phiNode.getInstructionUseBegin(); usePtr < useEnd; usePtr++) {
|
||||
assert(usePtr->isRegister());
|
||||
RegisterName sourceName = usePtr->getRegisterName();
|
||||
RegisterName sourceRoot = findRoot(sourceName, rangeName);
|
||||
|
||||
if (sourceRoot != destinationRoot && !destination.test(sourceRoot))
|
||||
rangeName[sourceRoot] = destinationRoot;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
registerAllocator.rangeCount = compress(registerAllocator.name2range, rangeName, nameCount, nameCount);
|
||||
}
|
||||
|
||||
#endif // _LIVE_RANGE_H_
|
||||
163
mozilla/ef/Compiler/RegisterAllocator/LiveRangeGraph.h
Normal file
163
mozilla/ef/Compiler/RegisterAllocator/LiveRangeGraph.h
Normal file
@@ -0,0 +1,163 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _LIVE_RANGE_GRAPH_
|
||||
#define _LIVE_RANGE_GRAPH_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "Pool.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Instruction.h"
|
||||
#include "RegisterTypes.h"
|
||||
|
||||
class RegisterAllocator;
|
||||
|
||||
template <class RegisterPressure>
|
||||
class LiveRangeGraph
|
||||
{
|
||||
private:
|
||||
|
||||
RegisterAllocator& registerAllocator;
|
||||
|
||||
RegisterPressure::Set* edges;
|
||||
Uint32 rangeCount;
|
||||
|
||||
public:
|
||||
//
|
||||
//
|
||||
LiveRangeGraph(RegisterAllocator& registerAllocator) : registerAllocator(registerAllocator) {}
|
||||
|
||||
//
|
||||
//
|
||||
void build();
|
||||
|
||||
//
|
||||
//
|
||||
void addEdge(RegisterName name1, RegisterName name2);
|
||||
|
||||
//
|
||||
//
|
||||
bool haveEdge(RegisterName name1, RegisterName name2);
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
//
|
||||
//
|
||||
void printPretty(LogModuleObject log);
|
||||
#endif // DEBUG_LOG
|
||||
};
|
||||
|
||||
template <class RegisterPressure>
|
||||
void LiveRangeGraph<RegisterPressure>::build()
|
||||
{
|
||||
Pool& pool = registerAllocator.pool;
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
this->rangeCount = rangeCount;
|
||||
|
||||
edges = new(pool) RegisterPressure::Set(pool, rangeCount * rangeCount);
|
||||
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
LivenessInfo<RegisterPressure>& liveness = registerAllocator.liveness;
|
||||
SparseSet currentLive(pool, rangeCount);
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
ControlNode& node = *nodes[n];
|
||||
currentLive = liveness.liveOut[n];
|
||||
|
||||
InstructionList& instructions = node.getInstructions();
|
||||
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useBegin = instruction.getInstructionUseBegin();
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
InstructionUse* usePtr;
|
||||
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
InstructionDefine* definePtr;
|
||||
|
||||
if ((instruction.getFlags() & ifCopy) != 0) {
|
||||
assert(useBegin != useEnd && useBegin[0].isRegister());
|
||||
currentLive.clear(name2range[useBegin[0].getRegisterName()]);
|
||||
}
|
||||
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister()) {
|
||||
RegisterName define = name2range[definePtr->getRegisterName()];
|
||||
|
||||
for (SparseSet::iterator l = currentLive.begin(); !currentLive.done(l); l = currentLive.advance(l)) {
|
||||
RegisterName live = RegisterName(currentLive.get(l));
|
||||
if (define != live && registerAllocator.canInterfere(define, live))
|
||||
addEdge(define, live);
|
||||
}
|
||||
}
|
||||
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
currentLive.clear(name2range[definePtr->getRegisterName()]);
|
||||
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister())
|
||||
currentLive.set(name2range[usePtr->getRegisterName()]);
|
||||
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
RegisterName use = name2range[usePtr->getRegisterName()];
|
||||
|
||||
for (SparseSet::iterator l = currentLive.begin(); !currentLive.done(l); l = currentLive.advance(l)) {
|
||||
RegisterName live = RegisterName(currentLive.get(l));
|
||||
if (use != live && registerAllocator.canInterfere(use, live))
|
||||
addEdge(use, live);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
void LiveRangeGraph<RegisterPressure>::addEdge(RegisterName name1, RegisterName name2)
|
||||
{
|
||||
assert(name1 != name2);
|
||||
edges->set(name1 * rangeCount + name2);
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
bool LiveRangeGraph<RegisterPressure>::haveEdge(RegisterName name1, RegisterName name2)
|
||||
{
|
||||
assert(name1 != name2);
|
||||
return edges->test(name1 * rangeCount + name2);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
template <class RegisterPressure>
|
||||
void LiveRangeGraph<RegisterPressure>::printPretty(LogModuleObject log)
|
||||
{
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Live ranges graph:\n"));
|
||||
for (RegisterName name1 = RegisterName(1); name1 < rangeCount; name1 = RegisterName(name1 + 1)) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\t%d:\t", name1));
|
||||
for (RegisterName name2 = RegisterName(1); name2 < rangeCount; name2 = RegisterName(name2 + 1))
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%c", ((name1 != name2) && haveEdge(name1, name2)) ? '1' : '0'));
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_LOG
|
||||
|
||||
#endif // _LIVE_RANGE_GRAPH_
|
||||
21
mozilla/ef/Compiler/RegisterAllocator/Liveness.cpp
Normal file
21
mozilla/ef/Compiler/RegisterAllocator/Liveness.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "Liveness.h"
|
||||
|
||||
301
mozilla/ef/Compiler/RegisterAllocator/Liveness.h
Normal file
301
mozilla/ef/Compiler/RegisterAllocator/Liveness.h
Normal file
@@ -0,0 +1,301 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _LIVENESS_H_
|
||||
#define _LIVENESS_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Instruction.h"
|
||||
#include "RegisterTypes.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// LivenessInfo -
|
||||
|
||||
template <class RegisterPressure>
|
||||
struct LivenessInfo
|
||||
{
|
||||
RegisterPressure::Set* liveIn;
|
||||
RegisterPressure::Set* liveOut;
|
||||
DEBUG_LOG_ONLY(Uint32 size);
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
void printPretty(LogModuleObject log);
|
||||
#endif // DEBUG_LOG
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Liveness
|
||||
//
|
||||
// The liveness is defined by the following data-flow equations:
|
||||
//
|
||||
// LiveIn(n) = LocalLive(n) U (LiveOut(n) - Killed(n)).
|
||||
// LiveOut(n) = U LiveIn(s) (s a successor of n).
|
||||
//
|
||||
// where LocalLive(n) is the set of used registers in the block n, Killed(n)
|
||||
// is the set of defined registers in the block n, LiveIn(n) is the set of
|
||||
// live registers at the begining of the block n and LiveOut(n) is the set
|
||||
// of live registers at the end of the block n.
|
||||
//
|
||||
//
|
||||
// We will compute the liveness analysis in two stages:
|
||||
//
|
||||
// 1- Build LocalLive(n) (wich is an approximation of LiveIn(n)) and Killed(n)
|
||||
// for each block n.
|
||||
// 2- Perform a backward data-flow analysis to propagate the liveness information
|
||||
// through the entire control-flow graph.
|
||||
//
|
||||
|
||||
template <class RegisterPressure>
|
||||
struct Liveness
|
||||
{
|
||||
static LivenessInfo<RegisterPressure> analysis(ControlGraph& controlGraph, Uint32 rangeCount, const RegisterName* name2range);
|
||||
static LivenessInfo<RegisterPressure> analysis(ControlGraph& controlGraph, Uint32 nameCount);
|
||||
};
|
||||
|
||||
template <class RegisterPressure>
|
||||
LivenessInfo<RegisterPressure> Liveness<RegisterPressure>::analysis(ControlGraph& controlGraph, Uint32 rangeCount, const RegisterName* name2range)
|
||||
{
|
||||
Pool& pool = controlGraph.pool;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
// Allocate the temporary sets.
|
||||
RegisterPressure::Set* killed = new(pool) RegisterPressure::Set[nNodes](pool, rangeCount);
|
||||
|
||||
// Allocate the globals sets.
|
||||
RegisterPressure::Set* liveIn = new(pool) RegisterPressure::Set[nNodes](pool, rangeCount);
|
||||
RegisterPressure::Set* liveOut = new(pool) RegisterPressure::Set[nNodes](pool, rangeCount);
|
||||
|
||||
// First stage of the liveness analysis: Compute the sets LocalLive(stored in LiveIn) and Killed.
|
||||
//
|
||||
for (Uint32 n = 0; n < (nNodes - 1); n++) {
|
||||
ControlNode& node = *nodes[n];
|
||||
|
||||
RegisterPressure::Set& currentLocalLive = liveIn[n];
|
||||
RegisterPressure::Set& currentKilled = killed[n];
|
||||
|
||||
// Find the instructions contributions to the sets LocalLive and Killed.
|
||||
//
|
||||
InstructionList& instructions = node.getInstructions();
|
||||
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
// If a VirtualRegister is 'used' before being 'defined' then we add it to set LocalLive.
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
Uint32 index = name2range[usePtr->getRegisterName()];
|
||||
|
||||
if (!currentKilled.test(index))
|
||||
currentLocalLive.set(index);
|
||||
}
|
||||
|
||||
// If a Virtualregister is 'defined' then we add it to the set Killed.
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
currentKilled.set(name2range[definePtr->getRegisterName()]);
|
||||
}
|
||||
}
|
||||
|
||||
// Second stage of the liveness analysis: We propagate the LiveIn & LiveOut through the entire
|
||||
// control-flow graph.
|
||||
//
|
||||
RegisterPressure::Set temp(pool, rangeCount);
|
||||
|
||||
bool changed;
|
||||
do {
|
||||
changed = false;
|
||||
|
||||
// For all nodes is this graph except the endNode.
|
||||
for (Int32 n = (nNodes - 2); n >= 0; n--) {
|
||||
ControlNode& node = *nodes[n];
|
||||
|
||||
RegisterPressure::Set& currentLiveIn = liveIn[n];
|
||||
RegisterPressure::Set& currentLiveOut = liveOut[n];
|
||||
|
||||
// Compute temp = Union of LiveIn(s) (s a successor of this node) | usedByPhiNodes(n).
|
||||
// temp will be the new LiveOut(n).
|
||||
Uint32 nSuccessors = node.nSuccessors();
|
||||
if (nSuccessors != 0) {
|
||||
temp = liveIn[node.nthSuccessor(0).getTarget().dfsNum];
|
||||
for (Uint32 s = 1; s < nSuccessors; s++)
|
||||
temp |= liveIn[node.nthSuccessor(s).getTarget().dfsNum];
|
||||
} else
|
||||
temp.clear();
|
||||
|
||||
// If temp and LiveOut(n) differ then set LiveOut(n) = temp and recalculate the
|
||||
// new LiveIn(n).
|
||||
if (currentLiveOut != temp) {
|
||||
currentLiveOut = temp;
|
||||
temp -= killed[n]; // FIX: could be optimized with one call to unionDiff !
|
||||
temp |= currentLiveIn;
|
||||
|
||||
if (currentLiveIn != temp) {
|
||||
currentLiveIn = temp;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while(changed);
|
||||
|
||||
LivenessInfo<RegisterPressure> liveness;
|
||||
liveness.liveIn = liveIn;
|
||||
liveness.liveOut = liveOut;
|
||||
DEBUG_LOG_ONLY(liveness.size = nNodes);
|
||||
return liveness;
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
LivenessInfo<RegisterPressure> Liveness<RegisterPressure>::analysis(ControlGraph& controlGraph, Uint32 nameCount)
|
||||
{
|
||||
Pool& pool = controlGraph.pool;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
// Allocate the temporary sets.
|
||||
RegisterPressure::Set* killed = new(pool) RegisterPressure::Set[nNodes](pool, nameCount);
|
||||
RegisterPressure::Set* usedByPhiNodes = NULL;
|
||||
|
||||
// Allocate the globals sets.
|
||||
RegisterPressure::Set* liveIn = new(pool) RegisterPressure::Set[nNodes](pool, nameCount);
|
||||
RegisterPressure::Set* liveOut = new(pool) RegisterPressure::Set[nNodes](pool, nameCount);
|
||||
|
||||
// First stage of the liveness analysis: Compute the sets LocalLive(stored in LiveIn) and Killed.
|
||||
//
|
||||
for (Uint32 n = 0; n < (nNodes - 1); n++) {
|
||||
ControlNode& node = *nodes[n];
|
||||
|
||||
RegisterPressure::Set& currentLocalLive = liveIn[n];
|
||||
RegisterPressure::Set& currentKilled = killed[n];
|
||||
|
||||
InstructionList& phiNodes = node.getPhiNodeInstructions();
|
||||
|
||||
if ((usedByPhiNodes == NULL) && !phiNodes.empty())
|
||||
usedByPhiNodes = new(pool) RegisterPressure::Set[nNodes](pool, nameCount);
|
||||
|
||||
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
|
||||
Instruction& phiNode = phiNodes.get(p);
|
||||
|
||||
InstructionDefine& define = phiNode.getInstructionDefineBegin()[0];
|
||||
currentKilled.set(define.getRegisterName());
|
||||
|
||||
typedef DoublyLinkedList<ControlEdge> ControlEdgeList;
|
||||
const ControlEdgeList& predecessors = node.getPredecessors();
|
||||
ControlEdgeList::iterator p = predecessors.begin();
|
||||
InstructionUse* useEnd = phiNode.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = phiNode.getInstructionUseBegin(); usePtr < useEnd; usePtr++, p = predecessors.advance(p))
|
||||
if (usePtr->isRegister())
|
||||
usedByPhiNodes[predecessors.get(p).getSource().dfsNum].set(usePtr->getRegisterName());
|
||||
}
|
||||
|
||||
// Find the instructions contributions to the sets LocalLive and Killed.
|
||||
//
|
||||
InstructionList& instructions = node.getInstructions();
|
||||
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
// If a VirtualRegister is 'used' before being 'defined' then we add it to set LocalLive.
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
Uint32 index = usePtr->getRegisterName();
|
||||
|
||||
if (!currentKilled.test(index))
|
||||
currentLocalLive.set(index);
|
||||
}
|
||||
|
||||
// If a Virtualregister is 'defined' then we add it to the set Killed.
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
currentKilled.set(definePtr->getRegisterName());
|
||||
}
|
||||
}
|
||||
|
||||
// Second stage of the liveness analysis: We propagate the LiveIn & LiveOut through the entire
|
||||
// control-flow graph.
|
||||
//
|
||||
RegisterPressure::Set temp(pool, nameCount);
|
||||
|
||||
bool changed;
|
||||
do {
|
||||
changed = false;
|
||||
|
||||
// For all nodes is this graph except the endNode.
|
||||
for (Int32 n = (nNodes - 2); n >= 0; n--) {
|
||||
ControlNode& node = *nodes[n];
|
||||
|
||||
RegisterPressure::Set& currentLiveIn = liveIn[n];
|
||||
RegisterPressure::Set& currentLiveOut = liveOut[n];
|
||||
|
||||
// Compute temp = Union of LiveIn(s) (s a successor of this node) | usedByPhiNodes(n).
|
||||
// temp will be the new LiveOut(n).
|
||||
Uint32 nSuccessors = node.nSuccessors();
|
||||
if (nSuccessors != 0) {
|
||||
temp = liveIn[node.nthSuccessor(0).getTarget().dfsNum];
|
||||
for (Uint32 s = 1; s < nSuccessors; s++)
|
||||
temp |= liveIn[node.nthSuccessor(s).getTarget().dfsNum];
|
||||
} else
|
||||
temp.clear();
|
||||
|
||||
// Insert the phiNodes contribution.
|
||||
if (usedByPhiNodes != NULL)
|
||||
temp |= usedByPhiNodes[n];
|
||||
|
||||
// If temp and LiveOut(n) differ then set LiveOut(n) = temp and recalculate the
|
||||
// new LiveIn(n).
|
||||
if (currentLiveOut != temp) {
|
||||
currentLiveOut = temp;
|
||||
temp -= killed[n]; // FIX: could be optimized with one call to unionDiff !
|
||||
temp |= currentLiveIn;
|
||||
|
||||
if (currentLiveIn != temp) {
|
||||
currentLiveIn = temp;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while(changed);
|
||||
|
||||
LivenessInfo<RegisterPressure> liveness;
|
||||
liveness.liveIn = liveIn;
|
||||
liveness.liveOut = liveOut;
|
||||
DEBUG_LOG_ONLY(liveness.size = nNodes);
|
||||
return liveness;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
template <class RegisterPressure>
|
||||
void LivenessInfo<RegisterPressure>::printPretty(LogModuleObject log)
|
||||
{
|
||||
for (Uint32 n = 0; n < size; n++) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Node N%d:\n\tliveIn = ", n));
|
||||
liveIn[n].printPretty(log);
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\tliveOut = "));
|
||||
liveOut[n].printPretty(log);
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_LOG
|
||||
|
||||
#endif // _LIVENESS_H_
|
||||
40
mozilla/ef/Compiler/RegisterAllocator/Makefile
Normal file
40
mozilla/ef/Compiler/RegisterAllocator/Makefile
Normal file
@@ -0,0 +1,40 @@
|
||||
#! gmake
|
||||
|
||||
DEPTH = ../..
|
||||
|
||||
MODULE_NAME = RegisterAllocator
|
||||
|
||||
include $(DEPTH)/config/config.mk
|
||||
|
||||
INCLUDES += \
|
||||
-I$(DEPTH)/Utilities/General \
|
||||
-I$(DEPTH)/Utilities/zlib \
|
||||
-I$(DEPTH)/Runtime/ClassReader \
|
||||
-I$(DEPTH)/Runtime/NativeMethods \
|
||||
-I$(DEPTH)/Runtime/System \
|
||||
-I$(DEPTH)/Runtime/ClassInfo \
|
||||
-I$(DEPTH)/Runtime/FileReader \
|
||||
-I$(DEPTH)/Compiler/PrimitiveGraph \
|
||||
-I$(DEPTH)/Compiler/FrontEnd \
|
||||
-I$(DEPTH)/Compiler/Optimizer \
|
||||
-I$(DEPTH)/Compiler/CodeGenerator \
|
||||
-I$(DEPTH)/Compiler/CodeGenerator/md \
|
||||
-I$(DEPTH)/Compiler/CodeGenerator/md/$(CPU_ARCH) \
|
||||
-I$(DEPTH)/Compiler/RegisterAllocator \
|
||||
-I$(DEPTH)/Driver/StandAloneJava \
|
||||
-I$(DEPTH)/Debugger \
|
||||
$(NULL)
|
||||
|
||||
CXXSRCS = \
|
||||
RegisterAllocator.cpp \
|
||||
RegisterAllocatorTools.cpp \
|
||||
DominatorGraph.cpp \
|
||||
VirtualRegister.cpp \
|
||||
BitSet.cpp \
|
||||
SparseSet.cpp \
|
||||
$(NULL)
|
||||
|
||||
|
||||
include $(DEPTH)/config/rules.mk
|
||||
|
||||
libs:: $(MODULE)
|
||||
392
mozilla/ef/Compiler/RegisterAllocator/PhiNodeRemover.h
Normal file
392
mozilla/ef/Compiler/RegisterAllocator/PhiNodeRemover.h
Normal file
@@ -0,0 +1,392 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _PHI_NODE_REMOVER_H_
|
||||
#define _PHI_NODE_REMOVER_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "Pool.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "DominatorGraph.h"
|
||||
#include "VirtualRegister.h"
|
||||
#include "RegisterPressure.h"
|
||||
#include "Liveness.h"
|
||||
#include "Instruction.h"
|
||||
#include "InstructionEmitter.h"
|
||||
#include "SparseSet.h"
|
||||
#include <string.h>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// RegisterNameNode -
|
||||
|
||||
struct RegisterNameNode
|
||||
{
|
||||
RegisterNameNode* next;
|
||||
RegisterName newName;
|
||||
Uint32 nextPushed;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// CopyData -
|
||||
|
||||
struct CopyData
|
||||
{
|
||||
RegisterName source;
|
||||
RegisterClassKind classKind;
|
||||
Uint32 useCount;
|
||||
bool isLiveOut;
|
||||
RegisterName sourceNameToUse;
|
||||
RegisterName temporaryName;
|
||||
RegisterNameNode* newName;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// PhiNodeRemover<RegisterPressure> -
|
||||
|
||||
template <class RegisterPressure>
|
||||
struct PhiNodeRemover
|
||||
{
|
||||
// Replace the phi nodes by copy instructions.
|
||||
static void replacePhiNodes(ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter);
|
||||
};
|
||||
|
||||
// Split some of the critical edges and return true if there are still some
|
||||
// in the graph after that.
|
||||
//
|
||||
static bool splitCriticalEdges(ControlGraph& /*cg*/)
|
||||
{
|
||||
// FIX: not implemented.
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void pushName(Pool& pool, RegisterNameNode** stack, SparseSet& pushed, Uint32* nodeListPointer, RegisterName oldName, RegisterName newName)
|
||||
{
|
||||
RegisterNameNode& newNode = *new(pool) RegisterNameNode();
|
||||
|
||||
if (pushed.test(oldName))
|
||||
(*stack)->newName = newName;
|
||||
else {
|
||||
newNode.newName = newName;
|
||||
newNode.nextPushed = *nodeListPointer;
|
||||
*nodeListPointer = oldName;
|
||||
newNode.next = *stack;
|
||||
*stack = &newNode;
|
||||
pushed.set(oldName);
|
||||
}
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
void PhiNodeRemover<RegisterPressure>::replacePhiNodes(ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter)
|
||||
{
|
||||
Pool& pool = controlGraph.pool;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
// Initialize the local variables.
|
||||
//
|
||||
|
||||
// When we insert the copies we will also need to create new VirtualRegisters for
|
||||
// the insertion of temporaries. The maximum number of temporary register will not
|
||||
// exceed the number of phiNodes in the primitive graph.
|
||||
Uint32 nameCount = vrManager.getSize();
|
||||
Uint32 maxNameCount = nameCount;
|
||||
for (Uint32 n = 0; n < nNodes; n++)
|
||||
maxNameCount += nodes[n]->getPhiNodes().length();
|
||||
|
||||
// If the CFG contains some critical edges (backward edge which source has more than one
|
||||
// outgoing edge and destination has more than one incomimg edge) then we need the liveness
|
||||
// information to be able to insert temporary copies.
|
||||
RegisterPressure::Set* liveOut = NULL;
|
||||
if (splitCriticalEdges(controlGraph))
|
||||
liveOut = Liveness<LowRegisterPressure>::analysis(controlGraph, nameCount).liveOut;
|
||||
|
||||
DominatorGraph dGraph(controlGraph);
|
||||
|
||||
SparseSet pushed(pool, maxNameCount);
|
||||
SparseSet destinationList(pool, maxNameCount);
|
||||
SparseSet workList(pool, maxNameCount);
|
||||
|
||||
CopyData* copyStats = new(pool) CopyData[maxNameCount];
|
||||
memset(copyStats, '\0', maxNameCount*sizeof(CopyData));
|
||||
|
||||
struct NodeStack {
|
||||
Uint32* next;
|
||||
Uint32* limit;
|
||||
Uint32 pushedList;
|
||||
};
|
||||
|
||||
// Allocate the node stack and initialize the node stack pointer.
|
||||
NodeStack* nodeStack = new(pool) NodeStack[nNodes + 1];
|
||||
NodeStack* nodeStackPtr = nodeStack;
|
||||
|
||||
// We start by the begin node.
|
||||
Uint32 startNode = 0;
|
||||
Uint32* next = &startNode;
|
||||
Uint32* limit = &startNode + 1;
|
||||
|
||||
while (true) {
|
||||
|
||||
if (next == limit) {
|
||||
// If there are no more node in the sibling, we have to pop the current
|
||||
// frame from the stack and update the copyStats of the pushed nodes.
|
||||
//
|
||||
if (nodeStackPtr == nodeStack)
|
||||
// We are at the bottom of the stack and there are no more nodes
|
||||
// to look at. We are done !
|
||||
break;
|
||||
|
||||
--nodeStackPtr;
|
||||
// We are done with all the children of this node in the dominator tree.
|
||||
// We need to update the copy information of all the new names pushed
|
||||
// during the walk over this node.
|
||||
Uint32 pushedList = nodeStackPtr->pushedList;
|
||||
while (pushedList != 0) {
|
||||
Uint32 nextName = copyStats[pushedList].newName->nextPushed;
|
||||
copyStats[pushedList].newName = copyStats[pushedList].newName->next;
|
||||
pushedList = nextName;
|
||||
}
|
||||
|
||||
// restore the previous frame.
|
||||
next = nodeStackPtr->next;
|
||||
limit = nodeStackPtr->limit;
|
||||
} else {
|
||||
Uint32 currentNode = *next++;
|
||||
Uint32 pushedList = 0;
|
||||
|
||||
|
||||
// Initialize the sets.
|
||||
pushed.clear();
|
||||
destinationList.clear();
|
||||
|
||||
// STEP1:
|
||||
// Walk the instruction list and to replace all the instruction uses with their new name.
|
||||
// If the instruction is a phi node and its defined register is alive at the end of this
|
||||
// block then we push the defined register into the stack.
|
||||
//
|
||||
ControlNode& node = *nodes[currentNode];
|
||||
RegisterPressure::Set* currentLiveOut = (liveOut != NULL) ? &liveOut[currentNode] : (RegisterPressure::Set*) 0;
|
||||
|
||||
InstructionList& phiNodes = node.getPhiNodeInstructions();
|
||||
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
|
||||
Instruction& phiNode = phiNodes.get(p);
|
||||
|
||||
InstructionUse* useEnd = phiNode.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = phiNode.getInstructionUseBegin(); usePtr < useEnd; usePtr++) {
|
||||
assert(usePtr->isRegister());
|
||||
RegisterName name = usePtr->getRegisterName();
|
||||
|
||||
if (copyStats[name].newName != NULL && copyStats[name].newName->newName != name)
|
||||
usePtr->setRegisterName(copyStats[name].newName->newName);
|
||||
}
|
||||
|
||||
if (currentLiveOut != NULL) {
|
||||
// This is a phi node and we have to push its defined name if it is live
|
||||
// at the end of the node. We only need to do this if the CFG has critical edges.
|
||||
assert(phiNode.getInstructionDefineBegin() != phiNode.getInstructionDefineEnd() && phiNode.getInstructionDefineBegin()[0].isRegister());
|
||||
RegisterName name = phiNode.getInstructionDefineBegin()[0].getRegisterName();
|
||||
|
||||
if (currentLiveOut->test(name))
|
||||
pushName(pool, &(copyStats[name].newName), pushed, &pushedList, name, name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
InstructionList& instructions = node.getInstructions();
|
||||
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
RegisterName name = usePtr->getRegisterName();
|
||||
|
||||
if (copyStats[name].newName != NULL && copyStats[name].newName->newName != name)
|
||||
usePtr->setRegisterName(copyStats[name].newName->newName);
|
||||
}
|
||||
}
|
||||
|
||||
// STEP2:
|
||||
// Look at this node's successors' phiNodes. We keep track of the number of time
|
||||
// a VR will be used by another copy instruction and insert each definition into the
|
||||
// destinationList. This is the only pass over this node's successors as we will
|
||||
// get all the information we need in the CopyData structures.
|
||||
//
|
||||
ControlEdge* successorEdgeEnd = node.getSuccessorsEnd();
|
||||
for (ControlEdge* successorEdgePtr = node.getSuccessorsBegin(); successorEdgePtr < successorEdgeEnd; successorEdgePtr++) {
|
||||
Uint32 useIndex = successorEdgePtr->getIndex();
|
||||
ControlNode& successor = successorEdgePtr->getTarget();
|
||||
|
||||
// Look at its phi nodes. The phi nodes are at the top of the instruction list. We exit
|
||||
// as soon as we find an instruction which is not a phi node
|
||||
InstructionList& phiNodes = successor.getPhiNodeInstructions();
|
||||
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
|
||||
Instruction& phiNode = phiNodes.get(p);
|
||||
|
||||
assert((phiNode.getInstructionUseBegin() + useIndex) < phiNode.getInstructionUseEnd());
|
||||
assert(phiNode.getInstructionDefineBegin() != phiNode.getInstructionDefineEnd());
|
||||
|
||||
InstructionUse& source = phiNode.getInstructionUseBegin()[useIndex];
|
||||
InstructionDefine& destination = phiNode.getInstructionDefineBegin()[0];
|
||||
|
||||
assert(source.isRegister() && destination.isRegister());
|
||||
|
||||
RegisterName sourceName = source.getRegisterName();
|
||||
RegisterName destinationName = destination.getRegisterName();
|
||||
|
||||
// Get the correct name for the source.
|
||||
if (copyStats[sourceName].newName != NULL)
|
||||
sourceName = copyStats[sourceName].newName->newName;
|
||||
|
||||
// Update the CopyData structures.
|
||||
if ((sourceName != rnInvalid) && (sourceName != destinationName)) {
|
||||
copyStats[destinationName].source = sourceName;
|
||||
copyStats[destinationName].classKind = destination.getRegisterClass();
|
||||
copyStats[destinationName].isLiveOut = (currentLiveOut != NULL) ? currentLiveOut->test(destinationName) : false;
|
||||
copyStats[destinationName].sourceNameToUse = destinationName;
|
||||
copyStats[sourceName].sourceNameToUse = sourceName;
|
||||
copyStats[sourceName].useCount++;
|
||||
destinationList.set(destinationName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// STEP3:
|
||||
// Insert into the worklist only the destination registers that will be not used in
|
||||
// another copy instruction in this block.
|
||||
//
|
||||
assert(workList.getSize() == 0);
|
||||
for (SparseSet::iterator d = destinationList.begin(); !destinationList.done(d); d = destinationList.advance(d)) {
|
||||
Uint32 dest = destinationList.get(d);
|
||||
if (copyStats[dest].useCount == 0)
|
||||
workList.set(dest);
|
||||
}
|
||||
|
||||
// STEP4:
|
||||
// Insert the copy instructions.
|
||||
//
|
||||
Uint32 destinationListSize = destinationList.getSize();
|
||||
InstructionList::iterator endOfTheNode = instructions.end();
|
||||
|
||||
// Find the right place to insert the copy instructions.
|
||||
if (destinationListSize != 0)
|
||||
while (instructions.get(endOfTheNode).getFlags() & ifControl)
|
||||
endOfTheNode = instructions.retreat(endOfTheNode);
|
||||
|
||||
while (destinationListSize != 0) {
|
||||
while(workList.getSize()) {
|
||||
RegisterName destinationName = RegisterName(workList.getOne());
|
||||
RegisterName sourceName = copyStats[destinationName].source;
|
||||
|
||||
workList.clear(destinationName);
|
||||
if (copyStats[destinationName].isLiveOut && !copyStats[destinationName].temporaryName) {
|
||||
// Lost copy problem.
|
||||
copyStats[destinationName].isLiveOut = false;
|
||||
|
||||
RegisterName sourceName = destinationName;
|
||||
RegisterClassKind classKind = copyStats[sourceName].classKind;
|
||||
RegisterName destinationName = getName(vrManager.newVirtualRegister(classKind));
|
||||
assert(destinationName < maxNameCount);
|
||||
|
||||
copyStats[destinationName].classKind = classKind;
|
||||
copyStats[sourceName].useCount = 0;
|
||||
|
||||
// We need to insert a copy to a temporary register to keep the
|
||||
// source register valid at the end of the node defining it.
|
||||
// This copy will be inserted right after the phi node defining it.
|
||||
RegisterName from = copyStats[sourceName].sourceNameToUse;
|
||||
Instruction* definingPhiNode = vrManager.getVirtualRegister(from).getDefiningInstruction();
|
||||
assert(definingPhiNode && (definingPhiNode->getFlags() & ifPhiNode) != 0);
|
||||
|
||||
RegisterID fromID = buildRegisterID(from, classKind);
|
||||
RegisterID toID = buildRegisterID(destinationName, classKind);
|
||||
Instruction& copy = emitter.newCopy(*definingPhiNode->getPrimitive(), fromID, toID);
|
||||
vrManager.getVirtualRegister(destinationName).setDefiningInstruction(copy);
|
||||
definingPhiNode->getPrimitive()->getContainer()->getInstructions().addFirst(copy);
|
||||
|
||||
copyStats[sourceName].temporaryName = destinationName;
|
||||
copyStats[sourceName].sourceNameToUse = destinationName;
|
||||
pushName(pool, &(copyStats[sourceName].newName), pushed, &pushedList, sourceName, destinationName);
|
||||
}
|
||||
|
||||
// Insert the copy instruction at the end of the current node.
|
||||
RegisterName from = copyStats[sourceName].sourceNameToUse;
|
||||
|
||||
RegisterClassKind classKind = copyStats[destinationName].classKind;
|
||||
RegisterID fromID = buildRegisterID(from, classKind);
|
||||
RegisterID toID = buildRegisterID(destinationName, classKind);
|
||||
Instruction& copy = emitter.newCopy(*vrManager.getVirtualRegister(from).getDefiningInstruction()->getPrimitive(), fromID, toID);
|
||||
instructions.insertAfter(copy, endOfTheNode);
|
||||
endOfTheNode = instructions.advance(endOfTheNode);
|
||||
|
||||
copyStats[sourceName].useCount = 0;
|
||||
if (destinationList.test(sourceName) && copyStats[sourceName].isLiveOut)
|
||||
pushName(pool, &(copyStats[sourceName].newName), pushed, &pushedList, sourceName, destinationName);
|
||||
copyStats[sourceName].isLiveOut = false;
|
||||
copyStats[sourceName].sourceNameToUse = destinationName;
|
||||
|
||||
if (destinationList.test(sourceName))
|
||||
workList.set(sourceName);
|
||||
destinationList.clear(destinationName);
|
||||
}
|
||||
|
||||
destinationListSize = destinationList.getSize();
|
||||
if (destinationListSize != 0) {
|
||||
RegisterName sourceName = RegisterName(destinationList.getOne());
|
||||
RegisterName destinationName;
|
||||
|
||||
if (!copyStats[sourceName].temporaryName) {
|
||||
// Cycle problem.
|
||||
RegisterClassKind classKind = copyStats[sourceName].classKind;
|
||||
destinationName = getName(vrManager.newVirtualRegister(classKind));
|
||||
assert(destinationName < maxNameCount);
|
||||
|
||||
copyStats[destinationName].classKind = classKind;
|
||||
copyStats[sourceName].temporaryName = destinationName;
|
||||
|
||||
// Insert the copy instruction at the end of the current node.
|
||||
RegisterName from = copyStats[sourceName].sourceNameToUse;
|
||||
|
||||
RegisterID fromID = buildRegisterID(from, classKind);
|
||||
RegisterID toID = buildRegisterID(destinationName, classKind);
|
||||
Instruction& copy = emitter.newCopy(*vrManager.getVirtualRegister(from).getDefiningInstruction()->getPrimitive(), fromID, toID);
|
||||
vrManager.getVirtualRegister(destinationName).setDefiningInstruction(copy);
|
||||
instructions.insertAfter(copy, endOfTheNode);
|
||||
endOfTheNode = instructions.advance(endOfTheNode);
|
||||
} else
|
||||
destinationName = copyStats[sourceName].temporaryName;
|
||||
|
||||
copyStats[sourceName].useCount = 0;
|
||||
copyStats[sourceName].isLiveOut = false;
|
||||
copyStats[sourceName].sourceNameToUse = destinationName;
|
||||
pushName(pool, &(copyStats[sourceName].newName), pushed, &pushedList, sourceName, destinationName);
|
||||
|
||||
workList.set(sourceName);
|
||||
}
|
||||
}
|
||||
|
||||
nodeStackPtr->pushedList = pushedList;
|
||||
nodeStackPtr->next = next;
|
||||
nodeStackPtr->limit = limit;
|
||||
++nodeStackPtr;
|
||||
next = dGraph.getSuccessorsBegin(currentNode);
|
||||
limit = dGraph.getSuccessorsEnd(currentNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // _PHI_NODE_REMOVER_H_
|
||||
155
mozilla/ef/Compiler/RegisterAllocator/RegisterAllocator.cpp
Normal file
155
mozilla/ef/Compiler/RegisterAllocator/RegisterAllocator.cpp
Normal file
@@ -0,0 +1,155 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "LogModule.h"
|
||||
#include "RegisterAllocator.h"
|
||||
#include "RegisterPressure.h"
|
||||
#include "RegisterAllocatorTools.h"
|
||||
#include "PhiNodeRemover.h"
|
||||
#include "LiveRange.h"
|
||||
#include "Liveness.h"
|
||||
#include "InterferenceGraph.h"
|
||||
#include "LiveRangeGraph.h"
|
||||
#include "Coalescing.h"
|
||||
#include "Spilling.h"
|
||||
#include "Coloring.h"
|
||||
#include "Splits.h"
|
||||
|
||||
class Pool;
|
||||
class ControlGraph;
|
||||
class VirtualRegisterManager;
|
||||
class InstructionEmitter;
|
||||
|
||||
UT_DEFINE_LOG_MODULE(RegAlloc);
|
||||
|
||||
void RegisterAllocator::allocateRegisters(Pool& pool, ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter)
|
||||
{
|
||||
// Insert the phi node instructions. We want to do this to have a single defined register per instruction.
|
||||
// If we keep the PhiNode (as a DataNode) and a PhiNode is of DoubleWordKind then we have to execute
|
||||
// some special code for the high word annotation.
|
||||
//
|
||||
RegisterAllocatorTools::insertPhiNodeInstructions(controlGraph, emitter);
|
||||
|
||||
// Perform some tests on the instruction graph.
|
||||
//
|
||||
DEBUG_ONLY(RegisterAllocatorTools::testTheInstructionGraph(controlGraph, vrManager));
|
||||
|
||||
// Replace the phi node instructions by their equivalent copy instructions.
|
||||
//
|
||||
PhiNodeRemover<LowRegisterPressure>::replacePhiNodes(controlGraph, vrManager, emitter);
|
||||
|
||||
// Do the register allocation.
|
||||
//
|
||||
RegisterAllocator registerAllocator(pool, controlGraph, vrManager, emitter);
|
||||
registerAllocator.doGraphColoring();
|
||||
}
|
||||
|
||||
void RegisterAllocator::doGraphColoring()
|
||||
{
|
||||
// Initialize the liverange map.
|
||||
//
|
||||
initLiveRanges();
|
||||
|
||||
// Build the live ranges. We do this to compress the number of RegisterNames
|
||||
// used in the insterference graph.
|
||||
//
|
||||
LiveRange<LowRegisterPressure>::build(*this);
|
||||
|
||||
// Remove unnecessary copies.
|
||||
//
|
||||
RegisterAllocatorTools::removeUnnecessaryCopies(*this);
|
||||
|
||||
for (Uint8 loop = 0; loop < 10; loop++) {
|
||||
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("********* RegisterAllocator loop %d *********\n", loop));
|
||||
|
||||
while(true) {
|
||||
// Build the interference graph.
|
||||
//
|
||||
iGraph.build();
|
||||
|
||||
// Coalesce the copy instructions.
|
||||
//
|
||||
if (!Coalescing<LowRegisterPressure>::coalesce(*this))
|
||||
break;
|
||||
}
|
||||
|
||||
// Print the interference graph.
|
||||
//
|
||||
DEBUG_LOG_ONLY(iGraph.printPretty(UT_LOG_MODULE(RegAlloc)));
|
||||
|
||||
// Calculate the spill costs.
|
||||
//
|
||||
Spilling<LowRegisterPressure>::calculateSpillCosts(*this);
|
||||
DEBUG_LOG_ONLY(RegisterAllocatorTools::printSpillCosts(*this));
|
||||
|
||||
// Calculate the split costs.
|
||||
//
|
||||
Splits<LowRegisterPressure>::calculateSplitCosts(*this);
|
||||
DEBUG_LOG_ONLY(RegisterAllocatorTools::printSplitCosts(*this));
|
||||
|
||||
// Build the live range graph.
|
||||
//
|
||||
lGraph.build();
|
||||
DEBUG_LOG_ONLY(lGraph.printPretty(UT_LOG_MODULE(RegAlloc)));
|
||||
|
||||
// Color the graph. If it succeeds then we're done with the
|
||||
// register allocation.
|
||||
//
|
||||
if (Coloring<LowRegisterPressure>::color(*this)) {
|
||||
// Write the final colors in the instruction graph.
|
||||
//
|
||||
Coloring<LowRegisterPressure>::finalColoring(*this);
|
||||
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("********** RegisterAllocator done **********\n"));
|
||||
DEBUG_LOG_ONLY(RegisterAllocatorTools::printInstructions(*this));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// We need to spill some registers.
|
||||
//
|
||||
Spilling<LowRegisterPressure>::insertSpillCode(*this);
|
||||
|
||||
// Insert the split instructions.
|
||||
//
|
||||
Splits<LowRegisterPressure>::insertSplitCode(*this);
|
||||
|
||||
// Update the live ranges.
|
||||
//
|
||||
// FIX
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
RegisterAllocatorTools::updateInstructionGraph(*this);
|
||||
RegisterAllocatorTools::printInstructions(*this);
|
||||
#endif
|
||||
fprintf(stderr, "!!! Coloring failed after 10 loops !!!\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
void RegisterAllocator::initLiveRanges()
|
||||
{
|
||||
Uint32 count = this->nameCount;
|
||||
RegisterName* name2range = new(pool) RegisterName[nameCount];
|
||||
for (RegisterName r = RegisterName(1); r < count; r = RegisterName(r + 1))
|
||||
name2range[r] = r;
|
||||
this->name2range = name2range;
|
||||
rangeCount = count;
|
||||
}
|
||||
88
mozilla/ef/Compiler/RegisterAllocator/RegisterAllocator.h
Normal file
88
mozilla/ef/Compiler/RegisterAllocator/RegisterAllocator.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _REGISTER_ALLOCATOR_H_
|
||||
#define _REGISTER_ALLOCATOR_H_
|
||||
|
||||
class Pool;
|
||||
class ControlGraph;
|
||||
class InstructionEmitter;
|
||||
struct SpillCost;
|
||||
struct SplitCost;
|
||||
|
||||
#include "Liveness.h"
|
||||
#include "VirtualRegister.h"
|
||||
#include "RegisterPressure.h" // This should included by Backend.cpp
|
||||
#include "InterferenceGraph.h"
|
||||
#include "LiveRangeGraph.h"
|
||||
|
||||
//template <class RegisterPressure>
|
||||
class RegisterAllocator
|
||||
{
|
||||
public:
|
||||
|
||||
Pool& pool; //
|
||||
ControlGraph& controlGraph; //
|
||||
VirtualRegisterManager& vrManager; //
|
||||
InstructionEmitter& emitter; //
|
||||
|
||||
RegisterName* name2range; //
|
||||
RegisterName* color; //
|
||||
SpillCost* spillCost; //
|
||||
SparseSet* willSpill; //
|
||||
SplitCost* splitCost; //
|
||||
NameLinkedList** splitAround; //
|
||||
InterferenceGraph<LowRegisterPressure> iGraph; //
|
||||
LiveRangeGraph<LowRegisterPressure> lGraph; //
|
||||
LivenessInfo<LowRegisterPressure> liveness; //
|
||||
Uint32 nameCount; //
|
||||
Uint32 rangeCount; //
|
||||
bool splitFound; //
|
||||
|
||||
private:
|
||||
|
||||
//
|
||||
//
|
||||
void doGraphColoring();
|
||||
|
||||
public:
|
||||
|
||||
//
|
||||
//
|
||||
inline RegisterAllocator(Pool& pool, ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter);
|
||||
|
||||
//
|
||||
//
|
||||
bool canInterfere(RegisterName /*name1*/, RegisterName /*name2*/) const {return true;}
|
||||
|
||||
//
|
||||
//
|
||||
void initLiveRanges();
|
||||
|
||||
//
|
||||
//
|
||||
static void allocateRegisters(Pool& pool, ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter);
|
||||
};
|
||||
|
||||
//
|
||||
//
|
||||
inline RegisterAllocator::RegisterAllocator(Pool& pool, ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter)
|
||||
: pool(pool), controlGraph(controlGraph), vrManager(vrManager), emitter(emitter), iGraph(*this), lGraph(*this), nameCount(vrManager.getSize()) {}
|
||||
|
||||
#endif // _REGISTER_ALLOCATOR_H_
|
||||
|
||||
355
mozilla/ef/Compiler/RegisterAllocator/RegisterAllocatorTools.cpp
Normal file
355
mozilla/ef/Compiler/RegisterAllocator/RegisterAllocatorTools.cpp
Normal file
@@ -0,0 +1,355 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "LogModule.h"
|
||||
#include "RegisterAllocatorTools.h"
|
||||
#include "Pool.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Primitives.h"
|
||||
#include "InstructionEmitter.h"
|
||||
#include "Instruction.h"
|
||||
#include "RegisterAllocator.h"
|
||||
#include "Spilling.h"
|
||||
#include "Splits.h"
|
||||
#include "BitSet.h"
|
||||
|
||||
UT_EXTERN_LOG_MODULE(RegAlloc);
|
||||
|
||||
#ifdef DEBUG
|
||||
void RegisterAllocatorTools::testTheInstructionGraph(ControlGraph& controlGraph, VirtualRegisterManager& vrManager)
|
||||
{
|
||||
// Test the declared VirtualRegisters. The register allocator tries to condense the register universe.
|
||||
// Any gap in the VirtualRegister names will be a loss of efficiency !!!!
|
||||
|
||||
Uint32 nameCount = vrManager.getSize();
|
||||
BitSet registerSeen(controlGraph.pool, nameCount);
|
||||
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister())
|
||||
registerSeen.set(usePtr->getRegisterName());
|
||||
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
registerSeen.set(definePtr->getRegisterName());
|
||||
}
|
||||
|
||||
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
|
||||
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
|
||||
Instruction& instruction = phiNodes.get(p);
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister())
|
||||
registerSeen.set(usePtr->getRegisterName());
|
||||
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
registerSeen.set(definePtr->getRegisterName());
|
||||
}
|
||||
}
|
||||
|
||||
bool renameRegisters = false;
|
||||
for (BitSet::iterator i = registerSeen.nextZero(0); !registerSeen.done(i); i = registerSeen.nextZero(i)) {
|
||||
renameRegisters = true;
|
||||
fprintf(stderr,
|
||||
"WARNING: The VirtualRegister vr%d has been allocated during CodeGeneration but\n"
|
||||
" is never used nor defined by any instruction in the instruction graph\n"
|
||||
" PLEASE FIX \n",
|
||||
i);
|
||||
}
|
||||
if (renameRegisters) {
|
||||
Instruction** definingInstruction = new Instruction*[nameCount];
|
||||
memset(definingInstruction, '\0', nameCount * sizeof(Instruction*));
|
||||
RegisterName* newName = new RegisterName[nameCount];
|
||||
memset(newName, '\0', nameCount * sizeof(RegisterName));
|
||||
RegisterName nextName = RegisterName(1);
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
RegisterName name = usePtr->getRegisterName();
|
||||
if (newName[name] == rnInvalid) {
|
||||
newName[name] = nextName;
|
||||
definingInstruction[nextName] = vrManager.getVirtualRegister(name).getDefiningInstruction();
|
||||
nextName = RegisterName(nextName + 1);
|
||||
}
|
||||
usePtr->setRegisterName(newName[name]);
|
||||
}
|
||||
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister()) {
|
||||
RegisterName name = definePtr->getRegisterName();
|
||||
if (newName[name] == rnInvalid) {
|
||||
newName[name] = nextName;
|
||||
definingInstruction[nextName] = vrManager.getVirtualRegister(name).getDefiningInstruction();
|
||||
nextName = RegisterName(nextName + 1);
|
||||
}
|
||||
definePtr->setRegisterName(newName[name]);
|
||||
}
|
||||
}
|
||||
|
||||
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
|
||||
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
|
||||
Instruction& instruction = phiNodes.get(p);
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
RegisterName name = usePtr->getRegisterName();
|
||||
if (newName[name] == rnInvalid) {
|
||||
newName[name] = nextName;
|
||||
definingInstruction[nextName] = vrManager.getVirtualRegister(name).getDefiningInstruction();
|
||||
nextName = RegisterName(nextName + 1);
|
||||
}
|
||||
usePtr->setRegisterName(newName[name]);
|
||||
}
|
||||
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister()) {
|
||||
RegisterName name = definePtr->getRegisterName();
|
||||
if (newName[name] == rnInvalid) {
|
||||
newName[name] = nextName;
|
||||
definingInstruction[nextName] = vrManager.getVirtualRegister(name).getDefiningInstruction();
|
||||
nextName = RegisterName(nextName + 1);
|
||||
}
|
||||
definePtr->setRegisterName(newName[name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vrManager.setSize(nextName);
|
||||
|
||||
for (RegisterName r = RegisterName(1); r < nextName; r = RegisterName(r + 1))
|
||||
vrManager.getVirtualRegister(r).definingInstruction = definingInstruction[r];
|
||||
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("RegisterMap:\n"));
|
||||
for (Uint32 i = 1; i < nameCount; i++)
|
||||
if (newName[i] != 0)
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tvr%d becomes vr%d.\n", i, newName[i]));
|
||||
else
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tvr%d is dead.\n", i));
|
||||
|
||||
|
||||
delete newName;
|
||||
delete definingInstruction;
|
||||
}
|
||||
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
void RegisterAllocatorTools::removeUnnecessaryCopies(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i);) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
i = instructions.advance(i);
|
||||
|
||||
if (instruction.getFlags() & ifCopy) {
|
||||
assert(instruction.getInstructionUseBegin() != instruction.getInstructionUseEnd() && instruction.getInstructionUseBegin()[0].isRegister());
|
||||
assert(instruction.getInstructionDefineBegin() != instruction.getInstructionDefineEnd() && instruction.getInstructionDefineBegin()[0].isRegister());
|
||||
|
||||
RegisterName source = name2range[instruction.getInstructionUseBegin()[0].getRegisterName()];
|
||||
RegisterName destination = name2range[instruction.getInstructionDefineBegin()[0].getRegisterName()];
|
||||
|
||||
if (source == destination)
|
||||
instruction.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RegisterAllocatorTools::updateInstructionGraph(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister())
|
||||
usePtr->setRegisterName(name2range[usePtr->getRegisterName()]);
|
||||
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
definePtr->setRegisterName(name2range[definePtr->getRegisterName()]);
|
||||
}
|
||||
|
||||
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
|
||||
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
|
||||
Instruction& instruction = phiNodes.get(p);
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister())
|
||||
usePtr->setRegisterName(name2range[usePtr->getRegisterName()]);
|
||||
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
definePtr->setRegisterName(name2range[definePtr->getRegisterName()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RegisterAllocatorTools::insertPhiNodeInstructions(ControlGraph& controlGraph, InstructionEmitter& emitter)
|
||||
{
|
||||
Pool& pool = controlGraph.pool;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
ControlNode& node = *nodes[n];
|
||||
DoublyLinkedList<PhiNode>& phiNodes = node.getPhiNodes();
|
||||
|
||||
if (!phiNodes.empty()) {
|
||||
|
||||
// Set the index of the incoming edges.
|
||||
Uint32 index = 0;
|
||||
const DoublyLinkedList<ControlEdge>& predecessors = node.getPredecessors();
|
||||
for (DoublyLinkedList<ControlEdge>::iterator p = predecessors.begin(); !predecessors.done(p); p = predecessors.advance(p))
|
||||
predecessors.get(p).setIndex(index++);
|
||||
|
||||
// Insert the phi node instruction in the instruction list.
|
||||
for (DoublyLinkedList<PhiNode>::iterator i = phiNodes.begin(); !phiNodes.done(i); i = phiNodes.advance(i)) {
|
||||
PhiNode& phiNode = phiNodes.get(i);
|
||||
ValueKind kind = phiNode.getKind();
|
||||
|
||||
if (!isStorableKind(kind))
|
||||
continue;
|
||||
|
||||
RegisterClassKind classKind = rckGeneral; // FIX: get class kind from phi node kind.
|
||||
Uint32 nInputs = phiNode.nInputs();
|
||||
|
||||
PhiNodeInstruction& phiNodeInstruction = *new(pool) PhiNodeInstruction(&phiNode, pool, nInputs);
|
||||
|
||||
emitter.defineProducer(phiNode, phiNodeInstruction, 0, classKind, drLow);
|
||||
for (Uint32 whichInput = 0; whichInput < nInputs; whichInput++)
|
||||
emitter.useProducer(phiNode.nthInputVariable(whichInput), phiNodeInstruction, whichInput, classKind, drLow);
|
||||
|
||||
node.addPhiNodeInstruction(phiNodeInstruction);
|
||||
|
||||
if (isDoublewordKind(kind)) {
|
||||
PhiNodeInstruction& phiNodeInstruction = *new(pool) PhiNodeInstruction(&phiNode, pool, nInputs);
|
||||
|
||||
emitter.defineProducer(phiNode, phiNodeInstruction, 0, classKind, drHigh);
|
||||
for (Uint32 whichInput = 0; whichInput < nInputs; whichInput++)
|
||||
emitter.useProducer(phiNode.nthInputVariable(whichInput), phiNodeInstruction, whichInput, classKind, drHigh);
|
||||
|
||||
node.addPhiNodeInstruction(phiNodeInstruction);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
|
||||
void RegisterAllocatorTools::printSpillCosts(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
LogModuleObject log = UT_LOG_MODULE(RegAlloc);
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
SpillCost* cost = registerAllocator.spillCost;
|
||||
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Spill costs:\n"));
|
||||
for (Uint32 i = 1; i < rangeCount; i++) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\trange %d : ", i));
|
||||
if (cost[i].infinite)
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("infinite\n"));
|
||||
else
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%f\n", cost[i].cost));
|
||||
}
|
||||
}
|
||||
|
||||
void RegisterAllocatorTools::printSplitCosts(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
LogModuleObject log = UT_LOG_MODULE(RegAlloc);
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
SplitCost* cost = registerAllocator.splitCost;
|
||||
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Split costs:\n"));
|
||||
for (Uint32 i = 1; i < rangeCount; i++) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\trange %d : loads = %f stores = %f\n", i, cost[i].loads, cost[i].stores));
|
||||
}
|
||||
}
|
||||
|
||||
void RegisterAllocatorTools::printInstructions(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
LogModuleObject log = UT_LOG_MODULE(RegAlloc);
|
||||
ControlNode** nodes = registerAllocator.controlGraph.dfsList;
|
||||
Uint32 nNodes = registerAllocator.controlGraph.nNodes;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("N%d:\n", n));
|
||||
|
||||
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
|
||||
if (!phiNodes.empty()) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (" PhiNodes:\n", n));
|
||||
for(InstructionList::iterator i = phiNodes.begin(); !phiNodes.done(i); i = phiNodes.advance(i)) {
|
||||
phiNodes.get(i).printPretty(log);
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
|
||||
}
|
||||
if (!instructions.empty())
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (" Instructions:\n", n));
|
||||
}
|
||||
|
||||
for(InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
|
||||
instructions.get(i).printPretty(log);
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_LOG
|
||||
117
mozilla/ef/Compiler/RegisterAllocator/RegisterAllocatorTools.h
Normal file
117
mozilla/ef/Compiler/RegisterAllocator/RegisterAllocatorTools.h
Normal file
@@ -0,0 +1,117 @@
|
||||
// -*- mode:C++; tab-width:4; truncate-lines:t -*-
|
||||
//
|
||||
// CONFIDENTIAL AND PROPRIETARY SOURCE CODE OF
|
||||
// NETSCAPE COMMUNICATIONS CORPORATION
|
||||
// Copyright © 1996, 1997 Netscape Communications Corporation. All Rights
|
||||
// Reserved. Use of this Source Code is subject to the terms of the
|
||||
// applicable license agreement from Netscape Communications Corporation.
|
||||
// The copyright notice(s) in this Source Code does not indicate actual or
|
||||
// intended publication of this Source Code.
|
||||
//
|
||||
// $Id: RegisterAllocatorTools.h,v 1.1.2.1 1999-03-02 16:12:05 fur%netscape.com Exp $
|
||||
//
|
||||
|
||||
#ifndef _REGISTER_ALLOCATOR_TOOLS_H_
|
||||
#define _REGISTER_ALLOCATOR_TOOLS_H_
|
||||
|
||||
#include "LogModule.h"
|
||||
#include "RegisterTypes.h"
|
||||
#include <string.h>
|
||||
|
||||
class RegisterAllocator;
|
||||
class ControlGraph;
|
||||
class InstructionEmitter;
|
||||
class VirtualRegisterManager;
|
||||
|
||||
struct RegisterAllocatorTools
|
||||
{
|
||||
//
|
||||
//
|
||||
static void insertPhiNodeInstructions(ControlGraph& controlGraph, InstructionEmitter& emitter);
|
||||
|
||||
//
|
||||
//
|
||||
static void updateInstructionGraph(RegisterAllocator& registerAllocator);
|
||||
|
||||
//
|
||||
//
|
||||
static void removeUnnecessaryCopies(RegisterAllocator& registerAllocator);
|
||||
|
||||
#ifdef DEBUG
|
||||
//
|
||||
//
|
||||
static void testTheInstructionGraph(ControlGraph& controlGraph, VirtualRegisterManager& vrManager);
|
||||
#endif // DEBUG
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
//
|
||||
//
|
||||
static void printInstructions(RegisterAllocator& registerAllocator);
|
||||
|
||||
//
|
||||
//
|
||||
static void printSpillCosts(RegisterAllocator& registerAllocator);
|
||||
|
||||
//
|
||||
//
|
||||
static void printSplitCosts(RegisterAllocator& registerAllocator);
|
||||
#endif // DEBUG_LOG
|
||||
};
|
||||
|
||||
//
|
||||
// FIX: this should go in a class (LookupTable ?)
|
||||
//
|
||||
|
||||
inline RegisterName findRoot(RegisterName name, RegisterName* table)
|
||||
{
|
||||
RegisterName* stack = table;
|
||||
RegisterName* stackPtr = stack;
|
||||
|
||||
RegisterName newName;
|
||||
while((newName = table[name]) != name) {
|
||||
*--stackPtr = name;
|
||||
name = newName;
|
||||
}
|
||||
|
||||
while (stackPtr != stack)
|
||||
table[*stackPtr++] = name;
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
inline void init(RegisterName* table, Uint32 nameCount)
|
||||
{
|
||||
for (RegisterName r = RegisterName(0); r < nameCount; r = RegisterName(r + 1))
|
||||
table[r] = r;
|
||||
}
|
||||
|
||||
inline Uint32 compress(RegisterName* name2range, RegisterName* table, Uint32 nameCount, Uint32 tableSize)
|
||||
{
|
||||
RegisterName* liveRange = new RegisterName[tableSize];
|
||||
memset(liveRange, '\0', tableSize * sizeof(RegisterName));
|
||||
|
||||
// Update the lookup table.
|
||||
for (RegisterName r = RegisterName(1); r < tableSize; r = RegisterName(r + 1))
|
||||
findRoot(r, table);
|
||||
|
||||
// Count the liveranges.
|
||||
Uint32 liveRangeCount = 1;
|
||||
for (RegisterName s = RegisterName(1); s < tableSize; s = RegisterName(s + 1))
|
||||
if (table[s] == s)
|
||||
liveRange[s] = RegisterName(liveRangeCount++);
|
||||
|
||||
for (RegisterName t = RegisterName(1); t < nameCount; t = RegisterName(t + 1))
|
||||
name2range[t] = liveRange[table[name2range[t]]];
|
||||
|
||||
return liveRangeCount;
|
||||
}
|
||||
|
||||
inline double doLog10(Uint32 power)
|
||||
{
|
||||
double log = 1.0;
|
||||
while (power--)
|
||||
log *= 10.0;
|
||||
return log;
|
||||
}
|
||||
|
||||
#endif // _REGISTER_ALLOCATOR_TOOLS_H_
|
||||
@@ -1,4 +1,4 @@
|
||||
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
@@ -16,27 +16,23 @@
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsIURI.idl"
|
||||
#ifndef _REGISTER_ASSIGNER_H_
|
||||
#define _REGISTER_ASSIGNER_H_
|
||||
|
||||
/**
|
||||
* JAR URLs have the following syntax
|
||||
*
|
||||
* jar:<jar-file-uri>!/<jar-entry>
|
||||
*
|
||||
* EXAMPLE: jar:http://www.big.com/blue.jar!/ocean.html
|
||||
*/
|
||||
[scriptable, uuid(c7e410d3-85f2-11d3-9f63-006008a6efe9)]
|
||||
interface nsIJARURI : nsIURI {
|
||||
#include "Fundamentals.h"
|
||||
#include "VirtualRegister.h"
|
||||
|
||||
/**
|
||||
* Returns the root URI (the one for the actual JAR file) for this JAR.
|
||||
* eg http://www.big.com/blue.jar
|
||||
*/
|
||||
attribute nsIURI JARFile;
|
||||
class FastBitMatrix;
|
||||
|
||||
/**
|
||||
* Returns the entry specified for this JAR URI.
|
||||
* eg ocean.html
|
||||
*/
|
||||
attribute string JAREntry;
|
||||
class RegisterAssigner
|
||||
{
|
||||
protected:
|
||||
VirtualRegisterManager& vRegManager;
|
||||
|
||||
public:
|
||||
RegisterAssigner(VirtualRegisterManager& vrMan) : vRegManager(vrMan) {}
|
||||
|
||||
virtual bool assignRegisters(FastBitMatrix& interferenceMatrix) = 0;
|
||||
};
|
||||
|
||||
#endif /* _REGISTER_ASSIGNER_H_ */
|
||||
25
mozilla/ef/Compiler/RegisterAllocator/RegisterClass.h
Normal file
25
mozilla/ef/Compiler/RegisterAllocator/RegisterClass.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _REGISTER_CLASS_H_
|
||||
#define _REGISTER_CLASS_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "RegisterTypes.h"
|
||||
|
||||
#endif // _REGISTER_CLASS_H_
|
||||
@@ -1,4 +1,4 @@
|
||||
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
@@ -16,27 +16,22 @@
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsIURI.idl"
|
||||
#ifndef _REGISTER_PRESSURE_H_
|
||||
#define _REGISTER_PRESSURE_H_
|
||||
|
||||
/**
|
||||
* JAR URLs have the following syntax
|
||||
*
|
||||
* jar:<jar-file-uri>!/<jar-entry>
|
||||
*
|
||||
* EXAMPLE: jar:http://www.big.com/blue.jar!/ocean.html
|
||||
*/
|
||||
[scriptable, uuid(c7e410d3-85f2-11d3-9f63-006008a6efe9)]
|
||||
interface nsIJARURI : nsIURI {
|
||||
#include "BitSet.h"
|
||||
#include "HashSet.h"
|
||||
|
||||
/**
|
||||
* Returns the root URI (the one for the actual JAR file) for this JAR.
|
||||
* eg http://www.big.com/blue.jar
|
||||
*/
|
||||
attribute nsIURI JARFile;
|
||||
|
||||
/**
|
||||
* Returns the entry specified for this JAR URI.
|
||||
* eg ocean.html
|
||||
*/
|
||||
attribute string JAREntry;
|
||||
struct LowRegisterPressure
|
||||
{
|
||||
typedef BitSet Set;
|
||||
static const bool setIsOrdered = true;
|
||||
};
|
||||
|
||||
struct HighRegisterPressure
|
||||
{
|
||||
typedef HashSet Set;
|
||||
static const bool setIsOrdered = false;
|
||||
};
|
||||
|
||||
#endif // _REGISTER_PRESSURE_H_
|
||||
104
mozilla/ef/Compiler/RegisterAllocator/RegisterTypes.h
Normal file
104
mozilla/ef/Compiler/RegisterAllocator/RegisterTypes.h
Normal file
@@ -0,0 +1,104 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _REGISTER_TYPES_H_
|
||||
#define _REGISTER_TYPES_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// RegisterName -
|
||||
//
|
||||
|
||||
enum RegisterName {
|
||||
rnInvalid = 0,
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// RegisterClassKind -
|
||||
//
|
||||
|
||||
enum RegisterClassKind {
|
||||
rckInvalid = 0,
|
||||
rckGeneral,
|
||||
rckStackSlot,
|
||||
|
||||
nRegisterClassKind
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// RegisterID -
|
||||
//
|
||||
|
||||
enum RegisterID {
|
||||
invalidID = 0
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// RegisterKind -
|
||||
//
|
||||
|
||||
enum RegisterKind {
|
||||
rkCallerSave = 0,
|
||||
rkCalleeSave,
|
||||
};
|
||||
|
||||
struct NameLinkedList {
|
||||
RegisterName name;
|
||||
NameLinkedList* next;
|
||||
};
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
const registerNameMask = 0x03ffffff;
|
||||
const coloredRegisterMask = 0x04000000;
|
||||
const machineRegisterMask = 0x08000000;
|
||||
const registerClassMask = 0xf0000000;
|
||||
|
||||
const registerNameShift = 0;
|
||||
const coloredRegisterShift = 26;
|
||||
const machineRegisterShift = 27;
|
||||
const registerClassShift = 28;
|
||||
|
||||
#else // DEBUG
|
||||
|
||||
const registerNameMask = 0x0fffffff;
|
||||
const registerClassMask = 0xf0000000;
|
||||
|
||||
const registerNameShift = 0;
|
||||
const registerClassShift = 28;
|
||||
|
||||
#endif // DEBUG
|
||||
|
||||
|
||||
inline RegisterClassKind getClass(RegisterID registerID) {return RegisterClassKind((registerID & registerClassMask) >> registerClassShift);}
|
||||
inline RegisterName getName(RegisterID registerID) {return RegisterName((registerID & registerNameMask) >> registerNameShift);}
|
||||
inline void setClass(RegisterID& registerID, RegisterClassKind classKind) {registerID = RegisterID((registerID & ~registerClassMask) | ((classKind << registerClassShift) & registerClassMask));}
|
||||
inline void setName(RegisterID& registerID, RegisterName name) {assert((name & ~registerNameMask) == 0); registerID = RegisterID((registerID & ~registerNameMask) | ((name << registerNameShift) & registerNameMask));}
|
||||
inline RegisterID buildRegisterID(RegisterName name, RegisterClassKind classKind) {return RegisterID(((classKind << registerClassShift) & registerClassMask) | ((name << registerNameShift) & registerNameMask));}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
inline bool isMachineRegister(RegisterID rid) {return (rid & machineRegisterMask) != 0;}
|
||||
inline void setMachineRegister(RegisterID& rid) {rid = RegisterID(rid | machineRegisterMask);}
|
||||
inline bool isColoredRegister(RegisterID rid) {return (rid & coloredRegisterMask) != 0;}
|
||||
inline void setColoredRegister(RegisterID& rid) {rid = RegisterID(rid | coloredRegisterMask);}
|
||||
|
||||
#endif // DEBUG
|
||||
|
||||
#endif // _REGISTER_TYPES_H_
|
||||
32
mozilla/ef/Compiler/RegisterAllocator/SSATools.cpp
Normal file
32
mozilla/ef/Compiler/RegisterAllocator/SSATools.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "SSATools.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "VirtualRegister.h"
|
||||
#include "Liveness.h"
|
||||
|
||||
void replacePhiNodes(ControlGraph& controlGraph, VirtualRegisterManager& vrManager)
|
||||
{
|
||||
if (!controlGraph.hasBackEdges)
|
||||
return;
|
||||
|
||||
Liveness liveness(controlGraph.pool);
|
||||
liveness.buildLivenessAnalysis(controlGraph, vrManager);
|
||||
}
|
||||
29
mozilla/ef/Compiler/RegisterAllocator/SSATools.h
Normal file
29
mozilla/ef/Compiler/RegisterAllocator/SSATools.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SSA_TOOLS_H_
|
||||
#define _SSA_TOOLS_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
|
||||
class ControlGraph;
|
||||
class VirtualRegisterManager;
|
||||
|
||||
extern void replacePhiNodes(ControlGraph& controlGraph, VirtualRegisterManager& vrManager);
|
||||
|
||||
#endif // _SSA_TOOLS_H_
|
||||
37
mozilla/ef/Compiler/RegisterAllocator/SparseSet.cpp
Normal file
37
mozilla/ef/Compiler/RegisterAllocator/SparseSet.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "SparseSet.h"
|
||||
#include "BitSet.h"
|
||||
#include "Pool.h"
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
// Print the set.
|
||||
//
|
||||
void SparseSet::printPretty(LogModuleObject log)
|
||||
{
|
||||
Pool pool;
|
||||
BitSet set(pool, universeSize);
|
||||
|
||||
for (Uint32 i = 0; i < count; i++)
|
||||
set.set(node[i].element);
|
||||
|
||||
set.printPretty(log);
|
||||
}
|
||||
#endif // DEBUG_LOG
|
||||
168
mozilla/ef/Compiler/RegisterAllocator/SparseSet.h
Normal file
168
mozilla/ef/Compiler/RegisterAllocator/SparseSet.h
Normal file
@@ -0,0 +1,168 @@
|
||||
// -*- mode:C++; tab-width:4; truncate-lines:t -*-
|
||||
//
|
||||
// CONFIDENTIAL AND PROPRIETARY SOURCE CODE OF
|
||||
// NETSCAPE COMMUNICATIONS CORPORATION
|
||||
// Copyright © 1996, 1997 Netscape Communications Corporation. All Rights
|
||||
// Reserved. Use of this Source Code is subject to the terms of the
|
||||
// applicable license agreement from Netscape Communications Corporation.
|
||||
// The copyright notice(s) in this Source Code does not indicate actual or
|
||||
// intended publication of this Source Code.
|
||||
//
|
||||
// $Id: SparseSet.h,v 1.1.2.1 1999-03-02 16:12:07 fur%netscape.com Exp $
|
||||
//
|
||||
|
||||
#ifndef _SPARSE_SET_H_
|
||||
#define _SPARSE_SET_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "Pool.h"
|
||||
#include "LogModule.h"
|
||||
#include "BitSet.h"
|
||||
|
||||
class SparseSet
|
||||
{
|
||||
private:
|
||||
|
||||
struct Node {
|
||||
Uint32 element;
|
||||
Uint32 stackIndex;
|
||||
};
|
||||
|
||||
Node* node;
|
||||
Uint32 count;
|
||||
Uint32 universeSize;
|
||||
|
||||
private:
|
||||
|
||||
// No copy constructor.
|
||||
SparseSet(const SparseSet&);
|
||||
|
||||
// Check if the given set's universe is of the same size than this universe.
|
||||
void checkUniverseCompatibility(const SparseSet& set) const {assert(set.universeSize == universeSize);}
|
||||
// Check if pos is valid for this set's universe.
|
||||
void checkMember(Int32 pos) const {assert(pos >=0 && Uint32(pos) < universeSize);}
|
||||
|
||||
public:
|
||||
|
||||
SparseSet(Pool& pool, Uint32 universeSize) : universeSize(universeSize) {node = new(pool) Node[universeSize]; clear();}
|
||||
|
||||
// Clear the sparse set.
|
||||
void clear() {count = 0;}
|
||||
// Clear the element at index.
|
||||
inline void clear(Uint32 index);
|
||||
// Set the element at index.
|
||||
inline void set(Uint32 index);
|
||||
// Return true if the element at index is set.
|
||||
inline bool test(Uint32 index) const;
|
||||
// Union with the given sparse set.
|
||||
inline void or(const SparseSet& set);
|
||||
// Intersection with the given sparse set.
|
||||
inline void and(const SparseSet& set);
|
||||
// Difference with the given sparse set.
|
||||
inline void difference(const SparseSet& set);
|
||||
// Copy set.
|
||||
inline SparseSet& operator = (const SparseSet& set);
|
||||
inline SparseSet& operator = (const BitSet& set);
|
||||
// Return true if the sparse sets are identical.
|
||||
friend bool operator == (const SparseSet& set1, const SparseSet& set2);
|
||||
// Return true if the sparse sets are different.
|
||||
friend bool operator != (const SparseSet& set1, const SparseSet& set2);
|
||||
|
||||
// Logical operators.
|
||||
SparseSet& operator |= (const SparseSet& set) {or(set); return *this;}
|
||||
SparseSet& operator &= (const SparseSet& set) {and(set); return *this;}
|
||||
SparseSet& operator -= (const SparseSet& set) {difference(set); return *this;}
|
||||
|
||||
// Iterator to conform with the set API.
|
||||
typedef Int32 iterator;
|
||||
// Return the iterator for the first element of this set.
|
||||
iterator begin() const {return count - 1;}
|
||||
// Return the next iterator.
|
||||
iterator advance(iterator pos) const {return --pos;}
|
||||
// Return true if the iterator is at the end of the set.
|
||||
bool done(iterator pos) const {return pos < 0;}
|
||||
// Return the element for the given iterator;
|
||||
Uint32 get(iterator pos) const {return node[pos].element;}
|
||||
// Return one element of this set.
|
||||
Uint32 getOne() const {assert(count > 0); return node[0].element;}
|
||||
// Return the size of this set.
|
||||
Uint32 getSize() const {return count;}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
// Print the set.
|
||||
void printPretty(LogModuleObject log);
|
||||
#endif // DEBUG_LOG
|
||||
};
|
||||
|
||||
inline void SparseSet::clear(Uint32 element)
|
||||
{
|
||||
checkMember(element);
|
||||
Uint32 count = this->count;
|
||||
Node* node = this->node;
|
||||
|
||||
Uint32 stackIndex = node[element].stackIndex;
|
||||
|
||||
if ((stackIndex < count) && (node[stackIndex].element == element)) {
|
||||
Uint32 stackTop = node[count - 1].element;
|
||||
|
||||
node[stackIndex].element = stackTop;
|
||||
node[stackTop].stackIndex = stackIndex;
|
||||
this->count = count - 1;
|
||||
}
|
||||
}
|
||||
|
||||
inline void SparseSet::set(Uint32 element)
|
||||
{
|
||||
checkMember(element);
|
||||
Uint32 count = this->count;
|
||||
Node* node = this->node;
|
||||
|
||||
Uint32 stackIndex = node[element].stackIndex;
|
||||
|
||||
if ((stackIndex >= count) || (node[stackIndex].element != element)) {
|
||||
node[count].element = element;
|
||||
node[element].stackIndex = count;
|
||||
this->count = count + 1;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool SparseSet::test(Uint32 element) const
|
||||
{
|
||||
checkMember(element);
|
||||
Node* node = this->node;
|
||||
|
||||
Uint32 stackIndex = node[element].stackIndex;
|
||||
return ((stackIndex < count) && (node[stackIndex].element == element));
|
||||
}
|
||||
|
||||
inline SparseSet& SparseSet::operator = (const SparseSet& set)
|
||||
{
|
||||
checkUniverseCompatibility(set);
|
||||
Uint32 sourceCount = set.getSize();
|
||||
Node* node = this->node;
|
||||
|
||||
memcpy(node, set.node, sourceCount * sizeof(Node));
|
||||
|
||||
for (Uint32 i = 0; i < sourceCount; i++) {
|
||||
Uint32 element = node[i].element;
|
||||
node[element].stackIndex = i;
|
||||
}
|
||||
|
||||
count = sourceCount;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
inline SparseSet& SparseSet::operator = (const BitSet& set)
|
||||
{
|
||||
// FIX: there's room for optimization here.
|
||||
assert(universeSize == set.getSize());
|
||||
|
||||
clear();
|
||||
for (Int32 i = set.firstOne(); i != -1; i = set.nextOne(i))
|
||||
this->set(i);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif // _SPARSE_SET_H_
|
||||
270
mozilla/ef/Compiler/RegisterAllocator/Spilling.cpp
Normal file
270
mozilla/ef/Compiler/RegisterAllocator/Spilling.cpp
Normal file
@@ -0,0 +1,270 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef NEW_LAURENTM_CODE
|
||||
#define INCLUDE_EMITTER
|
||||
#include "CpuInfo.h"
|
||||
#include "Fundamentals.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Instruction.h"
|
||||
#include "InstructionEmitter.h"
|
||||
#include "Spilling.h"
|
||||
|
||||
|
||||
void Spilling::
|
||||
insertSpillCode(ControlNode** dfsList, Uint32 nNodes)
|
||||
{
|
||||
PRUint32 nVirtualRegisters = vRegManager.count();
|
||||
FastBitSet currentLive(vRegManager.pool, nVirtualRegisters);
|
||||
FastBitSet usedInThisInstruction(vRegManager.pool, nVirtualRegisters);
|
||||
RegisterFifo grNeedLoad(nVirtualRegisters);
|
||||
RegisterFifo fpNeedLoad(nVirtualRegisters);
|
||||
|
||||
for (PRInt32 n = nNodes - 1; n >= 0; n--)
|
||||
{
|
||||
PR_ASSERT(grNeedLoad.empty() & fpNeedLoad.empty());
|
||||
ControlNode& node = *dfsList[n];
|
||||
|
||||
currentLive = node.liveAtEnd;
|
||||
|
||||
PRUint32 nGeneralAlive = 0;
|
||||
PRUint32 nFloatingPointAlive = 0;
|
||||
|
||||
// Get the number of registers alive at the end of this node.
|
||||
for (PRInt32 j = currentLive.firstOne(); j != -1; j = currentLive.nextOne(j))
|
||||
{
|
||||
VirtualRegister& vReg = vRegManager.getVirtualRegister(j);
|
||||
if (vReg.spillInfo.willSpill)
|
||||
{
|
||||
currentLive.clear(j);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (vReg.getClass())
|
||||
{
|
||||
case vrcInteger:
|
||||
nGeneralAlive++;
|
||||
break;
|
||||
case vrcFloatingPoint:
|
||||
case vrcFixedPoint:
|
||||
nFloatingPointAlive++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if(node.dfsNum == 8) printf("\n________Begin Node %d________\n", node.dfsNum);
|
||||
|
||||
InstructionList& instructions = node.getInstructions();
|
||||
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i))
|
||||
{
|
||||
Instruction& instruction = instructions.get(i);
|
||||
InstructionUse* useBegin = instruction.getInstructionUseBegin();
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
InstructionUse* usePtr;
|
||||
InstructionDefine* defBegin = instruction.getInstructionDefineBegin();
|
||||
InstructionDefine* defEnd = instruction.getInstructionDefineEnd();
|
||||
InstructionDefine* defPtr;
|
||||
|
||||
// if(node.dfsNum == 8) { printf("\n");
|
||||
// instruction.printPretty(stdout);
|
||||
// printf("\n"); }
|
||||
|
||||
// Handle definitions
|
||||
for (defPtr = defBegin; defPtr < defEnd; defPtr++)
|
||||
if (defPtr->isVirtualRegister())
|
||||
{
|
||||
VirtualRegister& vReg = defPtr->getVirtualRegister();
|
||||
currentLive.clear(vReg.getRegisterIndex());
|
||||
switch (vReg.getClass())
|
||||
{
|
||||
case vrcInteger:
|
||||
nGeneralAlive--;
|
||||
break;
|
||||
case vrcFloatingPoint:
|
||||
case vrcFixedPoint:
|
||||
nFloatingPointAlive--;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for deaths
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isVirtualRegister())
|
||||
{
|
||||
VirtualRegister& vReg = usePtr->getVirtualRegister();
|
||||
if (!currentLive.test(vReg.getRegisterIndex()))
|
||||
// This is the last use of this register.
|
||||
{
|
||||
currentLive.set(vReg.getRegisterIndex());
|
||||
switch (vReg.getClass())
|
||||
{
|
||||
case vrcInteger:
|
||||
nGeneralAlive++;
|
||||
while (/*(nGeneralAlive > NUMBER_OF_GREGISTERS) &&*/ !grNeedLoad.empty())
|
||||
{
|
||||
PRUint32 toLoad = grNeedLoad.get();
|
||||
currentLive.clear(toLoad);
|
||||
nGeneralAlive--;
|
||||
|
||||
VirtualRegister& nReg = vRegManager.getVirtualRegister(toLoad);
|
||||
Instruction& lastUsingInstruction = *nReg.spillInfo.lastUsingInstruction;
|
||||
emitter.emitLoadAfter(*lastUsingInstruction.getPrimitive(), lastUsingInstruction.getLinks().prev,
|
||||
nReg.getAlias(), *nReg.equivalentRegister[vrcStackSlot]);
|
||||
nReg.releaseSelf();
|
||||
}
|
||||
break;
|
||||
case vrcFloatingPoint:
|
||||
case vrcFixedPoint:
|
||||
nFloatingPointAlive++;
|
||||
while (/*(nFloatingPointAlive > NUMBER_OF_FPREGISTERS) &&*/ !fpNeedLoad.empty())
|
||||
{
|
||||
PRUint32 toLoad = fpNeedLoad.get();
|
||||
currentLive.clear(toLoad);
|
||||
nFloatingPointAlive--;
|
||||
|
||||
VirtualRegister& nReg = vRegManager.getVirtualRegister(toLoad);
|
||||
Instruction& lastUsingInstruction = *nReg.spillInfo.lastUsingInstruction;
|
||||
emitter.emitLoadAfter(*lastUsingInstruction.getPrimitive(), lastUsingInstruction.getLinks().prev,
|
||||
nReg.getAlias(), *nReg.equivalentRegister[vrcStackSlot]);
|
||||
nReg.releaseSelf();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle uses
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isVirtualRegister())
|
||||
{
|
||||
VirtualRegister& vReg = usePtr->getVirtualRegister();
|
||||
PRUint32 registerIndex = vReg.getRegisterIndex();
|
||||
|
||||
if (vReg.spillInfo.willSpill) {
|
||||
#if defined(GENERATE_FOR_X86)
|
||||
if (!instruction.switchUseToSpill((usePtr - useBegin), *vReg.equivalentRegister[vrcStackSlot]))
|
||||
#endif
|
||||
{
|
||||
switch (vReg.getClass())
|
||||
{
|
||||
case vrcInteger:
|
||||
if (!grNeedLoad.test(registerIndex))
|
||||
{
|
||||
grNeedLoad.put(registerIndex);
|
||||
VirtualRegister& alias = vRegManager.newVirtualRegister(vrcInteger);
|
||||
if (vReg.isPreColored())
|
||||
alias.preColorRegister(vReg.getPreColor());
|
||||
/* if (vReg.hasSpecialInterference) {
|
||||
alias.specialInterference.sizeTo(NUMBER_OF_REGISTERS);
|
||||
alias.specialInterference = vReg.specialInterference;
|
||||
alias.hasSpecialInterference = true;
|
||||
} */
|
||||
vReg.setAlias(alias);
|
||||
vReg.retainSelf();
|
||||
}
|
||||
break;
|
||||
case vrcFloatingPoint:
|
||||
case vrcFixedPoint:
|
||||
if (!fpNeedLoad.test(registerIndex))
|
||||
{
|
||||
fpNeedLoad.put(registerIndex);
|
||||
VirtualRegister& alias = vRegManager.newVirtualRegister(vReg.getClass());
|
||||
if (vReg.isPreColored())
|
||||
alias.preColorRegister(vReg.getPreColor());
|
||||
/*if (vReg.hasSpecialInterference) {
|
||||
alias.specialInterference.sizeTo(NUMBER_OF_REGISTERS);
|
||||
alias.specialInterference = vReg.specialInterference;
|
||||
alias.hasSpecialInterference = true;
|
||||
} */
|
||||
vReg.setAlias(alias);
|
||||
vReg.retainSelf();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
usePtr->getVirtualRegisterPtr().initialize(vReg.getAlias());
|
||||
usedInThisInstruction.set(registerIndex);
|
||||
vReg.spillInfo.lastUsingInstruction = &instruction;
|
||||
}
|
||||
currentLive.clear(registerIndex);
|
||||
} else { // will not spill
|
||||
currentLive.set(registerIndex);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle definitions
|
||||
for (defPtr = defBegin; defPtr < defEnd; defPtr++)
|
||||
if (defPtr->isVirtualRegister())
|
||||
{
|
||||
VirtualRegister& vReg = defPtr->getVirtualRegister();
|
||||
|
||||
if (vReg.spillInfo.willSpill)
|
||||
#if defined(GENERATE_FOR_X86)
|
||||
if (!instruction.switchDefineToSpill((defPtr - defBegin), *vReg.equivalentRegister[vrcStackSlot]))
|
||||
#endif
|
||||
{
|
||||
if (usedInThisInstruction.test(vReg.getRegisterIndex()))
|
||||
// this virtualRegister was used in this instruction and is also defined. We need to move
|
||||
// this virtual register to its alias first and then save it to memory.
|
||||
{
|
||||
emitter.emitStoreAfter(*instruction.getPrimitive(), &instruction.getLinks(),
|
||||
vReg.getAlias(), *vReg.equivalentRegister[vrcStackSlot]);
|
||||
defPtr->getVirtualRegisterPtr().initialize(vReg.getAlias());
|
||||
}
|
||||
else
|
||||
{
|
||||
emitter.emitStoreAfter(*instruction.getPrimitive(), &instruction.getLinks(),
|
||||
vReg, *vReg.equivalentRegister[vrcStackSlot]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while (!grNeedLoad.empty())
|
||||
{
|
||||
PRUint32 nl = grNeedLoad.get();
|
||||
VirtualRegister& nlReg = vRegManager.getVirtualRegister(nl);
|
||||
Instruction& lastUse = *nlReg.spillInfo.lastUsingInstruction;
|
||||
|
||||
emitter.emitLoadAfter(*lastUse.getPrimitive(), lastUse.getLinks().prev,
|
||||
nlReg.getAlias(), *nlReg.equivalentRegister[vrcStackSlot]);
|
||||
nlReg.releaseSelf();
|
||||
}
|
||||
while (!fpNeedLoad.empty())
|
||||
{
|
||||
PRUint32 nl = fpNeedLoad.get();
|
||||
VirtualRegister& nlReg = vRegManager.getVirtualRegister(nl);
|
||||
Instruction& lastUse = *nlReg.spillInfo.lastUsingInstruction;
|
||||
|
||||
emitter.emitLoadAfter(*lastUse.getPrimitive(), lastUse.getLinks().prev,
|
||||
nlReg.getAlias(), *nlReg.equivalentRegister[vrcStackSlot]);
|
||||
nlReg.releaseSelf();
|
||||
}
|
||||
|
||||
// if(node.dfsNum == 8) printf("\n________End Node %d________\n", node.dfsNum);
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
269
mozilla/ef/Compiler/RegisterAllocator/Spilling.h
Normal file
269
mozilla/ef/Compiler/RegisterAllocator/Spilling.h
Normal file
@@ -0,0 +1,269 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SPILLING_H_
|
||||
#define _SPILLING_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include <string.h>
|
||||
#include "RegisterAllocator.h"
|
||||
#include "RegisterAllocatorTools.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Instruction.h"
|
||||
#include "SparseSet.h"
|
||||
|
||||
template <class RegisterPressure>
|
||||
class Spilling
|
||||
{
|
||||
private:
|
||||
static void insertStoreAfter(Instruction& instruction, RegisterName name);
|
||||
static void insertLoadBefore(Instruction& instruction, RegisterName name);
|
||||
|
||||
public:
|
||||
static void calculateSpillCosts(RegisterAllocator& registerAllocator);
|
||||
static void insertSpillCode(RegisterAllocator& registerAllocator);
|
||||
};
|
||||
|
||||
struct SpillCost
|
||||
{
|
||||
double loads;
|
||||
double stores;
|
||||
double copies;
|
||||
double cost;
|
||||
bool infinite;
|
||||
};
|
||||
|
||||
template <class RegisterPressure>
|
||||
void Spilling<RegisterPressure>::insertSpillCode(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
|
||||
Pool& pool = registerAllocator.pool;
|
||||
SparseSet currentLive(pool, rangeCount);
|
||||
SparseSet needLoad(pool, rangeCount);
|
||||
SparseSet mustSpill(pool, rangeCount);
|
||||
SparseSet& willSpill = *registerAllocator.willSpill;
|
||||
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
RegisterPressure::Set* liveOut = registerAllocator.liveness.liveOut;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
|
||||
needLoad.clear();
|
||||
currentLive = liveOut[n];
|
||||
mustSpill = currentLive;
|
||||
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
for (InstructionList::iterator i = instructions.end(); !instructions.done(i);) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
i = instructions.retreat(i);
|
||||
|
||||
InstructionUse* useBegin = instruction.getInstructionUseBegin();
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
InstructionUse* usePtr;
|
||||
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
InstructionDefine* definePtr;
|
||||
|
||||
bool foundLiveDefine = false;
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister()) {
|
||||
if (currentLive.test(name2range[definePtr->getRegisterName()])) {
|
||||
foundLiveDefine = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
foundLiveDefine = true;
|
||||
break;
|
||||
}
|
||||
if (defineBegin != defineEnd && !foundLiveDefine) {
|
||||
fprintf(stderr, "!!! Removed instruction because it was only defining unused registers !!!\n");
|
||||
instruction.remove();
|
||||
}
|
||||
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister()) {
|
||||
RegisterName range = name2range[definePtr->getRegisterName()];
|
||||
#ifdef DEBUG
|
||||
if (needLoad.test(range))
|
||||
if (!mustSpill.test(range) && registerAllocator.spillCost[range].infinite && willSpill.test(range)) {
|
||||
fprintf(stderr, "Tried to spill a register with infinite spill cost\n");
|
||||
abort();
|
||||
}
|
||||
#endif // DEBUG
|
||||
if (willSpill.test(range))
|
||||
insertStoreAfter(instruction, range);
|
||||
|
||||
needLoad.clear(range);
|
||||
}
|
||||
|
||||
if (instruction.getFlags() & ifCopy)
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
RegisterName range = name2range[usePtr->getRegisterName()];
|
||||
if (!currentLive.test(range))
|
||||
for (SparseSet::iterator r = needLoad.begin(); !needLoad.done(r); r = needLoad.advance(r)) {
|
||||
RegisterName load = RegisterName(needLoad.get(r));
|
||||
if (willSpill.test(load))
|
||||
insertLoadBefore(instruction, load);
|
||||
mustSpill.set(load);
|
||||
}
|
||||
needLoad.clear();
|
||||
}
|
||||
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
currentLive.clear(name2range[definePtr->getRegisterName()]);
|
||||
|
||||
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
RegisterName range = name2range[usePtr->getRegisterName()];
|
||||
currentLive.set(range);
|
||||
needLoad.set(range);
|
||||
}
|
||||
}
|
||||
|
||||
for (SparseSet::iterator l = needLoad.begin(); !needLoad.done(l); l = needLoad.advance(l)) {
|
||||
RegisterName load = RegisterName(needLoad.get(l));
|
||||
if (willSpill.test(load))
|
||||
insertLoadBefore(instructions.first(), load);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
void Spilling<RegisterPressure>::insertLoadBefore(Instruction& /*instruction*/, RegisterName name)
|
||||
{
|
||||
fprintf(stdout, "will insert load for range %d\n", name);
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
void Spilling<RegisterPressure>::insertStoreAfter(Instruction& /*instruction*/, RegisterName name)
|
||||
{
|
||||
fprintf(stdout, "will insert store for range %d\n", name);
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
void Spilling<RegisterPressure>::calculateSpillCosts(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
|
||||
Pool& pool = registerAllocator.pool;
|
||||
SparseSet live(pool, rangeCount);
|
||||
SparseSet needLoad(pool, rangeCount);
|
||||
SparseSet mustSpill(pool, rangeCount);
|
||||
|
||||
SparseSet alreadyStored(pool, rangeCount); // FIX: should get this from previous spilling.
|
||||
|
||||
SpillCost* cost = new SpillCost[rangeCount];
|
||||
memset(cost, '\0', rangeCount * sizeof(SpillCost));
|
||||
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
RegisterPressure::Set* liveOut = registerAllocator.liveness.liveOut;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
ControlNode& node = *nodes[n];
|
||||
|
||||
double weight = doLog10(node.loopDepth);
|
||||
|
||||
needLoad.clear();
|
||||
live = liveOut[n];
|
||||
mustSpill = live;
|
||||
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useBegin = instruction.getInstructionUseBegin();
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
InstructionUse* usePtr;
|
||||
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
InstructionDefine* definePtr;
|
||||
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister()) {
|
||||
RegisterName range = name2range[definePtr->getRegisterName()];
|
||||
|
||||
if (needLoad.test(range))
|
||||
if (!mustSpill.test(range))
|
||||
cost[range].infinite = true;
|
||||
|
||||
if ((false /* !rematerializable(range) */ || !needLoad.test(range)) && !alreadyStored.test(range))
|
||||
cost[range].stores += weight;
|
||||
|
||||
needLoad.clear(range);
|
||||
}
|
||||
|
||||
if (instruction.getFlags() & ifCopy)
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister())
|
||||
if (!live.test(name2range[usePtr->getRegisterName()])) {
|
||||
for (SparseSet::iterator l = needLoad.begin(); !needLoad.done(l); l = needLoad.advance(l)) {
|
||||
Uint32 range = needLoad.get(l);
|
||||
cost[range].loads += weight;
|
||||
mustSpill.set(range);
|
||||
}
|
||||
needLoad.clear();
|
||||
}
|
||||
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
live.clear(name2range[definePtr->getRegisterName()]);
|
||||
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
RegisterName range = name2range[usePtr->getRegisterName()];
|
||||
|
||||
live.set(range);
|
||||
needLoad.set(range);
|
||||
}
|
||||
|
||||
if (instruction.getFlags() & ifCopy) {
|
||||
assert(useBegin != useEnd && useBegin[0].isRegister());
|
||||
assert(defineBegin != defineEnd && defineBegin[0].isRegister());
|
||||
|
||||
RegisterName source = name2range[useBegin[0].getRegisterName()];
|
||||
RegisterName destination = name2range[defineBegin[0].getRegisterName()];
|
||||
|
||||
cost[source].copies += weight;
|
||||
cost[destination].copies += weight;
|
||||
}
|
||||
}
|
||||
|
||||
for (SparseSet::iterator s = needLoad.begin(); !needLoad.done(s); s = needLoad.advance(s))
|
||||
cost[needLoad.get(s)].loads += weight;
|
||||
}
|
||||
|
||||
for (Uint32 r = 0; r < rangeCount; r++) {
|
||||
SpillCost& c = cost[r];
|
||||
c.cost = 2 * (c.loads + c.stores) - c.copies;
|
||||
}
|
||||
|
||||
registerAllocator.spillCost = cost;
|
||||
}
|
||||
|
||||
#endif // _SPILLING_H_
|
||||
239
mozilla/ef/Compiler/RegisterAllocator/Splits.h
Normal file
239
mozilla/ef/Compiler/RegisterAllocator/Splits.h
Normal file
@@ -0,0 +1,239 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SPLITS_H_
|
||||
#define _SPLITS_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include <string.h>
|
||||
#include "Pool.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Instruction.h"
|
||||
#include "RegisterAllocator.h"
|
||||
#include "RegisterAllocatorTools.h"
|
||||
|
||||
UT_EXTERN_LOG_MODULE(RegAlloc);
|
||||
|
||||
template <class RegisterPressure>
|
||||
struct Splits
|
||||
{
|
||||
static void calculateSplitCosts(RegisterAllocator& registerAllocator);
|
||||
static bool findSplit(RegisterAllocator& registerAllocator, RegisterName* color, RegisterName range);
|
||||
static void insertSplitCode(RegisterAllocator& registerAllocator);
|
||||
};
|
||||
|
||||
struct SplitCost
|
||||
{
|
||||
double loads;
|
||||
double stores;
|
||||
};
|
||||
|
||||
template <class RegisterPressure>
|
||||
void Splits<RegisterPressure>::insertSplitCode(RegisterAllocator& /*registerAllocator*/)
|
||||
{
|
||||
// FIX
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
bool Splits<RegisterPressure>::findSplit(RegisterAllocator& registerAllocator, RegisterName* color, RegisterName range)
|
||||
{
|
||||
Pool& pool = registerAllocator.pool;
|
||||
NameLinkedList** neighborsWithColor = new(pool) NameLinkedList*[6]; // FIX
|
||||
memset(neighborsWithColor, '\0', 6 * sizeof(NameLinkedList*));
|
||||
|
||||
InterferenceGraph<RegisterPressure>& iGraph = registerAllocator.iGraph;
|
||||
|
||||
for (InterferenceVector* vector = iGraph.getInterferenceVector(range); vector != NULL; vector = vector->next)
|
||||
for (Int32 i = vector->count - 1; i >=0; --i) {
|
||||
RegisterName neighbor = vector->neighbors[i];
|
||||
RegisterName c = color[neighbor];
|
||||
|
||||
if (c < 6) { // FIX
|
||||
NameLinkedList* node = new(pool) NameLinkedList();
|
||||
node->name = neighbor;
|
||||
node->next = neighborsWithColor[c];
|
||||
neighborsWithColor[c] = node;
|
||||
}
|
||||
}
|
||||
|
||||
bool splitAroundName = true;
|
||||
|
||||
LiveRangeGraph<RegisterPressure>& lGraph = registerAllocator.lGraph;
|
||||
RegisterName bestColor = RegisterName(6); // FIX
|
||||
double bestCost = registerAllocator.spillCost[range].cost;
|
||||
SplitCost* splitCost = registerAllocator.splitCost;
|
||||
|
||||
for (RegisterName i = RegisterName(0); i < 6; i = RegisterName(i + 1)) { // FIX
|
||||
|
||||
double splitAroundNameCost = 0.0;
|
||||
bool canSplitAroundName = true;
|
||||
|
||||
SplitCost& sCost = splitCost[range];
|
||||
double addedCost = 2.0 * (sCost.stores + sCost.loads);
|
||||
|
||||
for (NameLinkedList* node = neighborsWithColor[i]; node != NULL; node = node->next) {
|
||||
RegisterName neighbor = node->name;
|
||||
if (lGraph.haveEdge(neighbor, range)) {
|
||||
canSplitAroundName = false;
|
||||
break;
|
||||
} else
|
||||
splitAroundNameCost += addedCost;
|
||||
}
|
||||
if (canSplitAroundName && splitAroundNameCost < bestCost) {
|
||||
bestCost = splitAroundNameCost;
|
||||
bestColor = i;
|
||||
splitAroundName = true;
|
||||
}
|
||||
|
||||
double splitAroundColorCost = 0.0;
|
||||
bool canSplitAroundColor = true;
|
||||
|
||||
for (NameLinkedList* node = neighborsWithColor[i]; node != NULL; node = node->next) {
|
||||
RegisterName neighbor = node->name;
|
||||
if (lGraph.haveEdge(range, neighbor)) {
|
||||
canSplitAroundColor = false;
|
||||
break;
|
||||
} else {
|
||||
SplitCost& sCost = splitCost[neighbor];
|
||||
double addedCost = 2.0 * (sCost.stores + sCost.loads);
|
||||
splitAroundColorCost += addedCost;
|
||||
}
|
||||
}
|
||||
if (canSplitAroundColor && splitAroundColorCost < bestCost) {
|
||||
bestCost = splitAroundColorCost;
|
||||
bestColor = i;
|
||||
splitAroundName = false;
|
||||
}
|
||||
}
|
||||
if (bestColor < RegisterName(6)) {
|
||||
color[range] = bestColor;
|
||||
registerAllocator.splitFound = true;
|
||||
|
||||
NameLinkedList** splitAround = registerAllocator.splitAround;
|
||||
|
||||
if (splitAroundName)
|
||||
for (NameLinkedList* node = neighborsWithColor[bestColor]; node != NULL; node = node->next) {
|
||||
NameLinkedList* newNode = new(pool) NameLinkedList();
|
||||
newNode->name = node->name;
|
||||
newNode->next = splitAround[range];
|
||||
splitAround[range] = newNode;
|
||||
}
|
||||
else
|
||||
for (NameLinkedList* node = neighborsWithColor[bestColor]; node != NULL; node = node->next) {
|
||||
NameLinkedList* newNode = new(pool) NameLinkedList();
|
||||
RegisterName neighbor = node->name;
|
||||
newNode->name = range;
|
||||
newNode->next = splitAround[neighbor];
|
||||
splitAround[neighbor] = newNode;
|
||||
}
|
||||
|
||||
trespass("Found a split");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
void Splits<RegisterPressure>::calculateSplitCosts(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
Pool& pool = registerAllocator.pool;
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
|
||||
SplitCost* splitCost = new(pool) SplitCost[rangeCount];
|
||||
memset(splitCost, '\0', rangeCount * sizeof(SplitCost));
|
||||
|
||||
SparseSet live(pool, rangeCount);
|
||||
RegisterPressure::Set* liveIn = registerAllocator.liveness.liveIn;
|
||||
RegisterPressure::Set* liveOut = registerAllocator.liveness.liveOut;
|
||||
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
ControlNode& node = *nodes[n];
|
||||
double weight = doLog10(node.loopDepth);
|
||||
|
||||
live = liveOut[n];
|
||||
|
||||
ControlEdge* successorsEnd = node.getSuccessorsEnd();
|
||||
for (ControlEdge* successorsPtr = node.getSuccessorsBegin(); successorsPtr < successorsEnd; successorsPtr++) {
|
||||
ControlNode& successor = successorsPtr->getTarget();
|
||||
|
||||
if (successor.getControlKind() != ckEnd) {
|
||||
RegisterPressure::Set& successorLiveIn = liveIn[successor.dfsNum];
|
||||
|
||||
for (SparseSet::iterator i = live.begin(); !live.done(i); i = live.advance(i)) {
|
||||
RegisterName name = RegisterName(live.get(i));
|
||||
if (!successorLiveIn.test(name))
|
||||
splitCost[name].loads += doLog10(successor.loopDepth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InstructionList& instructions = node.getInstructions();
|
||||
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useBegin = instruction.getInstructionUseBegin();
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
InstructionUse* usePtr;
|
||||
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
InstructionDefine* definePtr;
|
||||
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
splitCost[name2range[definePtr->getRegisterName()]].stores += weight;
|
||||
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
RegisterName range = name2range[usePtr->getRegisterName()];
|
||||
if (!live.test(range)) {
|
||||
if (&instruction != &instructions.last())
|
||||
splitCost[range].loads += weight;
|
||||
else {
|
||||
ControlEdge* successorsEnd = node.getSuccessorsEnd();
|
||||
for (ControlEdge* successorsPtr = node.getSuccessorsBegin(); successorsPtr < successorsEnd; successorsPtr++)
|
||||
splitCost[range].loads += doLog10(successorsPtr->getTarget().loopDepth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
live.clear(name2range[definePtr->getRegisterName()]);
|
||||
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister())
|
||||
live.set(name2range[usePtr->getRegisterName()]);
|
||||
}
|
||||
}
|
||||
|
||||
NameLinkedList** splitAround = new(pool) NameLinkedList*[rangeCount];
|
||||
memset(splitAround, '\0', rangeCount * sizeof(NameLinkedList*));
|
||||
registerAllocator.splitAround = splitAround;
|
||||
|
||||
registerAllocator.splitCost = splitCost;
|
||||
registerAllocator.splitFound = false;
|
||||
}
|
||||
|
||||
#endif // _SPLITS_H_
|
||||
186
mozilla/ef/Compiler/RegisterAllocator/Timer.cpp
Normal file
186
mozilla/ef/Compiler/RegisterAllocator/Timer.cpp
Normal file
@@ -0,0 +1,186 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "HashTable.h"
|
||||
#include "Timer.h"
|
||||
#include "Pool.h"
|
||||
|
||||
static Pool pool; // Pool for the Timer class.
|
||||
static HashTable<TimerEntry*> timerEntries(pool); // Timers hashtable.
|
||||
|
||||
const nTimersInABlock = 128; // Number of timers in a block.
|
||||
static PRTime *timers = new(pool) PRTime[nTimersInABlock]; // A block of timers.
|
||||
static Uint8 nextTimer = 0; // nextAvailableTimer.
|
||||
|
||||
//
|
||||
// Calibrate the call to PR_Now().
|
||||
//
|
||||
static PRTime calibrate()
|
||||
{
|
||||
PRTime t = PR_Now();
|
||||
PRTime& a = *new(pool) PRTime();
|
||||
|
||||
// Call 10 times the PR_Now() function.
|
||||
a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now();
|
||||
a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now();
|
||||
t = (PR_Now() - t + 9) / 10;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
static PRTime adjust = calibrate();
|
||||
|
||||
//
|
||||
// Return the named timer..
|
||||
//
|
||||
TimerEntry& Timer::getTimerEntry(const char* name)
|
||||
{
|
||||
if (!timerEntries.exists(name)) {
|
||||
TimerEntry* newEntry = new(pool) TimerEntry();
|
||||
newEntry->accumulator = 0;
|
||||
newEntry->running = false;
|
||||
timerEntries.add(name, newEntry);
|
||||
}
|
||||
|
||||
return *timerEntries[name];
|
||||
}
|
||||
|
||||
//
|
||||
// Return a reference to a new timer.
|
||||
//
|
||||
PRTime& Timer::getNewTimer()
|
||||
{
|
||||
if (nextTimer >= nTimersInABlock) {
|
||||
timers = new(pool) PRTime[nTimersInABlock];
|
||||
nextTimer = 0;
|
||||
}
|
||||
return timers[nextTimer++];
|
||||
}
|
||||
|
||||
static Uint32 timersAreFrozen = 0;
|
||||
|
||||
//
|
||||
// Start the named timer.
|
||||
//
|
||||
void Timer::start(const char* name)
|
||||
{
|
||||
if (timersAreFrozen)
|
||||
return;
|
||||
|
||||
freezeTimers();
|
||||
|
||||
TimerEntry& timer = getTimerEntry(name);
|
||||
PR_ASSERT(!timer.running);
|
||||
|
||||
timer.accumulator = 0;
|
||||
timer.running = true;
|
||||
timer.done = false;
|
||||
|
||||
unfreezeTimers();
|
||||
}
|
||||
|
||||
//
|
||||
// Stop the named timer.
|
||||
//
|
||||
void Timer::stop(const char* name)
|
||||
{
|
||||
if (timersAreFrozen)
|
||||
return;
|
||||
|
||||
freezeTimers();
|
||||
|
||||
TimerEntry& timer = getTimerEntry(name);
|
||||
PR_ASSERT(timer.running);
|
||||
timer.running = false;
|
||||
timer.done = true;
|
||||
|
||||
unfreezeTimers();
|
||||
}
|
||||
|
||||
//
|
||||
// Freeze all the running timers.
|
||||
//
|
||||
void Timer::freezeTimers()
|
||||
{
|
||||
PRTime when = PR_Now() - adjust;
|
||||
|
||||
if (timersAreFrozen == 0) {
|
||||
Vector<TimerEntry*> entries = timerEntries;
|
||||
Uint32 count = entries.size();
|
||||
|
||||
for (Uint32 i = 0; i < count; i++) {
|
||||
TimerEntry& entry = *entries[i];
|
||||
if (entry.running) {
|
||||
entry.accumulator += (when - *entry.startTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
timersAreFrozen++;
|
||||
}
|
||||
|
||||
//
|
||||
// Unfreeze all the running timers.
|
||||
//
|
||||
void Timer::unfreezeTimers()
|
||||
{
|
||||
PR_ASSERT(timersAreFrozen != 0);
|
||||
timersAreFrozen--;
|
||||
|
||||
if (timersAreFrozen == 0) {
|
||||
Vector<TimerEntry *> entries = timerEntries;
|
||||
Uint32 count = entries.size();
|
||||
|
||||
PRTime& newStart = getNewTimer();
|
||||
|
||||
for (Uint32 i = 0; i < count; i++) {
|
||||
TimerEntry& entry = *entries[i];
|
||||
if (entry.running) {
|
||||
entry.startTime = &newStart;
|
||||
}
|
||||
}
|
||||
|
||||
newStart = PR_Now();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Print the named timer in the file f.
|
||||
//
|
||||
void Timer::print(FILE* f, const char *name)
|
||||
{
|
||||
if (timersAreFrozen)
|
||||
return;
|
||||
|
||||
freezeTimers();
|
||||
|
||||
TimerEntry& timer = getTimerEntry(name);
|
||||
|
||||
PR_ASSERT(timer.done);
|
||||
PRTime elapsed = timer.accumulator;
|
||||
|
||||
if (elapsed >> 32) {
|
||||
fprintf(f, "[timer %s out of range]\n", name);
|
||||
} else {
|
||||
fprintf(f, "[%dus in %s]\n", Uint32(elapsed), name);
|
||||
}
|
||||
fflush(f);
|
||||
|
||||
unfreezeTimers();
|
||||
}
|
||||
|
||||
80
mozilla/ef/Compiler/RegisterAllocator/Timer.h
Normal file
80
mozilla/ef/Compiler/RegisterAllocator/Timer.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _TIMER_H_
|
||||
#define _TIMER_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "HashTable.h"
|
||||
#include "prtime.h"
|
||||
|
||||
//
|
||||
// Naming convention:
|
||||
// As the class Timer contains only static methods, the timer's name should start with the
|
||||
// module name. Otherwise starting 2 timers with the same name will assert.
|
||||
//
|
||||
|
||||
#ifndef NO_TIMER
|
||||
|
||||
struct TimerEntry
|
||||
{
|
||||
PRTime *startTime; // Current time when we start the timer.
|
||||
PRTime accumulator; // Time spent in this timer.
|
||||
bool running; // True if the timer is running.
|
||||
bool done; // True if the timer was running and was stopped.
|
||||
};
|
||||
|
||||
class Timer
|
||||
{
|
||||
private:
|
||||
|
||||
// Return the named timer.
|
||||
static TimerEntry& getTimerEntry(const char* name);
|
||||
// Return a reference to a new Timer.
|
||||
static PRTime& getNewTimer();
|
||||
|
||||
public:
|
||||
|
||||
// Start the timer.
|
||||
static void start(const char* name);
|
||||
// Stop the timer.
|
||||
static void stop(const char* name);
|
||||
// Freeze all the running timers.
|
||||
static void freezeTimers();
|
||||
// Unfreeze all the running timers.
|
||||
static void unfreezeTimers();
|
||||
// Print the timer.
|
||||
static void print(FILE* f, const char *name);
|
||||
};
|
||||
|
||||
inline void startTimer(const char* name) {Timer::start(name);}
|
||||
inline void stopTimer(const char* name) {Timer::stop(name); Timer::print(stdout, name);}
|
||||
#define START_TIMER_SAFE Timer::freezeTimers();
|
||||
#define END_TIMER_SAFE Timer::unfreezeTimers();
|
||||
#define TIMER_SAFE(x) START_TIMER_SAFE x; END_TIMER_SAFE
|
||||
|
||||
#else /* NO_TIMER */
|
||||
|
||||
inline void startTimer(const char* /*name*/) {}
|
||||
inline void stopTimer(const char* /*name*/) {}
|
||||
#define START_TIMER_SAFE
|
||||
#define END_TIMER_SAFE
|
||||
#define TIMER_SAFE(x) x;
|
||||
|
||||
#endif /* NO_TIMER */
|
||||
#endif /* _TIMER_H_ */
|
||||
40
mozilla/ef/Compiler/RegisterAllocator/VirtualRegister.cpp
Normal file
40
mozilla/ef/Compiler/RegisterAllocator/VirtualRegister.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "VirtualRegister.h"
|
||||
#include "Instruction.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// VirtualRegister -
|
||||
|
||||
#ifdef MANUAL_TEMPLATES
|
||||
template class IndexedPool<VirtualRegister>;
|
||||
#endif
|
||||
|
||||
// Set the defining instruction.
|
||||
//
|
||||
void VirtualRegister::setDefiningInstruction(Instruction& instruction)
|
||||
{
|
||||
if (definingInstruction != NULL) {
|
||||
if ((instruction.getFlags() & ifCopy) && (definingInstruction->getFlags() & ifPhiNode))
|
||||
return;
|
||||
}
|
||||
definingInstruction = &instruction;
|
||||
}
|
||||
|
||||
116
mozilla/ef/Compiler/RegisterAllocator/VirtualRegister.h
Normal file
116
mozilla/ef/Compiler/RegisterAllocator/VirtualRegister.h
Normal file
@@ -0,0 +1,116 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _VIRTUAL_REGISTER_H_
|
||||
#define _VIRTUAL_REGISTER_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "IndexedPool.h"
|
||||
#include <string.h>
|
||||
|
||||
#include "RegisterTypes.h"
|
||||
#include "RegisterClass.h"
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// VirtualRegister - 24b
|
||||
|
||||
class Instruction;
|
||||
|
||||
class VirtualRegister : public IndexedObject<VirtualRegister>
|
||||
{
|
||||
public:
|
||||
|
||||
Instruction* definingInstruction; // Instruction defining this VR.
|
||||
|
||||
// Initialize a VR of the given classKind.
|
||||
VirtualRegister(RegisterClassKind /*classKind*/) : definingInstruction(NULL) {}
|
||||
|
||||
// Return the defining instruction for this VR.
|
||||
Instruction* getDefiningInstruction() const {return definingInstruction;}
|
||||
// Set the defining instruction.
|
||||
void setDefiningInstruction(Instruction& insn);
|
||||
};
|
||||
|
||||
// Return true if the VirtualRegisters are equals. The only way 2 VRs can be equal is if
|
||||
// they have the same index. If they have the same index then they are at the same
|
||||
// address in the indexed pool.
|
||||
//
|
||||
inline bool operator == (const VirtualRegister& regA, const VirtualRegister& regB) {return ®A == ®B;}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// VirtualRegisterManager -
|
||||
|
||||
struct PreColoredRegister
|
||||
{
|
||||
RegisterID id;
|
||||
RegisterName color;
|
||||
};
|
||||
|
||||
class VirtualRegisterManager
|
||||
{
|
||||
private:
|
||||
|
||||
IndexedPool<VirtualRegister> registerPool;
|
||||
PreColoredRegister machineRegister[6];
|
||||
|
||||
public:
|
||||
VirtualRegisterManager()
|
||||
{
|
||||
for (Uint32 i = 0; i < 6; i++)
|
||||
machineRegister[i].id = invalidID;
|
||||
}
|
||||
|
||||
// Return the VirtualRegister at the given index.
|
||||
VirtualRegister& getVirtualRegister(RegisterName name) const {return registerPool.get(name);}
|
||||
|
||||
// Return a new VirtualRegister.
|
||||
RegisterID newVirtualRegister(RegisterClassKind classKind)
|
||||
{
|
||||
VirtualRegister& vReg = *new(registerPool) VirtualRegister(classKind);
|
||||
RegisterID rid;
|
||||
|
||||
setName(rid, RegisterName(vReg.getIndex()));
|
||||
setClass(rid, classKind);
|
||||
return rid;
|
||||
}
|
||||
|
||||
RegisterID newMachineRegister(RegisterName name, RegisterClassKind classKind)
|
||||
{
|
||||
RegisterID rid = machineRegister[name].id;
|
||||
|
||||
if (rid == invalidID) {
|
||||
rid = newVirtualRegister(classKind);
|
||||
DEBUG_ONLY(setMachineRegister(rid));
|
||||
machineRegister[name].id = rid;
|
||||
machineRegister[name].color = name;
|
||||
}
|
||||
|
||||
return rid;
|
||||
}
|
||||
|
||||
PreColoredRegister* getMachineRegistersBegin() const {return (PreColoredRegister*) machineRegister;} // FIX
|
||||
PreColoredRegister* getMachineRegistersEnd() const {return (PreColoredRegister*) &machineRegister[6];} // FIX
|
||||
|
||||
// Return the VirtualRegister universe size.
|
||||
Uint32 getSize() {return registerPool.getSize();}
|
||||
|
||||
void setSize(Uint32 size) {registerPool.setSize(size);}
|
||||
};
|
||||
|
||||
#endif // _VIRTUAL_REGISTER_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,250 +0,0 @@
|
||||
/* -*- Mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#ifdef DEBUG_dp
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include "nsCookieService.h" /* don't remove -- needed for mac build */
|
||||
#include "nsCookieHTTPNotify.h"
|
||||
#include "nsIGenericFactory.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
#include "nsCookie.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsINetModuleMgr.h"
|
||||
#include "nsILoadGroup.h"
|
||||
#include "nsICategoryManager.h"
|
||||
#include "nsIHttpProtocolHandler.h" // for NS_HTTP_STARTUP_CATEGORY
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIPrompt.h"
|
||||
|
||||
static NS_DEFINE_CID(kINetModuleMgrCID, NS_NETMODULEMGR_CID);
|
||||
|
||||
///////////////////////////////////
|
||||
// nsISupports
|
||||
|
||||
NS_IMPL_ISUPPORTS2(nsCookieHTTPNotify, nsIHttpNotify, nsINetNotify);
|
||||
|
||||
///////////////////////////////////
|
||||
// nsCookieHTTPNotify Implementation
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsCookieHTTPNotify, Init)
|
||||
|
||||
nsresult nsCookieHTTPNotify::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
||||
{
|
||||
return nsCookieHTTPNotifyConstructor(aOuter, aIID, aResult);
|
||||
}
|
||||
|
||||
NS_METHOD nsCookieHTTPNotify::RegisterProc(nsIComponentManager *aCompMgr,
|
||||
nsIFile *aPath,
|
||||
const char *registryLocation,
|
||||
const char *componentType,
|
||||
const nsModuleComponentInfo *info)
|
||||
{
|
||||
// Register ourselves into the NS_CATEGORY_HTTP_STARTUP
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsICategoryManager> catman = do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsXPIDLCString prevEntry;
|
||||
rv = catman->AddCategoryEntry(NS_HTTP_STARTUP_CATEGORY, "Http Cookie Notify", NS_COOKIEHTTPNOTIFY_CONTRACTID,
|
||||
PR_TRUE, PR_TRUE, getter_Copies(prevEntry));
|
||||
|
||||
return NS_OK;
|
||||
|
||||
}
|
||||
|
||||
NS_METHOD nsCookieHTTPNotify::UnregisterProc(nsIComponentManager *aCompMgr,
|
||||
nsIFile *aPath,
|
||||
const char *registryLocation,
|
||||
const nsModuleComponentInfo *info)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsICategoryManager> catman = do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsXPIDLCString prevEntry;
|
||||
rv = catman->DeleteCategoryEntry(NS_HTTP_STARTUP_CATEGORY, NS_COOKIEHTTPNOTIFY_CONTRACTID, PR_TRUE,
|
||||
getter_Copies(prevEntry));
|
||||
|
||||
// Return value is not used from this function.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCookieHTTPNotify::Init()
|
||||
{
|
||||
// Register to handing http requests and responses
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsINetModuleMgr> pNetModuleMgr = do_GetService(kINetModuleMgrCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = pNetModuleMgr->RegisterModule(NS_NETWORK_MODULE_MANAGER_HTTP_REQUEST_CONTRACTID,
|
||||
(nsIHttpNotify *)this);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = pNetModuleMgr->RegisterModule(NS_NETWORK_MODULE_MANAGER_HTTP_RESPONSE_CONTRACTID,
|
||||
(nsIHttpNotify *)this);
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCookieHTTPNotify::nsCookieHTTPNotify()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mCookieService = nsnull;
|
||||
#ifdef DEBUG_dp
|
||||
printf("CookieHTTPNotify Created.\n");
|
||||
#endif /* DEBUG_dp */
|
||||
}
|
||||
|
||||
nsCookieHTTPNotify::~nsCookieHTTPNotify()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCookieHTTPNotify::SetupCookieService()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (!mCookieService)
|
||||
{
|
||||
mCookieService = do_GetService(NS_COOKIESERVICE_CONTRACTID, &rv);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
///////////////////////////////////
|
||||
// nsIHttpNotify
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCookieHTTPNotify::OnModifyRequest(nsIHttpChannel *aHttpChannel)
|
||||
{
|
||||
nsresult rv;
|
||||
// Preconditions
|
||||
NS_ENSURE_ARG_POINTER(aHttpChannel);
|
||||
|
||||
// Get the url
|
||||
nsCOMPtr<nsIURI> pURL;
|
||||
rv = aHttpChannel->GetURI(getter_AddRefs(pURL));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Get the original url that the user either typed in or clicked on
|
||||
nsCOMPtr<nsILoadGroup> pLoadGroup;
|
||||
rv = aHttpChannel->GetLoadGroup(getter_AddRefs(pLoadGroup));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsIChannel> pChannel;
|
||||
if (pLoadGroup) {
|
||||
nsCOMPtr<nsIRequest> pRequest;
|
||||
rv = pLoadGroup->GetDefaultLoadRequest(getter_AddRefs(pRequest));
|
||||
if (pRequest)
|
||||
pChannel = do_QueryInterface(pRequest);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> pFirstURL;
|
||||
if (pChannel) {
|
||||
rv = pChannel->GetURI(getter_AddRefs(pFirstURL));
|
||||
} else {
|
||||
rv = aHttpChannel->GetURI(getter_AddRefs(pFirstURL));
|
||||
}
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Ensure that the cookie service exists
|
||||
rv = SetupCookieService();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
char * cookie;
|
||||
rv = mCookieService->GetCookieStringFromHttp(pURL, pFirstURL, &cookie);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Set the cookie into the request headers
|
||||
if (cookie && *cookie)
|
||||
rv = aHttpChannel->SetRequestHeader("Cookie", cookie);
|
||||
nsMemory::Free((void *)cookie);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCookieHTTPNotify::OnExamineResponse(nsIHttpChannel *aHttpChannel)
|
||||
{
|
||||
nsresult rv;
|
||||
// Preconditions
|
||||
NS_ENSURE_ARG_POINTER(aHttpChannel);
|
||||
|
||||
// Get the Cookie header
|
||||
nsXPIDLCString cookieHeader;
|
||||
rv = aHttpChannel->GetResponseHeader("Set-Cookie", getter_Copies(cookieHeader));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (!cookieHeader) return NS_OK; // not an error, there's just no header.
|
||||
|
||||
// Get the url
|
||||
nsCOMPtr<nsIURI> pURL;
|
||||
rv = aHttpChannel->GetURI(getter_AddRefs(pURL));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Get the original url that the user either typed in or clicked on
|
||||
nsCOMPtr<nsILoadGroup> pLoadGroup;
|
||||
rv = aHttpChannel->GetLoadGroup(getter_AddRefs(pLoadGroup));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
nsCOMPtr<nsIChannel> pChannel;
|
||||
if (pLoadGroup) {
|
||||
nsCOMPtr<nsIRequest> pRequest;
|
||||
rv = pLoadGroup->GetDefaultLoadRequest(getter_AddRefs(pRequest));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
pChannel = do_QueryInterface(pRequest);
|
||||
}
|
||||
nsCOMPtr<nsIURI> pFirstURL;
|
||||
if (pChannel) {
|
||||
rv = pChannel->GetURI(getter_AddRefs(pFirstURL));
|
||||
} else {
|
||||
rv = aHttpChannel->GetURI(getter_AddRefs(pFirstURL));
|
||||
}
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Get the prompter
|
||||
nsCOMPtr<nsIInterfaceRequestor> pInterfaces;
|
||||
nsCOMPtr<nsIPrompt> pPrompter;
|
||||
if (pChannel) {
|
||||
pChannel->GetNotificationCallbacks(getter_AddRefs(pInterfaces));
|
||||
} else {
|
||||
aHttpChannel->GetNotificationCallbacks(getter_AddRefs(pInterfaces));
|
||||
}
|
||||
if (pInterfaces)
|
||||
pInterfaces->GetInterface(NS_GET_IID(nsIPrompt), getter_AddRefs(pPrompter));
|
||||
|
||||
// Get the expires
|
||||
nsXPIDLCString dateHeader;
|
||||
rv = aHttpChannel->GetResponseHeader("Date", getter_Copies(dateHeader));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Ensure that we have the cookie service
|
||||
rv = SetupCookieService();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Save the cookie
|
||||
rv = mCookieService->SetCookieStringFromHttp(pURL, pFirstURL, pPrompter, cookieHeader, dateHeader);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#ifndef nsCookieHTTPNotify_h___
|
||||
#define nsCookieHTTPNotify_h___
|
||||
|
||||
#include "nsIHttpNotify.h"
|
||||
#include "nsICookieService.h"
|
||||
#include "nsIComponentManager.h"
|
||||
|
||||
// {6BC1F522-1F45-11d3-8AD4-00105A1B8860}
|
||||
#define NS_COOKIEHTTPNOTIFY_CID \
|
||||
{ 0x6bc1f522, 0x1f45, 0x11d3, { 0x8a, 0xd4, 0x0, 0x10, 0x5a, 0x1b, 0x88, 0x60 } }
|
||||
|
||||
#define NS_COOKIEHTTPNOTIFY_CONTRACTID "@mozilla.org/cookie-notifier;1"
|
||||
#define NS_COOKIEHTTPNOTIFY_CLASSNAME "Cookie Notifier"
|
||||
|
||||
struct nsModuleComponentInfo; // forward declaration
|
||||
|
||||
class nsCookieHTTPNotify : public nsIHttpNotify {
|
||||
public:
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// Init method
|
||||
NS_IMETHOD Init();
|
||||
|
||||
// nsIHttpNotify methods:
|
||||
NS_DECL_NSIHTTPNOTIFY
|
||||
|
||||
// nsCookieHTTPNotify methods:
|
||||
nsCookieHTTPNotify();
|
||||
virtual ~nsCookieHTTPNotify();
|
||||
|
||||
static nsresult Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
|
||||
static NS_METHOD RegisterProc(nsIComponentManager *aCompMgr,
|
||||
nsIFile *aPath,
|
||||
const char *registryLocation,
|
||||
const char *componentType,
|
||||
const nsModuleComponentInfo *info);
|
||||
static NS_METHOD UnregisterProc(nsIComponentManager *aCompMgr,
|
||||
nsIFile *aPath,
|
||||
const char *registryLocation,
|
||||
const nsModuleComponentInfo *info);
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsICookieService> mCookieService;
|
||||
|
||||
NS_IMETHOD SetupCookieService();
|
||||
};
|
||||
#endif /* nsCookieHTTPNotify_h___ */
|
||||
@@ -1,43 +0,0 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape 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/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = necko
|
||||
LIBRARY_NAME = nkdatetm_s
|
||||
REQUIRES = xpcom string
|
||||
|
||||
CPPSRCS = \
|
||||
nsDateTimeHandler.cpp \
|
||||
nsDateTimeChannel.cpp \
|
||||
$(NULL)
|
||||
|
||||
# we don't want the shared lib, but we want to force the creation of a
|
||||
# static lib.
|
||||
override NO_SHARED_LIB=1
|
||||
override NO_STATIC_LIB=
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
@@ -1,327 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
// datetime implementation
|
||||
|
||||
#include "nsDateTimeChannel.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsILoadGroup.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsISocketTransportService.h"
|
||||
#include "nsITransport.h"
|
||||
#include "nsIProgressEventSink.h"
|
||||
|
||||
static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID);
|
||||
|
||||
// nsDateTimeChannel methods
|
||||
nsDateTimeChannel::nsDateTimeChannel() {
|
||||
NS_INIT_REFCNT();
|
||||
mContentLength = -1;
|
||||
mPort = -1;
|
||||
}
|
||||
|
||||
nsDateTimeChannel::~nsDateTimeChannel() {
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS4(nsDateTimeChannel,
|
||||
nsIChannel,
|
||||
nsIRequest,
|
||||
nsIStreamListener,
|
||||
nsIRequestObserver)
|
||||
|
||||
nsresult
|
||||
nsDateTimeChannel::Init(nsIURI* uri)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
NS_ASSERTION(uri, "no uri");
|
||||
|
||||
mUrl = uri;
|
||||
|
||||
rv = mUrl->GetPort(&mPort);
|
||||
if (NS_FAILED(rv) || mPort < 1)
|
||||
mPort = DATETIME_PORT;
|
||||
|
||||
rv = mUrl->GetPath(getter_Copies(mHost));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (!*(const char *)mHost) return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsDateTimeChannel::Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult)
|
||||
{
|
||||
nsDateTimeChannel* dc = new nsDateTimeChannel();
|
||||
if (dc == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(dc);
|
||||
nsresult rv = dc->QueryInterface(aIID, aResult);
|
||||
NS_RELEASE(dc);
|
||||
return rv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIRequest methods:
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDateTimeChannel::GetName(PRUnichar* *result)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDateTimeChannel::IsPending(PRBool *result)
|
||||
{
|
||||
NS_NOTREACHED("nsDateTimeChannel::IsPending");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDateTimeChannel::GetStatus(nsresult *status)
|
||||
{
|
||||
*status = NS_OK;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDateTimeChannel::Cancel(nsresult status)
|
||||
{
|
||||
NS_ASSERTION(NS_FAILED(status), "shouldn't cancel with a success code");
|
||||
NS_NOTREACHED("nsDateTimeChannel::Cancel");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDateTimeChannel::Suspend(void)
|
||||
{
|
||||
NS_NOTREACHED("nsDateTimeChannel::Suspend");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDateTimeChannel::Resume(void)
|
||||
{
|
||||
NS_NOTREACHED("nsDateTimeChannel::Resume");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIChannel methods:
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDateTimeChannel::GetOriginalURI(nsIURI* *aURI)
|
||||
{
|
||||
*aURI = mOriginalURI ? mOriginalURI : mUrl;
|
||||
NS_ADDREF(*aURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDateTimeChannel::SetOriginalURI(nsIURI* aURI)
|
||||
{
|
||||
mOriginalURI = aURI;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDateTimeChannel::GetURI(nsIURI* *aURI)
|
||||
{
|
||||
*aURI = mUrl;
|
||||
NS_IF_ADDREF(*aURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDateTimeChannel::Open(nsIInputStream **_retval)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
NS_WITH_SERVICE(nsISocketTransportService, socketService, kSocketTransportServiceCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsITransport> transport;
|
||||
rv = socketService->CreateTransport(mHost, mPort, nsnull, -1, 32, 32, getter_AddRefs(transport));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
transport->SetNotificationCallbacks(mCallbacks,
|
||||
(mLoadFlags & LOAD_BACKGROUND));
|
||||
|
||||
return transport->OpenInputStream(0, -1, 0, _retval);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDateTimeChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *ctxt)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
NS_WITH_SERVICE(nsISocketTransportService, socketService, kSocketTransportServiceCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsITransport> transport;
|
||||
rv = socketService->CreateTransport(mHost, mPort, nsnull, -1, 32, 32, getter_AddRefs(transport));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
transport->SetNotificationCallbacks(mCallbacks,
|
||||
(mLoadFlags & LOAD_BACKGROUND));
|
||||
|
||||
mListener = aListener;
|
||||
|
||||
nsCOMPtr<nsIRequest> request;
|
||||
return transport->AsyncRead(this, ctxt, 0, -1, 0, getter_AddRefs(request));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDateTimeChannel::GetLoadFlags(PRUint32 *aLoadFlags)
|
||||
{
|
||||
*aLoadFlags = mLoadFlags;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDateTimeChannel::SetLoadFlags(PRUint32 aLoadFlags)
|
||||
{
|
||||
mLoadFlags = aLoadFlags;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#define DATETIME_TYPE "text/plain"
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDateTimeChannel::GetContentType(char* *aContentType) {
|
||||
if (!aContentType) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aContentType = nsCRT::strdup(DATETIME_TYPE);
|
||||
if (!*aContentType) return NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDateTimeChannel::SetContentType(const char *aContentType)
|
||||
{
|
||||
//It doesn't make sense to set the content-type on this type
|
||||
// of channel...
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDateTimeChannel::GetContentLength(PRInt32 *aContentLength)
|
||||
{
|
||||
*aContentLength = mContentLength;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDateTimeChannel::SetContentLength(PRInt32 aContentLength)
|
||||
{
|
||||
NS_NOTREACHED("nsDateTimeChannel::SetContentLength");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDateTimeChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup)
|
||||
{
|
||||
*aLoadGroup = mLoadGroup;
|
||||
NS_IF_ADDREF(*aLoadGroup);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDateTimeChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
|
||||
{
|
||||
if (mLoadGroup) // if we already had a load group remove ourselves...
|
||||
(void)mLoadGroup->RemoveRequest(this, nsnull, NS_OK);
|
||||
|
||||
mLoadGroup = aLoadGroup;
|
||||
if (mLoadGroup) {
|
||||
return mLoadGroup->AddRequest(this, nsnull);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDateTimeChannel::GetOwner(nsISupports* *aOwner)
|
||||
{
|
||||
*aOwner = mOwner.get();
|
||||
NS_IF_ADDREF(*aOwner);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDateTimeChannel::SetOwner(nsISupports* aOwner)
|
||||
{
|
||||
mOwner = aOwner;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDateTimeChannel::GetNotificationCallbacks(nsIInterfaceRequestor* *aNotificationCallbacks)
|
||||
{
|
||||
*aNotificationCallbacks = mCallbacks.get();
|
||||
NS_IF_ADDREF(*aNotificationCallbacks);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDateTimeChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
|
||||
{
|
||||
mCallbacks = aNotificationCallbacks;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDateTimeChannel::GetSecurityInfo(nsISupports **sec)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(sec);
|
||||
*sec = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIRequestObserver methods
|
||||
NS_IMETHODIMP
|
||||
nsDateTimeChannel::OnStartRequest(nsIRequest *request, nsISupports *aContext) {
|
||||
return mListener->OnStartRequest(this, aContext);
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDateTimeChannel::OnStopRequest(nsIRequest *request, nsISupports* aContext,
|
||||
nsresult aStatus) {
|
||||
if (mLoadGroup) {
|
||||
nsresult rv = mLoadGroup->RemoveRequest(this, nsnull, aStatus);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
return mListener->OnStopRequest(this, aContext, aStatus);
|
||||
}
|
||||
|
||||
|
||||
// nsIStreamListener method
|
||||
NS_IMETHODIMP
|
||||
nsDateTimeChannel::OnDataAvailable(nsIRequest *request, nsISupports* aContext,
|
||||
nsIInputStream *aInputStream, PRUint32 aSourceOffset,
|
||||
PRUint32 aLength) {
|
||||
mContentLength = aLength;
|
||||
return mListener->OnDataAvailable(this, aContext, aInputStream, aSourceOffset, aLength);
|
||||
}
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
// A datetime channel retrieves date time information from
|
||||
// RFC 867 compliant datetime servers. The date/time returned
|
||||
// to the caller is of MIME type "text/plain".
|
||||
|
||||
#ifndef nsDateTimeChannel_h___
|
||||
#define nsDateTimeChannel_h___
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsILoadGroup.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsDateTimeHandler.h"
|
||||
#include "nsIStreamListener.h"
|
||||
|
||||
|
||||
class nsDateTimeChannel
|
||||
: public nsIChannel,
|
||||
public nsIStreamListener {
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIREQUEST
|
||||
NS_DECL_NSICHANNEL
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
|
||||
// nsDateTimeChannel methods:
|
||||
nsDateTimeChannel();
|
||||
virtual ~nsDateTimeChannel();
|
||||
|
||||
// Define a Create method to be used with a factory:
|
||||
static NS_METHOD
|
||||
Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult);
|
||||
|
||||
nsresult Init(nsIURI* uri);
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
|
||||
nsCOMPtr<nsIURI> mOriginalURI;
|
||||
nsCOMPtr<nsIURI> mUrl;
|
||||
nsCOMPtr<nsIStreamListener> mListener;
|
||||
PRUint32 mLoadFlags;
|
||||
nsCOMPtr<nsILoadGroup> mLoadGroup;
|
||||
nsCString mContentType;
|
||||
PRInt32 mContentLength;
|
||||
nsCOMPtr<nsISupports> mOwner;
|
||||
|
||||
PRInt32 mPort;
|
||||
nsXPIDLCString mHost;
|
||||
};
|
||||
|
||||
#endif /* nsDateTimeChannel_h___ */
|
||||
@@ -1,117 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#include "nspr.h"
|
||||
#include "nsDateTimeChannel.h"
|
||||
#include "nsDateTimeHandler.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIProgressEventSink.h"
|
||||
#include "nsNetCID.h"
|
||||
|
||||
static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsDateTimeHandler::nsDateTimeHandler() {
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
nsDateTimeHandler::~nsDateTimeHandler() {
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsDateTimeHandler, nsIProtocolHandler)
|
||||
|
||||
NS_METHOD
|
||||
nsDateTimeHandler::Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult) {
|
||||
|
||||
nsDateTimeHandler* ph = new nsDateTimeHandler();
|
||||
if (ph == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(ph);
|
||||
nsresult rv = ph->QueryInterface(aIID, aResult);
|
||||
NS_RELEASE(ph);
|
||||
return rv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIProtocolHandler methods:
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDateTimeHandler::GetScheme(char* *result) {
|
||||
*result = nsCRT::strdup("datetime");
|
||||
if (!*result) return NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDateTimeHandler::GetDefaultPort(PRInt32 *result) {
|
||||
*result = DATETIME_PORT;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDateTimeHandler::NewURI(const char *aSpec, nsIURI *aBaseURI,
|
||||
nsIURI **result) {
|
||||
nsresult rv;
|
||||
|
||||
// no concept of a relative datetime url
|
||||
NS_ASSERTION(!aBaseURI, "base url passed into datetime protocol handler");
|
||||
|
||||
nsIURI* url;
|
||||
rv = nsComponentManager::CreateInstance(kSimpleURICID, nsnull,
|
||||
NS_GET_IID(nsIURI),
|
||||
(void**)&url);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = url->SetSpec((char*)aSpec);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_RELEASE(url);
|
||||
return rv;
|
||||
}
|
||||
|
||||
*result = url;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDateTimeHandler::NewChannel(nsIURI* url, nsIChannel* *result)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsDateTimeChannel* channel;
|
||||
rv = nsDateTimeChannel::Create(nsnull, NS_GET_IID(nsIChannel), (void**)&channel);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = channel->Init(url);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_RELEASE(channel);
|
||||
return rv;
|
||||
}
|
||||
|
||||
*result = channel;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1,51 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
// The datetime protocol handler creates "datetime" URIs of the form
|
||||
// "datetime:RFC867Server".
|
||||
|
||||
#ifndef nsDateTimeHandler_h___
|
||||
#define nsDateTimeHandler_h___
|
||||
|
||||
#include "nsIProtocolHandler.h"
|
||||
|
||||
#define DATETIME_PORT 13
|
||||
|
||||
// {AA27D2A0-B71B-11d3-A1A0-0050041CAF44}
|
||||
#define NS_DATETIMEHANDLER_CID \
|
||||
{ 0xaa27d2a0, 0xb71b, 0x11d3, { 0xa1, 0xa0, 0x0, 0x50, 0x4, 0x1c, 0xaf, 0x44 } }
|
||||
|
||||
class nsDateTimeHandler : public nsIProtocolHandler
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPROTOCOLHANDLER
|
||||
|
||||
// nsDateTimeHandler methods:
|
||||
nsDateTimeHandler();
|
||||
virtual ~nsDateTimeHandler();
|
||||
|
||||
// Define a Create method to be used with a factory:
|
||||
static NS_METHOD Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult);
|
||||
};
|
||||
|
||||
#endif /* nsDateTimeHandler_h___ */
|
||||
@@ -1,34 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#include "nsIGenericFactory.h"
|
||||
#include "nsDateTimeHandler.h"
|
||||
|
||||
static nsModuleComponentInfo gResComponents[] = {
|
||||
{ "The DateTime Protocol Handler",
|
||||
NS_DATETIMEHANDLER_CID,
|
||||
NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "datetime",
|
||||
nsDateTimeHandler::Create
|
||||
}
|
||||
};
|
||||
|
||||
NS_IMPL_NSGETMODULE(datetime, gResComponents)
|
||||
@@ -1,42 +0,0 @@
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Brian Ryner.
|
||||
# Portions created by Brian Ryner are Copyright (C) 2000 Brian Ryner.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Brian Ryner <bryner@uiuc.edu>
|
||||
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = necko
|
||||
LIBRARY_NAME = nkfinger_s
|
||||
REQUIRES = xpcom string mimetype
|
||||
|
||||
CPPSRCS = \
|
||||
nsFingerHandler.cpp \
|
||||
nsFingerChannel.cpp \
|
||||
$(NULL)
|
||||
|
||||
# we don't want the shared lib, but we want to force the creation of a
|
||||
# static lib.
|
||||
override NO_SHARED_LIB=1
|
||||
override NO_STATIC_LIB=
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
@@ -1,427 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Brian Ryner.
|
||||
* Portions created by Brian Ryner are Copyright (C) 2000 Brian Ryner.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Brian Ryner <bryner@uiuc.edu>
|
||||
*/
|
||||
|
||||
// finger implementation
|
||||
|
||||
#include "nsFingerChannel.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsILoadGroup.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsISocketTransportService.h"
|
||||
#include "nsIStringStream.h"
|
||||
#include "nsMimeTypes.h"
|
||||
#include "nsIStreamConverterService.h"
|
||||
#include "nsITXTToHTMLConv.h"
|
||||
#include "nsIProgressEventSink.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID);
|
||||
static NS_DEFINE_CID(kStreamConverterServiceCID, NS_STREAMCONVERTERSERVICE_CID);
|
||||
|
||||
#define BUFFER_SEG_SIZE (4*1024)
|
||||
#define BUFFER_MAX_SIZE (64*1024)
|
||||
|
||||
// nsFingerChannel methods
|
||||
nsFingerChannel::nsFingerChannel()
|
||||
: mContentLength(-1),
|
||||
mActAsObserver(PR_TRUE),
|
||||
mPort(-1),
|
||||
mStatus(NS_OK)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
nsFingerChannel::~nsFingerChannel() {
|
||||
}
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS4(nsFingerChannel,
|
||||
nsIChannel,
|
||||
nsIRequest,
|
||||
nsIStreamListener,
|
||||
nsIRequestObserver)
|
||||
|
||||
nsresult
|
||||
nsFingerChannel::Init(nsIURI* uri)
|
||||
{
|
||||
nsresult rv;
|
||||
nsXPIDLCString autoBuffer;
|
||||
|
||||
NS_ASSERTION(uri, "no uri");
|
||||
|
||||
mUrl = uri;
|
||||
|
||||
// For security reasons, we do not allow the user to specify a
|
||||
// non-default port for finger: URL's.
|
||||
|
||||
mPort = FINGER_PORT;
|
||||
|
||||
rv = mUrl->GetPath(getter_Copies(autoBuffer)); // autoBuffer = user@host
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Now parse out the user and host
|
||||
const char* buf = autoBuffer.get();
|
||||
const char* pos = PL_strchr(buf, '@');
|
||||
|
||||
// Catch the case of just the host being given
|
||||
if (!pos) {
|
||||
mHost.Assign(buf);
|
||||
} else {
|
||||
mUser.Assign(buf,pos-buf);
|
||||
mHost.Assign(pos+1); // ignore '@'
|
||||
}
|
||||
|
||||
if (mHost.IsEmpty()) return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsFingerChannel::Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult)
|
||||
{
|
||||
nsFingerChannel* fc = new nsFingerChannel();
|
||||
if (fc == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(fc);
|
||||
nsresult rv = fc->QueryInterface(aIID, aResult);
|
||||
NS_RELEASE(fc);
|
||||
return rv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIRequest methods:
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFingerChannel::GetName(PRUnichar* *result)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFingerChannel::IsPending(PRBool *result)
|
||||
{
|
||||
NS_NOTREACHED("nsFingerChannel::IsPending");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFingerChannel::GetStatus(nsresult *status)
|
||||
{
|
||||
*status = mStatus;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFingerChannel::Cancel(nsresult status)
|
||||
{
|
||||
NS_ASSERTION(NS_FAILED(status), "shouldn't cancel with a success code");
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
mStatus = status;
|
||||
if (mTransportRequest) {
|
||||
rv = mTransportRequest->Cancel(status);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFingerChannel::Suspend(void)
|
||||
{
|
||||
NS_NOTREACHED("nsFingerChannel::Suspend");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFingerChannel::Resume(void)
|
||||
{
|
||||
NS_NOTREACHED("nsFingerChannel::Resume");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIChannel methods:
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFingerChannel::GetOriginalURI(nsIURI* *aURI)
|
||||
{
|
||||
*aURI = mOriginalURI ? mOriginalURI : mUrl;
|
||||
NS_ADDREF(*aURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFingerChannel::SetOriginalURI(nsIURI* aURI)
|
||||
{
|
||||
mOriginalURI = aURI;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFingerChannel::GetURI(nsIURI* *aURI)
|
||||
{
|
||||
*aURI = mUrl;
|
||||
NS_IF_ADDREF(*aURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFingerChannel::Open(nsIInputStream **_retval)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
NS_WITH_SERVICE(nsISocketTransportService, socketService, kSocketTransportServiceCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = socketService->CreateTransport(mHost, mPort, nsnull, -1, BUFFER_SEG_SIZE,
|
||||
BUFFER_MAX_SIZE, getter_AddRefs(mTransport));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
mTransport->SetNotificationCallbacks(mCallbacks,
|
||||
(mLoadFlags & LOAD_BACKGROUND));
|
||||
|
||||
return mTransport->OpenInputStream(0, PRUint32(-1), 0, _retval);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFingerChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *ctxt)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
NS_WITH_SERVICE(nsISocketTransportService, socketService, kSocketTransportServiceCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = socketService->CreateTransport(mHost, mPort, nsnull, -1, BUFFER_SEG_SIZE,
|
||||
BUFFER_MAX_SIZE, getter_AddRefs(mTransport));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
mTransport->SetNotificationCallbacks(mCallbacks,
|
||||
(mLoadFlags & LOAD_BACKGROUND));
|
||||
|
||||
mListener = aListener;
|
||||
mResponseContext = ctxt;
|
||||
|
||||
return SendRequest(mTransport);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFingerChannel::GetLoadFlags(PRUint32 *aLoadFlags)
|
||||
{
|
||||
*aLoadFlags = mLoadFlags;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFingerChannel::SetLoadFlags(PRUint32 aLoadFlags)
|
||||
{
|
||||
mLoadFlags = aLoadFlags;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#define FINGER_TYPE TEXT_HTML
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFingerChannel::GetContentType(char* *aContentType) {
|
||||
if (!aContentType) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aContentType = nsCRT::strdup(FINGER_TYPE);
|
||||
if (!*aContentType) return NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFingerChannel::SetContentType(const char *aContentType)
|
||||
{
|
||||
//It doesn't make sense to set the content-type on this type
|
||||
// of channel...
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFingerChannel::GetContentLength(PRInt32 *aContentLength)
|
||||
{
|
||||
*aContentLength = mContentLength;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFingerChannel::SetContentLength(PRInt32 aContentLength)
|
||||
{
|
||||
NS_NOTREACHED("nsFingerChannel::SetContentLength");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFingerChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup)
|
||||
{
|
||||
*aLoadGroup = mLoadGroup;
|
||||
NS_IF_ADDREF(*aLoadGroup);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFingerChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
|
||||
{
|
||||
mLoadGroup = aLoadGroup;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFingerChannel::GetOwner(nsISupports* *aOwner)
|
||||
{
|
||||
*aOwner = mOwner.get();
|
||||
NS_IF_ADDREF(*aOwner);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFingerChannel::SetOwner(nsISupports* aOwner)
|
||||
{
|
||||
mOwner = aOwner;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFingerChannel::GetNotificationCallbacks(nsIInterfaceRequestor* *aNotificationCallbacks)
|
||||
{
|
||||
*aNotificationCallbacks = mCallbacks.get();
|
||||
NS_IF_ADDREF(*aNotificationCallbacks);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFingerChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
|
||||
{
|
||||
mCallbacks = aNotificationCallbacks;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFingerChannel::GetSecurityInfo(nsISupports * *aSecurityInfo)
|
||||
{
|
||||
*aSecurityInfo = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIRequestObserver methods
|
||||
NS_IMETHODIMP
|
||||
nsFingerChannel::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext) {
|
||||
if (!mActAsObserver) {
|
||||
// acting as a listener
|
||||
return mListener->OnStartRequest(this, mResponseContext);
|
||||
} else {
|
||||
// we don't want to pass our AsyncWrite's OnStart through
|
||||
// we just ignore this
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFingerChannel::OnStopRequest(nsIRequest *aRequest, nsISupports* aContext,
|
||||
nsresult aStatus)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (NS_FAILED(aStatus) || !mActAsObserver) {
|
||||
if (mLoadGroup) {
|
||||
rv = mLoadGroup->RemoveRequest(this, nsnull, aStatus);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
rv = mListener->OnStopRequest(this, mResponseContext, aStatus);
|
||||
mTransport = 0;
|
||||
return rv;
|
||||
} else {
|
||||
// at this point we know the request has been sent.
|
||||
// we're no longer acting as an observer.
|
||||
|
||||
mActAsObserver = PR_FALSE;
|
||||
nsCOMPtr<nsIStreamListener> converterListener;
|
||||
|
||||
NS_WITH_SERVICE(nsIStreamConverterService, StreamConvService,
|
||||
kStreamConverterServiceCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsAutoString fromStr; fromStr.AssignWithConversion("text/plain");
|
||||
nsAutoString toStr; toStr.AssignWithConversion("text/html");
|
||||
|
||||
rv = StreamConvService->AsyncConvertData(fromStr.GetUnicode(),
|
||||
toStr.GetUnicode(), this, mResponseContext,
|
||||
getter_AddRefs(converterListener));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsITXTToHTMLConv> converter(do_QueryInterface(converterListener));
|
||||
if (converter) {
|
||||
nsAutoString title; title.AssignWithConversion("Finger information for ");
|
||||
nsXPIDLCString userHost;
|
||||
rv = mUrl->GetPath(getter_Copies(userHost));
|
||||
title.AppendWithConversion(userHost);
|
||||
converter->SetTitle(title.GetUnicode());
|
||||
converter->PreFormatHTML(PR_TRUE);
|
||||
}
|
||||
|
||||
return mTransport->AsyncRead(converterListener, mResponseContext, 0, PRUint32(-1), 0,
|
||||
getter_AddRefs(mTransportRequest));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// nsIStreamListener method
|
||||
NS_IMETHODIMP
|
||||
nsFingerChannel::OnDataAvailable(nsIRequest *aRequest, nsISupports* aContext,
|
||||
nsIInputStream *aInputStream, PRUint32 aSourceOffset,
|
||||
PRUint32 aLength) {
|
||||
mContentLength = aLength;
|
||||
return mListener->OnDataAvailable(this, mResponseContext, aInputStream, aSourceOffset, aLength);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFingerChannel::SendRequest(nsITransport* aTransport) {
|
||||
// The text to send should already be in mUser
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsISupports> result;
|
||||
nsCOMPtr<nsIInputStream> charstream;
|
||||
nsCString requestBuffer(mUser);
|
||||
|
||||
if (mLoadGroup) {
|
||||
mLoadGroup->AddRequest(this, nsnull);
|
||||
}
|
||||
|
||||
requestBuffer.Append(CRLF);
|
||||
|
||||
mRequest = requestBuffer.ToNewCString();
|
||||
|
||||
rv = NS_NewCharInputStream(getter_AddRefs(result), mRequest);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
charstream = do_QueryInterface(result, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = NS_AsyncWriteFromStream(getter_AddRefs(mTransportRequest),
|
||||
aTransport, charstream,
|
||||
0, requestBuffer.Length(), 0,
|
||||
this, nsnull);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Brian Ryner.
|
||||
* Portions created by Brian Ryner are Copyright (C) 2000 Brian Ryner.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Brian Ryner <bryner@uiuc.edu>
|
||||
*/
|
||||
|
||||
#ifndef nsFingerChannel_h___
|
||||
#define nsFingerChannel_h___
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsILoadGroup.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsFingerHandler.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsITransport.h"
|
||||
|
||||
class nsFingerChannel
|
||||
: public nsIChannel,
|
||||
public nsIStreamListener {
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIREQUEST
|
||||
NS_DECL_NSICHANNEL
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
|
||||
// nsFingerChannel methods:
|
||||
nsFingerChannel();
|
||||
virtual ~nsFingerChannel();
|
||||
|
||||
// Define a Create method to be used with a factory:
|
||||
static NS_METHOD
|
||||
Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult);
|
||||
|
||||
nsresult Init(nsIURI* uri);
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
|
||||
nsCOMPtr<nsIURI> mOriginalURI;
|
||||
nsCOMPtr<nsIURI> mUrl;
|
||||
nsCOMPtr<nsIStreamListener> mListener;
|
||||
PRUint32 mLoadFlags;
|
||||
nsCOMPtr<nsILoadGroup> mLoadGroup;
|
||||
nsCString mContentType;
|
||||
PRInt32 mContentLength;
|
||||
nsCOMPtr<nsISupports> mOwner;
|
||||
PRUint32 mBufferSegmentSize;
|
||||
PRUint32 mBufferMaxSize;
|
||||
PRBool mActAsObserver;
|
||||
|
||||
PRInt32 mPort;
|
||||
nsCString mHost;
|
||||
nsCString mUser;
|
||||
|
||||
nsXPIDLCString mRequest;
|
||||
|
||||
nsCOMPtr<nsISupports> mResponseContext;
|
||||
nsCOMPtr<nsITransport> mTransport;
|
||||
nsCOMPtr<nsIRequest> mTransportRequest;
|
||||
nsresult mStatus;
|
||||
|
||||
protected:
|
||||
nsresult SendRequest(nsITransport* aTransport);
|
||||
};
|
||||
|
||||
#endif /* nsFingerChannel_h___ */
|
||||
@@ -1,117 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Brian Ryner.
|
||||
* Portions created by Brian Ryner are Copyright (C) 2000 Brian Ryner.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Brian Ryner <bryner@uiuc.edu>
|
||||
*/
|
||||
|
||||
#include "nspr.h"
|
||||
#include "nsFingerChannel.h"
|
||||
#include "nsFingerHandler.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIProgressEventSink.h"
|
||||
#include "nsNetCID.h"
|
||||
|
||||
static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsFingerHandler::nsFingerHandler() {
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
nsFingerHandler::~nsFingerHandler() {
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsFingerHandler, nsIProtocolHandler)
|
||||
|
||||
NS_METHOD
|
||||
nsFingerHandler::Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult) {
|
||||
|
||||
nsFingerHandler* ph = new nsFingerHandler();
|
||||
if (ph == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(ph);
|
||||
nsresult rv = ph->QueryInterface(aIID, aResult);
|
||||
NS_RELEASE(ph);
|
||||
return rv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIProtocolHandler methods:
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFingerHandler::GetScheme(char* *result) {
|
||||
*result = nsCRT::strdup("finger");
|
||||
if (!*result) return NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFingerHandler::GetDefaultPort(PRInt32 *result) {
|
||||
*result = FINGER_PORT;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFingerHandler::NewURI(const char *aSpec, nsIURI *aBaseURI,
|
||||
nsIURI **result) {
|
||||
nsresult rv;
|
||||
|
||||
// no concept of a relative finger url
|
||||
NS_ASSERTION(!aBaseURI, "base url passed into finger protocol handler");
|
||||
|
||||
nsIURI* url;
|
||||
rv = nsComponentManager::CreateInstance(kSimpleURICID, nsnull,
|
||||
NS_GET_IID(nsIURI),
|
||||
(void**)&url);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = url->SetSpec((char*)aSpec);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_RELEASE(url);
|
||||
return rv;
|
||||
}
|
||||
|
||||
*result = url;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFingerHandler::NewChannel(nsIURI* url, nsIChannel* *result)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsFingerChannel* channel;
|
||||
rv = nsFingerChannel::Create(nsnull, NS_GET_IID(nsIChannel), (void**)&channel);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = channel->Init(url);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_RELEASE(channel);
|
||||
return rv;
|
||||
}
|
||||
|
||||
*result = channel;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1,52 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Brian Ryner.
|
||||
* Portions created by Brian Ryner are Copyright (C) 2000 Brian Ryner.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Brian Ryner <bryner@uiuc.edu>
|
||||
*/
|
||||
|
||||
// The finger protocol handler creates "finger" URIs of the form
|
||||
// "finger:user@host" or "finger:host".
|
||||
|
||||
#ifndef nsFingerHandler_h___
|
||||
#define nsFingerHandler_h___
|
||||
|
||||
#include "nsIProtocolHandler.h"
|
||||
|
||||
#define FINGER_PORT 79
|
||||
|
||||
// {0x76d6d5d8-1dd2-11b2-b361-850ddf15ef07}
|
||||
#define NS_FINGERHANDLER_CID \
|
||||
{ 0x76d6d5d8, 0x1dd2, 0x11b2, \
|
||||
{0xb3, 0x61, 0x85, 0x0d, 0xdf, 0x15, 0xef, 0x07} }
|
||||
|
||||
class nsFingerHandler : public nsIProtocolHandler
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPROTOCOLHANDLER
|
||||
|
||||
// nsFingerHandler methods:
|
||||
nsFingerHandler();
|
||||
virtual ~nsFingerHandler();
|
||||
|
||||
// Define a Create method to be used with a factory:
|
||||
static NS_METHOD Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult);
|
||||
};
|
||||
|
||||
#endif /* nsFingerHandler_h___ */
|
||||
@@ -1,34 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Brian Ryner.
|
||||
* Portions created by Brian Ryner are Copyright (C) 2000 Brian Ryner.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Brian Ryner <bryner@uiuc.edu>
|
||||
*/
|
||||
|
||||
#include "nsIGenericFactory.h"
|
||||
#include "nsFingerHandler.h"
|
||||
|
||||
static nsModuleComponentInfo gResComponents[] = {
|
||||
{ "The Finger Protocol Handler",
|
||||
NS_FINGERHANDLER_CID,
|
||||
NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "finger",
|
||||
nsFingerHandler::Create
|
||||
}
|
||||
};
|
||||
|
||||
NS_IMPL_NSGETMODULE(finger, gResComponents)
|
||||
@@ -1,180 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIDOMDocument;
|
||||
interface nsIDOMEventListener;
|
||||
interface nsIHttpChannel;
|
||||
|
||||
[scriptable, uuid(b7215e70-4157-11d4-9a42-000064657374)]
|
||||
interface nsIXMLHttpRequest : nsISupports {
|
||||
/**
|
||||
* Meant to be a script-only mechanism for setting a load event listener.
|
||||
* The attribute is expected to be JavaScript function object. When
|
||||
* the load event occurs, the function is invoked.
|
||||
* This attribute should not be used from native code!!
|
||||
*/
|
||||
attribute nsISupports onload;
|
||||
|
||||
/**
|
||||
* Meant to be a script-only mechanism for setting an error event listener.
|
||||
* The attribute is expected to be JavaScript function object. When
|
||||
* the error event occurs, the function is invoked.
|
||||
* This attribute should not be used from native code!!
|
||||
*/
|
||||
attribute nsISupports onerror;
|
||||
|
||||
/**
|
||||
* The HTTP request uses an HTTP channel in order to perform the
|
||||
* request. This attribute represents the HTTP channel used
|
||||
* for the request. NULL if the HTTP channel has not yet been
|
||||
* created.
|
||||
*/
|
||||
readonly attribute nsIHttpChannel channel;
|
||||
|
||||
/**
|
||||
* The response to the HTTP request is parsed as if it were a
|
||||
* text/xml stream. This attributes represents the response as
|
||||
* a DOM Document object. NULL if the request is unsuccessful or
|
||||
* has not yet been sent.
|
||||
*/
|
||||
readonly attribute nsIDOMDocument responseXML;
|
||||
|
||||
/**
|
||||
* The response to the HTTP request as text.
|
||||
* NULL if the request is unsuccessful or
|
||||
* has not yet been sent.
|
||||
*/
|
||||
readonly attribute wstring responseText;
|
||||
|
||||
|
||||
/**
|
||||
* The status of the response to the HTTP request.
|
||||
*/
|
||||
readonly attribute unsigned long status;
|
||||
|
||||
/**
|
||||
* The string representing the status of the response to the
|
||||
* HTTP request.
|
||||
*/
|
||||
readonly attribute string statusText;
|
||||
|
||||
/**
|
||||
* If the HTTP request has been sent already, this method will
|
||||
* abort the request.
|
||||
*/
|
||||
void abort();
|
||||
|
||||
/**
|
||||
* Returns all of the HTTP response headers as a string string.
|
||||
*
|
||||
* @returns A string containing all of the response headers.
|
||||
* NULL if the response has not yet been received.
|
||||
*/
|
||||
string getAllResponseHeaders();
|
||||
|
||||
/**
|
||||
* Returns the text of the header with the specified name.
|
||||
*
|
||||
* @param header The name of the header to retrieve
|
||||
* @returns A string containing the text of the header specified.
|
||||
* NULL if the response has not yet been received or the
|
||||
* header does not exist in the response.
|
||||
*/
|
||||
string getResponseHeader(in string header);
|
||||
|
||||
/**
|
||||
* Native (non-script) method to initialize a request. Note that
|
||||
* the HTTP request is not sent until the <code>send</code> method
|
||||
* is invoked.
|
||||
*
|
||||
* @param method The HTTP method - either "POST" or "GET".
|
||||
* @param url The URL to which to send the request.
|
||||
* @param async Whether the request is synchronous or asynchronous
|
||||
* i.e. whether send returns only after the response
|
||||
* is received or if it returns immediately after
|
||||
* sending the request. In the latter case, notification
|
||||
* of completion is sent through the event listeners.
|
||||
* @param user A username for authentication if necessary.
|
||||
* @param password A password for authentication if necessary.
|
||||
*/
|
||||
[noscript] void openRequest(in string method,
|
||||
in string url,
|
||||
in boolean async,
|
||||
in string user,
|
||||
in string password);
|
||||
|
||||
/**
|
||||
* Meant to be a script-only method for initializing a request.
|
||||
* The parameters are similar to the ones detailed in the
|
||||
* description of <code>openRequest</code>, but the last
|
||||
* 3 are optional.
|
||||
*
|
||||
* @param method The HTTP method - either "POST" or "GET".
|
||||
* @param url The URL to which to send the request.
|
||||
* @param async (optional) Whether the request is synchronous or
|
||||
* asynchronous i.e. whether send returns only after
|
||||
* the response is received or if it returns immediately after
|
||||
* sending the request. In the latter case, notification
|
||||
* of completion is sent through the event listeners.
|
||||
* The default value is true.
|
||||
* @param user (optional) A username for authentication if necessary.
|
||||
* The default value is the empty string
|
||||
* @param password (optional) A password for authentication if necessary.
|
||||
* The default value is the empty string
|
||||
*/
|
||||
void open(in string method, in string url);
|
||||
|
||||
/**
|
||||
* Sends the HTTP request. If the request is asynchronous, returns
|
||||
* immediately after sending the request. If it is synchronous
|
||||
* returns only after the response has been received.
|
||||
*
|
||||
* @param body Either an instance of nsIDOMDocument, nsIInputStream
|
||||
* or a string (nsISupportsWString in the native calling
|
||||
* case). This is used to populate the body of the
|
||||
* HTTP request if the HTTP request method is "POST".
|
||||
* If the parameter is a nsIDOMDocument, it is serialized.
|
||||
* If the parameter is a nsIInputStream, it is expected
|
||||
* to contain the ContentType: and ContentLength: headers
|
||||
* and trailing carriage-return/line-feed pairs.
|
||||
*/
|
||||
void send(in nsISupports body);
|
||||
|
||||
/**
|
||||
* Sets a HTTP request header.
|
||||
*
|
||||
* @param header The name of the header to set in the request.
|
||||
* @param value The body of the header.
|
||||
*/
|
||||
void setRequestHeader(in string header, in string value);
|
||||
};
|
||||
|
||||
%{ C++
|
||||
#define NS_XMLHTTPREQUEST_CID \
|
||||
{ /* d164e770-4157-11d4-9a42-000064657374 */ \
|
||||
0xd164e770, 0x4157, 0x11d4, \
|
||||
{0x9a, 0x42, 0x00, 0x00, 0x64, 0x65, 0x73, 0x74} }
|
||||
#define NS_XMLHTTPREQUEST_CONTRACTID \
|
||||
"@mozilla.org/xmlextras/xmlhttprequest;1"
|
||||
%}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,244 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#ifndef nsXMLHttpRequest_h__
|
||||
#define nsXMLHttpRequest_h__
|
||||
|
||||
#define IMPLEMENT_SYNC_LOAD
|
||||
|
||||
#include "nsIXMLHttpRequest.h"
|
||||
#include "nsISupportsUtils.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIDOMLoadListener.h"
|
||||
#include "nsIDOMEventTarget.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsISecurityCheckedComponent.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#ifdef IMPLEMENT_SYNC_LOAD
|
||||
#include "nsIWebBrowserChrome.h"
|
||||
#endif
|
||||
#include "nsWeakReference.h"
|
||||
#include "nsISupportsArray.h"
|
||||
#include "jsapi.h"
|
||||
|
||||
enum {
|
||||
XML_HTTP_REQUEST_INITIALIZED,
|
||||
XML_HTTP_REQUEST_OPENED,
|
||||
XML_HTTP_REQUEST_SENT,
|
||||
XML_HTTP_REQUEST_COMPLETED,
|
||||
XML_HTTP_REQUEST_ABORTED
|
||||
};
|
||||
|
||||
class nsXMLHttpRequest : public nsIXMLHttpRequest,
|
||||
public nsIDOMLoadListener,
|
||||
public nsIDOMEventTarget,
|
||||
public nsISecurityCheckedComponent,
|
||||
public nsIStreamListener,
|
||||
public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
nsXMLHttpRequest();
|
||||
virtual ~nsXMLHttpRequest();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIXMLHttpRequest
|
||||
NS_DECL_NSIXMLHTTPREQUEST
|
||||
|
||||
// nsIDOMEventTarget
|
||||
NS_DECL_NSIDOMEVENTTARGET
|
||||
|
||||
// nsIDOMEventListener
|
||||
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
|
||||
|
||||
// nsIDOMLoadListener
|
||||
NS_IMETHOD Load(nsIDOMEvent* aEvent);
|
||||
NS_IMETHOD Unload(nsIDOMEvent* aEvent);
|
||||
NS_IMETHOD Abort(nsIDOMEvent* aEvent);
|
||||
NS_IMETHOD Error(nsIDOMEvent* aEvent);
|
||||
|
||||
// nsISecurityCheckedComponent
|
||||
NS_DECL_NSISECURITYCHECKEDCOMPONENT
|
||||
|
||||
// nsIStreamListener
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
|
||||
// nsIRequestObserver
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
|
||||
protected:
|
||||
nsresult MakeScriptEventListener(nsISupports* aObject,
|
||||
nsIDOMEventListener** aListener);
|
||||
void GetScriptEventListener(nsISupportsArray* aList,
|
||||
nsIDOMEventListener** aListener);
|
||||
PRBool StuffReturnValue(nsIDOMEventListener* aListener);
|
||||
|
||||
|
||||
nsresult GetStreamForWString(const PRUnichar* aStr,
|
||||
PRInt32 aLength,
|
||||
nsIInputStream** aStream);
|
||||
|
||||
nsCOMPtr<nsISupports> mContext;
|
||||
nsCOMPtr<nsIHttpChannel> mChannel;
|
||||
nsCOMPtr<nsIRequest> mReadRequest;
|
||||
nsCOMPtr<nsIDOMDocument> mDocument;
|
||||
nsCOMPtr<nsIURI> mBaseURI;
|
||||
nsCOMPtr<nsIDocument> mBaseDocument;
|
||||
#ifdef IMPLEMENT_SYNC_LOAD
|
||||
nsCOMPtr<nsIWebBrowserChrome> mChromeWindow;
|
||||
#endif
|
||||
nsCOMPtr<nsISupportsArray> mLoadEventListeners;
|
||||
nsCOMPtr<nsISupportsArray> mErrorEventListeners;
|
||||
|
||||
nsresult DetectCharset(nsAWritableString& aCharset);
|
||||
nsresult ConvertBodyToText(PRUnichar **aOutBuffer);
|
||||
static NS_METHOD StreamReaderFunc(nsIInputStream* in,
|
||||
void* closure,
|
||||
const char* fromRawSegment,
|
||||
PRUint32 toOffset,
|
||||
PRUint32 count,
|
||||
PRUint32 *writeCount);
|
||||
|
||||
// used to implement getAllResponseHeaders()
|
||||
class nsHeaderVisitor : public nsIHttpHeaderVisitor {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIHTTPHEADERVISITOR
|
||||
nsHeaderVisitor() { NS_INIT_ISUPPORTS(); }
|
||||
virtual ~nsHeaderVisitor() {}
|
||||
const nsACString &Headers() { return mHeaders; }
|
||||
private:
|
||||
nsCString mHeaders;
|
||||
};
|
||||
|
||||
#if 1 // When nsCString::Append()/Length() works for strings that contain nulls, remove this buffer impl
|
||||
class ResponseBodyBuffer {
|
||||
public:
|
||||
ResponseBodyBuffer()
|
||||
: mBuffer(0),
|
||||
mBufferSize(0),
|
||||
mBufferFreeIndex(0),
|
||||
mCanBeString(PR_FALSE),
|
||||
mBufferChecked(PR_FALSE) {}
|
||||
~ResponseBodyBuffer() { nsMemory::Free(mBuffer); }
|
||||
void Truncate(void) {
|
||||
nsMemory::Free(mBuffer);
|
||||
mBuffer=nsnull;
|
||||
mBufferSize=mBufferFreeIndex=0;
|
||||
mCanBeString = PR_FALSE;
|
||||
mBufferChecked = PR_FALSE;
|
||||
}
|
||||
nsresult Append(const char* aBuffer, PRUint32 aBufferLen) {
|
||||
if (aBufferLen > (mBufferSize-mBufferFreeIndex)) {
|
||||
PRUint32 newBufferSize = (mBufferSize > aBufferLen ? mBufferSize : aBufferLen)<<1;
|
||||
char * newBuffer = NS_STATIC_CAST(char*,nsMemory::Realloc(mBuffer,newBufferSize));
|
||||
if (!newBuffer) {
|
||||
nsMemory::Free(mBuffer);
|
||||
mBuffer = nsnull;
|
||||
mBufferChecked = PR_FALSE;
|
||||
mCanBeString = PR_FALSE;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
mBuffer = newBuffer;
|
||||
mBufferSize = newBufferSize;
|
||||
}
|
||||
memcpy(&mBuffer[mBufferFreeIndex],aBuffer,aBufferLen);
|
||||
mBufferFreeIndex += aBufferLen;
|
||||
mBufferChecked = PR_FALSE;
|
||||
mCanBeString = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
const char * GetBuffer(void) { return mBuffer; }
|
||||
PRUint32 GetBufferLength(void) { return mBufferFreeIndex; }
|
||||
PRBool CanBeString(void) {
|
||||
if (!mBufferFreeIndex)
|
||||
return PR_TRUE; // Perhaps this is a bit questionable...
|
||||
if (!mBufferChecked) {
|
||||
mBufferChecked = PR_TRUE;
|
||||
|
||||
mCanBeString = PR_TRUE;
|
||||
|
||||
PRUint32 i;
|
||||
for (i = 0; i < mBufferFreeIndex; i++) {
|
||||
if (!mBuffer[i]) {
|
||||
mCanBeString = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return mCanBeString;
|
||||
}
|
||||
private:
|
||||
char *mBuffer;
|
||||
PRUint32 mBufferSize;
|
||||
PRUint32 mBufferFreeIndex;
|
||||
PRPackedBool mCanBeString;
|
||||
PRPackedBool mBufferChecked;
|
||||
};
|
||||
ResponseBodyBuffer mResponseBody;
|
||||
#else
|
||||
nsCString mResponseBody;
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIStreamListener> mXMLParserStreamListener;
|
||||
|
||||
PRInt32 mStatus;
|
||||
PRBool mAsync;
|
||||
};
|
||||
|
||||
#define NS_IPRIVATEJSEVENTLISTENER_IID \
|
||||
{ /* d47a6550-4327-11d4-9a45-000064657374 */ \
|
||||
0xd47a6550, 0x4327, 0x11d4, \
|
||||
{0x9a, 0x45, 0x00, 0x00, 0x64, 0x65, 0x73, 0x74} }
|
||||
|
||||
class nsIPrivateJSEventListener : public nsISupports {
|
||||
public:
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IPRIVATEJSEVENTLISTENER_IID)
|
||||
|
||||
NS_IMETHOD GetFunctionObj(JSObject** aObj) = 0;
|
||||
};
|
||||
|
||||
class nsXMLHttpRequestScriptListener : public nsIDOMEventListener,
|
||||
public nsIPrivateJSEventListener
|
||||
{
|
||||
public:
|
||||
nsXMLHttpRequestScriptListener(JSObject* aScopeObj, JSObject* aFunctionObj);
|
||||
virtual ~nsXMLHttpRequestScriptListener();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIDOMEventListener
|
||||
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
|
||||
|
||||
// nsIPrivateJSEventListener
|
||||
NS_IMETHOD GetFunctionObj(JSObject** aObj);
|
||||
|
||||
protected:
|
||||
JSObject* mScopeObj;
|
||||
JSObject* mFunctionObj;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,907 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#include "libimg.h"
|
||||
#include "nsImageNet.h"
|
||||
#include "ilINetContext.h"
|
||||
#include "ilIURL.h"
|
||||
#include "ilINetReader.h"
|
||||
#include "ilErrors.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsILoadGroup.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsWeakPtr.h"
|
||||
#include "prprf.h"
|
||||
|
||||
|
||||
#include "nsITimer.h"
|
||||
#include "nsVoidArray.h"
|
||||
#include "nsString.h"
|
||||
#include "prmem.h"
|
||||
#include "plstr.h"
|
||||
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
#include "nsCURILoader.h"
|
||||
#include "nsIURIContentListener.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
#include "nsIStreamConverterService.h"
|
||||
#include "nsIPref.h"
|
||||
|
||||
static NS_DEFINE_CID(kStreamConvServiceCID, NS_STREAMCONVERTERSERVICE_CID);
|
||||
static NS_DEFINE_IID(kIURLIID, NS_IURL_IID);
|
||||
static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
|
||||
|
||||
PRLogModuleInfo *image_net_context_async_log_module = NULL;
|
||||
|
||||
#define IMAGE_BUF_SIZE 4096
|
||||
|
||||
class ImageConsumer;
|
||||
|
||||
class ImageNetContextImpl : public ilINetContext {
|
||||
public:
|
||||
ImageNetContextImpl(ImgCachePolicy aReloadPolicy,
|
||||
nsISupports * aLoadContext,
|
||||
nsReconnectCB aReconnectCallback,
|
||||
void* aReconnectArg);
|
||||
virtual ~ImageNetContextImpl();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
virtual ilINetContext* Clone();
|
||||
|
||||
virtual ImgCachePolicy GetReloadPolicy();
|
||||
virtual ImgCachePolicy SetReloadPolicy(ImgCachePolicy ReloadPolicy);
|
||||
|
||||
|
||||
virtual void AddReferer(ilIURL *aUrl);
|
||||
|
||||
virtual void Interrupt();
|
||||
|
||||
virtual ilIURL* CreateURL(const char *aUrl,
|
||||
ImgCachePolicy aReloadMethod);
|
||||
|
||||
virtual PRBool IsLocalFileURL(char *aAddress);
|
||||
#ifdef NU_CACHE
|
||||
virtual PRBool IsURLInCache(ilIURL *aUrl);
|
||||
#else /* NU_CACHE */
|
||||
virtual PRBool IsURLInMemCache(ilIURL *aUrl);
|
||||
|
||||
virtual PRBool IsURLInDiskCache(ilIURL *aUrl);
|
||||
#endif
|
||||
|
||||
virtual int GetURL (ilIURL * aUrl, ImgCachePolicy aLoadMethod,
|
||||
ilINetReader *aReader, PRBool IsAnimationLoop);
|
||||
|
||||
virtual int GetContentLength(ilIURL * aURL);
|
||||
|
||||
nsresult RemoveRequest(ImageConsumer *aConsumer);
|
||||
nsresult RequestDone(ImageConsumer *aConsumer, nsIRequest* request,
|
||||
nsISupports* ctxt, nsresult status, const PRUnichar* aMsg);
|
||||
|
||||
nsVoidArray *mRequests; // WEAK references to |ImageConsumer|s
|
||||
ImgCachePolicy mReloadPolicy;
|
||||
nsWeakPtr mLoadContext;
|
||||
nsReconnectCB mReconnectCallback;
|
||||
void* mReconnectArg;
|
||||
};
|
||||
|
||||
class ImageConsumer : public nsIStreamListener, public nsIURIContentListener, public nsIInterfaceRequestor
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
ImageConsumer(ilIURL *aURL, ImageNetContextImpl *aContext);
|
||||
|
||||
// nsIRequestObserver methods:
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
NS_DECL_NSIURICONTENTLISTENER
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
|
||||
void SetKeepPumpingData(nsIRequest* request, nsISupports* context) {
|
||||
NS_ADDREF(request);
|
||||
NS_IF_RELEASE(mRequest);
|
||||
mRequest = request;
|
||||
|
||||
NS_IF_ADDREF(context);
|
||||
NS_IF_RELEASE(mUserContext);
|
||||
mUserContext = context;
|
||||
}
|
||||
|
||||
void Interrupt();
|
||||
|
||||
static void KeepPumpingStream(nsITimer *aTimer, void *aClosure);
|
||||
|
||||
protected:
|
||||
virtual ~ImageConsumer();
|
||||
ilIURL *mURL;
|
||||
PRBool mInterrupted;
|
||||
ImageNetContextImpl *mContext;
|
||||
nsIInputStream *mStream;
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
PRBool mFirstRead;
|
||||
char *mBuffer;
|
||||
PRInt32 mStatus;
|
||||
nsIRequest* mRequest;
|
||||
nsISupports* mUserContext;
|
||||
PRBool mIsMulti;
|
||||
};
|
||||
|
||||
ImageConsumer::ImageConsumer(ilIURL *aURL, ImageNetContextImpl *aContext)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mURL = aURL;
|
||||
NS_ADDREF(mURL);
|
||||
mContext = aContext;
|
||||
NS_ADDREF(mContext);
|
||||
mInterrupted = PR_FALSE;
|
||||
mFirstRead = PR_TRUE;
|
||||
mStream = nsnull;
|
||||
mBuffer = nsnull;
|
||||
mStatus = 0;
|
||||
mRequest = nsnull;
|
||||
mUserContext = nsnull;
|
||||
mIsMulti = PR_FALSE;
|
||||
}
|
||||
|
||||
NS_IMPL_THREADSAFE_ADDREF(ImageConsumer)
|
||||
NS_IMPL_THREADSAFE_RELEASE(ImageConsumer)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(ImageConsumer)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIURIContentListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIURIContentListener)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMETHODIMP ImageConsumer::GetInterface(const nsIID & aIID, void * *aInstancePtr)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aInstancePtr);
|
||||
return QueryInterface(aIID, aInstancePtr);
|
||||
}
|
||||
|
||||
// nsIURIContentListener support
|
||||
|
||||
NS_IMETHODIMP
|
||||
ImageConsumer::OnStartURIOpen(nsIURI* aURI,
|
||||
const char* aWindowTarget, PRBool* aAbortOpen)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ImageConsumer::GetProtocolHandler(nsIURI *aURI, nsIProtocolHandler **aProtocolHandler)
|
||||
{
|
||||
*aProtocolHandler = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ImageConsumer::GetParentContentListener(nsIURIContentListener** aParent)
|
||||
{
|
||||
*aParent = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ImageConsumer::SetParentContentListener(nsIURIContentListener* aParent)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ImageConsumer::GetLoadCookie(nsISupports ** aLoadCookie)
|
||||
{
|
||||
nsCOMPtr<nsISupports> loadContext = do_QueryReferent(mContext->mLoadContext);
|
||||
*aLoadCookie = loadContext;
|
||||
NS_IF_ADDREF(*aLoadCookie);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ImageConsumer::SetLoadCookie(nsISupports * aLoadCookie)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ImageConsumer::IsPreferred(const char * aContentType,
|
||||
nsURILoadCommand aCommand,
|
||||
const char * aWindowTarget,
|
||||
char ** aDesiredContentType,
|
||||
PRBool * aCanHandleContent)
|
||||
|
||||
{
|
||||
return CanHandleContent(aContentType, aCommand, aWindowTarget,
|
||||
aDesiredContentType, aCanHandleContent);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ImageConsumer::CanHandleContent(const char * aContentType,
|
||||
nsURILoadCommand aCommand,
|
||||
const char * aWindowTarget,
|
||||
char ** aDesiredContentType,
|
||||
PRBool * aCanHandleContent)
|
||||
|
||||
{
|
||||
// if we had a webshell or doc shell around, we'd pass this call
|
||||
// through to it...but we don't =(
|
||||
if (!nsCRT::strcasecmp(aContentType, "message/rfc822"))
|
||||
*aDesiredContentType = nsCRT::strdup("application/vnd.mozilla.xul+xml");
|
||||
// since we explicilty loaded the url, we always want to handle it!
|
||||
*aCanHandleContent = PR_TRUE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ImageConsumer::DoContent(const char * aContentType,
|
||||
nsURILoadCommand aCommand,
|
||||
const char * aWindowTarget,
|
||||
nsIRequest * aOpenedChannel,
|
||||
nsIStreamListener ** aContentHandler,
|
||||
PRBool * aAbortProcess)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (aAbortProcess)
|
||||
*aAbortProcess = PR_FALSE;
|
||||
|
||||
nsAutoString contentType; contentType.AssignWithConversion(aContentType);
|
||||
|
||||
if (contentType.EqualsWithConversion("multipart/x-mixed-replace")
|
||||
|| contentType.EqualsWithConversion("multipart/mixed")) {
|
||||
// if we're getting multipart data, we have to convert it.
|
||||
// so wedge the converter inbetween us and the consumer.
|
||||
mIsMulti= PR_TRUE;
|
||||
|
||||
nsCOMPtr<nsIStreamConverterService> convServ = do_GetService(kStreamConvServiceCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsAutoString astrix; astrix.AssignWithConversion("*/*");
|
||||
return convServ->AsyncConvertData(contentType.GetUnicode(),
|
||||
astrix.GetUnicode(),
|
||||
NS_STATIC_CAST(nsIStreamListener*, this),
|
||||
nsnull /*a context?*/, aContentHandler);
|
||||
}
|
||||
|
||||
QueryInterface(NS_GET_IID(nsIStreamListener), (void **) aContentHandler);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
ImageConsumer::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
|
||||
{
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
|
||||
|
||||
PRUint32 httpStatus;
|
||||
if (mInterrupted) {
|
||||
mStatus = MK_INTERRUPTED;
|
||||
return NS_ERROR_ABORT;
|
||||
}
|
||||
|
||||
mBuffer = (char *)PR_MALLOC(IMAGE_BUF_SIZE);
|
||||
if (mBuffer == nsnull) {
|
||||
mStatus = MK_IMAGE_LOSSAGE;
|
||||
return NS_ERROR_ABORT;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIHttpChannel> pHTTPCon(do_QueryInterface(channel));
|
||||
if (pHTTPCon) {
|
||||
pHTTPCon->GetResponseStatus(&httpStatus);
|
||||
if (httpStatus == 404) {
|
||||
mStatus = MK_IMAGE_LOSSAGE;
|
||||
return NS_ERROR_ABORT;
|
||||
}
|
||||
}
|
||||
|
||||
ilINetReader *reader = mURL->GetReader(); //ptn test: nsCOMPtr??
|
||||
/*nsresult err=*/ reader->FlushImgBuffer(); //flush current data in buffer before starting
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
char* aContentType = NULL;
|
||||
rv = channel->GetContentType(&aContentType); //nsCRT alloc's str
|
||||
if (NS_FAILED(rv)) {
|
||||
if(aContentType){
|
||||
nsCRT::free(aContentType);
|
||||
}
|
||||
aContentType = nsCRT::strdup("unknown");
|
||||
}
|
||||
if(nsCRT::strlen(aContentType) > 50){
|
||||
//somethings wrong. mimetype string shouldn't be this big.
|
||||
//protect us from the user.
|
||||
nsCRT::free(aContentType);
|
||||
aContentType = nsCRT::strdup("unknown");
|
||||
}
|
||||
|
||||
if (reader->StreamCreated(mURL, aContentType) != PR_TRUE) {
|
||||
mStatus = MK_IMAGE_LOSSAGE;
|
||||
reader->StreamAbort(mStatus);
|
||||
NS_RELEASE(reader);
|
||||
nsCRT::free(aContentType);
|
||||
return NS_ERROR_ABORT;
|
||||
}
|
||||
nsCRT::free(aContentType);
|
||||
NS_RELEASE(reader);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#define IMAGE_BUF_SIZE 4096
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
ImageConsumer::OnDataAvailable(nsIRequest* request, nsISupports* aContext,
|
||||
nsIInputStream *pIStream, PRUint32 offset, PRUint32 length)
|
||||
{
|
||||
PRUint32 max_read=0;
|
||||
PRUint32 bytes_read = 0;
|
||||
ilINetReader *reader = mURL->GetReader();
|
||||
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
|
||||
|
||||
if (mInterrupted || mStatus != 0) {
|
||||
mStatus = MK_INTERRUPTED;
|
||||
reader->StreamAbort(mStatus);
|
||||
NS_RELEASE(reader);
|
||||
return NS_ERROR_ABORT;
|
||||
}
|
||||
|
||||
nsresult err = 0;
|
||||
PRUint32 nb = 0;
|
||||
char* uriStr = NULL;
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
|
||||
err = channel->GetURI(getter_AddRefs(uri));
|
||||
if (NS_SUCCEEDED(err) && uri) {
|
||||
err = uri->GetSpec(&uriStr);
|
||||
if (NS_FAILED(err)){
|
||||
/* if we can't get a file spec, it is bad, very bad.*/
|
||||
mStatus = MK_INTERRUPTED;
|
||||
reader->StreamAbort(mStatus);
|
||||
NS_RELEASE(reader);
|
||||
return NS_ERROR_ABORT;
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
err = reader->WriteReady(&max_read); //max read is most decoder can handle
|
||||
if(NS_FAILED(err)) //note length tells how much we already have.
|
||||
break;
|
||||
|
||||
if(max_read < 0){
|
||||
max_read = 128;
|
||||
}
|
||||
|
||||
if (max_read > (length - bytes_read)) {
|
||||
max_read = length - bytes_read;
|
||||
}
|
||||
|
||||
if (max_read > IMAGE_BUF_SIZE) {
|
||||
max_read = IMAGE_BUF_SIZE;
|
||||
}
|
||||
|
||||
// make sure there's enough data available to decode the image.
|
||||
// put test into WriteReady
|
||||
if (mFirstRead && length < 4)
|
||||
break;
|
||||
|
||||
err = pIStream->Read(mBuffer,
|
||||
max_read, &nb);
|
||||
|
||||
if (err == NS_BASE_STREAM_WOULD_BLOCK) {
|
||||
NS_ASSERTION(nb == 0, "Data will be lost.");
|
||||
err = NS_OK;
|
||||
break;
|
||||
}
|
||||
if (NS_FAILED(err) || nb == 0) {
|
||||
NS_ASSERTION(nb == 0, "Data will be lost.");
|
||||
break;
|
||||
}
|
||||
|
||||
bytes_read += nb;
|
||||
if (mFirstRead == PR_TRUE) {
|
||||
|
||||
err = reader->FirstWrite((const unsigned char *)mBuffer, nb, uriStr);
|
||||
mFirstRead = PR_FALSE; //? move after err chk?
|
||||
/*
|
||||
* If FirstWrite(...) fails then the image type
|
||||
* cannot be determined and the il_container
|
||||
* stream functions have not been initialized!
|
||||
*/
|
||||
if (NS_FAILED(err)) {
|
||||
mStatus = MK_IMAGE_LOSSAGE;
|
||||
mInterrupted = PR_TRUE;
|
||||
if(uriStr)
|
||||
nsCRT::free(uriStr);
|
||||
NS_RELEASE(reader);
|
||||
return NS_ERROR_ABORT;
|
||||
}
|
||||
}
|
||||
|
||||
err = reader->Write((const unsigned char *)mBuffer, (int32)nb);
|
||||
if(NS_FAILED(err)){
|
||||
mStatus = MK_IMAGE_LOSSAGE;
|
||||
mInterrupted = PR_TRUE;
|
||||
if(uriStr)
|
||||
nsCRT::free(uriStr);
|
||||
NS_RELEASE(reader);
|
||||
return NS_ERROR_ABORT;
|
||||
}
|
||||
} while(bytes_read < length);
|
||||
|
||||
if (uriStr) {
|
||||
nsCRT::free(uriStr);
|
||||
}
|
||||
|
||||
if (NS_FAILED(err)) {
|
||||
mStatus = MK_IMAGE_LOSSAGE;
|
||||
mInterrupted = PR_TRUE;
|
||||
}
|
||||
|
||||
if (bytes_read < length) {
|
||||
// If we haven't emptied the stream, hold onto it, because
|
||||
// we will need to read from it subsequently and we don't
|
||||
// know if we'll get a OnDataAvailable call again.
|
||||
//
|
||||
// Addref the new stream before releasing the old one,
|
||||
// in case it is the same stream!
|
||||
NS_ADDREF(pIStream);
|
||||
NS_IF_RELEASE(mStream);
|
||||
mStream = pIStream;
|
||||
} else {
|
||||
NS_IF_RELEASE(mStream);
|
||||
}
|
||||
NS_RELEASE(reader);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
ImageConsumer::KeepPumpingStream(nsITimer *aTimer, void *aClosure)
|
||||
{
|
||||
ImageConsumer *consumer = (ImageConsumer *)aClosure;
|
||||
|
||||
consumer->OnStopRequest(consumer->mRequest, consumer->mUserContext,
|
||||
NS_BINDING_SUCCEEDED);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ImageConsumer::OnStopRequest(nsIRequest* request, nsISupports* aContext, nsresult status)
|
||||
{
|
||||
if (mTimer) {
|
||||
mTimer->Cancel();
|
||||
mTimer = nsnull;
|
||||
}
|
||||
|
||||
if (NS_BINDING_SUCCEEDED != status) {
|
||||
mStatus = MK_INTERRUPTED;
|
||||
}
|
||||
|
||||
|
||||
// Since we're still holding on to the stream, there's still data
|
||||
// that needs to be read. So, pump the stream ourselves.
|
||||
if((mStream != nsnull) && (status == NS_BINDING_SUCCEEDED)) {
|
||||
PRUint32 str_length;
|
||||
nsresult err = mStream->Available(&str_length);
|
||||
if (NS_SUCCEEDED(err)) {
|
||||
NS_ASSERTION((str_length > 0), "No data left in the stream!");
|
||||
err = OnDataAvailable(request, aContext, mStream, 0, str_length); // XXX fix offset
|
||||
if (NS_SUCCEEDED(err)) {
|
||||
// If we still have the stream, there's still data to be
|
||||
// pumped, so we set a timer to call us back again.
|
||||
if (mStream) {
|
||||
SetKeepPumpingData(request, aContext);
|
||||
|
||||
nsresult rv;
|
||||
mTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
|
||||
if (NS_FAILED(rv) ||
|
||||
(NS_OK != mTimer->Init(ImageConsumer::KeepPumpingStream, this, 0))) {
|
||||
mStatus = MK_IMAGE_LOSSAGE;
|
||||
NS_RELEASE(mStream);
|
||||
}
|
||||
else {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
mStatus = MK_IMAGE_LOSSAGE;
|
||||
NS_IF_RELEASE(mStream);
|
||||
}
|
||||
}
|
||||
else {
|
||||
mStatus = MK_IMAGE_LOSSAGE;
|
||||
NS_IF_RELEASE(mStream);
|
||||
}
|
||||
}
|
||||
|
||||
ilINetReader *reader = mURL->GetReader();
|
||||
if (0 != mStatus) {
|
||||
reader->StreamAbort(mStatus);
|
||||
}
|
||||
else {
|
||||
reader->StreamComplete(mIsMulti);
|
||||
}
|
||||
|
||||
if(mIsMulti)
|
||||
mFirstRead = PR_TRUE; //reset to read new frame
|
||||
|
||||
reader->NetRequestDone(mURL, mStatus);
|
||||
NS_RELEASE(reader);
|
||||
|
||||
return mContext->RequestDone(this, request, aContext, status, nsnull);
|
||||
}
|
||||
|
||||
void
|
||||
ImageConsumer::Interrupt()
|
||||
{
|
||||
mInterrupted = PR_TRUE;
|
||||
}
|
||||
|
||||
ImageConsumer::~ImageConsumer()
|
||||
{
|
||||
if (mTimer) {
|
||||
mTimer->Cancel();
|
||||
mTimer = nsnull;
|
||||
}
|
||||
if (mContext) {
|
||||
nsresult res = mContext->RemoveRequest(this);
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
// The load was canceled.
|
||||
mStatus = MK_INTERRUPTED;
|
||||
if (mURL) {
|
||||
nsCOMPtr<ilINetReader> reader( dont_AddRef( mURL->GetReader() ) );
|
||||
reader->StreamAbort(mStatus);
|
||||
reader->NetRequestDone(mURL, mStatus);
|
||||
}
|
||||
}
|
||||
NS_RELEASE(mContext);
|
||||
}
|
||||
NS_IF_RELEASE(mURL);
|
||||
NS_IF_RELEASE(mStream);
|
||||
if (mBuffer != nsnull) {
|
||||
PR_DELETE(mBuffer);
|
||||
}
|
||||
NS_IF_RELEASE(mRequest);
|
||||
NS_IF_RELEASE(mUserContext);
|
||||
}
|
||||
|
||||
ImageNetContextImpl::ImageNetContextImpl(ImgCachePolicy aReloadPolicy,
|
||||
nsISupports * aLoadContext,
|
||||
nsReconnectCB aReconnectCallback,
|
||||
void* aReconnectArg)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mRequests = nsnull;
|
||||
mLoadContext = getter_AddRefs(NS_GetWeakReference(aLoadContext));
|
||||
mReloadPolicy = aReloadPolicy;
|
||||
mReconnectCallback = aReconnectCallback;
|
||||
mReconnectArg = aReconnectArg;
|
||||
}
|
||||
|
||||
ImageNetContextImpl::~ImageNetContextImpl()
|
||||
{
|
||||
delete mRequests;
|
||||
}
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(ImageNetContextImpl, ilINetContext)
|
||||
|
||||
ilINetContext*
|
||||
ImageNetContextImpl::Clone()
|
||||
{
|
||||
ilINetContext *cx;
|
||||
nsCOMPtr<nsISupports> loadContext = do_QueryReferent(mLoadContext);
|
||||
|
||||
//mReconnectArg is ImageGroup. If GetURL is triggered
|
||||
//by timer for animation, ImageGroup may have been unloaded
|
||||
//before timer kicks off.
|
||||
//mReconnectCallback=nsnull; mReconnectArg=nsnull;
|
||||
|
||||
if (NS_NewImageNetContext(&cx, loadContext, mReconnectCallback, mReconnectArg) == NS_OK)
|
||||
{
|
||||
return cx;
|
||||
}
|
||||
else {
|
||||
return nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
ImgCachePolicy
|
||||
ImageNetContextImpl::GetReloadPolicy()
|
||||
{
|
||||
return mReloadPolicy;
|
||||
}
|
||||
|
||||
ImgCachePolicy
|
||||
ImageNetContextImpl::SetReloadPolicy(ImgCachePolicy reloadpolicy)
|
||||
{
|
||||
mReloadPolicy=reloadpolicy;
|
||||
return mReloadPolicy;
|
||||
}
|
||||
|
||||
void
|
||||
ImageNetContextImpl::AddReferer(ilIURL *aUrl)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ImageNetContextImpl::Interrupt()
|
||||
{
|
||||
if (mRequests != nsnull) {
|
||||
int i, count = mRequests->Count();
|
||||
for (i=0; i < count; i++) {
|
||||
ImageConsumer *ic = (ImageConsumer *)mRequests->ElementAt(i);
|
||||
ic->Interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ilIURL*
|
||||
ImageNetContextImpl::CreateURL(const char *aURL,
|
||||
ImgCachePolicy aReloadMethod)
|
||||
{
|
||||
ilIURL *url;
|
||||
|
||||
nsCOMPtr<nsISupports> loadContext (do_QueryReferent(mLoadContext));
|
||||
nsCOMPtr<nsILoadGroup> group (do_GetInterface(loadContext));
|
||||
if (NS_NewImageURL(&url, aURL, group) == NS_OK)
|
||||
{
|
||||
return url;
|
||||
}
|
||||
else {
|
||||
return nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
ImageNetContextImpl::IsLocalFileURL(char *aAddress)
|
||||
{
|
||||
if (PL_strncasecmp(aAddress, "file:", 5) == 0) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
else {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef NU_CACHE
|
||||
PRBool
|
||||
ImageNetContextImpl::IsURLInCache(ilIURL *aUrl)
|
||||
{
|
||||
return PR_TRUE;
|
||||
}
|
||||
#else /* NU_CACHE */
|
||||
PRBool
|
||||
ImageNetContextImpl::IsURLInMemCache(ilIURL *aUrl)
|
||||
{
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
ImageNetContextImpl::IsURLInDiskCache(ilIURL *aUrl)
|
||||
{
|
||||
return PR_TRUE;
|
||||
}
|
||||
#endif /* NU_CACHE */
|
||||
|
||||
int
|
||||
ImageNetContextImpl::GetContentLength (ilIURL * aURL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ImageNetContextImpl::GetURL (ilIURL * aURL,
|
||||
ImgCachePolicy aLoadMethod,
|
||||
ilINetReader *aReader,
|
||||
PRBool IsAnimationLoop)
|
||||
{
|
||||
|
||||
|
||||
NS_PRECONDITION(nsnull != aURL, "null URL");
|
||||
NS_PRECONDITION(nsnull != aReader, "null reader");
|
||||
if (aURL == nsnull || aReader == nsnull) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mRequests == nsnull) {
|
||||
mRequests = new nsVoidArray();
|
||||
if (mRequests == nsnull) {
|
||||
// XXX Should still call exit function
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int ret;
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIURI> nsurl = do_QueryInterface(aURL, &rv);
|
||||
if (NS_FAILED(rv)) return 0;
|
||||
|
||||
aURL->SetReader(aReader);
|
||||
SetReloadPolicy(aLoadMethod);
|
||||
|
||||
|
||||
// Find previously created ImageConsumer if possible
|
||||
ImageConsumer *ic = new ImageConsumer(aURL, this);
|
||||
if (ic == nsnull)
|
||||
return -1;
|
||||
NS_ADDREF(ic);
|
||||
|
||||
// See if a reconnect is being done...(XXX: hack!)
|
||||
if (mReconnectCallback == nsnull
|
||||
|| !(*mReconnectCallback)(mReconnectArg, ic)) {
|
||||
// first, create a channel for the protocol....
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
nsCOMPtr<nsISupports> loadContext (do_QueryReferent(mLoadContext));
|
||||
nsCOMPtr<nsILoadGroup> group (do_GetInterface(loadContext));
|
||||
nsCOMPtr<nsIInterfaceRequestor> sink(do_QueryInterface(loadContext));
|
||||
|
||||
nsLoadFlags flags=0;
|
||||
if(IsAnimationLoop)
|
||||
flags |= nsIRequest::LOAD_FROM_CACHE;
|
||||
|
||||
rv = NS_OpenURI(getter_AddRefs(channel), nsurl, nsnull, group, sink, flags);
|
||||
if (NS_FAILED(rv)) goto error;
|
||||
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(channel);
|
||||
if (httpChannel)
|
||||
{
|
||||
// Get the defloadRequest from the loadgroup-
|
||||
nsCOMPtr<nsIRequest> defLoadRequest;
|
||||
if (NS_SUCCEEDED(group->GetDefaultLoadRequest(
|
||||
getter_AddRefs(defLoadRequest))) && defLoadRequest)
|
||||
{
|
||||
nsCOMPtr<nsIChannel> reqchannel = do_QueryInterface(defLoadRequest);
|
||||
|
||||
// Get the referrer from the loadchannel-
|
||||
nsCOMPtr<nsIURI> referrer;
|
||||
if (NS_SUCCEEDED(reqchannel->GetURI(getter_AddRefs(referrer))))
|
||||
{
|
||||
// Set the referrer-
|
||||
httpChannel->SetReferrer(referrer, nsIHttpChannel::REFERRER_INLINES);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
rv = channel->GetLoadFlags(&flags);
|
||||
if (NS_FAILED(rv)) goto error;
|
||||
|
||||
if (aURL->GetBackgroundLoad())
|
||||
flags |= nsIRequest::LOAD_BACKGROUND;
|
||||
|
||||
(void)channel->SetLoadFlags(flags);
|
||||
|
||||
nsCOMPtr<nsISupports> window (do_QueryInterface(NS_STATIC_CAST(nsIStreamListener *, ic)));
|
||||
|
||||
// let's try uri dispatching...
|
||||
nsCOMPtr<nsIURILoader> pURILoader (do_GetService(NS_URI_LOADER_CONTRACTID, &rv));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
nsURILoadCommand loadCmd = nsIURILoader::viewNormal;
|
||||
PRBool bIsBackground = aURL->GetBackgroundLoad();
|
||||
if (bIsBackground) {
|
||||
loadCmd = nsIURILoader::viewNormalBackground;
|
||||
}
|
||||
|
||||
|
||||
rv = pURILoader->OpenURI(channel, loadCmd, nsnull /* window target */,
|
||||
window);
|
||||
}
|
||||
// rv = channel->AsyncOpen(ic, nsnull);
|
||||
if (NS_FAILED(rv)) goto error;
|
||||
}
|
||||
|
||||
ret = mRequests->AppendElement((void *)ic) ? 0 : -1;
|
||||
NS_RELEASE(ic); // if nothing else is holding onto it, it will remove
|
||||
// itself from mRequests
|
||||
return ret;
|
||||
|
||||
error:
|
||||
NS_RELEASE(ic);
|
||||
return -1;
|
||||
}
|
||||
|
||||
nsresult
|
||||
ImageNetContextImpl::RemoveRequest(ImageConsumer *aConsumer)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (mRequests) {
|
||||
rv = mRequests->RemoveElement((void *)aConsumer)?NS_OK:NS_ERROR_FAILURE;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
ImageNetContextImpl::RequestDone(ImageConsumer *aConsumer, nsIRequest* request,
|
||||
nsISupports* ctxt, nsresult status, const PRUnichar* aMsg)
|
||||
{
|
||||
RemoveRequest(aConsumer);
|
||||
/// if (mLoadGroup)
|
||||
/// return mLoadGroup->RemoveChannel(channel, ctxt, status, aMsg);
|
||||
/// else
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
extern "C" NS_GFX_(nsresult)
|
||||
NS_NewImageNetContext(ilINetContext **aInstancePtrResult,
|
||||
nsISupports * aLoadContext,
|
||||
nsReconnectCB aReconnectCallback,
|
||||
void* aReconnectArg)
|
||||
{
|
||||
|
||||
PRUint32 necko_attribs;
|
||||
ImgCachePolicy imglib_attribs = USE_IMG_CACHE;
|
||||
nsLoadFlags defchan_attribs = nsIRequest::LOAD_NORMAL;
|
||||
|
||||
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
|
||||
if (nsnull == aInstancePtrResult) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
if(aLoadContext){
|
||||
nsCOMPtr<nsILoadGroup> group (do_GetInterface(aLoadContext));
|
||||
/*nsresult rv = */group->GetLoadFlags(&necko_attribs);
|
||||
/*
|
||||
Need code to check freshness of necko cache.
|
||||
*/
|
||||
nsCOMPtr<nsIRequest> defLoadRequest;
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
if (NS_SUCCEEDED(group->GetDefaultLoadRequest(
|
||||
getter_AddRefs(defLoadRequest))) && defLoadRequest)
|
||||
{
|
||||
channel = do_QueryInterface(defLoadRequest);
|
||||
if (channel) channel->GetLoadFlags(&defchan_attribs);
|
||||
}
|
||||
|
||||
#if defined( DEBUG )
|
||||
if (image_net_context_async_log_module == NULL) {
|
||||
image_net_context_async_log_module = PR_NewLogModule("IMAGENETCTXASYNC");
|
||||
}
|
||||
#endif
|
||||
if((nsIRequest::VALIDATE_ALWAYS & defchan_attribs)||
|
||||
(nsIRequest::INHIBIT_PERSISTENT_CACHING & defchan_attribs)||
|
||||
(nsIRequest::LOAD_BYPASS_CACHE & defchan_attribs)) {
|
||||
imglib_attribs = DONT_USE_IMG_CACHE;
|
||||
#if defined( DEBUG )
|
||||
PR_LOG(image_net_context_async_log_module, 1, ("ImageNetContextAsync: NS_NewImageNetContext: DONT_USE_IMAGE_CACHE\n"));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
ilINetContext *cx = new ImageNetContextImpl( imglib_attribs,
|
||||
aLoadContext,
|
||||
aReconnectCallback,
|
||||
aReconnectArg);
|
||||
if (cx == nsnull) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return cx->QueryInterface(NS_GET_IID(ilINetContext), (void **) aInstancePtrResult);
|
||||
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
//#define DONT_INFORM_WEBSHELL
|
||||
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIDocumentLoader.h"
|
||||
#include "nsIWebShellServices.h"
|
||||
#include "nsIContentViewerContainer.h"
|
||||
#include "nsCURILoader.h"
|
||||
#include "nsObserverBase.h"
|
||||
#include "nsIParser.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
#include "nsXPIDLString.h"
|
||||
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
|
||||
static NS_DEFINE_IID(kDocLoaderServiceCID, NS_DOCUMENTLOADER_SERVICE_CID);
|
||||
static NS_DEFINE_IID(kIDocumentLoaderIID, NS_IDOCUMENTLOADER_IID);
|
||||
static NS_DEFINE_IID(kIWebShellServicesIID, NS_IWEB_SHELL_SERVICES_IID);
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
NS_IMETHODIMP nsObserverBase::NotifyWebShell(
|
||||
nsISupports* aParserBundle, const char* charset, nsCharsetSource source)
|
||||
{
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
nsCOMPtr<nsISupportsParserBundle> bundle=do_QueryInterface(aParserBundle);
|
||||
|
||||
if (bundle) {
|
||||
nsresult res = NS_OK;
|
||||
|
||||
// XXX - Make sure not to reload POST data to prevent bugs such as 27006
|
||||
nsAutoString theChannelKey;
|
||||
theChannelKey.AssignWithConversion("channel");
|
||||
|
||||
nsCOMPtr<nsIChannel> channel=nsnull;
|
||||
res=bundle->GetDataFromBundle(theChannelKey,getter_AddRefs(channel));
|
||||
if(NS_SUCCEEDED(res)) {
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel,&res));
|
||||
if(NS_SUCCEEDED(res)) {
|
||||
nsXPIDLCString method;
|
||||
httpChannel->GetRequestMethod(getter_Copies(method));
|
||||
if(method) {
|
||||
if(!PL_strcasecmp(method, "POST"))
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoString theDocShellKey;
|
||||
theDocShellKey.AssignWithConversion("docshell"); // Key to find docshell from the bundle.
|
||||
|
||||
nsCOMPtr<nsIDocShell> docshell=nsnull;
|
||||
|
||||
res=bundle->GetDataFromBundle(theDocShellKey,getter_AddRefs(docshell));
|
||||
if(NS_SUCCEEDED(res)) {
|
||||
nsCOMPtr<nsIWebShellServices> wss=nsnull;
|
||||
wss=do_QueryInterface(docshell,&res); // Query webshell service through docshell.
|
||||
if(NS_SUCCEEDED(res)) {
|
||||
|
||||
#ifndef DONT_INFORM_WEBSHELL
|
||||
// ask the webshellservice to load the URL
|
||||
if(NS_FAILED( res = wss->SetRendering(PR_FALSE) ))
|
||||
rv=res;
|
||||
|
||||
// XXX nisheeth, uncomment the following two line to see the reent problem
|
||||
|
||||
else if(NS_FAILED(res = wss->StopDocumentLoad())){
|
||||
rv = wss->SetRendering(PR_TRUE); // turn on the rendering so at least we will see something.
|
||||
}
|
||||
|
||||
else if(NS_FAILED(res = wss->ReloadDocument(charset, source))) {
|
||||
rv = wss->SetRendering(PR_TRUE); // turn on the rendering so at least we will see something.
|
||||
}
|
||||
else
|
||||
rv = NS_ERROR_HTMLPARSER_STOPPARSING; // We're reloading a new document...stop loading the current.
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape 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/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
|
||||
# XP way of doing the build date.
|
||||
# 1998091509 = 1998, September, 15th, 9am local time zone
|
||||
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime;
|
||||
# localtime returns year minus 1900
|
||||
$year = $year + 1900;
|
||||
printf("#define PRODUCT_VERSION \"%04d%02d%02d\"\n", $year, 1+$mon, $mday);
|
||||
@@ -1,90 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Alec Flett <alecf@netscape.com>
|
||||
*/
|
||||
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsICategoryManager.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsXPIDLString.h"
|
||||
|
||||
#include "nsContentHTTPStartup.h"
|
||||
#include "nsIHttpProtocolHandler.h"
|
||||
#include "gbdate.h"
|
||||
|
||||
#define PRODUCT_NAME "Gecko"
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsContentHTTPStartup,nsIObserver)
|
||||
|
||||
nsresult
|
||||
nsContentHTTPStartup::Observe( nsISupports *aSubject,
|
||||
const PRUnichar *aTopic,
|
||||
const PRUnichar *aData)
|
||||
{
|
||||
if (nsCRT::strcmp(aTopic, NS_HTTP_STARTUP_TOPIC) != 0)
|
||||
return NS_OK;
|
||||
|
||||
nsresult rv = nsnull;
|
||||
|
||||
nsCOMPtr<nsIHttpProtocolHandler> http(do_QueryInterface(aSubject));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = http->SetProduct(PRODUCT_NAME);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = http->SetProductSub((char*) PRODUCT_VERSION);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsContentHTTPStartup::RegisterHTTPStartup()
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsICategoryManager>
|
||||
catMan(do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv));
|
||||
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsXPIDLCString previousEntry;
|
||||
rv = catMan->AddCategoryEntry(NS_HTTP_STARTUP_CATEGORY,
|
||||
"Content UserAgent Setter",
|
||||
NS_CONTENTHTTPSTARTUP_CONTRACTID,
|
||||
PR_TRUE, PR_TRUE,
|
||||
getter_Copies(previousEntry));
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsContentHTTPStartup::UnregisterHTTPStartup()
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsICategoryManager>
|
||||
catMan(do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv));
|
||||
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,864 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Pierre Phaneuf <pp@ludusdesign.com>
|
||||
*/
|
||||
|
||||
#include "msgCore.h" // for pre-compiled headers
|
||||
#include "nsCOMPtr.h"
|
||||
#include <stdio.h>
|
||||
#include "nscore.h"
|
||||
#include "nsIFactory.h"
|
||||
#include "nsISupports.h"
|
||||
#include "comi18n.h"
|
||||
#include "prmem.h"
|
||||
#include "plstr.h"
|
||||
#include "nsIPref.h"
|
||||
#include "nsRepository.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsString.h"
|
||||
#include "nsAbSyncPostEngine.h"
|
||||
#include "nsIIOService.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsMimeTypes.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
#include "nsTextFormatter.h"
|
||||
#include "nsICookieService.h"
|
||||
#include "nsIAbSync.h"
|
||||
#include "nsAbSyncCID.h"
|
||||
|
||||
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
|
||||
static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
|
||||
static NS_DEFINE_CID(kCookieServiceCID, NS_COOKIESERVICE_CID);
|
||||
static NS_DEFINE_CID(kCAbSyncMojoCID, NS_AB_SYNC_MOJO_CID);
|
||||
static NS_DEFINE_CID(kAbSync, NS_ABSYNC_SERVICE_CID);
|
||||
|
||||
/*
|
||||
* This function will be used by the factory to generate an
|
||||
* object class object....
|
||||
*/
|
||||
NS_METHOD
|
||||
nsAbSyncPostEngine::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
||||
{
|
||||
if (aOuter)
|
||||
return NS_ERROR_NO_AGGREGATION;
|
||||
|
||||
nsAbSyncPostEngine *ph = new nsAbSyncPostEngine();
|
||||
if (ph == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
return ph->QueryInterface(aIID, aResult);
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(nsAbSyncPostEngine)
|
||||
NS_IMPL_RELEASE(nsAbSyncPostEngine)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsAbSyncPostEngine)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIURIContentListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIURIContentListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIAbSyncPostEngine)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
/*
|
||||
* Inherited methods for nsMimeConverter
|
||||
*/
|
||||
nsAbSyncPostEngine::nsAbSyncPostEngine()
|
||||
{
|
||||
/* the following macro is used to initialize the ref counting data */
|
||||
NS_INIT_REFCNT();
|
||||
|
||||
// Init member variables...
|
||||
mTotalWritten = 0;
|
||||
mStillRunning = PR_TRUE;
|
||||
mContentType = nsnull;
|
||||
mCharset = nsnull;
|
||||
|
||||
mListenerArray = nsnull;
|
||||
mListenerArrayCount = 0;
|
||||
|
||||
mPostEngineState = nsIAbSyncPostEngineState::nsIAbSyncPostIdle;
|
||||
mTransactionID = 0;
|
||||
mMessageSize = 0;
|
||||
mAuthenticationRunning = PR_TRUE;
|
||||
mCookie = nsnull;
|
||||
mUser = nsnull;
|
||||
mSyncProtocolRequest = nsnull;
|
||||
mSyncProtocolRequestPrefix = nsnull;
|
||||
mChannel = nsnull;
|
||||
mMojoSyncSpec = nsnull;
|
||||
}
|
||||
|
||||
nsAbSyncPostEngine::~nsAbSyncPostEngine()
|
||||
{
|
||||
mStillRunning = PR_FALSE;
|
||||
PR_FREEIF(mContentType);
|
||||
PR_FREEIF(mCharset);
|
||||
|
||||
PR_FREEIF(mSyncProtocolRequest);
|
||||
PR_FREEIF(mSyncProtocolRequestPrefix);
|
||||
PR_FREEIF(mCookie);
|
||||
PR_FREEIF(mUser);
|
||||
PR_FREEIF(mMojoSyncSpec);
|
||||
DeleteListeners();
|
||||
}
|
||||
|
||||
PRInt32 Base64Decode_int(const char *in_str, unsigned char *out_str,
|
||||
PRUint32& decoded_len);
|
||||
/* ==================================================================
|
||||
* Base64Encode
|
||||
*
|
||||
* Returns number of bytes that were encoded.
|
||||
*
|
||||
* >0 -> OK
|
||||
* -1 -> BAD (output buffer not big enough).
|
||||
*
|
||||
* ==================================================================
|
||||
*/
|
||||
PRInt32 Base64Encode(const unsigned char *in_str, PRInt32 in_len, char *out_str,
|
||||
PRInt32 out_len)
|
||||
{
|
||||
static unsigned char base64[] =
|
||||
{
|
||||
/* 0 1 2 3 4 5 6 7 */
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', /* 0 */
|
||||
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', /* 1 */
|
||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', /* 2 */
|
||||
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', /* 3 */
|
||||
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', /* 4 */
|
||||
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', /* 5 */
|
||||
'w', 'x', 'y', 'z', '0', '1', '2', '3', /* 6 */
|
||||
'4', '5', '6', '7', '8', '9', '+', '/' /* 7 */
|
||||
};
|
||||
PRInt32 curr_out_len = 0;
|
||||
|
||||
PRInt32 i = 0;
|
||||
unsigned char a, b, c;
|
||||
|
||||
out_str[0] = '\0';
|
||||
|
||||
if (in_len > 0)
|
||||
{
|
||||
|
||||
while (i < in_len)
|
||||
{
|
||||
a = in_str[i];
|
||||
b = (i + 1 >= in_len) ? 0 : in_str[i + 1];
|
||||
c = (i + 2 >= in_len) ? 0 : in_str[i + 2];
|
||||
|
||||
if (i + 2 < in_len)
|
||||
{
|
||||
out_str[curr_out_len++] = (base64[(a >> 2) & 0x3F]);
|
||||
out_str[curr_out_len++] = (base64[((a << 4) & 0x30)
|
||||
+ ((b >> 4) & 0xf)]);
|
||||
out_str[curr_out_len++] = (base64[((b << 2) & 0x3c)
|
||||
+ ((c >> 6) & 0x3)]);
|
||||
out_str[curr_out_len++] = (base64[c & 0x3F]);
|
||||
}
|
||||
else if (i + 1 < in_len)
|
||||
{
|
||||
out_str[curr_out_len++] = (base64[(a >> 2) & 0x3F]);
|
||||
out_str[curr_out_len++] = (base64[((a << 4) & 0x30)
|
||||
+ ((b >> 4) & 0xf)]);
|
||||
out_str[curr_out_len++] = (base64[((b << 2) & 0x3c)
|
||||
+ ((c >> 6) & 0x3)]);
|
||||
out_str[curr_out_len++] = '=';
|
||||
}
|
||||
else
|
||||
{
|
||||
out_str[curr_out_len++] = (base64[(a >> 2) & 0x3F]);
|
||||
out_str[curr_out_len++] = (base64[((a << 4) & 0x30)
|
||||
+ ((b >> 4) & 0xf)]);
|
||||
out_str[curr_out_len++] = '=';
|
||||
out_str[curr_out_len++] = '=';
|
||||
}
|
||||
|
||||
i += 3;
|
||||
|
||||
if((curr_out_len + 4) > out_len)
|
||||
{
|
||||
return(-1);
|
||||
}
|
||||
|
||||
}
|
||||
out_str[curr_out_len] = '\0';
|
||||
}
|
||||
|
||||
return curr_out_len;
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine decodes base64 string to a buffer.
|
||||
* Populates 'out_str' with b64 decoded data.
|
||||
*
|
||||
* Returns number of bytes that were decoded.
|
||||
* >0 -> OK
|
||||
* -1 -> BAD (output buffer not big enough).
|
||||
*/
|
||||
PRInt32 Base64Decode(const char *in_str, unsigned char *out_str,
|
||||
PRUint32* decoded_len)
|
||||
{
|
||||
return Base64Decode_int(in_str, out_str, *decoded_len);
|
||||
}
|
||||
|
||||
PRInt32 Base64Decode_int(const char *in_str, unsigned char *out_str,
|
||||
PRUint32& decoded_len)
|
||||
{
|
||||
PRInt32 in_len = strlen (/*(char *)*/ in_str);
|
||||
PRInt32 ii = 0;
|
||||
PRInt32 a = 0;
|
||||
char ch;
|
||||
PRInt32 b1 = 0;
|
||||
long b4 = 0;
|
||||
PRInt32 nn = 0;
|
||||
|
||||
/* Decode remainder of base 64 string */
|
||||
|
||||
while (ii < in_len)
|
||||
{
|
||||
ch = in_str[ii++];
|
||||
if (ch >= 'A' && ch <= 'Z') b1 = (ch - 'A');
|
||||
else if (ch >= 'a' && ch <= 'z') b1 = 26 + (ch - 'a');
|
||||
else if (ch >= '0' && ch <= '9') b1 = 52 + (ch - '0');
|
||||
else if (ch == '+') b1 = 62;
|
||||
else if (ch == '/') b1 = 63;
|
||||
else if (ch == '\r' || ch == '\n') continue;
|
||||
else
|
||||
{
|
||||
if (ch == '=')
|
||||
{
|
||||
if (nn == 3)
|
||||
{
|
||||
if ((a + 2) > (PRInt32) decoded_len)
|
||||
return (-1); /* Bail. Buffer overflow */
|
||||
b4 = (b4 << 6);
|
||||
out_str[a++] = (char) (0xff & (b4 >> 16));
|
||||
out_str[a++] = (char) (0xff & (b4 >> 8));
|
||||
}
|
||||
else if (nn == 2)
|
||||
{
|
||||
if ((a + 1) > (PRInt32) decoded_len)
|
||||
{
|
||||
return (-1); /* Bail. Buffer overflow */
|
||||
}
|
||||
b4 = (b4 << 12);
|
||||
out_str[a++] = (char) (0xff & (b4 >> 16));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
b4 = (b4 << 6) | (long) b1;
|
||||
nn++;
|
||||
if (nn == 4)
|
||||
{
|
||||
if ((a + 3) > (PRInt32) decoded_len)
|
||||
{
|
||||
return (-1); /* Bail. Buffer overflow */
|
||||
}
|
||||
out_str[a++] = (char) (0xff & (b4 >> 16));
|
||||
out_str[a++] = (char) (0xff & (b4 >> 8));
|
||||
out_str[a++] = (char) (0xff & (b4));
|
||||
nn = 0;
|
||||
}
|
||||
}
|
||||
|
||||
out_str[a] = '\0';
|
||||
decoded_len = a;
|
||||
|
||||
return (a);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAbSyncPostEngine::GetInterface(const nsIID & aIID, void * *aInstancePtr)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aInstancePtr);
|
||||
return QueryInterface(aIID, aInstancePtr);
|
||||
}
|
||||
|
||||
// nsIURIContentListener support
|
||||
NS_IMETHODIMP
|
||||
nsAbSyncPostEngine::OnStartURIOpen(nsIURI* aURI,
|
||||
const char* aWindowTarget, PRBool* aAbortOpen)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAbSyncPostEngine::GetProtocolHandler(nsIURI *aURI, nsIProtocolHandler **aProtocolHandler)
|
||||
{
|
||||
*aProtocolHandler = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAbSyncPostEngine::IsPreferred(const char * aContentType,
|
||||
nsURILoadCommand aCommand,
|
||||
const char * aWindowTarget,
|
||||
char ** aDesiredContentType,
|
||||
PRBool * aCanHandleContent)
|
||||
|
||||
{
|
||||
return CanHandleContent(aContentType, aCommand, aWindowTarget, aDesiredContentType,
|
||||
aCanHandleContent);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAbSyncPostEngine::CanHandleContent(const char * aContentType,
|
||||
nsURILoadCommand aCommand,
|
||||
const char * aWindowTarget,
|
||||
char ** aDesiredContentType,
|
||||
PRBool * aCanHandleContent)
|
||||
|
||||
{
|
||||
if (nsCRT::strcasecmp(aContentType, MESSAGE_RFC822) == 0)
|
||||
*aDesiredContentType = nsCRT::strdup("text/html");
|
||||
|
||||
// since we explicilty loaded the url, we always want to handle it!
|
||||
*aCanHandleContent = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAbSyncPostEngine::DoContent(const char * aContentType,
|
||||
nsURILoadCommand aCommand,
|
||||
const char * aWindowTarget,
|
||||
nsIRequest *request,
|
||||
nsIStreamListener ** aContentHandler,
|
||||
PRBool * aAbortProcess)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (aAbortProcess)
|
||||
*aAbortProcess = PR_FALSE;
|
||||
QueryInterface(NS_GET_IID(nsIStreamListener), (void **) aContentHandler);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAbSyncPostEngine::GetParentContentListener(nsIURIContentListener** aParent)
|
||||
{
|
||||
*aParent = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAbSyncPostEngine::SetParentContentListener(nsIURIContentListener* aParent)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAbSyncPostEngine::GetLoadCookie(nsISupports ** aLoadCookie)
|
||||
{
|
||||
*aLoadCookie = mLoadCookie;
|
||||
NS_IF_ADDREF(*aLoadCookie);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAbSyncPostEngine::SetLoadCookie(nsISupports * aLoadCookie)
|
||||
{
|
||||
mLoadCookie = aLoadCookie;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAbSyncPostEngine::StillRunning(PRBool *running)
|
||||
{
|
||||
*running = mStillRunning;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
// Methods for nsIStreamListener...
|
||||
nsresult
|
||||
nsAbSyncPostEngine::OnDataAvailable(nsIRequest *request, nsISupports * ctxt, nsIInputStream *aIStream,
|
||||
PRUint32 sourceOffset, PRUint32 aLength)
|
||||
{
|
||||
PRUint32 readLen = aLength;
|
||||
|
||||
char *buf = (char *)PR_Malloc(aLength);
|
||||
if (!buf)
|
||||
return NS_ERROR_OUT_OF_MEMORY; /* we couldn't allocate the object */
|
||||
|
||||
// read the data from the input stram...
|
||||
nsresult rv = aIStream->Read(buf, aLength, &readLen);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// write to the protocol response buffer...
|
||||
mProtocolResponse.Append(NS_ConvertASCIItoUCS2(buf, readLen));
|
||||
PR_FREEIF(buf);
|
||||
mTotalWritten += readLen;
|
||||
|
||||
if (!mAuthenticationRunning)
|
||||
NotifyListenersOnProgress(mTransactionID, mTotalWritten, 0);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
// Methods for nsIRequestObserver
|
||||
nsresult
|
||||
nsAbSyncPostEngine::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
|
||||
{
|
||||
if (mAuthenticationRunning)
|
||||
NotifyListenersOnStartAuthOperation();
|
||||
else
|
||||
NotifyListenersOnStartSending(mTransactionID, mMessageSize);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAbSyncPostEngine::OnStopRequest(nsIRequest *request, nsISupports * /* ctxt */, nsresult aStatus)
|
||||
{
|
||||
#ifdef NS_DEBUG_rhp
|
||||
printf("nsAbSyncPostEngine::OnStopRequest()\n");
|
||||
#endif
|
||||
|
||||
char *tProtResponse = nsnull;
|
||||
|
||||
//
|
||||
// Now complete the stream!
|
||||
//
|
||||
mStillRunning = PR_FALSE;
|
||||
|
||||
// Check the content type!
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
|
||||
if (channel)
|
||||
{
|
||||
char *contentType = nsnull;
|
||||
char *charset = nsnull;
|
||||
|
||||
if (NS_SUCCEEDED(channel->GetContentType(&contentType)) && contentType)
|
||||
{
|
||||
if (PL_strcasecmp(contentType, UNKNOWN_CONTENT_TYPE))
|
||||
{
|
||||
mContentType = contentType;
|
||||
}
|
||||
}
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(channel);
|
||||
if (httpChannel)
|
||||
{
|
||||
if (NS_SUCCEEDED(httpChannel->GetCharset(&charset)) && charset)
|
||||
{
|
||||
mCharset = charset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set the state...
|
||||
mPostEngineState = nsIAbSyncPostEngineState::nsIAbSyncPostIdle;
|
||||
|
||||
if (mAuthenticationRunning)
|
||||
{
|
||||
nsresult rv;
|
||||
if (mSyncMojo)
|
||||
rv = mSyncMojo->GetAbSyncMojoResults(&mUser, &mCookie, &mMojoSyncSpec, &mMojoSyncPort);
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
// Before we really get started...lets let sync know who is doing this...
|
||||
NS_WITH_SERVICE(nsIAbSync, sync, kAbSync, &rv);
|
||||
if (NS_SUCCEEDED(rv) || sync)
|
||||
sync->SetAbSyncUser(mUser);
|
||||
|
||||
// Base64 encode then url encode it...
|
||||
//
|
||||
char tUser[256] = "";
|
||||
|
||||
if (Base64Encode((unsigned char *)mUser, nsCRT::strlen(mUser), tUser, sizeof(tUser)) < 0)
|
||||
{
|
||||
rv = NS_ERROR_FAILURE;
|
||||
NotifyListenersOnStopAuthOperation(rv, tProtResponse);
|
||||
NotifyListenersOnStopSending(mTransactionID, rv, nsnull);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *tUser2 = nsEscape(tUser, url_Path);
|
||||
if (!tUser2)
|
||||
{
|
||||
rv = NS_ERROR_FAILURE;
|
||||
NotifyListenersOnStopAuthOperation(rv, tProtResponse);
|
||||
NotifyListenersOnStopSending(mTransactionID, rv, nsnull);
|
||||
}
|
||||
else
|
||||
{
|
||||
mSyncProtocolRequestPrefix = PR_smprintf("cn=%s&cc=%s&", tUser2, mCookie);
|
||||
PR_FREEIF(tUser2);
|
||||
NotifyListenersOnStopAuthOperation(aStatus, tProtResponse);
|
||||
KickTheSyncOperation();
|
||||
}
|
||||
}
|
||||
|
||||
// RICHIE - Special here to show the server we are hitting!
|
||||
// RICHIE - REMOVE THIS BEFORE SHIPPING!!!!
|
||||
#ifdef DEBUG
|
||||
PRUnichar *msgValue = nsnull;
|
||||
msgValue = nsTextFormatter::smprintf(nsString(NS_ConvertASCIItoUCS2("Server: %s - port %d")).GetUnicode(),
|
||||
mMojoSyncSpec, mMojoSyncPort);
|
||||
NotifyListenersOnStatus(mTransactionID, msgValue);
|
||||
PR_FREEIF(msgValue);
|
||||
// RICHIE
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
NotifyListenersOnStopAuthOperation(rv, tProtResponse);
|
||||
NotifyListenersOnStopSending(mTransactionID, rv, nsnull);
|
||||
}
|
||||
|
||||
mSyncMojo = nsnull;
|
||||
}
|
||||
else
|
||||
{
|
||||
tProtResponse = mProtocolResponse.ToNewCString();
|
||||
NotifyListenersOnStopSending(mTransactionID, aStatus, tProtResponse);
|
||||
}
|
||||
|
||||
PR_FREEIF(tProtResponse);
|
||||
|
||||
// Time to return...
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void AddSyncListener (in nsIAbSyncPostListener aListener); */
|
||||
NS_IMETHODIMP nsAbSyncPostEngine::AddPostListener(nsIAbSyncPostListener *aListener)
|
||||
{
|
||||
if ( (mListenerArrayCount > 0) || mListenerArray )
|
||||
{
|
||||
++mListenerArrayCount;
|
||||
mListenerArray = (nsIAbSyncPostListener **)
|
||||
PR_Realloc(*mListenerArray, sizeof(nsIAbSyncPostListener *) * mListenerArrayCount);
|
||||
if (!mListenerArray)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
else
|
||||
{
|
||||
mListenerArray[mListenerArrayCount - 1] = aListener;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mListenerArrayCount = 1;
|
||||
mListenerArray = (nsIAbSyncPostListener **) PR_Malloc(sizeof(nsIAbSyncPostListener *) * mListenerArrayCount);
|
||||
if (!mListenerArray)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsCRT::memset(mListenerArray, 0, (sizeof(nsIAbSyncPostListener *) * mListenerArrayCount));
|
||||
|
||||
mListenerArray[0] = aListener;
|
||||
NS_ADDREF(mListenerArray[0]);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/* void RemoveSyncListener (in nsIAbSyncPostListener aListener); */
|
||||
NS_IMETHODIMP nsAbSyncPostEngine::RemovePostListener(nsIAbSyncPostListener *aListener)
|
||||
{
|
||||
PRInt32 i;
|
||||
for (i=0; i<mListenerArrayCount; i++)
|
||||
if (mListenerArray[i] == aListener)
|
||||
{
|
||||
NS_RELEASE(mListenerArray[i]);
|
||||
mListenerArray[i] = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAbSyncPostEngine::DeleteListeners()
|
||||
{
|
||||
if ( (mListenerArray) && (*mListenerArray) )
|
||||
{
|
||||
PRInt32 i;
|
||||
for (i=0; i<mListenerArrayCount; i++)
|
||||
{
|
||||
NS_RELEASE(mListenerArray[i]);
|
||||
}
|
||||
|
||||
PR_FREEIF(mListenerArray);
|
||||
}
|
||||
|
||||
mListenerArrayCount = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAbSyncPostEngine::NotifyListenersOnStartAuthOperation(void)
|
||||
{
|
||||
PRInt32 i;
|
||||
for (i=0; i<mListenerArrayCount; i++)
|
||||
if (mListenerArray[i] != nsnull)
|
||||
mListenerArray[i]->OnStartAuthOperation();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAbSyncPostEngine::NotifyListenersOnStopAuthOperation(nsresult aStatus, const char *aCookie)
|
||||
{
|
||||
PRInt32 i;
|
||||
for (i=0; i<mListenerArrayCount; i++)
|
||||
if (mListenerArray[i] != nsnull)
|
||||
mListenerArray[i]->OnStopAuthOperation(aStatus, nsnull, aCookie);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAbSyncPostEngine::NotifyListenersOnStartSending(PRInt32 aTransactionID, PRUint32 aMsgSize)
|
||||
{
|
||||
PRInt32 i;
|
||||
for (i=0; i<mListenerArrayCount; i++)
|
||||
if (mListenerArray[i] != nsnull)
|
||||
mListenerArray[i]->OnStartOperation(aTransactionID, aMsgSize);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAbSyncPostEngine::NotifyListenersOnProgress(PRInt32 aTransactionID, PRUint32 aProgress, PRUint32 aProgressMax)
|
||||
{
|
||||
PRInt32 i;
|
||||
for (i=0; i<mListenerArrayCount; i++)
|
||||
if (mListenerArray[i] != nsnull)
|
||||
mListenerArray[i]->OnProgress(aTransactionID, aProgress, aProgressMax);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAbSyncPostEngine::NotifyListenersOnStatus(PRInt32 aTransactionID, PRUnichar *aMsg)
|
||||
{
|
||||
PRInt32 i;
|
||||
for (i=0; i<mListenerArrayCount; i++)
|
||||
if (mListenerArray[i] != nsnull)
|
||||
mListenerArray[i]->OnStatus(aTransactionID, aMsg);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAbSyncPostEngine::NotifyListenersOnStopSending(PRInt32 aTransactionID, nsresult aStatus,
|
||||
char *aProtocolResponse)
|
||||
{
|
||||
PRInt32 i;
|
||||
for (i=0; i<mListenerArrayCount; i++)
|
||||
if (mListenerArray[i] != nsnull)
|
||||
mListenerArray[i]->OnStopOperation(aTransactionID, aStatus, nsnull, aProtocolResponse);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Utility to create a nsIURI object...
|
||||
extern "C" nsresult
|
||||
nsEngineNewURI(nsIURI** aInstancePtrResult, const char *aSpec, nsIURI *aBase)
|
||||
{
|
||||
nsresult res;
|
||||
|
||||
if (nsnull == aInstancePtrResult)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
NS_WITH_SERVICE(nsIIOService, pService, kIOServiceCID, &res);
|
||||
if (NS_FAILED(res))
|
||||
return NS_ERROR_FACTORY_NOT_REGISTERED;
|
||||
|
||||
return pService->NewURI(aSpec, aBase, aInstancePtrResult);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAbSyncPostEngine::FireURLRequest(nsIURI *aURL, const char *postData)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIInputStream> postStream;
|
||||
|
||||
if (!postData)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
NS_ENSURE_SUCCESS(NS_OpenURI(getter_AddRefs(mChannel), aURL, nsnull), NS_ERROR_FAILURE);
|
||||
|
||||
// Tag the post stream onto the channel...but never seemed to work...so putting it
|
||||
// directly on the URL spec
|
||||
//
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(mChannel);
|
||||
if (!httpChannel)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (NS_SUCCEEDED(rv = NS_NewPostDataStream(getter_AddRefs(postStream), PR_FALSE, postData, 0)))
|
||||
httpChannel->SetUploadStream(postStream);
|
||||
|
||||
httpChannel->AsyncOpen(this, nsnull);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* PRInt32 GetCurrentState (); */
|
||||
NS_IMETHODIMP nsAbSyncPostEngine::GetCurrentState(PRInt32 *_retval)
|
||||
{
|
||||
*_retval = mPostEngineState;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This is the implementation of the actual post driver.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
NS_IMETHODIMP nsAbSyncPostEngine::BuildMojoString(nsIDocShell *aRootDocShell, char **aID)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (!aID)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// Now, get the COMPtr to the Mojo!
|
||||
if (!mSyncMojo)
|
||||
{
|
||||
rv = nsComponentManager::CreateInstance(kCAbSyncMojoCID, NULL, NS_GET_IID(nsIAbSyncMojo), getter_AddRefs(mSyncMojo));
|
||||
if ( NS_FAILED(rv) || (!mSyncMojo) )
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
rv = mSyncMojo->BuildMojoString(aRootDocShell, aID);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAbSyncPostEngine::SendAbRequest(const char *aSpec, PRInt32 aPort, const char *aProtocolRequest, PRInt32 aTransactionID,
|
||||
nsIDocShell *aDocShell, const char *aUser)
|
||||
{
|
||||
nsresult rv;
|
||||
char *mojoUser = nsnull;
|
||||
char *mojoSnack = nsnull;
|
||||
|
||||
// Only try if we are not currently busy!
|
||||
if (mPostEngineState != nsIAbSyncPostEngineState::nsIAbSyncPostIdle)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// Now, get the COMPtr to the Mojo!
|
||||
if (!mSyncMojo)
|
||||
{
|
||||
rv = nsComponentManager::CreateInstance(kCAbSyncMojoCID, NULL, NS_GET_IID(nsIAbSyncMojo), getter_AddRefs(mSyncMojo));
|
||||
if ( NS_FAILED(rv) || (!mSyncMojo) )
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (aUser)
|
||||
mUser = nsCRT::strdup(aUser);
|
||||
if (NS_FAILED(mSyncMojo->StartAbSyncMojo(this, aDocShell, mUser)))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// Set transaction ID and save/init Sync info...
|
||||
mTransactionID = aTransactionID;
|
||||
|
||||
// Init stuff we need....
|
||||
mSyncProtocolRequest = nsCRT::strdup(aProtocolRequest);
|
||||
mProtocolResponse = NS_ConvertASCIItoUCS2("");
|
||||
mTotalWritten = 0;
|
||||
|
||||
// The first thing we need to do is authentication so do it!
|
||||
mAuthenticationRunning = PR_TRUE;
|
||||
mPostEngineState = nsIAbSyncPostEngineState::nsIAbSyncAuthenticationRunning;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAbSyncPostEngine::KickTheSyncOperation(void)
|
||||
{
|
||||
nsresult rv;
|
||||
nsIURI *workURI = nsnull;
|
||||
char *protString = nsnull;
|
||||
|
||||
// The first thing we need to do is authentication so do it!
|
||||
mAuthenticationRunning = PR_FALSE;
|
||||
mProtocolResponse = NS_ConvertASCIItoUCS2("");
|
||||
mPostEngineState = nsIAbSyncPostEngineState::nsIAbSyncPostRunning;
|
||||
|
||||
char *postHeader = "Content-Type: application/x-www-form-urlencoded\r\nContent-Length: %d\r\nCookie: %s\r\n\r\n%s";
|
||||
protString = PR_smprintf("%s%s", mSyncProtocolRequestPrefix, mSyncProtocolRequest);
|
||||
if (protString)
|
||||
mMessageSize = nsCRT::strlen(protString);
|
||||
else
|
||||
mMessageSize = 0;
|
||||
|
||||
char *tCommand = PR_smprintf(postHeader, mMessageSize, mCookie, protString);
|
||||
PR_FREEIF(protString);
|
||||
|
||||
#ifdef DEBUG_rhp
|
||||
printf("COMMAND = %s\n", tCommand);
|
||||
#endif
|
||||
|
||||
if (!tCommand)
|
||||
{
|
||||
rv = NS_ERROR_OUT_OF_MEMORY; // we couldn't allocate the string
|
||||
goto GetOuttaHere;
|
||||
}
|
||||
|
||||
rv = nsEngineNewURI(&workURI, mMojoSyncSpec, nsnull);
|
||||
if (NS_FAILED(rv) || (!workURI))
|
||||
{
|
||||
rv = NS_ERROR_FAILURE; // we couldn't allocate the string
|
||||
goto GetOuttaHere;
|
||||
}
|
||||
|
||||
if (mMojoSyncPort > 0)
|
||||
workURI->SetPort(mMojoSyncPort);
|
||||
|
||||
rv = FireURLRequest(workURI, tCommand);
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
NotifyListenersOnStartSending(mTransactionID, mMessageSize);
|
||||
|
||||
GetOuttaHere:
|
||||
NS_IF_RELEASE(workURI);
|
||||
PR_FREEIF(tCommand);
|
||||
mPostEngineState = nsIAbSyncPostEngineState::nsIAbSyncPostRunning;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAbSyncPostEngine::CancelAbSync()
|
||||
{
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
if (mSyncMojo)
|
||||
{
|
||||
rv = mSyncMojo->CancelTheMojo();
|
||||
}
|
||||
else if (mChannel)
|
||||
{
|
||||
rv = mChannel->Cancel(NS_BINDING_ABORTED);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAbSyncPostEngine::GetMojoUserAndSnack(char **aMojoUser, char **aMojoSnack)
|
||||
{
|
||||
if ( (!mUser) || (!mCookie) )
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
*aMojoUser = nsCRT::strdup(mUser);
|
||||
*aMojoSnack = nsCRT::strdup(mCookie);
|
||||
|
||||
if ( (!*aMojoUser) || (!*aMojoSnack) )
|
||||
return NS_ERROR_FAILURE;
|
||||
else
|
||||
return NS_OK;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,453 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Pierre Phaneuf <pp@ludusdesign.com>
|
||||
*/
|
||||
|
||||
#include "nsURLFetcher.h"
|
||||
|
||||
#include "msgCore.h" // for pre-compiled headers
|
||||
#include "nsCOMPtr.h"
|
||||
#include <stdio.h>
|
||||
#include "nscore.h"
|
||||
#include "nsIFactory.h"
|
||||
#include "nsISupports.h"
|
||||
#include "comi18n.h"
|
||||
#include "prmem.h"
|
||||
#include "plstr.h"
|
||||
#include "nsRepository.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIIOService.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsMimeTypes.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
#include "nsIWebProgress.h"
|
||||
#include "nsMsgAttachmentHandler.h"
|
||||
#include "nsMsgSend.h"
|
||||
|
||||
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
|
||||
|
||||
|
||||
NS_IMPL_ISUPPORTS7(nsURLFetcher, nsIURLFetcher, nsIStreamListener, nsIURIContentListener, nsIInterfaceRequestor, nsIWebProgressListener, nsIHttpEventSink, nsISupportsWeakReference)
|
||||
|
||||
|
||||
/*
|
||||
* Inherited methods for nsMimeConverter
|
||||
*/
|
||||
nsURLFetcher::nsURLFetcher()
|
||||
{
|
||||
#if defined(DEBUG_ducarroz)
|
||||
printf("CREATE nsURLFetcher: %x\n", this);
|
||||
#endif
|
||||
/* the following macro is used to initialize the ref counting data */
|
||||
NS_INIT_REFCNT();
|
||||
|
||||
// Init member variables...
|
||||
mOutStream = nsnull;
|
||||
mTotalWritten = 0;
|
||||
mStillRunning = PR_TRUE;
|
||||
mCallback = nsnull;
|
||||
mContentType = nsnull;
|
||||
mCharset = nsnull;
|
||||
mOnStopRequestProcessed = PR_FALSE;
|
||||
mRedirection = PR_FALSE;
|
||||
}
|
||||
|
||||
nsURLFetcher::~nsURLFetcher()
|
||||
{
|
||||
#if defined(DEBUG_ducarroz)
|
||||
printf("DISPOSE nsURLFetcher: %x\n", this);
|
||||
#endif
|
||||
mStillRunning = PR_FALSE;
|
||||
|
||||
PR_FREEIF(mContentType);
|
||||
PR_FREEIF(mCharset);
|
||||
// Remove the DocShell as a listener of the old WebProgress...
|
||||
if (mLoadCookie)
|
||||
{
|
||||
nsCOMPtr<nsIWebProgress> webProgress(do_QueryInterface(mLoadCookie));
|
||||
|
||||
if (webProgress)
|
||||
webProgress->RemoveProgressListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsURLFetcher::GetInterface(const nsIID & aIID, void * *aInstancePtr)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aInstancePtr);
|
||||
return QueryInterface(aIID, aInstancePtr);
|
||||
}
|
||||
|
||||
// nsIURIContentListener support
|
||||
NS_IMETHODIMP
|
||||
nsURLFetcher::OnStartURIOpen(nsIURI* aURI,
|
||||
const char* aWindowTarget, PRBool* aAbortOpen)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsURLFetcher::GetProtocolHandler(nsIURI *aURI, nsIProtocolHandler **aProtocolHandler)
|
||||
{
|
||||
*aProtocolHandler = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsURLFetcher::IsPreferred(const char * aContentType,
|
||||
nsURILoadCommand aCommand,
|
||||
const char * aWindowTarget,
|
||||
char ** aDesiredContentType,
|
||||
PRBool * aCanHandleContent)
|
||||
|
||||
{
|
||||
return CanHandleContent(aContentType, aCommand, aWindowTarget, aDesiredContentType,
|
||||
aCanHandleContent);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsURLFetcher::CanHandleContent(const char * aContentType,
|
||||
nsURILoadCommand aCommand,
|
||||
const char * aWindowTarget,
|
||||
char ** aDesiredContentType,
|
||||
PRBool * aCanHandleContent)
|
||||
|
||||
{
|
||||
if (nsCRT::strcasecmp(aContentType, MESSAGE_RFC822) == 0)
|
||||
*aDesiredContentType = nsCRT::strdup("text/html");
|
||||
|
||||
// since we explicilty loaded the url, we always want to handle it!
|
||||
*aCanHandleContent = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsURLFetcher::DoContent(const char * aContentType,
|
||||
nsURILoadCommand aCommand,
|
||||
const char * aWindowTarget,
|
||||
nsIRequest *request,
|
||||
nsIStreamListener ** aContentHandler,
|
||||
PRBool * aAbortProcess)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (aAbortProcess)
|
||||
*aAbortProcess = PR_FALSE;
|
||||
QueryInterface(NS_GET_IID(nsIStreamListener), (void **) aContentHandler);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsURLFetcher::GetParentContentListener(nsIURIContentListener** aParent)
|
||||
{
|
||||
*aParent = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsURLFetcher::SetParentContentListener(nsIURIContentListener* aParent)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsURLFetcher::GetLoadCookie(nsISupports ** aLoadCookie)
|
||||
{
|
||||
*aLoadCookie = mLoadCookie;
|
||||
NS_IF_ADDREF(*aLoadCookie);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsURLFetcher::SetLoadCookie(nsISupports * aLoadCookie)
|
||||
{
|
||||
// Remove the DocShell as a listener of the old WebProgress...
|
||||
if (mLoadCookie)
|
||||
{
|
||||
nsCOMPtr<nsIWebProgress> webProgress(do_QueryInterface(mLoadCookie));
|
||||
|
||||
if (webProgress)
|
||||
webProgress->RemoveProgressListener(this);
|
||||
}
|
||||
|
||||
mLoadCookie = aLoadCookie;
|
||||
|
||||
// Add the DocShell as a listener to the new WebProgress...
|
||||
if (mLoadCookie)
|
||||
{
|
||||
nsCOMPtr<nsIWebProgress> webProgress(do_QueryInterface(mLoadCookie));
|
||||
|
||||
if (webProgress)
|
||||
webProgress->AddProgressListener(this);
|
||||
}
|
||||
return NS_OK;
|
||||
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsURLFetcher::StillRunning(PRBool *running)
|
||||
{
|
||||
*running = mStillRunning;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
// Methods for nsIStreamListener...
|
||||
nsresult
|
||||
nsURLFetcher::OnDataAvailable(nsIRequest *request, nsISupports * ctxt, nsIInputStream *aIStream,
|
||||
PRUint32 sourceOffset, PRUint32 aLength)
|
||||
{
|
||||
PRUint32 readLen = aLength;
|
||||
PRUint32 wroteIt;
|
||||
|
||||
if (!mOutStream)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
char *buf = (char *)PR_Malloc(aLength);
|
||||
if (!buf)
|
||||
return NS_ERROR_OUT_OF_MEMORY; /* we couldn't allocate the object */
|
||||
|
||||
// read the data from the input stram...
|
||||
nsresult rv = aIStream->Read(buf, aLength, &readLen);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// write to the output file...
|
||||
wroteIt = mOutStream->write(buf, readLen);
|
||||
PR_FREEIF(buf);
|
||||
|
||||
if (wroteIt != readLen)
|
||||
return NS_ERROR_FAILURE;
|
||||
else
|
||||
{
|
||||
mTotalWritten += wroteIt;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Methods for nsIStreamObserver
|
||||
nsresult
|
||||
nsURLFetcher::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
|
||||
{
|
||||
mRedirection = PR_FALSE; // start a new request, reset mRedirection
|
||||
|
||||
nsMsgAttachmentHandler *attachmentHdl = (nsMsgAttachmentHandler *)mTagData;
|
||||
if (attachmentHdl)
|
||||
{
|
||||
nsCOMPtr<nsIMsgSend> sendPtr;
|
||||
attachmentHdl->GetMimeDeliveryState(getter_AddRefs(sendPtr));
|
||||
if (sendPtr)
|
||||
{
|
||||
nsCOMPtr<nsIMsgProgress> progress;
|
||||
sendPtr->GetProgress(getter_AddRefs(progress));
|
||||
if (progress)
|
||||
{
|
||||
PRBool cancel = PR_FALSE;
|
||||
progress->GetProcessCanceledByUser(&cancel);
|
||||
if (cancel)
|
||||
return request->Cancel(NS_ERROR_ABORT);
|
||||
}
|
||||
}
|
||||
attachmentHdl->mRequest = request;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsURLFetcher::OnStopRequest(nsIRequest *request, nsISupports * /* ctxt */, nsresult aStatus)
|
||||
{
|
||||
#if defined(DEBUG_ducarroz)
|
||||
printf("nsURLFetcher::OnStopRequest()\n");
|
||||
#endif
|
||||
|
||||
// it's possible we could get in here from the channel calling us with an OnStopRequest and from our
|
||||
// onStatusChange method (in the case of an error). So we should protect against this to make sure we
|
||||
// don't process the on stop request twice...
|
||||
|
||||
if (mOnStopRequestProcessed) return NS_OK;
|
||||
mOnStopRequestProcessed = PR_TRUE;
|
||||
|
||||
nsMsgAttachmentHandler *attachmentHdl = (nsMsgAttachmentHandler *)mTagData;
|
||||
if (attachmentHdl)
|
||||
attachmentHdl->mRequest = nsnull;
|
||||
|
||||
//
|
||||
// Now complete the stream!
|
||||
//
|
||||
mStillRunning = PR_FALSE;
|
||||
|
||||
// First close the output stream...
|
||||
if (mOutStream)
|
||||
{
|
||||
mOutStream->close();
|
||||
mOutStream = nsnull;
|
||||
}
|
||||
|
||||
|
||||
// Check the content type!
|
||||
char *contentType = nsnull;
|
||||
char *charset = nsnull;
|
||||
|
||||
nsCOMPtr<nsIChannel> aChannel = do_QueryInterface(request);
|
||||
if(!aChannel) return NS_ERROR_FAILURE;
|
||||
|
||||
if (NS_SUCCEEDED(aChannel->GetContentType(&contentType)) && contentType)
|
||||
{
|
||||
if (PL_strcasecmp(contentType, UNKNOWN_CONTENT_TYPE))
|
||||
{
|
||||
mContentType = contentType;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel);
|
||||
if (httpChannel)
|
||||
{
|
||||
if (NS_SUCCEEDED(httpChannel->GetCharset(&charset)) && charset)
|
||||
{
|
||||
mCharset = charset;
|
||||
}
|
||||
}
|
||||
|
||||
// Now if there is a callback, we need to call it...
|
||||
if (mCallback)
|
||||
mCallback (aStatus, mContentType, mCharset, mTotalWritten, nsnull, mTagData);
|
||||
|
||||
// Time to return...
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsURLFetcher::Initialize(nsOutputFileStream *fOut,
|
||||
nsAttachSaveCompletionCallback cb,
|
||||
void *tagData)
|
||||
{
|
||||
if (!fOut)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
if (!fOut->is_open())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
mOutStream = fOut;
|
||||
mCallback = cb; //JFD: Please, no more callback, use a listener...
|
||||
mTagData = tagData; //JFD: TODO, WE SHOULD USE A NSCOMPTR to hold this stuff!!!
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsURLFetcher::FireURLRequest(nsIURI *aURL, nsOutputFileStream *fOut,
|
||||
nsAttachSaveCompletionCallback cb, void *tagData)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if ( (!aURL) || (!fOut) )
|
||||
{
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (!fOut->is_open())
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// we're about to fire a new url request so make sure the on stop request flag is cleared...
|
||||
mOnStopRequestProcessed = PR_FALSE;
|
||||
|
||||
// let's try uri dispatching...
|
||||
nsCOMPtr<nsIURILoader> pURILoader (do_GetService(NS_URI_LOADER_CONTRACTID));
|
||||
NS_ENSURE_TRUE(pURILoader, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsISupports> cntListener (do_QueryInterface(NS_STATIC_CAST(nsIStreamListener *, this)));
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
nsCOMPtr<nsILoadGroup> loadGroup;
|
||||
pURILoader->GetLoadGroupForContext(cntListener, getter_AddRefs(loadGroup));
|
||||
NS_ENSURE_SUCCESS(NS_OpenURI(getter_AddRefs(channel), aURL, nsnull, loadGroup, this), NS_ERROR_FAILURE);
|
||||
|
||||
rv = pURILoader->OpenURI(channel, nsIURILoader::viewNormal, nsnull /* window target */,
|
||||
cntListener);
|
||||
|
||||
mOutStream = fOut;
|
||||
mCallback = cb;
|
||||
mTagData = tagData;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
// web progress listener implementation
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsURLFetcher::OnProgressChange(nsIWebProgress *aProgress, nsIRequest *aRequest,
|
||||
PRInt32 aCurSelfProgress, PRInt32 aMaxSelfProgress,
|
||||
PRInt32 aCurTotalProgress, PRInt32 aMaxTotalProgress)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsURLFetcher::OnStateChange(nsIWebProgress *aProgress, nsIRequest *aRequest,
|
||||
PRInt32 aStateFlags, nsresult aStatus)
|
||||
{
|
||||
// all we care about is the case where an error occurred (as in we were unable to locate the
|
||||
// the url....
|
||||
|
||||
if (NS_FAILED(aStatus))
|
||||
{
|
||||
//... but we must ignore abort message caused by a redirection!
|
||||
if (aStatus == NS_BINDING_ABORTED && mRedirection)
|
||||
return NS_OK;
|
||||
|
||||
OnStopRequest(aRequest, nsnull, aStatus);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsURLFetcher::OnLocationChange(nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest,
|
||||
nsIURI *aURI)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsURLFetcher::OnStatusChange(nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest,
|
||||
nsresult aStatus,
|
||||
const PRUnichar* aMessage)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsURLFetcher::OnSecurityChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
PRInt32 state)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsURLFetcher::OnRedirect(nsIHttpChannel *aOldChannel, nsIChannel *aNewChannel)
|
||||
{
|
||||
mRedirection = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
#ifndef nsURLFetcher_h_
|
||||
#define nsURLFetcher_h_
|
||||
|
||||
#include "nsIURLFetcher.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIStreamListener.h"
|
||||
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsCURILoader.h"
|
||||
#include "nsIURIContentListener.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "nsIHttpEventSink.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
|
||||
class nsURLFetcher : public nsIURLFetcher,
|
||||
public nsIStreamListener,
|
||||
public nsIURIContentListener,
|
||||
public nsIInterfaceRequestor,
|
||||
public nsIWebProgressListener,
|
||||
public nsIHttpEventSink,
|
||||
public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
nsURLFetcher();
|
||||
virtual ~nsURLFetcher();
|
||||
|
||||
/* this macro defines QueryInterface, AddRef and Release for this class */
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// Methods for nsIURLFetcher
|
||||
NS_DECL_NSIURLFETCHER
|
||||
|
||||
// Methods for nsIStreamListener
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
|
||||
// Methods for nsIRequestObserver
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
|
||||
// Methods for nsIURICOntentListener
|
||||
NS_DECL_NSIURICONTENTLISTENER
|
||||
|
||||
// Methods for nsIInterfaceRequestor
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
|
||||
// Methods for nsIWebProgressListener
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
|
||||
// Methods for nsIHttpEventSink
|
||||
NS_DECL_NSIHTTPEVENTSINK
|
||||
|
||||
private:
|
||||
nsOutputFileStream *mOutStream; // the output file stream
|
||||
PRBool mStillRunning; // Are we still running?
|
||||
PRInt32 mTotalWritten; // Size counter variable
|
||||
char *mContentType; // The content type retrieved from the server
|
||||
char *mCharset; // The charset retrieved from the server
|
||||
void *mTagData; // Tag data for callback...
|
||||
nsAttachSaveCompletionCallback mCallback; // Callback to call once the file is saved...
|
||||
nsCOMPtr<nsISupports> mLoadCookie; // load cookie used by the uri loader when we fetch the url
|
||||
PRBool mOnStopRequestProcessed; // used to prevent calling OnStopRequest multiple times
|
||||
PRBool mRedirection; // Set when we get a redirection, should ignore stop message.
|
||||
};
|
||||
|
||||
#endif /* nsURLFetcher_h_ */
|
||||
@@ -1,39 +0,0 @@
|
||||
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#include "nsIChannel.idl"
|
||||
|
||||
interface nsISimpleEnumerator;
|
||||
|
||||
[scriptable, uuid(c7e410d1-85f2-11d3-9f63-006008a6efe9)]
|
||||
interface nsIJARChannel : nsIChannel
|
||||
{
|
||||
|
||||
/**
|
||||
* Enumerates all the entries in the JAR (the root URI).
|
||||
* ARGUMENTS:
|
||||
* aRoot - a string representing the root dir to enumerate from
|
||||
* or null to enumerate the whole thing.
|
||||
*/
|
||||
nsISimpleEnumerator EnumerateEntries(in string aRoot);
|
||||
|
||||
};
|
||||
@@ -1,34 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#include "nsIProtocolHandler.idl"
|
||||
|
||||
interface nsIZipReaderCache;
|
||||
|
||||
[scriptable, uuid(92c3b42c-98c4-11d3-8cd9-0060b0fc14a3)]
|
||||
interface nsIJARProtocolHandler : nsIProtocolHandler {
|
||||
|
||||
/**
|
||||
* JARCache contains the collection of open jar files.
|
||||
*/
|
||||
readonly attribute nsIZipReaderCache JARCache;
|
||||
};
|
||||
@@ -1,696 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998,2000 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsJARChannel.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsIFileTransportService.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsCExternalHandlerService.h"
|
||||
#include "nsIMIMEService.h"
|
||||
#include "nsAutoLock.h"
|
||||
#include "nsIFileStreams.h"
|
||||
#include "nsMimeTypes.h"
|
||||
#include "nsScriptSecurityManager.h"
|
||||
#include "nsIAggregatePrincipal.h"
|
||||
#include "nsIProgressEventSink.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsIJAR.h"
|
||||
|
||||
static NS_DEFINE_CID(kFileTransportServiceCID, NS_FILETRANSPORTSERVICE_CID);
|
||||
static NS_DEFINE_CID(kZipReaderCID, NS_ZIPREADER_CID);
|
||||
static NS_DEFINE_CID(kScriptSecurityManagerCID, NS_SCRIPTSECURITYMANAGER_CID);
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
//
|
||||
// Log module for SocketTransport logging...
|
||||
//
|
||||
// To enable logging (see prlog.h for full details):
|
||||
//
|
||||
// set NSPR_LOG_MODULES=nsJarProtocol:5
|
||||
// set NSPR_LOG_FILE=nspr.log
|
||||
//
|
||||
// this enables PR_LOG_DEBUG level information and places all output in
|
||||
// the file nspr.log
|
||||
//
|
||||
PRLogModuleInfo* gJarProtocolLog = nsnull;
|
||||
|
||||
#endif /* PR_LOGGING */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define NS_DEFAULT_JAR_BUFFER_SEGMENT_SIZE (16*1024)
|
||||
#define NS_DEFAULT_JAR_BUFFER_MAX_SIZE (256*1024)
|
||||
|
||||
nsJARChannel::nsJARChannel()
|
||||
: mLoadFlags(LOAD_NORMAL),
|
||||
mContentType(nsnull),
|
||||
mContentLength(-1),
|
||||
mJAREntry(nsnull),
|
||||
mStatus(NS_OK),
|
||||
mMonitor(nsnull)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
//
|
||||
// Initialize the global PRLogModule for socket transport logging
|
||||
// if necessary...
|
||||
//
|
||||
if (nsnull == gJarProtocolLog) {
|
||||
gJarProtocolLog = PR_NewLogModule("nsJarProtocol");
|
||||
}
|
||||
#endif /* PR_LOGGING */
|
||||
}
|
||||
|
||||
nsJARChannel::~nsJARChannel()
|
||||
{
|
||||
if (mContentType)
|
||||
nsCRT::free(mContentType);
|
||||
if (mJAREntry)
|
||||
nsCRT::free(mJAREntry);
|
||||
if (mMonitor)
|
||||
PR_DestroyMonitor(mMonitor);
|
||||
}
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS7(nsJARChannel,
|
||||
nsIJARChannel,
|
||||
nsIChannel,
|
||||
nsIRequest,
|
||||
nsIRequestObserver,
|
||||
nsIStreamListener,
|
||||
nsIStreamIO,
|
||||
nsIDownloadObserver)
|
||||
|
||||
NS_METHOD
|
||||
nsJARChannel::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (aOuter)
|
||||
return NS_ERROR_NO_AGGREGATION;
|
||||
|
||||
nsJARChannel* jarChannel = new nsJARChannel();
|
||||
if (jarChannel == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(jarChannel);
|
||||
rv = jarChannel->QueryInterface(aIID, aResult);
|
||||
NS_RELEASE(jarChannel);
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsJARChannel::Init(nsIJARProtocolHandler* aHandler, nsIURI* uri)
|
||||
{
|
||||
nsresult rv;
|
||||
mURI = do_QueryInterface(uri, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
mMonitor = PR_NewMonitor();
|
||||
if (mMonitor == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
mJARProtocolHandler = aHandler;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIRequest methods
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::GetName(PRUnichar* *result)
|
||||
{
|
||||
nsresult rv;
|
||||
nsXPIDLCString urlStr;
|
||||
rv = mURI->GetSpec(getter_Copies(urlStr));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
nsString name;
|
||||
name.AppendWithConversion(urlStr);
|
||||
*result = name.ToNewUnicode();
|
||||
return *result ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::IsPending(PRBool* result)
|
||||
{
|
||||
NS_NOTREACHED("nsJARChannel::IsPending");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::GetStatus(nsresult *status)
|
||||
{
|
||||
*status = mStatus;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::Cancel(nsresult status)
|
||||
{
|
||||
NS_ASSERTION(NS_FAILED(status), "shouldn't cancel with a success code");
|
||||
nsresult rv = NS_OK;
|
||||
nsAutoMonitor monitor(mMonitor);
|
||||
|
||||
if (mJarExtractionTransport) {
|
||||
rv = mJarExtractionTransport->Cancel(status);
|
||||
mJarExtractionTransport = nsnull;
|
||||
}
|
||||
|
||||
mStatus = status;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::Suspend()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsAutoMonitor monitor(mMonitor);
|
||||
|
||||
if (mJarExtractionTransport) {
|
||||
rv = mJarExtractionTransport->Suspend();
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::Resume()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsAutoMonitor monitor(mMonitor);
|
||||
|
||||
if (mJarExtractionTransport) {
|
||||
rv = mJarExtractionTransport->Resume();
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIChannel methods
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::GetOriginalURI(nsIURI* *aOriginalURI)
|
||||
{
|
||||
if (mOriginalURI)
|
||||
*aOriginalURI = mOriginalURI;
|
||||
else
|
||||
*aOriginalURI = NS_STATIC_CAST(nsIURI*, mURI);
|
||||
|
||||
NS_IF_ADDREF(*aOriginalURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::SetOriginalURI(nsIURI* aOriginalURI)
|
||||
{
|
||||
mOriginalURI = aOriginalURI;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::GetURI(nsIURI* *aURI)
|
||||
{
|
||||
*aURI = mURI;
|
||||
NS_ADDREF(*aURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsJARChannel::OpenJARElement()
|
||||
{
|
||||
nsresult rv;
|
||||
nsAutoCMonitor mon(this);
|
||||
rv = Open(nsnull, nsnull);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = GetInputStream(getter_AddRefs(mSynchronousInputStream));
|
||||
mon.Notify(); // wake up nsIChannel::Open
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::Open(nsIInputStream* *result)
|
||||
{
|
||||
nsAutoCMonitor mon(this);
|
||||
nsresult rv;
|
||||
mSynchronousRead = PR_TRUE;
|
||||
rv = EnsureJARFileAvailable();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (mSynchronousInputStream == nsnull)
|
||||
mon.Wait();
|
||||
if (mSynchronousInputStream)
|
||||
{
|
||||
*result = mSynchronousInputStream; // Result of GetInputStream called on transport thread
|
||||
NS_ADDREF(*result);
|
||||
mSynchronousInputStream = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
else
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::AsyncOpen(nsIStreamListener* listener, nsISupports* ctxt)
|
||||
{
|
||||
nsresult rv;
|
||||
mUserContext = ctxt;
|
||||
mUserListener = listener;
|
||||
|
||||
if (mLoadGroup) {
|
||||
rv = mLoadGroup->AddRequest(this, nsnull);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
mSynchronousRead = PR_FALSE;
|
||||
return EnsureJARFileAvailable();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsJARChannel::EnsureJARFileAvailable()
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIChannel> jarBaseChannel;
|
||||
nsCOMPtr<nsIFile> jarCacheFile;
|
||||
nsCOMPtr<nsIChannel> jarCacheTransport;
|
||||
nsCOMPtr<nsIInputStream> jarBaseIn;
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
nsXPIDLCString jarURLStr;
|
||||
mURI->GetSpec(getter_Copies(jarURLStr));
|
||||
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
|
||||
("nsJarProtocol: EnsureJARFileAvailable %s", (const char*)jarURLStr));
|
||||
#endif
|
||||
|
||||
rv = mURI->GetJARFile(getter_AddRefs(mJARBaseURI));
|
||||
if (NS_FAILED(rv)) goto error;
|
||||
|
||||
rv = mURI->GetJAREntry(&mJAREntry);
|
||||
if (NS_FAILED(rv)) goto error;
|
||||
|
||||
rv = NS_NewDownloader(getter_AddRefs(mDownloader),
|
||||
mJARBaseURI, this, nsnull, mSynchronousRead, mLoadGroup, mCallbacks,
|
||||
mLoadFlags);
|
||||
|
||||
// if DownloadComplete() was called early, need to release the reference.
|
||||
if (mSynchronousRead && mSynchronousInputStream)
|
||||
mDownloader = null_nsCOMPtr();
|
||||
|
||||
error:
|
||||
if (NS_FAILED(rv) && mLoadGroup) {
|
||||
nsresult rv2 = mLoadGroup->RemoveRequest(this, nsnull, NS_OK);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv2), "RemoveChannel failed");
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsJARChannel::AsyncReadJARElement()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsAutoMonitor monitor(mMonitor);
|
||||
|
||||
NS_WITH_SERVICE(nsIFileTransportService, fts, kFileTransportServiceCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsITransport> jarTransport;
|
||||
rv = fts->CreateTransportFromStreamIO(this, getter_AddRefs(jarTransport));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (mCallbacks) {
|
||||
nsCOMPtr<nsIProgressEventSink> sink = do_GetInterface(mCallbacks);
|
||||
if (sink) {
|
||||
// don't think that this is not needed anymore
|
||||
// jarTransport->SetProgressEventSink(sink);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
nsXPIDLCString jarURLStr;
|
||||
mURI->GetSpec(getter_Copies(jarURLStr));
|
||||
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
|
||||
("nsJarProtocol: AsyncRead jar entry %s", (const char*)jarURLStr));
|
||||
#endif
|
||||
|
||||
rv = jarTransport->AsyncRead(this, nsnull, 0, PRUint32(-1), 0,
|
||||
getter_AddRefs(mJarExtractionTransport));
|
||||
mJarExtractionTransport = 0;
|
||||
jarTransport = 0;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::GetLoadFlags(PRUint32* aLoadFlags)
|
||||
{
|
||||
*aLoadFlags = mLoadFlags;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::SetLoadFlags(PRUint32 aLoadFlags)
|
||||
{
|
||||
mLoadFlags = aLoadFlags;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::GetContentType(char* *aContentType)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (mContentType == nsnull) {
|
||||
if (!mJAREntry)
|
||||
return NS_ERROR_FAILURE;
|
||||
char* fileName = nsCRT::strdup(mJAREntry);
|
||||
if (fileName != nsnull) {
|
||||
PRInt32 len = nsCRT::strlen(fileName);
|
||||
const char* ext = nsnull;
|
||||
for (PRInt32 i = len-1; i >= 0; i--) {
|
||||
if (fileName[i] == '.') {
|
||||
ext = &fileName[i + 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ext) {
|
||||
nsCOMPtr<nsIMIMEService> mimeServ (do_GetService(NS_MIMESERVICE_CONTRACTID, &rv));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = mimeServ->GetTypeFromExtension(ext, &mContentType);
|
||||
}
|
||||
}
|
||||
else
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsCRT::free(fileName);
|
||||
}
|
||||
else {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
mContentType = nsCRT::strdup(UNKNOWN_CONTENT_TYPE);
|
||||
if (mContentType == nsnull)
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
else
|
||||
rv = NS_OK;
|
||||
}
|
||||
}
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
*aContentType = nsCRT::strdup(mContentType);
|
||||
if (*aContentType == nsnull)
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::SetContentType(const char *aContentType)
|
||||
{
|
||||
if (mContentType) {
|
||||
nsCRT::free(mContentType);
|
||||
}
|
||||
|
||||
mContentType = nsCRT::strdup(aContentType);
|
||||
if (!mContentType) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::GetContentLength(PRInt32* aContentLength)
|
||||
{
|
||||
if (mContentLength == -1)
|
||||
return NS_ERROR_FAILURE;
|
||||
*aContentLength = mContentLength;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::SetContentLength(PRInt32 aContentLength)
|
||||
{
|
||||
NS_NOTREACHED("nsJARChannel::SetContentLength");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup)
|
||||
{
|
||||
*aLoadGroup = mLoadGroup;
|
||||
NS_IF_ADDREF(*aLoadGroup);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
|
||||
{
|
||||
mLoadGroup = aLoadGroup;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::GetOwner(nsISupports* *aOwner)
|
||||
{
|
||||
nsresult rv;
|
||||
if (mOwner == nsnull) {
|
||||
//-- Verify signature, if one is present, and set owner accordingly
|
||||
rv = EnsureZipReader();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsIJAR> jar = do_QueryInterface(mJAR, &rv);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "Zip reader is not an nsIJAR");
|
||||
nsCOMPtr<nsIPrincipal> certificate;
|
||||
rv = jar->GetCertificatePrincipal(mJAREntry,
|
||||
getter_AddRefs(certificate));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (certificate)
|
||||
{ // Get the codebase principal
|
||||
NS_WITH_SERVICE(nsIScriptSecurityManager, secMan,
|
||||
kScriptSecurityManagerCID, &rv);
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
nsCOMPtr<nsIPrincipal> codebase;
|
||||
rv = secMan->GetCodebasePrincipal(mJARBaseURI,
|
||||
getter_AddRefs(codebase));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Join the certificate and the codebase
|
||||
nsCOMPtr<nsIAggregatePrincipal> agg;
|
||||
agg = do_QueryInterface(certificate, &rv);
|
||||
rv = agg->SetCodebase(codebase);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
mOwner = do_QueryInterface(agg, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
}
|
||||
*aOwner = mOwner;
|
||||
NS_IF_ADDREF(*aOwner);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::SetOwner(nsISupports* aOwner)
|
||||
{
|
||||
mOwner = aOwner;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::GetNotificationCallbacks(nsIInterfaceRequestor* *aNotificationCallbacks)
|
||||
{
|
||||
*aNotificationCallbacks = mCallbacks.get();
|
||||
NS_IF_ADDREF(*aNotificationCallbacks);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
|
||||
{
|
||||
mCallbacks = aNotificationCallbacks;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::GetSecurityInfo(nsISupports * *aSecurityInfo)
|
||||
{
|
||||
*aSecurityInfo = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIDownloadObserver methods:
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::OnDownloadComplete(nsIDownloader* aDownloader, nsISupports* aClosure,
|
||||
nsresult aStatus, nsIFile* aFile)
|
||||
{
|
||||
nsresult rv=aStatus;
|
||||
if(NS_SUCCEEDED(aStatus)) {
|
||||
NS_ASSERTION(!mDownloader ||(aDownloader == mDownloader.get()), "wrong downloader");
|
||||
mDownloadedJARFile = aFile;
|
||||
// after successfully downloading the jar file to the cache,
|
||||
// start the extraction process:
|
||||
if (mSynchronousRead)
|
||||
rv = OpenJARElement();
|
||||
else
|
||||
rv = AsyncReadJARElement();
|
||||
}
|
||||
mDownloader = 0;
|
||||
return rv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIRequestObserver methods:
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::OnStartRequest(nsIRequest* jarExtractionTransport,
|
||||
nsISupports* context)
|
||||
{
|
||||
return mUserListener->OnStartRequest(this, mUserContext);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::OnStopRequest(nsIRequest* jarExtractionTransport, nsISupports* context,
|
||||
nsresult aStatus)
|
||||
{
|
||||
nsresult rv;
|
||||
#ifdef PR_LOGGING
|
||||
nsCOMPtr<nsIURI> jarURI;
|
||||
nsXPIDLCString jarURLStr;
|
||||
rv = mURI->GetSpec(getter_Copies(jarURLStr));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
|
||||
("nsJarProtocol: jar extraction complete %s status=%x",
|
||||
(const char*)jarURLStr, aStatus));
|
||||
}
|
||||
#endif
|
||||
|
||||
rv = mUserListener->OnStopRequest(this, mUserContext, aStatus);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "OnStopRequest failed");
|
||||
|
||||
if (mLoadGroup)
|
||||
mLoadGroup->RemoveRequest(this, context, aStatus);
|
||||
|
||||
mUserListener = nsnull;
|
||||
mUserContext = nsnull;
|
||||
mJarExtractionTransport = nsnull;
|
||||
return rv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIStreamListener methods:
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::OnDataAvailable(nsIRequest* jarCacheTransport,
|
||||
nsISupports* context,
|
||||
nsIInputStream *inStr,
|
||||
PRUint32 sourceOffset,
|
||||
PRUint32 count)
|
||||
{
|
||||
return mUserListener->OnDataAvailable(this, mUserContext,
|
||||
inStr, sourceOffset, count);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIStreamIO methods:
|
||||
|
||||
nsresult
|
||||
nsJARChannel::EnsureZipReader()
|
||||
{
|
||||
if (mJAR == nsnull) {
|
||||
nsresult rv;
|
||||
if (mDownloadedJARFile == nsnull)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIZipReaderCache> jarCache;
|
||||
rv = mJARProtocolHandler->GetJARCache(getter_AddRefs(jarCache));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = jarCache->GetZip(mDownloadedJARFile, getter_AddRefs(mJAR));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::Open(char* *contentType, PRInt32 *contentLength)
|
||||
{
|
||||
nsresult rv;
|
||||
rv = EnsureZipReader();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsIZipEntry> entry;
|
||||
rv = mJAR->GetEntry(mJAREntry, getter_AddRefs(entry));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (contentLength) {
|
||||
rv = entry->GetRealSize((PRUint32*)contentLength);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
if (contentType) {
|
||||
rv = GetContentType(contentType);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::Close(nsresult status)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::GetInputStream(nsIInputStream* *aInputStream)
|
||||
{
|
||||
#ifdef PR_LOGGING
|
||||
nsXPIDLCString jarURLStr;
|
||||
mURI->GetSpec(getter_Copies(jarURLStr));
|
||||
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
|
||||
("nsJarProtocol: GetInputStream jar entry %s", (const char*)jarURLStr));
|
||||
#endif
|
||||
NS_ENSURE_TRUE(mJAR, NS_ERROR_NULL_POINTER);
|
||||
return mJAR->GetInputStream(mJAREntry, aInputStream);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::GetOutputStream(nsIOutputStream* *aOutputStream)
|
||||
{
|
||||
NS_NOTREACHED("nsJARChannel::GetOutputStream");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::GetName(char* *aName)
|
||||
{
|
||||
return mURI->GetSpec(aName);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIJARChannel methods:
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::EnumerateEntries(const char *aRoot, nsISimpleEnumerator **_retval)
|
||||
{
|
||||
NS_NOTREACHED("nsJARChannel::EnumerateEntries");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1,111 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998,2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#ifndef nsJARChannel_h__
|
||||
#define nsJARChannel_h__
|
||||
|
||||
#include "nsIJARChannel.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIJARProtocolHandler.h"
|
||||
#include "nsIJARURI.h"
|
||||
#include "nsIStreamIO.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIZipReader.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsILoadGroup.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIFile.h"
|
||||
#include "prmon.h"
|
||||
#include "nsIDownloader.h"
|
||||
#include "nsIInputStream.h"
|
||||
|
||||
class nsIFileChannel;
|
||||
class nsJARChannel;
|
||||
|
||||
#define NS_JARCHANNEL_CID \
|
||||
{ /* 0xc7e410d5-0x85f2-11d3-9f63-006008a6efe9 */ \
|
||||
0xc7e410d5, \
|
||||
0x85f2, \
|
||||
0x11d3, \
|
||||
{0x9f, 0x63, 0x00, 0x60, 0x08, 0xa6, 0xef, 0xe9} \
|
||||
}
|
||||
|
||||
class nsJARChannel : public nsIJARChannel,
|
||||
public nsIStreamListener,
|
||||
public nsIStreamIO,
|
||||
public nsIDownloadObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIREQUEST
|
||||
NS_DECL_NSICHANNEL
|
||||
NS_DECL_NSIJARCHANNEL
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
NS_DECL_NSISTREAMIO
|
||||
NS_DECL_NSIDOWNLOADOBSERVER
|
||||
|
||||
nsJARChannel();
|
||||
virtual ~nsJARChannel();
|
||||
|
||||
// Define a Create method to be used with a factory:
|
||||
static NS_METHOD
|
||||
Create(nsISupports* aOuter, REFNSIID aIID, void **aResult);
|
||||
|
||||
nsresult Init(nsIJARProtocolHandler* aHandler, nsIURI* uri);
|
||||
nsresult EnsureJARFileAvailable();
|
||||
nsresult OpenJARElement();
|
||||
nsresult AsyncReadJARElement();
|
||||
nsresult EnsureZipReader();
|
||||
|
||||
friend class nsJARDownloadObserver;
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIJARProtocolHandler> mJARProtocolHandler;
|
||||
nsCOMPtr<nsIJARURI> mURI;
|
||||
nsCOMPtr<nsILoadGroup> mLoadGroup;
|
||||
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
|
||||
nsCOMPtr<nsIURI> mOriginalURI;
|
||||
nsLoadFlags mLoadFlags;
|
||||
nsCOMPtr<nsISupports> mOwner;
|
||||
|
||||
nsCOMPtr<nsISupports> mUserContext;
|
||||
nsCOMPtr<nsIStreamListener> mUserListener;
|
||||
|
||||
char* mContentType;
|
||||
PRInt32 mContentLength;
|
||||
nsCOMPtr<nsIURI> mJARBaseURI;
|
||||
char* mJAREntry;
|
||||
nsCOMPtr<nsIZipReader> mJAR;
|
||||
nsCOMPtr<nsIFile> mDownloadedJARFile;
|
||||
nsresult mStatus;
|
||||
PRBool mSynchronousRead;
|
||||
nsCOMPtr<nsIInputStream> mSynchronousInputStream;
|
||||
|
||||
PRMonitor* mMonitor;
|
||||
nsCOMPtr<nsIDownloader> mDownloader;
|
||||
nsCOMPtr<nsIRequest> mJarExtractionTransport;
|
||||
|
||||
};
|
||||
|
||||
#endif // nsJARChannel_h__
|
||||
@@ -1,162 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#include "nsJARProtocolHandler.h"
|
||||
#include "nsIIOService.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsJARURI.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsJARChannel.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsNetCID.h"
|
||||
|
||||
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
|
||||
static NS_DEFINE_CID(kJARUriCID, NS_JARURI_CID);
|
||||
static NS_DEFINE_CID(kZipReaderCacheCID, NS_ZIPREADERCACHE_CID);
|
||||
|
||||
#define NS_JAR_CACHE_SIZE 32
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsJARProtocolHandler::nsJARProtocolHandler()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsJARProtocolHandler::Init()
|
||||
{
|
||||
nsresult rv;
|
||||
rv = nsComponentManager::CreateInstance(kZipReaderCacheCID,
|
||||
nsnull,
|
||||
NS_GET_IID(nsIZipReaderCache),
|
||||
getter_AddRefs(mJARCache));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = mJARCache->Init(NS_JAR_CACHE_SIZE);
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsJARProtocolHandler::~nsJARProtocolHandler()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS2(nsJARProtocolHandler,
|
||||
nsIJARProtocolHandler,
|
||||
nsIProtocolHandler)
|
||||
|
||||
NS_METHOD
|
||||
nsJARProtocolHandler::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
||||
{
|
||||
if (aOuter)
|
||||
return NS_ERROR_NO_AGGREGATION;
|
||||
|
||||
nsJARProtocolHandler* ph = new nsJARProtocolHandler();
|
||||
if (ph == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(ph);
|
||||
nsresult rv = ph->Init();
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = ph->QueryInterface(aIID, aResult);
|
||||
}
|
||||
NS_RELEASE(ph);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARProtocolHandler::GetJARCache(nsIZipReaderCache* *result)
|
||||
{
|
||||
*result = mJARCache;
|
||||
NS_ADDREF(*result);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIProtocolHandler methods:
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARProtocolHandler::GetScheme(char* *result)
|
||||
{
|
||||
*result = nsCRT::strdup("jar");
|
||||
if (*result == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARProtocolHandler::GetDefaultPort(PRInt32 *result)
|
||||
{
|
||||
*result = -1; // no port for JAR: URLs
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARProtocolHandler::NewURI(const char *aSpec, nsIURI *aBaseURI,
|
||||
nsIURI **result)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsIURI* url;
|
||||
|
||||
rv = nsJARURI::Create(nsnull, NS_GET_IID(nsIJARURI), (void**)&url);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (aBaseURI)
|
||||
{
|
||||
nsXPIDLCString aResolvedURI;
|
||||
rv = aBaseURI->Resolve(aSpec, getter_Copies(aResolvedURI));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = url->SetSpec(aResolvedURI);
|
||||
} else {
|
||||
rv = url->SetSpec((char*)aSpec);
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_RELEASE(url);
|
||||
return rv;
|
||||
}
|
||||
|
||||
*result = url;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsJARChannel* channel;
|
||||
rv = nsJARChannel::Create(nsnull, NS_GET_IID(nsIJARChannel), (void**)&channel);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = channel->Init(this, uri);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_RELEASE(channel);
|
||||
return rv;
|
||||
}
|
||||
|
||||
*result = channel;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1,61 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#ifndef nsJARProtocolHandler_h___
|
||||
#define nsJARProtocolHandler_h___
|
||||
|
||||
#include "nsIJARProtocolHandler.h"
|
||||
#include "nsIProtocolHandler.h"
|
||||
#include "nsIJARURI.h"
|
||||
#include "nsIZipReader.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#define NS_JARPROTOCOLHANDLER_CID \
|
||||
{ /* 0xc7e410d4-0x85f2-11d3-9f63-006008a6efe9 */ \
|
||||
0xc7e410d4, \
|
||||
0x85f2, \
|
||||
0x11d3, \
|
||||
{0x9f, 0x63, 0x00, 0x60, 0x08, 0xa6, 0xef, 0xe9} \
|
||||
}
|
||||
|
||||
|
||||
class nsJARProtocolHandler : public nsIJARProtocolHandler
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPROTOCOLHANDLER
|
||||
NS_DECL_NSIJARPROTOCOLHANDLER
|
||||
|
||||
// nsJARProtocolHandler methods:
|
||||
nsJARProtocolHandler();
|
||||
virtual ~nsJARProtocolHandler();
|
||||
|
||||
static NS_METHOD
|
||||
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
|
||||
|
||||
nsresult Init();
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIZipReaderCache> mJARCache;
|
||||
};
|
||||
|
||||
#endif /* nsJARProtocolHandler_h___ */
|
||||
@@ -1,38 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
#include "nsIModule.h"
|
||||
#include "nsIGenericFactory.h"
|
||||
#include "nsJARProtocolHandler.h"
|
||||
|
||||
|
||||
static nsModuleComponentInfo components[] =
|
||||
{
|
||||
{ "JAR Protocol Handler",
|
||||
NS_JARPROTOCOLHANDLER_CID,
|
||||
NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "jar",
|
||||
nsJARProtocolHandler::Create
|
||||
},
|
||||
};
|
||||
|
||||
NS_IMPL_NSGETMODULE(nsJarProtocolModule, components);
|
||||
|
||||
|
||||
@@ -1,396 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsJARURI.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsIIOService.h"
|
||||
#include "nsFileSpec.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIZipReader.h"
|
||||
|
||||
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsJARURI::nsJARURI()
|
||||
: mJAREntry(nsnull)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
nsJARURI::~nsJARURI()
|
||||
{
|
||||
if (mJAREntry)
|
||||
nsMemory::Free(mJAREntry);
|
||||
}
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS2(nsJARURI, nsIJARURI, nsIURI)
|
||||
|
||||
NS_METHOD
|
||||
nsJARURI::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
||||
{
|
||||
if (aOuter)
|
||||
return NS_ERROR_NO_AGGREGATION;
|
||||
|
||||
nsJARURI* uri = new nsJARURI();
|
||||
|
||||
if (uri == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(uri);
|
||||
nsresult rv = uri->Init();
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = uri->QueryInterface(aIID, aResult);
|
||||
}
|
||||
NS_RELEASE(uri);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsJARURI::Init()
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#define NS_JAR_SCHEME "jar:"
|
||||
#define NS_JAR_DELIMITER "!/"
|
||||
|
||||
nsresult
|
||||
nsJARURI::FormatSpec(const char* entryPath, char* *result)
|
||||
{
|
||||
nsresult rv;
|
||||
char* jarFileSpec;
|
||||
rv = mJARFile->GetSpec(&jarFileSpec);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCString spec(NS_JAR_SCHEME);
|
||||
spec += jarFileSpec;
|
||||
nsCRT::free(jarFileSpec);
|
||||
spec += NS_JAR_DELIMITER;
|
||||
spec += entryPath;
|
||||
|
||||
*result = nsCRT::strdup(spec);
|
||||
return *result ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsURI methods:
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARURI::GetSpec(char* *aSpec)
|
||||
{
|
||||
return FormatSpec(mJAREntry, aSpec);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARURI::SetSpec(const char * aSpec)
|
||||
{
|
||||
nsresult rv;
|
||||
NS_WITH_SERVICE(nsIIOService, serv, kIOServiceCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
PRUint32 startPos, endPos;
|
||||
rv = serv->ExtractScheme(aSpec, &startPos, &endPos, nsnull);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (nsCRT::strncmp("jar", &aSpec[startPos], endPos - startPos - 1) != 0)
|
||||
return NS_ERROR_MALFORMED_URI;
|
||||
|
||||
// Search backward from the end for the "!/" delimiter. Remember, jar URLs
|
||||
// can nest, e.g.:
|
||||
// jar:jar:http://www.foo.com/bar.jar!/a.jar!/b.html
|
||||
// This gets the b.html document from out of the a.jar file, that's
|
||||
// contained within the bar.jar file.
|
||||
|
||||
nsCAutoString jarPath(aSpec);
|
||||
PRInt32 pos = jarPath.RFind(NS_JAR_DELIMITER);
|
||||
if (pos == -1 || endPos + 1 > (PRUint32)pos)
|
||||
return NS_ERROR_MALFORMED_URI;
|
||||
|
||||
jarPath.Cut(pos, jarPath.Length());
|
||||
jarPath.Cut(0, endPos);
|
||||
|
||||
rv = serv->NewURI(jarPath, nsnull, getter_AddRefs(mJARFile));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCAutoString entry(aSpec);
|
||||
entry.Cut(0, pos + 2); // 2 == strlen(NS_JAR_DELIMITER)
|
||||
while (entry.CharAt(0) == '/')
|
||||
entry.Cut(0,1); // Strip any additional leading slashes from entry path
|
||||
|
||||
rv = serv->ResolveRelativePath(entry, nsnull, &mJAREntry);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARURI::GetPrePath(char* *prePath)
|
||||
{
|
||||
*prePath = nsCRT::strdup("jar:");
|
||||
return *prePath ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARURI::SetPrePath(const char* prePath)
|
||||
{
|
||||
NS_NOTREACHED("nsJARURI::SetPrePath");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARURI::GetScheme(char * *aScheme)
|
||||
{
|
||||
*aScheme = nsCRT::strdup("jar");
|
||||
return *aScheme ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARURI::SetScheme(const char * aScheme)
|
||||
{
|
||||
// doesn't make sense to set the scheme of a jar: URL
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARURI::GetUsername(char * *aUsername)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARURI::SetUsername(const char * aUsername)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARURI::GetPassword(char * *aPassword)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARURI::SetPassword(const char * aPassword)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARURI::GetPreHost(char * *aPreHost)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARURI::SetPreHost(const char * aPreHost)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARURI::GetHost(char * *aHost)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARURI::SetHost(const char * aHost)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARURI::GetPort(PRInt32 *aPort)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARURI::SetPort(PRInt32 aPort)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARURI::GetPath(char * *aPath)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARURI::SetPath(const char * aPath)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARURI::Equals(nsIURI *other, PRBool *result)
|
||||
{
|
||||
nsresult rv;
|
||||
*result = PR_FALSE;
|
||||
|
||||
if (other == nsnull)
|
||||
return NS_OK; // not equal
|
||||
|
||||
nsJARURI* otherJAR;
|
||||
rv = other->QueryInterface(NS_GET_IID(nsIJARURI), (void**)&otherJAR);
|
||||
if (NS_FAILED(rv))
|
||||
return NS_OK; // not equal
|
||||
|
||||
nsCOMPtr<nsIURI> otherJARFile;
|
||||
rv = otherJAR->GetJARFile(getter_AddRefs(otherJARFile));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
PRBool equal;
|
||||
rv = mJARFile->Equals(otherJARFile, &equal);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (!equal)
|
||||
return NS_OK; // not equal
|
||||
|
||||
char* otherJAREntry;
|
||||
rv = otherJAR->GetJAREntry(&otherJAREntry);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
*result = nsCRT::strcmp(mJAREntry, otherJAREntry) == 0;
|
||||
nsCRT::free(otherJAREntry);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARURI::SchemeIs(const char *i_Scheme, PRBool *o_Equals)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(o_Equals);
|
||||
if (!i_Scheme) return NS_ERROR_INVALID_ARG;
|
||||
|
||||
if (*i_Scheme == 'j' || *i_Scheme == 'J') {
|
||||
*o_Equals = PL_strcasecmp("jar", i_Scheme) ? PR_FALSE : PR_TRUE;
|
||||
} else {
|
||||
*o_Equals = PR_FALSE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARURI::Clone(nsIURI **result)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIURI> newJARFile;
|
||||
rv = mJARFile->Clone(getter_AddRefs(newJARFile));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
char* newJAREntry = nsCRT::strdup(mJAREntry);
|
||||
if (newJAREntry == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsJARURI* uri = new nsJARURI();
|
||||
if (uri == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(uri);
|
||||
uri->mJARFile = newJARFile;
|
||||
uri->mJAREntry = newJAREntry;
|
||||
*result = uri;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARURI::Resolve(const char *relativePath, char **result)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (!relativePath) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
NS_WITH_SERVICE(nsIIOService, serv, kIOServiceCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsXPIDLCString scheme;
|
||||
rv = serv->ExtractScheme(relativePath, nsnull, nsnull, getter_Copies(scheme));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// then aSpec is absolute
|
||||
*result = nsCRT::strdup(relativePath);
|
||||
if (*result == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCAutoString path(mJAREntry);
|
||||
PRInt32 pos = path.RFind("/");
|
||||
if (pos >= 0)
|
||||
path.Truncate(pos + 1);
|
||||
else
|
||||
path = "";
|
||||
|
||||
char* resolvedEntry;
|
||||
rv = serv->ResolveRelativePath(relativePath, path.get(),
|
||||
&resolvedEntry);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = FormatSpec(resolvedEntry, result);
|
||||
nsCRT::free(resolvedEntry);
|
||||
return rv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIJARUri methods:
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARURI::GetJARFile(nsIURI* *jarFile)
|
||||
{
|
||||
*jarFile = mJARFile;
|
||||
NS_ADDREF(*jarFile);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARURI::SetJARFile(nsIURI* jarFile)
|
||||
{
|
||||
mJARFile = jarFile;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARURI::GetJAREntry(char* *entryPath)
|
||||
{
|
||||
nsCAutoString entry(mJAREntry);
|
||||
PRInt32 pos = entry.RFindCharInSet("#?;");
|
||||
if (pos >= 0)
|
||||
entry.Truncate(pos);
|
||||
*entryPath = entry.ToNewCString();
|
||||
return *entryPath ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARURI::SetJAREntry(const char* entryPath)
|
||||
{
|
||||
nsresult rv;
|
||||
NS_WITH_SERVICE(nsIIOService, serv, kIOServiceCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (mJAREntry)
|
||||
nsCRT::free(mJAREntry);
|
||||
|
||||
rv = serv->ResolveRelativePath(entryPath, nsnull, &mJAREntry);
|
||||
return rv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1,55 +0,0 @@
|
||||
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsJARURI_h__
|
||||
#define nsJARURI_h__
|
||||
|
||||
#include "nsIJARURI.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#define NS_JARURI_CID \
|
||||
{ /* 0xc7e410d7-0x85f2-11d3-9f63-006008a6efe9 */ \
|
||||
0xc7e410d7, \
|
||||
0x85f2, \
|
||||
0x11d3, \
|
||||
{0x9f, 0x63, 0x00, 0x60, 0x08, 0xa6, 0xef, 0xe9} \
|
||||
}
|
||||
|
||||
class nsJARURI : public nsIJARURI
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIURI
|
||||
NS_DECL_NSIJARURI
|
||||
|
||||
// nsJARURI
|
||||
nsJARURI();
|
||||
virtual ~nsJARURI();
|
||||
|
||||
static NS_METHOD
|
||||
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
|
||||
|
||||
nsresult Init();
|
||||
nsresult FormatSpec(const char* entryPath, char* *result);
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIURI> mJARFile;
|
||||
char *mJAREntry;
|
||||
};
|
||||
|
||||
#endif // nsJARURI_h__
|
||||
@@ -1,221 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*/
|
||||
|
||||
#include "imgCache.h"
|
||||
|
||||
#include "ImageLogging.h"
|
||||
|
||||
#include "imgRequest.h"
|
||||
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIServiceManager.h"
|
||||
|
||||
#include "nsICache.h"
|
||||
#include "nsICacheService.h"
|
||||
#include "nsICacheSession.h"
|
||||
#include "nsICacheEntryDescriptor.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS1(imgCache, imgICache)
|
||||
|
||||
imgCache::imgCache()
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
/* member initializers and constructor code */
|
||||
}
|
||||
|
||||
imgCache::~imgCache()
|
||||
{
|
||||
/* destructor code */
|
||||
}
|
||||
|
||||
/* void clearCache (in boolean chrome); */
|
||||
NS_IMETHODIMP imgCache::ClearCache(PRBool chrome)
|
||||
{
|
||||
if (chrome)
|
||||
return imgCache::ClearChromeImageCache();
|
||||
else
|
||||
return imgCache::ClearImageCache();
|
||||
}
|
||||
|
||||
static nsCOMPtr<nsICacheSession> gSession = nsnull;
|
||||
static nsCOMPtr<nsICacheSession> gChromeSession = nsnull;
|
||||
|
||||
void GetCacheSession(nsIURI *aURI, nsICacheSession **_retval)
|
||||
{
|
||||
NS_ASSERTION(aURI, "Null URI!");
|
||||
|
||||
PRBool isChrome = PR_FALSE;
|
||||
aURI->SchemeIs("chrome", &isChrome);
|
||||
|
||||
if (gSession && !isChrome) {
|
||||
*_retval = gSession;
|
||||
NS_ADDREF(*_retval);
|
||||
return;
|
||||
}
|
||||
|
||||
if (gChromeSession && isChrome) {
|
||||
*_retval = gChromeSession;
|
||||
NS_ADDREF(*_retval);
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsICacheService> cacheService(do_GetService("@mozilla.org/network/cache-service;1"));
|
||||
if (!cacheService) {
|
||||
NS_WARNING("Unable to get the cache service");
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsICacheSession> newSession;
|
||||
cacheService->CreateSession(isChrome ? "image-chrome" : "image",
|
||||
nsICache::NOT_STREAM_BASED,
|
||||
PR_FALSE, getter_AddRefs(newSession));
|
||||
|
||||
if (!newSession) {
|
||||
NS_WARNING("Unable to create a cache session");
|
||||
return;
|
||||
}
|
||||
|
||||
if (isChrome)
|
||||
gChromeSession = newSession;
|
||||
else
|
||||
gSession = newSession;
|
||||
|
||||
*_retval = newSession;
|
||||
NS_ADDREF(*_retval);
|
||||
}
|
||||
|
||||
|
||||
void imgCache::Shutdown()
|
||||
{
|
||||
gSession = nsnull;
|
||||
gChromeSession = nsnull;
|
||||
}
|
||||
|
||||
|
||||
nsresult imgCache::ClearChromeImageCache()
|
||||
{
|
||||
if (!gChromeSession)
|
||||
return NS_OK;
|
||||
|
||||
return gChromeSession->EvictEntries();
|
||||
}
|
||||
|
||||
nsresult imgCache::ClearImageCache()
|
||||
{
|
||||
if (!gSession)
|
||||
return NS_OK;
|
||||
|
||||
return gSession->EvictEntries();
|
||||
}
|
||||
|
||||
PRBool imgCache::Put(nsIURI *aKey, imgRequest *request, nsICacheEntryDescriptor **aEntry)
|
||||
{
|
||||
LOG_STATIC_FUNC(gImgLog, "imgCache::Put");
|
||||
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsICacheSession> ses;
|
||||
GetCacheSession(aKey, getter_AddRefs(ses));
|
||||
if (!ses) return PR_FALSE;
|
||||
|
||||
nsXPIDLCString spec;
|
||||
aKey->GetSpec(getter_Copies(spec));
|
||||
|
||||
nsCOMPtr<nsICacheEntryDescriptor> entry;
|
||||
|
||||
rv = ses->OpenCacheEntry(spec, nsICache::ACCESS_WRITE, nsICache::BLOCKING, getter_AddRefs(entry));
|
||||
|
||||
if (NS_FAILED(rv) || !entry)
|
||||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsISupports> sup(do_QueryInterface(NS_STATIC_CAST(imgIRequest*, request)));
|
||||
entry->SetCacheElement(sup);
|
||||
|
||||
entry->MarkValid();
|
||||
|
||||
*aEntry = entry;
|
||||
NS_ADDREF(*aEntry);
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool imgCache::Get(nsIURI *aKey, imgRequest **aRequest, nsICacheEntryDescriptor **aEntry)
|
||||
{
|
||||
LOG_STATIC_FUNC(gImgLog, "imgCache::Get");
|
||||
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsICacheSession> ses;
|
||||
GetCacheSession(aKey, getter_AddRefs(ses));
|
||||
if (!ses) return PR_FALSE;
|
||||
|
||||
nsXPIDLCString spec;
|
||||
aKey->GetSpec(getter_Copies(spec));
|
||||
|
||||
nsCOMPtr<nsICacheEntryDescriptor> entry;
|
||||
|
||||
rv = ses->OpenCacheEntry(spec, nsICache::ACCESS_READ, nsICache::BLOCKING, getter_AddRefs(entry));
|
||||
|
||||
if (NS_FAILED(rv) || !entry)
|
||||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsISupports> sup;
|
||||
entry->GetCacheElement(getter_AddRefs(sup));
|
||||
|
||||
nsCOMPtr<imgIRequest> req(do_QueryInterface(sup));
|
||||
*aRequest = NS_REINTERPRET_CAST(imgRequest*, req.get());
|
||||
NS_IF_ADDREF(*aRequest);
|
||||
|
||||
*aEntry = entry;
|
||||
NS_ADDREF(*aEntry);
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
||||
PRBool imgCache::Remove(nsIURI *aKey)
|
||||
{
|
||||
LOG_STATIC_FUNC(gImgLog, "imgCache::Remove");
|
||||
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsICacheSession> ses;
|
||||
GetCacheSession(aKey, getter_AddRefs(ses));
|
||||
if (!ses) return PR_FALSE;
|
||||
|
||||
nsXPIDLCString spec;
|
||||
aKey->GetSpec(getter_Copies(spec));
|
||||
|
||||
nsCOMPtr<nsICacheEntryDescriptor> entry;
|
||||
|
||||
rv = ses->OpenCacheEntry(spec, nsICache::ACCESS_READ, nsICache::BLOCKING, getter_AddRefs(entry));
|
||||
|
||||
if (NS_FAILED(rv) || !entry)
|
||||
return PR_FALSE;
|
||||
|
||||
entry->Doom();
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
@@ -1,388 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "imgLoader.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
#include "nsIIOService.h"
|
||||
#include "nsILoadGroup.h"
|
||||
#include "nsIProxyObjectManager.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsXPIDLString.h"
|
||||
|
||||
#include "imgCache.h"
|
||||
#include "imgRequest.h"
|
||||
#include "imgRequestProxy.h"
|
||||
|
||||
#include "ImageLogging.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS1(imgLoader, imgILoader)
|
||||
|
||||
imgLoader::imgLoader()
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
/* member initializers and constructor code */
|
||||
}
|
||||
|
||||
imgLoader::~imgLoader()
|
||||
{
|
||||
/* destructor code */
|
||||
}
|
||||
|
||||
/* imgIRequest loadImage (in nsIURI uri, in nsILoadGroup aLoadGroup, in imgIDecoderObserver aObserver, in nsISupports cx); */
|
||||
NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI, nsILoadGroup *aLoadGroup, imgIDecoderObserver *aObserver, nsISupports *cx, imgIRequest **_retval)
|
||||
{
|
||||
NS_ASSERTION(aURI, "imgLoader::LoadImage -- NULL URI pointer");
|
||||
|
||||
if (!aURI)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
nsXPIDLCString spec;
|
||||
aURI->GetSpec(getter_Copies(spec));
|
||||
LOG_SCOPE_WITH_PARAM(gImgLog, "imgLoader::LoadImage", "aURI", spec.get());
|
||||
#endif
|
||||
|
||||
imgRequest *request = nsnull;
|
||||
|
||||
nsCOMPtr<nsICacheEntryDescriptor> entry;
|
||||
imgCache::Get(aURI, &request, getter_AddRefs(entry)); // addrefs request
|
||||
|
||||
if (request && entry && aLoadGroup) {
|
||||
/* this isn't exactly what I want here. This code will re-doom every
|
||||
cache hit in a document while it is force reloading. So for multiple
|
||||
copies of an image on a page, when you force reload, this will cause
|
||||
you to get seperate loads for each copy of the image... this sucks.
|
||||
*/
|
||||
PRUint32 flags = 0;
|
||||
PRBool doomRequest = PR_FALSE;
|
||||
aLoadGroup->GetLoadFlags(&flags);
|
||||
if (flags & nsIRequest::LOAD_BYPASS_CACHE)
|
||||
doomRequest = PR_TRUE;
|
||||
else {
|
||||
nsCOMPtr<nsIRequest> r;
|
||||
aLoadGroup->GetDefaultLoadRequest(getter_AddRefs(r));
|
||||
if (r) {
|
||||
r->GetLoadFlags(&flags);
|
||||
if (flags & nsIRequest::LOAD_BYPASS_CACHE)
|
||||
doomRequest = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (doomRequest) {
|
||||
entry->Doom(); // doom this thing.
|
||||
entry = nsnull;
|
||||
NS_RELEASE(request);
|
||||
request = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
if (!request) {
|
||||
/* no request from the cache. do a new load */
|
||||
LOG_SCOPE(gImgLog, "imgLoader::LoadImage |cache miss|");
|
||||
|
||||
nsCOMPtr<nsIIOService> ioserv(do_GetService("@mozilla.org/network/io-service;1"));
|
||||
if (!ioserv) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIChannel> newChannel;
|
||||
ioserv->NewChannelFromURI(aURI, getter_AddRefs(newChannel));
|
||||
if (!newChannel) return NS_ERROR_FAILURE;
|
||||
|
||||
if (aLoadGroup) {
|
||||
PRUint32 flags;
|
||||
aLoadGroup->GetLoadFlags(&flags);
|
||||
newChannel->SetLoadFlags(flags);
|
||||
}
|
||||
|
||||
NS_NEWXPCOM(request, imgRequest);
|
||||
if (!request) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(request);
|
||||
|
||||
PR_LOG(gImgLog, PR_LOG_DEBUG,
|
||||
("[this=%p] imgLoader::LoadImage -- Created new imgRequest [request=%p]\n", this, request));
|
||||
|
||||
#ifdef MOZ_NEW_CACHE
|
||||
imgCache::Put(aURI, request, getter_AddRefs(entry));
|
||||
|
||||
request->Init(newChannel, entry);
|
||||
#else
|
||||
request->Init(newChannel, nsnull);
|
||||
#endif
|
||||
|
||||
PR_LOG(gImgLog, PR_LOG_DEBUG,
|
||||
("[this=%p] imgLoader::LoadImage -- Calling channel->AsyncOpen()\n", this));
|
||||
|
||||
// create the proxy listener
|
||||
ProxyListener *pl = new ProxyListener(NS_STATIC_CAST(nsIStreamListener *, request));
|
||||
if (!pl) {
|
||||
NS_RELEASE(request);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_ADDREF(pl);
|
||||
|
||||
// set the referrer if this is an HTTP request
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(newChannel));
|
||||
if (aLoadGroup && httpChannel) {
|
||||
nsresult rv;
|
||||
// Get the defloadRequest from the loadgroup
|
||||
nsCOMPtr<nsIRequest> defLoadRequest;
|
||||
rv = aLoadGroup->GetDefaultLoadRequest(getter_AddRefs(defLoadRequest));
|
||||
|
||||
if (NS_SUCCEEDED(rv) && defLoadRequest) {
|
||||
nsCOMPtr<nsIChannel> reqChannel(do_QueryInterface(defLoadRequest));
|
||||
|
||||
if (reqChannel) {
|
||||
// Get the referrer from the loadchannel
|
||||
nsCOMPtr<nsIURI> referrer;
|
||||
rv = reqChannel->GetURI(getter_AddRefs(referrer));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// Set the referrer
|
||||
httpChannel->SetReferrer(referrer, nsIHttpChannel::REFERRER_INLINES);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX Are we calling AsyncOpen() too early? Is it possible for
|
||||
AsyncOpen to result in an OnStartRequest to the channel before
|
||||
we call CreateNewProxyForRequest() ?
|
||||
*/
|
||||
nsresult asyncOpenResult = newChannel->AsyncOpen(NS_STATIC_CAST(nsIStreamListener *, pl), nsnull);
|
||||
|
||||
NS_RELEASE(pl);
|
||||
|
||||
if (NS_FAILED(asyncOpenResult)) {
|
||||
/* If AsyncOpen fails, then we want to hand back a request proxy
|
||||
object that has a canceled load.
|
||||
*/
|
||||
LOG_MSG(gImgLog, "imgLoader::LoadImage", "async open failed.");
|
||||
|
||||
nsresult rv = CreateNewProxyForRequest(request, aLoadGroup, aObserver,
|
||||
cx, _retval);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
request->OnStartRequest(newChannel, nsnull);
|
||||
request->OnStopRequest(newChannel, nsnull, NS_BINDING_ABORTED);
|
||||
}
|
||||
|
||||
NS_RELEASE(request);
|
||||
|
||||
return asyncOpenResult;
|
||||
}
|
||||
|
||||
} else {
|
||||
/* request found in cache. use it */
|
||||
LOG_MSG_WITH_PARAM(gImgLog, "imgLoader::LoadImage |cache hit|", "request", request);
|
||||
}
|
||||
|
||||
LOG_MSG(gImgLog, "imgLoader::LoadImage", "creating proxy request.");
|
||||
|
||||
nsresult rv = CreateNewProxyForRequest(request, aLoadGroup, aObserver, cx, _retval);
|
||||
|
||||
NS_RELEASE(request);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* imgIRequest loadImageWithChannel(in nsIChannel, in imgIDecoderObserver aObserver, in nsISupports cx, out nsIStreamListener); */
|
||||
NS_IMETHODIMP imgLoader::LoadImageWithChannel(nsIChannel *channel, imgIDecoderObserver *aObserver, nsISupports *cx, nsIStreamListener **listener, imgIRequest **_retval)
|
||||
{
|
||||
NS_ASSERTION(channel, "imgLoader::LoadImageWithChannel -- NULL channel pointer");
|
||||
|
||||
imgRequest *request = nsnull;
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
channel->GetOriginalURI(getter_AddRefs(uri));
|
||||
|
||||
nsCOMPtr<nsICacheEntryDescriptor> entry;
|
||||
imgCache::Get(uri, &request, getter_AddRefs(entry)); // addrefs request
|
||||
|
||||
if (request) {
|
||||
// we have this in our cache already.. cancel the current (document) load
|
||||
|
||||
/* XXX If |*listener| is null when we return here, the caller should
|
||||
probably cancel the channel instead of us doing it here.
|
||||
*/
|
||||
channel->Cancel(NS_BINDING_ABORTED); // this should fire an OnStopRequest
|
||||
|
||||
*listener = nsnull; // give them back a null nsIStreamListener
|
||||
} else {
|
||||
NS_NEWXPCOM(request, imgRequest);
|
||||
if (!request) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(request);
|
||||
|
||||
imgCache::Put(uri, request, getter_AddRefs(entry));
|
||||
|
||||
request->Init(channel, entry);
|
||||
|
||||
ProxyListener *pl = new ProxyListener(NS_STATIC_CAST(nsIStreamListener *, request));
|
||||
if (!pl) {
|
||||
NS_RELEASE(request);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_ADDREF(pl);
|
||||
|
||||
*listener = NS_STATIC_CAST(nsIStreamListener*, pl);
|
||||
NS_ADDREF(*listener);
|
||||
|
||||
NS_RELEASE(pl);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsILoadGroup> loadGroup;
|
||||
channel->GetLoadGroup(getter_AddRefs(loadGroup));
|
||||
|
||||
nsresult rv = CreateNewProxyForRequest(request, loadGroup, aObserver, cx, _retval);
|
||||
|
||||
NS_RELEASE(request);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
|
||||
nsresult
|
||||
imgLoader::CreateNewProxyForRequest(imgRequest *aRequest, nsILoadGroup *aLoadGroup,
|
||||
imgIDecoderObserver *aObserver, nsISupports *cx,
|
||||
imgIRequest **_retval)
|
||||
{
|
||||
LOG_SCOPE_WITH_PARAM(gImgLog, "imgLoader::CreateNewProxyForRequest", "imgRequest", aRequest);
|
||||
|
||||
/* XXX If we move decoding onto seperate threads, we should save off the
|
||||
calling thread here and pass it off to |proxyRequest| so that it call
|
||||
proxy calls to |aObserver|.
|
||||
*/
|
||||
|
||||
imgRequestProxy *proxyRequest;
|
||||
NS_NEWXPCOM(proxyRequest, imgRequestProxy);
|
||||
if (!proxyRequest) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(proxyRequest);
|
||||
|
||||
// init adds itself to imgRequest's list of observers
|
||||
nsresult rv = proxyRequest->Init(aRequest, aLoadGroup, aObserver, cx);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_RELEASE(proxyRequest);
|
||||
return rv;
|
||||
}
|
||||
|
||||
*_retval = NS_STATIC_CAST(imgIRequest*, proxyRequest);
|
||||
NS_ADDREF(*_retval);
|
||||
|
||||
NS_RELEASE(proxyRequest);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* proxy stream listener class used to handle multipart/x-mixed-replace
|
||||
*/
|
||||
|
||||
#include "nsIRequest.h"
|
||||
#include "nsIStreamConverterService.h"
|
||||
#include "nsXPIDLString.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS2(ProxyListener, nsIStreamListener, nsIRequestObserver)
|
||||
|
||||
ProxyListener::ProxyListener(nsIStreamListener *dest) :
|
||||
mDestListener(dest)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
/* member initializers and constructor code */
|
||||
}
|
||||
|
||||
ProxyListener::~ProxyListener()
|
||||
{
|
||||
/* destructor code */
|
||||
}
|
||||
|
||||
|
||||
/** nsIRequestObserver methods **/
|
||||
|
||||
/* void onStartRequest (in nsIRequest request, in nsISupports ctxt); */
|
||||
NS_IMETHODIMP ProxyListener::OnStartRequest(nsIRequest *aRequest, nsISupports *ctxt)
|
||||
{
|
||||
if (!mDestListener)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
|
||||
if (channel) {
|
||||
nsXPIDLCString contentType;
|
||||
nsresult rv = channel->GetContentType(getter_Copies(contentType));
|
||||
|
||||
if (contentType.get()) {
|
||||
/* If multipart/x-mixed-replace content, we'll insert a MIME decoder
|
||||
in the pipeline to handle the content and pass it along to our
|
||||
original listener.
|
||||
*/
|
||||
if (NS_LITERAL_CSTRING("multipart/x-mixed-replace").Equals(contentType)) {
|
||||
|
||||
nsCOMPtr<nsIStreamConverterService> convServ(do_GetService("@mozilla.org/streamConverters;1", &rv));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsIStreamListener> toListener(mDestListener);
|
||||
nsCOMPtr<nsIStreamListener> fromListener;
|
||||
|
||||
rv = convServ->AsyncConvertData(NS_LITERAL_STRING("multipart/x-mixed-replace").get(),
|
||||
NS_LITERAL_STRING("*/*").get(),
|
||||
toListener,
|
||||
nsnull,
|
||||
getter_AddRefs(fromListener));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
mDestListener = fromListener;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mDestListener->OnStartRequest(aRequest, ctxt);
|
||||
}
|
||||
|
||||
/* void onStopRequest (in nsIRequest request, in nsISupports ctxt, in nsresult status); */
|
||||
NS_IMETHODIMP ProxyListener::OnStopRequest(nsIRequest *aRequest, nsISupports *ctxt, nsresult status)
|
||||
{
|
||||
if (!mDestListener)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return mDestListener->OnStopRequest(aRequest, ctxt, status);
|
||||
}
|
||||
|
||||
/** nsIStreamListener methods **/
|
||||
|
||||
/* void onDataAvailable (in nsIRequest request, in nsISupports ctxt, in nsIInputStream inStr, in unsigned long sourceOffset, in unsigned long count); */
|
||||
NS_IMETHODIMP ProxyListener::OnDataAvailable(nsIRequest *aRequest, nsISupports *ctxt, nsIInputStream *inStr, PRUint32 sourceOffset, PRUint32 count)
|
||||
{
|
||||
if (!mDestListener)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return mDestListener->OnDataAvailable(aRequest, ctxt, inStr, sourceOffset, count);
|
||||
}
|
||||
@@ -1,491 +0,0 @@
|
||||
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
// SYNTAX HINTS: dashes are delimiters. Use underscores instead.
|
||||
// The first character after a period must be alphabetic.
|
||||
|
||||
pref("network.search.url","http://cgi.netscape.com/cgi-bin/url_search.cgi?search=");
|
||||
|
||||
pref("keyword.URL", "http://keyword.netscape.com/keyword/");
|
||||
pref("keyword.enabled", true);
|
||||
pref("general.useragent.locale", "chrome://navigator/locale/navigator.properties");
|
||||
pref("general.useragent.misc", "rv:0.9+");
|
||||
|
||||
pref("general.startup.browser", true);
|
||||
pref("general.startup.mail", false);
|
||||
pref("general.startup.news", false);
|
||||
pref("general.startup.editor", false);
|
||||
pref("general.startup.compose", false);
|
||||
pref("general.startup.addressbook", false);
|
||||
|
||||
pref("general.open_location.last_url", "");
|
||||
pref("general.open_location.last_window_choice", 0);
|
||||
|
||||
// 0 = blank, 1 = home (browser.startup.homepage), 2 = last
|
||||
pref("browser.startup.page", 1);
|
||||
pref("browser.startup.homepage", "chrome://navigator-region/locale/region.properties");
|
||||
// "browser.startup.homepage_override" was for 4.x
|
||||
pref("browser.startup.homepage_override.1", true);
|
||||
pref("browser.startup.autoload_homepage", true);
|
||||
|
||||
pref("browser.cache.disk_cache_size", 50000);
|
||||
pref("browser.cache.enable", true);
|
||||
pref("browser.cache.disk.enable", true);
|
||||
pref("browser.cache.memory_cache_size", 4096);
|
||||
pref("browser.cache.disk_cache_ssl", false);
|
||||
pref("browser.cache.check_doc_frequency", 0);
|
||||
|
||||
pref("browser.display.use_document_fonts", 1); // 0 = never, 1 = quick, 2 = always
|
||||
pref("browser.display.use_document_colors", true);
|
||||
pref("browser.display.use_system_colors",true);
|
||||
pref("browser.display.foreground_color", "#000000");
|
||||
pref("browser.display.background_color", "#C0C0C0");
|
||||
pref("browser.anchor_color", "#0000EE");
|
||||
pref("browser.visited_color", "#551A8B");
|
||||
pref("browser.underline_anchors", true);
|
||||
|
||||
pref("browser.display.use_focus_colors", false);
|
||||
pref("browser.display.focus_background_color", "#117722");
|
||||
pref("browser.display.focus_text_color", "#ffffff");
|
||||
pref("browser.display.focus_ring_width", 1);
|
||||
pref("browser.display.focus_ring_on_anything", false);
|
||||
|
||||
pref("browser.chrome.toolbar_tips", true);
|
||||
pref("browser.chrome.toolbar_style", 2);
|
||||
|
||||
pref("browser.toolbars.showbutton.bookmarks", true);
|
||||
pref("browser.toolbars.showbutton.go", false);
|
||||
pref("browser.toolbars.showbutton.home", true);
|
||||
pref("browser.toolbars.showbutton.mynetscape", true);
|
||||
pref("browser.toolbars.showbutton.net2phone", true);
|
||||
pref("browser.toolbars.showbutton.print", true);
|
||||
pref("browser.toolbars.showbutton.search", true);
|
||||
|
||||
pref("accessibility.browsewithcaret", false);
|
||||
pref("accessibility.usetexttospeech", "");
|
||||
pref("accessibility.usebrailledisplay", "");
|
||||
|
||||
// Dialog modality issues
|
||||
pref("browser.prefWindowModal", true);
|
||||
pref("browser.show_about_as_stupid_modal_window", false);
|
||||
|
||||
pref("browser.download.progressDnldDialog.keepAlive", false); // keep the dnload progress dialog up after dnload is complete
|
||||
|
||||
// various default search settings
|
||||
pref("browser.search.defaulturl", "chrome://navigator-region/locale/region.properties");
|
||||
pref("browser.search.opensidebarsearchpanel", true);
|
||||
pref("browser.search.last_search_category", "NC:SearchCategory?category=urn:search:category:1");
|
||||
pref("browser.search.mode", 0);
|
||||
pref("browser.search.powermode", 0);
|
||||
pref("browser.urlbar.autocomplete.enabled", true);
|
||||
pref("browser.urlbar.clickSelectsAll",false);
|
||||
|
||||
pref("browser.history.last_page_visited", "");
|
||||
pref("browser.history_expire_days", 9);
|
||||
pref("browser.sessionhistory.max_entries", 50);
|
||||
|
||||
pref("browser.PICS.ratings_enabled", false);
|
||||
pref("browser.PICS.pages_must_be_rated", false);
|
||||
pref("browser.PICS.disable_for_this_session", false);
|
||||
pref("browser.PICS.reenable_for_this_session", false);
|
||||
pref("browser.PICS.service.http___home_netscape_com_default_rating.service_enabled", true);
|
||||
pref("browser.PICS.service.http___home_netscape_com_default_rating.s", 0);
|
||||
|
||||
pref("browser.target_new_blocked", false);
|
||||
|
||||
// loading and rendering of framesets and iframes
|
||||
pref("browser.frames.enabled", true);
|
||||
|
||||
// view source
|
||||
pref("view_source.syntax_highlight", true);
|
||||
|
||||
// gfx widgets
|
||||
pref("nglayout.widget.mode", 2);
|
||||
pref("nglayout.widget.gfxscrollbars", true);
|
||||
|
||||
// use nsViewManager2
|
||||
pref("nglayout.view.useViewManager2", true);
|
||||
|
||||
// css2 hover pref
|
||||
pref("nglayout.events.showHierarchicalHover", false);
|
||||
|
||||
// whether or not to use xbl form controls
|
||||
pref("nglayout.debug.enable_xbl_forms", false);
|
||||
|
||||
// Smart Browsing prefs
|
||||
pref("browser.related.enabled", true);
|
||||
pref("browser.related.autoload", 1); // 0 = Always, 1 = After first use, 2 = Never
|
||||
pref("browser.related.provider", "http://www-rl.netscape.com/wtgn?");
|
||||
pref("browser.related.disabledForDomains", "");
|
||||
pref("browser.goBrowsing.enabled", true);
|
||||
|
||||
//Internet Search
|
||||
pref("browser.search.defaultenginename", "chrome://navigator/locale/navigator.properties");
|
||||
|
||||
// Default Capability Preferences: Security-Critical!
|
||||
// Editing these may create a security risk - be sure you know what you're doing
|
||||
//pref("capability.policy.default.barprop.visible.set", "UniversalBrowserWrite");
|
||||
|
||||
pref("capability.policy.default.Domexception.code", "allAccess");
|
||||
pref("capability.policy.default.Domexception.message", "allAccess");
|
||||
pref("capability.policy.default.Domexception.name", "allAccess");
|
||||
pref("capability.policy.default.Domexception.result", "allAccess");
|
||||
pref("capability.policy.default.Domexception.tostring", "allAccess");
|
||||
|
||||
pref("capability.policy.default.History.back", "allAccess");
|
||||
pref("capability.policy.default.History.current", "UniversalBrowserRead");
|
||||
pref("capability.policy.default.History.forward", "allAccess");
|
||||
pref("capability.policy.default.History.go", "allAccess");
|
||||
//pref("capability.policy.default.History.item", "UniversalBrowserRead");
|
||||
pref("capability.policy.default.History.length", "UniversalBrowserRead");
|
||||
pref("capability.policy.default.History.next", "UniversalBrowserRead");
|
||||
pref("capability.policy.default.History.previous", "UniversalBrowserRead");
|
||||
pref("capability.policy.default.History.toString", "UniversalBrowserRead");
|
||||
|
||||
pref("capability.policy.default.HTMLDocument.close", "allAccess");
|
||||
pref("capability.policy.default.HTMLDocument.open", "allAccess");
|
||||
pref("capability.policy.default.HTMLDocument.write", "allAccess");
|
||||
pref("capability.policy.default.HTMLDocument.writeln", "allAccess");
|
||||
|
||||
pref("capability.policy.default.Location.hash.set", "allAccess");
|
||||
pref("capability.policy.default.Location.host.set", "allAccess");
|
||||
pref("capability.policy.default.Location.hostname.set", "allAccess");
|
||||
pref("capability.policy.default.Location.href.set", "allAccess");
|
||||
pref("capability.policy.default.Location.pathname.set", "allAccess");
|
||||
pref("capability.policy.default.Location.port.set", "allAccess");
|
||||
pref("capability.policy.default.Location.protocol.set", "allAccess");
|
||||
pref("capability.policy.default.Location.reload", "allAccess");
|
||||
pref("capability.policy.default.Location.replace", "allAccess");
|
||||
pref("capability.policy.default.Location.search.set", "allAccess");
|
||||
|
||||
pref("capability.policy.default.Navigator.preference", "allAccess");
|
||||
pref("capability.policy.default.Navigator.preferenceinternal.get", "UniversalPreferencesRead");
|
||||
pref("capability.policy.default.Navigator.preferenceinternal.set", "UniversalPreferencesWrite");
|
||||
|
||||
pref("capability.policy.default.Window.blur", "allAccess");
|
||||
pref("capability.policy.default.Window.close", "allAccess");
|
||||
pref("capability.policy.default.Window.closed", "allAccess");
|
||||
pref("capability.policy.default.Window.Components", "allAccess");
|
||||
pref("capability.policy.default.Window.document", "allAccess");
|
||||
pref("capability.policy.default.Window.focus", "allAccess");
|
||||
pref("capability.policy.default.Window.history", "allAccess");
|
||||
pref("capability.policy.default.Window.location", "allAccess");
|
||||
// window.openDialog is insecure and must be made inaccessible from web scripts - see bug 56009
|
||||
pref("capability.policy.default.Window.opendialog", "noAccess");
|
||||
pref("capability.policy.default.Window.self", "allAccess");
|
||||
pref("capability.policy.default.Window.window", "allAccess");
|
||||
|
||||
pref("capability.policy.mailnews.Domexception.tostring", "noAccess");
|
||||
pref("capability.policy.mailnews.HTMLDocument.domain", "noAccess");
|
||||
pref("capability.policy.mailnews.HTMLDocument.URL", "noAccess");
|
||||
//pref("capability.policy.mailnews.nsdocument.location", "noAccess");
|
||||
pref("capability.policy.mailnews.sites", "mailbox: imap: news:");
|
||||
pref("capability.policy.mailnews.Window.name.set", "noAccess");
|
||||
pref("capability.policy.mailnews.Window.location", "noAccess");
|
||||
|
||||
pref("javascript.enabled", true);
|
||||
pref("javascript.allow.mailnews", false);
|
||||
pref("javascript.options.strict", false);
|
||||
|
||||
// advanced prefs
|
||||
pref("advanced.always_load_images", true);
|
||||
pref("security.enable_java", true);
|
||||
pref("css.allow", true);
|
||||
pref("advanced.mailftp", false);
|
||||
pref("image.animation_mode", "normal");
|
||||
|
||||
pref("offline.startup_state", 0);
|
||||
pref("offline.send.unsent_messages", 0);
|
||||
pref("offline.download.download_messages", 0);
|
||||
pref("offline.prompt_synch_on_exit", true);
|
||||
pref("offline.news.download.use_days", 0);
|
||||
|
||||
pref("network.hosts.smtp_server", "mail");
|
||||
pref("network.hosts.pop_server", "mail");
|
||||
pref("network.protocols.useSystemDefaults", false); // set to true if user links should use system default handlers
|
||||
|
||||
// <ruslan>
|
||||
pref("network.http.version", "1.1"); // default
|
||||
// pref("network.http.version", "1.0"); // uncomment this out in case of problems
|
||||
// pref("network.http.version", "0.9"); // it'll work too if you're crazy
|
||||
// keep-alive option is effectively obsolete. Nevertheless it'll work with
|
||||
// some older 1.0 servers:
|
||||
|
||||
pref("network.http.keep-alive", true); // set it to false in case of problems
|
||||
pref("network.http.proxy.keep-alive", true );
|
||||
pref("network.http.keep-alive.timeout", 300);
|
||||
|
||||
pref("network.http.max-connections", 16);
|
||||
pref("network.http.max-connections-per-server", 8);
|
||||
pref("network.http.keep-alive.max-connections", 20); // max connections to be kept alive
|
||||
pref("network.http.keep-alive.max-connections-per-server", 8);
|
||||
|
||||
pref("network.http.connect.timeout", 30); // in seconds
|
||||
pref("network.http.request.timeout", 120); // in seconds
|
||||
|
||||
// Enable http compression: comment this out in case of problems with 1.1
|
||||
pref("network.http.accept-encoding" ,"gzip,deflate,compress,identity");
|
||||
|
||||
pref("network.http.pipelining" , false);
|
||||
pref("network.http.proxy.pipelining", false);
|
||||
|
||||
// Always pipeling the very first request: this will only work when you are
|
||||
// absolutely sure the the site or proxy you are browsing to/through support
|
||||
// pipelining; the default behavior will be that the browser will first make
|
||||
// a normal, non-pipelined request, then examine and remember the responce
|
||||
// and only the subsequent requests to that site will be pipeline
|
||||
pref("network.http.pipelining.firstrequest", false);
|
||||
|
||||
// Max number of requests in the pipeline
|
||||
pref("network.http.pipelining.maxrequests" , 4);
|
||||
|
||||
pref("network.http.proxy.ssl.connect",true);
|
||||
// </ruslan>
|
||||
|
||||
// until the directory view has an owner
|
||||
// necko will produce html -- dougt
|
||||
pref("network.dir.generate_html", true);
|
||||
|
||||
// sspitzer: change this back to "news" when we get to beta.
|
||||
// for now, set this to news.mozilla.org because you can only
|
||||
// post to the server specified by this pref.
|
||||
pref("network.hosts.nntp_server", "news.mozilla.org");
|
||||
|
||||
pref("network.hosts.socks_server", "");
|
||||
pref("network.hosts.socks_serverport", 1080);
|
||||
pref("network.hosts.socks_conf", "");
|
||||
pref("network.image.imageBehavior", 0); // 0-Accept, 1-dontAcceptForeign, 2-dontUse
|
||||
pref("network.image.warnAboutImages", false);
|
||||
pref("network.proxy.autoconfig_url", "");
|
||||
pref("network.proxy.type", 0);
|
||||
pref("network.proxy.ftp", "");
|
||||
pref("network.proxy.ftp_port", 0);
|
||||
pref("network.proxy.gopher", "");
|
||||
pref("network.proxy.gopher_port", 0);
|
||||
pref("network.proxy.news", "");
|
||||
pref("network.proxy.news_port", 0);
|
||||
pref("network.proxy.http", "");
|
||||
pref("network.proxy.http_port", 0);
|
||||
pref("network.proxy.wais", "");
|
||||
pref("network.proxy.wais_port", 0);
|
||||
pref("network.proxy.ssl", "");
|
||||
pref("network.proxy.ssl_port", 0);
|
||||
pref("network.proxy.socks", "");
|
||||
pref("network.proxy.socks_port", 0);
|
||||
pref("network.proxy.no_proxies_on", "");
|
||||
pref("network.online", true); //online/offline
|
||||
pref("network.accept_cookies", 0); // 0 = Always, 1 = warn, 2 = never
|
||||
pref("network.foreign_cookies", 0); // 0 = Accept, 1 = Don't accept
|
||||
pref("network.cookie.cookieBehavior", 0); // 0-Accept, 1-dontAcceptForeign, 2-dontUse
|
||||
pref("network.cookie.warnAboutCookies", false);
|
||||
pref("signon.rememberSignons", true);
|
||||
pref("network.sendRefererHeader", 2); // 0=don't send any, 1=send only on clicks, 2=send on image requests as well
|
||||
pref("network.enablePad", false); // Allow client to do proxy autodiscovery
|
||||
pref("converter.html2txt.structs", true); // Output structured phrases (strong, em, code, sub, sup, b, i, u)
|
||||
pref("converter.html2txt.header_strategy", 1); // 0 = no indention; 1 = indention, increased with header level; 2 = numbering and slight indention
|
||||
pref("wallet.captureForms", true);
|
||||
pref("wallet.notified", false);
|
||||
pref("wallet.TutorialFromMenu", "chrome://navigator/locale/navigator.properties");
|
||||
pref("wallet.Server", "chrome://navigator/locale/navigator.properties");
|
||||
pref("wallet.Samples", "chrome://navigator/locale/navigator.properties");
|
||||
pref("wallet.version", "1");
|
||||
pref("wallet.enabled", true);
|
||||
pref("wallet.crypto", false);
|
||||
pref("imageblocker.enabled", true);
|
||||
pref("intl.accept_languages", "chrome://navigator/locale/navigator.properties");
|
||||
pref("intl.accept_charsets", "iso-8859-1,*,utf-8");
|
||||
pref("intl.collationOption", "chrome://navigator/locale/navigator.properties");
|
||||
pref("intl.menuitems.alwaysappendacceskeys","chrome://navigator/locale/navigator.properties");
|
||||
pref("intl.charsetmenu.browser.static", "chrome://navigator/locale/navigator.properties");
|
||||
pref("intl.charsetmenu.browser.more1", "chrome://navigator/locale/navigator.properties");
|
||||
pref("intl.charsetmenu.browser.more2", "chrome://navigator/locale/navigator.properties");
|
||||
pref("intl.charsetmenu.browser.more3", "chrome://navigator/locale/navigator.properties");
|
||||
pref("intl.charsetmenu.browser.more4", "chrome://navigator/locale/navigator.properties");
|
||||
pref("intl.charsetmenu.browser.more5", "chrome://navigator/locale/navigator.properties");
|
||||
pref("intl.charsetmenu.mailedit", "chrome://navigator/locale/navigator.properties");
|
||||
pref("intl.charsetmenu.browser.cache", "");
|
||||
pref("intl.charsetmenu.mailview.cache", "");
|
||||
pref("intl.charsetmenu.composer.cache", "");
|
||||
pref("intl.charsetmenu.browser.cache.size", 5);
|
||||
pref("intl.charset.detector", "chrome://navigator/locale/navigator.properties");
|
||||
pref("intl.charset.default", "chrome://navigator/locale/navigator.properties");
|
||||
|
||||
pref("font.default", "serif");
|
||||
pref("font.size.variable.ar", 16);
|
||||
pref("font.size.fixed.ar", 13);
|
||||
|
||||
pref("font.size.variable.el", 16);
|
||||
pref("font.size.fixed.el", 13);
|
||||
|
||||
pref("font.size.variable.he", 16);
|
||||
pref("font.size.fixed.he", 13);
|
||||
|
||||
pref("font.size.variable.ja", 16);
|
||||
pref("font.size.fixed.ja", 16);
|
||||
|
||||
pref("font.size.variable.ko", 16);
|
||||
pref("font.size.fixed.ko", 16);
|
||||
|
||||
pref("font.size.variable.th", 16);
|
||||
pref("font.size.fixed.th", 13);
|
||||
|
||||
pref("font.size.variable.tr", 16);
|
||||
pref("font.size.fixed.tr", 13);
|
||||
|
||||
pref("font.size.variable.x-baltic", 16);
|
||||
pref("font.size.fixed.x-baltic", 13);
|
||||
|
||||
pref("font.size.variable.x-central-euro", 16);
|
||||
pref("font.size.fixed.x-central-euro", 13);
|
||||
|
||||
pref("font.size.variable.x-cyrillic", 16);
|
||||
pref("font.size.fixed.x-cyrillic", 13);
|
||||
|
||||
pref("font.size.variable.x-unicode", 16);
|
||||
pref("font.size.fixed.x-unicode", 13);
|
||||
|
||||
pref("font.size.variable.x-western", 16);
|
||||
pref("font.size.fixed.x-western", 13);
|
||||
|
||||
pref("font.size.variable.zh-CN", 16);
|
||||
pref("font.size.fixed.zh-CN", 16);
|
||||
|
||||
pref("font.size.variable.zh-TW", 16);
|
||||
pref("font.size.fixed.zh-TW", 16);
|
||||
|
||||
// -- folders (Mac: these are binary aliases.)
|
||||
localDefPref("mail.signature_file", "");
|
||||
localDefPref("mail.directory", "");
|
||||
|
||||
pref("images.dither", "auto");
|
||||
localDefPref("news.directory", "");
|
||||
localDefPref("security.directory", "");
|
||||
|
||||
pref("autoupdate.enabled", true);
|
||||
|
||||
pref("silentdownload.enabled", true);
|
||||
pref("silentdownload.directory", "");
|
||||
pref("silentdownload.range", 3000);
|
||||
pref("silentdownload.interval", 10000);
|
||||
|
||||
pref("browser.editor.disabled", false);
|
||||
|
||||
pref("spellchecker.dictionary", "");
|
||||
|
||||
pref("signed.applets.codebase_principal_support", false);
|
||||
pref("security.checkloaduri", true);
|
||||
pref("security.xpconnect.plugin.unrestricted", true);
|
||||
|
||||
// Modifier key prefs: default to Windows settings,
|
||||
// menu access key = alt, accelerator key = control.
|
||||
pref("ui.key.accelKey", 17);
|
||||
pref("ui.key.menuAccessKey", 18);
|
||||
pref("ui.key.menuAccessKeyFocuses", false);
|
||||
pref("ui.key.saveLink.shift", true); // true = shift, false = meta
|
||||
|
||||
// Middle-mouse handling
|
||||
pref("middlemouse.paste", false);
|
||||
pref("middlemouse.openNewWindow", true);
|
||||
pref("middlemouse.contentLoadURL", false);
|
||||
pref("middlemouse.scrollbarPosition", false);
|
||||
|
||||
// Clipboard behavior
|
||||
pref("clipboard.autocopy", false);
|
||||
|
||||
// 0=lines, 1=pages, 2=history , 3=text size
|
||||
pref("mousewheel.withnokey.action",0);
|
||||
pref("mousewheel.withnokey.numlines",1);
|
||||
pref("mousewheel.withnokey.sysnumlines",true);
|
||||
pref("mousewheel.withcontrolkey.action",0);
|
||||
pref("mousewheel.withcontrolkey.numlines",1);
|
||||
pref("mousewheel.withcontrolkey.sysnumlines",true);
|
||||
pref("mousewheel.withshiftkey.action",0);
|
||||
pref("mousewheel.withshiftkey.numlines",1);
|
||||
pref("mousewheel.withshiftkey.sysnumlines",false);
|
||||
pref("mousewheel.withaltkey.action",2);
|
||||
pref("mousewheel.withaltkey.numlines",1);
|
||||
pref("mousewheel.withaltkey.sysnumlines",false);
|
||||
|
||||
pref("profile.confirm_automigration",true);
|
||||
|
||||
// Customizable toolbar stuff
|
||||
pref("custtoolbar.personal_toolbar_folder", "");
|
||||
|
||||
pref("sidebar.customize.all_panels.url", "http://sidebar-rdf.netscape.com/%LOCALE%/sidebar-rdf/%SIDEBAR_VERSION%/all-panels.rdf");
|
||||
pref("sidebar.customize.more_panels.url", "http://dmoz.org/Netscape/Sidebar/");
|
||||
|
||||
pref("prefs.converted-to-utf8",false);
|
||||
// --------------------------------------------------
|
||||
// IBMBIDI
|
||||
// --------------------------------------------------
|
||||
//
|
||||
// ------------------
|
||||
// Text Direction
|
||||
// ------------------
|
||||
// 1 = directionLTRBidi *
|
||||
// 2 = directionRTLBidi
|
||||
pref("bidi.direction", 1);
|
||||
// ------------------
|
||||
// Text Type
|
||||
// ------------------
|
||||
// 1 = charsettexttypeBidi *
|
||||
// 2 = logicaltexttypeBidi
|
||||
// 3 = visualtexttypeBidi
|
||||
pref("bidi.texttype", 1);
|
||||
// ------------------
|
||||
// Controls Text Mode
|
||||
// ------------------
|
||||
// 1 = logicalcontrolstextmodeBidiCmd
|
||||
// 2 = visiualcontrolstextmodeBidi
|
||||
// 3 = containercontrolstextmodeBidi *
|
||||
pref("bidi.controlstextmode", 1);
|
||||
// ------------------
|
||||
// Clipboard Text Mode
|
||||
// ------------------
|
||||
// 1 = logicalclipboardtextmodeBidi
|
||||
// 2 = visiualclipboardtextmodeBidi
|
||||
// 3 = sourceclipboardtextmodeBidi *
|
||||
pref("bidi.clipboardtextmode", 3);
|
||||
// ------------------
|
||||
// Numeral Style
|
||||
// ------------------
|
||||
// 1 = regularcontextnumeralBidi *
|
||||
// 2 = hindicontextnumeralBidi
|
||||
// 3 = arabicnumeralBidi
|
||||
// 4 = hindinumeralBidi
|
||||
pref("bidi.numeral", 1);
|
||||
// ------------------
|
||||
// Support Mode
|
||||
// ------------------
|
||||
// 1 = mozillaBidisupport *
|
||||
// 2 = OsBidisupport
|
||||
// 3 = disableBidisupport
|
||||
pref("bidi.support", 1);
|
||||
// ------------------
|
||||
// Charset Mode
|
||||
// ------------------
|
||||
// 1 = doccharactersetBidi *
|
||||
// 2 = defaultcharactersetBidi
|
||||
pref("bidi.characterset", 1);
|
||||
|
||||
|
||||
pref("browser.throbber.url","chrome://navigator-region/locale/region.properties");
|
||||
@@ -1,493 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Mitesh Shah <mitesh@netscape.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsAutoConfig.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
#include "nsIFileStreams.h"
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
#include "prmem.h"
|
||||
#include "jsapi.h"
|
||||
#include "prefapi.h"
|
||||
#include "nsIProfile.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIEventQueueService.h"
|
||||
#include "nsLiteralString.h"
|
||||
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS4(nsAutoConfig, nsIAutoConfig, nsITimerCallback, nsIStreamListener,nsIObserver)
|
||||
|
||||
nsAutoConfig::nsAutoConfig()
|
||||
{
|
||||
/* member initializers and constructor code */
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
nsresult nsAutoConfig::Init()
|
||||
{
|
||||
/* member initializers and constructor code */
|
||||
|
||||
nsresult rv=NS_OK;
|
||||
|
||||
mLoaded = PR_FALSE;
|
||||
|
||||
// Registering the object as an observer to the profile-after-change topic
|
||||
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (observerService) {
|
||||
rv = observerService->AddObserver(this,
|
||||
NS_LITERAL_STRING("profile-after-change").get());
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
nsCOMPtr<nsIPrefService> prefs =
|
||||
do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = prefs->GetBranch(nsnull,getter_AddRefs(mPrefBranch));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoConfig::~nsAutoConfig()
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv);
|
||||
if (observerService)
|
||||
rv = observerService->RemoveObserver(this,
|
||||
NS_LITERAL_STRING("profile-after-change").get());
|
||||
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAutoConfig::OnStartRequest(nsIRequest* request, nsISupports* context)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAutoConfig::OnDataAvailable(nsIRequest* request,
|
||||
nsISupports* context,
|
||||
nsIInputStream *aIStream,
|
||||
PRUint32 aSourceOffset,
|
||||
PRUint32 aLength)
|
||||
{
|
||||
PRUint32 amt, size;
|
||||
nsresult rv;
|
||||
char buf[1025];
|
||||
|
||||
while (aLength) {
|
||||
size = PR_MIN(aLength, sizeof(buf));
|
||||
rv = aIStream->Read(buf, size, &amt);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ASSERTION((NS_BASE_STREAM_WOULD_BLOCK != rv),
|
||||
"The stream should never block.");
|
||||
return rv;
|
||||
}
|
||||
mBuf.Append(buf,amt);
|
||||
aLength -= amt;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAutoConfig::OnStopRequest(nsIRequest* request, nsISupports* context,
|
||||
nsresult aStatus)
|
||||
{
|
||||
|
||||
nsresult rv;
|
||||
|
||||
// If the request is failed, go read the failover.jsc file
|
||||
if (NS_FAILED(aStatus)) {
|
||||
return readOfflineFile();
|
||||
}
|
||||
|
||||
//Checking for the http response, if failure go read the failover file.
|
||||
nsCOMPtr<nsIHttpChannel> pHTTPCon(do_QueryInterface(request));
|
||||
if (pHTTPCon) {
|
||||
PRUint32 httpStatus;
|
||||
pHTTPCon->GetResponseStatus(&httpStatus);
|
||||
if (httpStatus != 200)
|
||||
return readOfflineFile();
|
||||
}
|
||||
|
||||
// Send the autoconfig.jsc to javascript engine.
|
||||
PRBool success = PREF_EvaluateConfigScript(mBuf.get(), mBuf.Length(),nsnull,
|
||||
PR_FALSE,PR_TRUE,PR_FALSE);
|
||||
if (success) {
|
||||
rv = writeFailoverFile(); /* Write the autoconfig.jsc to
|
||||
failover.jsc (cached copy) */
|
||||
if(NS_FAILED(rv))
|
||||
NS_WARNING("Error writing failover.jsc file");
|
||||
// Clean up the previous read.
|
||||
// If there is a timer, these methods will be called again.
|
||||
mBuf.Truncate(0);
|
||||
mLoaded = PR_TRUE; //Releasing the deadlock
|
||||
return NS_OK;
|
||||
}
|
||||
else {
|
||||
NS_WARNING("Error reading autoconfig.jsc from the network, reading the offline version");
|
||||
// Clean up the previous read so it will be ready for
|
||||
// the next updated read.
|
||||
mBuf.Truncate(0);
|
||||
return readOfflineFile();
|
||||
}
|
||||
}
|
||||
|
||||
// Notify method as a TimerCallBack function
|
||||
NS_IMETHODIMP_(void) nsAutoConfig::Notify(nsITimer *timer)
|
||||
{
|
||||
DownloadAutoCfg();
|
||||
}
|
||||
|
||||
/* Observe() is called twice: once at the instantiation time and other
|
||||
after the profile is set. It doesn't do anything but return NS_OK during the
|
||||
creation time. Second time it calls DownloadAutoCfg().
|
||||
*/
|
||||
NS_IMETHODIMP nsAutoConfig::Observe(nsISupports *aSubject, const PRUnichar *aTopic, const PRUnichar *someData)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (!nsCRT::strcmp(aTopic, NS_LITERAL_STRING("profile-after-change").get()))
|
||||
{
|
||||
// Getting the current profile name since we already have the
|
||||
// pointer to the object.
|
||||
nsCOMPtr<nsIProfile> profile = do_QueryInterface(aSubject);
|
||||
if (profile) {
|
||||
nsXPIDLString profileName;
|
||||
rv = profile->GetCurrentProfile(getter_Copies(profileName));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
// setting the member variable to the current profile name
|
||||
mCurrProfile.AssignWithConversion(profileName);
|
||||
else
|
||||
return rv;
|
||||
}
|
||||
return DownloadAutoCfg();
|
||||
}
|
||||
else if (!nsCRT::strcmp(aTopic, NS_LITERAL_STRING("app-startup").get()))
|
||||
{
|
||||
// This is the object instantiation, do nothing and return NS_OK;
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAutoConfig::DownloadAutoCfg()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsCAutoString emailAddr;
|
||||
nsXPIDLCString urlName;
|
||||
PRBool appendMail=PR_FALSE, offline=PR_FALSE;
|
||||
static PRBool firstTime = PR_TRUE;
|
||||
|
||||
|
||||
// get the value of the autoconfig url
|
||||
rv = mPrefBranch->GetCharPref("autoadmin.global_config_url",
|
||||
getter_Copies(urlName));
|
||||
if(NS_FAILED(rv) || (nsCRT::strlen(urlName) == 0))
|
||||
return NS_OK; /* Return ok if there is no config url set. */
|
||||
|
||||
// Check to see if the network is online/offline
|
||||
|
||||
nsCOMPtr<nsIIOService> ios =
|
||||
do_GetService(NS_IOSERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = ios->GetOffline(&offline);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (offline) {
|
||||
|
||||
PRBool offlineFailover = PR_FALSE;
|
||||
rv = mPrefBranch->GetBoolPref("autoadmin.offline_failover",
|
||||
&offlineFailover);
|
||||
|
||||
// Read the failover.jsc if the network is offline and the pref says so
|
||||
if ( offlineFailover ) {
|
||||
return readOfflineFile();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
nsCAutoString cfgUrl(urlName);
|
||||
|
||||
/* Append user's identity at the end of the URL if the pref says so.
|
||||
First we are checking for the user's email address but if it is not
|
||||
available in the case where the client is used without messenger, user's
|
||||
profile name will be used as an unique identifier
|
||||
*/
|
||||
|
||||
rv = mPrefBranch->GetBoolPref("autoadmin.append_emailaddr", &appendMail);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && appendMail) {
|
||||
rv = getEmailAddr(emailAddr);
|
||||
if (NS_SUCCEEDED(rv) && emailAddr) {
|
||||
/* Adding the unique identifier at the end of autoconfig URL.
|
||||
In this case the autoconfig URL is a script and
|
||||
emailAddr as passed as an argument */
|
||||
cfgUrl.Append("?");
|
||||
cfgUrl.Append(emailAddr);
|
||||
}
|
||||
}
|
||||
|
||||
// Getting an event queue. If we start an AsyncOpen, the thread
|
||||
// needs to wait before the reading of autoconfig is done
|
||||
|
||||
nsCOMPtr<nsIEventQueue> currentThreadQ;
|
||||
|
||||
if (firstTime) {
|
||||
nsCOMPtr<nsIEventQueueService> service =
|
||||
do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = service->GetThreadEventQueue(NS_CURRENT_THREAD,getter_AddRefs(currentThreadQ));
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
|
||||
}
|
||||
mLoaded = PR_FALSE;
|
||||
|
||||
// create a new url
|
||||
|
||||
nsCOMPtr<nsIURI> url;
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
|
||||
rv = NS_NewURI(getter_AddRefs(url), cfgUrl, nsnull, nsnull);
|
||||
if(NS_FAILED(rv)) return rv;
|
||||
|
||||
// open a channel for the url
|
||||
|
||||
rv = NS_OpenURI(getter_AddRefs(channel),url, nsnull, nsnull);
|
||||
if(NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = channel->AsyncOpen(this, nsnull);
|
||||
if (NS_FAILED(rv)) {
|
||||
readOfflineFile();
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
// Set a repeating timer if the pref is set.
|
||||
// This is to be done only once.
|
||||
|
||||
if (firstTime) {
|
||||
firstTime = PR_FALSE;
|
||||
PRInt32 minutes = 0;
|
||||
rv = mPrefBranch->GetIntPref("autoadmin.refresh_interval",
|
||||
&minutes);
|
||||
if(NS_SUCCEEDED(rv) && minutes > 0) {
|
||||
// Create a new timer and pass this nsAutoConfig
|
||||
// object as a timer callback.
|
||||
nsCOMPtr<nsITimer> timer;
|
||||
timer = do_CreateInstance("@mozilla.org/timer;1",&rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = timer->Init(this, minutes*60*1000, NS_PRIORITY_NORMAL,
|
||||
NS_TYPE_REPEATING_SLACK);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// process events until we're finished. AutoConfig.jsc reading needs
|
||||
// to be finished before the browser starts loading up
|
||||
// We are waiting for the mLoaded which will be set through
|
||||
// onStopRequest or readOfflineFile methods
|
||||
// There is a possibility of deadlock so we need to make sure
|
||||
// that mLoaded will be set to true in any case (success/failure)
|
||||
|
||||
PLEvent *event;
|
||||
while (!mLoaded) {
|
||||
rv = currentThreadQ->WaitForEvent(&event);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv),"-->nsAutoConfig::DownloadAutoCfg: currentThreadQ->WaitForEvent failed...");
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = currentThreadQ->HandleEvent(event);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "-->nsAutoConfig::DownloadAutoCfg: currentThreadQ->HandleEvent failed...");
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
}
|
||||
|
||||
} //first_time
|
||||
|
||||
return NS_OK;
|
||||
|
||||
} // nsPref::DownloadAutoCfg()
|
||||
|
||||
|
||||
|
||||
nsresult nsAutoConfig::readOfflineFile()
|
||||
{
|
||||
PRBool failCache = PR_TRUE;
|
||||
nsresult rv;
|
||||
PRBool offline;
|
||||
|
||||
rv = mPrefBranch->GetBoolPref("autoadmin.failover_to_cached", &failCache);
|
||||
|
||||
if (failCache == PR_FALSE) {
|
||||
|
||||
// disable network connections and return.
|
||||
|
||||
nsCOMPtr<nsIIOService> ios =
|
||||
do_GetService(NS_IOSERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) return reportError();
|
||||
|
||||
rv = ios->GetOffline(&offline);
|
||||
if (NS_FAILED(rv)) return reportError();
|
||||
if (!offline) {
|
||||
rv = ios->SetOffline(PR_TRUE);
|
||||
if (NS_FAILED(rv)) return reportError();
|
||||
}
|
||||
|
||||
// lock the "network.online" prference so user cannot toggle back to
|
||||
// online mode.
|
||||
rv = mPrefBranch->SetBoolPref("network.online", PR_FALSE);
|
||||
if (NS_FAILED(rv)) return reportError();
|
||||
mPrefBranch->LockPref("network.online");
|
||||
|
||||
mLoaded = PR_TRUE;
|
||||
return NS_OK;
|
||||
|
||||
}
|
||||
|
||||
// failCache = true
|
||||
|
||||
// Open the file and read the content.
|
||||
// execute the javascript file
|
||||
|
||||
nsCOMPtr<nsIFile> failoverFile;
|
||||
rv = NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR,
|
||||
getter_AddRefs(failoverFile));
|
||||
if (NS_FAILED(rv)) return reportError();
|
||||
#ifdef XP_MAC
|
||||
failoverFile->Append("Essential Files");
|
||||
#endif
|
||||
|
||||
failoverFile->Append("failover.jsc");
|
||||
rv = evaluateLocalFile(failoverFile);
|
||||
if (NS_FAILED(rv))
|
||||
NS_WARNING("Couldn't open failover.jsc, going back to default prefs");
|
||||
mLoaded = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsAutoConfig::evaluateLocalFile(nsIFile* file)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIInputStream> inStr;
|
||||
|
||||
rv = NS_NewLocalFileInputStream(getter_AddRefs(inStr), file);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
PRInt64 fileSize;
|
||||
PRUint32 fs, amt=0;
|
||||
file->GetFileSize(&fileSize);
|
||||
LL_L2UI(fs, fileSize); // Converting 64 bit structure to unsigned int
|
||||
char* buf = (char *) PR_Malloc(fs*sizeof(char)) ;
|
||||
if(!buf)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
rv = inStr->Read(buf, fs, &amt);
|
||||
if (NS_FAILED(rv))
|
||||
NS_ASSERTION((NS_BASE_STREAM_WOULD_BLOCK != rv),
|
||||
"The stream should never block.");
|
||||
|
||||
if (!PREF_EvaluateConfigScript(buf,fs,nsnull, PR_FALSE, PR_TRUE, PR_FALSE)){
|
||||
PR_FREEIF(buf);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
inStr->Close();
|
||||
PR_FREEIF(buf);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsAutoConfig::writeFailoverFile()
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIFile> failoverFile;
|
||||
nsCOMPtr<nsIOutputStream> outStr;
|
||||
PRUint32 amt;
|
||||
|
||||
rv = NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR,
|
||||
getter_AddRefs(failoverFile));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
#ifdef XP_MAC
|
||||
failoverFile->Append("Essential Files");
|
||||
#endif
|
||||
|
||||
failoverFile->Append("failover.jsc");
|
||||
|
||||
rv = NS_NewLocalFileOutputStream(getter_AddRefs(outStr), failoverFile);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = outStr->Write(mBuf.get(),mBuf.Length(),&amt);
|
||||
outStr->Close();
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsAutoConfig::getEmailAddr(nsAWritableCString & emailAddr)
|
||||
{
|
||||
|
||||
nsresult rv;
|
||||
nsXPIDLCString prefValue;
|
||||
|
||||
/* Getting an email address through set of three preferences:
|
||||
First getting a default account with
|
||||
"mail.accountmanager.defaultaccount"
|
||||
second getting an associated id with the default account
|
||||
Third getting an email address with id
|
||||
*/
|
||||
|
||||
rv = mPrefBranch->GetCharPref("mail.accountmanager.defaultaccount",
|
||||
getter_Copies(prefValue));
|
||||
// Checking prefValue and its length. Since by default the preference
|
||||
// is set to nothing
|
||||
if (NS_SUCCEEDED(rv) && nsCRT::strlen(prefValue) > 0) {
|
||||
emailAddr = NS_LITERAL_CSTRING("mail.account.") +
|
||||
nsLocalCString(prefValue) + NS_LITERAL_CSTRING(".identities");
|
||||
rv = mPrefBranch->GetCharPref(PromiseFlatCString(emailAddr).get(),
|
||||
getter_Copies(prefValue));
|
||||
if (NS_FAILED(rv) || nsCRT::strlen(prefValue) < 0) return rv;
|
||||
emailAddr = NS_LITERAL_CSTRING("mail.identity.") +
|
||||
nsLocalCString(prefValue) + NS_LITERAL_CSTRING(".useremail");
|
||||
rv = mPrefBranch->GetCharPref(PromiseFlatCString(emailAddr).get(),
|
||||
getter_Copies(prefValue));
|
||||
if (NS_FAILED(rv) || nsCRT::strlen(prefValue) < 0) return rv;
|
||||
emailAddr = nsLocalCString(prefValue);
|
||||
}
|
||||
else {
|
||||
if (mCurrProfile) {
|
||||
emailAddr = mCurrProfile;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
nsresult nsAutoConfig::reportError()
|
||||
{
|
||||
NS_ERROR("AutoConfig::readOfflineFile() failed");
|
||||
mLoaded = PR_TRUE; //Releasing lock to avoid deadlock in DownloadAutoCfg()
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
Binary file not shown.
@@ -1,105 +0,0 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape 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/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = plugin
|
||||
XPIDL_MODULE = layout
|
||||
LIBRARY_NAME = gkplugin
|
||||
EXPORT_LIBRARY = 1
|
||||
IS_COMPONENT = 1
|
||||
REQUIRES = xpcom string java pref necko gtkxtbin webshell caps intl dom locale layout widget cookie mimetype oji exthandler docshell webbrwsr nkcache gfx2 timer windowwatcher js
|
||||
# for xlib port
|
||||
REQUIRES += xlibrgb
|
||||
|
||||
CPPSRCS = \
|
||||
ns4xPlugin.cpp \
|
||||
ns4xPluginInstance.cpp \
|
||||
nsPluginDocLoaderFactory.cpp \
|
||||
nsPluginHostImpl.cpp \
|
||||
nsPluginModule.cpp \
|
||||
nsPluginInstancePeer.cpp \
|
||||
nsPluginViewer.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(OS_ARCH), BeOS)
|
||||
CPPSRCS += nsPluginsDirBeOS.cpp
|
||||
else
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),os2)
|
||||
CPPSRCS += nsPluginsDirOS2.cpp
|
||||
else
|
||||
CPPSRCS += nsPluginsDirUnix.cpp
|
||||
endif
|
||||
endif
|
||||
|
||||
EXPORTS = \
|
||||
nsPluginsCID.h \
|
||||
nsIPluginHost.h \
|
||||
nsIPluginInstanceOwner.h \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
|
||||
|
||||
EXTRA_DSO_LIBS += gkgfx
|
||||
|
||||
EXTRA_DSO_LDOPTS = \
|
||||
$(MOZ_NECKO_UTIL_LIBS) \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
|
||||
ifndef MOZ_MONOLITHIC_TOOLKIT
|
||||
EXTRA_DSO_LDOPTS += $(MOZ_GTK_LDFLAGS)
|
||||
else
|
||||
EXTRA_DSO_LDOPTS += $(TK_LIBS)
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
DEFINES += -D_IMPL_NS_PLUGIN
|
||||
|
||||
ifdef MOZ_ENABLE_GTK
|
||||
ifndef MOZ_MONOLITHIC_TOOLKIT
|
||||
CXXFLAGS += $(MOZ_GTK_CFLAGS)
|
||||
CFLAGS += $(MOZ_GTK_CFLAGS)
|
||||
EXTRA_DSO_LDOPTS += -lgtkxtbin -lgtksuperwin -L/usr/X11R6/lib -lXt
|
||||
else
|
||||
CXXFLAGS += $(TK_CFLAGS)
|
||||
CFLAGS += $(TK_CFLAGS)
|
||||
EXTRA_DSO_LDOPTS += -lgtkxtbin -lgtksuperwin -L/usr/X11R6/lib -lXt
|
||||
endif #MOZ_MONOLITHIC_TOOLKIT
|
||||
endif #MOZ_ENABLE_GTK
|
||||
|
||||
ifdef MOZ_ENABLE_QT
|
||||
EXTRA_DSO_LDOPTS += $(MOZ_QT_LDFLAGS)
|
||||
ifndef MOZ_MONOLITHIC_TOOLKIT
|
||||
CXXFLAGS += $(MOZ_QT_CFLAGS)
|
||||
CFLAGS += $(MOZ_QT_CFLAGS)
|
||||
else
|
||||
CXXFLAGS += $(TK_CFLAGS)
|
||||
CFLAGS += $(TK_CFLAGS)
|
||||
endif #MOZ_MONOLITHIC_TOOLKIT
|
||||
endif #MOZ_ENABLE_QT
|
||||
@@ -1,99 +0,0 @@
|
||||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape 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/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
|
||||
DEPTH=..\..\..
|
||||
include <$(DEPTH)/config/config.mak>
|
||||
|
||||
|
||||
EXPORTS = \
|
||||
nsPluginsCID.h \
|
||||
nsIPluginHost.h \
|
||||
nsIPluginInstanceOwner.h
|
||||
|
||||
MAKE_OBJ_TYPE = DLL
|
||||
DLLNAME = gkplugin
|
||||
DLL=.\$(OBJDIR)\$(DLLNAME).dll
|
||||
|
||||
MODULE=raptor
|
||||
IS_COMPONENT=1
|
||||
|
||||
DEFINES =-D_IMPL_NS_PLUGIN -DWIN32_LEAN_AND_MEAN
|
||||
|
||||
OBJS = \
|
||||
.\$(OBJDIR)\ns4xPlugin.obj \
|
||||
.\$(OBJDIR)\ns4xPluginInstance.obj \
|
||||
.\$(OBJDIR)\nsPluginDocLoaderFactory.obj \
|
||||
.\$(OBJDIR)\nsPluginHostImpl.obj \
|
||||
.\$(OBJDIR)\nsPluginModule.obj \
|
||||
.\$(OBJDIR)\nsPluginInstancePeer.obj \
|
||||
.\$(OBJDIR)\nsPluginViewer.obj \
|
||||
.\$(OBJDIR)\nsPluginsDirWin.obj \
|
||||
$(NULL)
|
||||
|
||||
LINCS = \
|
||||
-I$(PUBLIC)\raptor \
|
||||
-I$(PUBLIC)\dom \
|
||||
-I$(PUBLIC)\xpcom \
|
||||
-I$(PUBLIC)\plugin \
|
||||
-I$(PUBLIC)\java \
|
||||
!ifdef NECKO
|
||||
-I$(PUBLIC)\necko \
|
||||
!else
|
||||
-I$(PUBLIC)\netlib \
|
||||
!endif
|
||||
-I$(PUBLIC)\oji \
|
||||
-I$(PUBLIC)\cache \
|
||||
-I$(PUBLIC)\pref \
|
||||
-I$(PUBLIC)\js \
|
||||
$(NULL)
|
||||
|
||||
|
||||
LCFLAGS = \
|
||||
$(LCFLAGS) \
|
||||
-D_IMPL_NS_PLUGIN \
|
||||
-GX \
|
||||
$(NULL)
|
||||
|
||||
!ifdef NU_CACHE
|
||||
CACHELIBNAME=cache.lib
|
||||
!else
|
||||
CACHELIBNAME=netcache.lib
|
||||
!endif
|
||||
|
||||
LLIBS = \
|
||||
$(DIST)\lib\gkgfxwin.lib \
|
||||
$(DIST)\lib\xpcom.lib \
|
||||
$(DIST)\lib\xppref32.lib \
|
||||
$(LIBNSPR)
|
||||
|
||||
WIN_LIBS = \
|
||||
version.lib
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
it:
|
||||
echo $(LLIBS)
|
||||
|
||||
install:: $(DLL)
|
||||
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).dll $(DIST)\bin\components
|
||||
|
||||
clobber::
|
||||
rm -f $(DIST)\bin\$(DLLNAME).dll
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -1,105 +0,0 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape 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/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = plugin
|
||||
XPIDL_MODULE = layout
|
||||
LIBRARY_NAME = gkplugin
|
||||
EXPORT_LIBRARY = 1
|
||||
IS_COMPONENT = 1
|
||||
REQUIRES = xpcom string java pref necko gtkxtbin webshell caps intl dom locale layout widget cookie mimetype oji exthandler docshell webbrwsr nkcache gfx2 timer windowwatcher js
|
||||
# for xlib port
|
||||
REQUIRES += xlibrgb
|
||||
|
||||
CPPSRCS = \
|
||||
ns4xPlugin.cpp \
|
||||
ns4xPluginInstance.cpp \
|
||||
nsPluginDocLoaderFactory.cpp \
|
||||
nsPluginHostImpl.cpp \
|
||||
nsPluginModule.cpp \
|
||||
nsPluginInstancePeer.cpp \
|
||||
nsPluginViewer.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(OS_ARCH), BeOS)
|
||||
CPPSRCS += nsPluginsDirBeOS.cpp
|
||||
else
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),os2)
|
||||
CPPSRCS += nsPluginsDirOS2.cpp
|
||||
else
|
||||
CPPSRCS += nsPluginsDirUnix.cpp
|
||||
endif
|
||||
endif
|
||||
|
||||
EXPORTS = \
|
||||
nsPluginsCID.h \
|
||||
nsIPluginHost.h \
|
||||
nsIPluginInstanceOwner.h \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
|
||||
|
||||
EXTRA_DSO_LIBS += gkgfx
|
||||
|
||||
EXTRA_DSO_LDOPTS = \
|
||||
$(MOZ_NECKO_UTIL_LIBS) \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
|
||||
ifndef MOZ_MONOLITHIC_TOOLKIT
|
||||
EXTRA_DSO_LDOPTS += $(MOZ_GTK_LDFLAGS)
|
||||
else
|
||||
EXTRA_DSO_LDOPTS += $(TK_LIBS)
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
DEFINES += -D_IMPL_NS_PLUGIN
|
||||
|
||||
ifdef MOZ_ENABLE_GTK
|
||||
ifndef MOZ_MONOLITHIC_TOOLKIT
|
||||
CXXFLAGS += $(MOZ_GTK_CFLAGS)
|
||||
CFLAGS += $(MOZ_GTK_CFLAGS)
|
||||
EXTRA_DSO_LDOPTS += -lgtkxtbin -lgtksuperwin -L/usr/X11R6/lib -lXt
|
||||
else
|
||||
CXXFLAGS += $(TK_CFLAGS)
|
||||
CFLAGS += $(TK_CFLAGS)
|
||||
EXTRA_DSO_LDOPTS += -lgtkxtbin -lgtksuperwin -L/usr/X11R6/lib -lXt
|
||||
endif #MOZ_MONOLITHIC_TOOLKIT
|
||||
endif #MOZ_ENABLE_GTK
|
||||
|
||||
ifdef MOZ_ENABLE_QT
|
||||
EXTRA_DSO_LDOPTS += $(MOZ_QT_LDFLAGS)
|
||||
ifndef MOZ_MONOLITHIC_TOOLKIT
|
||||
CXXFLAGS += $(MOZ_QT_CFLAGS)
|
||||
CFLAGS += $(MOZ_QT_CFLAGS)
|
||||
else
|
||||
CXXFLAGS += $(TK_CFLAGS)
|
||||
CFLAGS += $(TK_CFLAGS)
|
||||
endif #MOZ_MONOLITHIC_TOOLKIT
|
||||
endif #MOZ_ENABLE_QT
|
||||
@@ -1,99 +0,0 @@
|
||||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape 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/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
|
||||
DEPTH=..\..\..
|
||||
include <$(DEPTH)/config/config.mak>
|
||||
|
||||
|
||||
EXPORTS = \
|
||||
nsPluginsCID.h \
|
||||
nsIPluginHost.h \
|
||||
nsIPluginInstanceOwner.h
|
||||
|
||||
MAKE_OBJ_TYPE = DLL
|
||||
DLLNAME = gkplugin
|
||||
DLL=.\$(OBJDIR)\$(DLLNAME).dll
|
||||
|
||||
MODULE=raptor
|
||||
IS_COMPONENT=1
|
||||
|
||||
DEFINES =-D_IMPL_NS_PLUGIN -DWIN32_LEAN_AND_MEAN
|
||||
|
||||
OBJS = \
|
||||
.\$(OBJDIR)\ns4xPlugin.obj \
|
||||
.\$(OBJDIR)\ns4xPluginInstance.obj \
|
||||
.\$(OBJDIR)\nsPluginDocLoaderFactory.obj \
|
||||
.\$(OBJDIR)\nsPluginHostImpl.obj \
|
||||
.\$(OBJDIR)\nsPluginModule.obj \
|
||||
.\$(OBJDIR)\nsPluginInstancePeer.obj \
|
||||
.\$(OBJDIR)\nsPluginViewer.obj \
|
||||
.\$(OBJDIR)\nsPluginsDirWin.obj \
|
||||
$(NULL)
|
||||
|
||||
LINCS = \
|
||||
-I$(PUBLIC)\raptor \
|
||||
-I$(PUBLIC)\dom \
|
||||
-I$(PUBLIC)\xpcom \
|
||||
-I$(PUBLIC)\plugin \
|
||||
-I$(PUBLIC)\java \
|
||||
!ifdef NECKO
|
||||
-I$(PUBLIC)\necko \
|
||||
!else
|
||||
-I$(PUBLIC)\netlib \
|
||||
!endif
|
||||
-I$(PUBLIC)\oji \
|
||||
-I$(PUBLIC)\cache \
|
||||
-I$(PUBLIC)\pref \
|
||||
-I$(PUBLIC)\js \
|
||||
$(NULL)
|
||||
|
||||
|
||||
LCFLAGS = \
|
||||
$(LCFLAGS) \
|
||||
-D_IMPL_NS_PLUGIN \
|
||||
-GX \
|
||||
$(NULL)
|
||||
|
||||
!ifdef NU_CACHE
|
||||
CACHELIBNAME=cache.lib
|
||||
!else
|
||||
CACHELIBNAME=netcache.lib
|
||||
!endif
|
||||
|
||||
LLIBS = \
|
||||
$(DIST)\lib\gkgfxwin.lib \
|
||||
$(DIST)\lib\xpcom.lib \
|
||||
$(DIST)\lib\xppref32.lib \
|
||||
$(LIBNSPR)
|
||||
|
||||
WIN_LIBS = \
|
||||
version.lib
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
it:
|
||||
echo $(LLIBS)
|
||||
|
||||
install:: $(DLL)
|
||||
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).dll $(DIST)\bin\components
|
||||
|
||||
clobber::
|
||||
rm -f $(DIST)\bin\$(DLLNAME).dll
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,47 +0,0 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape 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/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
|
||||
DEPTH = ..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
DIRS = \
|
||||
base \
|
||||
cache \
|
||||
dns \
|
||||
socket \
|
||||
mime \
|
||||
streamconv \
|
||||
protocol \
|
||||
build \
|
||||
build2 \
|
||||
resources \
|
||||
$(NULL)
|
||||
|
||||
ifdef ENABLE_TESTS
|
||||
DIRS += test
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape 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/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
|
||||
DEPTH = ../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
DIRS = public src
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
#!gmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape 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/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
|
||||
DEPTH = ..\..
|
||||
|
||||
MODULE = necko
|
||||
|
||||
DIRS= \
|
||||
public \
|
||||
src \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
@@ -1,8 +0,0 @@
|
||||
#
|
||||
# This is a list of local files which get copied to the mozilla:dist directory
|
||||
#
|
||||
|
||||
netCore.h
|
||||
nsNetUtil.h
|
||||
nsUnixColorPrintf.h
|
||||
nsIPasswordManagerUtils.h
|
||||
@@ -1,34 +0,0 @@
|
||||
#
|
||||
# This is a list of local files which get copied to the mozilla:dist directory
|
||||
#
|
||||
|
||||
nsIAuthenticator.idl
|
||||
nsIAuthPrompt.idl
|
||||
nsIChannel.idl
|
||||
nsIFileChannel.idl
|
||||
nsIDownloader.idl
|
||||
nsIFileTransportService.idl
|
||||
nsIPrompt.idl
|
||||
nsIProtocolProxyService.idl
|
||||
nsIProxyAutoConfig.idl
|
||||
nsIProxyAutoConfigUtils.idl
|
||||
nsIProxy.idl
|
||||
nsIRequest.idl
|
||||
nsISocketTransportService.idl
|
||||
nsIStreamIO.idl
|
||||
nsIStreamIOChannel.idl
|
||||
nsIStreamListener.idl
|
||||
nsITransport.idl
|
||||
nsIStreamLoader.idl
|
||||
nsIDownloader.idl
|
||||
nsIRequestObserver.idl
|
||||
nsIRequestObserverProxy.idl
|
||||
nsIStreamProvider.idl
|
||||
nsIURI.idl
|
||||
nsIURL.idl
|
||||
nsIURLParser.idl
|
||||
nsIWebFilters.idl
|
||||
nsISecurityEventSink.idl
|
||||
nsISecretDecoderRing.idl
|
||||
nsISecureBrowserUI.idl
|
||||
nsISecurityManagerComponent.idl
|
||||
@@ -1 +0,0 @@
|
||||
security-prefs.js
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user