Compare commits
2 Commits
src
...
regalloc_c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1c43d4984f | ||
|
|
cfe021ff88 |
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_
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
/* -*- 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
|
* 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
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||||
@@ -16,10 +16,5 @@
|
|||||||
* Reserved.
|
* Reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __NS_JSWINPROTOTYPE_H__
|
#include "Fundamentals.h"
|
||||||
#define __NS_JSWINPROTOTYPE_H__
|
#include "HashSet.h"
|
||||||
|
|
||||||
PRInt32
|
|
||||||
InitWinProfilePrototype(JSContext *jscontext, JSObject *global, JSObject **winRegPrototype);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
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_
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
/* -*- 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
|
* 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
|
* 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
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||||
@@ -16,9 +16,6 @@
|
|||||||
* Reserved.
|
* Reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "nsWinRegValue.h"
|
#include "Fundamentals.h"
|
||||||
|
#include "Liveness.h"
|
||||||
|
|
||||||
PR_BEGIN_EXTERN_C
|
|
||||||
|
|
||||||
|
|
||||||
PR_END_EXTERN_C
|
|
||||||
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,5 +1,5 @@
|
|||||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
/* -*- 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
|
* 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
|
* 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
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||||
@@ -16,23 +16,23 @@
|
|||||||
* Reserved.
|
* Reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef nsInstallFileOpEnums_h__
|
#ifndef _REGISTER_ASSIGNER_H_
|
||||||
#define nsInstallFileOpEnums_h__
|
#define _REGISTER_ASSIGNER_H_
|
||||||
|
|
||||||
typedef enum nsInstallFileOpEnums {
|
#include "Fundamentals.h"
|
||||||
NS_FOP_DIR_CREATE = 0,
|
#include "VirtualRegister.h"
|
||||||
NS_FOP_DIR_REMOVE = 1,
|
|
||||||
NS_FOP_DIR_RENAME = 2,
|
|
||||||
NS_FOP_FILE_COPY = 3,
|
|
||||||
NS_FOP_FILE_DELETE = 4,
|
|
||||||
NS_FOP_FILE_EXECUTE = 5,
|
|
||||||
NS_FOP_FILE_MOVE = 6,
|
|
||||||
NS_FOP_FILE_RENAME = 7,
|
|
||||||
NS_FOP_WIN_SHORTCUT_CREATE = 8,
|
|
||||||
NS_FOP_MAC_ALIAS_CREATE = 9,
|
|
||||||
NS_FOP_UNIX_LINK_CREATE = 10,
|
|
||||||
NS_FOP_FILE_SET_STAT = 11
|
|
||||||
|
|
||||||
} nsInstallFileOpEnums;
|
class FastBitMatrix;
|
||||||
|
|
||||||
#endif /* nsInstallFileOpEnums_h__ */
|
class RegisterAssigner
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
VirtualRegisterManager& vRegManager;
|
||||||
|
|
||||||
|
public:
|
||||||
|
RegisterAssigner(VirtualRegisterManager& vrMan) : vRegManager(vrMan) {}
|
||||||
|
|
||||||
|
virtual bool assignRegisters(FastBitMatrix& interferenceMatrix) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _REGISTER_ASSIGNER_H_ */
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
/* -*- 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
|
* 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
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||||
@@ -16,10 +16,10 @@
|
|||||||
* Reserved.
|
* Reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __NS_JSWINREG_H__
|
#ifndef _REGISTER_CLASS_H_
|
||||||
#define __NS_JSWINREG_H__
|
#define _REGISTER_CLASS_H_
|
||||||
|
|
||||||
PRInt32
|
#include "Fundamentals.h"
|
||||||
InitWinRegPrototype(JSContext *jscontext, JSObject *global, JSObject **winRegPrototype);
|
#include "RegisterTypes.h"
|
||||||
|
|
||||||
#endif
|
#endif // _REGISTER_CLASS_H_
|
||||||
37
mozilla/ef/Compiler/RegisterAllocator/RegisterPressure.h
Normal file
37
mozilla/ef/Compiler/RegisterAllocator/RegisterPressure.h
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _REGISTER_PRESSURE_H_
|
||||||
|
#define _REGISTER_PRESSURE_H_
|
||||||
|
|
||||||
|
#include "BitSet.h"
|
||||||
|
#include "HashSet.h"
|
||||||
|
|
||||||
|
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_ */
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
/* -*- 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
|
* 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
|
* 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
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||||
@@ -16,41 +16,25 @@
|
|||||||
* Reserved.
|
* Reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef nsWinRegValue_h__
|
#include "Fundamentals.h"
|
||||||
#define nsWinRegValue_h__
|
#include "VirtualRegister.h"
|
||||||
|
#include "Instruction.h"
|
||||||
|
|
||||||
#include "prtypes.h"
|
//------------------------------------------------------------------------------
|
||||||
|
// VirtualRegister -
|
||||||
|
|
||||||
|
#ifdef MANUAL_TEMPLATES
|
||||||
|
template class IndexedPool<VirtualRegister>;
|
||||||
|
#endif
|
||||||
|
|
||||||
PR_BEGIN_EXTERN_C
|
// Set the defining instruction.
|
||||||
|
//
|
||||||
|
void VirtualRegister::setDefiningInstruction(Instruction& instruction)
|
||||||
|
{
|
||||||
|
if (definingInstruction != NULL) {
|
||||||
|
if ((instruction.getFlags() & ifCopy) && (definingInstruction->getFlags() & ifPhiNode))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
definingInstruction = &instruction;
|
||||||
|
}
|
||||||
|
|
||||||
struct nsWinRegValue {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/* Public Fields */
|
|
||||||
PRInt32 type;
|
|
||||||
void* data;
|
|
||||||
PRInt32 data_length;
|
|
||||||
|
|
||||||
/* Public Methods */
|
|
||||||
nsWinRegValue(PRInt32 datatype, void* regdata, PRInt32 len)
|
|
||||||
{
|
|
||||||
type = datatype;
|
|
||||||
data = regdata;
|
|
||||||
data_length = len;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* should we copy the regdata? */
|
|
||||||
private:
|
|
||||||
|
|
||||||
/* Private Fields */
|
|
||||||
|
|
||||||
|
|
||||||
/* Private Methods */
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
PR_END_EXTERN_C
|
|
||||||
|
|
||||||
#endif /* nsWinRegValue_h__ */
|
|
||||||
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_
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
#!gmake
|
|
||||||
#
|
|
||||||
# The contents of this file are subject to the Netscape Public License
|
|
||||||
# Version 1.0 (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,
|
|
||||||
# released March 31, 1998.
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
# Contributors:
|
|
||||||
# Daniel Veditz <dveditz@netscape.com>
|
|
||||||
# Douglas Turner <dougt@netscape.com>
|
|
||||||
|
|
||||||
|
|
||||||
DEPTH = ..
|
|
||||||
topsrcdir = @top_srcdir@
|
|
||||||
srcdir = @srcdir@
|
|
||||||
VPATH = @srcdir@
|
|
||||||
|
|
||||||
include $(DEPTH)/config/autoconf.mk
|
|
||||||
|
|
||||||
DIRS = public
|
|
||||||
|
|
||||||
include $(topsrcdir)/config/config.mk
|
|
||||||
|
|
||||||
include $(topsrcdir)/config/rules.mk
|
|
||||||
|
|
||||||
|
|
||||||
Binary file not shown.
Binary file not shown.
@@ -1,30 +0,0 @@
|
|||||||
#!nmake
|
|
||||||
#
|
|
||||||
# The contents of this file are subject to the Netscape Public License
|
|
||||||
# Version 1.0 (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,
|
|
||||||
# released March 31, 1998.
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
# Contributors:
|
|
||||||
# Daniel Veditz <dveditz@netscape.com>
|
|
||||||
# Douglas Turner <dougt@netscape.com>
|
|
||||||
|
|
||||||
|
|
||||||
DEPTH=..
|
|
||||||
|
|
||||||
DIRS= public res src
|
|
||||||
|
|
||||||
include <$(DEPTH)\config\rules.mak>
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:NC="http://home.netscape.com/NC-rdf#">
|
|
||||||
|
|
||||||
<RDF:Bag ID="NC:SoftwareUpdateRoot">
|
|
||||||
<RDF:li>
|
|
||||||
<RDF:Bag ID="NC:NewSoftwareToday" NC:title="New Software">
|
|
||||||
|
|
||||||
<RDF:li>
|
|
||||||
<RDF:Description ID="AimUpdate344">
|
|
||||||
<NC:type resource="http://home.netscape.com/NC-rdf#SoftwarePackage" />
|
|
||||||
<NC:title>AOL AIM</NC:title>
|
|
||||||
<NC:description>An Instant Message Client</NC:description>
|
|
||||||
<NC:version>3.4.1.12</NC:version>
|
|
||||||
<NC:registryKey>/AOL/AIM/</NC:registryKey>
|
|
||||||
<NC:url>http://home.netscape.com/index.html</NC:url>
|
|
||||||
</RDF:Description>
|
|
||||||
</RDF:li>
|
|
||||||
|
|
||||||
<RDF:li>
|
|
||||||
<RDF:Description ID="PGPPlugin345">
|
|
||||||
<NC:type resource="http://home.netscape.com/NC-rdf#SoftwarePackage" />
|
|
||||||
<NC:title>PGP Plugin For Mozilla</NC:title>
|
|
||||||
<NC:description>A high grade encryption plugin</NC:description>
|
|
||||||
<NC:version>1.1.2.0</NC:version>
|
|
||||||
<NC:registryKey>/PGP/ROCKS/</NC:registryKey>
|
|
||||||
<NC:url>http://home.netscape.com/index.html</NC:url>
|
|
||||||
</RDF:Description>
|
|
||||||
</RDF:li>
|
|
||||||
|
|
||||||
</RDF:Bag>
|
|
||||||
</RDF:li>
|
|
||||||
</RDF:Bag>
|
|
||||||
</RDF:RDF>
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
window {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
tree {
|
|
||||||
display: table;
|
|
||||||
background-color: #FFFFFF;
|
|
||||||
border: none;
|
|
||||||
border-spacing: 0px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
treecol {
|
|
||||||
display: table-column;
|
|
||||||
width: 200px;
|
|
||||||
}
|
|
||||||
|
|
||||||
treeitem {
|
|
||||||
display: table-row;
|
|
||||||
}
|
|
||||||
|
|
||||||
treehead {
|
|
||||||
display: table-header-group;
|
|
||||||
}
|
|
||||||
|
|
||||||
treebody {
|
|
||||||
display: table-row-group;
|
|
||||||
}
|
|
||||||
|
|
||||||
treecell {
|
|
||||||
display: table-cell;
|
|
||||||
font-family: Verdana, Sans-Serif;
|
|
||||||
font-size: 8pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
treecell[selectedcell] {
|
|
||||||
background-color: yellow;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
treehead treeitem treecell {
|
|
||||||
background-color: #c0c0c0;
|
|
||||||
border: outset 1px;
|
|
||||||
border-color: white #707070 #707070 white;
|
|
||||||
padding-left: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
treeitem[type="http://home.netscape.com/NC-rdf#SoftwarePackage"] > treecell > titledbutton {
|
|
||||||
list-style-image: url("resource:/res/rdf/SoftwareUpdatePackage.gif");
|
|
||||||
}
|
|
||||||
|
|
||||||
treeitem[type="http://home.netscape.com/NC-rdf#Folder"] > treecell > titledbutton {
|
|
||||||
list-style-image: url("resource:/res/rdf/bookmark-folder-closed.gif");
|
|
||||||
|
|
||||||
treeitem[type="http://home.netscape.com/NC-rdf#Folder"][open="true"] > treecell > titledbutton {
|
|
||||||
list-style-image: url("resource:/res/rdf/bookmark-folder-open.gif");
|
|
||||||
}
|
|
||||||
@@ -1,123 +0,0 @@
|
|||||||
// the rdf service
|
|
||||||
var RDF = Components.classes['component://netscape/rdf/rdf-service'].getService();
|
|
||||||
RDF = RDF.QueryInterface(Components.interfaces.nsIRDFService);
|
|
||||||
|
|
||||||
function getAttr(registry,service,attr_name)
|
|
||||||
{
|
|
||||||
var attr = registry.GetTarget(service,
|
|
||||||
RDF.GetResource('http://home.netscape.com/NC-rdf#' + attr_name),
|
|
||||||
true);
|
|
||||||
if (attr)
|
|
||||||
attr = attr.QueryInterface(Components.interfaces.nsIRDFLiteral);
|
|
||||||
|
|
||||||
if (attr)
|
|
||||||
attr = attr.Value;
|
|
||||||
|
|
||||||
return attr;
|
|
||||||
}
|
|
||||||
|
|
||||||
function Init()
|
|
||||||
{
|
|
||||||
// this is the main rdf file.
|
|
||||||
|
|
||||||
var mainRegistry = RDF.GetDataSource('resource://res/rdf/SoftwareUpdates.rdf');
|
|
||||||
|
|
||||||
var mainContainer = Components.classes['component://netscape/rdf/container'].createInstance();
|
|
||||||
mainContainer = mainContainer.QueryInterface(Components.interfaces.nsIRDFContainer);
|
|
||||||
|
|
||||||
mainContainer.Init(mainRegistry, RDF.GetResource('NC:SoftwareUpdateDataSources'));
|
|
||||||
|
|
||||||
// Now enumerate all of the softwareupdate datasources.
|
|
||||||
var mainEnumerator = mainContainer.GetElements();
|
|
||||||
while (mainEnumerator.HasMoreElements())
|
|
||||||
{
|
|
||||||
var aDistributor = mainEnumerator.GetNext();
|
|
||||||
aDistributor = aDistributor.QueryInterface(Components.interfaces.nsIRDFResource);
|
|
||||||
|
|
||||||
var distributorContainer = Components.classes['component://netscape/rdf/container'].createInstance();
|
|
||||||
distributorContainer = distributorContainer.QueryInterface(Components.interfaces.nsIRDFContainer);
|
|
||||||
|
|
||||||
var distributorRegistry = RDF.GetDataSource(aDistributor.Value);
|
|
||||||
var distributorResource = RDF.GetResource('NC:SoftwareUpdateRoot');
|
|
||||||
|
|
||||||
distributorContainer.Init(distributorRegistry, distributorResource);
|
|
||||||
|
|
||||||
// Now enumerate all of the distributorContainer's packages.
|
|
||||||
|
|
||||||
var distributorEnumerator = distributorContainer.GetElements();
|
|
||||||
|
|
||||||
while (distributorEnumerator.HasMoreElements())
|
|
||||||
{
|
|
||||||
var aPackage = distributorEnumerator.GetNext();
|
|
||||||
aPackage = aPackage.QueryInterface(Components.interfaces.nsIRDFResource);
|
|
||||||
|
|
||||||
// remove any that we do not want.
|
|
||||||
|
|
||||||
if (getAttr(distributorRegistry, aPackage, 'title') == "AOL AIM")
|
|
||||||
{
|
|
||||||
//distributorContainer.RemoveElement(aPackage, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var tree = document.getElementById('tree');
|
|
||||||
|
|
||||||
// Add it to the tree control's composite datasource.
|
|
||||||
tree.database.AddDataSource(distributorRegistry);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Install all of the stylesheets in the softwareupdate Registry into the
|
|
||||||
// panel.
|
|
||||||
|
|
||||||
// TODO
|
|
||||||
|
|
||||||
// XXX hack to force the tree to rebuild
|
|
||||||
var treebody = document.getElementById('NC:SoftwareUpdateRoot');
|
|
||||||
treebody.setAttribute('id', 'NC:SoftwareUpdateRoot');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function OpenURL(event, node)
|
|
||||||
{
|
|
||||||
if (node.getAttribute('type') == "http://home.netscape.com/NC-rdf#SoftwarePackage")
|
|
||||||
{
|
|
||||||
url = node.getAttribute('url');
|
|
||||||
|
|
||||||
/*window.open(url,'bookmarks');*/
|
|
||||||
|
|
||||||
var toolkitCore = XPAppCoresManager.Find("ToolkitCore");
|
|
||||||
if (!toolkitCore)
|
|
||||||
{
|
|
||||||
toolkitCore = new ToolkitCore();
|
|
||||||
if (toolkitCore)
|
|
||||||
{
|
|
||||||
toolkitCore.Init("ToolkitCore");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (toolkitCore)
|
|
||||||
{
|
|
||||||
toolkitCore.ShowWindow(url,window);
|
|
||||||
}
|
|
||||||
|
|
||||||
dump("OpenURL(" + url + ")\n");
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// To get around "window.onload" not working in viewer.
|
|
||||||
function Boot()
|
|
||||||
{
|
|
||||||
var tree = document.getElementById('tree');
|
|
||||||
if (tree == null) {
|
|
||||||
setTimeout(Boot, 0);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Init();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setTimeout('Boot()', 0);
|
|
||||||
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
<?xml-stylesheet href="resource:/res/rdf/sidebar.css" type="text/css"?>
|
|
||||||
<?xml-stylesheet href="resource:/res/rdf/SoftwareUpdate.css" type="text/css"?>
|
|
||||||
<window
|
|
||||||
xmlns:html="http://www.w3.org/TR/REC-html40"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
|
||||||
|
|
||||||
<html:script src="SoftwareUpdate.js"/>
|
|
||||||
|
|
||||||
<tree id="tree"
|
|
||||||
flex="100%"
|
|
||||||
datasources="rdf:softwareupdates"
|
|
||||||
ondblclick="return OpenURL(event, event.target.parentNode);">
|
|
||||||
|
|
||||||
<treecol rdf:resource="http://home.netscape.com/NC-rdf#title" />
|
|
||||||
<treecol rdf:resource="http://home.netscape.com/NC-rdf#description" />
|
|
||||||
<treecol rdf:resource="http://home.netscape.com/NC-rdf#version" />
|
|
||||||
|
|
||||||
<treehead>
|
|
||||||
<treeitem>
|
|
||||||
<treecell>Title</treecell>
|
|
||||||
<treecell>Description</treecell>
|
|
||||||
<treecell>Version</treecell>
|
|
||||||
</treeitem>
|
|
||||||
</treehead>
|
|
||||||
|
|
||||||
<treebody id="NC:SoftwareUpdateRoot" rdf:containment="http://home.netscape.com/NC-rdf#child" />
|
|
||||||
</tree>
|
|
||||||
</window>
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 201 B |
@@ -1,7 +0,0 @@
|
|||||||
<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:NC="http://home.netscape.com/softwareupdate-schema#">
|
|
||||||
|
|
||||||
<RDF:Bag ID="NC:SoftwareUpdateDataSources">
|
|
||||||
<RDF:li resource="resource:/res/rdf/SoftwareUpdate-Source-1.rdf" />
|
|
||||||
</RDF:Bag>
|
|
||||||
</RDF:RDF>
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
#
|
|
||||||
# This is a list of local files which get copied to the mozilla:dist directory
|
|
||||||
#
|
|
||||||
|
|
||||||
nsISoftwareUpdate.h
|
|
||||||
nsSoftwareUpdateIIDs.h
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
#!gmake
|
|
||||||
#
|
|
||||||
# The contents of this file are subject to the Netscape Public License
|
|
||||||
# Version 1.0 (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,
|
|
||||||
# released March 31, 1998.
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
# Contributors:
|
|
||||||
# Daniel Veditz <dveditz@netscape.com>
|
|
||||||
# Douglas Turner <dougt@netscape.com>
|
|
||||||
|
|
||||||
DEPTH = ../..
|
|
||||||
topsrcdir = @top_srcdir@
|
|
||||||
srcdir = @srcdir@
|
|
||||||
VPATH = @srcdir@
|
|
||||||
|
|
||||||
include $(DEPTH)/config/autoconf.mk
|
|
||||||
|
|
||||||
MODULE = xpinstall
|
|
||||||
|
|
||||||
XPIDLSRCS = nsIXPInstallProgress.idl
|
|
||||||
|
|
||||||
EXPORTS = \
|
|
||||||
nsIDOMInstallTriggerGlobal.h \
|
|
||||||
nsIDOMInstallVersion.h \
|
|
||||||
nsSoftwareUpdateIIDs.h \
|
|
||||||
nsISoftwareUpdate.h \
|
|
||||||
$(NULL)
|
|
||||||
|
|
||||||
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
|
|
||||||
|
|
||||||
include $(topsrcdir)/config/config.mk
|
|
||||||
|
|
||||||
include $(topsrcdir)/config/rules.mk
|
|
||||||
@@ -1,113 +0,0 @@
|
|||||||
interface Install
|
|
||||||
{
|
|
||||||
/* IID: { 0x18c2f988, 0xb09f, 0x11d2, \
|
|
||||||
{0xbc, 0xde, 0x00, 0x80, 0x5f, 0x0e, 0x13, 0x53}} */
|
|
||||||
|
|
||||||
const int BAD_PACKAGE_NAME = -200;
|
|
||||||
const int UNEXPECTED_ERROR = -201;
|
|
||||||
const int ACCESS_DENIED = -202;
|
|
||||||
const int TOO_MANY_CERTIFICATES = -203; /* Installer file must have 1 certificate */
|
|
||||||
const int NO_INSTALLER_CERTIFICATE = -204; /* Installer file must have a certificate */
|
|
||||||
const int NO_CERTIFICATE = -205; /* Extracted file is not signed */
|
|
||||||
const int NO_MATCHING_CERTIFICATE = -206; /* Extracted file does not match installer certificate */
|
|
||||||
const int UNKNOWN_JAR_FILE = -207; /* JAR file has not been opened */
|
|
||||||
const int INVALID_ARGUMENTS = -208; /* Bad arguments to a function */
|
|
||||||
const int ILLEGAL_RELATIVE_PATH = -209; /* Illegal relative path */
|
|
||||||
const int USER_CANCELLED = -210; /* User cancelled */
|
|
||||||
const int INSTALL_NOT_STARTED = -211;
|
|
||||||
const int SILENT_MODE_DENIED = -212;
|
|
||||||
const int NO_SUCH_COMPONENT = -213; /* no such component in the registry. */
|
|
||||||
const int FILE_DOES_NOT_EXIST = -214; /* File cannot be deleted as it does not exist */
|
|
||||||
const int FILE_READ_ONLY = -215; /* File cannot be deleted as it is read only. */
|
|
||||||
const int FILE_IS_DIRECTORY = -216; /* File cannot be deleted as it is a directory */
|
|
||||||
const int NETWORK_FILE_IS_IN_USE = -217; /* File on the network is in-use */
|
|
||||||
const int APPLE_SINGLE_ERR = -218; /* error in AppleSingle unpacking */
|
|
||||||
const int INVALID_PATH_ERR = -219; /* GetFolder() did not like the folderID */
|
|
||||||
const int PATCH_BAD_DIFF = -220; /* error in GDIFF patch */
|
|
||||||
const int PATCH_BAD_CHECKSUM_TARGET = -221; /* source file doesn't checksum */
|
|
||||||
const int PATCH_BAD_CHECKSUM_RESULT = -222; /* final patched file fails checksum */
|
|
||||||
const int UNINSTALL_FAILED = -223; /* error while uninstalling a package */
|
|
||||||
const int GESTALT_UNKNOWN_ERR = -5550;
|
|
||||||
const int GESTALT_INVALID_ARGUMENT = -5551;
|
|
||||||
|
|
||||||
const int SUCCESS = 0;
|
|
||||||
const int REBOOT_NEEDED = 999;
|
|
||||||
|
|
||||||
/* install types */
|
|
||||||
const int LIMITED_INSTALL = 0;
|
|
||||||
const int FULL_INSTALL = 1;
|
|
||||||
const int NO_STATUS_DLG = 2;
|
|
||||||
const int NO_FINALIZE_DLG = 4;
|
|
||||||
|
|
||||||
// these should not be public...
|
|
||||||
/* message IDs*/
|
|
||||||
const int SU_INSTALL_FILE_UNEXPECTED_MSG_ID = 0;
|
|
||||||
const int SU_DETAILS_REPLACE_FILE_MSG_ID = 1;
|
|
||||||
const int SU_DETAILS_INSTALL_FILE_MSG_ID = 2;
|
|
||||||
//////////////////////////
|
|
||||||
|
|
||||||
readonly attribute wstring UserPackageName;
|
|
||||||
readonly attribute wstring RegPackageName;
|
|
||||||
|
|
||||||
void Install();
|
|
||||||
|
|
||||||
void AbortInstall();
|
|
||||||
|
|
||||||
long AddDirectory( in wstring regName,
|
|
||||||
in wstring version,
|
|
||||||
in wstring jarSource,
|
|
||||||
in InstallFolder folder,
|
|
||||||
in wstring subdir,
|
|
||||||
in boolean forceMode );
|
|
||||||
|
|
||||||
|
|
||||||
long AddSubcomponent( in wstring regName,
|
|
||||||
in wstring version,
|
|
||||||
in wstring jarSource,
|
|
||||||
in InstallFolder folder,
|
|
||||||
in wstring targetName,
|
|
||||||
in boolean forceMode );
|
|
||||||
|
|
||||||
long DeleteComponent( in wstring registryName);
|
|
||||||
|
|
||||||
long DeleteFile( in InstallFolder folder,
|
|
||||||
in wstring relativeFileName );
|
|
||||||
|
|
||||||
long DiskSpaceAvailable( in InstallFolder folder );
|
|
||||||
|
|
||||||
long Execute(in wstring jarSource, in wstring args);
|
|
||||||
|
|
||||||
long FinalizeInstall();
|
|
||||||
|
|
||||||
long Gestalt (in wstring selector);
|
|
||||||
|
|
||||||
InstallFolder GetComponentFolder( in wstring regName,
|
|
||||||
in wstring subdirectory);
|
|
||||||
|
|
||||||
InstallFolder GetFolder(in wstring targetFolder,
|
|
||||||
in wstring subdirectory);
|
|
||||||
|
|
||||||
long GetLastError();
|
|
||||||
|
|
||||||
long GetWinProfile(in InstallFolder folder, in wstring file);
|
|
||||||
|
|
||||||
long GetWinRegistry();
|
|
||||||
|
|
||||||
long Patch( in wstring regName,
|
|
||||||
in wstring version,
|
|
||||||
in wstring jarSource,
|
|
||||||
in InstallFolder folder,
|
|
||||||
in wstring targetName );
|
|
||||||
|
|
||||||
void ResetError();
|
|
||||||
|
|
||||||
void SetPackageFolder( in InstallFolder folder );
|
|
||||||
|
|
||||||
long StartInstall( in wstring userPackageName,
|
|
||||||
in wstring packageName,
|
|
||||||
in wstring version,
|
|
||||||
in long flags );
|
|
||||||
|
|
||||||
long Uninstall( in wstring packageName);
|
|
||||||
|
|
||||||
};
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
interface InstallTriggerGlobal
|
|
||||||
{
|
|
||||||
/* IID: { 0x18c2f987, 0xb09f, 0x11d2, \
|
|
||||||
{0xbc, 0xde, 0x00, 0x80, 0x5f, 0x0e, 0x13, 0x53}} */
|
|
||||||
|
|
||||||
const int MAJOR_DIFF = 4;
|
|
||||||
const int MINOR_DIFF = 3;
|
|
||||||
const int REL_DIFF = 2;
|
|
||||||
const int BLD_DIFF = 1;
|
|
||||||
const int EQUAL = 0;
|
|
||||||
|
|
||||||
boolean UpdateEnabled ();
|
|
||||||
|
|
||||||
long StartSoftwareUpdate(in wstring URL);
|
|
||||||
|
|
||||||
long ConditionalSoftwareUpdate( in wstring URL,
|
|
||||||
in wstring regName,
|
|
||||||
in long diffLevel,
|
|
||||||
in wstring version,
|
|
||||||
in long mode);
|
|
||||||
|
|
||||||
long CompareVersion( in wstring regName, in wstring version );
|
|
||||||
|
|
||||||
};
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
interface InstallVersion
|
|
||||||
{
|
|
||||||
/* IID: { 0x18c2f986, 0xb09f, 0x11d2, \
|
|
||||||
{0xbc, 0xde, 0x00, 0x80, 0x5f, 0x0e, 0x13, 0x53}} */
|
|
||||||
|
|
||||||
const int EQUAL = 0;
|
|
||||||
const int BLD_DIFF = 1;
|
|
||||||
const int BLD_DIFF_MINUS = -1;
|
|
||||||
const int REL_DIFF = 2;
|
|
||||||
const int REL_DIFF_MINUS = -2;
|
|
||||||
const int MINOR_DIFF = 3;
|
|
||||||
const int MINOR_DIFF_MINUS = -3;
|
|
||||||
const int MAJOR_DIFF = 4;
|
|
||||||
const int MAJOR_DIFF_MINUS = -4;
|
|
||||||
|
|
||||||
attribute int major;
|
|
||||||
attribute int minor;
|
|
||||||
attribute int release;
|
|
||||||
attribute int build;
|
|
||||||
|
|
||||||
void InstallVersion();
|
|
||||||
|
|
||||||
void init(in wstring versionString);
|
|
||||||
/*
|
|
||||||
void init(in int major, in int minor, in int release, in int build);
|
|
||||||
*/
|
|
||||||
wstring toString();
|
|
||||||
|
|
||||||
/* int compareTo(in wstring version);
|
|
||||||
int compareTo(in int major, in int minor, in int release, in int build);
|
|
||||||
*/
|
|
||||||
int compareTo(in InstallVersion versionObject);
|
|
||||||
|
|
||||||
};
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
#!nmake
|
|
||||||
#
|
|
||||||
# The contents of this file are subject to the Netscape Public License
|
|
||||||
# Version 1.0 (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,
|
|
||||||
# released March 31, 1998.
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
# Contributors:
|
|
||||||
# Daniel Veditz <dveditz@netscape.com>
|
|
||||||
# Douglas Turner <dougt@netscape.com>
|
|
||||||
|
|
||||||
MODULE=xpinstall
|
|
||||||
DEPTH=..\..
|
|
||||||
|
|
||||||
EXPORTS= nsIDOMInstallTriggerGlobal.h \
|
|
||||||
nsIDOMInstallVersion.h \
|
|
||||||
nsSoftwareUpdateIIDs.h \
|
|
||||||
nsISoftwareUpdate.h
|
|
||||||
|
|
||||||
XPIDLSRCS = .\nsIXPInstallProgress.idl
|
|
||||||
|
|
||||||
include <$(DEPTH)\config\config.mak>
|
|
||||||
include <$(DEPTH)\config\rules.mak>
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
#error
|
|
||||||
@@ -1,96 +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.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.
|
|
||||||
*/
|
|
||||||
/* AUTO-GENERATED. DO NOT EDIT!!! */
|
|
||||||
|
|
||||||
#ifndef nsIDOMInstallTriggerGlobal_h__
|
|
||||||
#define nsIDOMInstallTriggerGlobal_h__
|
|
||||||
|
|
||||||
#include "nsISupports.h"
|
|
||||||
#include "nsString.h"
|
|
||||||
#include "nsIScriptContext.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define NS_IDOMINSTALLTRIGGERGLOBAL_IID \
|
|
||||||
{ 0x18c2f987, 0xb09f, 0x11d2, \
|
|
||||||
{0xbc, 0xde, 0x00, 0x80, 0x5f, 0x0e, 0x13, 0x53}}
|
|
||||||
|
|
||||||
class nsIDOMInstallTriggerGlobal : public nsISupports {
|
|
||||||
public:
|
|
||||||
static const nsIID& IID() { static nsIID iid = NS_IDOMINSTALLTRIGGERGLOBAL_IID; return iid; }
|
|
||||||
enum {
|
|
||||||
MAJOR_DIFF = 4,
|
|
||||||
MINOR_DIFF = 3,
|
|
||||||
REL_DIFF = 2,
|
|
||||||
BLD_DIFF = 1,
|
|
||||||
EQUAL = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
NS_IMETHOD UpdateEnabled(PRBool* aReturn)=0;
|
|
||||||
|
|
||||||
NS_IMETHOD StartSoftwareUpdate(const nsString& aURL, PRInt32* aReturn)=0;
|
|
||||||
NS_IMETHOD StartSoftwareUpdate(const nsString& aURL, PRInt32 aFlags, PRInt32* aReturn)=0;
|
|
||||||
|
|
||||||
NS_IMETHOD ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, PRInt32 aDiffLevel, const nsString& aVersion, PRInt32 aMode, PRInt32* aReturn)=0;
|
|
||||||
NS_IMETHOD ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, PRInt32 aDiffLevel, nsIDOMInstallVersion* aVersion, PRInt32 aMode, PRInt32* aReturn)=0;
|
|
||||||
NS_IMETHOD ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, nsIDOMInstallVersion* aVersion, PRInt32 aMode, PRInt32* aReturn)=0;
|
|
||||||
NS_IMETHOD ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, const nsString& aVersion, PRInt32 aMode, PRInt32* aReturn)=0;
|
|
||||||
NS_IMETHOD ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, const nsString& aVersion, PRInt32* aReturn)=0;
|
|
||||||
NS_IMETHOD ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, nsIDOMInstallVersion* aVersion, PRInt32* aReturn)=0;
|
|
||||||
|
|
||||||
NS_IMETHOD CompareVersion(const nsString& aRegName, PRInt32 aMajor, PRInt32 aMinor, PRInt32 aRelease, PRInt32 aBuild, PRInt32* aReturn)=0;
|
|
||||||
NS_IMETHOD CompareVersion(const nsString& aRegName, const nsString& aVersion, PRInt32* aReturn)=0;
|
|
||||||
NS_IMETHOD CompareVersion(const nsString& aRegName, nsIDOMInstallVersion* aVersion, PRInt32* aReturn)=0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#define NS_DECL_IDOMINSTALLTRIGGERGLOBAL \
|
|
||||||
NS_IMETHOD UpdateEnabled(PRBool* aReturn); \
|
|
||||||
NS_IMETHOD StartSoftwareUpdate(const nsString& aURL, PRInt32 aFlags, PRInt32* aReturn); \
|
|
||||||
NS_IMETHOD StartSoftwareUpdate(const nsString& aURL, PRInt32* aReturn); \
|
|
||||||
NS_IMETHOD ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, PRInt32 aDiffLevel, const nsString& aVersion, PRInt32 aMode, PRInt32* aReturn); \
|
|
||||||
NS_IMETHOD ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, PRInt32 aDiffLevel, nsIDOMInstallVersion* aVersion, PRInt32 aMode, PRInt32* aReturn); \
|
|
||||||
NS_IMETHOD ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, nsIDOMInstallVersion* aVersion, PRInt32 aMode, PRInt32* aReturn); \
|
|
||||||
NS_IMETHOD ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, const nsString& aVersion, PRInt32 aMode, PRInt32* aReturn); \
|
|
||||||
NS_IMETHOD ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, const nsString& aVersion, PRInt32* aReturn); \
|
|
||||||
NS_IMETHOD ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, nsIDOMInstallVersion* aVersion, PRInt32* aReturn); \
|
|
||||||
NS_IMETHOD CompareVersion(const nsString& aRegName, PRInt32 aMajor, PRInt32 aMinor, PRInt32 aRelease, PRInt32 aBuild, PRInt32* aReturn); \
|
|
||||||
NS_IMETHOD CompareVersion(const nsString& aRegName, const nsString& aVersion, PRInt32* aReturn); \
|
|
||||||
NS_IMETHOD CompareVersion(const nsString& aRegName, nsIDOMInstallVersion* aVersion, PRInt32* aReturn); \
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define NS_FORWARD_IDOMINSTALLTRIGGERGLOBAL(_to) \
|
|
||||||
NS_IMETHOD UpdateEnabled(PRBool* aReturn) { return _to##UpdateEnabled(aReturn); } \
|
|
||||||
NS_IMETHOD StartSoftwareUpdate(const nsString& aURL, PRInt32 aFlags, PRInt32* aReturn) { return _to##StartSoftwareUpdate(aURL, aFlags, aReturn); } \
|
|
||||||
NS_IMETHOD StartSoftwareUpdate(const nsString& aURL, PRInt32* aReturn) { return _to##StartSoftwareUpdate(aURL, aReturn); } \
|
|
||||||
NS_IMETHOD ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, PRInt32 aDiffLevel, const nsString& aVersion, PRInt32 aMode, PRInt32* aReturn) { return _to##ConditionalSoftwareUpdate(aURL, aRegName, aDiffLevel, aVersion, aMode, aReturn); } \
|
|
||||||
NS_IMETHOD ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, PRInt32 aDiffLevel, nsIDOMInstallVersion* aVersion, PRInt32 aMode, PRInt32* aReturn) { return _to##ConditionalSoftwareUpdate(aURL, aRegName, aDiffLevel, aVersion, aMode, aReturn); } \
|
|
||||||
NS_IMETHOD ConditionalSoftwareUpdate(const nsString& aURL, nsIDOMInstallVersion* aRegName, const nsString& aVersion, PRInt32 aMode, PRInt32* aReturn) { return _to##ConditionalSoftwareUpdate(aURL, aDiffLevel, aVersion, aMode, aReturn); } \
|
|
||||||
NS_IMETHOD ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, const nsString& aVersion, PRInt32 aMode, PRInt32* aReturn) { return _to##ConditionalSoftwareUpdate(aURL, aDiffLevel, aVersion, aMode, aReturn); } \
|
|
||||||
NS_IMETHOD ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, const nsString& aVersion, PRInt32* aReturn) { return _to##ConditionalSoftwareUpdate(aURL, aDiffLevel, aVersion, aReturn); } \
|
|
||||||
NS_IMETHOD ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, nsIDOMInstallVersion* aVersion, PRInt32* aReturn) { return _to##ConditionalSoftwareUpdate(aURL, aDiffLevel, aVersion, aReturn); } \
|
|
||||||
NS_IMETHOD CompareVersion(const nsString& aRegName, PRInt32 aMajor, PRInt32 aMinor, PRInt32 aRelease, PRInt32 aBuild, PRInt32* aReturn) { return _to##CompareVersion(aRegName, aMajor, aMinor, aRelease, aBuild, aReturn); } \
|
|
||||||
NS_IMETHOD CompareVersion(const nsString& aRegName, const nsString& aVersion, PRInt32* aReturn) { return _to##CompareVersion(aRegName, aVersion, aReturn); } \
|
|
||||||
NS_IMETHOD CompareVersion(const nsString& aRegName, nsIDOMInstallVersion* aVersion, PRInt32* aReturn) { return _to##CompareVersion(aRegName, aVersion, aReturn); } \
|
|
||||||
|
|
||||||
|
|
||||||
extern nsresult NS_InitInstallTriggerGlobalClass(nsIScriptContext *aContext, void **aPrototype);
|
|
||||||
|
|
||||||
extern "C" NS_DOM nsresult NS_NewScriptInstallTriggerGlobal(nsIScriptContext *aContext, nsISupports *aSupports, nsISupports *aParent, void **aReturn);
|
|
||||||
|
|
||||||
#endif // nsIDOMInstallTriggerGlobal_h__
|
|
||||||
@@ -1,107 +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.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.
|
|
||||||
*/
|
|
||||||
/* AUTO-GENERATED. DO NOT EDIT!!! */
|
|
||||||
|
|
||||||
#ifndef nsIDOMInstallVersion_h__
|
|
||||||
#define nsIDOMInstallVersion_h__
|
|
||||||
|
|
||||||
#include "nsISupports.h"
|
|
||||||
#include "nsString.h"
|
|
||||||
#include "nsIScriptContext.h"
|
|
||||||
|
|
||||||
class nsIDOMInstallVersion;
|
|
||||||
|
|
||||||
#define NS_IDOMINSTALLVERSION_IID \
|
|
||||||
{ 0x18c2f986, 0xb09f, 0x11d2, \
|
|
||||||
{0xbc, 0xde, 0x00, 0x80, 0x5f, 0x0e, 0x13, 0x53}}
|
|
||||||
|
|
||||||
class nsIDOMInstallVersion : public nsISupports {
|
|
||||||
public:
|
|
||||||
static const nsIID& IID() { static nsIID iid = NS_IDOMINSTALLVERSION_IID; return iid; }
|
|
||||||
enum {
|
|
||||||
EQUAL = 0,
|
|
||||||
BLD_DIFF = 1,
|
|
||||||
BLD_DIFF_MINUS = -1,
|
|
||||||
REL_DIFF = 2,
|
|
||||||
REL_DIFF_MINUS = -2,
|
|
||||||
MINOR_DIFF = 3,
|
|
||||||
MINOR_DIFF_MINUS = -3,
|
|
||||||
MAJOR_DIFF = 4,
|
|
||||||
MAJOR_DIFF_MINUS = -4
|
|
||||||
};
|
|
||||||
|
|
||||||
NS_IMETHOD GetMajor(PRInt32* aMajor)=0;
|
|
||||||
NS_IMETHOD SetMajor(PRInt32 aMajor)=0;
|
|
||||||
|
|
||||||
NS_IMETHOD GetMinor(PRInt32* aMinor)=0;
|
|
||||||
NS_IMETHOD SetMinor(PRInt32 aMinor)=0;
|
|
||||||
|
|
||||||
NS_IMETHOD GetRelease(PRInt32* aRelease)=0;
|
|
||||||
NS_IMETHOD SetRelease(PRInt32 aRelease)=0;
|
|
||||||
|
|
||||||
NS_IMETHOD GetBuild(PRInt32* aBuild)=0;
|
|
||||||
NS_IMETHOD SetBuild(PRInt32 aBuild)=0;
|
|
||||||
|
|
||||||
NS_IMETHOD Init(const nsString& aVersionString)=0;
|
|
||||||
|
|
||||||
NS_IMETHOD ToString(nsString& aReturn)=0;
|
|
||||||
|
|
||||||
NS_IMETHOD CompareTo(nsIDOMInstallVersion* aVersionObject, PRInt32* aReturn)=0;
|
|
||||||
NS_IMETHOD CompareTo(const nsString& aString, PRInt32* aReturn)=0;
|
|
||||||
NS_IMETHOD CompareTo(PRInt32 aMajor, PRInt32 aMinor, PRInt32 aRelease, PRInt32 aBuild, PRInt32* aReturn)=0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#define NS_DECL_IDOMINSTALLVERSION \
|
|
||||||
NS_IMETHOD GetMajor(PRInt32* aMajor); \
|
|
||||||
NS_IMETHOD SetMajor(PRInt32 aMajor); \
|
|
||||||
NS_IMETHOD GetMinor(PRInt32* aMinor); \
|
|
||||||
NS_IMETHOD SetMinor(PRInt32 aMinor); \
|
|
||||||
NS_IMETHOD GetRelease(PRInt32* aRelease); \
|
|
||||||
NS_IMETHOD SetRelease(PRInt32 aRelease); \
|
|
||||||
NS_IMETHOD GetBuild(PRInt32* aBuild); \
|
|
||||||
NS_IMETHOD SetBuild(PRInt32 aBuild); \
|
|
||||||
NS_IMETHOD Init(const nsString& aVersionString); \
|
|
||||||
NS_IMETHOD ToString(nsString& aReturn); \
|
|
||||||
NS_IMETHOD CompareTo(nsIDOMInstallVersion* aVersionObject, PRInt32* aReturn); \
|
|
||||||
NS_IMETHOD CompareTo(const nsString& aString, PRInt32* aReturn); \
|
|
||||||
NS_IMETHOD CompareTo(PRInt32 aMajor, PRInt32 aMinor, PRInt32 aRelease, PRInt32 aBuild, PRInt32* aReturn); \
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define NS_FORWARD_IDOMINSTALLVERSION(_to) \
|
|
||||||
NS_IMETHOD GetMajor(PRInt32* aMajor) { return _to##GetMajor(aMajor); } \
|
|
||||||
NS_IMETHOD SetMajor(PRInt32 aMajor) { return _to##SetMajor(aMajor); } \
|
|
||||||
NS_IMETHOD GetMinor(PRInt32* aMinor) { return _to##GetMinor(aMinor); } \
|
|
||||||
NS_IMETHOD SetMinor(PRInt32 aMinor) { return _to##SetMinor(aMinor); } \
|
|
||||||
NS_IMETHOD GetRelease(PRInt32* aRelease) { return _to##GetRelease(aRelease); } \
|
|
||||||
NS_IMETHOD SetRelease(PRInt32 aRelease) { return _to##SetRelease(aRelease); } \
|
|
||||||
NS_IMETHOD GetBuild(PRInt32* aBuild) { return _to##GetBuild(aBuild); } \
|
|
||||||
NS_IMETHOD SetBuild(PRInt32 aBuild) { return _to##SetBuild(aBuild); } \
|
|
||||||
NS_IMETHOD Init(const nsString& aVersionString) { return _to##Init(aVersionString); } \
|
|
||||||
NS_IMETHOD ToString(nsString& aReturn) { return _to##ToString(aReturn); } \
|
|
||||||
NS_IMETHOD CompareTo(nsIDOMInstallVersion* aVersionObject, PRInt32* aReturn) { return _to##CompareTo(aVersionObject, aReturn); } \
|
|
||||||
NS_IMETHOD CompareTo(const nsString& aString, PRInt32* aReturn) { return _to##CompareTo(aString, aReturn); } \
|
|
||||||
NS_IMETHOD CompareTo(PRInt32 aMajor, PRInt32 aMinor, PRInt32 aRelease, PRInt32 aBuild, PRInt32* aReturn) { return _to##CompareTo(aMajor, aMinor, aRelease, aBuild, aReturn); } \
|
|
||||||
|
|
||||||
|
|
||||||
extern nsresult NS_InitInstallVersionClass(nsIScriptContext *aContext, void **aPrototype);
|
|
||||||
|
|
||||||
extern "C" NS_DOM nsresult NS_NewScriptInstallVersion(nsIScriptContext *aContext, nsISupports *aSupports, nsISupports *aParent, void **aReturn);
|
|
||||||
|
|
||||||
#endif // nsIDOMInstallVersion_h__
|
|
||||||
@@ -1,85 +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.0 (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,
|
|
||||||
* released March 31, 1998.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* Daniel Veditz <dveditz@netscape.com>
|
|
||||||
* Douglas Turner <dougt@netscape.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef nsISoftwareUpdate_h__
|
|
||||||
#define nsISoftwareUpdate_h__
|
|
||||||
|
|
||||||
#include "nsISupports.h"
|
|
||||||
#include "nsIFactory.h"
|
|
||||||
#include "nsString.h"
|
|
||||||
|
|
||||||
#include "nsIXPInstallProgress.h"
|
|
||||||
|
|
||||||
#define NS_IXPINSTALLCOMPONENT_PROGID NS_IAPPSHELLCOMPONENT_PROGID "/xpinstall"
|
|
||||||
#define NS_IXPINSTALLCOMPONENT_CLASSNAME "Mozilla XPInstall Component"
|
|
||||||
|
|
||||||
|
|
||||||
#define NS_ISOFTWAREUPDATE_IID \
|
|
||||||
{ 0x18c2f992, \
|
|
||||||
0xb09f, \
|
|
||||||
0x11d2, \
|
|
||||||
{0xbc, 0xde, 0x00, 0x80, 0x5f, 0x0e, 0x13, 0x53}\
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class nsISoftwareUpdate : public nsISupports
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISOFTWAREUPDATE_IID)
|
|
||||||
|
|
||||||
NS_IMETHOD InstallJar(const nsString& fromURL,
|
|
||||||
const nsString& localFile,
|
|
||||||
long flags) = 0;
|
|
||||||
|
|
||||||
NS_IMETHOD RegisterNotifier(nsIXPInstallProgress *notifier) = 0;
|
|
||||||
|
|
||||||
NS_IMETHOD InstallPending(void) = 0;
|
|
||||||
|
|
||||||
/* FIX: these should be in a private interface */
|
|
||||||
NS_IMETHOD InstallJarCallBack() = 0;
|
|
||||||
NS_IMETHOD GetTopLevelNotifier(nsIXPInstallProgress **notifier) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class nsSoftwareUpdateFactory : public nsIFactory
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
nsSoftwareUpdateFactory();
|
|
||||||
virtual ~nsSoftwareUpdateFactory();
|
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS
|
|
||||||
|
|
||||||
NS_IMETHOD CreateInstance(nsISupports *aOuter,
|
|
||||||
REFNSIID aIID,
|
|
||||||
void **aResult);
|
|
||||||
|
|
||||||
NS_IMETHOD LockFactory(PRBool aLock);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif // nsISoftwareUpdate_h__
|
|
||||||
|
|
||||||
@@ -1,30 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "nsISupports.idl"
|
|
||||||
|
|
||||||
[uuid(eea90d40-b059-11d2-915e-c12b696c9333)]
|
|
||||||
interface nsIXPInstallProgress : nsISupports
|
|
||||||
{
|
|
||||||
void BeforeJavascriptEvaluation();
|
|
||||||
void AfterJavascriptEvaluation();
|
|
||||||
void InstallStarted([const] in string UIPackageName);
|
|
||||||
void ItemScheduled([const] in string message );
|
|
||||||
void InstallFinalization([const] in string message, in long itemNum, in long totNum );
|
|
||||||
void InstallAborted();
|
|
||||||
};
|
|
||||||
@@ -1,93 +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.0 (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,
|
|
||||||
* released March 31, 1998.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* Douglas Turner <dougt@netscape.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef nsIXPInstallProgressNotifier_h__
|
|
||||||
#define nsIXPInstallProgressNotifier_h__
|
|
||||||
|
|
||||||
|
|
||||||
class nsIXPInstallProgressNotifier
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Function name : BeforeJavascriptEvaluation
|
|
||||||
// Description : This will be called when prior to the install script being evaluate
|
|
||||||
// Return type : void
|
|
||||||
// Argument : void
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
virtual void BeforeJavascriptEvaluation(void) = 0;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Function name : AfterJavascriptEvaluation
|
|
||||||
// Description : This will be called after the install script has being evaluated
|
|
||||||
// Return type : void
|
|
||||||
// Argument : void
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
virtual void AfterJavascriptEvaluation(void) = 0;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Function name : InstallStarted
|
|
||||||
// Description : This will be called when StartInstall has been called
|
|
||||||
// Return type : void
|
|
||||||
// Argument : char* UIPackageName - User Package Name
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
virtual void InstallStarted(const char* UIPackageName) = 0;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Function name : ItemScheduled
|
|
||||||
// Description : This will be called when items are being scheduled
|
|
||||||
// Return type : Any value returned other than zero, will be treated as an error and the script will be aborted
|
|
||||||
// Argument : The message that should be displayed to the user
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
virtual long ItemScheduled( const char* message ) = 0;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Function name : InstallFinalization
|
|
||||||
// Description : This will be called when the installation is in its Finalize stage
|
|
||||||
// Return type : void
|
|
||||||
// Argument : char* message - The message that should be displayed to the user
|
|
||||||
// Argument : long itemNum - This is the current item number
|
|
||||||
// Argument : long totNum - This is the total number of items
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
virtual void InstallFinalization( const char* message, long itemNum, long totNum ) = 0;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Function name : InstallAborted
|
|
||||||
// Description : This will be called when the install is aborted
|
|
||||||
// Return type : void
|
|
||||||
// Argument : void
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
virtual void InstallAborted(void) = 0;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,64 +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.0 (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,
|
|
||||||
* released March 31, 1998.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* Daniel Veditz <dveditz@netscape.com>
|
|
||||||
* Douglas Turner <dougt@netscape.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef nsSoftwareUpdateIIDs_h___
|
|
||||||
#define nsSoftwareUpdateIIDs_h___
|
|
||||||
|
|
||||||
#define NS_SoftwareUpdate_CID \
|
|
||||||
{ /* 18c2f989-b09f-11d2-bcde-00805f0e1353 */ \
|
|
||||||
0x18c2f989, \
|
|
||||||
0xb09f, \
|
|
||||||
0x11d2, \
|
|
||||||
{0xbc, 0xde, 0x00, 0x80, 0x5f, 0x0e, 0x13, 0x53} \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define NS_SoftwareUpdateInstall_CID \
|
|
||||||
{ /* 18c2f98b-b09f-11d2-bcde-00805f0e1353 */ \
|
|
||||||
0x18c2f98b, \
|
|
||||||
0xb09f, \
|
|
||||||
0x11d2, \
|
|
||||||
{0xbc, 0xde, 0x00, 0x80, 0x5f, 0x0e, 0x13, 0x53} \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define NS_SoftwareUpdateInstallTrigger_CID \
|
|
||||||
{ /* 18c2f98d-b09f-11d2-bcde-00805f0e1353 */ \
|
|
||||||
0x18c2f98d, \
|
|
||||||
0xb09f, \
|
|
||||||
0x11d2, \
|
|
||||||
{0xbc, 0xde, 0x00, 0x80, 0x5f, 0x0e, 0x13, 0x53} \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define NS_SoftwareUpdateInstallVersion_CID \
|
|
||||||
{ /* 18c2f98f-b09f-11d2-bcde-00805f0e1353 */ \
|
|
||||||
0x18c2f98f, \
|
|
||||||
0xb09f, \
|
|
||||||
0x11d2, \
|
|
||||||
{0xbc, 0xde, 0x00, 0x80, 0x5f, 0x0e, 0x13, 0x53} \
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* nsSoftwareUpdateIIDs_h___ */
|
|
||||||
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
progress.xul
|
|
||||||
progress.css
|
|
||||||
progress.html
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
#!gmake
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
DEPTH=../..
|
|
||||||
topsrcdir = @top_srcdir@
|
|
||||||
srcdir = @srcdir@
|
|
||||||
VPATH = @srcdir@
|
|
||||||
|
|
||||||
include $(DEPTH)/config/autoconf.mk
|
|
||||||
include $(topsrcdir)/config/config.mk
|
|
||||||
include $(topsrcdir)/config/rules.mk
|
|
||||||
|
|
||||||
EXPORT_RESOURCE_XPINSTALL = \
|
|
||||||
$(srcdir)/progress.xul \
|
|
||||||
$(srcdir)/progress.html \
|
|
||||||
$(srcdir)/progress.css \
|
|
||||||
$(NULL)
|
|
||||||
|
|
||||||
install::
|
|
||||||
$(INSTALL) $(EXPORT_RESOURCE_XPINSTALL) $(DIST)/bin/res/xpinstall
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
#!nmake
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
DEPTH=..\..
|
|
||||||
IGNORE_MANIFEST=1
|
|
||||||
|
|
||||||
include <$(DEPTH)\config\rules.mak>
|
|
||||||
|
|
||||||
install:: $(DLL)
|
|
||||||
$(MAKE_INSTALL) progress.xul $(DIST)\bin\res\xpinstall
|
|
||||||
$(MAKE_INSTALL) progress.css $(DIST)\bin\res\xpinstall
|
|
||||||
$(MAKE_INSTALL) progress.html $(DIST)\bin\res\xpinstall
|
|
||||||
|
|
||||||
clobber::
|
|
||||||
rm -f $(DIST)\res\xpinstall\progress.xul
|
|
||||||
rm -f $(DIST)\res\xpinstall\progress.css
|
|
||||||
rm -f $(DIST)\res\xpinstall\progress.html
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
TD {
|
|
||||||
font: 10pt sans-serif;
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
|
||||||
<html>
|
|
||||||
<body bgcolor="#C0C0C0" style="overflow:visible; margin: 0px; color-background: rgb(192,192,192);">
|
|
||||||
<center>
|
|
||||||
<table BORDER COLS=5 WIDTH="99%" style="color-background:rgb(192,192,192);">
|
|
||||||
<tr>
|
|
||||||
<td WIDTH="3%" NOWRAP style="border: 1px inset rgb(192,192,192);"> </td>
|
|
||||||
<td WIDTH="3%" NOWRAP style="border: 1px inset rgb(192,192,192);"> </td>
|
|
||||||
<td WIDTH="3%" NOWRAP style="border: 1px inset rgb(192,192,192);"> </td>
|
|
||||||
<td WIDTH="10%" NOWRAP style="border: 1px inset rgb(192,192,192);"> </td>
|
|
||||||
<td WIDTH="81%" NOWRAP style="border: 1px inset rgb(192,192,192);"> </td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</center>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
<?xml-stylesheet href="../samples/xul.css" type="text/css"?>
|
|
||||||
<?xml-stylesheet href="progress.css" type="text/css"?>
|
|
||||||
|
|
||||||
<!DOCTYPE window
|
|
||||||
[
|
|
||||||
<!ENTITY downloadWindow.title "XPInstall Progress">
|
|
||||||
<!ENTITY status "Status:">
|
|
||||||
<!ENTITY cancelButtonTitle "Cancel">
|
|
||||||
]
|
|
||||||
>
|
|
||||||
|
|
||||||
<window xmlns:html="http://www.w3.org/TR/REC-html40"
|
|
||||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
|
||||||
title="XPInstall Progress"
|
|
||||||
width="425"
|
|
||||||
height="225">
|
|
||||||
|
|
||||||
<data>
|
|
||||||
<broadcaster id="data.canceled" type="string" value="false"/>
|
|
||||||
</data>
|
|
||||||
|
|
||||||
|
|
||||||
<html:script>
|
|
||||||
|
|
||||||
function cancelInstall()
|
|
||||||
{
|
|
||||||
var cancelData = document.getElementById("data.canceled");
|
|
||||||
cancelData.setAttribute( "value", "true");
|
|
||||||
}
|
|
||||||
|
|
||||||
</html:script>
|
|
||||||
|
|
||||||
<html:center>
|
|
||||||
<html:table style="width:100%;">
|
|
||||||
|
|
||||||
<html:tr>
|
|
||||||
<html:td align="center">
|
|
||||||
<html:input id="dialog.uiPackageName" readonly="" style="background-color:lightgray;width:300px;"/>
|
|
||||||
</html:td>
|
|
||||||
</html:tr>
|
|
||||||
|
|
||||||
<html:tr>
|
|
||||||
<html:td nowrap="" style="border: 1px rgb(192,192,192);" align="center">
|
|
||||||
<html:input id="dialog.currentAction" readonly="" style="background-color:lightgray;width:450px;"/>
|
|
||||||
</html:td>
|
|
||||||
</html:tr>
|
|
||||||
|
|
||||||
|
|
||||||
<html:tr>
|
|
||||||
<html:td align="center" width="15%" nowrap="" style="border: 1px rgb(192,192,192);">
|
|
||||||
<progressmeter id="dialog.progress" mode="undetermined" style="width:300px;height:16px;">
|
|
||||||
</progressmeter>
|
|
||||||
</html:td>
|
|
||||||
</html:tr>
|
|
||||||
|
|
||||||
<html:tr>
|
|
||||||
<html:td align="center" width="3%" nowrap="" style="border: 1px rgb(192,192,192);">
|
|
||||||
<html:button onclick="cancelInstall()" height="12">
|
|
||||||
&cancelButtonTitle;
|
|
||||||
</html:button>
|
|
||||||
</html:td>
|
|
||||||
</html:tr>
|
|
||||||
</html:table>
|
|
||||||
|
|
||||||
</html:center>
|
|
||||||
</window>
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
#!gmake
|
|
||||||
#
|
|
||||||
# The contents of this file are subject to the Netscape Public License
|
|
||||||
# Version 1.0 (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,
|
|
||||||
# released March 31, 1998.
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
# Contributors:
|
|
||||||
# Daniel Veditz <dveditz@netscape.com>
|
|
||||||
# Douglas Turner <dougt@netscape.com>
|
|
||||||
|
|
||||||
DEPTH = ../..
|
|
||||||
topsrcdir = @top_srcdir@
|
|
||||||
VPATH = @srcdir@
|
|
||||||
srcdir = @srcdir@
|
|
||||||
|
|
||||||
include $(DEPTH)/config/autoconf.mk
|
|
||||||
|
|
||||||
MODULE = xpinstall
|
|
||||||
LIBRARY_NAME = xpinstall
|
|
||||||
IS_COMPONENT = 1
|
|
||||||
REQUIRES = dom js netlib raptor xpcom
|
|
||||||
|
|
||||||
CPPSRCS = \
|
|
||||||
nsSoftwareUpdate.cpp \
|
|
||||||
nsInstall.cpp \
|
|
||||||
nsInstallDelete.cpp \
|
|
||||||
nsInstallExecute.cpp \
|
|
||||||
nsInstallFile.cpp \
|
|
||||||
nsInstallFolder.cpp \
|
|
||||||
nsInstallPatch.cpp \
|
|
||||||
nsInstallUninstall.cpp \
|
|
||||||
nsInstallTrigger.cpp \
|
|
||||||
nsInstallResources.cpp \
|
|
||||||
nsJSInstall.cpp \
|
|
||||||
nsJSInstallTriggerGlobal.cpp\
|
|
||||||
nsSoftwareUpdateRun.cpp \
|
|
||||||
nsSoftwareUpdateStream.cpp \
|
|
||||||
nsTopProgressNotifier.cpp \
|
|
||||||
nsLoggingProgressNotifier \
|
|
||||||
ScheduledTasks.cpp \
|
|
||||||
nsInstallFileOpItem.cpp \
|
|
||||||
$(NULL)
|
|
||||||
|
|
||||||
INCLUDES += -I$(srcdir)/../public
|
|
||||||
|
|
||||||
include $(topsrcdir)/config/rules.mk
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,233 +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.0 (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,
|
|
||||||
|
|
||||||
* released March 31, 1998.
|
|
||||||
|
|
||||||
*
|
|
||||||
|
|
||||||
* 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.
|
|
||||||
|
|
||||||
*
|
|
||||||
|
|
||||||
* Contributors:
|
|
||||||
|
|
||||||
* Douglas Turner <dougt@netscape.com>
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef SU_PAS_H
|
|
||||||
|
|
||||||
#define SU_PAS_H
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <Errors.h>
|
|
||||||
|
|
||||||
#include <Types.h>
|
|
||||||
|
|
||||||
#include <Files.h>
|
|
||||||
|
|
||||||
#include <Script.h>
|
|
||||||
|
|
||||||
#include <Resources.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct PASHeader /* header portion of Patchable AppleSingle */
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
UInt32 magicNum; /* internal file type tag = 0x00244200*/
|
|
||||||
|
|
||||||
UInt32 versionNum; /* format version: 1 = 0x00010000 */
|
|
||||||
|
|
||||||
UInt8 filler[16]; /* filler */
|
|
||||||
|
|
||||||
UInt16 numEntries; /* number of entries which follow */
|
|
||||||
|
|
||||||
} PASHeader ;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct PASEntry /* one Patchable AppleSingle entry descriptor */
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
UInt32 entryID; /* entry type: see list, 0 invalid */
|
|
||||||
|
|
||||||
UInt32 entryOffset; /* offset, in bytes, from beginning */
|
|
||||||
|
|
||||||
/* of file to this entry's data */
|
|
||||||
|
|
||||||
UInt32 entryLength; /* length of data in octets */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} PASEntry;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct PASMiscInfo
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
short fileHasResFork;
|
|
||||||
|
|
||||||
short fileResAttrs;
|
|
||||||
|
|
||||||
OSType fileType;
|
|
||||||
|
|
||||||
OSType fileCreator;
|
|
||||||
|
|
||||||
UInt32 fileFlags;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} PASMiscInfo;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct PASResFork
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
short NumberOfTypes;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} PASResFork;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct PASResource
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
short attr;
|
|
||||||
|
|
||||||
short attrID;
|
|
||||||
|
|
||||||
OSType attrType;
|
|
||||||
|
|
||||||
Str255 attrName;
|
|
||||||
|
|
||||||
unsigned long length;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} PASResource;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if PRAGMA_ALIGN_SUPPORTED
|
|
||||||
|
|
||||||
#pragma options align=reset
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define kCreator 'MOSS'
|
|
||||||
|
|
||||||
#define kType 'PASf'
|
|
||||||
|
|
||||||
#define PAS_BUFFER_SIZE (1024*512)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define PAS_MAGIC_NUM (0x00244200)
|
|
||||||
|
|
||||||
#define PAS_VERSION (0x00010000)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
enum
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
ePas_Data = 1,
|
|
||||||
|
|
||||||
ePas_Misc,
|
|
||||||
|
|
||||||
ePas_Resource
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Prototypes */
|
|
||||||
|
|
||||||
OSErr PAS_EncodeFile(FSSpec *inSpec, FSSpec *outSpec);
|
|
||||||
|
|
||||||
OSErr PAS_DecodeFile(FSSpec *inSpec, FSSpec *outSpec);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* SU_PAS_H */
|
|
||||||
@@ -1,380 +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.0 (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,
|
|
||||||
* released March 31, 1998.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* Daniel Veditz <dveditz@netscape.com>
|
|
||||||
* Douglas Turner <dougt@netscape.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "nscore.h"
|
|
||||||
#include "NSReg.h"
|
|
||||||
#include "nsFileSpec.h"
|
|
||||||
#include "nsFileStream.h"
|
|
||||||
#include "nsInstall.h" // for error codes
|
|
||||||
#include "prmem.h"
|
|
||||||
#include "ScheduledTasks.h"
|
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
BOOL WIN32_IsMoveFileExBroken()
|
|
||||||
{
|
|
||||||
/* the NT option MOVEFILE_DELAY_UNTIL_REBOOT is broken on
|
|
||||||
* Windows NT 3.51 Service Pack 4 and NT 4.0 before Service Pack 2
|
|
||||||
*/
|
|
||||||
BOOL broken = FALSE;
|
|
||||||
OSVERSIONINFO osinfo;
|
|
||||||
|
|
||||||
// they *all* appear broken--better to have one way that works.
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
osinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
|
||||||
if (GetVersionEx(&osinfo) && osinfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
|
|
||||||
{
|
|
||||||
if ( osinfo.dwMajorVersion == 3 && osinfo.dwMinorVersion == 51 )
|
|
||||||
{
|
|
||||||
if ( 0 == stricmp(osinfo.szCSDVersion,"Service Pack 4"))
|
|
||||||
{
|
|
||||||
broken = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ( osinfo.dwMajorVersion == 4 )
|
|
||||||
{
|
|
||||||
if (osinfo.szCSDVersion[0] == '\0' ||
|
|
||||||
(0 == stricmp(osinfo.szCSDVersion,"Service Pack 1")))
|
|
||||||
{
|
|
||||||
broken = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return broken;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PRInt32 DoWindowsReplaceExistingFileStuff(const char* currentName, const char* finalName)
|
|
||||||
{
|
|
||||||
PRInt32 err = 0;
|
|
||||||
|
|
||||||
char* final = strdup(finalName);
|
|
||||||
char* current = strdup(currentName);
|
|
||||||
|
|
||||||
/* couldn't delete, probably in use. Schedule for later */
|
|
||||||
DWORD dwVersion, dwWindowsMajorVersion;
|
|
||||||
|
|
||||||
/* Get OS version info */
|
|
||||||
dwVersion = GetVersion();
|
|
||||||
dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
|
|
||||||
|
|
||||||
/* Get build numbers for Windows NT or Win32s */
|
|
||||||
|
|
||||||
if (dwVersion < 0x80000000) // Windows NT
|
|
||||||
{
|
|
||||||
/* On Windows NT */
|
|
||||||
if ( WIN32_IsMoveFileExBroken() )
|
|
||||||
{
|
|
||||||
/* the MOVEFILE_DELAY_UNTIL_REBOOT option doesn't work on
|
|
||||||
* NT 3.51 SP4 or on NT 4.0 until SP2
|
|
||||||
*/
|
|
||||||
struct stat statbuf;
|
|
||||||
PRBool nameFound = PR_FALSE;
|
|
||||||
char tmpname[_MAX_PATH];
|
|
||||||
|
|
||||||
strncpy( tmpname, finalName, _MAX_PATH );
|
|
||||||
int len = strlen(tmpname);
|
|
||||||
while (!nameFound && len < _MAX_PATH )
|
|
||||||
{
|
|
||||||
tmpname[len-1] = '~';
|
|
||||||
tmpname[len] = '\0';
|
|
||||||
if ( stat(tmpname, &statbuf) != 0 )
|
|
||||||
nameFound = TRUE;
|
|
||||||
else
|
|
||||||
len++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( nameFound )
|
|
||||||
{
|
|
||||||
if ( MoveFile( finalName, tmpname ) )
|
|
||||||
{
|
|
||||||
if ( MoveFile( currentName, finalName ) )
|
|
||||||
{
|
|
||||||
DeleteFileNowOrSchedule(nsFileSpec(tmpname));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* 2nd move failed, put old file back */
|
|
||||||
MoveFile( tmpname, finalName );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* non-executable in use; schedule for later */
|
|
||||||
return -1; // let the start registry stuff do our work!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ( MoveFileEx(currentName, finalName, MOVEFILE_DELAY_UNTIL_REBOOT) )
|
|
||||||
{
|
|
||||||
err = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // Windows 95 or Win16
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Place an entry in the WININIT.INI file in the Windows directory
|
|
||||||
* to delete finalName and rename currentName to be finalName at reboot
|
|
||||||
*/
|
|
||||||
|
|
||||||
int strlen;
|
|
||||||
char Src[_MAX_PATH]; // 8.3 name
|
|
||||||
char Dest[_MAX_PATH]; // 8.3 name
|
|
||||||
|
|
||||||
strlen = GetShortPathName( (LPCTSTR)currentName, (LPTSTR)Src, (DWORD)sizeof(Src) );
|
|
||||||
if ( strlen > 0 )
|
|
||||||
{
|
|
||||||
free(current);
|
|
||||||
current = strdup(Src);
|
|
||||||
}
|
|
||||||
|
|
||||||
strlen = GetShortPathName( (LPCTSTR) finalName, (LPTSTR) Dest, (DWORD) sizeof(Dest));
|
|
||||||
if ( strlen > 0 )
|
|
||||||
{
|
|
||||||
free(final);
|
|
||||||
final = strdup(Dest);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* NOTE: use OEM filenames! Even though it looks like a Windows
|
|
||||||
* .INI file, WININIT.INI is processed under DOS
|
|
||||||
*/
|
|
||||||
|
|
||||||
AnsiToOem( final, final );
|
|
||||||
AnsiToOem( current, current );
|
|
||||||
|
|
||||||
if ( WritePrivateProfileString( "Rename", final, current, "WININIT.INI" ) )
|
|
||||||
err = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(final);
|
|
||||||
free(current);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
REGERR DeleteFileNowOrSchedule(nsFileSpec& filename)
|
|
||||||
{
|
|
||||||
|
|
||||||
REGERR result = 0;
|
|
||||||
|
|
||||||
filename.Delete(false);
|
|
||||||
|
|
||||||
if (filename.Exists())
|
|
||||||
{
|
|
||||||
RKEY newkey;
|
|
||||||
HREG reg;
|
|
||||||
if ( REGERR_OK == NR_RegOpen("", ®) )
|
|
||||||
{
|
|
||||||
if (REGERR_OK == NR_RegAddKey( reg, ROOTKEY_PRIVATE, REG_DELETE_LIST_KEY, &newkey) )
|
|
||||||
{
|
|
||||||
// FIX should be using nsPersistentFileDescriptor!!!
|
|
||||||
|
|
||||||
result = NR_RegSetEntry( reg, newkey, (char*)(const char*)filename.GetNativePathCString(), REGTYPE_ENTRY_FILE, nsnull, 0);
|
|
||||||
if (result == REGERR_OK)
|
|
||||||
result = nsInstall::REBOOT_NEEDED;
|
|
||||||
}
|
|
||||||
|
|
||||||
NR_RegClose(reg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
/* tmp file is the bad one that we want to replace with target. */
|
|
||||||
|
|
||||||
REGERR ReplaceFileNowOrSchedule(nsFileSpec& replacementFile, nsFileSpec& doomedFile )
|
|
||||||
{
|
|
||||||
REGERR result = 0;
|
|
||||||
|
|
||||||
if(replacementFile == doomedFile)
|
|
||||||
{
|
|
||||||
/* do not have to do anything */
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
doomedFile.Delete(false);
|
|
||||||
|
|
||||||
if (! doomedFile.Exists() )
|
|
||||||
{
|
|
||||||
// Now that we have move the existing file, we can move the mExtracedFile into place.
|
|
||||||
nsFileSpec parentofFinalFile;
|
|
||||||
|
|
||||||
doomedFile.GetParent(parentofFinalFile);
|
|
||||||
result = replacementFile.Move(parentofFinalFile);
|
|
||||||
if ( NS_SUCCEEDED(result) )
|
|
||||||
{
|
|
||||||
char* leafName = doomedFile.GetLeafName();
|
|
||||||
replacementFile.Rename(leafName);
|
|
||||||
nsCRT::free(leafName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
if (DoWindowsReplaceExistingFileStuff(replacementFile.GetNativePathCString(), doomedFile.GetNativePathCString()) == 0)
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RKEY newkey;
|
|
||||||
HREG reg;
|
|
||||||
|
|
||||||
if ( REGERR_OK == NR_RegOpen("", ®) )
|
|
||||||
{
|
|
||||||
result = NR_RegAddKey( reg, ROOTKEY_PRIVATE, REG_REPLACE_LIST_KEY, &newkey);
|
|
||||||
if ( result == REGERR_OK )
|
|
||||||
{
|
|
||||||
char* replacementFileName = (char*)(const char*)replacementFile.GetNativePathCString();
|
|
||||||
result = NR_RegSetEntry( reg, newkey, (char*)(const char*)doomedFile.GetNativePathCString(), REGTYPE_ENTRY_FILE, replacementFileName, strlen(replacementFileName));
|
|
||||||
if (result == REGERR_OK)
|
|
||||||
result = nsInstall::REBOOT_NEEDED;
|
|
||||||
}
|
|
||||||
|
|
||||||
NR_RegClose(reg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DeleteScheduledFiles(void);
|
|
||||||
void ReplaceScheduledFiles(void);
|
|
||||||
|
|
||||||
extern "C" void PerformScheduledTasks(void *data)
|
|
||||||
{
|
|
||||||
DeleteScheduledFiles();
|
|
||||||
ReplaceScheduledFiles();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DeleteScheduledFiles(void)
|
|
||||||
{
|
|
||||||
HREG reg;
|
|
||||||
|
|
||||||
if (REGERR_OK == NR_RegOpen("", ®))
|
|
||||||
{
|
|
||||||
RKEY key;
|
|
||||||
REGENUM state;
|
|
||||||
|
|
||||||
/* perform scheduled file deletions and replacements (PC only) */
|
|
||||||
if (REGERR_OK == NR_RegGetKey(reg, ROOTKEY_PRIVATE, REG_DELETE_LIST_KEY,&key))
|
|
||||||
{
|
|
||||||
char buf[MAXREGNAMELEN];
|
|
||||||
|
|
||||||
while (REGERR_OK == NR_RegEnumEntries(reg, key, &state, buf, sizeof(buf), NULL ))
|
|
||||||
{
|
|
||||||
nsFileSpec doomedFile(buf);
|
|
||||||
|
|
||||||
doomedFile.Delete(PR_FALSE);
|
|
||||||
|
|
||||||
if (! doomedFile.Exists())
|
|
||||||
{
|
|
||||||
NR_RegDeleteEntry( reg, key, buf );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* delete list node if empty */
|
|
||||||
if (REGERR_NOMORE == NR_RegEnumEntries( reg, key, &state, buf, sizeof(buf), NULL ))
|
|
||||||
{
|
|
||||||
NR_RegDeleteKey(reg, ROOTKEY_PRIVATE, REG_DELETE_LIST_KEY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NR_RegClose(reg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReplaceScheduledFiles(void)
|
|
||||||
{
|
|
||||||
HREG reg;
|
|
||||||
|
|
||||||
if (REGERR_OK == NR_RegOpen("", ®))
|
|
||||||
{
|
|
||||||
RKEY key;
|
|
||||||
REGENUM state;
|
|
||||||
|
|
||||||
/* replace files if any listed */
|
|
||||||
if (REGERR_OK == NR_RegGetKey(reg, ROOTKEY_PRIVATE, REG_REPLACE_LIST_KEY, &key))
|
|
||||||
{
|
|
||||||
char tmpfile[MAXREGNAMELEN];
|
|
||||||
char target[MAXREGNAMELEN];
|
|
||||||
|
|
||||||
state = 0;
|
|
||||||
while (REGERR_OK == NR_RegEnumEntries(reg, key, &state, tmpfile, sizeof(tmpfile), NULL ))
|
|
||||||
{
|
|
||||||
|
|
||||||
nsFileSpec replaceFile(tmpfile);
|
|
||||||
|
|
||||||
if (! replaceFile.Exists() )
|
|
||||||
{
|
|
||||||
NR_RegDeleteEntry( reg, key, tmpfile );
|
|
||||||
}
|
|
||||||
else if ( REGERR_OK != NR_RegGetEntryString( reg, key, tmpfile, target, sizeof(target) ) )
|
|
||||||
{
|
|
||||||
/* can't read target filename, corruption? */
|
|
||||||
NR_RegDeleteEntry( reg, key, tmpfile );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nsFileSpec targetFile(target);
|
|
||||||
|
|
||||||
targetFile.Delete(PR_FALSE);
|
|
||||||
|
|
||||||
if (!targetFile.Exists())
|
|
||||||
{
|
|
||||||
nsFileSpec parentofTarget;
|
|
||||||
targetFile.GetParent(parentofTarget);
|
|
||||||
|
|
||||||
nsresult result = replaceFile.Move(parentofTarget);
|
|
||||||
if ( NS_SUCCEEDED(result) )
|
|
||||||
{
|
|
||||||
char* leafName = targetFile.GetLeafName();
|
|
||||||
replaceFile.Rename(leafName);
|
|
||||||
nsCRT::free(leafName);
|
|
||||||
|
|
||||||
NR_RegDeleteEntry( reg, key, tmpfile );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* delete list node if empty */
|
|
||||||
if (REGERR_NOMORE == NR_RegEnumEntries(reg, key, &state, tmpfile, sizeof(tmpfile), NULL ))
|
|
||||||
{
|
|
||||||
NR_RegDeleteKey(reg, ROOTKEY_PRIVATE, REG_REPLACE_LIST_KEY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NR_RegClose(reg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,42 +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.0 (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,
|
|
||||||
* released March 31, 1998.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* Daniel Veditz <dveditz@netscape.com>
|
|
||||||
* Douglas Turner <dougt@netscape.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef __SCHEDULEDTASKS_H__
|
|
||||||
#define __SCHEDULEDTASKS_H__
|
|
||||||
|
|
||||||
|
|
||||||
#include "NSReg.h"
|
|
||||||
#include "nsFileSpec.h"
|
|
||||||
|
|
||||||
|
|
||||||
REGERR DeleteFileNowOrSchedule(nsFileSpec& filename);
|
|
||||||
REGERR ReplaceFileNowOrSchedule(nsFileSpec& tmpfile, nsFileSpec& target );
|
|
||||||
|
|
||||||
|
|
||||||
extern "C" void PerformScheduledTasks(void *data);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,135 +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.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.
|
|
||||||
*/
|
|
||||||
/*--------------------------------------------------------------
|
|
||||||
* GDIFF.H
|
|
||||||
*
|
|
||||||
* Constants used in processing the GDIFF format
|
|
||||||
*--------------------------------------------------------------*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "prio.h"
|
|
||||||
#include "nsFileSpec.h"
|
|
||||||
|
|
||||||
#define GDIFF_MAGIC "\xD1\xFF\xD1\xFF"
|
|
||||||
#define GDIFF_MAGIC_LEN 4
|
|
||||||
#define GDIFF_VER 5
|
|
||||||
#define GDIFF_EOF "\0"
|
|
||||||
|
|
||||||
#define GDIFF_VER_POS 4
|
|
||||||
#define GDIFF_CS_POS 5
|
|
||||||
#define GDIFF_CSLEN_POS 6
|
|
||||||
|
|
||||||
#define GDIFF_HEADERSIZE 7
|
|
||||||
#define GDIFF_APPDATALEN 4
|
|
||||||
|
|
||||||
#define GDIFF_CS_NONE 0
|
|
||||||
#define GDIFF_CS_MD5 1
|
|
||||||
#define GDIFF_CS_SHA 2
|
|
||||||
#define GDIFF_CS_CRC32 32
|
|
||||||
|
|
||||||
#define CRC32_LEN 4
|
|
||||||
|
|
||||||
/*--------------------------------------
|
|
||||||
* GDIFF opcodes
|
|
||||||
*------------------------------------*/
|
|
||||||
#define ENDDIFF 0
|
|
||||||
#define ADD8MAX 246
|
|
||||||
#define ADD16 247
|
|
||||||
#define ADD32 248
|
|
||||||
#define COPY16BYTE 249
|
|
||||||
#define COPY16SHORT 250
|
|
||||||
#define COPY16LONG 251
|
|
||||||
#define COPY32BYTE 252
|
|
||||||
#define COPY32SHORT 253
|
|
||||||
#define COPY32LONG 254
|
|
||||||
#define COPY64 255
|
|
||||||
|
|
||||||
/* instruction sizes */
|
|
||||||
#define ADD16SIZE 2
|
|
||||||
#define ADD32SIZE 4
|
|
||||||
#define COPY16BYTESIZE 3
|
|
||||||
#define COPY16SHORTSIZE 4
|
|
||||||
#define COPY16LONGSIZE 6
|
|
||||||
#define COPY32BYTESIZE 5
|
|
||||||
#define COPY32SHORTSIZE 6
|
|
||||||
#define COPY32LONGSIZE 8
|
|
||||||
#define COPY64SIZE 12
|
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------------
|
|
||||||
* error codes
|
|
||||||
*------------------------------------*/
|
|
||||||
#define GDIFF_OK 0
|
|
||||||
#define GDIFF_ERR_UNKNOWN -1
|
|
||||||
#define GDIFF_ERR_ARGS -2
|
|
||||||
#define GDIFF_ERR_ACCESS -3
|
|
||||||
#define GDIFF_ERR_MEM -4
|
|
||||||
#define GDIFF_ERR_HEADER -5
|
|
||||||
#define GDIFF_ERR_BADDIFF -6
|
|
||||||
#define GDIFF_ERR_OPCODE -7
|
|
||||||
#define GDIFF_ERR_OLDFILE -8
|
|
||||||
#define GDIFF_ERR_CHKSUMTYPE -9
|
|
||||||
#define GDIFF_ERR_CHECKSUM -10
|
|
||||||
#define GDIFF_ERR_CHECKSUM_TARGET -11
|
|
||||||
#define GDIFF_ERR_CHECKSUM_RESULT -12
|
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------------
|
|
||||||
* types
|
|
||||||
*------------------------------------*/
|
|
||||||
#ifndef AIX
|
|
||||||
#ifdef OSF1
|
|
||||||
#include <sys/types.h>
|
|
||||||
#else
|
|
||||||
typedef unsigned char uchar;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct _diffdata {
|
|
||||||
PRFileDesc* fSrc;
|
|
||||||
PRFileDesc* fOut;
|
|
||||||
PRFileDesc* fDiff;
|
|
||||||
uint8 checksumType;
|
|
||||||
uint8 checksumLength;
|
|
||||||
uchar* oldChecksum;
|
|
||||||
uchar* newChecksum;
|
|
||||||
PRBool bMacAppleSingle;
|
|
||||||
PRBool bWin32BoundImage;
|
|
||||||
uchar* databuf;
|
|
||||||
uint32 bufsize;
|
|
||||||
} DIFFDATA;
|
|
||||||
|
|
||||||
typedef DIFFDATA* pDIFFDATA;
|
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------------
|
|
||||||
* miscellaneous
|
|
||||||
*------------------------------------*/
|
|
||||||
|
|
||||||
#define APPFLAG_W32BOUND "autoinstall:Win32PE"
|
|
||||||
#define APPFLAG_APPLESINGLE "autoinstall:AppleSingle"
|
|
||||||
|
|
||||||
#ifndef TRUE
|
|
||||||
#define TRUE 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef FALSE
|
|
||||||
#define FALSE 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
#!nmake
|
|
||||||
#
|
|
||||||
# The contents of this file are subject to the Netscape Public License
|
|
||||||
# Version 1.0 (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,
|
|
||||||
# released March 31, 1998.
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
# Contributors:
|
|
||||||
# Daniel Veditz <dveditz@netscape.com>
|
|
||||||
# Douglas Turner <dougt@netscape.com>
|
|
||||||
|
|
||||||
|
|
||||||
DEPTH=..\..
|
|
||||||
IGNORE_MANIFEST=1
|
|
||||||
|
|
||||||
MAKE_OBJ_TYPE = DLL
|
|
||||||
MODULE=xpinstall
|
|
||||||
|
|
||||||
DLL=.\$(OBJDIR)\$(MODULE).dll
|
|
||||||
|
|
||||||
DEFINES=-D_IMPL_NS_DOM -DWIN32_LEAN_AND_MEAN
|
|
||||||
|
|
||||||
LCFLAGS = \
|
|
||||||
$(LCFLAGS) \
|
|
||||||
$(DEFINES) \
|
|
||||||
$(NULL)
|
|
||||||
|
|
||||||
LINCS= \
|
|
||||||
-I$(PUBLIC)\xpinstall \
|
|
||||||
-I$(PUBLIC)\jar \
|
|
||||||
-I$(PUBLIC)\libreg \
|
|
||||||
-I$(PUBLIC)\netlib \
|
|
||||||
-I$(PUBLIC)\xpcom \
|
|
||||||
-I$(PUBLIC)\pref \
|
|
||||||
-I$(PUBLIC)\rdf \
|
|
||||||
-I$(PUBLIC)\js \
|
|
||||||
-I$(PUBLIC)\dom \
|
|
||||||
-I$(PUBLIC)\raptor \
|
|
||||||
-I$(PUBLIC)\nspr2 \
|
|
||||||
-I$(PUBLIC)\zlib \
|
|
||||||
-I$(PUBLIC)\xpfe\components \
|
|
||||||
$(NULL)
|
|
||||||
|
|
||||||
LLIBS = \
|
|
||||||
$(DIST)\lib\jar50.lib \
|
|
||||||
$(DIST)\lib\libreg32.lib \
|
|
||||||
$(DIST)\lib\netlib.lib \
|
|
||||||
$(DIST)\lib\xpcom.lib \
|
|
||||||
$(DIST)\lib\js3250.lib \
|
|
||||||
$(DIST)\lib\jsdombase_s.lib \
|
|
||||||
$(DIST)\lib\jsdomevents_s.lib \
|
|
||||||
$(DIST)\lib\zlib.lib \
|
|
||||||
$(DIST)\lib\plc3.lib \
|
|
||||||
$(LIBNSPR) \
|
|
||||||
$(NULL)
|
|
||||||
|
|
||||||
|
|
||||||
OBJS = \
|
|
||||||
.\$(OBJDIR)\nsInstall.obj \
|
|
||||||
.\$(OBJDIR)\nsInstallTrigger.obj \
|
|
||||||
.\$(OBJDIR)\nsInstallVersion.obj \
|
|
||||||
.\$(OBJDIR)\nsInstallFolder.obj \
|
|
||||||
.\$(OBJDIR)\nsJSInstall.obj \
|
|
||||||
.\$(OBJDIR)\nsJSInstallTriggerGlobal.obj \
|
|
||||||
.\$(OBJDIR)\nsJSInstallVersion.obj \
|
|
||||||
.\$(OBJDIR)\nsSoftwareUpdate.obj \
|
|
||||||
.\$(OBJDIR)\nsSoftwareUpdateRun.obj \
|
|
||||||
.\$(OBJDIR)\nsSoftwareUpdateStream.obj \
|
|
||||||
.\$(OBJDIR)\nsInstallFile.obj \
|
|
||||||
.\$(OBJDIR)\nsInstallDelete.obj \
|
|
||||||
.\$(OBJDIR)\nsInstallExecute.obj \
|
|
||||||
.\$(OBJDIR)\nsInstallPatch.obj \
|
|
||||||
.\$(OBJDIR)\nsInstallUninstall.obj \
|
|
||||||
.\$(OBJDIR)\nsInstallResources.obj \
|
|
||||||
.\$(OBJDIR)\nsTopProgressNotifier.obj \
|
|
||||||
.\$(OBJDIR)\nsLoggingProgressNotifier.obj\
|
|
||||||
.\$(OBJDIR)\ScheduledTasks.obj \
|
|
||||||
.\$(OBJDIR)\nsWinReg.obj \
|
|
||||||
.\$(OBJDIR)\nsJSWinReg.obj \
|
|
||||||
.\$(OBJDIR)\nsWinRegItem.obj \
|
|
||||||
.\$(OBJDIR)\nsWinRegValue.obj \
|
|
||||||
.\$(OBJDIR)\nsWinProfile.obj \
|
|
||||||
.\$(OBJDIR)\nsJSWinProfile.obj \
|
|
||||||
.\$(OBJDIR)\nsWinProfileItem.obj \
|
|
||||||
.\$(OBJDIR)\nsInstallProgressDialog.obj \
|
|
||||||
.\$(OBJDIR)\nsInstallFileOpItem.obj \
|
|
||||||
$(NULL)
|
|
||||||
|
|
||||||
include <$(DEPTH)\config\rules.mak>
|
|
||||||
|
|
||||||
install:: $(DLL)
|
|
||||||
$(MAKE_INSTALL) .\$(OBJDIR)\$(MODULE).lib $(DIST)\lib
|
|
||||||
$(MAKE_INSTALL) .\$(OBJDIR)\$(MODULE).dll $(DIST)\bin\components
|
|
||||||
|
|
||||||
clobber::
|
|
||||||
rm -f $(DIST)\lib\$(MODULE).lib
|
|
||||||
rm -f $(DIST)\bin\components\$(MODULE).dll
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,265 +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.0 (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,
|
|
||||||
* released March 31, 1998.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* Daniel Veditz <dveditz@netscape.com>
|
|
||||||
* Douglas Turner <dougt@netscape.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef __NS_INSTALL_H__
|
|
||||||
#define __NS_INSTALL_H__
|
|
||||||
|
|
||||||
#include "nscore.h"
|
|
||||||
#include "nsISupports.h"
|
|
||||||
|
|
||||||
#include "jsapi.h"
|
|
||||||
|
|
||||||
#include "plevent.h"
|
|
||||||
|
|
||||||
#include "nsString.h"
|
|
||||||
#include "nsFileSpec.h"
|
|
||||||
#include "nsVector.h"
|
|
||||||
#include "nsHashtable.h"
|
|
||||||
|
|
||||||
#include "nsSoftwareUpdate.h"
|
|
||||||
|
|
||||||
#include "nsInstallObject.h"
|
|
||||||
#include "nsInstallVersion.h"
|
|
||||||
|
|
||||||
#include "nsIXPInstallProgress.h"
|
|
||||||
|
|
||||||
|
|
||||||
class nsInstallInfo
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
nsInstallInfo(const nsString& fromURL, const nsString& localFile, long flags);
|
|
||||||
|
|
||||||
nsInstallInfo(nsVector* fromURL, nsVector* localFiles, long flags);
|
|
||||||
|
|
||||||
virtual ~nsInstallInfo();
|
|
||||||
|
|
||||||
nsString& GetFromURL(PRUint32 index = 0);
|
|
||||||
|
|
||||||
nsString& GetLocalFile(PRUint32 index = 0);
|
|
||||||
|
|
||||||
void GetArguments(nsString& args, PRUint32 index = 0);
|
|
||||||
|
|
||||||
long GetFlags();
|
|
||||||
|
|
||||||
PRBool IsMultipleTrigger();
|
|
||||||
|
|
||||||
static void DeleteVector(nsVector* vector);
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
|
|
||||||
PRBool mMultipleTrigger;
|
|
||||||
nsresult mError;
|
|
||||||
|
|
||||||
long mFlags;
|
|
||||||
nsVector *mFromURLs;
|
|
||||||
nsVector *mLocalFiles;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class nsInstall
|
|
||||||
{
|
|
||||||
friend class nsWinReg;
|
|
||||||
friend class nsWinProfile;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
BAD_PACKAGE_NAME = -200,
|
|
||||||
UNEXPECTED_ERROR = -201,
|
|
||||||
ACCESS_DENIED = -202,
|
|
||||||
TOO_MANY_CERTIFICATES = -203,
|
|
||||||
NO_INSTALLER_CERTIFICATE = -204,
|
|
||||||
NO_CERTIFICATE = -205,
|
|
||||||
NO_MATCHING_CERTIFICATE = -206,
|
|
||||||
UNKNOWN_JAR_FILE = -207,
|
|
||||||
INVALID_ARGUMENTS = -208,
|
|
||||||
ILLEGAL_RELATIVE_PATH = -209,
|
|
||||||
USER_CANCELLED = -210,
|
|
||||||
INSTALL_NOT_STARTED = -211,
|
|
||||||
SILENT_MODE_DENIED = -212,
|
|
||||||
NO_SUCH_COMPONENT = -213,
|
|
||||||
FILE_DOES_NOT_EXIST = -214,
|
|
||||||
FILE_READ_ONLY = -215,
|
|
||||||
FILE_IS_DIRECTORY = -216,
|
|
||||||
NETWORK_FILE_IS_IN_USE = -217,
|
|
||||||
APPLE_SINGLE_ERR = -218,
|
|
||||||
INVALID_PATH_ERR = -219,
|
|
||||||
PATCH_BAD_DIFF = -220,
|
|
||||||
PATCH_BAD_CHECKSUM_TARGET = -221,
|
|
||||||
PATCH_BAD_CHECKSUM_RESULT = -222,
|
|
||||||
UNINSTALL_FAILED = -223,
|
|
||||||
GESTALT_UNKNOWN_ERR = -5550,
|
|
||||||
GESTALT_INVALID_ARGUMENT = -5551,
|
|
||||||
|
|
||||||
SUCCESS = 0,
|
|
||||||
REBOOT_NEEDED = 999,
|
|
||||||
|
|
||||||
LIMITED_INSTALL = 0,
|
|
||||||
FULL_INSTALL = 1,
|
|
||||||
NO_STATUS_DLG = 2,
|
|
||||||
NO_FINALIZE_DLG = 4,
|
|
||||||
|
|
||||||
INSTALL_FILE_UNEXPECTED_MSG_ID = 0,
|
|
||||||
DETAILS_REPLACE_FILE_MSG_ID = 1,
|
|
||||||
DETAILS_INSTALL_FILE_MSG_ID = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
nsInstall();
|
|
||||||
virtual ~nsInstall();
|
|
||||||
|
|
||||||
PRInt32 SetScriptObject(void* aScriptObject);
|
|
||||||
|
|
||||||
PRInt32 SaveWinRegPrototype(void* aScriptObject);
|
|
||||||
PRInt32 SaveWinProfilePrototype(void* aScriptObject);
|
|
||||||
|
|
||||||
JSObject* RetrieveWinRegPrototype(void);
|
|
||||||
JSObject* RetrieveWinProfilePrototype(void);
|
|
||||||
|
|
||||||
PRInt32 GetUserPackageName(nsString& aUserPackageName);
|
|
||||||
PRInt32 GetRegPackageName(nsString& aRegPackageName);
|
|
||||||
|
|
||||||
PRInt32 AbortInstall();
|
|
||||||
|
|
||||||
PRInt32 AddDirectory(const nsString& aRegName, const nsString& aVersion, const nsString& aJarSource, const nsString& aFolder, const nsString& aSubdir, PRBool aForceMode, PRInt32* aReturn);
|
|
||||||
PRInt32 AddDirectory(const nsString& aRegName, const nsString& aVersion, const nsString& aJarSource, const nsString& aFolder, const nsString& aSubdir, PRInt32* aReturn);
|
|
||||||
PRInt32 AddDirectory(const nsString& aRegName, const nsString& aJarSource, const nsString& aFolder, const nsString& aSubdir, PRInt32* aReturn);
|
|
||||||
PRInt32 AddDirectory(const nsString& aJarSource, PRInt32* aReturn);
|
|
||||||
|
|
||||||
PRInt32 AddSubcomponent(const nsString& aRegName, const nsString& aVersion, const nsString& aJarSource, const nsString& aFolder, const nsString& aTargetName, PRBool aForceMode, PRInt32* aReturn);
|
|
||||||
PRInt32 AddSubcomponent(const nsString& aRegName, const nsString& aVersion, const nsString& aJarSource, const nsString& aFolder, const nsString& aTargetName, PRInt32* aReturn);
|
|
||||||
PRInt32 AddSubcomponent(const nsString& aRegName, const nsString& aJarSource, const nsString& aFolder, const nsString& aTargetName, PRInt32* aReturn);
|
|
||||||
PRInt32 AddSubcomponent(const nsString& aJarSource, PRInt32* aReturn);
|
|
||||||
|
|
||||||
PRInt32 DeleteComponent(const nsString& aRegistryName, PRInt32* aReturn);
|
|
||||||
PRInt32 DeleteFile(const nsString& aFolder, const nsString& aRelativeFileName, PRInt32* aReturn);
|
|
||||||
PRInt32 DiskSpaceAvailable(const nsString& aFolder, PRInt32* aReturn);
|
|
||||||
PRInt32 Execute(const nsString& aJarSource, const nsString& aArgs, PRInt32* aReturn);
|
|
||||||
PRInt32 Execute(const nsString& aJarSource, PRInt32* aReturn);
|
|
||||||
PRInt32 FinalizeInstall(PRInt32* aReturn);
|
|
||||||
PRInt32 Gestalt(const nsString& aSelector, PRInt32* aReturn);
|
|
||||||
PRInt32 GetComponentFolder(const nsString& aComponentName, const nsString& aSubdirectory, nsString** aFolder);
|
|
||||||
PRInt32 GetComponentFolder(const nsString& aComponentName, nsString** aFolder);
|
|
||||||
PRInt32 GetFolder(const nsString& aTargetFolder, const nsString& aSubdirectory, nsString** aFolder);
|
|
||||||
PRInt32 GetFolder(const nsString& aTargetFolder, nsString** aFolder);
|
|
||||||
PRInt32 GetLastError(PRInt32* aReturn);
|
|
||||||
PRInt32 GetWinProfile(const nsString& aFolder, const nsString& aFile, JSContext* jscontext, JSClass* WinProfileClass, jsval* aReturn);
|
|
||||||
PRInt32 GetWinRegistry(JSContext* jscontext, JSClass* WinRegClass, jsval* aReturn);
|
|
||||||
PRInt32 Patch(const nsString& aRegName, const nsString& aVersion, const nsString& aJarSource, const nsString& aFolder, const nsString& aTargetName, PRInt32* aReturn);
|
|
||||||
PRInt32 Patch(const nsString& aRegName, const nsString& aJarSource, const nsString& aFolder, const nsString& aTargetName, PRInt32* aReturn);
|
|
||||||
PRInt32 ResetError();
|
|
||||||
PRInt32 SetPackageFolder(const nsString& aFolder);
|
|
||||||
PRInt32 StartInstall(const nsString& aUserPackageName, const nsString& aPackageName, const nsString& aVersion, PRInt32* aReturn);
|
|
||||||
PRInt32 Uninstall(const nsString& aPackageName, PRInt32* aReturn);
|
|
||||||
|
|
||||||
PRInt32 FileOpDirCreate(nsFileSpec& aTarget, PRInt32* aReturn);
|
|
||||||
PRInt32 FileOpDirGetParent(nsFileSpec& aTarget, nsFileSpec* aReturn);
|
|
||||||
PRInt32 FileOpDirRemove(nsFileSpec& aTarget, PRInt32 aFlags, PRInt32* aReturn);
|
|
||||||
PRInt32 FileOpDirRename(nsFileSpec& aSrc, nsFileSpec& aTarget, PRInt32* aReturn);
|
|
||||||
PRInt32 FileOpFileCopy(nsFileSpec& aSrc, nsFileSpec& aTarget, PRInt32* aReturn);
|
|
||||||
PRInt32 FileOpFileDelete(nsFileSpec& aTarget, PRInt32 aFlags, PRInt32* aReturn);
|
|
||||||
PRInt32 FileOpFileExists(nsFileSpec& aTarget, PRBool* aReturn);
|
|
||||||
PRInt32 FileOpFileExecute(nsFileSpec& aTarget, nsString& aParams, PRInt32* aReturn);
|
|
||||||
PRInt32 FileOpFileGetNativeVersion(nsFileSpec& aTarget, nsString* aReturn);
|
|
||||||
PRInt32 FileOpFileGetDiskSpaceAvailable(nsFileSpec& aTarget, PRUint32* aReturn);
|
|
||||||
PRInt32 FileOpFileGetModDate(nsFileSpec& aTarget, nsFileSpec::TimeStamp* aReturn);
|
|
||||||
PRInt32 FileOpFileGetSize(nsFileSpec& aTarget, PRUint32* aReturn);
|
|
||||||
PRInt32 FileOpFileIsDirectory(nsFileSpec& aTarget, PRBool* aReturn);
|
|
||||||
PRInt32 FileOpFileIsFile(nsFileSpec& aTarget, PRBool* aReturn);
|
|
||||||
PRInt32 FileOpFileModDateChanged(nsFileSpec& aTarget, nsFileSpec::TimeStamp& aOldStamp, PRBool* aReturn);
|
|
||||||
PRInt32 FileOpFileMove(nsFileSpec& aSrc, nsFileSpec& aTarget, PRInt32* aReturn);
|
|
||||||
PRInt32 FileOpFileRename(nsFileSpec& aSrc, nsFileSpec& aTarget, PRInt32* aReturn);
|
|
||||||
PRInt32 FileOpFileWinShortcutCreate(nsFileSpec& aTarget, PRInt32 aFlags, PRInt32* aReturn);
|
|
||||||
PRInt32 FileOpFileMacAliasCreate(nsFileSpec& aTarget, PRInt32 aFlags, PRInt32* aReturn);
|
|
||||||
PRInt32 FileOpFileUnixLinkCreate(nsFileSpec& aTarget, PRInt32 aFlags, PRInt32* aReturn);
|
|
||||||
|
|
||||||
PRInt32 ExtractFileFromJar(const nsString& aJarfile, nsFileSpec* aSuggestedName, nsFileSpec** aRealName);
|
|
||||||
void AddPatch(nsHashKey *aKey, nsFileSpec* fileName);
|
|
||||||
void GetPatch(nsHashKey *aKey, nsFileSpec* fileName);
|
|
||||||
|
|
||||||
void GetJarFileLocation(nsString& aFile);
|
|
||||||
void SetJarFileLocation(const nsString& aFile);
|
|
||||||
|
|
||||||
void GetInstallArguments(nsString& args);
|
|
||||||
void SetInstallArguments(const nsString& args);
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
JSObject* mScriptObject;
|
|
||||||
|
|
||||||
JSObject* mWinRegObject;
|
|
||||||
JSObject* mWinProfileObject;
|
|
||||||
|
|
||||||
nsString mJarFileLocation;
|
|
||||||
void* mJarFileData;
|
|
||||||
|
|
||||||
nsString mInstallArguments;
|
|
||||||
|
|
||||||
PRBool mUserCancelled;
|
|
||||||
|
|
||||||
PRBool mUninstallPackage;
|
|
||||||
PRBool mRegisterPackage;
|
|
||||||
|
|
||||||
nsString mRegistryPackageName; /* Name of the package we are installing */
|
|
||||||
nsString mUIName; /* User-readable package name */
|
|
||||||
|
|
||||||
nsInstallVersion* mVersionInfo; /* Component version info */
|
|
||||||
|
|
||||||
nsVector* mInstalledFiles;
|
|
||||||
nsHashtable* mPatchList;
|
|
||||||
|
|
||||||
nsIXPInstallProgress *mNotifier;
|
|
||||||
|
|
||||||
PRInt32 mLastError;
|
|
||||||
|
|
||||||
void ParseFlags(int flags);
|
|
||||||
PRInt32 SanityCheck(void);
|
|
||||||
void GetTime(nsString &aString);
|
|
||||||
|
|
||||||
|
|
||||||
PRInt32 GetQualifiedRegName(const nsString& name, nsString& qualifiedRegName );
|
|
||||||
PRInt32 GetQualifiedPackageName( const nsString& name, nsString& qualifiedName );
|
|
||||||
|
|
||||||
void CurrentUserNode(nsString& userRegNode);
|
|
||||||
PRBool BadRegName(const nsString& regName);
|
|
||||||
PRInt32 SaveError(PRInt32 errcode);
|
|
||||||
|
|
||||||
void CleanUp();
|
|
||||||
|
|
||||||
PRInt32 OpenJARFile(void);
|
|
||||||
void CloseJARFile(void);
|
|
||||||
PRInt32 ExtractDirEntries(const nsString& directory, nsVector *paths);
|
|
||||||
|
|
||||||
PRInt32 ScheduleForInstall(nsInstallObject* ob);
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,235 +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.0 (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,
|
|
||||||
* released March 31, 1998.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* Daniel Veditz <dveditz@netscape.com>
|
|
||||||
* Douglas Turner <dougt@netscape.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "prmem.h"
|
|
||||||
|
|
||||||
#include "nsFileSpec.h"
|
|
||||||
|
|
||||||
#include "VerReg.h"
|
|
||||||
#include "ScheduledTasks.h"
|
|
||||||
#include "nsInstallDelete.h"
|
|
||||||
#include "nsInstallResources.h"
|
|
||||||
|
|
||||||
#include "nsInstall.h"
|
|
||||||
#include "nsIDOMInstallVersion.h"
|
|
||||||
|
|
||||||
nsInstallDelete::nsInstallDelete( nsInstall* inInstall,
|
|
||||||
const nsString& folderSpec,
|
|
||||||
const nsString& inPartialPath,
|
|
||||||
PRInt32 *error)
|
|
||||||
|
|
||||||
: nsInstallObject(inInstall)
|
|
||||||
{
|
|
||||||
if ((folderSpec == "null") || (inInstall == NULL))
|
|
||||||
{
|
|
||||||
*error = nsInstall::INVALID_ARGUMENTS;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mDeleteStatus = DELETE_FILE;
|
|
||||||
mFinalFile = nsnull;
|
|
||||||
mRegistryName = "";
|
|
||||||
|
|
||||||
|
|
||||||
mFinalFile = new nsFileSpec(folderSpec);
|
|
||||||
*mFinalFile += inPartialPath;
|
|
||||||
|
|
||||||
*error = ProcessInstallDelete();
|
|
||||||
}
|
|
||||||
|
|
||||||
nsInstallDelete::nsInstallDelete( nsInstall* inInstall,
|
|
||||||
const nsString& inComponentName,
|
|
||||||
PRInt32 *error)
|
|
||||||
|
|
||||||
: nsInstallObject(inInstall)
|
|
||||||
{
|
|
||||||
if (inInstall == NULL)
|
|
||||||
{
|
|
||||||
*error = nsInstall::INVALID_ARGUMENTS;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mDeleteStatus = DELETE_COMPONENT;
|
|
||||||
mFinalFile = nsnull;
|
|
||||||
mRegistryName = inComponentName;
|
|
||||||
|
|
||||||
*error = ProcessInstallDelete();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
nsInstallDelete::~nsInstallDelete()
|
|
||||||
{
|
|
||||||
if (mFinalFile == nsnull)
|
|
||||||
delete mFinalFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PRInt32 nsInstallDelete::Prepare()
|
|
||||||
{
|
|
||||||
// no set-up necessary
|
|
||||||
return nsInstall::SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRInt32 nsInstallDelete::Complete()
|
|
||||||
{
|
|
||||||
PRInt32 err = nsInstall::SUCCESS;
|
|
||||||
|
|
||||||
if (mInstall == NULL)
|
|
||||||
return nsInstall::INVALID_ARGUMENTS;
|
|
||||||
|
|
||||||
if (mDeleteStatus == DELETE_COMPONENT)
|
|
||||||
{
|
|
||||||
char* temp = mRegistryName.ToNewCString();
|
|
||||||
err = VR_Remove(temp);
|
|
||||||
delete [] temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((mDeleteStatus == DELETE_FILE) || (err == REGERR_OK))
|
|
||||||
{
|
|
||||||
err = NativeComplete();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
err = nsInstall::UNEXPECTED_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsInstallDelete::Abort()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
char* nsInstallDelete::toString()
|
|
||||||
{
|
|
||||||
char* buffer = new char[1024];
|
|
||||||
|
|
||||||
if (mDeleteStatus == DELETE_COMPONENT)
|
|
||||||
{
|
|
||||||
sprintf( buffer, nsInstallResources::GetDeleteComponentString(), nsAutoCString(mRegistryName));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (mFinalFile)
|
|
||||||
sprintf( buffer, nsInstallResources::GetDeleteFileString(), mFinalFile->GetCString());
|
|
||||||
}
|
|
||||||
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PRBool
|
|
||||||
nsInstallDelete::CanUninstall()
|
|
||||||
{
|
|
||||||
return PR_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRBool
|
|
||||||
nsInstallDelete::RegisterPackageNode()
|
|
||||||
{
|
|
||||||
return PR_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PRInt32 nsInstallDelete::ProcessInstallDelete()
|
|
||||||
{
|
|
||||||
PRInt32 err;
|
|
||||||
|
|
||||||
char* tempCString = nsnull;
|
|
||||||
|
|
||||||
if (mDeleteStatus == DELETE_COMPONENT)
|
|
||||||
{
|
|
||||||
/* Check if the component is in the registry */
|
|
||||||
tempCString = mRegistryName.ToNewCString();
|
|
||||||
|
|
||||||
err = VR_InRegistry( tempCString );
|
|
||||||
|
|
||||||
if (err != REGERR_OK)
|
|
||||||
{
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char* tempRegistryString;
|
|
||||||
|
|
||||||
tempRegistryString = (char*)PR_Calloc(MAXREGPATHLEN, sizeof(char));
|
|
||||||
|
|
||||||
err = VR_GetPath( tempCString , MAXREGPATHLEN, tempRegistryString);
|
|
||||||
|
|
||||||
if (err == REGERR_OK)
|
|
||||||
{
|
|
||||||
if (mFinalFile)
|
|
||||||
delete mFinalFile;
|
|
||||||
|
|
||||||
mFinalFile = new nsFileSpec(tempRegistryString);
|
|
||||||
}
|
|
||||||
|
|
||||||
PR_FREEIF(tempRegistryString);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(tempCString)
|
|
||||||
delete [] tempCString;
|
|
||||||
|
|
||||||
if (mFinalFile->Exists())
|
|
||||||
{
|
|
||||||
if (mFinalFile->IsFile())
|
|
||||||
{
|
|
||||||
err = nsInstall::SUCCESS;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
err = nsInstall::FILE_IS_DIRECTORY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
err = nsInstall::FILE_DOES_NOT_EXIST;
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PRInt32 nsInstallDelete::NativeComplete()
|
|
||||||
{
|
|
||||||
if (mFinalFile->Exists())
|
|
||||||
{
|
|
||||||
if (mFinalFile->IsFile())
|
|
||||||
{
|
|
||||||
return DeleteFileNowOrSchedule(*mFinalFile);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return nsInstall::FILE_IS_DIRECTORY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nsInstall::FILE_DOES_NOT_EXIST;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,78 +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.0 (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,
|
|
||||||
* released March 31, 1998.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* Daniel Veditz <dveditz@netscape.com>
|
|
||||||
* Douglas Turner <dougt@netscape.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef nsInstallDelete_h__
|
|
||||||
#define nsInstallDelete_h__
|
|
||||||
|
|
||||||
#include "prtypes.h"
|
|
||||||
#include "nsString.h"
|
|
||||||
|
|
||||||
#include "nsInstallObject.h"
|
|
||||||
|
|
||||||
#include "nsInstall.h"
|
|
||||||
|
|
||||||
#define DELETE_COMPONENT 1
|
|
||||||
#define DELETE_FILE 2
|
|
||||||
|
|
||||||
class nsInstallDelete : public nsInstallObject
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
nsInstallDelete( nsInstall* inInstall,
|
|
||||||
const nsString& folderSpec,
|
|
||||||
const nsString& inPartialPath,
|
|
||||||
PRInt32 *error);
|
|
||||||
|
|
||||||
nsInstallDelete( nsInstall* inInstall,
|
|
||||||
const nsString& ,
|
|
||||||
PRInt32 *error);
|
|
||||||
|
|
||||||
virtual ~nsInstallDelete();
|
|
||||||
|
|
||||||
PRInt32 Prepare();
|
|
||||||
PRInt32 Complete();
|
|
||||||
void Abort();
|
|
||||||
char* toString();
|
|
||||||
|
|
||||||
PRBool CanUninstall();
|
|
||||||
PRBool RegisterPackageNode();
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
/* Private Fields */
|
|
||||||
|
|
||||||
nsFileSpec* mFinalFile;
|
|
||||||
|
|
||||||
nsString mRegistryName;
|
|
||||||
PRInt32 mDeleteStatus;
|
|
||||||
|
|
||||||
PRInt32 ProcessInstallDelete();
|
|
||||||
PRInt32 NativeComplete();
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* nsInstallDelete_h__ */
|
|
||||||
@@ -1,136 +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.0 (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,
|
|
||||||
* released March 31, 1998.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* Daniel Veditz <dveditz@netscape.com>
|
|
||||||
* Douglas Turner <dougt@netscape.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "prmem.h"
|
|
||||||
|
|
||||||
#include "nsFileSpec.h"
|
|
||||||
|
|
||||||
#include "VerReg.h"
|
|
||||||
#include "nsInstallExecute.h"
|
|
||||||
#include "nsInstallResources.h"
|
|
||||||
#include "ScheduledTasks.h"
|
|
||||||
|
|
||||||
#include "nsInstall.h"
|
|
||||||
#include "nsIDOMInstallVersion.h"
|
|
||||||
|
|
||||||
nsInstallExecute:: nsInstallExecute( nsInstall* inInstall,
|
|
||||||
const nsString& inJarLocation,
|
|
||||||
const nsString& inArgs,
|
|
||||||
PRInt32 *error)
|
|
||||||
|
|
||||||
: nsInstallObject(inInstall)
|
|
||||||
{
|
|
||||||
if ((inInstall == nsnull) || (inJarLocation == "null"))
|
|
||||||
{
|
|
||||||
*error = nsInstall::INVALID_ARGUMENTS;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mJarLocation = inJarLocation;
|
|
||||||
mArgs = inArgs;
|
|
||||||
mExecutableFile = nsnull;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
nsInstallExecute::~nsInstallExecute()
|
|
||||||
{
|
|
||||||
if (mExecutableFile)
|
|
||||||
delete mExecutableFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PRInt32 nsInstallExecute::Prepare()
|
|
||||||
{
|
|
||||||
if (mInstall == NULL || mJarLocation == "null")
|
|
||||||
return nsInstall::INVALID_ARGUMENTS;
|
|
||||||
|
|
||||||
return mInstall->ExtractFileFromJar(mJarLocation, nsnull, &mExecutableFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
PRInt32 nsInstallExecute::Complete()
|
|
||||||
{
|
|
||||||
if (mExecutableFile == nsnull)
|
|
||||||
return nsInstall::INVALID_ARGUMENTS;
|
|
||||||
|
|
||||||
nsFileSpec app( *mExecutableFile);
|
|
||||||
|
|
||||||
if (!app.Exists())
|
|
||||||
{
|
|
||||||
return nsInstall::INVALID_ARGUMENTS;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRInt32 result = app.Execute( mArgs );
|
|
||||||
|
|
||||||
DeleteFileNowOrSchedule( app );
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsInstallExecute::Abort()
|
|
||||||
{
|
|
||||||
/* Get the names */
|
|
||||||
if (mExecutableFile == nsnull)
|
|
||||||
return;
|
|
||||||
|
|
||||||
DeleteFileNowOrSchedule(*mExecutableFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
char* nsInstallExecute::toString()
|
|
||||||
{
|
|
||||||
char* buffer = new char[1024];
|
|
||||||
|
|
||||||
// if the FileSpec is NULL, just us the in jar file name.
|
|
||||||
|
|
||||||
if (mExecutableFile == nsnull)
|
|
||||||
{
|
|
||||||
char *tempString = mJarLocation.ToNewCString();
|
|
||||||
sprintf( buffer, nsInstallResources::GetExecuteString(), tempString);
|
|
||||||
delete [] tempString;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sprintf( buffer, nsInstallResources::GetExecuteString(), mExecutableFile->GetCString());
|
|
||||||
}
|
|
||||||
return buffer;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PRBool
|
|
||||||
nsInstallExecute::CanUninstall()
|
|
||||||
{
|
|
||||||
return PR_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRBool
|
|
||||||
nsInstallExecute::RegisterPackageNode()
|
|
||||||
{
|
|
||||||
return PR_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,73 +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.0 (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,
|
|
||||||
* released March 31, 1998.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* Daniel Veditz <dveditz@netscape.com>
|
|
||||||
* Douglas Turner <dougt@netscape.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef nsInstallExecute_h__
|
|
||||||
#define nsInstallExecute_h__
|
|
||||||
|
|
||||||
#include "prtypes.h"
|
|
||||||
#include "nsString.h"
|
|
||||||
|
|
||||||
#include "nsInstallObject.h"
|
|
||||||
|
|
||||||
#include "nsInstall.h"
|
|
||||||
#include "nsIDOMInstallVersion.h"
|
|
||||||
|
|
||||||
|
|
||||||
class nsInstallExecute : public nsInstallObject
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
nsInstallExecute( nsInstall* inInstall,
|
|
||||||
const nsString& inJarLocation,
|
|
||||||
const nsString& inArgs,
|
|
||||||
PRInt32 *error);
|
|
||||||
|
|
||||||
|
|
||||||
virtual ~nsInstallExecute();
|
|
||||||
|
|
||||||
PRInt32 Prepare();
|
|
||||||
PRInt32 Complete();
|
|
||||||
void Abort();
|
|
||||||
char* toString();
|
|
||||||
|
|
||||||
PRBool CanUninstall();
|
|
||||||
PRBool RegisterPackageNode();
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
nsString mJarLocation; // Location in the JAR
|
|
||||||
nsString mArgs; // command line arguments
|
|
||||||
|
|
||||||
nsFileSpec *mExecutableFile; // temporary file location
|
|
||||||
|
|
||||||
|
|
||||||
PRInt32 NativeComplete(void);
|
|
||||||
void NativeAbort(void);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* nsInstallExecute_h__ */
|
|
||||||
@@ -1,366 +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.0 (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,
|
|
||||||
* released March 31, 1998.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* Daniel Veditz <dveditz@netscape.com>
|
|
||||||
* Douglas Turner <dougt@netscape.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "nsInstallFile.h"
|
|
||||||
#include "nsFileSpec.h"
|
|
||||||
#include "VerReg.h"
|
|
||||||
#include "ScheduledTasks.h"
|
|
||||||
#include "nsInstall.h"
|
|
||||||
#include "nsIDOMInstallVersion.h"
|
|
||||||
#include "nsInstallResources.h"
|
|
||||||
|
|
||||||
/* Public Methods */
|
|
||||||
|
|
||||||
/* Constructor
|
|
||||||
inInstall - softUpdate object we belong to
|
|
||||||
inComponentName - full path of the registry component
|
|
||||||
inVInfo - full version info
|
|
||||||
inJarLocation - location inside the JAR file
|
|
||||||
inFinalFileSpec - final location on disk
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
nsInstallFile::nsInstallFile(nsInstall* inInstall,
|
|
||||||
const nsString& inComponentName,
|
|
||||||
const nsString& inVInfo,
|
|
||||||
const nsString& inJarLocation,
|
|
||||||
const nsString& folderSpec,
|
|
||||||
const nsString& inPartialPath,
|
|
||||||
PRBool forceInstall,
|
|
||||||
PRInt32 *error)
|
|
||||||
: nsInstallObject(inInstall)
|
|
||||||
{
|
|
||||||
mVersionRegistryName = nsnull;
|
|
||||||
mJarLocation = nsnull;
|
|
||||||
mExtracedFile = nsnull;
|
|
||||||
mFinalFile = nsnull;
|
|
||||||
mVersionInfo = nsnull;
|
|
||||||
|
|
||||||
mUpgradeFile = PR_FALSE;
|
|
||||||
|
|
||||||
if ((folderSpec == "null") || (inInstall == NULL))
|
|
||||||
{
|
|
||||||
*error = nsInstall::INVALID_ARGUMENTS;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for existence of the newer version */
|
|
||||||
|
|
||||||
PRBool versionNewer = PR_FALSE; // Is this a newer version
|
|
||||||
char* qualifiedRegNameString = inComponentName.ToNewCString();
|
|
||||||
|
|
||||||
if ( (forceInstall == PR_FALSE ) && (inVInfo != "") && ( VR_ValidateComponent( qualifiedRegNameString ) == 0 ) )
|
|
||||||
{
|
|
||||||
nsInstallVersion *newVersion = new nsInstallVersion();
|
|
||||||
newVersion->Init(inVInfo);
|
|
||||||
|
|
||||||
VERSION versionStruct;
|
|
||||||
|
|
||||||
VR_GetVersion( qualifiedRegNameString, &versionStruct );
|
|
||||||
|
|
||||||
nsInstallVersion* oldVersion = new nsInstallVersion();
|
|
||||||
|
|
||||||
oldVersion->Init(versionStruct.major,
|
|
||||||
versionStruct.minor,
|
|
||||||
versionStruct.release,
|
|
||||||
versionStruct.build);
|
|
||||||
|
|
||||||
PRInt32 areTheyEqual;
|
|
||||||
newVersion->CompareTo(oldVersion, &areTheyEqual);
|
|
||||||
|
|
||||||
delete oldVersion;
|
|
||||||
delete newVersion;
|
|
||||||
|
|
||||||
if (areTheyEqual == nsIDOMInstallVersion::MAJOR_DIFF_MINUS ||
|
|
||||||
areTheyEqual == nsIDOMInstallVersion::MINOR_DIFF_MINUS ||
|
|
||||||
areTheyEqual == nsIDOMInstallVersion::REL_DIFF_MINUS ||
|
|
||||||
areTheyEqual == nsIDOMInstallVersion::BLD_DIFF_MINUS )
|
|
||||||
{
|
|
||||||
// the file to be installed is OLDER than what is on disk. Return error
|
|
||||||
delete qualifiedRegNameString;
|
|
||||||
*error = areTheyEqual;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delete qualifiedRegNameString;
|
|
||||||
|
|
||||||
|
|
||||||
mFinalFile = new nsFileSpec(folderSpec);
|
|
||||||
*mFinalFile += inPartialPath;
|
|
||||||
|
|
||||||
mReplaceFile = mFinalFile->Exists();
|
|
||||||
|
|
||||||
if (mReplaceFile == PR_FALSE)
|
|
||||||
{
|
|
||||||
nsFileSpec parent;
|
|
||||||
mFinalFile->GetParent(parent);
|
|
||||||
nsFileSpec makeDirs(parent.GetCString(), PR_TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
mForceInstall = forceInstall;
|
|
||||||
|
|
||||||
mVersionRegistryName = new nsString(inComponentName);
|
|
||||||
mJarLocation = new nsString(inJarLocation);
|
|
||||||
mVersionInfo = new nsString(inVInfo);
|
|
||||||
|
|
||||||
nsString regPackageName;
|
|
||||||
mInstall->GetRegPackageName(regPackageName);
|
|
||||||
|
|
||||||
// determine Child status
|
|
||||||
if ( regPackageName == "" )
|
|
||||||
{
|
|
||||||
// in the "current communicator package" absolute pathnames (start
|
|
||||||
// with slash) indicate shared files -- all others are children
|
|
||||||
mChildFile = ( mVersionRegistryName->CharAt(0) != '/' );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
// there is no "starts with" api in nsString. LAME!
|
|
||||||
nsString startsWith;
|
|
||||||
mVersionRegistryName->Left(startsWith, regPackageName.Length());
|
|
||||||
|
|
||||||
if (startsWith.Equals(regPackageName))
|
|
||||||
{
|
|
||||||
mChildFile = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mChildFile = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
nsInstallFile::~nsInstallFile()
|
|
||||||
{
|
|
||||||
if (mVersionRegistryName)
|
|
||||||
delete mVersionRegistryName;
|
|
||||||
|
|
||||||
if (mJarLocation)
|
|
||||||
delete mJarLocation;
|
|
||||||
|
|
||||||
if (mExtracedFile)
|
|
||||||
delete mExtracedFile;
|
|
||||||
|
|
||||||
if (mFinalFile)
|
|
||||||
delete mFinalFile;
|
|
||||||
|
|
||||||
if (mVersionInfo)
|
|
||||||
delete mVersionInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Prepare
|
|
||||||
* Extracts file out of the JAR archive
|
|
||||||
*/
|
|
||||||
PRInt32 nsInstallFile::Prepare()
|
|
||||||
{
|
|
||||||
if (mInstall == nsnull || mFinalFile == nsnull || mJarLocation == nsnull )
|
|
||||||
return nsInstall::INVALID_ARGUMENTS;
|
|
||||||
|
|
||||||
return mInstall->ExtractFileFromJar(*mJarLocation, mFinalFile, &mExtracedFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Complete
|
|
||||||
* Completes the install:
|
|
||||||
* - move the downloaded file to the final location
|
|
||||||
* - updates the registry
|
|
||||||
*/
|
|
||||||
PRInt32 nsInstallFile::Complete()
|
|
||||||
{
|
|
||||||
PRInt32 err;
|
|
||||||
|
|
||||||
if (mInstall == nsnull || mVersionRegistryName == nsnull || mFinalFile == nsnull )
|
|
||||||
{
|
|
||||||
return nsInstall::INVALID_ARGUMENTS;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = CompleteFileMove();
|
|
||||||
|
|
||||||
if ( 0 == err || nsInstall::REBOOT_NEEDED == err )
|
|
||||||
{
|
|
||||||
err = RegisterInVersionRegistry();
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsInstallFile::Abort()
|
|
||||||
{
|
|
||||||
if (mExtracedFile != nsnull)
|
|
||||||
mExtracedFile->Delete(PR_FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
char* nsInstallFile::toString()
|
|
||||||
{
|
|
||||||
char* buffer = new char[1024];
|
|
||||||
|
|
||||||
if (mFinalFile == nsnull)
|
|
||||||
{
|
|
||||||
sprintf( buffer, nsInstallResources::GetInstallFileString(), nsnull);
|
|
||||||
}
|
|
||||||
else if (mReplaceFile)
|
|
||||||
{
|
|
||||||
// we are replacing this file.
|
|
||||||
|
|
||||||
sprintf( buffer, nsInstallResources::GetReplaceFileString(), mFinalFile->GetCString());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sprintf( buffer, nsInstallResources::GetInstallFileString(), mFinalFile->GetCString());
|
|
||||||
}
|
|
||||||
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PRInt32 nsInstallFile::CompleteFileMove()
|
|
||||||
{
|
|
||||||
int result = 0;
|
|
||||||
|
|
||||||
if (mExtracedFile == nsnull)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( *mExtracedFile == *mFinalFile )
|
|
||||||
{
|
|
||||||
/* No need to rename, they are the same */
|
|
||||||
result = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = ReplaceFileNowOrSchedule(*mExtracedFile, *mFinalFile );
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRInt32
|
|
||||||
nsInstallFile::RegisterInVersionRegistry()
|
|
||||||
{
|
|
||||||
int refCount;
|
|
||||||
nsString regPackageName;
|
|
||||||
mInstall->GetRegPackageName(regPackageName);
|
|
||||||
|
|
||||||
|
|
||||||
// Register file and log for Uninstall
|
|
||||||
|
|
||||||
if (!mChildFile)
|
|
||||||
{
|
|
||||||
int found;
|
|
||||||
if (regPackageName != "")
|
|
||||||
{
|
|
||||||
found = VR_UninstallFileExistsInList( (char*)(const char*)nsAutoCString(regPackageName) ,
|
|
||||||
(char*)(const char*)nsAutoCString(*mVersionRegistryName));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
found = VR_UninstallFileExistsInList( "", (char*)(const char*)nsAutoCString(*mVersionRegistryName) );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found != REGERR_OK)
|
|
||||||
mUpgradeFile = PR_FALSE;
|
|
||||||
else
|
|
||||||
mUpgradeFile = PR_TRUE;
|
|
||||||
}
|
|
||||||
else if (REGERR_OK == VR_InRegistry( (char*)(const char*)nsAutoCString(*mVersionRegistryName)))
|
|
||||||
{
|
|
||||||
mUpgradeFile = PR_TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mUpgradeFile = PR_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( REGERR_OK != VR_GetRefCount( (char*)(const char*)nsAutoCString(*mVersionRegistryName), &refCount ))
|
|
||||||
{
|
|
||||||
refCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
VR_Install( (char*)(const char*)nsAutoCString(*mVersionRegistryName),
|
|
||||||
(char*)(const char*)mFinalFile->GetNativePathCString(), // DO NOT CHANGE THIS.
|
|
||||||
(char*)(const char*)nsAutoCString(*mVersionInfo),
|
|
||||||
PR_FALSE );
|
|
||||||
|
|
||||||
if (mUpgradeFile)
|
|
||||||
{
|
|
||||||
if (refCount == 0)
|
|
||||||
VR_SetRefCount( (char*)(const char*)nsAutoCString(*mVersionRegistryName), 1 );
|
|
||||||
else
|
|
||||||
VR_SetRefCount( (char*)(const char*)nsAutoCString(*mVersionRegistryName), refCount ); //FIX?? what should the ref count be/
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (refCount != 0)
|
|
||||||
{
|
|
||||||
VR_SetRefCount( (char*)(const char*)nsAutoCString(*mVersionRegistryName), refCount + 1 );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (mReplaceFile)
|
|
||||||
VR_SetRefCount( (char*)(const char*)nsAutoCString(*mVersionRegistryName), 2 );
|
|
||||||
else
|
|
||||||
VR_SetRefCount( (char*)(const char*)nsAutoCString(*mVersionRegistryName), 1 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !mChildFile && !mUpgradeFile )
|
|
||||||
{
|
|
||||||
if (regPackageName != "")
|
|
||||||
{
|
|
||||||
VR_UninstallAddFileToList( (char*)(const char*)nsAutoCString(regPackageName),
|
|
||||||
(char*)(const char*)nsAutoCString(*mVersionRegistryName));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
VR_UninstallAddFileToList( "", (char*)(const char*)nsAutoCString(*mVersionRegistryName) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nsInstall::SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* CanUninstall
|
|
||||||
* InstallFile() installs files which can be uninstalled,
|
|
||||||
* hence this function returns true.
|
|
||||||
*/
|
|
||||||
PRBool
|
|
||||||
nsInstallFile::CanUninstall()
|
|
||||||
{
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* RegisterPackageNode
|
|
||||||
* InstallFile() installs files which need to be registered,
|
|
||||||
* hence this function returns true.
|
|
||||||
*/
|
|
||||||
PRBool
|
|
||||||
nsInstallFile::RegisterPackageNode()
|
|
||||||
{
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
@@ -1,93 +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.0 (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,
|
|
||||||
* released March 31, 1998.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* Daniel Veditz <dveditz@netscape.com>
|
|
||||||
* Douglas Turner <dougt@netscape.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef nsInstallFile_h__
|
|
||||||
#define nsInstallFile_h__
|
|
||||||
|
|
||||||
#include "prtypes.h"
|
|
||||||
#include "nsString.h"
|
|
||||||
|
|
||||||
#include "nsInstallObject.h"
|
|
||||||
|
|
||||||
#include "nsInstall.h"
|
|
||||||
#include "nsInstallVersion.h"
|
|
||||||
|
|
||||||
class nsInstallFile : public nsInstallObject
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
/*************************************************************
|
|
||||||
* Public Methods
|
|
||||||
*
|
|
||||||
* Constructor
|
|
||||||
* inSoftUpdate - softUpdate object we belong to
|
|
||||||
* inComponentName - full path of the registry component
|
|
||||||
* inVInfo - full version info
|
|
||||||
* inJarLocation - location inside the JAR file
|
|
||||||
* inFinalFileSpec - final location on disk
|
|
||||||
*************************************************************/
|
|
||||||
nsInstallFile( nsInstall* inInstall,
|
|
||||||
const nsString& inVRName,
|
|
||||||
const nsString& inVInfo,
|
|
||||||
const nsString& inJarLocation,
|
|
||||||
const nsString& folderSpec,
|
|
||||||
const nsString& inPartialPath,
|
|
||||||
PRBool forceInstall,
|
|
||||||
PRInt32 *error);
|
|
||||||
|
|
||||||
virtual ~nsInstallFile();
|
|
||||||
|
|
||||||
PRInt32 Prepare();
|
|
||||||
PRInt32 Complete();
|
|
||||||
void Abort();
|
|
||||||
char* toString();
|
|
||||||
|
|
||||||
PRBool CanUninstall();
|
|
||||||
PRBool RegisterPackageNode();
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
/* Private Fields */
|
|
||||||
nsString* mVersionInfo; /* Version info for this file*/
|
|
||||||
|
|
||||||
nsString* mJarLocation; /* Location in the JAR */
|
|
||||||
nsFileSpec* mExtracedFile; /* temporary file location */
|
|
||||||
nsFileSpec* mFinalFile; /* final file destination */
|
|
||||||
|
|
||||||
nsString* mVersionRegistryName; /* full version path */
|
|
||||||
|
|
||||||
PRBool mForceInstall; /* whether install is forced */
|
|
||||||
PRBool mReplaceFile; /* whether file exists */
|
|
||||||
PRBool mChildFile; /* whether file is a child */
|
|
||||||
PRBool mUpgradeFile; /* whether file is an upgrade */
|
|
||||||
|
|
||||||
|
|
||||||
PRInt32 CompleteFileMove();
|
|
||||||
PRInt32 RegisterInVersionRegistry();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* nsInstallFile_h__ */
|
|
||||||
@@ -1,316 +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.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 "nspr.h"
|
|
||||||
#include "nsInstall.h"
|
|
||||||
#include "nsInstallFileOpEnums.h"
|
|
||||||
#include "nsInstallFileOpItem.h"
|
|
||||||
|
|
||||||
/* Public Methods */
|
|
||||||
|
|
||||||
nsInstallFileOpItem::nsInstallFileOpItem(nsInstall* aInstallObj,
|
|
||||||
PRInt32 aCommand,
|
|
||||||
nsFileSpec& aTarget,
|
|
||||||
PRInt32 aFlags,
|
|
||||||
PRInt32* aReturn)
|
|
||||||
:nsInstallObject(aInstallObj)
|
|
||||||
{
|
|
||||||
mIObj = aInstallObj;
|
|
||||||
mCommand = aCommand;
|
|
||||||
mFlags = aFlags;
|
|
||||||
mSrc = nsnull;
|
|
||||||
mParams = nsnull;
|
|
||||||
mTarget = new nsFileSpec(aTarget);
|
|
||||||
|
|
||||||
*aReturn = NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsInstallFileOpItem::nsInstallFileOpItem(nsInstall* aInstallObj,
|
|
||||||
PRInt32 aCommand,
|
|
||||||
nsFileSpec& aSrc,
|
|
||||||
nsFileSpec& aTarget,
|
|
||||||
PRInt32* aReturn)
|
|
||||||
:nsInstallObject(aInstallObj)
|
|
||||||
{
|
|
||||||
mIObj = aInstallObj;
|
|
||||||
mCommand = aCommand;
|
|
||||||
mFlags = 0;
|
|
||||||
mSrc = new nsFileSpec(aSrc);
|
|
||||||
mParams = nsnull;
|
|
||||||
mTarget = new nsFileSpec(aTarget);
|
|
||||||
|
|
||||||
*aReturn = NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsInstallFileOpItem::nsInstallFileOpItem(nsInstall* aInstallObj,
|
|
||||||
PRInt32 aCommand,
|
|
||||||
nsFileSpec& aTarget,
|
|
||||||
PRInt32* aReturn)
|
|
||||||
:nsInstallObject(aInstallObj)
|
|
||||||
{
|
|
||||||
mIObj = aInstallObj;
|
|
||||||
mCommand = aCommand;
|
|
||||||
mFlags = 0;
|
|
||||||
mSrc = nsnull;
|
|
||||||
mParams = nsnull;
|
|
||||||
mTarget = new nsFileSpec(aTarget);
|
|
||||||
|
|
||||||
*aReturn = NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsInstallFileOpItem::nsInstallFileOpItem(nsInstall* aInstallObj,
|
|
||||||
PRInt32 aCommand,
|
|
||||||
nsFileSpec& aTarget,
|
|
||||||
nsString& aParams,
|
|
||||||
PRInt32* aReturn)
|
|
||||||
:nsInstallObject(aInstallObj)
|
|
||||||
{
|
|
||||||
mIObj = aInstallObj;
|
|
||||||
mCommand = aCommand;
|
|
||||||
mFlags = 0;
|
|
||||||
mSrc = nsnull;
|
|
||||||
mParams = new nsString(aParams);
|
|
||||||
mTarget = new nsFileSpec(aTarget);
|
|
||||||
|
|
||||||
*aReturn = NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsInstallFileOpItem::~nsInstallFileOpItem()
|
|
||||||
{
|
|
||||||
if(mSrc)
|
|
||||||
delete mSrc;
|
|
||||||
if(mTarget)
|
|
||||||
delete mTarget;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRInt32 nsInstallFileOpItem::Complete()
|
|
||||||
{
|
|
||||||
PRInt32 aReturn = NS_OK;
|
|
||||||
|
|
||||||
switch(mCommand)
|
|
||||||
{
|
|
||||||
case NS_FOP_DIR_CREATE:
|
|
||||||
NativeFileOpDirCreate(mTarget);
|
|
||||||
break;
|
|
||||||
case NS_FOP_DIR_REMOVE:
|
|
||||||
NativeFileOpDirRemove(mTarget, mFlags);
|
|
||||||
break;
|
|
||||||
case NS_FOP_DIR_RENAME:
|
|
||||||
NativeFileOpDirRename(mSrc, mTarget);
|
|
||||||
break;
|
|
||||||
case NS_FOP_FILE_COPY:
|
|
||||||
NativeFileOpFileCopy(mSrc, mTarget);
|
|
||||||
break;
|
|
||||||
case NS_FOP_FILE_DELETE:
|
|
||||||
NativeFileOpFileDelete(mTarget, mFlags);
|
|
||||||
break;
|
|
||||||
case NS_FOP_FILE_EXECUTE:
|
|
||||||
NativeFileOpFileExecute(mTarget, mParams);
|
|
||||||
break;
|
|
||||||
case NS_FOP_FILE_MOVE:
|
|
||||||
NativeFileOpFileMove(mSrc, mTarget);
|
|
||||||
break;
|
|
||||||
case NS_FOP_FILE_RENAME:
|
|
||||||
NativeFileOpFileRename(mSrc, mTarget);
|
|
||||||
break;
|
|
||||||
case NS_FOP_WIN_SHORTCUT_CREATE:
|
|
||||||
NativeFileOpWinShortcutCreate();
|
|
||||||
break;
|
|
||||||
case NS_FOP_MAC_ALIAS_CREATE:
|
|
||||||
NativeFileOpMacAliasCreate();
|
|
||||||
break;
|
|
||||||
case NS_FOP_UNIX_LINK_CREATE:
|
|
||||||
NativeFileOpUnixLinkCreate();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return aReturn;
|
|
||||||
}
|
|
||||||
|
|
||||||
float nsInstallFileOpItem::GetInstallOrder()
|
|
||||||
{
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* nsInstallFileOpItem::toString()
|
|
||||||
{
|
|
||||||
nsString result;
|
|
||||||
char* resultCString;
|
|
||||||
|
|
||||||
switch(mCommand)
|
|
||||||
{
|
|
||||||
case NS_FOP_FILE_COPY:
|
|
||||||
result = "Copy file: ";
|
|
||||||
result.Append(mSrc->GetNativePathCString());
|
|
||||||
result.Append(" to ");
|
|
||||||
result.Append(mTarget->GetNativePathCString());
|
|
||||||
resultCString = result.ToNewCString();
|
|
||||||
break;
|
|
||||||
case NS_FOP_FILE_DELETE:
|
|
||||||
result = "Delete file: ";
|
|
||||||
result.Append(mTarget->GetNativePathCString());
|
|
||||||
resultCString = result.ToNewCString();
|
|
||||||
break;
|
|
||||||
case NS_FOP_FILE_MOVE:
|
|
||||||
result = "Move file: ";
|
|
||||||
result.Append(mSrc->GetNativePathCString());
|
|
||||||
result.Append(" to ");
|
|
||||||
result.Append(mTarget->GetNativePathCString());
|
|
||||||
resultCString = result.ToNewCString();
|
|
||||||
break;
|
|
||||||
case NS_FOP_FILE_RENAME:
|
|
||||||
result = "Rename file: ";
|
|
||||||
result.Append(mTarget->GetNativePathCString());
|
|
||||||
resultCString = result.ToNewCString();
|
|
||||||
break;
|
|
||||||
case NS_FOP_DIR_CREATE:
|
|
||||||
result = "Create Folder: ";
|
|
||||||
result.Append(mTarget->GetNativePathCString());
|
|
||||||
resultCString = result.ToNewCString();
|
|
||||||
break;
|
|
||||||
case NS_FOP_DIR_REMOVE:
|
|
||||||
result = "Remove Folder: ";
|
|
||||||
result.Append(mTarget->GetNativePathCString());
|
|
||||||
resultCString = result.ToNewCString();
|
|
||||||
break;
|
|
||||||
case NS_FOP_WIN_SHORTCUT_CREATE:
|
|
||||||
break;
|
|
||||||
case NS_FOP_MAC_ALIAS_CREATE:
|
|
||||||
break;
|
|
||||||
case NS_FOP_UNIX_LINK_CREATE:
|
|
||||||
break;
|
|
||||||
case NS_FOP_FILE_SET_STAT:
|
|
||||||
result = "Set file stat: ";
|
|
||||||
result.Append(mTarget->GetNativePathCString());
|
|
||||||
resultCString = result.ToNewCString();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
result = "Unkown file operation command!";
|
|
||||||
resultCString = result.ToNewCString();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return resultCString;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRInt32 nsInstallFileOpItem::Prepare()
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsInstallFileOpItem::Abort()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Private Methods */
|
|
||||||
|
|
||||||
/* CanUninstall
|
|
||||||
* InstallFileOpItem() does not install any files which can be uninstalled,
|
|
||||||
* hence this function returns false.
|
|
||||||
*/
|
|
||||||
PRBool
|
|
||||||
nsInstallFileOpItem::CanUninstall()
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* RegisterPackageNode
|
|
||||||
* InstallFileOpItem() does notinstall files which need to be registered,
|
|
||||||
* hence this function returns false.
|
|
||||||
*/
|
|
||||||
PRBool
|
|
||||||
nsInstallFileOpItem::RegisterPackageNode()
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// File operation functions begin here
|
|
||||||
//
|
|
||||||
PRInt32
|
|
||||||
nsInstallFileOpItem::NativeFileOpDirCreate(nsFileSpec* aTarget)
|
|
||||||
{
|
|
||||||
aTarget->CreateDirectory();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRInt32
|
|
||||||
nsInstallFileOpItem::NativeFileOpDirRemove(nsFileSpec* aTarget, PRInt32 aFlags)
|
|
||||||
{
|
|
||||||
aTarget->Delete(aFlags);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRInt32
|
|
||||||
nsInstallFileOpItem::NativeFileOpDirRename(nsFileSpec* aSrc, nsFileSpec* aTarget)
|
|
||||||
{
|
|
||||||
aSrc->Rename(*aTarget);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRInt32
|
|
||||||
nsInstallFileOpItem::NativeFileOpFileCopy(nsFileSpec* aSrc, nsFileSpec* aTarget)
|
|
||||||
{
|
|
||||||
aSrc->Copy(*aTarget);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRInt32
|
|
||||||
nsInstallFileOpItem::NativeFileOpFileDelete(nsFileSpec* aTarget, PRInt32 aFlags)
|
|
||||||
{
|
|
||||||
aTarget->Delete(aFlags);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRInt32
|
|
||||||
nsInstallFileOpItem::NativeFileOpFileExecute(nsFileSpec* aTarget, nsString* aParams)
|
|
||||||
{
|
|
||||||
aTarget->Execute(*aParams);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRInt32
|
|
||||||
nsInstallFileOpItem::NativeFileOpFileMove(nsFileSpec* aSrc, nsFileSpec* aTarget)
|
|
||||||
{
|
|
||||||
aSrc->Move(*aTarget);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRInt32
|
|
||||||
nsInstallFileOpItem::NativeFileOpFileRename(nsFileSpec* aSrc, nsFileSpec* aTarget)
|
|
||||||
{
|
|
||||||
aSrc->Rename(*aTarget);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRInt32
|
|
||||||
nsInstallFileOpItem::NativeFileOpWinShortcutCreate()
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRInt32
|
|
||||||
nsInstallFileOpItem::NativeFileOpMacAliasCreate()
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRInt32
|
|
||||||
nsInstallFileOpItem::NativeFileOpUnixLinkCreate()
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,111 +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.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 nsInstallFileOpItem_h__
|
|
||||||
#define nsInstallFileOpItem_h__
|
|
||||||
|
|
||||||
#include "prtypes.h"
|
|
||||||
|
|
||||||
#include "nsFileSpec.h"
|
|
||||||
#include "nsSoftwareUpdate.h"
|
|
||||||
#include "nsInstallObject.h"
|
|
||||||
#include "nsInstall.h"
|
|
||||||
|
|
||||||
class nsInstallFileOpItem : public nsInstallObject
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/* Public Fields */
|
|
||||||
|
|
||||||
/* Public Methods */
|
|
||||||
// used by:
|
|
||||||
// FileOpFileDelete()
|
|
||||||
nsInstallFileOpItem(nsInstall* installObj,
|
|
||||||
PRInt32 aCommand,
|
|
||||||
nsFileSpec& aTarget,
|
|
||||||
PRInt32 aFlags,
|
|
||||||
PRInt32* aReturn);
|
|
||||||
|
|
||||||
// used by:
|
|
||||||
// FileOpDirRemove()
|
|
||||||
// FileOpDirRename()
|
|
||||||
// FileOpFileCopy()
|
|
||||||
// FileOpFileMove()
|
|
||||||
// FileOpFileRename()
|
|
||||||
nsInstallFileOpItem(nsInstall* installObj,
|
|
||||||
PRInt32 aCommand,
|
|
||||||
nsFileSpec& aSrc,
|
|
||||||
nsFileSpec& aTarget,
|
|
||||||
PRInt32* aReturn);
|
|
||||||
|
|
||||||
// used by:
|
|
||||||
// FileOpDirCreate()
|
|
||||||
nsInstallFileOpItem(nsInstall* aInstallObj,
|
|
||||||
PRInt32 aCommand,
|
|
||||||
nsFileSpec& aTarget,
|
|
||||||
PRInt32* aReturn);
|
|
||||||
|
|
||||||
// used by:
|
|
||||||
// FileOpFileExecute()
|
|
||||||
nsInstallFileOpItem(nsInstall* aInstallObj,
|
|
||||||
PRInt32 aCommand,
|
|
||||||
nsFileSpec& aTarget,
|
|
||||||
nsString& aParams,
|
|
||||||
PRInt32* aReturn);
|
|
||||||
|
|
||||||
~nsInstallFileOpItem();
|
|
||||||
|
|
||||||
PRInt32 Prepare(void);
|
|
||||||
PRInt32 Complete();
|
|
||||||
char* toString();
|
|
||||||
void Abort();
|
|
||||||
float GetInstallOrder();
|
|
||||||
|
|
||||||
/* should these be protected? */
|
|
||||||
PRBool CanUninstall();
|
|
||||||
PRBool RegisterPackageNode();
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
/* Private Fields */
|
|
||||||
|
|
||||||
nsInstall* mIObj; // initiating Install object
|
|
||||||
nsFileSpec* mSrc;
|
|
||||||
nsFileSpec* mTarget;
|
|
||||||
nsString* mParams;
|
|
||||||
long mFStat;
|
|
||||||
PRInt32 mFlags;
|
|
||||||
PRInt32 mCommand;
|
|
||||||
|
|
||||||
/* Private Methods */
|
|
||||||
|
|
||||||
PRInt32 NativeFileOpDirCreate(nsFileSpec* aTarget);
|
|
||||||
PRInt32 NativeFileOpDirRemove(nsFileSpec* aTarget, PRInt32 aFlags);
|
|
||||||
PRInt32 NativeFileOpDirRename(nsFileSpec* aSrc, nsFileSpec* aTarget);
|
|
||||||
PRInt32 NativeFileOpFileCopy(nsFileSpec* aSrc, nsFileSpec* aTarget);
|
|
||||||
PRInt32 NativeFileOpFileDelete(nsFileSpec* aTarget, PRInt32 aFlags);
|
|
||||||
PRInt32 NativeFileOpFileExecute(nsFileSpec* aTarget, nsString* aParams);
|
|
||||||
PRInt32 NativeFileOpFileMove(nsFileSpec* aSrc, nsFileSpec* aTarget);
|
|
||||||
PRInt32 NativeFileOpFileRename(nsFileSpec* aSrc, nsFileSpec* aTarget);
|
|
||||||
PRInt32 NativeFileOpWinShortcutCreate();
|
|
||||||
PRInt32 NativeFileOpMacAliasCreate();
|
|
||||||
PRInt32 NativeFileOpUnixLinkCreate();
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* nsInstallFileOpItem_h__ */
|
|
||||||
|
|
||||||
@@ -1,336 +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.0 (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,
|
|
||||||
* released March 31, 1998.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* Daniel Veditz <dveditz@netscape.com>
|
|
||||||
* Douglas Turner <dougt@netscape.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "nsInstall.h"
|
|
||||||
#include "nsInstallFolder.h"
|
|
||||||
|
|
||||||
#include "nscore.h"
|
|
||||||
#include "prtypes.h"
|
|
||||||
#include "nsRepository.h"
|
|
||||||
|
|
||||||
#include "nsString.h"
|
|
||||||
#include "nsFileSpec.h"
|
|
||||||
#include "nsSpecialSystemDirectory.h"
|
|
||||||
|
|
||||||
#include "nsFileLocations.h"
|
|
||||||
#include "nsIFileLocator.h"
|
|
||||||
|
|
||||||
struct DirectoryTable
|
|
||||||
{
|
|
||||||
char * directoryName; /* The formal directory name */
|
|
||||||
PRInt32 folderEnum; /* Directory ID */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DirectoryTable DirectoryTable[] =
|
|
||||||
{
|
|
||||||
{"Plugins", 100 },
|
|
||||||
{"Program", 101 },
|
|
||||||
{"Communicator", 102 },
|
|
||||||
{"User Pick", 103 },
|
|
||||||
{"Temporary", 104 },
|
|
||||||
{"Installed", 105 },
|
|
||||||
{"Current User", 106 },
|
|
||||||
{"Preferences", 107 },
|
|
||||||
{"OS Drive", 108 },
|
|
||||||
{"file:///", 109 },
|
|
||||||
|
|
||||||
{"Components", 110 },
|
|
||||||
{"Chrome", 111 },
|
|
||||||
|
|
||||||
{"Win System", 200 },
|
|
||||||
{"Windows", 201 },
|
|
||||||
|
|
||||||
{"Mac System", 300 },
|
|
||||||
{"Mac Desktop", 301 },
|
|
||||||
{"Mac Trash", 302 },
|
|
||||||
{"Mac Startup", 303 },
|
|
||||||
{"Mac Shutdown", 304 },
|
|
||||||
{"Mac Apple Menu", 305 },
|
|
||||||
{"Mac Control Panel", 306 },
|
|
||||||
{"Mac Extension", 307 },
|
|
||||||
{"Mac Fonts", 308 },
|
|
||||||
{"Mac Preferences", 309 },
|
|
||||||
{"Mac Documents", 310 },
|
|
||||||
|
|
||||||
{"Unix Local", 400 },
|
|
||||||
{"Unix Lib", 401 },
|
|
||||||
|
|
||||||
{"", -1 }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
nsInstallFolder::nsInstallFolder(const nsString& aFolderID)
|
|
||||||
{
|
|
||||||
mFileSpec = nsnull;
|
|
||||||
SetDirectoryPath( aFolderID, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
nsInstallFolder::nsInstallFolder(const nsString& aFolderID, const nsString& aRelativePath)
|
|
||||||
{
|
|
||||||
mFileSpec = nsnull;
|
|
||||||
|
|
||||||
/*
|
|
||||||
aFolderID can be either a Folder enum in which case we merely pass it to SetDirectoryPath, or
|
|
||||||
it can be a Directory. If it is the later, it must already exist and of course be a directory
|
|
||||||
not a file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
nsFileSpec dirCheck(aFolderID);
|
|
||||||
if ( (dirCheck.Error() == NS_OK) && (dirCheck.IsDirectory()) && (dirCheck.Exists()))
|
|
||||||
{
|
|
||||||
nsString tempString = aFolderID;
|
|
||||||
tempString += aRelativePath;
|
|
||||||
mFileSpec = new nsFileSpec(tempString);
|
|
||||||
|
|
||||||
// make sure that the directory is created.
|
|
||||||
nsFileSpec(mFileSpec->GetCString(), PR_TRUE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SetDirectoryPath( aFolderID, aRelativePath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
nsInstallFolder::~nsInstallFolder()
|
|
||||||
{
|
|
||||||
if (mFileSpec != nsnull)
|
|
||||||
delete mFileSpec;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsInstallFolder::GetDirectoryPath(nsString& aDirectoryPath)
|
|
||||||
{
|
|
||||||
aDirectoryPath = "";
|
|
||||||
|
|
||||||
if (mFileSpec != nsnull)
|
|
||||||
{
|
|
||||||
// We want the a NATIVE path.
|
|
||||||
aDirectoryPath.SetString(mFileSpec->GetCString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsInstallFolder::SetDirectoryPath(const nsString& aFolderID, const nsString& aRelativePath)
|
|
||||||
{
|
|
||||||
if ( aFolderID.EqualsIgnoreCase("User Pick") )
|
|
||||||
{
|
|
||||||
PickDefaultDirectory();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ( aFolderID.EqualsIgnoreCase("Installed") )
|
|
||||||
{
|
|
||||||
mFileSpec = new nsFileSpec(aRelativePath, PR_TRUE); // creates the directories to the relative path.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PRInt32 folderDirSpecID = MapNameToEnum(aFolderID);
|
|
||||||
|
|
||||||
switch (folderDirSpecID)
|
|
||||||
{
|
|
||||||
case 100: /////////////////////////////////////////////////////////// Plugins
|
|
||||||
SetAppShellDirectory(nsSpecialFileSpec::App_PluginsDirectory );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 101: /////////////////////////////////////////////////////////// Program
|
|
||||||
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::OS_CurrentProcessDirectory ));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 102: /////////////////////////////////////////////////////////// Communicator
|
|
||||||
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::OS_CurrentProcessDirectory ));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 103: /////////////////////////////////////////////////////////// User Pick
|
|
||||||
// we should never be here.
|
|
||||||
mFileSpec = nsnull;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 104: /////////////////////////////////////////////////////////// Temporary
|
|
||||||
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::OS_TemporaryDirectory ));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 105: /////////////////////////////////////////////////////////// Installed
|
|
||||||
// we should never be here.
|
|
||||||
mFileSpec = nsnull;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 106: /////////////////////////////////////////////////////////// Current User
|
|
||||||
SetAppShellDirectory(nsSpecialFileSpec::App_UserProfileDirectory50 );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 107: /////////////////////////////////////////////////////////// Preferences
|
|
||||||
SetAppShellDirectory(nsSpecialFileSpec::App_PrefsDirectory50 );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 108: /////////////////////////////////////////////////////////// OS Drive
|
|
||||||
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::OS_DriveDirectory ));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 109: /////////////////////////////////////////////////////////// File URL
|
|
||||||
{
|
|
||||||
nsString tempFileURLString = aFolderID;
|
|
||||||
tempFileURLString += aRelativePath;
|
|
||||||
mFileSpec = new nsFileSpec( nsFileURL(tempFileURLString) );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 110: /////////////////////////////////////////////////////////// Components
|
|
||||||
SetAppShellDirectory(nsSpecialFileSpec::App_ComponentsDirectory );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 111: /////////////////////////////////////////////////////////// Chrome
|
|
||||||
SetAppShellDirectory(nsSpecialFileSpec::App_ChromeDirectory );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 200: /////////////////////////////////////////////////////////// Win System
|
|
||||||
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::Win_SystemDirectory ));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 201: /////////////////////////////////////////////////////////// Windows
|
|
||||||
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::Win_WindowsDirectory ));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 300: /////////////////////////////////////////////////////////// Mac System
|
|
||||||
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::Mac_SystemDirectory ));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 301: /////////////////////////////////////////////////////////// Mac Desktop
|
|
||||||
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::Mac_DesktopDirectory ));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 302: /////////////////////////////////////////////////////////// Mac Trash
|
|
||||||
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::Mac_TrashDirectory ));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 303: /////////////////////////////////////////////////////////// Mac Startup
|
|
||||||
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::Mac_StartupDirectory ));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 304: /////////////////////////////////////////////////////////// Mac Shutdown
|
|
||||||
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::Mac_StartupDirectory ));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 305: /////////////////////////////////////////////////////////// Mac Apple Menu
|
|
||||||
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::Mac_AppleMenuDirectory ));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 306: /////////////////////////////////////////////////////////// Mac Control Panel
|
|
||||||
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::Mac_ControlPanelDirectory ));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 307: /////////////////////////////////////////////////////////// Mac Extension
|
|
||||||
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::Mac_ExtensionDirectory ));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 308: /////////////////////////////////////////////////////////// Mac Fonts
|
|
||||||
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::Mac_FontsDirectory ));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 309: /////////////////////////////////////////////////////////// Mac Preferences
|
|
||||||
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::Mac_PreferencesDirectory ));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 310: /////////////////////////////////////////////////////////// Mac Documents
|
|
||||||
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::Mac_DocumentsDirectory ));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 400: /////////////////////////////////////////////////////////// Unix Local
|
|
||||||
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::Unix_LocalDirectory ));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 401: /////////////////////////////////////////////////////////// Unix Lib
|
|
||||||
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::Unix_LibDirectory ));
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
case -1:
|
|
||||||
default:
|
|
||||||
mFileSpec = nsnull;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#ifndef XP_MAC
|
|
||||||
if (aRelativePath.Length() > 0)
|
|
||||||
{
|
|
||||||
nsString tempPath(aRelativePath);
|
|
||||||
|
|
||||||
if (aRelativePath.Last() != '/' || aRelativePath.Last() != '\\')
|
|
||||||
tempPath += '/';
|
|
||||||
|
|
||||||
*mFileSpec += tempPath;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
// make sure that the directory is created.
|
|
||||||
nsFileSpec(mFileSpec->GetCString(), PR_TRUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsInstallFolder::PickDefaultDirectory()
|
|
||||||
{
|
|
||||||
//FIX: Need to put up a dialog here and set mFileSpec
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* MapNameToEnum
|
|
||||||
* maps name from the directory table to its enum */
|
|
||||||
PRInt32
|
|
||||||
nsInstallFolder::MapNameToEnum(const nsString& name)
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
if ( name == "null")
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
while ( DirectoryTable[i].directoryName[0] != 0 )
|
|
||||||
{
|
|
||||||
if ( name.EqualsIgnoreCase(DirectoryTable[i].directoryName) )
|
|
||||||
return DirectoryTable[i].folderEnum;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static NS_DEFINE_IID(kFileLocatorIID, NS_IFILELOCATOR_IID);
|
|
||||||
static NS_DEFINE_IID(kFileLocatorCID, NS_FILELOCATOR_CID);
|
|
||||||
|
|
||||||
void
|
|
||||||
nsInstallFolder::SetAppShellDirectory(PRUint32 value)
|
|
||||||
{
|
|
||||||
nsIFileLocator * appShellLocator;
|
|
||||||
|
|
||||||
nsresult rv = nsComponentManager::CreateInstance(kFileLocatorCID,
|
|
||||||
nsnull,
|
|
||||||
kFileLocatorIID,
|
|
||||||
(void**) &appShellLocator);
|
|
||||||
|
|
||||||
if ( NS_SUCCEEDED(rv) )
|
|
||||||
{
|
|
||||||
mFileSpec = new nsFileSpec();
|
|
||||||
appShellLocator->GetFileLocation(value, mFileSpec);
|
|
||||||
NS_RELEASE(appShellLocator);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,58 +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.0 (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,
|
|
||||||
* released March 31, 1998.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* Daniel Veditz <dveditz@netscape.com>
|
|
||||||
* Douglas Turner <dougt@netscape.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef __NS_INSTALLFOLDER_H__
|
|
||||||
#define __NS_INSTALLFOLDER_H__
|
|
||||||
|
|
||||||
#include "nscore.h"
|
|
||||||
#include "prtypes.h"
|
|
||||||
|
|
||||||
#include "nsString.h"
|
|
||||||
#include "nsFileSpec.h"
|
|
||||||
#include "nsSpecialSystemDirectory.h"
|
|
||||||
|
|
||||||
class nsInstallFolder
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
nsInstallFolder(const nsString& aFolderID);
|
|
||||||
nsInstallFolder(const nsString& aFolderID, const nsString& aRelativePath);
|
|
||||||
virtual ~nsInstallFolder();
|
|
||||||
|
|
||||||
void GetDirectoryPath(nsString& aDirectoryPath);
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
nsFileSpec* mFileSpec;
|
|
||||||
|
|
||||||
void SetDirectoryPath(const nsString& aFolderID, const nsString& aRelativePath);
|
|
||||||
void PickDefaultDirectory();
|
|
||||||
PRInt32 MapNameToEnum(const nsString& name);
|
|
||||||
void SetAppShellDirectory(PRUint32 value);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,52 +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.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 nsInstallObject_h__
|
|
||||||
#define nsInstallObject_h__
|
|
||||||
|
|
||||||
#include "prtypes.h"
|
|
||||||
|
|
||||||
class nsInstall;
|
|
||||||
|
|
||||||
class nsInstallObject
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/* Public Methods */
|
|
||||||
nsInstallObject(nsInstall* inInstall) {mInstall = inInstall; }
|
|
||||||
|
|
||||||
/* Override with your set-up action */
|
|
||||||
virtual PRInt32 Prepare() = 0;
|
|
||||||
|
|
||||||
/* Override with your Completion action */
|
|
||||||
virtual PRInt32 Complete() = 0;
|
|
||||||
|
|
||||||
/* Override with an explanatory string for the progress dialog */
|
|
||||||
virtual char* toString() = 0;
|
|
||||||
|
|
||||||
/* Override with your clean-up function */
|
|
||||||
virtual void Abort() = 0;
|
|
||||||
|
|
||||||
/* should these be protected? */
|
|
||||||
virtual PRBool CanUninstall() = 0;
|
|
||||||
virtual PRBool RegisterPackageNode() = 0;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
nsInstall* mInstall;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* nsInstallObject_h__ */
|
|
||||||
@@ -1,986 +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.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 "nsFileSpec.h"
|
|
||||||
#include "prmem.h"
|
|
||||||
#include "nsInstall.h"
|
|
||||||
#include "nsInstallPatch.h"
|
|
||||||
#include "nsInstallResources.h"
|
|
||||||
#include "nsIDOMInstallVersion.h"
|
|
||||||
#include "zlib.h"
|
|
||||||
|
|
||||||
#include "gdiff.h"
|
|
||||||
|
|
||||||
#include "VerReg.h"
|
|
||||||
#include "ScheduledTasks.h"
|
|
||||||
#include "plstr.h"
|
|
||||||
#include "xp_file.h" /* for XP_PlatformFileToURL */
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef XP_MAC
|
|
||||||
#include "PatchableAppleSingle.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define BUFSIZE 32768
|
|
||||||
#define OPSIZE 1
|
|
||||||
#define MAXCMDSIZE 12
|
|
||||||
#define SRCFILE 0
|
|
||||||
#define OUTFILE 1
|
|
||||||
|
|
||||||
#define getshort(s) (uint16)( ((uchar)*(s) << 8) + ((uchar)*((s)+1)) )
|
|
||||||
|
|
||||||
#define getlong(s) \
|
|
||||||
(uint32)( ((uchar)*(s) << 24) + ((uchar)*((s)+1) << 16 ) + \
|
|
||||||
((uchar)*((s)+2) << 8) + ((uchar)*((s)+3)) )
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int32 gdiff_parseHeader( pDIFFDATA dd );
|
|
||||||
static int32 gdiff_validateFile( pDIFFDATA dd, int file );
|
|
||||||
static int32 gdiff_valCRC32( pDIFFDATA dd, PRFileDesc* fh, uint32 chksum );
|
|
||||||
static int32 gdiff_ApplyPatch( pDIFFDATA dd );
|
|
||||||
static int32 gdiff_getdiff( pDIFFDATA dd, uchar *buffer, uint32 length );
|
|
||||||
static int32 gdiff_add( pDIFFDATA dd, uint32 count );
|
|
||||||
static int32 gdiff_copy( pDIFFDATA dd, uint32 position, uint32 count );
|
|
||||||
static int32 gdiff_validateFile( pDIFFDATA dd, int file );
|
|
||||||
|
|
||||||
|
|
||||||
nsInstallPatch::nsInstallPatch( nsInstall* inInstall,
|
|
||||||
const nsString& inVRName,
|
|
||||||
const nsString& inVInfo,
|
|
||||||
const nsString& inJarLocation,
|
|
||||||
PRInt32 *error)
|
|
||||||
|
|
||||||
: nsInstallObject(inInstall)
|
|
||||||
{
|
|
||||||
char tempTargetFile[MAXREGPATHLEN];
|
|
||||||
char* tempVersionString = inVRName.ToNewCString();
|
|
||||||
|
|
||||||
PRInt32 err = VR_GetPath(tempVersionString, MAXREGPATHLEN, tempTargetFile );
|
|
||||||
|
|
||||||
delete [] tempVersionString;
|
|
||||||
|
|
||||||
if (err != REGERR_OK)
|
|
||||||
{
|
|
||||||
*error = nsInstall::NO_SUCH_COMPONENT;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
nsString folderSpec(tempTargetFile);
|
|
||||||
|
|
||||||
mPatchFile = nsnull;
|
|
||||||
mTargetFile = nsnull;
|
|
||||||
mPatchedFile = nsnull;
|
|
||||||
mRegistryName = new nsString(inVRName);
|
|
||||||
mJarLocation = new nsString(inJarLocation);
|
|
||||||
mTargetFile = new nsFileSpec(folderSpec);
|
|
||||||
|
|
||||||
mVersionInfo = new nsInstallVersion();
|
|
||||||
|
|
||||||
mVersionInfo->Init(inVInfo);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
nsInstallPatch::nsInstallPatch( nsInstall* inInstall,
|
|
||||||
const nsString& inVRName,
|
|
||||||
const nsString& inVInfo,
|
|
||||||
const nsString& inJarLocation,
|
|
||||||
const nsString& folderSpec,
|
|
||||||
const nsString& inPartialPath,
|
|
||||||
PRInt32 *error)
|
|
||||||
|
|
||||||
: nsInstallObject(inInstall)
|
|
||||||
{
|
|
||||||
if ((inInstall == nsnull) || (inVRName == "null") || (inJarLocation == "null"))
|
|
||||||
{
|
|
||||||
*error = nsInstall::INVALID_ARGUMENTS;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mPatchFile = nsnull;
|
|
||||||
mTargetFile = nsnull;
|
|
||||||
mPatchedFile = nsnull;
|
|
||||||
mRegistryName = new nsString(inVRName);
|
|
||||||
mJarLocation = new nsString(inJarLocation);
|
|
||||||
mVersionInfo = new nsInstallVersion();
|
|
||||||
|
|
||||||
mVersionInfo->Init(inVInfo);
|
|
||||||
|
|
||||||
mTargetFile = new nsFileSpec(folderSpec);
|
|
||||||
if(inPartialPath != "null")
|
|
||||||
*mTargetFile += inPartialPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsInstallPatch::~nsInstallPatch()
|
|
||||||
{
|
|
||||||
if (mVersionInfo)
|
|
||||||
delete mVersionInfo;
|
|
||||||
|
|
||||||
if (mTargetFile)
|
|
||||||
delete mTargetFile;
|
|
||||||
|
|
||||||
if (mJarLocation)
|
|
||||||
delete mJarLocation;
|
|
||||||
|
|
||||||
if (mRegistryName)
|
|
||||||
delete mRegistryName;
|
|
||||||
|
|
||||||
if (mPatchedFile)
|
|
||||||
delete mPatchedFile;
|
|
||||||
|
|
||||||
if (mPatchFile)
|
|
||||||
delete mPatchFile;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PRInt32 nsInstallPatch::Prepare()
|
|
||||||
{
|
|
||||||
PRInt32 err;
|
|
||||||
PRBool deleteOldSrc;
|
|
||||||
|
|
||||||
if (mTargetFile == nsnull)
|
|
||||||
return nsInstall::INVALID_ARGUMENTS;
|
|
||||||
|
|
||||||
if (mTargetFile->Exists())
|
|
||||||
{
|
|
||||||
if (mTargetFile->IsFile())
|
|
||||||
{
|
|
||||||
err = nsInstall::SUCCESS;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
err = nsInstall::FILE_IS_DIRECTORY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
err = nsInstall::FILE_DOES_NOT_EXIST;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err != nsInstall::SUCCESS)
|
|
||||||
{
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = mInstall->ExtractFileFromJar(*mJarLocation, mTargetFile, &mPatchFile);
|
|
||||||
|
|
||||||
|
|
||||||
nsFileSpec *fileName = nsnull;
|
|
||||||
nsVoidKey ikey( HashFilePath( nsFilePath(*mTargetFile) ) );
|
|
||||||
|
|
||||||
mInstall->GetPatch(&ikey, fileName);
|
|
||||||
|
|
||||||
if (fileName != nsnull)
|
|
||||||
{
|
|
||||||
deleteOldSrc = PR_TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fileName = mTargetFile;
|
|
||||||
deleteOldSrc = PR_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = NativePatch( *fileName, // the file to patch
|
|
||||||
*mPatchFile, // the patch that was extracted from the jarfile
|
|
||||||
&mPatchedFile); // the new patched file
|
|
||||||
|
|
||||||
if (err != nsInstall::SUCCESS)
|
|
||||||
{
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
PR_ASSERT(mPatchedFile != nsnull);
|
|
||||||
mInstall->AddPatch(&ikey, mPatchedFile );
|
|
||||||
|
|
||||||
if ( deleteOldSrc )
|
|
||||||
{
|
|
||||||
DeleteFileNowOrSchedule(*fileName );
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRInt32 nsInstallPatch::Complete()
|
|
||||||
{
|
|
||||||
if ((mInstall == nsnull) || (mVersionInfo == nsnull) || (mPatchedFile == nsnull) || (mTargetFile == nsnull))
|
|
||||||
{
|
|
||||||
return nsInstall::INVALID_ARGUMENTS;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRInt32 err = nsInstall::SUCCESS;
|
|
||||||
|
|
||||||
nsFileSpec *fileName = nsnull;
|
|
||||||
nsVoidKey ikey( HashFilePath( nsFilePath(*mTargetFile) ) );
|
|
||||||
|
|
||||||
mInstall->GetPatch(&ikey, fileName);
|
|
||||||
|
|
||||||
if (fileName != nsnull && (*fileName == *mPatchedFile) )
|
|
||||||
{
|
|
||||||
// the patch has not been superceded--do final replacement
|
|
||||||
err = ReplaceFileNowOrSchedule( *mTargetFile, *mPatchedFile);
|
|
||||||
if ( 0 == err || nsInstall::REBOOT_NEEDED == err )
|
|
||||||
{
|
|
||||||
nsString tempVersionString;
|
|
||||||
mVersionInfo->ToString(tempVersionString);
|
|
||||||
|
|
||||||
char* tempRegName = mRegistryName->ToNewCString();
|
|
||||||
char* tempVersion = tempVersionString.ToNewCString();
|
|
||||||
|
|
||||||
err = VR_Install( tempRegName,
|
|
||||||
(char*) (const char *) nsNSPRPath(*mTargetFile),
|
|
||||||
tempVersion,
|
|
||||||
PR_FALSE );
|
|
||||||
|
|
||||||
delete [] tempRegName;
|
|
||||||
delete [] tempVersion;
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
err = nsInstall::UNEXPECTED_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// nothing -- old intermediate patched file was
|
|
||||||
// deleted by a superceding patch
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsInstallPatch::Abort()
|
|
||||||
{
|
|
||||||
nsFileSpec *fileName = nsnull;
|
|
||||||
nsVoidKey ikey( HashFilePath( nsFilePath(*mTargetFile) ) );
|
|
||||||
|
|
||||||
mInstall->GetPatch(&ikey, fileName);
|
|
||||||
|
|
||||||
if (fileName != nsnull && (*fileName == *mPatchedFile) )
|
|
||||||
{
|
|
||||||
DeleteFileNowOrSchedule( *mPatchedFile );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char* nsInstallPatch::toString()
|
|
||||||
{
|
|
||||||
char* buffer = new char[1024];
|
|
||||||
|
|
||||||
// FIX! sprintf( buffer, nsInstallResources::GetPatchFileString(), mPatchedFile->GetCString());
|
|
||||||
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PRBool
|
|
||||||
nsInstallPatch::CanUninstall()
|
|
||||||
{
|
|
||||||
return PR_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRBool
|
|
||||||
nsInstallPatch::RegisterPackageNode()
|
|
||||||
{
|
|
||||||
return PR_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PRInt32
|
|
||||||
nsInstallPatch::NativePatch(const nsFileSpec &sourceFile, const nsFileSpec &patchFile, nsFileSpec **newFile)
|
|
||||||
{
|
|
||||||
|
|
||||||
DIFFDATA *dd;
|
|
||||||
PRInt32 status = GDIFF_ERR_MEM;
|
|
||||||
char *tmpurl = NULL;
|
|
||||||
char *realfile = PL_strdup(nsNSPRPath(sourceFile)); // needs to be sourceFile!!!
|
|
||||||
nsFileSpec outFileSpec = sourceFile;
|
|
||||||
|
|
||||||
dd = (DIFFDATA *)PR_Calloc( 1, sizeof(DIFFDATA));
|
|
||||||
if (dd != NULL)
|
|
||||||
{
|
|
||||||
dd->databuf = (uchar*)PR_Malloc(BUFSIZE);
|
|
||||||
if (dd->databuf == NULL)
|
|
||||||
{
|
|
||||||
status = GDIFF_ERR_MEM;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
dd->bufsize = BUFSIZE;
|
|
||||||
|
|
||||||
// validate patch header & check for special instructions
|
|
||||||
dd->fDiff = PR_Open (nsNSPRPath(patchFile), PR_RDONLY, 0666);
|
|
||||||
|
|
||||||
|
|
||||||
if (dd->fDiff != NULL)
|
|
||||||
{
|
|
||||||
status = gdiff_parseHeader(dd);
|
|
||||||
} else {
|
|
||||||
status = GDIFF_ERR_ACCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef dono
|
|
||||||
#ifdef WIN32
|
|
||||||
|
|
||||||
/* unbind Win32 images */
|
|
||||||
if ( dd->bWin32BoundImage && status == GDIFF_OK ) {
|
|
||||||
tmpurl = WH_TempName( xpURL, NULL );
|
|
||||||
if ( tmpurl != NULL ) {
|
|
||||||
if (su_unbind( srcfile, srctype, tmpurl, xpURL ))
|
|
||||||
{
|
|
||||||
PL_strfree(realfile);
|
|
||||||
realfile = tmpurl;
|
|
||||||
realtype = xpURL;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
status = GDIFF_ERR_MEM;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef XP_MAC
|
|
||||||
|
|
||||||
if ( dd->bMacAppleSingle && status == GDIFF_OK )
|
|
||||||
{
|
|
||||||
// create a tmp file, so that we can AppleSingle the src file
|
|
||||||
nsSpecialSystemDirectory tempMacFile(nsSpecialSystemDirectory::OS_TemporaryDirectory);
|
|
||||||
nsString srcName = sourceFile.GetLeafName();
|
|
||||||
tempMacFile.SetLeafName(srcName);
|
|
||||||
tempMacFile.MakeUnique();
|
|
||||||
|
|
||||||
// Encode!
|
|
||||||
// Encode src file, and put into temp file
|
|
||||||
FSSpec sourceSpec = sourceFile.GetFSSpec();
|
|
||||||
FSSpec tempSpec = tempMacFile.GetFSSpec();
|
|
||||||
|
|
||||||
status = PAS_EncodeFile(&sourceSpec, &tempSpec);
|
|
||||||
|
|
||||||
if (status == noErr)
|
|
||||||
{
|
|
||||||
// set
|
|
||||||
PL_strfree(realfile);
|
|
||||||
realfile = PL_strdup(nsNSPRPath(tempMacFile));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (status != NS_OK)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
// make a unique file at the same location of our source file (FILENAME-ptch.EXT)
|
|
||||||
nsString patchFileName = "-ptch";
|
|
||||||
nsString newFileName = sourceFile.GetLeafName();
|
|
||||||
|
|
||||||
PRInt32 index;
|
|
||||||
if ((index = newFileName.RFind(".")) > 0)
|
|
||||||
{
|
|
||||||
nsString extention;
|
|
||||||
nsString fileName;
|
|
||||||
newFileName.Right(extention, (newFileName.Length() - index) );
|
|
||||||
newFileName.Left(fileName, (newFileName.Length() - (newFileName.Length() - index)));
|
|
||||||
newFileName = fileName + patchFileName + extention;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
newFileName += patchFileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
outFileSpec.SetLeafName(newFileName); //????
|
|
||||||
outFileSpec.MakeUnique();
|
|
||||||
|
|
||||||
char *outFile = PL_strdup(nsNSPRPath(outFileSpec));
|
|
||||||
|
|
||||||
// apply patch to the source file
|
|
||||||
dd->fSrc = PR_Open ( realfile, PR_RDONLY, 0666);
|
|
||||||
dd->fOut = PR_Open ( outFile, PR_RDWR|PR_CREATE_FILE|PR_TRUNCATE, 0666);
|
|
||||||
|
|
||||||
if (dd->fSrc != NULL && dd->fOut != NULL)
|
|
||||||
{
|
|
||||||
status = gdiff_validateFile (dd, SRCFILE);
|
|
||||||
|
|
||||||
// specify why diff failed
|
|
||||||
if (status == GDIFF_ERR_CHECKSUM)
|
|
||||||
status = GDIFF_ERR_CHECKSUM_TARGET;
|
|
||||||
|
|
||||||
if (status == GDIFF_OK)
|
|
||||||
status = gdiff_ApplyPatch(dd);
|
|
||||||
|
|
||||||
if (status == GDIFF_OK)
|
|
||||||
status = gdiff_validateFile (dd, OUTFILE);
|
|
||||||
|
|
||||||
if (status == GDIFF_ERR_CHECKSUM)
|
|
||||||
status = GDIFF_ERR_CHECKSUM_RESULT;
|
|
||||||
|
|
||||||
if (status == GDIFF_OK)
|
|
||||||
{
|
|
||||||
*newFile = &outFileSpec;
|
|
||||||
if ( outFile != nsnull)
|
|
||||||
PL_strfree( outFile );
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
status = GDIFF_ERR_ACCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef XP_MAC
|
|
||||||
if ( dd->bMacAppleSingle && status == GDIFF_OK )
|
|
||||||
{
|
|
||||||
// create another file, so that we can decode somewhere
|
|
||||||
nsFileSpec anotherName = outFileSpec;
|
|
||||||
anotherName.MakeUnique();
|
|
||||||
|
|
||||||
// Close the out file so that we can read it
|
|
||||||
PR_Close( dd->fOut );
|
|
||||||
dd->fOut = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
FSSpec outSpec = outFileSpec.GetFSSpec();
|
|
||||||
FSSpec anotherSpec = anotherName.GetFSSpec();
|
|
||||||
|
|
||||||
|
|
||||||
status = PAS_DecodeFile(&outSpec, &anotherSpec);
|
|
||||||
if (status != noErr)
|
|
||||||
{
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsFileSpec parent;
|
|
||||||
|
|
||||||
outFileSpec.GetParent(parent);
|
|
||||||
|
|
||||||
outFileSpec.Delete(PR_FALSE);
|
|
||||||
anotherName.Copy(parent);
|
|
||||||
|
|
||||||
*newFile = &anotherName;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
if ( dd != NULL )
|
|
||||||
{
|
|
||||||
if ( dd->fSrc != nsnull )
|
|
||||||
PR_Close( dd->fSrc );
|
|
||||||
|
|
||||||
|
|
||||||
if ( dd->fDiff != nsnull )
|
|
||||||
PR_Close( dd->fDiff );
|
|
||||||
|
|
||||||
if ( dd->fOut != nsnull )
|
|
||||||
{
|
|
||||||
PR_Close( dd->fOut );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( status != GDIFF_OK )
|
|
||||||
//XP_FileRemove( outfile, outtype );
|
|
||||||
newFile = NULL;
|
|
||||||
|
|
||||||
PR_FREEIF( dd->databuf );
|
|
||||||
PR_FREEIF( dd->oldChecksum );
|
|
||||||
PR_FREEIF( dd->newChecksum );
|
|
||||||
PR_DELETE(dd);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( tmpurl != NULL ) {
|
|
||||||
//XP_FileRemove( tmpurl, xpURL );
|
|
||||||
tmpurl = NULL;
|
|
||||||
PR_DELETE( tmpurl );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* lets map any GDIFF error to nice SU errors */
|
|
||||||
|
|
||||||
switch (status)
|
|
||||||
{
|
|
||||||
case GDIFF_OK:
|
|
||||||
break;
|
|
||||||
case GDIFF_ERR_HEADER:
|
|
||||||
case GDIFF_ERR_BADDIFF:
|
|
||||||
case GDIFF_ERR_OPCODE:
|
|
||||||
case GDIFF_ERR_CHKSUMTYPE:
|
|
||||||
status = nsInstall::PATCH_BAD_DIFF;
|
|
||||||
break;
|
|
||||||
case GDIFF_ERR_CHECKSUM_TARGET:
|
|
||||||
status = nsInstall::PATCH_BAD_CHECKSUM_TARGET;
|
|
||||||
break;
|
|
||||||
case GDIFF_ERR_CHECKSUM_RESULT:
|
|
||||||
status = nsInstall::PATCH_BAD_CHECKSUM_RESULT;
|
|
||||||
break;
|
|
||||||
case GDIFF_ERR_OLDFILE:
|
|
||||||
case GDIFF_ERR_ACCESS:
|
|
||||||
case GDIFF_ERR_MEM:
|
|
||||||
case GDIFF_ERR_UNKNOWN:
|
|
||||||
default:
|
|
||||||
status = nsInstall::UNEXPECTED_ERROR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
|
||||||
|
|
||||||
// return -1; //old return value
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void*
|
|
||||||
nsInstallPatch::HashFilePath(const nsFilePath& aPath)
|
|
||||||
{
|
|
||||||
PRUint32 rv = 0;
|
|
||||||
|
|
||||||
char* cPath = PL_strdup(nsNSPRPath(aPath));
|
|
||||||
|
|
||||||
if(cPath != nsnull)
|
|
||||||
{
|
|
||||||
char ch;
|
|
||||||
char* filePath = PL_strdup(cPath);
|
|
||||||
PRUint32 cnt=0;
|
|
||||||
|
|
||||||
while ((ch = *filePath++) != 0)
|
|
||||||
{
|
|
||||||
// FYI: rv = rv*37 + ch
|
|
||||||
rv = ((rv << 5) + (rv << 2) + rv) + ch;
|
|
||||||
cnt++;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (PRUint32 i=0; i<=cnt; i++)
|
|
||||||
*filePath--;
|
|
||||||
PL_strfree(filePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
PL_strfree(cPath);
|
|
||||||
|
|
||||||
return (void*)rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------
|
|
||||||
* gdiff_parseHeader()
|
|
||||||
*
|
|
||||||
* reads and validates the GDIFF header info
|
|
||||||
*---------------------------------------------------------
|
|
||||||
*/
|
|
||||||
static
|
|
||||||
int32 gdiff_parseHeader( pDIFFDATA dd )
|
|
||||||
{
|
|
||||||
int32 err = GDIFF_OK;
|
|
||||||
uint8 cslen;
|
|
||||||
uint8 oldcslen;
|
|
||||||
uint8 newcslen;
|
|
||||||
uint32 nRead;
|
|
||||||
uchar header[GDIFF_HEADERSIZE];
|
|
||||||
|
|
||||||
/* Read the fixed-size part of the header */
|
|
||||||
|
|
||||||
nRead = PR_Read (dd->fDiff, header, GDIFF_HEADERSIZE);
|
|
||||||
if ( nRead != GDIFF_HEADERSIZE ||
|
|
||||||
memcmp( header, GDIFF_MAGIC, GDIFF_MAGIC_LEN ) != 0 ||
|
|
||||||
header[GDIFF_VER_POS] != GDIFF_VER )
|
|
||||||
{
|
|
||||||
err = GDIFF_ERR_HEADER;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* get the checksum information */
|
|
||||||
|
|
||||||
dd->checksumType = header[GDIFF_CS_POS];
|
|
||||||
cslen = header[GDIFF_CSLEN_POS];
|
|
||||||
|
|
||||||
if ( cslen > 0 )
|
|
||||||
{
|
|
||||||
oldcslen = cslen / 2;
|
|
||||||
newcslen = cslen - oldcslen;
|
|
||||||
PR_ASSERT( newcslen == oldcslen );
|
|
||||||
|
|
||||||
dd->checksumLength = oldcslen;
|
|
||||||
dd->oldChecksum = (uchar*)PR_MALLOC(oldcslen);
|
|
||||||
dd->newChecksum = (uchar*)PR_MALLOC(newcslen);
|
|
||||||
|
|
||||||
if ( dd->oldChecksum != NULL && dd->newChecksum != NULL )
|
|
||||||
{
|
|
||||||
nRead = PR_Read (dd->fDiff, dd->oldChecksum, oldcslen);
|
|
||||||
if ( nRead == oldcslen )
|
|
||||||
{
|
|
||||||
nRead = PR_Read (dd->fDiff, dd->newChecksum, newcslen);
|
|
||||||
if ( nRead != newcslen ) {
|
|
||||||
err = GDIFF_ERR_HEADER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
err = GDIFF_ERR_HEADER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
err = GDIFF_ERR_MEM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* get application data, if any */
|
|
||||||
|
|
||||||
if ( err == GDIFF_OK )
|
|
||||||
{
|
|
||||||
uint32 appdataSize;
|
|
||||||
uchar *buf;
|
|
||||||
uchar lenbuf[GDIFF_APPDATALEN];
|
|
||||||
|
|
||||||
nRead = PR_Read(dd->fDiff, lenbuf, GDIFF_APPDATALEN);
|
|
||||||
if ( nRead == GDIFF_APPDATALEN )
|
|
||||||
{
|
|
||||||
appdataSize = getlong(lenbuf);
|
|
||||||
|
|
||||||
if ( appdataSize > 0 )
|
|
||||||
{
|
|
||||||
buf = (uchar *)PR_MALLOC( appdataSize );
|
|
||||||
|
|
||||||
if ( buf != NULL )
|
|
||||||
{
|
|
||||||
nRead = PR_Read (dd->fDiff, buf, appdataSize);
|
|
||||||
if ( nRead == appdataSize )
|
|
||||||
{
|
|
||||||
if ( 0 == memcmp( buf, APPFLAG_W32BOUND, appdataSize ) )
|
|
||||||
dd->bWin32BoundImage = TRUE;
|
|
||||||
|
|
||||||
if ( 0 == memcmp( buf, APPFLAG_APPLESINGLE, appdataSize ) )
|
|
||||||
dd->bMacAppleSingle = TRUE;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
err = GDIFF_ERR_HEADER;
|
|
||||||
}
|
|
||||||
|
|
||||||
PR_DELETE( buf );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
err = GDIFF_ERR_MEM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
err = GDIFF_ERR_HEADER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (err);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------
|
|
||||||
* gdiff_validateFile()
|
|
||||||
*
|
|
||||||
* computes the checksum of the file and compares it to
|
|
||||||
* the value stored in the GDIFF header
|
|
||||||
*---------------------------------------------------------
|
|
||||||
*/
|
|
||||||
static
|
|
||||||
int32 gdiff_validateFile( pDIFFDATA dd, int file )
|
|
||||||
{
|
|
||||||
int32 result;
|
|
||||||
PRFileDesc* fh;
|
|
||||||
uchar* chksum;
|
|
||||||
|
|
||||||
/* which file are we dealing with? */
|
|
||||||
if ( file == SRCFILE ) {
|
|
||||||
fh = dd->fSrc;
|
|
||||||
chksum = dd->oldChecksum;
|
|
||||||
}
|
|
||||||
else { /* OUTFILE */
|
|
||||||
fh = dd->fOut;
|
|
||||||
chksum = dd->newChecksum;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* make sure file's at beginning */
|
|
||||||
PR_Seek( fh, 0, PR_SEEK_SET );
|
|
||||||
|
|
||||||
/* calculate appropriate checksum */
|
|
||||||
switch (dd->checksumType)
|
|
||||||
{
|
|
||||||
case GDIFF_CS_NONE:
|
|
||||||
result = GDIFF_OK;
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
case GDIFF_CS_CRC32:
|
|
||||||
if ( dd->checksumLength == CRC32_LEN )
|
|
||||||
result = gdiff_valCRC32( dd, fh, getlong(chksum) );
|
|
||||||
else
|
|
||||||
result = GDIFF_ERR_HEADER;
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
case GDIFF_CS_MD5:
|
|
||||||
|
|
||||||
|
|
||||||
case GDIFF_CS_SHA:
|
|
||||||
|
|
||||||
|
|
||||||
default:
|
|
||||||
/* unsupported checksum type */
|
|
||||||
result = GDIFF_ERR_CHKSUMTYPE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* reset file position to beginning and return status */
|
|
||||||
PR_Seek( fh, 0, PR_SEEK_SET );
|
|
||||||
return (result);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------
|
|
||||||
* gdiff_valCRC32()
|
|
||||||
*
|
|
||||||
* computes the checksum of the file and compares it to
|
|
||||||
* the passed in checksum. Assumes file is positioned at
|
|
||||||
* beginning.
|
|
||||||
*---------------------------------------------------------
|
|
||||||
*/
|
|
||||||
static
|
|
||||||
int32 gdiff_valCRC32( pDIFFDATA dd, PRFileDesc* fh, uint32 chksum )
|
|
||||||
{
|
|
||||||
uint32 crc;
|
|
||||||
uint32 nRead;
|
|
||||||
|
|
||||||
crc = crc32(0L, Z_NULL, 0);
|
|
||||||
|
|
||||||
nRead = PR_Read (fh, dd->databuf, dd->bufsize);
|
|
||||||
while ( nRead > 0 )
|
|
||||||
{
|
|
||||||
crc = crc32( crc, dd->databuf, nRead );
|
|
||||||
nRead = PR_Read (fh, dd->databuf, dd->bufsize);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( crc == chksum )
|
|
||||||
return GDIFF_OK;
|
|
||||||
else
|
|
||||||
return GDIFF_ERR_CHECKSUM;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------
|
|
||||||
* gdiff_ApplyPatch()
|
|
||||||
*
|
|
||||||
* Combines patch data with source file to produce the
|
|
||||||
* new target file. Assumes all three files have been
|
|
||||||
* opened, GDIFF header read, and all other setup complete
|
|
||||||
*
|
|
||||||
* The GDIFF patch is processed sequentially which random
|
|
||||||
* access is neccessary for the source file.
|
|
||||||
*---------------------------------------------------------
|
|
||||||
*/
|
|
||||||
static
|
|
||||||
int32 gdiff_ApplyPatch( pDIFFDATA dd )
|
|
||||||
{
|
|
||||||
int32 err;
|
|
||||||
XP_Bool done;
|
|
||||||
uint32 position;
|
|
||||||
uint32 count;
|
|
||||||
uchar opcode;
|
|
||||||
uchar cmdbuf[MAXCMDSIZE];
|
|
||||||
|
|
||||||
done = FALSE;
|
|
||||||
while ( !done ) {
|
|
||||||
err = gdiff_getdiff( dd, &opcode, OPSIZE );
|
|
||||||
if ( err != GDIFF_OK )
|
|
||||||
break;
|
|
||||||
|
|
||||||
switch (opcode)
|
|
||||||
{
|
|
||||||
case ENDDIFF:
|
|
||||||
done = TRUE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ADD16:
|
|
||||||
err = gdiff_getdiff( dd, cmdbuf, ADD16SIZE );
|
|
||||||
if ( err == GDIFF_OK ) {
|
|
||||||
err = gdiff_add( dd, getshort( cmdbuf ) );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ADD32:
|
|
||||||
err = gdiff_getdiff( dd, cmdbuf, ADD32SIZE );
|
|
||||||
if ( err == GDIFF_OK ) {
|
|
||||||
err = gdiff_add( dd, getlong( cmdbuf ) );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case COPY16BYTE:
|
|
||||||
err = gdiff_getdiff( dd, cmdbuf, COPY16BYTESIZE );
|
|
||||||
if ( err == GDIFF_OK ) {
|
|
||||||
position = getshort( cmdbuf );
|
|
||||||
count = *(cmdbuf + sizeof(short));
|
|
||||||
err = gdiff_copy( dd, position, count );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case COPY16SHORT:
|
|
||||||
err = gdiff_getdiff( dd, cmdbuf, COPY16SHORTSIZE );
|
|
||||||
if ( err == GDIFF_OK ) {
|
|
||||||
position = getshort( cmdbuf );
|
|
||||||
count = getshort(cmdbuf + sizeof(short));
|
|
||||||
err = gdiff_copy( dd, position, count );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case COPY16LONG:
|
|
||||||
err = gdiff_getdiff( dd, cmdbuf, COPY16LONGSIZE );
|
|
||||||
if ( err == GDIFF_OK ) {
|
|
||||||
position = getshort( cmdbuf );
|
|
||||||
count = getlong(cmdbuf + sizeof(short));
|
|
||||||
err = gdiff_copy( dd, position, count );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case COPY32BYTE:
|
|
||||||
err = gdiff_getdiff( dd, cmdbuf, COPY32BYTESIZE );
|
|
||||||
if ( err == GDIFF_OK ) {
|
|
||||||
position = getlong( cmdbuf );
|
|
||||||
count = *(cmdbuf + sizeof(long));
|
|
||||||
err = gdiff_copy( dd, position, count );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case COPY32SHORT:
|
|
||||||
err = gdiff_getdiff( dd, cmdbuf, COPY32SHORTSIZE );
|
|
||||||
if ( err == GDIFF_OK ) {
|
|
||||||
position = getlong( cmdbuf );
|
|
||||||
count = getshort(cmdbuf + sizeof(long));
|
|
||||||
err = gdiff_copy( dd, position, count );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case COPY32LONG:
|
|
||||||
err = gdiff_getdiff( dd, cmdbuf, COPY32LONGSIZE );
|
|
||||||
if ( err == GDIFF_OK ) {
|
|
||||||
position = getlong( cmdbuf );
|
|
||||||
count = getlong(cmdbuf + sizeof(long));
|
|
||||||
err = gdiff_copy( dd, position, count );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case COPY64:
|
|
||||||
/* we don't support 64-bit file positioning yet */
|
|
||||||
err = GDIFF_ERR_OPCODE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
err = gdiff_add( dd, opcode );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( err != GDIFF_OK )
|
|
||||||
done = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* return status */
|
|
||||||
return (err);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------
|
|
||||||
* gdiff_getdiff()
|
|
||||||
*
|
|
||||||
* reads the next "length" bytes of the diff into "buffer"
|
|
||||||
*
|
|
||||||
* XXX: need a diff buffer to optimize reads!
|
|
||||||
*---------------------------------------------------------
|
|
||||||
*/
|
|
||||||
static
|
|
||||||
int32 gdiff_getdiff( pDIFFDATA dd, uchar *buffer, uint32 length )
|
|
||||||
{
|
|
||||||
uint32 bytesRead;
|
|
||||||
|
|
||||||
bytesRead = PR_Read (dd->fDiff, buffer, length);
|
|
||||||
if ( bytesRead != length )
|
|
||||||
return GDIFF_ERR_BADDIFF;
|
|
||||||
|
|
||||||
return GDIFF_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------
|
|
||||||
* gdiff_add()
|
|
||||||
*
|
|
||||||
* append "count" bytes from diff file to new file
|
|
||||||
*---------------------------------------------------------
|
|
||||||
*/
|
|
||||||
static
|
|
||||||
int32 gdiff_add( pDIFFDATA dd, uint32 count )
|
|
||||||
{
|
|
||||||
int32 err = GDIFF_OK;
|
|
||||||
uint32 nRead;
|
|
||||||
uint32 chunksize;
|
|
||||||
|
|
||||||
while ( count > 0 ) {
|
|
||||||
chunksize = ( count > dd->bufsize) ? dd->bufsize : count;
|
|
||||||
nRead = PR_Read (dd->fDiff, dd->databuf, chunksize);
|
|
||||||
if ( nRead != chunksize ) {
|
|
||||||
err = GDIFF_ERR_BADDIFF;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
PR_Write (dd->fOut, dd->databuf, chunksize);
|
|
||||||
|
|
||||||
count -= chunksize;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (err);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------
|
|
||||||
* gdiff_copy()
|
|
||||||
*
|
|
||||||
* copy "count" bytes from "position" in source file
|
|
||||||
*---------------------------------------------------------
|
|
||||||
*/
|
|
||||||
static
|
|
||||||
int32 gdiff_copy( pDIFFDATA dd, uint32 position, uint32 count )
|
|
||||||
{
|
|
||||||
int32 err = GDIFF_OK;
|
|
||||||
uint32 nRead;
|
|
||||||
uint32 chunksize;
|
|
||||||
|
|
||||||
PR_Seek (dd->fSrc, position, PR_SEEK_SET);
|
|
||||||
|
|
||||||
while ( count > 0 ) {
|
|
||||||
chunksize = (count > dd->bufsize) ? dd->bufsize : count;
|
|
||||||
|
|
||||||
nRead = PR_Read (dd->fSrc, dd->databuf, chunksize);
|
|
||||||
if ( nRead != chunksize ) {
|
|
||||||
err = GDIFF_ERR_OLDFILE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
PR_Write (dd->fOut, dd->databuf, chunksize);
|
|
||||||
|
|
||||||
count -= chunksize;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (err);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,79 +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.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 nsInstallPatch_h__
|
|
||||||
#define nsInstallPatch_h__
|
|
||||||
|
|
||||||
#include "prtypes.h"
|
|
||||||
#include "nsString.h"
|
|
||||||
|
|
||||||
#include "nsInstallObject.h"
|
|
||||||
|
|
||||||
#include "nsInstall.h"
|
|
||||||
#include "nsInstallFolder.h"
|
|
||||||
#include "nsInstallVersion.h"
|
|
||||||
|
|
||||||
|
|
||||||
class nsInstallPatch : public nsInstallObject
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
nsInstallPatch( nsInstall* inInstall,
|
|
||||||
const nsString& inVRName,
|
|
||||||
const nsString& inVInfo,
|
|
||||||
const nsString& inJarLocation,
|
|
||||||
const nsString& folderSpec,
|
|
||||||
const nsString& inPartialPath,
|
|
||||||
PRInt32 *error);
|
|
||||||
|
|
||||||
nsInstallPatch( nsInstall* inInstall,
|
|
||||||
const nsString& inVRName,
|
|
||||||
const nsString& inVInfo,
|
|
||||||
const nsString& inJarLocation,
|
|
||||||
PRInt32 *error);
|
|
||||||
|
|
||||||
virtual ~nsInstallPatch();
|
|
||||||
|
|
||||||
PRInt32 Prepare();
|
|
||||||
PRInt32 Complete();
|
|
||||||
void Abort();
|
|
||||||
char* toString();
|
|
||||||
|
|
||||||
PRBool CanUninstall();
|
|
||||||
PRBool RegisterPackageNode();
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
|
|
||||||
nsInstallVersion *mVersionInfo;
|
|
||||||
|
|
||||||
nsFileSpec *mTargetFile;
|
|
||||||
nsFileSpec *mPatchFile;
|
|
||||||
nsFileSpec *mPatchedFile;
|
|
||||||
|
|
||||||
nsString *mJarLocation;
|
|
||||||
nsString *mRegistryName;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PRInt32 NativePatch(const nsFileSpec &sourceFile, const nsFileSpec &patchfile, nsFileSpec **newFile);
|
|
||||||
void* HashFilePath(const nsFilePath& aPath);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* nsInstallPatch_h__ */
|
|
||||||
@@ -1,343 +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.0 (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,
|
|
||||||
* released March 31, 1998.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* Douglas Turner <dougt@netscape.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "nsIXPInstallProgress.h"
|
|
||||||
#include "nsInstallProgressDialog.h"
|
|
||||||
|
|
||||||
#include "nsIAppShellComponentImpl.h"
|
|
||||||
|
|
||||||
#include "nsIServiceManager.h"
|
|
||||||
#include "nsIDocumentViewer.h"
|
|
||||||
#include "nsIContent.h"
|
|
||||||
#include "nsINameSpaceManager.h"
|
|
||||||
#include "nsIContentViewer.h"
|
|
||||||
#include "nsIDOMElement.h"
|
|
||||||
#include "nsINetService.h"
|
|
||||||
|
|
||||||
#include "nsIWebShell.h"
|
|
||||||
#include "nsIWebShellWindow.h"
|
|
||||||
|
|
||||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
|
||||||
static NS_DEFINE_IID( kAppShellServiceCID, NS_APPSHELL_SERVICE_CID );
|
|
||||||
static NS_DEFINE_IID( kNetServiceCID, NS_NETSERVICE_CID );
|
|
||||||
|
|
||||||
// Utility to set element attribute.
|
|
||||||
static nsresult setAttribute( nsIDOMXULDocument *doc,
|
|
||||||
const char *id,
|
|
||||||
const char *name,
|
|
||||||
const nsString &value ) {
|
|
||||||
nsresult rv = NS_OK;
|
|
||||||
|
|
||||||
if ( doc ) {
|
|
||||||
// Find specified element.
|
|
||||||
nsCOMPtr<nsIDOMElement> elem;
|
|
||||||
rv = doc->GetElementById( id, getter_AddRefs( elem ) );
|
|
||||||
if ( elem ) {
|
|
||||||
// Set the text attribute.
|
|
||||||
rv = elem->SetAttribute( name, value );
|
|
||||||
if ( NS_SUCCEEDED( rv ) ) {
|
|
||||||
} else {
|
|
||||||
DEBUG_PRINTF( PR_STDOUT, "%s %d: SetAttribute failed, rv=0x%X\n",
|
|
||||||
__FILE__, (int)__LINE__, (int)rv );
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
DEBUG_PRINTF( PR_STDOUT, "%s %d: GetElementById failed, rv=0x%X\n",
|
|
||||||
__FILE__, (int)__LINE__, (int)rv );
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
rv = NS_ERROR_NULL_POINTER;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Utility to get element attribute.
|
|
||||||
static nsresult getAttribute( nsIDOMXULDocument *doc,
|
|
||||||
const char *id,
|
|
||||||
const char *name,
|
|
||||||
nsString &value ) {
|
|
||||||
nsresult rv = NS_OK;
|
|
||||||
|
|
||||||
if ( doc ) {
|
|
||||||
// Find specified element.
|
|
||||||
nsCOMPtr<nsIDOMElement> elem;
|
|
||||||
rv = doc->GetElementById( id, getter_AddRefs( elem ) );
|
|
||||||
if ( elem ) {
|
|
||||||
// Set the text attribute.
|
|
||||||
rv = elem->GetAttribute( name, value );
|
|
||||||
if ( NS_SUCCEEDED( rv ) ) {
|
|
||||||
} else {
|
|
||||||
DEBUG_PRINTF( PR_STDOUT, "%s %d: SetAttribute failed, rv=0x%X\n",
|
|
||||||
__FILE__, (int)__LINE__, (int)rv );
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
DEBUG_PRINTF( PR_STDOUT, "%s %d: GetElementById failed, rv=0x%X\n",
|
|
||||||
__FILE__, (int)__LINE__, (int)rv );
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
rv = NS_ERROR_NULL_POINTER;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
nsInstallProgressDialog::nsInstallProgressDialog()
|
|
||||||
{
|
|
||||||
NS_INIT_REFCNT();
|
|
||||||
mWindow = nsnull;
|
|
||||||
mDocument = nsnull;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
nsInstallProgressDialog::~nsInstallProgressDialog()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
NS_IMPL_ADDREF( nsInstallProgressDialog );
|
|
||||||
NS_IMPL_RELEASE( nsInstallProgressDialog );
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallProgressDialog::QueryInterface(REFNSIID aIID,void** aInstancePtr)
|
|
||||||
{
|
|
||||||
if (aInstancePtr == NULL) {
|
|
||||||
return NS_ERROR_NULL_POINTER;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Always NULL result, in case of failure
|
|
||||||
*aInstancePtr = NULL;
|
|
||||||
|
|
||||||
if (aIID.Equals(nsIXPInstallProgress::GetIID())) {
|
|
||||||
*aInstancePtr = (void*) ((nsInstallProgressDialog*)this);
|
|
||||||
NS_ADDREF_THIS();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
if (aIID.Equals(nsIXULWindowCallbacks::GetIID())) {
|
|
||||||
*aInstancePtr = (void*) ((nsIXULWindowCallbacks*)this);
|
|
||||||
NS_ADDREF_THIS();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
if (aIID.Equals(kISupportsIID)) {
|
|
||||||
*aInstancePtr = (void*) (nsISupports*)((nsIXPInstallProgress*)this);
|
|
||||||
NS_ADDREF_THIS();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_ERROR_NO_INTERFACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallProgressDialog::BeforeJavascriptEvaluation()
|
|
||||||
{
|
|
||||||
nsresult rv = NS_OK;
|
|
||||||
|
|
||||||
// Get app shell service.
|
|
||||||
nsIAppShellService *appShell;
|
|
||||||
rv = nsServiceManager::GetService( kAppShellServiceCID,
|
|
||||||
nsIAppShellService::GetIID(),
|
|
||||||
(nsISupports**)&appShell );
|
|
||||||
|
|
||||||
if ( NS_SUCCEEDED( rv ) )
|
|
||||||
{
|
|
||||||
// Open "progress" dialog.
|
|
||||||
nsIURL *url;
|
|
||||||
rv = NS_NewURL( &url, "resource:/res/xpinstall/progress.xul" );
|
|
||||||
|
|
||||||
if ( NS_SUCCEEDED(rv) )
|
|
||||||
{
|
|
||||||
|
|
||||||
nsIWebShellWindow *newWindow;
|
|
||||||
|
|
||||||
rv = appShell->CreateTopLevelWindow( nsnull,
|
|
||||||
url,
|
|
||||||
PR_TRUE,
|
|
||||||
newWindow,
|
|
||||||
nsnull,
|
|
||||||
this, // callbacks??
|
|
||||||
0,
|
|
||||||
0 );
|
|
||||||
|
|
||||||
if ( NS_SUCCEEDED( rv ) )
|
|
||||||
{
|
|
||||||
mWindow = newWindow;
|
|
||||||
NS_RELEASE( newWindow );
|
|
||||||
|
|
||||||
if (mWindow != nsnull)
|
|
||||||
mWindow->Show(PR_TRUE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DEBUG_PRINTF( PR_STDOUT, "Error creating progress dialog, rv=0x%X\n", (int)rv );
|
|
||||||
}
|
|
||||||
NS_RELEASE( url );
|
|
||||||
}
|
|
||||||
|
|
||||||
nsServiceManager::ReleaseService( kAppShellServiceCID, appShell );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DEBUG_PRINTF( PR_STDOUT, "Unable to get app shell service, rv=0x%X\n", (int)rv );
|
|
||||||
}
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallProgressDialog::AfterJavascriptEvaluation()
|
|
||||||
{
|
|
||||||
if (mWindow)
|
|
||||||
{
|
|
||||||
mWindow->Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallProgressDialog::InstallStarted(const char *UIPackageName)
|
|
||||||
{
|
|
||||||
setAttribute( mDocument, "dialog.uiPackageName", "value", nsString(UIPackageName) );
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallProgressDialog::ItemScheduled(const char *message)
|
|
||||||
{
|
|
||||||
PRInt32 maxChars = 40;
|
|
||||||
|
|
||||||
nsString theMessage(message);
|
|
||||||
PRInt32 len = theMessage.Length();
|
|
||||||
if (len > maxChars)
|
|
||||||
{
|
|
||||||
PRInt32 offset = (len/2) - ((len - maxChars)/2);
|
|
||||||
PRInt32 count = (len - maxChars);
|
|
||||||
theMessage.Cut(offset, count);
|
|
||||||
theMessage.Insert(nsString("..."), offset);
|
|
||||||
}
|
|
||||||
setAttribute( mDocument, "dialog.currentAction", "value", theMessage );
|
|
||||||
|
|
||||||
nsString aValue;
|
|
||||||
getAttribute( mDocument, "data.canceled", "value", aValue );
|
|
||||||
|
|
||||||
if (aValue.EqualsIgnoreCase("true"))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallProgressDialog::InstallFinalization(const char *message, PRInt32 itemNum, PRInt32 totNum)
|
|
||||||
{
|
|
||||||
|
|
||||||
PRInt32 maxChars = 40;
|
|
||||||
|
|
||||||
nsString theMessage(message);
|
|
||||||
PRInt32 len = theMessage.Length();
|
|
||||||
if (len > maxChars)
|
|
||||||
{
|
|
||||||
PRInt32 offset = (len/2) - ((len - maxChars)/2);
|
|
||||||
PRInt32 count = (len - maxChars);
|
|
||||||
theMessage.Cut(offset, count);
|
|
||||||
theMessage.Insert(nsString("..."), offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
setAttribute( mDocument, "dialog.currentAction", "value", theMessage );
|
|
||||||
|
|
||||||
nsresult rv = NS_OK;
|
|
||||||
char buf[16];
|
|
||||||
|
|
||||||
PR_snprintf( buf, sizeof buf, "%lu", totNum );
|
|
||||||
setAttribute( mDocument, "dialog.progress", "max", buf );
|
|
||||||
|
|
||||||
if (totNum != 0)
|
|
||||||
{
|
|
||||||
PR_snprintf( buf, sizeof buf, "%lu", ((totNum-itemNum)/totNum) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PR_snprintf( buf, sizeof buf, "%lu", 0 );
|
|
||||||
}
|
|
||||||
setAttribute( mDocument, "dialog.progress", "value", buf );
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallProgressDialog::InstallAborted()
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Do startup stuff from C++ side.
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallProgressDialog::ConstructBeforeJavaScript(nsIWebShell *aWebShell)
|
|
||||||
{
|
|
||||||
nsresult rv = NS_OK;
|
|
||||||
|
|
||||||
// Get content viewer from the web shell.
|
|
||||||
nsCOMPtr<nsIContentViewer> contentViewer;
|
|
||||||
rv = aWebShell ? aWebShell->GetContentViewer(getter_AddRefs(contentViewer))
|
|
||||||
: NS_ERROR_NULL_POINTER;
|
|
||||||
|
|
||||||
if ( contentViewer ) {
|
|
||||||
// Up-cast to a document viewer.
|
|
||||||
nsCOMPtr<nsIDocumentViewer> docViewer( do_QueryInterface( contentViewer, &rv ) );
|
|
||||||
if ( docViewer ) {
|
|
||||||
// Get the document from the doc viewer.
|
|
||||||
nsCOMPtr<nsIDocument> document;
|
|
||||||
rv = docViewer->GetDocument(*getter_AddRefs(document));
|
|
||||||
if ( document ) {
|
|
||||||
// Upcast to XUL document.
|
|
||||||
mDocument = do_QueryInterface( document, &rv );
|
|
||||||
if ( ! mDocument )
|
|
||||||
{
|
|
||||||
DEBUG_PRINTF( PR_STDOUT, "%s %d: Upcast to nsIDOMXULDocument failed, rv=0x%X\n",
|
|
||||||
__FILE__, (int)__LINE__, (int)rv );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DEBUG_PRINTF( PR_STDOUT, "%s %d: GetDocument failed, rv=0x%X\n",
|
|
||||||
__FILE__, (int)__LINE__, (int)rv );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DEBUG_PRINTF( PR_STDOUT, "%s %d: Upcast to nsIDocumentViewer failed, rv=0x%X\n",
|
|
||||||
__FILE__, (int)__LINE__, (int)rv );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DEBUG_PRINTF( PR_STDOUT, "%s %d: GetContentViewer failed, rv=0x%X\n",
|
|
||||||
__FILE__, (int)__LINE__, (int)rv );
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
@@ -1,67 +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.0 (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,
|
|
||||||
* released March 31, 1998.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* Douglas Turner <dougt@netscape.com>
|
|
||||||
*/
|
|
||||||
#ifndef __nsInstallProgressDialog_h__
|
|
||||||
#define __nsInstallProgressDialog_h__
|
|
||||||
|
|
||||||
#include "nsIXPInstallProgress.h"
|
|
||||||
#include "nsISupports.h"
|
|
||||||
#include "nsISupportsUtils.h"
|
|
||||||
|
|
||||||
#include "nsCOMPtr.h"
|
|
||||||
|
|
||||||
#include "nsIWebShell.h"
|
|
||||||
#include "nsIWebShellWindow.h"
|
|
||||||
#include "nsIXULWindowCallbacks.h"
|
|
||||||
|
|
||||||
#include "nsIDocument.h"
|
|
||||||
#include "nsIDOMXULDocument.h"
|
|
||||||
|
|
||||||
|
|
||||||
class nsInstallProgressDialog : public nsIXPInstallProgress, public nsIXULWindowCallbacks
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
nsInstallProgressDialog();
|
|
||||||
virtual ~nsInstallProgressDialog();
|
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS
|
|
||||||
|
|
||||||
|
|
||||||
NS_IMETHOD BeforeJavascriptEvaluation();
|
|
||||||
NS_IMETHOD AfterJavascriptEvaluation();
|
|
||||||
NS_IMETHOD InstallStarted(const char *UIPackageName);
|
|
||||||
NS_IMETHOD ItemScheduled(const char *message);
|
|
||||||
NS_IMETHOD InstallFinalization(const char *message, PRInt32 itemNum, PRInt32 totNum);
|
|
||||||
NS_IMETHOD InstallAborted();
|
|
||||||
|
|
||||||
// Declare implementations of nsIXULWindowCallbacks interface functions.
|
|
||||||
NS_IMETHOD ConstructBeforeJavaScript(nsIWebShell *aWebShell);
|
|
||||||
NS_IMETHOD ConstructAfterJavaScript(nsIWebShell *aWebShell) { return NS_OK; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMXULDocument> mDocument;
|
|
||||||
nsCOMPtr<nsIWebShellWindow> mWindow;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
@@ -1,67 +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.0 (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,
|
|
||||||
* released March 31, 1998.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* Daniel Veditz <dveditz@netscape.com>
|
|
||||||
* Douglas Turner <dougt@netscape.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "nsInstallResources.h"
|
|
||||||
|
|
||||||
char* nsInstallResources::GetInstallFileString(void)
|
|
||||||
{
|
|
||||||
return "Installing: %s";
|
|
||||||
}
|
|
||||||
|
|
||||||
char* nsInstallResources::GetReplaceFileString(void)
|
|
||||||
{
|
|
||||||
return "Replacing %s";
|
|
||||||
}
|
|
||||||
|
|
||||||
char* nsInstallResources::GetDeleteFileString(void)
|
|
||||||
{
|
|
||||||
return "Deleting file: %s";
|
|
||||||
}
|
|
||||||
|
|
||||||
char* nsInstallResources::GetDeleteComponentString(void)
|
|
||||||
{
|
|
||||||
return "Deleting component: %s";
|
|
||||||
}
|
|
||||||
|
|
||||||
char* nsInstallResources::GetExecuteString(void)
|
|
||||||
{
|
|
||||||
return "Executing: %s";
|
|
||||||
}
|
|
||||||
|
|
||||||
char* nsInstallResources::GetExecuteWithArgsString(void)
|
|
||||||
{
|
|
||||||
return "Executing: %s with argument: %s";
|
|
||||||
}
|
|
||||||
|
|
||||||
char* nsInstallResources::GetPatchFileString(void)
|
|
||||||
{
|
|
||||||
return "Patching: %s";
|
|
||||||
}
|
|
||||||
|
|
||||||
char* nsInstallResources::GetUninstallString(void)
|
|
||||||
{
|
|
||||||
return "Uninstalling: %s";
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,45 +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.0 (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,
|
|
||||||
* released March 31, 1998.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* Daniel Veditz <dveditz@netscape.com>
|
|
||||||
* Douglas Turner <dougt@netscape.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef __NS_INSTALLRESOURCES_H__
|
|
||||||
#define __NS_INSTALLRESOURCES_H__
|
|
||||||
|
|
||||||
class nsInstallResources
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
static char* GetInstallFileString(void);
|
|
||||||
static char* GetReplaceFileString(void);
|
|
||||||
static char* GetDeleteFileString(void);
|
|
||||||
static char* GetDeleteComponentString(void);
|
|
||||||
static char* GetExecuteString(void);
|
|
||||||
static char* GetExecuteWithArgsString(void);
|
|
||||||
static char* GetPatchFileString(void);
|
|
||||||
static char* GetUninstallString(void);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,359 +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.0 (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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "nsSoftwareUpdate.h"
|
|
||||||
#include "nsSoftwareUpdateStream.h"
|
|
||||||
#include "nsInstallTrigger.h"
|
|
||||||
#include "nsIDOMInstallTriggerGlobal.h"
|
|
||||||
|
|
||||||
#include "nscore.h"
|
|
||||||
#include "nsIFactory.h"
|
|
||||||
#include "nsISupports.h"
|
|
||||||
#include "nsIScriptGlobalObject.h"
|
|
||||||
|
|
||||||
#include "nsIPref.h"
|
|
||||||
|
|
||||||
#include "nsRepository.h"
|
|
||||||
#include "nsIServiceManager.h"
|
|
||||||
|
|
||||||
#include "nsSpecialSystemDirectory.h"
|
|
||||||
|
|
||||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
|
||||||
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
|
|
||||||
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
|
|
||||||
|
|
||||||
static NS_DEFINE_IID(kIInstallTrigger_IID, NS_IDOMINSTALLTRIGGERGLOBAL_IID);
|
|
||||||
static NS_DEFINE_IID(kIInstallTrigger_CID, NS_SoftwareUpdateInstallTrigger_CID);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
nsInstallTrigger::nsInstallTrigger()
|
|
||||||
{
|
|
||||||
mScriptObject = nsnull;
|
|
||||||
NS_INIT_REFCNT();
|
|
||||||
}
|
|
||||||
|
|
||||||
nsInstallTrigger::~nsInstallTrigger()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallTrigger::QueryInterface(REFNSIID aIID,void** aInstancePtr)
|
|
||||||
{
|
|
||||||
if (aInstancePtr == NULL)
|
|
||||||
{
|
|
||||||
return NS_ERROR_NULL_POINTER;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Always NULL result, in case of failure
|
|
||||||
*aInstancePtr = NULL;
|
|
||||||
|
|
||||||
if ( aIID.Equals(kIScriptObjectOwnerIID))
|
|
||||||
{
|
|
||||||
*aInstancePtr = (void*) ((nsIScriptObjectOwner*)this);
|
|
||||||
AddRef();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
else if ( aIID.Equals(kIInstallTrigger_IID) )
|
|
||||||
{
|
|
||||||
*aInstancePtr = (void*) ((nsIDOMInstallTriggerGlobal*)this);
|
|
||||||
AddRef();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
else if ( aIID.Equals(kISupportsIID) )
|
|
||||||
{
|
|
||||||
*aInstancePtr = (void*)(nsISupports*)(nsIScriptObjectOwner*)this;
|
|
||||||
AddRef();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_NOINTERFACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMPL_ADDREF(nsInstallTrigger)
|
|
||||||
NS_IMPL_RELEASE(nsInstallTrigger)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallTrigger::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
|
|
||||||
{
|
|
||||||
NS_PRECONDITION(nsnull != aScriptObject, "null arg");
|
|
||||||
nsresult res = NS_OK;
|
|
||||||
|
|
||||||
if (nsnull == mScriptObject)
|
|
||||||
{
|
|
||||||
nsIScriptGlobalObject *global = aContext->GetGlobalObject();
|
|
||||||
|
|
||||||
res = NS_NewScriptInstallTriggerGlobal( aContext,
|
|
||||||
(nsISupports *)(nsIDOMInstallTriggerGlobal*)this,
|
|
||||||
(nsISupports *)global,
|
|
||||||
&mScriptObject);
|
|
||||||
NS_IF_RELEASE(global);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
*aScriptObject = mScriptObject;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallTrigger::SetScriptObject(void *aScriptObject)
|
|
||||||
{
|
|
||||||
mScriptObject = aScriptObject;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static NS_DEFINE_IID(kPrefsIID, NS_IPREF_IID);
|
|
||||||
static NS_DEFINE_IID(kPrefsCID, NS_PREF_CID);
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallTrigger::UpdateEnabled(PRBool* aReturn)
|
|
||||||
{
|
|
||||||
nsIPref * prefs;
|
|
||||||
|
|
||||||
nsresult rv = nsServiceManager::GetService(kPrefsCID,
|
|
||||||
kPrefsIID,
|
|
||||||
(nsISupports**) &prefs);
|
|
||||||
|
|
||||||
|
|
||||||
if ( NS_SUCCEEDED(rv) )
|
|
||||||
{
|
|
||||||
rv = prefs->GetBoolPref( (const char*) AUTOUPDATE_ENABLE_PREF, aReturn);
|
|
||||||
|
|
||||||
if (NS_FAILED(rv))
|
|
||||||
{
|
|
||||||
*aReturn = PR_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_RELEASE(prefs);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*aReturn = PR_FALSE; /* no prefs manager. set to false */
|
|
||||||
}
|
|
||||||
|
|
||||||
//FIX!!!!!!!!!!
|
|
||||||
*aReturn = PR_TRUE;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallTrigger::StartSoftwareUpdate(const nsString& aURL, PRInt32 aFlags, PRInt32* aReturn)
|
|
||||||
{
|
|
||||||
nsString localFile;
|
|
||||||
CreateTempFileFromURL(aURL, localFile);
|
|
||||||
|
|
||||||
// start the download (this will clean itself up)
|
|
||||||
nsSoftwareUpdateListener *downloader = new nsSoftwareUpdateListener(aURL, localFile, aFlags);
|
|
||||||
|
|
||||||
*aReturn = NS_OK; // maybe we should do something more.
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallTrigger::StartSoftwareUpdate(const nsString& aURL, PRInt32* aReturn)
|
|
||||||
{
|
|
||||||
nsString localFile;
|
|
||||||
CreateTempFileFromURL(aURL, localFile);
|
|
||||||
|
|
||||||
// start the download (this will clean itself up)
|
|
||||||
nsSoftwareUpdateListener *downloader = new nsSoftwareUpdateListener(aURL, localFile, 0);
|
|
||||||
|
|
||||||
*aReturn = NS_OK; // maybe we should do something more.
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallTrigger::ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, PRInt32 aDiffLevel, const nsString& aVersion, PRInt32 aMode, PRInt32* aReturn)
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallTrigger::ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, PRInt32 aDiffLevel, nsIDOMInstallVersion* aVersion, PRInt32 aMode, PRInt32* aReturn)
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallTrigger::ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, nsIDOMInstallVersion* aVersion, PRInt32 aMode, PRInt32* aReturn)
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallTrigger::ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, const nsString& aVersion, PRInt32 aMode, PRInt32* aReturn)
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallTrigger::ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, const nsString& aVersion, PRInt32* aReturn)
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallTrigger::ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, nsIDOMInstallVersion* aVersion, PRInt32* aReturn)
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallTrigger::CompareVersion(const nsString& aRegName, PRInt32 aMajor, PRInt32 aMinor, PRInt32 aRelease, PRInt32 aBuild, PRInt32* aReturn)
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallTrigger::CompareVersion(const nsString& aRegName, const nsString& aVersion, PRInt32* aReturn)
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallTrigger::CompareVersion(const nsString& aRegName, nsIDOMInstallVersion* aVersion, PRInt32* aReturn)
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// this will take a nsIUrl, and create a temporary file. If it is local, we just us it.
|
|
||||||
|
|
||||||
void
|
|
||||||
nsInstallTrigger::CreateTempFileFromURL(const nsString& aURL, nsString& tempFileString)
|
|
||||||
{
|
|
||||||
// Checking to see if the url is local
|
|
||||||
|
|
||||||
if ( aURL.EqualsIgnoreCase("file://", 7) )
|
|
||||||
{
|
|
||||||
tempFileString.SetString( nsNSPRPath(nsFileURL(aURL)) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nsSpecialSystemDirectory tempFile(nsSpecialSystemDirectory::OS_TemporaryDirectory);
|
|
||||||
|
|
||||||
PRInt32 result = aURL.RFind("/");
|
|
||||||
if (result != -1)
|
|
||||||
{
|
|
||||||
nsString jarName;
|
|
||||||
|
|
||||||
aURL.Right(jarName, (aURL.Length() - result) );
|
|
||||||
|
|
||||||
PRInt32 argOffset = jarName.RFind("?");
|
|
||||||
|
|
||||||
if (argOffset != -1)
|
|
||||||
{
|
|
||||||
// we need to remove ? and everything after it
|
|
||||||
jarName.Truncate(argOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
tempFile += jarName;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tempFile += "xpinstall.jar";
|
|
||||||
}
|
|
||||||
|
|
||||||
tempFile.MakeUnique();
|
|
||||||
|
|
||||||
tempFileString.SetString( nsNSPRPath( nsFilePath(tempFile) ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
nsInstallTriggerFactory::nsInstallTriggerFactory(void)
|
|
||||||
{
|
|
||||||
NS_INIT_REFCNT();
|
|
||||||
}
|
|
||||||
|
|
||||||
nsInstallTriggerFactory::~nsInstallTriggerFactory(void)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(mRefCnt == 0, "non-zero refcnt at destruction");
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallTriggerFactory::QueryInterface(const nsIID &aIID, void **aResult)
|
|
||||||
{
|
|
||||||
if (! aResult)
|
|
||||||
return NS_ERROR_NULL_POINTER;
|
|
||||||
|
|
||||||
// Always NULL result, in case of failure
|
|
||||||
*aResult = nsnull;
|
|
||||||
|
|
||||||
if (aIID.Equals(kISupportsIID)) {
|
|
||||||
*aResult = NS_STATIC_CAST(nsISupports*, this);
|
|
||||||
AddRef();
|
|
||||||
return NS_OK;
|
|
||||||
} else if (aIID.Equals(kIFactoryIID)) {
|
|
||||||
*aResult = NS_STATIC_CAST(nsIFactory*, this);
|
|
||||||
AddRef();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_NOINTERFACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMPL_ADDREF(nsInstallTriggerFactory);
|
|
||||||
NS_IMPL_RELEASE(nsInstallTriggerFactory);
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallTriggerFactory::CreateInstance(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
|
||||||
{
|
|
||||||
if (! aResult)
|
|
||||||
return NS_ERROR_NULL_POINTER;
|
|
||||||
|
|
||||||
*aResult = nsnull;
|
|
||||||
|
|
||||||
nsresult rv;
|
|
||||||
|
|
||||||
nsInstallTrigger *inst = new nsInstallTrigger();
|
|
||||||
|
|
||||||
if (! inst)
|
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
if (NS_FAILED(rv = inst->QueryInterface(aIID, aResult)))
|
|
||||||
{
|
|
||||||
// We didn't get the right interface.
|
|
||||||
NS_ERROR("didn't support the interface you wanted");
|
|
||||||
}
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallTriggerFactory::LockFactory(PRBool aLock)
|
|
||||||
{
|
|
||||||
// Not implemented in simplest case.
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
#ifndef __NS_INSTALLTRIGGER_H__
|
|
||||||
#define __NS_INSTALLTRIGGER_H__
|
|
||||||
|
|
||||||
#include "nscore.h"
|
|
||||||
#include "nsString.h"
|
|
||||||
#include "nsIFactory.h"
|
|
||||||
#include "nsISupports.h"
|
|
||||||
#include "nsIScriptObjectOwner.h"
|
|
||||||
|
|
||||||
#include "nsIDOMInstallTriggerGlobal.h"
|
|
||||||
#include "nsSoftwareUpdate.h"
|
|
||||||
|
|
||||||
#include "prtypes.h"
|
|
||||||
#include "nsHashtable.h"
|
|
||||||
#include "nsVector.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class nsInstallTrigger: public nsIScriptObjectOwner, public nsIDOMInstallTriggerGlobal
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static const nsIID& IID() { static nsIID iid = NS_SoftwareUpdateInstallTrigger_CID; return iid; }
|
|
||||||
|
|
||||||
nsInstallTrigger();
|
|
||||||
~nsInstallTrigger();
|
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS
|
|
||||||
|
|
||||||
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
|
|
||||||
NS_IMETHOD SetScriptObject(void* aScriptObject);
|
|
||||||
|
|
||||||
NS_IMETHOD UpdateEnabled(PRBool* aReturn);
|
|
||||||
NS_IMETHOD StartSoftwareUpdate(const nsString& aURL, PRInt32 aFlags, PRInt32* aReturn);
|
|
||||||
NS_IMETHOD StartSoftwareUpdate(const nsString& aURL, PRInt32* aReturn);
|
|
||||||
NS_IMETHOD ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, PRInt32 aDiffLevel, const nsString& aVersion, PRInt32 aMode, PRInt32* aReturn);
|
|
||||||
NS_IMETHOD ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, PRInt32 aDiffLevel, nsIDOMInstallVersion* aVersion, PRInt32 aMode, PRInt32* aReturn);
|
|
||||||
NS_IMETHOD ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, nsIDOMInstallVersion* aVersion, PRInt32 aMode, PRInt32* aReturn);
|
|
||||||
NS_IMETHOD ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, const nsString& aVersion, PRInt32 aMode, PRInt32* aReturn);
|
|
||||||
NS_IMETHOD ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, const nsString& aVersion, PRInt32* aReturn);
|
|
||||||
NS_IMETHOD ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, nsIDOMInstallVersion* aVersion, PRInt32* aReturn);
|
|
||||||
NS_IMETHOD CompareVersion(const nsString& aRegName, PRInt32 aMajor, PRInt32 aMinor, PRInt32 aRelease, PRInt32 aBuild, PRInt32* aReturn);
|
|
||||||
NS_IMETHOD CompareVersion(const nsString& aRegName, const nsString& aVersion, PRInt32* aReturn);
|
|
||||||
NS_IMETHOD CompareVersion(const nsString& aRegName, nsIDOMInstallVersion* aVersion, PRInt32* aReturn);
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
void *mScriptObject;
|
|
||||||
void CreateTempFileFromURL(const nsString& aURL, nsString& tempFileString);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class nsInstallTriggerFactory : public nsIFactory
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
nsInstallTriggerFactory();
|
|
||||||
~nsInstallTriggerFactory();
|
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS
|
|
||||||
|
|
||||||
NS_IMETHOD CreateInstance(nsISupports *aOuter,
|
|
||||||
REFNSIID aIID,
|
|
||||||
void **aResult);
|
|
||||||
|
|
||||||
NS_IMETHOD LockFactory(PRBool aLock);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,196 +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.0 (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,
|
|
||||||
* released March 31, 1998.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* Daniel Veditz <dveditz@netscape.com>
|
|
||||||
* Douglas Turner <dougt@netscape.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "nsInstall.h"
|
|
||||||
#include "nsInstallUninstall.h"
|
|
||||||
#include "nsInstallResources.h"
|
|
||||||
#include "VerReg.h"
|
|
||||||
#include "prmem.h"
|
|
||||||
#include "nsFileSpec.h"
|
|
||||||
#include "ScheduledTasks.h"
|
|
||||||
|
|
||||||
extern "C" NS_EXPORT PRInt32 SU_Uninstall(char *regPackageName);
|
|
||||||
REGERR su_UninstallProcessItem(char *component_path);
|
|
||||||
|
|
||||||
|
|
||||||
nsInstallUninstall::nsInstallUninstall( nsInstall* inInstall,
|
|
||||||
const nsString& regName,
|
|
||||||
PRInt32 *error)
|
|
||||||
|
|
||||||
: nsInstallObject(inInstall)
|
|
||||||
{
|
|
||||||
if (regName == "null")
|
|
||||||
{
|
|
||||||
*error = nsInstall::INVALID_ARGUMENTS;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mRegName.SetString(regName);
|
|
||||||
|
|
||||||
char* userName = (char*)PR_Malloc(MAXREGPATHLEN);
|
|
||||||
PRInt32 err = VR_GetUninstallUserName( (char*) (const char*) nsAutoCString(regName),
|
|
||||||
userName,
|
|
||||||
MAXREGPATHLEN );
|
|
||||||
|
|
||||||
mUIName.SetString(userName);
|
|
||||||
|
|
||||||
if (err != REGERR_OK)
|
|
||||||
{
|
|
||||||
*error = nsInstall::NO_SUCH_COMPONENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
PR_FREEIF(userName);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
nsInstallUninstall::~nsInstallUninstall()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PRInt32 nsInstallUninstall::Prepare()
|
|
||||||
{
|
|
||||||
// no set-up necessary
|
|
||||||
return nsInstall::SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRInt32 nsInstallUninstall::Complete()
|
|
||||||
{
|
|
||||||
PRInt32 err = nsInstall::SUCCESS;
|
|
||||||
|
|
||||||
if (mInstall == NULL)
|
|
||||||
return nsInstall::INVALID_ARGUMENTS;
|
|
||||||
|
|
||||||
err = SU_Uninstall( (char*)(const char*) nsAutoCString(mRegName) );
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsInstallUninstall::Abort()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
char* nsInstallUninstall::toString()
|
|
||||||
{
|
|
||||||
char* buffer = new char[1024];
|
|
||||||
|
|
||||||
char* temp = mUIName.ToNewCString();
|
|
||||||
sprintf( buffer, nsInstallResources::GetUninstallString(), temp);
|
|
||||||
delete [] temp;
|
|
||||||
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PRBool
|
|
||||||
nsInstallUninstall::CanUninstall()
|
|
||||||
{
|
|
||||||
return PR_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRBool
|
|
||||||
nsInstallUninstall::RegisterPackageNode()
|
|
||||||
{
|
|
||||||
return PR_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" NS_EXPORT PRInt32 SU_Uninstall(char *regPackageName)
|
|
||||||
{
|
|
||||||
REGERR status = REGERR_FAIL;
|
|
||||||
char pathbuf[MAXREGPATHLEN+1] = {0};
|
|
||||||
char sharedfilebuf[MAXREGPATHLEN+1] = {0};
|
|
||||||
REGENUM state = 0;
|
|
||||||
int32 length;
|
|
||||||
int32 err;
|
|
||||||
|
|
||||||
if (regPackageName == NULL)
|
|
||||||
return REGERR_PARAM;
|
|
||||||
|
|
||||||
if (pathbuf == NULL)
|
|
||||||
return REGERR_PARAM;
|
|
||||||
|
|
||||||
/* Get next path from Registry */
|
|
||||||
status = VR_Enum( regPackageName, &state, pathbuf, MAXREGPATHLEN );
|
|
||||||
|
|
||||||
/* if we got a good path */
|
|
||||||
while (status == REGERR_OK)
|
|
||||||
{
|
|
||||||
char component_path[2*MAXREGPATHLEN+1] = {0};
|
|
||||||
strcat(component_path, regPackageName);
|
|
||||||
length = strlen(regPackageName);
|
|
||||||
if (component_path[length - 1] != '/')
|
|
||||||
strcat(component_path, "/");
|
|
||||||
strcat(component_path, pathbuf);
|
|
||||||
err = su_UninstallProcessItem(component_path);
|
|
||||||
status = VR_Enum( regPackageName, &state, pathbuf, MAXREGPATHLEN );
|
|
||||||
}
|
|
||||||
|
|
||||||
err = VR_Remove(regPackageName);
|
|
||||||
// there is a problem here. It looks like if the file is refcounted, we still blow away the reg key
|
|
||||||
// FIX!
|
|
||||||
state = 0;
|
|
||||||
status = VR_UninstallEnumSharedFiles( regPackageName, &state, sharedfilebuf, MAXREGPATHLEN );
|
|
||||||
while (status == REGERR_OK)
|
|
||||||
{
|
|
||||||
err = su_UninstallProcessItem(sharedfilebuf);
|
|
||||||
err = VR_UninstallDeleteFileFromList(regPackageName, sharedfilebuf);
|
|
||||||
status = VR_UninstallEnumSharedFiles( regPackageName, &state, sharedfilebuf, MAXREGPATHLEN );
|
|
||||||
}
|
|
||||||
|
|
||||||
err = VR_UninstallDeleteSharedFilesKey(regPackageName);
|
|
||||||
err = VR_UninstallDestroy(regPackageName);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
REGERR su_UninstallProcessItem(char *component_path)
|
|
||||||
{
|
|
||||||
int refcount;
|
|
||||||
int err;
|
|
||||||
char filepath[MAXREGPATHLEN];
|
|
||||||
|
|
||||||
err = VR_GetPath(component_path, sizeof(filepath), filepath);
|
|
||||||
if ( err == REGERR_OK )
|
|
||||||
{
|
|
||||||
err = VR_GetRefCount(component_path, &refcount);
|
|
||||||
if ( err == REGERR_OK )
|
|
||||||
{
|
|
||||||
--refcount;
|
|
||||||
if (refcount > 0)
|
|
||||||
err = VR_SetRefCount(component_path, refcount);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
err = VR_Remove(component_path);
|
|
||||||
DeleteFileNowOrSchedule(nsFileSpec(filepath));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* delete node and file */
|
|
||||||
err = VR_Remove(component_path);
|
|
||||||
DeleteFileNowOrSchedule(nsFileSpec(filepath));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
@@ -1,63 +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.0 (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,
|
|
||||||
* released March 31, 1998.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* Daniel Veditz <dveditz@netscape.com>
|
|
||||||
* Douglas Turner <dougt@netscape.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef nsInstallUninstall_h__
|
|
||||||
#define nsInstallUninstall_h__
|
|
||||||
|
|
||||||
#include "prtypes.h"
|
|
||||||
#include "nsString.h"
|
|
||||||
#include "nsInstallObject.h"
|
|
||||||
#include "nsInstall.h"
|
|
||||||
|
|
||||||
class nsInstallUninstall : public nsInstallObject
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
nsInstallUninstall( nsInstall* inInstall,
|
|
||||||
const nsString& regName,
|
|
||||||
PRInt32 *error);
|
|
||||||
|
|
||||||
|
|
||||||
virtual ~nsInstallUninstall();
|
|
||||||
|
|
||||||
PRInt32 Prepare();
|
|
||||||
PRInt32 Complete();
|
|
||||||
void Abort();
|
|
||||||
char* toString();
|
|
||||||
|
|
||||||
PRBool CanUninstall();
|
|
||||||
PRBool RegisterPackageNode();
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
nsString mRegName; // Registry name of package
|
|
||||||
nsString mUIName; // User name of package
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* nsInstallUninstall_h__ */
|
|
||||||
@@ -1,399 +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.0 (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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "nsSoftwareUpdate.h"
|
|
||||||
|
|
||||||
#include "nsInstallVersion.h"
|
|
||||||
#include "nsIDOMInstallVersion.h"
|
|
||||||
|
|
||||||
#include "nscore.h"
|
|
||||||
#include "nsIFactory.h"
|
|
||||||
#include "nsISupports.h"
|
|
||||||
#include "nsIScriptGlobalObject.h"
|
|
||||||
|
|
||||||
#include "prprf.h"
|
|
||||||
|
|
||||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
|
||||||
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
|
|
||||||
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
|
|
||||||
|
|
||||||
static NS_DEFINE_IID(kIInstallVersion_IID, NS_IDOMINSTALLVERSION_IID);
|
|
||||||
|
|
||||||
|
|
||||||
nsInstallVersion::nsInstallVersion()
|
|
||||||
{
|
|
||||||
mScriptObject = nsnull;
|
|
||||||
NS_INIT_REFCNT();
|
|
||||||
}
|
|
||||||
|
|
||||||
nsInstallVersion::~nsInstallVersion()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallVersion::QueryInterface(REFNSIID aIID,void** aInstancePtr)
|
|
||||||
{
|
|
||||||
if (aInstancePtr == NULL)
|
|
||||||
{
|
|
||||||
return NS_ERROR_NULL_POINTER;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Always NULL result, in case of failure
|
|
||||||
*aInstancePtr = NULL;
|
|
||||||
|
|
||||||
if ( aIID.Equals(kIScriptObjectOwnerIID))
|
|
||||||
{
|
|
||||||
*aInstancePtr = (void*) ((nsIScriptObjectOwner*)this);
|
|
||||||
AddRef();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
else if ( aIID.Equals(kIInstallVersion_IID) )
|
|
||||||
{
|
|
||||||
*aInstancePtr = (void*) ((nsIDOMInstallVersion*)this);
|
|
||||||
AddRef();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
else if ( aIID.Equals(kISupportsIID) )
|
|
||||||
{
|
|
||||||
*aInstancePtr = (void*)(nsISupports*)(nsIScriptObjectOwner*)this;
|
|
||||||
AddRef();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_NOINTERFACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
NS_IMPL_ADDREF(nsInstallVersion)
|
|
||||||
NS_IMPL_RELEASE(nsInstallVersion)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallVersion::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
|
|
||||||
{
|
|
||||||
NS_PRECONDITION(nsnull != aScriptObject, "null arg");
|
|
||||||
nsresult res = NS_OK;
|
|
||||||
|
|
||||||
if (nsnull == mScriptObject)
|
|
||||||
{
|
|
||||||
res = NS_NewScriptInstallVersion(aContext,
|
|
||||||
(nsISupports *)(nsIDOMInstallVersion*)this,
|
|
||||||
nsnull,
|
|
||||||
&mScriptObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
*aScriptObject = mScriptObject;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallVersion::SetScriptObject(void *aScriptObject)
|
|
||||||
{
|
|
||||||
mScriptObject = aScriptObject;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// this will go away when our constructors can have parameters.
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallVersion::Init(PRInt32 aMajor, PRInt32 aMinor, PRInt32 aRelease, PRInt32 aBuild)
|
|
||||||
{
|
|
||||||
major = aMajor;
|
|
||||||
minor = aMinor;
|
|
||||||
release = aRelease;
|
|
||||||
build = aBuild;
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallVersion::Init(const nsString& version)
|
|
||||||
{
|
|
||||||
PRInt32 errorCode;
|
|
||||||
PRInt32 aMajor, aMinor, aRelease, aBuild;
|
|
||||||
|
|
||||||
major = minor = release = build = 0;
|
|
||||||
|
|
||||||
errorCode = nsInstallVersion::StringToVersionNumbers(version, &aMajor, &aMinor, &aRelease, &aBuild);
|
|
||||||
if (NS_SUCCEEDED(errorCode))
|
|
||||||
{
|
|
||||||
Init(aMajor, aMinor, aRelease, aBuild);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallVersion::GetMajor(PRInt32* aMajor)
|
|
||||||
{
|
|
||||||
*aMajor = major;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallVersion::SetMajor(PRInt32 aMajor)
|
|
||||||
{
|
|
||||||
major = aMajor;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallVersion::GetMinor(PRInt32* aMinor)
|
|
||||||
{
|
|
||||||
*aMinor = minor;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallVersion::SetMinor(PRInt32 aMinor)
|
|
||||||
{
|
|
||||||
minor = aMinor;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallVersion::GetRelease(PRInt32* aRelease)
|
|
||||||
{
|
|
||||||
*aRelease = release;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallVersion::SetRelease(PRInt32 aRelease)
|
|
||||||
{
|
|
||||||
release = aRelease;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallVersion::GetBuild(PRInt32* aBuild)
|
|
||||||
{
|
|
||||||
*aBuild = build;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallVersion::SetBuild(PRInt32 aBuild)
|
|
||||||
{
|
|
||||||
build = aBuild;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallVersion::CompareTo(nsIDOMInstallVersion* aVersion, PRInt32* aReturn)
|
|
||||||
{
|
|
||||||
PRInt32 aMajor, aMinor, aRelease, aBuild;
|
|
||||||
|
|
||||||
aVersion->GetMajor(&aMajor);
|
|
||||||
aVersion->GetMinor(&aMinor);
|
|
||||||
aVersion->GetRelease(&aRelease);
|
|
||||||
aVersion->GetBuild(&aBuild);
|
|
||||||
|
|
||||||
CompareTo(aMajor, aMinor, aRelease, aBuild, aReturn);
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallVersion::CompareTo(const nsString& aAString, PRInt32* aReturn)
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallVersion::CompareTo(PRInt32 aMajor, PRInt32 aMinor, PRInt32 aRelease, PRInt32 aBuild, PRInt32* aReturn)
|
|
||||||
{
|
|
||||||
int diff;
|
|
||||||
|
|
||||||
if ( major == aMajor )
|
|
||||||
{
|
|
||||||
if ( minor == aMinor )
|
|
||||||
{
|
|
||||||
if ( release == aRelease )
|
|
||||||
{
|
|
||||||
if ( build == aBuild )
|
|
||||||
diff = EQUAL;
|
|
||||||
else if ( build > aBuild )
|
|
||||||
diff = BLD_DIFF;
|
|
||||||
else
|
|
||||||
diff = BLD_DIFF_MINUS;
|
|
||||||
}
|
|
||||||
else if ( release > aRelease )
|
|
||||||
diff = REL_DIFF;
|
|
||||||
else
|
|
||||||
diff = REL_DIFF_MINUS;
|
|
||||||
}
|
|
||||||
else if ( minor > aMinor )
|
|
||||||
diff = MINOR_DIFF;
|
|
||||||
else
|
|
||||||
diff = MINOR_DIFF_MINUS;
|
|
||||||
}
|
|
||||||
else if ( major > aMajor )
|
|
||||||
diff = MAJOR_DIFF;
|
|
||||||
else
|
|
||||||
diff = MAJOR_DIFF_MINUS;
|
|
||||||
|
|
||||||
*aReturn = diff;
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallVersion::ToString(nsString& aReturn)
|
|
||||||
{
|
|
||||||
char *result=NULL;
|
|
||||||
result = PR_sprintf_append(result, "%d.%d.%d.%d", major, minor, release, build);
|
|
||||||
|
|
||||||
aReturn = result;
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsInstallVersion::StringToVersionNumbers(const nsString& version, PRInt32 *aMajor, PRInt32 *aMinor, PRInt32 *aRelease, PRInt32 *aBuild)
|
|
||||||
{
|
|
||||||
PRInt32 errorCode;
|
|
||||||
|
|
||||||
int dot = version.Find('.', 0);
|
|
||||||
|
|
||||||
if ( dot == -1 )
|
|
||||||
{
|
|
||||||
*aMajor = version.ToInteger(&errorCode);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nsString majorStr;
|
|
||||||
version.Mid(majorStr, 0, dot);
|
|
||||||
*aMajor = majorStr.ToInteger(&errorCode);
|
|
||||||
|
|
||||||
int prev = dot+1;
|
|
||||||
dot = version.Find('.',prev);
|
|
||||||
if ( dot == -1 )
|
|
||||||
{
|
|
||||||
nsString minorStr;
|
|
||||||
version.Mid(minorStr, prev, version.Length() - prev);
|
|
||||||
*aMinor = minorStr.ToInteger(&errorCode);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nsString minorStr;
|
|
||||||
version.Mid(minorStr, prev, dot - prev);
|
|
||||||
*aMinor = minorStr.ToInteger(&errorCode);
|
|
||||||
|
|
||||||
prev = dot+1;
|
|
||||||
dot = version.Find('.',prev);
|
|
||||||
if ( dot == -1 )
|
|
||||||
{
|
|
||||||
nsString releaseStr;
|
|
||||||
version.Mid(releaseStr, prev, version.Length() - prev);
|
|
||||||
*aRelease = releaseStr.ToInteger(&errorCode);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nsString releaseStr;
|
|
||||||
version.Mid(releaseStr, prev, dot - prev);
|
|
||||||
*aRelease = releaseStr.ToInteger(&errorCode);
|
|
||||||
|
|
||||||
prev = dot+1;
|
|
||||||
if ( version.Length() > dot )
|
|
||||||
{
|
|
||||||
nsString buildStr;
|
|
||||||
version.Mid(buildStr, prev, version.Length() - prev);
|
|
||||||
*aBuild = buildStr.ToInteger(&errorCode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return errorCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
nsInstallVersionFactory::nsInstallVersionFactory(void)
|
|
||||||
{
|
|
||||||
NS_INIT_REFCNT();
|
|
||||||
}
|
|
||||||
|
|
||||||
nsInstallVersionFactory::~nsInstallVersionFactory(void)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(mRefCnt == 0, "non-zero refcnt at destruction");
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallVersionFactory::QueryInterface(const nsIID &aIID, void **aResult)
|
|
||||||
{
|
|
||||||
if (! aResult)
|
|
||||||
return NS_ERROR_NULL_POINTER;
|
|
||||||
|
|
||||||
// Always NULL result, in case of failure
|
|
||||||
*aResult = nsnull;
|
|
||||||
|
|
||||||
if (aIID.Equals(kISupportsIID)) {
|
|
||||||
*aResult = NS_STATIC_CAST(nsISupports*, this);
|
|
||||||
AddRef();
|
|
||||||
return NS_OK;
|
|
||||||
} else if (aIID.Equals(kIFactoryIID)) {
|
|
||||||
*aResult = NS_STATIC_CAST(nsIFactory*, this);
|
|
||||||
AddRef();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
return NS_NOINTERFACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMPL_ADDREF(nsInstallVersionFactory);
|
|
||||||
NS_IMPL_RELEASE(nsInstallVersionFactory);
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallVersionFactory::CreateInstance(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
|
||||||
{
|
|
||||||
if (aResult == NULL)
|
|
||||||
{
|
|
||||||
return NS_ERROR_NULL_POINTER;
|
|
||||||
}
|
|
||||||
|
|
||||||
*aResult = NULL;
|
|
||||||
|
|
||||||
/* do I have to use iSupports? */
|
|
||||||
nsInstallVersion *inst = new nsInstallVersion();
|
|
||||||
|
|
||||||
if (inst == NULL)
|
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
nsresult result = inst->QueryInterface(aIID, aResult);
|
|
||||||
|
|
||||||
if (NS_FAILED(result))
|
|
||||||
delete inst;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsInstallVersionFactory::LockFactory(PRBool aLock)
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
#ifndef __NS_INSTALLVERSION_H__
|
|
||||||
#define __NS_INSTALLVERSION_H__
|
|
||||||
|
|
||||||
#include "nscore.h"
|
|
||||||
#include "nsString.h"
|
|
||||||
#include "nsIFactory.h"
|
|
||||||
#include "nsISupports.h"
|
|
||||||
#include "nsIScriptObjectOwner.h"
|
|
||||||
|
|
||||||
#include "nsIDOMInstallVersion.h"
|
|
||||||
#include "nsSoftwareUpdate.h"
|
|
||||||
|
|
||||||
#include "prtypes.h"
|
|
||||||
|
|
||||||
class nsInstallVersion: public nsIScriptObjectOwner, public nsIDOMInstallVersion
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static const nsIID& IID() { static nsIID iid = NS_SoftwareUpdateInstallVersion_CID; return iid; }
|
|
||||||
|
|
||||||
nsInstallVersion();
|
|
||||||
virtual ~nsInstallVersion();
|
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS
|
|
||||||
|
|
||||||
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
|
|
||||||
NS_IMETHOD SetScriptObject(void* aScriptObject);
|
|
||||||
|
|
||||||
NS_IMETHOD Init(PRInt32 aMajor, PRInt32 aMinor, PRInt32 aRelease, PRInt32 aBuild);
|
|
||||||
NS_IMETHOD Init(const nsString& aVersionString);
|
|
||||||
|
|
||||||
NS_IMETHOD GetMajor(PRInt32* aMajor);
|
|
||||||
NS_IMETHOD SetMajor(PRInt32 aMajor);
|
|
||||||
|
|
||||||
NS_IMETHOD GetMinor(PRInt32* aMinor);
|
|
||||||
NS_IMETHOD SetMinor(PRInt32 aMinor);
|
|
||||||
|
|
||||||
NS_IMETHOD GetRelease(PRInt32* aRelease);
|
|
||||||
NS_IMETHOD SetRelease(PRInt32 aRelease);
|
|
||||||
|
|
||||||
NS_IMETHOD GetBuild(PRInt32* aBuild);
|
|
||||||
NS_IMETHOD SetBuild(PRInt32 aBuild);
|
|
||||||
|
|
||||||
NS_IMETHOD ToString(nsString& aReturn);
|
|
||||||
NS_IMETHOD CompareTo(nsIDOMInstallVersion* aVersion, PRInt32* aReturn);
|
|
||||||
NS_IMETHOD CompareTo(const nsString& aString, PRInt32* aReturn);
|
|
||||||
NS_IMETHOD CompareTo(PRInt32 aMajor, PRInt32 aMinor, PRInt32 aRelease, PRInt32 aBuild, PRInt32* aReturn);
|
|
||||||
|
|
||||||
static nsresult StringToVersionNumbers(const nsString& version, PRInt32 *aMajor, PRInt32 *aMinor, PRInt32 *aRelease, PRInt32 *aBuild);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void *mScriptObject;
|
|
||||||
PRInt32 major;
|
|
||||||
PRInt32 minor;
|
|
||||||
PRInt32 release;
|
|
||||||
PRInt32 build;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class nsInstallVersionFactory : public nsIFactory
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
nsInstallVersionFactory();
|
|
||||||
virtual ~nsInstallVersionFactory();
|
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS
|
|
||||||
|
|
||||||
NS_IMETHOD CreateInstance(nsISupports *aOuter,
|
|
||||||
REFNSIID aIID,
|
|
||||||
void **aResult);
|
|
||||||
|
|
||||||
NS_IMETHOD LockFactory(PRBool aLock);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,665 +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.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.
|
|
||||||
*/
|
|
||||||
/* AUTO-GENERATED. DO NOT EDIT!!! */
|
|
||||||
|
|
||||||
#include "jsapi.h"
|
|
||||||
#include "nsJSUtils.h"
|
|
||||||
#include "nscore.h"
|
|
||||||
#include "nsIScriptContext.h"
|
|
||||||
#include "nsIJSScriptObject.h"
|
|
||||||
#include "nsIScriptObjectOwner.h"
|
|
||||||
#include "nsIScriptGlobalObject.h"
|
|
||||||
#include "nsIPtr.h"
|
|
||||||
#include "nsString.h"
|
|
||||||
#include "nsIDOMInstallVersion.h"
|
|
||||||
#include "nsIDOMInstallTriggerGlobal.h"
|
|
||||||
|
|
||||||
extern void ConvertJSValToStr(nsString& aString,
|
|
||||||
JSContext* aContext,
|
|
||||||
jsval aValue);
|
|
||||||
|
|
||||||
extern void ConvertStrToJSVal(const nsString& aProp,
|
|
||||||
JSContext* aContext,
|
|
||||||
jsval* aReturn);
|
|
||||||
|
|
||||||
extern PRBool ConvertJSValToBool(PRBool* aProp,
|
|
||||||
JSContext* aContext,
|
|
||||||
jsval aValue);
|
|
||||||
|
|
||||||
extern PRBool ConvertJSValToObj(nsISupports** aSupports,
|
|
||||||
REFNSIID aIID,
|
|
||||||
const nsString& aTypeName,
|
|
||||||
JSContext* aContext,
|
|
||||||
jsval aValue);
|
|
||||||
|
|
||||||
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
|
|
||||||
static NS_DEFINE_IID(kIJSScriptObjectIID, NS_IJSSCRIPTOBJECT_IID);
|
|
||||||
static NS_DEFINE_IID(kIScriptGlobalObjectIID, NS_ISCRIPTGLOBALOBJECT_IID);
|
|
||||||
static NS_DEFINE_IID(kIInstallTriggerGlobalIID, NS_IDOMINSTALLTRIGGERGLOBAL_IID);
|
|
||||||
|
|
||||||
NS_DEF_PTR(nsIDOMInstallTriggerGlobal);
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************/
|
|
||||||
//
|
|
||||||
// InstallTriggerGlobal Properties Getter
|
|
||||||
//
|
|
||||||
PR_STATIC_CALLBACK(JSBool)
|
|
||||||
GetInstallTriggerGlobalProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|
||||||
{
|
|
||||||
nsIDOMInstallTriggerGlobal *a = (nsIDOMInstallTriggerGlobal*)JS_GetPrivate(cx, obj);
|
|
||||||
|
|
||||||
// If there's no private data, this must be the prototype, so ignore
|
|
||||||
if (nsnull == a) {
|
|
||||||
return JS_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (JSVAL_IS_INT(id)) {
|
|
||||||
switch(JSVAL_TO_INT(id)) {
|
|
||||||
case 0:
|
|
||||||
default:
|
|
||||||
return nsJSUtils::nsCallJSScriptObjectGetProperty(a, cx, id, vp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nsJSUtils::nsCallJSScriptObjectGetProperty(a, cx, id, vp);
|
|
||||||
}
|
|
||||||
|
|
||||||
return PR_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************/
|
|
||||||
//
|
|
||||||
// InstallTriggerGlobal Properties Setter
|
|
||||||
//
|
|
||||||
PR_STATIC_CALLBACK(JSBool)
|
|
||||||
SetInstallTriggerGlobalProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|
||||||
{
|
|
||||||
nsIDOMInstallTriggerGlobal *a = (nsIDOMInstallTriggerGlobal*)JS_GetPrivate(cx, obj);
|
|
||||||
|
|
||||||
// If there's no private data, this must be the prototype, so ignore
|
|
||||||
if (nsnull == a) {
|
|
||||||
return JS_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (JSVAL_IS_INT(id)) {
|
|
||||||
switch(JSVAL_TO_INT(id)) {
|
|
||||||
case 0:
|
|
||||||
default:
|
|
||||||
return nsJSUtils::nsCallJSScriptObjectSetProperty(a, cx, id, vp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nsJSUtils::nsCallJSScriptObjectSetProperty(a, cx, id, vp);
|
|
||||||
}
|
|
||||||
|
|
||||||
return PR_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// InstallTriggerGlobal finalizer
|
|
||||||
//
|
|
||||||
PR_STATIC_CALLBACK(void)
|
|
||||||
FinalizeInstallTriggerGlobal(JSContext *cx, JSObject *obj)
|
|
||||||
{
|
|
||||||
nsJSUtils::nsGenericFinalize(cx, obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// InstallTriggerGlobal enumerate
|
|
||||||
//
|
|
||||||
PR_STATIC_CALLBACK(JSBool)
|
|
||||||
EnumerateInstallTriggerGlobal(JSContext *cx, JSObject *obj)
|
|
||||||
{
|
|
||||||
return nsJSUtils::nsGenericEnumerate(cx, obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// InstallTriggerGlobal resolve
|
|
||||||
//
|
|
||||||
PR_STATIC_CALLBACK(JSBool)
|
|
||||||
ResolveInstallTriggerGlobal(JSContext *cx, JSObject *obj, jsval id)
|
|
||||||
{
|
|
||||||
return nsJSUtils::nsGenericResolve(cx, obj, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Native method UpdateEnabled
|
|
||||||
//
|
|
||||||
PR_STATIC_CALLBACK(JSBool)
|
|
||||||
InstallTriggerGlobalUpdateEnabled(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|
||||||
{
|
|
||||||
nsIDOMInstallTriggerGlobal *nativeThis = (nsIDOMInstallTriggerGlobal*)JS_GetPrivate(cx, obj);
|
|
||||||
JSBool rBool = JS_FALSE;
|
|
||||||
PRBool nativeRet;
|
|
||||||
|
|
||||||
*rval = JSVAL_NULL;
|
|
||||||
|
|
||||||
// If there's no private data, this must be the prototype, so ignore
|
|
||||||
if (nsnull == nativeThis) {
|
|
||||||
return JS_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (argc >= 0) {
|
|
||||||
|
|
||||||
if (NS_OK != nativeThis->UpdateEnabled(&nativeRet)) {
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
*rval = BOOLEAN_TO_JSVAL(nativeRet);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
JS_ReportError(cx, "Function UpdateEnabled requires 0 parameters");
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return JS_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Native method StartSoftwareUpdate
|
|
||||||
//
|
|
||||||
PR_STATIC_CALLBACK(JSBool)
|
|
||||||
InstallTriggerGlobalStartSoftwareUpdate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|
||||||
{
|
|
||||||
nsIDOMInstallTriggerGlobal *nativeThis = (nsIDOMInstallTriggerGlobal*)JS_GetPrivate(cx, obj);
|
|
||||||
JSBool rBool = JS_FALSE;
|
|
||||||
PRInt32 nativeRet;
|
|
||||||
nsAutoString b0;
|
|
||||||
PRInt32 b1;
|
|
||||||
|
|
||||||
*rval = JSVAL_NULL;
|
|
||||||
|
|
||||||
// If there's no private data, this must be the prototype, so ignore
|
|
||||||
if (nsnull == nativeThis) {
|
|
||||||
return JS_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (argc >= 2)
|
|
||||||
{
|
|
||||||
// public int StartSoftwareUpdate(String url,
|
|
||||||
// int flag);
|
|
||||||
|
|
||||||
ConvertJSValToStr(b0, cx, argv[0]);
|
|
||||||
|
|
||||||
if(!JS_ValueToInt32(cx, argv[1], (int32 *)&b1))
|
|
||||||
{
|
|
||||||
JS_ReportError(cx, "2nd parameter must be a number");
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(NS_OK != nativeThis->StartSoftwareUpdate(b0, b1, &nativeRet))
|
|
||||||
{
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
*rval = INT_TO_JSVAL(nativeRet);
|
|
||||||
}
|
|
||||||
else if(argc >= 1)
|
|
||||||
{
|
|
||||||
// public int StartSoftwareUpdate(String url);
|
|
||||||
|
|
||||||
ConvertJSValToStr(b0, cx, argv[0]);
|
|
||||||
|
|
||||||
if(NS_OK != nativeThis->StartSoftwareUpdate(b0, &nativeRet))
|
|
||||||
{
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
*rval = INT_TO_JSVAL(nativeRet);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
JS_ReportError(cx, "Function StartSoftwareUpdate requires 2 parameters");
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return JS_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Native method ConditionalSoftwareUpdate
|
|
||||||
//
|
|
||||||
PR_STATIC_CALLBACK(JSBool)
|
|
||||||
InstallTriggerGlobalConditionalSoftwareUpdate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|
||||||
{
|
|
||||||
nsIDOMInstallTriggerGlobal *nativeThis = (nsIDOMInstallTriggerGlobal*)JS_GetPrivate(cx, obj);
|
|
||||||
JSBool rBool = JS_FALSE;
|
|
||||||
PRInt32 nativeRet;
|
|
||||||
nsAutoString b0;
|
|
||||||
nsAutoString b1;
|
|
||||||
nsAutoString b2str;
|
|
||||||
PRInt32 b2int;
|
|
||||||
nsAutoString b3str;
|
|
||||||
PRInt32 b3int;
|
|
||||||
PRInt32 b4;
|
|
||||||
|
|
||||||
*rval = JSVAL_NULL;
|
|
||||||
|
|
||||||
// If there's no private data, this must be the prototype, so ignore
|
|
||||||
if (nsnull == nativeThis) {
|
|
||||||
return JS_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(argc >= 5)
|
|
||||||
{
|
|
||||||
// public int ConditionalSoftwareUpdate(String url,
|
|
||||||
// String registryName,
|
|
||||||
// int diffLevel,
|
|
||||||
// String version, --OR-- VersionInfo version
|
|
||||||
// int mode);
|
|
||||||
|
|
||||||
ConvertJSValToStr(b0, cx, argv[0]);
|
|
||||||
ConvertJSValToStr(b1, cx, argv[1]);
|
|
||||||
|
|
||||||
if(!JS_ValueToInt32(cx, argv[2], (int32 *)&b2int))
|
|
||||||
{
|
|
||||||
JS_ReportError(cx, "3rd parameter must be a number");
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!JS_ValueToInt32(cx, argv[4], (int32 *)&b4))
|
|
||||||
{
|
|
||||||
JS_ReportError(cx, "5th parameter must be a number");
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(JSVAL_IS_OBJECT(argv[3]))
|
|
||||||
{
|
|
||||||
JSObject* jsobj = JSVAL_TO_OBJECT(argv[3]);
|
|
||||||
JSClass* jsclass = JS_GetClass(cx, jsobj);
|
|
||||||
if((nsnull != jsclass) && (jsclass->flags & JSCLASS_HAS_PRIVATE))
|
|
||||||
{
|
|
||||||
nsIDOMInstallVersion* version = (nsIDOMInstallVersion*)JS_GetPrivate(cx, jsobj);
|
|
||||||
|
|
||||||
if(NS_OK != nativeThis->ConditionalSoftwareUpdate(b0, b1, b2int, version, b4, &nativeRet))
|
|
||||||
{
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ConvertJSValToStr(b3str, cx, argv[3]);
|
|
||||||
if(NS_OK != nativeThis->ConditionalSoftwareUpdate(b0, b1, b2int, b3str, b4, &nativeRet))
|
|
||||||
{
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*rval = INT_TO_JSVAL(nativeRet);
|
|
||||||
}
|
|
||||||
else if(argc >= 4)
|
|
||||||
{
|
|
||||||
// public int ConditionalSoftwareUpdate(String url,
|
|
||||||
// String registryName,
|
|
||||||
// String version, --OR-- VersionInfo version
|
|
||||||
// int mode);
|
|
||||||
|
|
||||||
ConvertJSValToStr(b0, cx, argv[0]);
|
|
||||||
ConvertJSValToStr(b1, cx, argv[1]);
|
|
||||||
|
|
||||||
if(!JS_ValueToInt32(cx, argv[3], (int32 *)&b3int))
|
|
||||||
{
|
|
||||||
JS_ReportError(cx, "4th parameter must be a number");
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(JSVAL_IS_OBJECT(argv[2]))
|
|
||||||
{
|
|
||||||
JSObject* jsobj = JSVAL_TO_OBJECT(argv[2]);
|
|
||||||
JSClass* jsclass = JS_GetClass(cx, jsobj);
|
|
||||||
if((nsnull != jsclass) && (jsclass->flags & JSCLASS_HAS_PRIVATE))
|
|
||||||
{
|
|
||||||
nsIDOMInstallVersion* version = (nsIDOMInstallVersion*)JS_GetPrivate(cx, jsobj);
|
|
||||||
|
|
||||||
if(NS_OK != nativeThis->ConditionalSoftwareUpdate(b0, b1, version, b3int, &nativeRet))
|
|
||||||
{
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ConvertJSValToStr(b2str, cx, argv[2]);
|
|
||||||
if(NS_OK != nativeThis->ConditionalSoftwareUpdate(b0, b1, b2str, b3int, &nativeRet))
|
|
||||||
{
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*rval = INT_TO_JSVAL(nativeRet);
|
|
||||||
}
|
|
||||||
else if(argc >= 3)
|
|
||||||
{
|
|
||||||
// public int ConditionalSoftwareUpdate(String url,
|
|
||||||
// String registryName,
|
|
||||||
// String version); --OR-- VersionInfo version
|
|
||||||
|
|
||||||
ConvertJSValToStr(b0, cx, argv[0]);
|
|
||||||
ConvertJSValToStr(b1, cx, argv[1]);
|
|
||||||
|
|
||||||
if(JSVAL_IS_OBJECT(argv[2]))
|
|
||||||
{
|
|
||||||
JSObject* jsobj = JSVAL_TO_OBJECT(argv[2]);
|
|
||||||
JSClass* jsclass = JS_GetClass(cx, jsobj);
|
|
||||||
if((nsnull != jsclass) && (jsclass->flags & JSCLASS_HAS_PRIVATE))
|
|
||||||
{
|
|
||||||
nsIDOMInstallVersion* version = (nsIDOMInstallVersion*)JS_GetPrivate(cx, jsobj);
|
|
||||||
|
|
||||||
if(NS_OK != nativeThis->ConditionalSoftwareUpdate(b0, b1, version, &nativeRet))
|
|
||||||
{
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ConvertJSValToStr(b2str, cx, argv[2]);
|
|
||||||
if(NS_OK != nativeThis->ConditionalSoftwareUpdate(b0, b1, b2str, &nativeRet))
|
|
||||||
{
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*rval = INT_TO_JSVAL(nativeRet);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
JS_ReportError(cx, "Function ConditionalSoftwareUpdate requires 5 parameters");
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return JS_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Native method CompareVersion
|
|
||||||
//
|
|
||||||
PR_STATIC_CALLBACK(JSBool)
|
|
||||||
InstallTriggerGlobalCompareVersion(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|
||||||
{
|
|
||||||
nsIDOMInstallTriggerGlobal *nativeThis = (nsIDOMInstallTriggerGlobal*)JS_GetPrivate(cx, obj);
|
|
||||||
JSBool rBool = JS_FALSE;
|
|
||||||
PRInt32 nativeRet;
|
|
||||||
nsAutoString b0;
|
|
||||||
nsAutoString b1str;
|
|
||||||
PRInt32 b1int;
|
|
||||||
PRInt32 b2int;
|
|
||||||
PRInt32 b3int;
|
|
||||||
PRInt32 b4int;
|
|
||||||
|
|
||||||
*rval = JSVAL_NULL;
|
|
||||||
|
|
||||||
// If there's no private data, this must be the prototype, so ignore
|
|
||||||
if (nsnull == nativeThis) {
|
|
||||||
return JS_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(argc >= 5)
|
|
||||||
{
|
|
||||||
// public int CompareVersion(String registryName,
|
|
||||||
// int major,
|
|
||||||
// int minor,
|
|
||||||
// int release,
|
|
||||||
// int build);
|
|
||||||
|
|
||||||
ConvertJSValToStr(b0, cx, argv[0]);
|
|
||||||
|
|
||||||
if(!JS_ValueToInt32(cx, argv[1], (int32 *)&b1int))
|
|
||||||
{
|
|
||||||
JS_ReportError(cx, "2th parameter must be a number");
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
if(!JS_ValueToInt32(cx, argv[2], (int32 *)&b2int))
|
|
||||||
{
|
|
||||||
JS_ReportError(cx, "3th parameter must be a number");
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
if(!JS_ValueToInt32(cx, argv[3], (int32 *)&b3int))
|
|
||||||
{
|
|
||||||
JS_ReportError(cx, "4th parameter must be a number");
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
if(!JS_ValueToInt32(cx, argv[4], (int32 *)&b4int))
|
|
||||||
{
|
|
||||||
JS_ReportError(cx, "5th parameter must be a number");
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(NS_OK != nativeThis->CompareVersion(b0, b1int, b2int, b3int, b4int, &nativeRet))
|
|
||||||
{
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
*rval = INT_TO_JSVAL(nativeRet);
|
|
||||||
}
|
|
||||||
else if(argc >= 2)
|
|
||||||
{
|
|
||||||
// public int CompareVersion(String registryName,
|
|
||||||
// String version); --OR-- VersionInfo version
|
|
||||||
|
|
||||||
ConvertJSValToStr(b0, cx, argv[0]);
|
|
||||||
|
|
||||||
if(JSVAL_IS_OBJECT(argv[1]))
|
|
||||||
{
|
|
||||||
JSObject* jsobj = JSVAL_TO_OBJECT(argv[1]);
|
|
||||||
JSClass* jsclass = JS_GetClass(cx, jsobj);
|
|
||||||
if((nsnull != jsclass) && (jsclass->flags & JSCLASS_HAS_PRIVATE))
|
|
||||||
{
|
|
||||||
nsIDOMInstallVersion* version = (nsIDOMInstallVersion*)JS_GetPrivate(cx, jsobj);
|
|
||||||
|
|
||||||
if(NS_OK != nativeThis->CompareVersion(b0, version, &nativeRet))
|
|
||||||
{
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ConvertJSValToStr(b1str, cx, argv[1]);
|
|
||||||
if(NS_OK != nativeThis->CompareVersion(b0, b1str, &nativeRet))
|
|
||||||
{
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*rval = INT_TO_JSVAL(nativeRet);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
JS_ReportError(cx, "Function CompareVersion requires 5 parameters");
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return JS_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************/
|
|
||||||
//
|
|
||||||
// class for InstallTriggerGlobal
|
|
||||||
//
|
|
||||||
JSClass InstallTriggerGlobalClass = {
|
|
||||||
"InstallTriggerGlobal",
|
|
||||||
JSCLASS_HAS_PRIVATE,
|
|
||||||
JS_PropertyStub,
|
|
||||||
JS_PropertyStub,
|
|
||||||
GetInstallTriggerGlobalProperty,
|
|
||||||
SetInstallTriggerGlobalProperty,
|
|
||||||
EnumerateInstallTriggerGlobal,
|
|
||||||
ResolveInstallTriggerGlobal,
|
|
||||||
JS_ConvertStub,
|
|
||||||
FinalizeInstallTriggerGlobal
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// InstallTriggerGlobal class properties
|
|
||||||
//
|
|
||||||
static JSPropertySpec InstallTriggerGlobalProperties[] =
|
|
||||||
{
|
|
||||||
{0}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// InstallTriggerGlobal class methods
|
|
||||||
//
|
|
||||||
static JSFunctionSpec InstallTriggerGlobalMethods[] =
|
|
||||||
{
|
|
||||||
{"UpdateEnabled", InstallTriggerGlobalUpdateEnabled, 0},
|
|
||||||
{"StartSoftwareUpdate", InstallTriggerGlobalStartSoftwareUpdate, 2},
|
|
||||||
{"ConditionalSoftwareUpdate", InstallTriggerGlobalConditionalSoftwareUpdate, 5},
|
|
||||||
{"CompareVersion", InstallTriggerGlobalCompareVersion, 5},
|
|
||||||
{0}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// InstallTriggerGlobal constructor
|
|
||||||
//
|
|
||||||
PR_STATIC_CALLBACK(JSBool)
|
|
||||||
InstallTriggerGlobal(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|
||||||
{
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// InstallTriggerGlobal class initialization
|
|
||||||
//
|
|
||||||
nsresult NS_InitInstallTriggerGlobalClass(nsIScriptContext *aContext, void **aPrototype)
|
|
||||||
{
|
|
||||||
JSContext *jscontext = (JSContext *)aContext->GetNativeContext();
|
|
||||||
JSObject *proto = nsnull;
|
|
||||||
JSObject *constructor = nsnull;
|
|
||||||
JSObject *parent_proto = nsnull;
|
|
||||||
JSObject *global = JS_GetGlobalObject(jscontext);
|
|
||||||
jsval vp;
|
|
||||||
|
|
||||||
if ((PR_TRUE != JS_LookupProperty(jscontext, global, "InstallTriggerGlobal", &vp)) ||
|
|
||||||
!JSVAL_IS_OBJECT(vp) ||
|
|
||||||
((constructor = JSVAL_TO_OBJECT(vp)) == nsnull) ||
|
|
||||||
(PR_TRUE != JS_LookupProperty(jscontext, JSVAL_TO_OBJECT(vp), "prototype", &vp)) ||
|
|
||||||
!JSVAL_IS_OBJECT(vp)) {
|
|
||||||
|
|
||||||
proto = JS_InitClass(jscontext, // context
|
|
||||||
global, // global object
|
|
||||||
parent_proto, // parent proto
|
|
||||||
&InstallTriggerGlobalClass, // JSClass
|
|
||||||
InstallTriggerGlobal, // JSNative ctor
|
|
||||||
0, // ctor args
|
|
||||||
InstallTriggerGlobalProperties, // proto props
|
|
||||||
InstallTriggerGlobalMethods, // proto funcs
|
|
||||||
nsnull, // ctor props (static)
|
|
||||||
nsnull); // ctor funcs (static)
|
|
||||||
if (nsnull == proto) {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((PR_TRUE == JS_LookupProperty(jscontext, global, "InstallTriggerGlobal", &vp)) &&
|
|
||||||
JSVAL_IS_OBJECT(vp) &&
|
|
||||||
((constructor = JSVAL_TO_OBJECT(vp)) != nsnull)) {
|
|
||||||
vp = INT_TO_JSVAL(nsIDOMInstallTriggerGlobal::MAJOR_DIFF);
|
|
||||||
JS_SetProperty(jscontext, constructor, "MAJOR_DIFF", &vp);
|
|
||||||
|
|
||||||
vp = INT_TO_JSVAL(nsIDOMInstallTriggerGlobal::MINOR_DIFF);
|
|
||||||
JS_SetProperty(jscontext, constructor, "MINOR_DIFF", &vp);
|
|
||||||
|
|
||||||
vp = INT_TO_JSVAL(nsIDOMInstallTriggerGlobal::REL_DIFF);
|
|
||||||
JS_SetProperty(jscontext, constructor, "REL_DIFF", &vp);
|
|
||||||
|
|
||||||
vp = INT_TO_JSVAL(nsIDOMInstallTriggerGlobal::BLD_DIFF);
|
|
||||||
JS_SetProperty(jscontext, constructor, "BLD_DIFF", &vp);
|
|
||||||
|
|
||||||
vp = INT_TO_JSVAL(nsIDOMInstallTriggerGlobal::EQUAL);
|
|
||||||
JS_SetProperty(jscontext, constructor, "EQUAL", &vp);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else if ((nsnull != constructor) && JSVAL_IS_OBJECT(vp)) {
|
|
||||||
proto = JSVAL_TO_OBJECT(vp);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aPrototype) {
|
|
||||||
*aPrototype = proto;
|
|
||||||
}
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Method for creating a new InstallTriggerGlobal JavaScript object
|
|
||||||
//
|
|
||||||
extern "C" NS_DOM nsresult NS_NewScriptInstallTriggerGlobal(nsIScriptContext *aContext, nsISupports *aSupports, nsISupports *aParent, void **aReturn)
|
|
||||||
{
|
|
||||||
NS_PRECONDITION(nsnull != aContext && nsnull != aSupports && nsnull != aReturn, "null argument to NS_NewScriptInstallTriggerGlobal");
|
|
||||||
JSObject *proto;
|
|
||||||
JSObject *parent;
|
|
||||||
nsIScriptObjectOwner *owner;
|
|
||||||
JSContext *jscontext = (JSContext *)aContext->GetNativeContext();
|
|
||||||
nsresult result = NS_OK;
|
|
||||||
nsIDOMInstallTriggerGlobal *aInstallTriggerGlobal;
|
|
||||||
|
|
||||||
if (nsnull == aParent) {
|
|
||||||
parent = nsnull;
|
|
||||||
}
|
|
||||||
else if (NS_OK == aParent->QueryInterface(kIScriptObjectOwnerIID, (void**)&owner)) {
|
|
||||||
if (NS_OK != owner->GetScriptObject(aContext, (void **)&parent)) {
|
|
||||||
NS_RELEASE(owner);
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
NS_RELEASE(owner);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NS_OK != NS_InitInstallTriggerGlobalClass(aContext, (void **)&proto)) {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = aSupports->QueryInterface(kIInstallTriggerGlobalIID, (void **)&aInstallTriggerGlobal);
|
|
||||||
if (NS_OK != result) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// create a js object for this class
|
|
||||||
*aReturn = JS_NewObject(jscontext, &InstallTriggerGlobalClass, proto, parent);
|
|
||||||
if (nsnull != *aReturn) {
|
|
||||||
// connect the native object to the js object
|
|
||||||
JS_SetPrivate(jscontext, (JSObject *)*aReturn, aInstallTriggerGlobal);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
NS_RELEASE(aInstallTriggerGlobal);
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
@@ -1,659 +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.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.
|
|
||||||
*/
|
|
||||||
/* AUTO-GENERATED. DO NOT EDIT!!! */
|
|
||||||
|
|
||||||
#include "jsapi.h"
|
|
||||||
#include "nsJSUtils.h"
|
|
||||||
#include "nscore.h"
|
|
||||||
#include "nsIScriptContext.h"
|
|
||||||
#include "nsIJSScriptObject.h"
|
|
||||||
#include "nsIScriptObjectOwner.h"
|
|
||||||
#include "nsIScriptGlobalObject.h"
|
|
||||||
#include "nsIPtr.h"
|
|
||||||
#include "nsString.h"
|
|
||||||
#include "nsIDOMInstallVersion.h"
|
|
||||||
#include "nsIScriptNameSpaceManager.h"
|
|
||||||
#include "nsRepository.h"
|
|
||||||
#include "nsDOMCID.h"
|
|
||||||
|
|
||||||
extern void ConvertJSValToStr(nsString& aString,
|
|
||||||
JSContext* aContext,
|
|
||||||
jsval aValue);
|
|
||||||
|
|
||||||
extern void ConvertStrToJSVal(const nsString& aProp,
|
|
||||||
JSContext* aContext,
|
|
||||||
jsval* aReturn);
|
|
||||||
|
|
||||||
extern PRBool ConvertJSValToBool(PRBool* aProp,
|
|
||||||
JSContext* aContext,
|
|
||||||
jsval aValue);
|
|
||||||
|
|
||||||
extern PRBool ConvertJSValToObj(nsISupports** aSupports,
|
|
||||||
REFNSIID aIID,
|
|
||||||
const nsString& aTypeName,
|
|
||||||
JSContext* aContext,
|
|
||||||
jsval aValue);
|
|
||||||
|
|
||||||
void ConvertJSvalToVersionString(nsString& versionString, JSContext* cx, jsval* argument);
|
|
||||||
|
|
||||||
|
|
||||||
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
|
|
||||||
static NS_DEFINE_IID(kIJSScriptObjectIID, NS_IJSSCRIPTOBJECT_IID);
|
|
||||||
static NS_DEFINE_IID(kIScriptGlobalObjectIID, NS_ISCRIPTGLOBALOBJECT_IID);
|
|
||||||
static NS_DEFINE_IID(kIInstallVersionIID, NS_IDOMINSTALLVERSION_IID);
|
|
||||||
|
|
||||||
NS_DEF_PTR(nsIDOMInstallVersion);
|
|
||||||
|
|
||||||
//
|
|
||||||
// InstallVersion property ids
|
|
||||||
//
|
|
||||||
enum InstallVersion_slots {
|
|
||||||
INSTALLVERSION_MAJOR = -1,
|
|
||||||
INSTALLVERSION_MINOR = -2,
|
|
||||||
INSTALLVERSION_RELEASE = -3,
|
|
||||||
INSTALLVERSION_BUILD = -4
|
|
||||||
};
|
|
||||||
|
|
||||||
/***********************************************************************/
|
|
||||||
//
|
|
||||||
// InstallVersion Properties Getter
|
|
||||||
//
|
|
||||||
PR_STATIC_CALLBACK(JSBool)
|
|
||||||
GetInstallVersionProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|
||||||
{
|
|
||||||
nsIDOMInstallVersion *a = (nsIDOMInstallVersion*)JS_GetPrivate(cx, obj);
|
|
||||||
|
|
||||||
// If there's no private data, this must be the prototype, so ignore
|
|
||||||
if (nsnull == a) {
|
|
||||||
return JS_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (JSVAL_IS_INT(id)) {
|
|
||||||
switch(JSVAL_TO_INT(id)) {
|
|
||||||
case INSTALLVERSION_MAJOR:
|
|
||||||
{
|
|
||||||
PRInt32 prop;
|
|
||||||
if (NS_OK == a->GetMajor(&prop)) {
|
|
||||||
*vp = INT_TO_JSVAL(prop);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case INSTALLVERSION_MINOR:
|
|
||||||
{
|
|
||||||
PRInt32 prop;
|
|
||||||
if (NS_OK == a->GetMinor(&prop)) {
|
|
||||||
*vp = INT_TO_JSVAL(prop);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case INSTALLVERSION_RELEASE:
|
|
||||||
{
|
|
||||||
PRInt32 prop;
|
|
||||||
if (NS_OK == a->GetRelease(&prop)) {
|
|
||||||
*vp = INT_TO_JSVAL(prop);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case INSTALLVERSION_BUILD:
|
|
||||||
{
|
|
||||||
PRInt32 prop;
|
|
||||||
if (NS_OK == a->GetBuild(&prop)) {
|
|
||||||
*vp = INT_TO_JSVAL(prop);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return nsJSUtils::nsCallJSScriptObjectGetProperty(a, cx, id, vp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nsJSUtils::nsCallJSScriptObjectGetProperty(a, cx, id, vp);
|
|
||||||
}
|
|
||||||
|
|
||||||
return PR_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************/
|
|
||||||
//
|
|
||||||
// InstallVersion Properties Setter
|
|
||||||
//
|
|
||||||
PR_STATIC_CALLBACK(JSBool)
|
|
||||||
SetInstallVersionProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|
||||||
{
|
|
||||||
nsIDOMInstallVersion *a = (nsIDOMInstallVersion*)JS_GetPrivate(cx, obj);
|
|
||||||
|
|
||||||
// If there's no private data, this must be the prototype, so ignore
|
|
||||||
if (nsnull == a) {
|
|
||||||
return JS_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (JSVAL_IS_INT(id)) {
|
|
||||||
switch(JSVAL_TO_INT(id)) {
|
|
||||||
case INSTALLVERSION_MAJOR:
|
|
||||||
{
|
|
||||||
PRInt32 prop;
|
|
||||||
int32 temp;
|
|
||||||
if (JSVAL_IS_NUMBER(*vp) && JS_ValueToInt32(cx, *vp, &temp)) {
|
|
||||||
prop = (PRInt32)temp;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
JS_ReportError(cx, "Parameter must be a number");
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
a->SetMajor(prop);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case INSTALLVERSION_MINOR:
|
|
||||||
{
|
|
||||||
PRInt32 prop;
|
|
||||||
int32 temp;
|
|
||||||
if (JSVAL_IS_NUMBER(*vp) && JS_ValueToInt32(cx, *vp, &temp)) {
|
|
||||||
prop = (PRInt32)temp;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
JS_ReportError(cx, "Parameter must be a number");
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
a->SetMinor(prop);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case INSTALLVERSION_RELEASE:
|
|
||||||
{
|
|
||||||
PRInt32 prop;
|
|
||||||
int32 temp;
|
|
||||||
if (JSVAL_IS_NUMBER(*vp) && JS_ValueToInt32(cx, *vp, &temp)) {
|
|
||||||
prop = (PRInt32)temp;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
JS_ReportError(cx, "Parameter must be a number");
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
a->SetRelease(prop);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case INSTALLVERSION_BUILD:
|
|
||||||
{
|
|
||||||
PRInt32 prop;
|
|
||||||
int32 temp;
|
|
||||||
if (JSVAL_IS_NUMBER(*vp) && JS_ValueToInt32(cx, *vp, &temp)) {
|
|
||||||
prop = (PRInt32)temp;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
JS_ReportError(cx, "Parameter must be a number");
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
a->SetBuild(prop);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return nsJSUtils::nsCallJSScriptObjectSetProperty(a, cx, id, vp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nsJSUtils::nsCallJSScriptObjectSetProperty(a, cx, id, vp);
|
|
||||||
}
|
|
||||||
|
|
||||||
return PR_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// InstallVersion finalizer
|
|
||||||
//
|
|
||||||
PR_STATIC_CALLBACK(void)
|
|
||||||
FinalizeInstallVersion(JSContext *cx, JSObject *obj)
|
|
||||||
{
|
|
||||||
nsJSUtils::nsGenericFinalize(cx, obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// InstallVersion enumerate
|
|
||||||
//
|
|
||||||
PR_STATIC_CALLBACK(JSBool)
|
|
||||||
EnumerateInstallVersion(JSContext *cx, JSObject *obj)
|
|
||||||
{
|
|
||||||
return nsJSUtils::nsGenericEnumerate(cx, obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// InstallVersion resolve
|
|
||||||
//
|
|
||||||
PR_STATIC_CALLBACK(JSBool)
|
|
||||||
ResolveInstallVersion(JSContext *cx, JSObject *obj, jsval id)
|
|
||||||
{
|
|
||||||
return nsJSUtils::nsGenericResolve(cx, obj, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Native method Init
|
|
||||||
//
|
|
||||||
PR_STATIC_CALLBACK(JSBool)
|
|
||||||
InstallVersionInit(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|
||||||
{
|
|
||||||
nsIDOMInstallVersion *nativeThis = (nsIDOMInstallVersion*)JS_GetPrivate(cx, obj);
|
|
||||||
JSBool rBool = JS_FALSE;
|
|
||||||
nsAutoString b0;
|
|
||||||
|
|
||||||
*rval = JSVAL_NULL;
|
|
||||||
|
|
||||||
// If there's no private data, this must be the prototype, so ignore
|
|
||||||
if (nsnull == nativeThis) {
|
|
||||||
return JS_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (argc >= 1) {
|
|
||||||
|
|
||||||
nsJSUtils::nsConvertJSValToString(b0, cx, argv[0]);
|
|
||||||
|
|
||||||
if (NS_OK != nativeThis->Init(b0)) {
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
*rval = JSVAL_VOID;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
JS_ReportError(cx, "Function init requires 1 parameters");
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return JS_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Native method ToString
|
|
||||||
//
|
|
||||||
PR_STATIC_CALLBACK(JSBool)
|
|
||||||
InstallVersionToString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|
||||||
{
|
|
||||||
nsIDOMInstallVersion *nativeThis = (nsIDOMInstallVersion*)JS_GetPrivate(cx, obj);
|
|
||||||
JSBool rBool = JS_FALSE;
|
|
||||||
nsAutoString nativeRet;
|
|
||||||
|
|
||||||
*rval = JSVAL_NULL;
|
|
||||||
|
|
||||||
// If there's no private data, this must be the prototype, so ignore
|
|
||||||
if (nsnull == nativeThis) {
|
|
||||||
return JS_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (argc >= 0) {
|
|
||||||
|
|
||||||
if (NS_OK != nativeThis->ToString(nativeRet)) {
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsJSUtils::nsConvertStringToJSVal(nativeRet, cx, rval);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
JS_ReportError(cx, "Function toString requires 0 parameters");
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return JS_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Native method CompareTo
|
|
||||||
//
|
|
||||||
PR_STATIC_CALLBACK(JSBool)
|
|
||||||
InstallVersionCompareTo(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|
||||||
{
|
|
||||||
nsIDOMInstallVersion *nativeThis = (nsIDOMInstallVersion*)JS_GetPrivate(cx, obj);
|
|
||||||
JSBool rBool = JS_FALSE;
|
|
||||||
PRInt32 nativeRet;
|
|
||||||
nsString b0str;
|
|
||||||
PRInt32 b0int;
|
|
||||||
PRInt32 b1int;
|
|
||||||
PRInt32 b2int;
|
|
||||||
PRInt32 b3int;
|
|
||||||
nsIDOMInstallVersionPtr versionObj;
|
|
||||||
|
|
||||||
*rval = JSVAL_NULL;
|
|
||||||
|
|
||||||
// If there's no private data, this must be the prototype, so ignore
|
|
||||||
if (nsnull == nativeThis) {
|
|
||||||
return JS_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(argc >= 4)
|
|
||||||
{
|
|
||||||
// public int CompareTo(int major,
|
|
||||||
// int minor,
|
|
||||||
// int release,
|
|
||||||
// int build);
|
|
||||||
|
|
||||||
if(!JSVAL_IS_INT(argv[0]))
|
|
||||||
{
|
|
||||||
JS_ReportError(cx, "1st parameter must be a number");
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
else if(!JSVAL_IS_INT(argv[1]))
|
|
||||||
{
|
|
||||||
JS_ReportError(cx, "2nd parameter must be a number");
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
else if(!JSVAL_IS_INT(argv[2]))
|
|
||||||
{
|
|
||||||
JS_ReportError(cx, "3rd parameter must be a number");
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
else if(!JSVAL_IS_INT(argv[3]))
|
|
||||||
{
|
|
||||||
JS_ReportError(cx, "4th parameter must be a number");
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
b0int = JSVAL_TO_INT(argv[0]);
|
|
||||||
b1int = JSVAL_TO_INT(argv[1]);
|
|
||||||
b2int = JSVAL_TO_INT(argv[2]);
|
|
||||||
b3int = JSVAL_TO_INT(argv[3]);
|
|
||||||
|
|
||||||
if(NS_OK != nativeThis->CompareTo(b0int, b1int, b2int, b3int, &nativeRet))
|
|
||||||
{
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
*rval = INT_TO_JSVAL(nativeRet);
|
|
||||||
}
|
|
||||||
else if(argc >= 1)
|
|
||||||
{
|
|
||||||
// public int AddDirectory(String version); --OR-- VersionInfo version
|
|
||||||
|
|
||||||
if(JSVAL_IS_OBJECT(argv[0]))
|
|
||||||
{
|
|
||||||
if(JS_FALSE == ConvertJSValToObj((nsISupports **)&versionObj,
|
|
||||||
kIInstallVersionIID,
|
|
||||||
"InstallVersion",
|
|
||||||
cx,
|
|
||||||
argv[0]))
|
|
||||||
{
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(NS_OK != nativeThis->CompareTo(versionObj, &nativeRet))
|
|
||||||
{
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ConvertJSValToStr(b0str, cx, argv[0]);
|
|
||||||
|
|
||||||
if(NS_OK != nativeThis->CompareTo(b0str, &nativeRet))
|
|
||||||
{
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*rval = INT_TO_JSVAL(nativeRet);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
JS_ReportError(cx, "Function compareTo requires 4 parameters");
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return JS_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************/
|
|
||||||
//
|
|
||||||
// class for InstallVersion
|
|
||||||
//
|
|
||||||
JSClass InstallVersionClass = {
|
|
||||||
"InstallVersion",
|
|
||||||
JSCLASS_HAS_PRIVATE,
|
|
||||||
JS_PropertyStub,
|
|
||||||
JS_PropertyStub,
|
|
||||||
GetInstallVersionProperty,
|
|
||||||
SetInstallVersionProperty,
|
|
||||||
EnumerateInstallVersion,
|
|
||||||
ResolveInstallVersion,
|
|
||||||
JS_ConvertStub,
|
|
||||||
FinalizeInstallVersion
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// InstallVersion class properties
|
|
||||||
//
|
|
||||||
static JSPropertySpec InstallVersionProperties[] =
|
|
||||||
{
|
|
||||||
{"major", INSTALLVERSION_MAJOR, JSPROP_ENUMERATE},
|
|
||||||
{"minor", INSTALLVERSION_MINOR, JSPROP_ENUMERATE},
|
|
||||||
{"release", INSTALLVERSION_RELEASE, JSPROP_ENUMERATE},
|
|
||||||
{"build", INSTALLVERSION_BUILD, JSPROP_ENUMERATE},
|
|
||||||
{0}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// InstallVersion class methods
|
|
||||||
//
|
|
||||||
static JSFunctionSpec InstallVersionMethods[] =
|
|
||||||
{
|
|
||||||
{"init", InstallVersionInit, 1},
|
|
||||||
{"toString", InstallVersionToString, 0},
|
|
||||||
{"compareTo", InstallVersionCompareTo, 1},
|
|
||||||
{0}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// InstallVersion constructor
|
|
||||||
//
|
|
||||||
PR_STATIC_CALLBACK(JSBool)
|
|
||||||
InstallVersion(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|
||||||
{
|
|
||||||
nsresult result;
|
|
||||||
nsIID classID;
|
|
||||||
nsIScriptContext* context = (nsIScriptContext*)JS_GetContextPrivate(cx);
|
|
||||||
nsIScriptNameSpaceManager* manager;
|
|
||||||
nsIDOMInstallVersion *nativeThis;
|
|
||||||
nsIScriptObjectOwner *owner = nsnull;
|
|
||||||
|
|
||||||
static NS_DEFINE_IID(kIDOMInstallVersionIID, NS_IDOMINSTALLVERSION_IID);
|
|
||||||
|
|
||||||
result = context->GetNameSpaceManager(&manager);
|
|
||||||
if (NS_OK != result) {
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = manager->LookupName("InstallVersion", PR_TRUE, classID);
|
|
||||||
NS_RELEASE(manager);
|
|
||||||
if (NS_OK != result) {
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = nsRepository::CreateInstance(classID,
|
|
||||||
nsnull,
|
|
||||||
kIDOMInstallVersionIID,
|
|
||||||
(void **)&nativeThis);
|
|
||||||
if (NS_OK != result) {
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX We should be calling Init() on the instance
|
|
||||||
|
|
||||||
result = nativeThis->QueryInterface(kIScriptObjectOwnerIID, (void **)&owner);
|
|
||||||
if (NS_OK != result) {
|
|
||||||
NS_RELEASE(nativeThis);
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
owner->SetScriptObject((void *)obj);
|
|
||||||
JS_SetPrivate(cx, obj, nativeThis);
|
|
||||||
|
|
||||||
NS_RELEASE(owner);
|
|
||||||
return JS_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// InstallVersion class initialization
|
|
||||||
//
|
|
||||||
nsresult NS_InitInstallVersionClass(nsIScriptContext *aContext, void **aPrototype)
|
|
||||||
{
|
|
||||||
JSContext *jscontext = (JSContext *)aContext->GetNativeContext();
|
|
||||||
JSObject *proto = nsnull;
|
|
||||||
JSObject *constructor = nsnull;
|
|
||||||
JSObject *parent_proto = nsnull;
|
|
||||||
JSObject *global = JS_GetGlobalObject(jscontext);
|
|
||||||
jsval vp;
|
|
||||||
|
|
||||||
if ((PR_TRUE != JS_LookupProperty(jscontext, global, "InstallVersion", &vp)) ||
|
|
||||||
!JSVAL_IS_OBJECT(vp) ||
|
|
||||||
((constructor = JSVAL_TO_OBJECT(vp)) == nsnull) ||
|
|
||||||
(PR_TRUE != JS_LookupProperty(jscontext, JSVAL_TO_OBJECT(vp), "prototype", &vp)) ||
|
|
||||||
!JSVAL_IS_OBJECT(vp)) {
|
|
||||||
|
|
||||||
proto = JS_InitClass(jscontext, // context
|
|
||||||
global, // global object
|
|
||||||
parent_proto, // parent proto
|
|
||||||
&InstallVersionClass, // JSClass
|
|
||||||
InstallVersion, // JSNative ctor
|
|
||||||
0, // ctor args
|
|
||||||
InstallVersionProperties, // proto props
|
|
||||||
InstallVersionMethods, // proto funcs
|
|
||||||
nsnull, // ctor props (static)
|
|
||||||
nsnull); // ctor funcs (static)
|
|
||||||
if (nsnull == proto) {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((PR_TRUE == JS_LookupProperty(jscontext, global, "InstallVersion", &vp)) &&
|
|
||||||
JSVAL_IS_OBJECT(vp) &&
|
|
||||||
((constructor = JSVAL_TO_OBJECT(vp)) != nsnull)) {
|
|
||||||
vp = INT_TO_JSVAL(nsIDOMInstallVersion::EQUAL);
|
|
||||||
JS_SetProperty(jscontext, constructor, "EQUAL", &vp);
|
|
||||||
|
|
||||||
vp = INT_TO_JSVAL(nsIDOMInstallVersion::BLD_DIFF);
|
|
||||||
JS_SetProperty(jscontext, constructor, "BLD_DIFF", &vp);
|
|
||||||
|
|
||||||
vp = INT_TO_JSVAL(nsIDOMInstallVersion::BLD_DIFF_MINUS);
|
|
||||||
JS_SetProperty(jscontext, constructor, "BLD_DIFF_MINUS", &vp);
|
|
||||||
|
|
||||||
vp = INT_TO_JSVAL(nsIDOMInstallVersion::REL_DIFF);
|
|
||||||
JS_SetProperty(jscontext, constructor, "REL_DIFF", &vp);
|
|
||||||
|
|
||||||
vp = INT_TO_JSVAL(nsIDOMInstallVersion::REL_DIFF_MINUS);
|
|
||||||
JS_SetProperty(jscontext, constructor, "REL_DIFF_MINUS", &vp);
|
|
||||||
|
|
||||||
vp = INT_TO_JSVAL(nsIDOMInstallVersion::MINOR_DIFF);
|
|
||||||
JS_SetProperty(jscontext, constructor, "MINOR_DIFF", &vp);
|
|
||||||
|
|
||||||
vp = INT_TO_JSVAL(nsIDOMInstallVersion::MINOR_DIFF_MINUS);
|
|
||||||
JS_SetProperty(jscontext, constructor, "MINOR_DIFF_MINUS", &vp);
|
|
||||||
|
|
||||||
vp = INT_TO_JSVAL(nsIDOMInstallVersion::MAJOR_DIFF);
|
|
||||||
JS_SetProperty(jscontext, constructor, "MAJOR_DIFF", &vp);
|
|
||||||
|
|
||||||
vp = INT_TO_JSVAL(nsIDOMInstallVersion::MAJOR_DIFF_MINUS);
|
|
||||||
JS_SetProperty(jscontext, constructor, "MAJOR_DIFF_MINUS", &vp);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else if ((nsnull != constructor) && JSVAL_IS_OBJECT(vp)) {
|
|
||||||
proto = JSVAL_TO_OBJECT(vp);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aPrototype) {
|
|
||||||
*aPrototype = proto;
|
|
||||||
}
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Method for creating a new InstallVersion JavaScript object
|
|
||||||
//
|
|
||||||
extern "C" NS_DOM nsresult NS_NewScriptInstallVersion(nsIScriptContext *aContext, nsISupports *aSupports, nsISupports *aParent, void **aReturn)
|
|
||||||
{
|
|
||||||
NS_PRECONDITION(nsnull != aContext && nsnull != aSupports && nsnull != aReturn, "null argument to NS_NewScriptInstallVersion");
|
|
||||||
JSObject *proto;
|
|
||||||
JSObject *parent;
|
|
||||||
nsIScriptObjectOwner *owner;
|
|
||||||
JSContext *jscontext = (JSContext *)aContext->GetNativeContext();
|
|
||||||
nsresult result = NS_OK;
|
|
||||||
nsIDOMInstallVersion *aInstallVersion;
|
|
||||||
|
|
||||||
if (nsnull == aParent) {
|
|
||||||
parent = nsnull;
|
|
||||||
}
|
|
||||||
else if (NS_OK == aParent->QueryInterface(kIScriptObjectOwnerIID, (void**)&owner)) {
|
|
||||||
if (NS_OK != owner->GetScriptObject(aContext, (void **)&parent)) {
|
|
||||||
NS_RELEASE(owner);
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
NS_RELEASE(owner);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NS_OK != NS_InitInstallVersionClass(aContext, (void **)&proto)) {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = aSupports->QueryInterface(kIInstallVersionIID, (void **)&aInstallVersion);
|
|
||||||
if (NS_OK != result) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// create a js object for this class
|
|
||||||
*aReturn = JS_NewObject(jscontext, &InstallVersionClass, proto, parent);
|
|
||||||
if (nsnull != *aReturn) {
|
|
||||||
// connect the native object to the js object
|
|
||||||
JS_SetPrivate(jscontext, (JSObject *)*aReturn, aInstallVersion);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
NS_RELEASE(aInstallVersion);
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user