Compare commits
2 Commits
VENKMAN_FL
...
regalloc_c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1c43d4984f | ||
|
|
cfe021ff88 |
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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -0,0 +1,80 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _DOMINATOR_GRAPH_H_
|
||||
#define _DOMINATOR_GRAPH_H_
|
||||
|
||||
#include "LogModule.h"
|
||||
|
||||
class ControlGraph;
|
||||
|
||||
struct DGNode
|
||||
{
|
||||
Uint32* successorsBegin;
|
||||
Uint32* successorsEnd;
|
||||
};
|
||||
|
||||
struct DGLinkedList
|
||||
{
|
||||
DGLinkedList* next;
|
||||
Uint32 index;
|
||||
};
|
||||
|
||||
class DominatorGraph
|
||||
{
|
||||
private:
|
||||
|
||||
ControlGraph& controlGraph;
|
||||
|
||||
Uint32 vCount;
|
||||
|
||||
Uint32* VtoG;
|
||||
Uint32* GtoV;
|
||||
Uint32* parent;
|
||||
Uint32* semi;
|
||||
Uint32* vertex;
|
||||
Uint32* label;
|
||||
Uint32* size;
|
||||
Uint32* ancestor;
|
||||
Uint32* child;
|
||||
Uint32* dom;
|
||||
DGLinkedList** bucket;
|
||||
DGNode* nodes;
|
||||
|
||||
private:
|
||||
|
||||
void build();
|
||||
|
||||
Uint32 DFS(Uint32 vx, Uint32 n);
|
||||
void LINK(Uint32 vx, Uint32 w);
|
||||
void COMPRESS(Uint32 vx);
|
||||
Uint32 EVAL(Uint32 vx);
|
||||
|
||||
public:
|
||||
|
||||
DominatorGraph(ControlGraph& controlGraph);
|
||||
|
||||
Uint32* getSuccessorsBegin(Uint32 n) const {return nodes[n].successorsBegin;}
|
||||
Uint32* getSuccessorsEnd(Uint32 n) const {return nodes[n].successorsEnd;}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
void printPretty(LogModuleObject log);
|
||||
#endif // DEBUG_LOG
|
||||
};
|
||||
|
||||
#endif // _DOMINATOR_GRAPH_H_
|
||||
20
mozilla/ef/Compiler/RegisterAllocator/HashSet.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "HashSet.h"
|
||||
97
mozilla/ef/Compiler/RegisterAllocator/HashSet.h
Normal file
@@ -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
@@ -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
@@ -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
@@ -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
@@ -0,0 +1,163 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _LIVE_RANGE_GRAPH_
|
||||
#define _LIVE_RANGE_GRAPH_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "Pool.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Instruction.h"
|
||||
#include "RegisterTypes.h"
|
||||
|
||||
class RegisterAllocator;
|
||||
|
||||
template <class RegisterPressure>
|
||||
class LiveRangeGraph
|
||||
{
|
||||
private:
|
||||
|
||||
RegisterAllocator& registerAllocator;
|
||||
|
||||
RegisterPressure::Set* edges;
|
||||
Uint32 rangeCount;
|
||||
|
||||
public:
|
||||
//
|
||||
//
|
||||
LiveRangeGraph(RegisterAllocator& registerAllocator) : registerAllocator(registerAllocator) {}
|
||||
|
||||
//
|
||||
//
|
||||
void build();
|
||||
|
||||
//
|
||||
//
|
||||
void addEdge(RegisterName name1, RegisterName name2);
|
||||
|
||||
//
|
||||
//
|
||||
bool haveEdge(RegisterName name1, RegisterName name2);
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
//
|
||||
//
|
||||
void printPretty(LogModuleObject log);
|
||||
#endif // DEBUG_LOG
|
||||
};
|
||||
|
||||
template <class RegisterPressure>
|
||||
void LiveRangeGraph<RegisterPressure>::build()
|
||||
{
|
||||
Pool& pool = registerAllocator.pool;
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
this->rangeCount = rangeCount;
|
||||
|
||||
edges = new(pool) RegisterPressure::Set(pool, rangeCount * rangeCount);
|
||||
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
LivenessInfo<RegisterPressure>& liveness = registerAllocator.liveness;
|
||||
SparseSet currentLive(pool, rangeCount);
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
ControlNode& node = *nodes[n];
|
||||
currentLive = liveness.liveOut[n];
|
||||
|
||||
InstructionList& instructions = node.getInstructions();
|
||||
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useBegin = instruction.getInstructionUseBegin();
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
InstructionUse* usePtr;
|
||||
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
InstructionDefine* definePtr;
|
||||
|
||||
if ((instruction.getFlags() & ifCopy) != 0) {
|
||||
assert(useBegin != useEnd && useBegin[0].isRegister());
|
||||
currentLive.clear(name2range[useBegin[0].getRegisterName()]);
|
||||
}
|
||||
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister()) {
|
||||
RegisterName define = name2range[definePtr->getRegisterName()];
|
||||
|
||||
for (SparseSet::iterator l = currentLive.begin(); !currentLive.done(l); l = currentLive.advance(l)) {
|
||||
RegisterName live = RegisterName(currentLive.get(l));
|
||||
if (define != live && registerAllocator.canInterfere(define, live))
|
||||
addEdge(define, live);
|
||||
}
|
||||
}
|
||||
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
currentLive.clear(name2range[definePtr->getRegisterName()]);
|
||||
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister())
|
||||
currentLive.set(name2range[usePtr->getRegisterName()]);
|
||||
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
RegisterName use = name2range[usePtr->getRegisterName()];
|
||||
|
||||
for (SparseSet::iterator l = currentLive.begin(); !currentLive.done(l); l = currentLive.advance(l)) {
|
||||
RegisterName live = RegisterName(currentLive.get(l));
|
||||
if (use != live && registerAllocator.canInterfere(use, live))
|
||||
addEdge(use, live);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
void LiveRangeGraph<RegisterPressure>::addEdge(RegisterName name1, RegisterName name2)
|
||||
{
|
||||
assert(name1 != name2);
|
||||
edges->set(name1 * rangeCount + name2);
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
bool LiveRangeGraph<RegisterPressure>::haveEdge(RegisterName name1, RegisterName name2)
|
||||
{
|
||||
assert(name1 != name2);
|
||||
return edges->test(name1 * rangeCount + name2);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
template <class RegisterPressure>
|
||||
void LiveRangeGraph<RegisterPressure>::printPretty(LogModuleObject log)
|
||||
{
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Live ranges graph:\n"));
|
||||
for (RegisterName name1 = RegisterName(1); name1 < rangeCount; name1 = RegisterName(name1 + 1)) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\t%d:\t", name1));
|
||||
for (RegisterName name2 = RegisterName(1); name2 < rangeCount; name2 = RegisterName(name2 + 1))
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%c", ((name1 != name2) && haveEdge(name1, name2)) ? '1' : '0'));
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_LOG
|
||||
|
||||
#endif // _LIVE_RANGE_GRAPH_
|
||||
21
mozilla/ef/Compiler/RegisterAllocator/Liveness.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "Liveness.h"
|
||||
|
||||
301
mozilla/ef/Compiler/RegisterAllocator/Liveness.h
Normal file
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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_
|
||||
38
mozilla/ef/Compiler/RegisterAllocator/RegisterAssigner.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/* -*- 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_ASSIGNER_H_
|
||||
#define _REGISTER_ASSIGNER_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "VirtualRegister.h"
|
||||
|
||||
class FastBitMatrix;
|
||||
|
||||
class RegisterAssigner
|
||||
{
|
||||
protected:
|
||||
VirtualRegisterManager& vRegManager;
|
||||
|
||||
public:
|
||||
RegisterAssigner(VirtualRegisterManager& vrMan) : vRegManager(vrMan) {}
|
||||
|
||||
virtual bool assignRegisters(FastBitMatrix& interferenceMatrix) = 0;
|
||||
};
|
||||
|
||||
#endif /* _REGISTER_ASSIGNER_H_ */
|
||||
25
mozilla/ef/Compiler/RegisterAllocator/RegisterClass.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _REGISTER_CLASS_H_
|
||||
#define _REGISTER_CLASS_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "RegisterTypes.h"
|
||||
|
||||
#endif // _REGISTER_CLASS_H_
|
||||
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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -0,0 +1,80 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _TIMER_H_
|
||||
#define _TIMER_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "HashTable.h"
|
||||
#include "prtime.h"
|
||||
|
||||
//
|
||||
// Naming convention:
|
||||
// As the class Timer contains only static methods, the timer's name should start with the
|
||||
// module name. Otherwise starting 2 timers with the same name will assert.
|
||||
//
|
||||
|
||||
#ifndef NO_TIMER
|
||||
|
||||
struct TimerEntry
|
||||
{
|
||||
PRTime *startTime; // Current time when we start the timer.
|
||||
PRTime accumulator; // Time spent in this timer.
|
||||
bool running; // True if the timer is running.
|
||||
bool done; // True if the timer was running and was stopped.
|
||||
};
|
||||
|
||||
class Timer
|
||||
{
|
||||
private:
|
||||
|
||||
// Return the named timer.
|
||||
static TimerEntry& getTimerEntry(const char* name);
|
||||
// Return a reference to a new Timer.
|
||||
static PRTime& getNewTimer();
|
||||
|
||||
public:
|
||||
|
||||
// Start the timer.
|
||||
static void start(const char* name);
|
||||
// Stop the timer.
|
||||
static void stop(const char* name);
|
||||
// Freeze all the running timers.
|
||||
static void freezeTimers();
|
||||
// Unfreeze all the running timers.
|
||||
static void unfreezeTimers();
|
||||
// Print the timer.
|
||||
static void print(FILE* f, const char *name);
|
||||
};
|
||||
|
||||
inline void startTimer(const char* name) {Timer::start(name);}
|
||||
inline void stopTimer(const char* name) {Timer::stop(name); Timer::print(stdout, name);}
|
||||
#define START_TIMER_SAFE Timer::freezeTimers();
|
||||
#define END_TIMER_SAFE Timer::unfreezeTimers();
|
||||
#define TIMER_SAFE(x) START_TIMER_SAFE x; END_TIMER_SAFE
|
||||
|
||||
#else /* NO_TIMER */
|
||||
|
||||
inline void startTimer(const char* /*name*/) {}
|
||||
inline void stopTimer(const char* /*name*/) {}
|
||||
#define START_TIMER_SAFE
|
||||
#define END_TIMER_SAFE
|
||||
#define TIMER_SAFE(x) x;
|
||||
|
||||
#endif /* NO_TIMER */
|
||||
#endif /* _TIMER_H_ */
|
||||
40
mozilla/ef/Compiler/RegisterAllocator/VirtualRegister.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "VirtualRegister.h"
|
||||
#include "Instruction.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// VirtualRegister -
|
||||
|
||||
#ifdef MANUAL_TEMPLATES
|
||||
template class IndexedPool<VirtualRegister>;
|
||||
#endif
|
||||
|
||||
// Set the defining instruction.
|
||||
//
|
||||
void VirtualRegister::setDefiningInstruction(Instruction& instruction)
|
||||
{
|
||||
if (definingInstruction != NULL) {
|
||||
if ((instruction.getFlags() & ifCopy) && (definingInstruction->getFlags() & ifPhiNode))
|
||||
return;
|
||||
}
|
||||
definingInstruction = &instruction;
|
||||
}
|
||||
|
||||
116
mozilla/ef/Compiler/RegisterAllocator/VirtualRegister.h
Normal file
@@ -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,46 +0,0 @@
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is The JavaScript Debugger
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation
|
||||
# Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation.
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU Public License (the "GPL"), in which case the
|
||||
# provisions of the GPL are applicable instead of those above.
|
||||
# If you wish to allow use of your version of this file only
|
||||
# under the terms of the GPL and not to allow others to use your
|
||||
# version of this file under the MPL, indicate your decision by
|
||||
# deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this
|
||||
# file under either the MPL or the GPL.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Robert Ginda, <rginda@netscape.com>, original author
|
||||
#
|
||||
|
||||
DEPTH = ../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
DIRS = resources
|
||||
|
||||
EXTRA_COMPONENTS = js/venkman-service.js
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
venkman-service.js
|
||||
@@ -1,450 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is The JavaScript Debugger
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation
|
||||
* Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the MPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Robert Ginda, <rginda@netscape.com>, original author
|
||||
*
|
||||
*/
|
||||
|
||||
/* components defined in this file */
|
||||
const CLINE_SERVICE_CTRID =
|
||||
"@mozilla.org/commandlinehandler/general-startup;1?type=venkman";
|
||||
const CLINE_SERVICE_CID =
|
||||
Components.ID("{18269616-1dd2-11b2-afa8-b612439bda27}");
|
||||
const JSDPROT_HANDLER_CTRID =
|
||||
"@mozilla.org/network/protocol;1?name=x-jsd";
|
||||
const JSDPROT_HANDLER_CID =
|
||||
Components.ID("{12ec790d-304e-4525-89a9-3e723d489d14}");
|
||||
|
||||
/* components used by this file */
|
||||
const CATMAN_CTRID = "@mozilla.org/categorymanager;1";
|
||||
const STRING_STREAM_CTRID = "@mozilla.org/io/string-input-stream;1";
|
||||
const MEDIATOR_CTRID =
|
||||
"@mozilla.org/appshell/window-mediator;1";
|
||||
const SIMPLEURI_CTRID = "@mozilla.org/network/simple-uri;1";
|
||||
|
||||
const nsIWindowMediator = Components.interfaces.nsIWindowMediator;
|
||||
const nsICmdLineHandler = Components.interfaces.nsICmdLineHandler;
|
||||
const nsICategoryManager = Components.interfaces.nsICategoryManager;
|
||||
const nsIProtocolHandler = Components.interfaces.nsIProtocolHandler;
|
||||
const nsIURI = Components.interfaces.nsIURI;
|
||||
const nsIURL = Components.interfaces.nsIURL;
|
||||
const nsIStringInputStream = Components.interfaces.nsIStringInputStream;
|
||||
const nsIChannel = Components.interfaces.nsIChannel;
|
||||
const nsIRequest = Components.interfaces.nsIRequest;
|
||||
const nsIProgressEventSink = Components.interfaces.nsIProgressEventSink;
|
||||
const nsISupports = Components.interfaces.nsISupports;
|
||||
|
||||
function findDebuggerWindow ()
|
||||
{
|
||||
var windowManager =
|
||||
Components.classes[MEDIATOR_CTRID].getService(nsIWindowMediator);
|
||||
|
||||
var window = windowManager.getMostRecentWindow("mozapp:venkman");
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
/* Command Line handler service */
|
||||
function CLineService()
|
||||
{}
|
||||
|
||||
CLineService.prototype.commandLineArgument = "-venkman";
|
||||
CLineService.prototype.prefNameForStartup = "general.startup.venkman";
|
||||
CLineService.prototype.chromeUrlForTask = "chrome://venkman/content";
|
||||
CLineService.prototype.helpText = "Start with JavaScript Debugger.";
|
||||
CLineService.prototype.handlesArgs = false;
|
||||
CLineService.prototype.defaultArgs = "";
|
||||
CLineService.prototype.openWindowWithArgs = false;
|
||||
|
||||
/* factory for command line handler service (CLineService) */
|
||||
var CLineFactory = new Object();
|
||||
|
||||
CLineFactory.createInstance =
|
||||
function clf_create (outer, iid) {
|
||||
if (outer != null)
|
||||
throw Components.results.NS_ERROR_NO_AGGREGATION;
|
||||
|
||||
if (!iid.equals(nsICmdLineHandler) && !iid.equals(nsISupports))
|
||||
throw Components.results.NS_ERROR_INVALID_ARG;
|
||||
|
||||
return new CLineService();
|
||||
}
|
||||
|
||||
/* x-jsd: protocol handler */
|
||||
|
||||
const JSD_DEFAULT_PORT = 2206; /* Dana's apartment number. */
|
||||
|
||||
/* protocol handler factory object */
|
||||
var JSDProtocolHandlerFactory = new Object();
|
||||
|
||||
JSDProtocolHandlerFactory.createInstance =
|
||||
function jsdhf_create (outer, iid) {
|
||||
if (outer != null)
|
||||
throw Components.results.NS_ERROR_NO_AGGREGATION;
|
||||
|
||||
if (!iid.equals(nsIProtocolHandler) && !iid.equals(nsISupports))
|
||||
throw Components.results.NS_ERROR_INVALID_ARG;
|
||||
|
||||
return new JSDProtocolHandler();
|
||||
}
|
||||
|
||||
function JSDURI (spec, charset)
|
||||
{
|
||||
this.spec = this.prePath = spec;
|
||||
this.charset = this.originCharset = charset;
|
||||
}
|
||||
|
||||
JSDURI.prototype.QueryInterface =
|
||||
function jsdch_qi (iid)
|
||||
{
|
||||
|
||||
if (!iid.equals(nsIURI) && !iid.equals(nsIURL) &&
|
||||
!iid.equals(nsISupports))
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
JSDURI.prototype.scheme = "x-jsd";
|
||||
|
||||
|
||||
JSDURI.prototype.fileBaseName =
|
||||
JSDURI.prototype.fileExtension =
|
||||
JSDURI.prototype.filePath =
|
||||
JSDURI.prototype.param =
|
||||
JSDURI.prototype.query =
|
||||
JSDURI.prototype.ref =
|
||||
JSDURI.prototype.directory =
|
||||
JSDURI.prototype.fileName =
|
||||
JSDURI.prototype.username =
|
||||
JSDURI.prototype.password =
|
||||
JSDURI.prototype.hostPort =
|
||||
JSDURI.prototype.path =
|
||||
JSDURI.prototype.asciiHost =
|
||||
JSDURI.prototype.userPass = "";
|
||||
|
||||
JSDURI.prototype.port = JSD_DEFAULT_PORT;
|
||||
|
||||
JSDURI.prototype.schemeIs =
|
||||
function jsduri_schemeis (scheme)
|
||||
{
|
||||
return scheme.toLowerCase() == "x-jsd";
|
||||
}
|
||||
|
||||
JSDURI.prototype.getCommonBaseSpec =
|
||||
function jsduri_commonbase (uri)
|
||||
{
|
||||
return "x-jsd:";
|
||||
}
|
||||
|
||||
JSDURI.prototype.getRelativeSpec =
|
||||
function jsduri_commonbase (uri)
|
||||
{
|
||||
return uri;
|
||||
}
|
||||
|
||||
JSDURI.prototype.equals =
|
||||
function jsduri_equals (uri)
|
||||
{
|
||||
return uri.spec == this.spec;
|
||||
}
|
||||
|
||||
JSDURI.prototype.clone =
|
||||
function jsduri_clone ()
|
||||
{
|
||||
return new JSDURI (this.spec);
|
||||
}
|
||||
|
||||
JSDURI.prototype.resolve =
|
||||
function jsduri_resolve(path)
|
||||
{
|
||||
//dump ("resolve " + path + " from " + this.spec + "\n");
|
||||
if (path[0] == "#")
|
||||
return this.spec + path;
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
function JSDProtocolHandler()
|
||||
{
|
||||
/* nothing here */
|
||||
}
|
||||
|
||||
JSDProtocolHandler.prototype.scheme = "x-jsd";
|
||||
JSDProtocolHandler.prototype.defaultPort = JSD_DEFAULT_PORT;
|
||||
JSDProtocolHandler.prototype.protocolFlags = nsIProtocolHandler.URI_NORELATIVE;
|
||||
|
||||
JSDProtocolHandler.prototype.allowPort =
|
||||
function jsdph_allowport (aPort, aScheme)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
JSDProtocolHandler.prototype.newURI =
|
||||
function jsdph_newuri (spec, charset, baseURI)
|
||||
{
|
||||
if (baseURI)
|
||||
{
|
||||
debug ("-*- jsdHandler: aBaseURI passed to newURI, bailing.\n");
|
||||
return null;
|
||||
}
|
||||
|
||||
var clazz = Components.classes[SIMPLEURI_CTRID];
|
||||
var uri = clazz.createInstance(nsIURI);
|
||||
uri.spec = spec;
|
||||
return uri;
|
||||
}
|
||||
|
||||
JSDProtocolHandler.prototype.newChannel =
|
||||
function jsdph_newchannel (uri)
|
||||
{
|
||||
return new JSDChannel (uri);
|
||||
}
|
||||
|
||||
function JSDChannel (uri)
|
||||
{
|
||||
this.URI = uri;
|
||||
this.originalURI = uri;
|
||||
this._isPending = true;
|
||||
var clazz = Components.classes[STRING_STREAM_CTRID];
|
||||
this.stringStream = clazz.createInstance(nsIStringInputStream);
|
||||
}
|
||||
|
||||
JSDChannel.prototype.QueryInterface =
|
||||
function jsdch_qi (iid)
|
||||
{
|
||||
|
||||
if (!iid.equals(nsIChannel) && !iid.equals(nsIRequest) &&
|
||||
!iid.equals(nsISupports))
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/* nsIChannel */
|
||||
JSDChannel.prototype.loadAttributes = null;
|
||||
JSDChannel.prototype.contentType = "text/html";
|
||||
JSDChannel.prototype.contentLength = -1;
|
||||
JSDChannel.prototype.owner = null;
|
||||
JSDChannel.prototype.loadGroup = null;
|
||||
JSDChannel.prototype.notificationCallbacks = null;
|
||||
JSDChannel.prototype.securityInfo = null;
|
||||
|
||||
JSDChannel.prototype.open =
|
||||
function jsdch_open()
|
||||
{
|
||||
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
JSDChannel.prototype.asyncOpen =
|
||||
function jsdch_aopen (streamListener, context)
|
||||
{
|
||||
this.streamListener = streamListener;
|
||||
this.context = context;
|
||||
if (this.loadGroup)
|
||||
this.loadGroup.addRequest (this, null);
|
||||
|
||||
var window = findDebuggerWindow();
|
||||
var ary = this.URI.spec.match (/x-jsd:([^:]+)/);
|
||||
var exception;
|
||||
|
||||
if (window && "console" in window && ary)
|
||||
{
|
||||
try
|
||||
{
|
||||
window.asyncOpenJSDURL (this, streamListener, context);
|
||||
return;
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
exception = ex;
|
||||
}
|
||||
}
|
||||
|
||||
var str =
|
||||
"<html><head><title>Error</title></head><body>Could not load <<b>" +
|
||||
this.URI.spec + "</b>><br>";
|
||||
|
||||
if (!ary)
|
||||
{
|
||||
str += "<b>Error parsing uri.</b>";
|
||||
}
|
||||
else if (exception)
|
||||
{
|
||||
str += "<b>Internal error: " + exception + "</b><br><pre>" +
|
||||
exception.stack;
|
||||
}
|
||||
else
|
||||
{
|
||||
str += "<b>Debugger is not running.</b>";
|
||||
}
|
||||
|
||||
str += "</body></html>";
|
||||
|
||||
this.respond (str);
|
||||
}
|
||||
|
||||
JSDChannel.prototype.respond =
|
||||
function jsdch_respond (str)
|
||||
{
|
||||
this.streamListener.onStartRequest (this, this.context);
|
||||
|
||||
var len = str.length;
|
||||
this.stringStream.setData (str, len);
|
||||
this.streamListener.onDataAvailable (this, this.context,
|
||||
this.stringStream, 0, len);
|
||||
this.streamListener.onStopRequest (this, this.context,
|
||||
Components.results.NS_OK);
|
||||
if (this.loadGroup)
|
||||
this.loadGroup.removeRequest (this, null, Components.results.NS_OK);
|
||||
this._isPending = false;
|
||||
}
|
||||
|
||||
/* nsIRequest */
|
||||
JSDChannel.prototype.isPending =
|
||||
function jsdch_ispending ()
|
||||
{
|
||||
return this._isPending;
|
||||
}
|
||||
|
||||
JSDChannel.prototype.status = Components.results.NS_OK;
|
||||
|
||||
JSDChannel.prototype.cancel =
|
||||
function jsdch_cancel (status)
|
||||
{
|
||||
if (this._isPending)
|
||||
{
|
||||
this._isPending = false;
|
||||
this.streamListener.onStopRequest (this, this.context, status);
|
||||
if (this.loadGroup)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.loadGroup.removeRequest (this, null, status);
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
dump ("we're not in the load group?\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
JSDChannel.prototype.suspend =
|
||||
JSDChannel.prototype.resume =
|
||||
function jsdch_notimpl ()
|
||||
{
|
||||
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
var Module = new Object();
|
||||
|
||||
Module.registerSelf =
|
||||
function (compMgr, fileSpec, location, type)
|
||||
{
|
||||
dump("*** Registering -venkman handler.\n");
|
||||
|
||||
compMgr =
|
||||
compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
|
||||
|
||||
compMgr.registerFactoryLocation(CLINE_SERVICE_CID,
|
||||
"Venkman CommandLine Service",
|
||||
CLINE_SERVICE_CTRID,
|
||||
fileSpec,
|
||||
location,
|
||||
type);
|
||||
|
||||
catman = Components.classes[CATMAN_CTRID].getService(nsICategoryManager);
|
||||
catman.addCategoryEntry("command-line-argument-handlers",
|
||||
"venkman command line handler",
|
||||
CLINE_SERVICE_CTRID, true, true);
|
||||
|
||||
dump("*** Registering x-jsd protocol handler.\n");
|
||||
compMgr.registerFactoryLocation(JSDPROT_HANDLER_CID,
|
||||
"x-jsd protocol handler",
|
||||
JSDPROT_HANDLER_CTRID,
|
||||
fileSpec,
|
||||
location,
|
||||
type);
|
||||
try
|
||||
{
|
||||
const JSD_CTRID = "@mozilla.org/js/jsd/debugger-service;1";
|
||||
const jsdIDebuggerService = Components.interfaces.jsdIDebuggerService;
|
||||
var jsds = Components.classes[JSD_CTRID].getService(jsdIDebuggerService);
|
||||
jsds.initAtStartup = true;
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
dump ("*** ERROR initializing debugger service");
|
||||
dump (ex);
|
||||
}
|
||||
}
|
||||
|
||||
Module.unregisterSelf =
|
||||
function(compMgr, fileSpec, location)
|
||||
{
|
||||
compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
|
||||
|
||||
compMgr.unregisterFactoryLocation(CLINE_SERVICE_CID, fileSpec);
|
||||
catman = Components.classes[CATMAN_CTRID].getService(nsICategoryManager);
|
||||
catman.deleteCategoryEntry("command-line-argument-handlers",
|
||||
CLINE_SERVICE_CTRID, true);
|
||||
}
|
||||
|
||||
Module.getClassObject =
|
||||
function (compMgr, cid, iid) {
|
||||
if (cid.equals(CLINE_SERVICE_CID))
|
||||
return CLineFactory;
|
||||
|
||||
if (cid.equals(JSDPROT_HANDLER_CID))
|
||||
return JSDProtocolHandlerFactory;
|
||||
|
||||
if (!iid.equals(Components.interfaces.nsIFactory))
|
||||
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
|
||||
}
|
||||
|
||||
Module.canUnload =
|
||||
function(compMgr)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/* entrypoint */
|
||||
function NSGetModule(compMgr, fileSpec) {
|
||||
return Module;
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is The JavaScript Debugger
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation
|
||||
# Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation.
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU Public License (the "GPL"), in which case the
|
||||
# provisions of the GPL are applicable instead of those above.
|
||||
# If you wish to allow use of your version of this file only
|
||||
# under the terms of the GPL and not to allow others to use your
|
||||
# version of this file under the MPL, indicate your decision by
|
||||
# deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this
|
||||
# file under either the MPL or the GPL.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Robert Ginda, <rginda@netscape.com>, original author
|
||||
#
|
||||
|
||||
DEPTH = ..\..
|
||||
|
||||
include <$(DEPTH)\config\config.mak>
|
||||
|
||||
DIRS = resources
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
libs::
|
||||
$(MAKE_INSTALL) .\js\venkman-service.js $(DIST)\bin\components
|
||||
@@ -1,42 +0,0 @@
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is The JavaScript Debugger
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation
|
||||
# Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation.
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU Public License (the "GPL"), in which case the
|
||||
# provisions of the GPL are applicable instead of those above.
|
||||
# If you wish to allow use of your version of this file only
|
||||
# under the terms of the GPL and not to allow others to use your
|
||||
# version of this file under the MPL, indicate your decision by
|
||||
# deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this
|
||||
# file under either the MPL or the GPL.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Robert Ginda, <rginda@netscape.com>, original author
|
||||
#
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
@@ -1,847 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is JSIRC Library
|
||||
*
|
||||
* The Initial Developer of the Original Code is New Dimensions Consulting,
|
||||
* Inc. Portions created by New Dimensions Consulting, Inc. are
|
||||
* Copyright (C) 1999 New Dimenstions Consulting, Inc. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*
|
||||
* Contributor(s):
|
||||
* Robert Ginda, rginda@ndcico.com, original author
|
||||
*/
|
||||
|
||||
|
||||
function getAccessKey (str)
|
||||
{
|
||||
var i = str.indexOf("&");
|
||||
if (i == -1)
|
||||
return "";
|
||||
return str[i + 1];
|
||||
}
|
||||
|
||||
function CommandRecord (name, func, usage, help, label, flags, keystr)
|
||||
{
|
||||
this.name = name;
|
||||
this.func = func;
|
||||
this._usage = usage;
|
||||
this.scanUsage();
|
||||
this.help = help;
|
||||
this.label = label ? label : name;
|
||||
this.labelstr = label.replace ("&", "");
|
||||
this.flags = flags;
|
||||
this._enabled = true;
|
||||
this.keyNodes = new Array();
|
||||
this.keystr = keystr;
|
||||
this.uiElements = new Array();
|
||||
|
||||
}
|
||||
|
||||
CommandRecord.prototype.__defineGetter__ ("enabled", cr_getenable);
|
||||
function cr_getenable ()
|
||||
{
|
||||
return this._enabled;
|
||||
}
|
||||
|
||||
CommandRecord.prototype.__defineSetter__ ("enabled", cr_setenable);
|
||||
function cr_setenable (state)
|
||||
{
|
||||
for (var i = 0; i < this.uiElements.length; ++i)
|
||||
{
|
||||
if (state)
|
||||
this.uiElements[i].removeAttribute ("disabled");
|
||||
else
|
||||
this.uiElements[i].setAttribute ("disabled", "true");
|
||||
}
|
||||
return (this._enabled = state);
|
||||
}
|
||||
|
||||
CommandRecord.prototype.__defineSetter__ ("usage", cr_setusage);
|
||||
function cr_setusage (usage)
|
||||
{
|
||||
this._usage = usage;
|
||||
this.scanUsage();
|
||||
}
|
||||
|
||||
CommandRecord.prototype.__defineGetter__ ("usage", cr_getusage);
|
||||
function cr_getusage()
|
||||
{
|
||||
return this._usage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal use only.
|
||||
*
|
||||
* Scans the argument spec, in the format "<a1> <a2> [<o1> <o2>]", into an
|
||||
* array of strings.
|
||||
*/
|
||||
CommandRecord.prototype.scanUsage =
|
||||
function cr_scanusage()
|
||||
{
|
||||
var spec = this._usage;
|
||||
var currentName = "";
|
||||
var inName = false;
|
||||
var len = spec.length;
|
||||
var capNext = false;
|
||||
|
||||
this._usage = spec;
|
||||
this.argNames = new Array();
|
||||
|
||||
for (var i = 0; i < len; ++i)
|
||||
{
|
||||
switch (spec[i])
|
||||
{
|
||||
case '[':
|
||||
this.argNames.push (":");
|
||||
break;
|
||||
|
||||
case '<':
|
||||
inName = true;
|
||||
break;
|
||||
|
||||
case '-':
|
||||
capNext = true;
|
||||
break;
|
||||
|
||||
case '>':
|
||||
inName = false;
|
||||
this.argNames.push (currentName);
|
||||
currentName = "";
|
||||
capNext = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (inName)
|
||||
currentName += capNext ? spec[i].toUpperCase() : spec[i];
|
||||
capNext = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the command formatted for presentation as part of online
|
||||
* documentation.
|
||||
*/
|
||||
CommandRecord.prototype.getDocumentation =
|
||||
function cr_getdocs(flagFormatter)
|
||||
|
||||
{
|
||||
var str;
|
||||
str = getMsg(MSN_DOC_COMMANDLABEL,
|
||||
[this.label.replace("&", ""), this.name]) + "\n";
|
||||
str += getMsg(MSN_DOC_KEY, this.keystr ? this.keystr : MSG_VAL_NA) + "\n";
|
||||
str += getMsg(MSN_DOC_SYNTAX, [this.name, this.usage]) + "\n";
|
||||
str += MSG_DOC_NOTES + "\n";
|
||||
str += (flagFormatter ? flagFormatter(this.flags) : this.flags) + "\n\n";
|
||||
str += MSG_DOC_DESCRIPTION + "\n";
|
||||
str += wrapText(this.help, 75) + "\n";
|
||||
return str;
|
||||
}
|
||||
|
||||
CommandRecord.prototype.argNames = new Array();
|
||||
|
||||
function CommandManager (defaultBundle)
|
||||
{
|
||||
this.commands = new Object();
|
||||
this.defaultBundle = defaultBundle;
|
||||
}
|
||||
|
||||
CommandManager.prototype.defineCommands =
|
||||
function cmgr_defcmds (cmdary)
|
||||
{
|
||||
var len = cmdary.length;
|
||||
var commands = new Object();
|
||||
var bundle = ("stringBundle" in cmdary ?
|
||||
cmdary.stringBundle :
|
||||
this.defaultBundle);
|
||||
|
||||
for (var i = 0; i < len; ++i)
|
||||
{
|
||||
var name = cmdary[i][0];
|
||||
var func = cmdary[i][1];
|
||||
var flags = cmdary[i][2];
|
||||
var usage = getMsgFrom(bundle, "cmd." + name + ".params", null, "");
|
||||
|
||||
var helpDefault;
|
||||
var labelDefault = name;
|
||||
var aliasFor;
|
||||
if (flags & CMD_NO_HELP)
|
||||
helpDefault = MSG_NO_HELP;
|
||||
|
||||
if (typeof func == "string")
|
||||
{
|
||||
var ary = func.match(/(\S+)/);
|
||||
if (ary)
|
||||
aliasFor = ary[1];
|
||||
helpDefault = getMsg (MSN_DEFAULT_ALIAS_HELP, func);
|
||||
labelDefault = getMsgFrom (bundle,
|
||||
"cmd." + aliasFor + ".label", null, name);
|
||||
}
|
||||
|
||||
var label = getMsgFrom(bundle,
|
||||
"cmd." + name + ".label", null, labelDefault);
|
||||
var help = getMsgFrom(bundle,
|
||||
"cmd." + name + ".help", null, helpDefault);
|
||||
var keystr = getMsgFrom (bundle, "cmd." + name + ".key", null, "");
|
||||
var command = new CommandRecord (name, func, usage, help, label, flags,
|
||||
keystr);
|
||||
if (aliasFor)
|
||||
command.aliasFor = aliasFor;
|
||||
this.addCommand(command);
|
||||
commands[name] = command;
|
||||
}
|
||||
|
||||
return commands;
|
||||
}
|
||||
|
||||
CommandManager.prototype.installKeys =
|
||||
function cmgr_instkeys (document, commands)
|
||||
{
|
||||
var parentElem = document.getElementById("dynamic-keys");
|
||||
if (!parentElem)
|
||||
{
|
||||
parentElem = document.createElement("keyset");
|
||||
parentElem.setAttribute ("id", "dynamic-keys");
|
||||
document.firstChild.appendChild (parentElem);
|
||||
}
|
||||
|
||||
if (!commands)
|
||||
commands = this.commands;
|
||||
|
||||
for (var c in commands)
|
||||
this.installKey (parentElem, commands[c]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a <key> node relative to a DOM node. Usually called once per command,
|
||||
* per document, so that accelerator keys work in all application windows.
|
||||
*
|
||||
* @param parentElem A reference to the DOM node which should contain the new
|
||||
* <key> node.
|
||||
* @param command reference to the CommandRecord to install.
|
||||
*/
|
||||
CommandManager.prototype.installKey =
|
||||
function cmgr_instkey (parentElem, command)
|
||||
{
|
||||
if (!command.keystr)
|
||||
return;
|
||||
|
||||
var ary = command.keystr.match (/(.*\s)?([\S]+)$/);
|
||||
if (!ASSERT(ary, "couldn't parse key string ``" + command.keystr +
|
||||
"'' for command ``" + command.name + "''"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var key = document.createElement ("key");
|
||||
key.setAttribute ("id", "key:" + command.name);
|
||||
key.setAttribute ("oncommand", "dispatch('" + command.name + "');");
|
||||
key.setAttribute ("modifiers", ary[1]);
|
||||
if (ary[2].indexOf("VK_") == 0)
|
||||
key.setAttribute ("keycode", ary[2]);
|
||||
else
|
||||
key.setAttribute ("key", ary[2]);
|
||||
|
||||
parentElem.appendChild(key);
|
||||
command.keyNodes.push(key);
|
||||
}
|
||||
|
||||
CommandManager.prototype.uninstallKeys =
|
||||
function cmgr_uninstkeys (commands)
|
||||
{
|
||||
if (!commands)
|
||||
commands = this.commands;
|
||||
|
||||
for (var c in commands)
|
||||
this.uninstallKey (commands[c]);
|
||||
}
|
||||
|
||||
CommandManager.prototype.uninstallKey =
|
||||
function cmgr_uninstkey (command)
|
||||
{
|
||||
for (var i in command.keyNodes)
|
||||
{
|
||||
try
|
||||
{
|
||||
/* document may no longer exist in a useful state. */
|
||||
command.keyNodes[i].parentNode.removeChild(command.keyNodes[i]);
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
dd ("*** caught exception uninstalling key node: " + ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new command with the manager.
|
||||
*/
|
||||
CommandManager.prototype.addCommand =
|
||||
function cmgr_add (command)
|
||||
{
|
||||
this.commands[command.name] = command;
|
||||
}
|
||||
|
||||
CommandManager.prototype.removeCommands =
|
||||
function cmgr_removes (commands)
|
||||
{
|
||||
for (var c in commands)
|
||||
this.removeCommand(commands[c]);
|
||||
}
|
||||
|
||||
CommandManager.prototype.removeCommand =
|
||||
function cmgr_remove (command)
|
||||
{
|
||||
delete this.commands[command.name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a hook for a particular command name. |id| is a human readable
|
||||
* identifier for the hook, and can be used to unregister the hook. If you
|
||||
* re-use a hook id, the previous hook function will be replaced.
|
||||
* If |before| is |true|, the hook will be called *before* the command executes,
|
||||
* if |before| is |false|, or not specified, the hook will be called *after*
|
||||
* the command executes.
|
||||
*/
|
||||
CommandManager.prototype.addHook =
|
||||
function cmgr_hook (commandName, func, id, before)
|
||||
{
|
||||
if (!ASSERT(commandName in this.commands,
|
||||
"Unknown command '" + commandName + "'"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var command = this.commands[commandName];
|
||||
|
||||
if (before)
|
||||
{
|
||||
if (!("beforeHookNames" in command))
|
||||
command.beforeHookNames = new Array();
|
||||
if (!("beforeHooks" in command))
|
||||
command.beforeHooks = new Object();
|
||||
if (id in command.beforeHooks)
|
||||
{
|
||||
arrayRemoveAt(command.beforeHookNames,
|
||||
command.beforeHooks[id][id + "_hookIndex"]);
|
||||
}
|
||||
command.beforeHooks[id] = func;
|
||||
command.beforeHookNames.push(id);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!("afterHookNames" in command))
|
||||
command.afterHookNames = new Array();
|
||||
if (!("afterHooks" in command))
|
||||
command.afterHooks = new Object();
|
||||
func[id + "_hookIndex"] = command.afterHookNames.length
|
||||
command.afterHooks[id] = func;
|
||||
command.afterHookNames.push(id);
|
||||
}
|
||||
}
|
||||
|
||||
CommandManager.prototype.addHooks =
|
||||
function cmgr_hooks (hooks, prefix)
|
||||
{
|
||||
if (!prefix)
|
||||
prefix = "";
|
||||
|
||||
for (var h in hooks)
|
||||
{
|
||||
this.addHook(h, hooks[h], prefix + ":" + h,
|
||||
("before" in hooks[h]) ? hooks[h].before : false);
|
||||
}
|
||||
}
|
||||
|
||||
CommandManager.prototype.removeHooks =
|
||||
function cmgr_remhooks (hooks, prefix)
|
||||
{
|
||||
if (!prefix)
|
||||
prefix = "";
|
||||
|
||||
for (var h in hooks)
|
||||
{
|
||||
this.removeHook(h, prefix + ":" + h,
|
||||
("before" in hooks[h]) ? hooks[h].before : false);
|
||||
}
|
||||
}
|
||||
|
||||
CommandManager.prototype.removeHook =
|
||||
function cmgr_unhook (commandName, id, before)
|
||||
{
|
||||
var command = this.commands[commandName];
|
||||
|
||||
if (before)
|
||||
{
|
||||
arrayRemoveAt(command.beforeHookNames,
|
||||
command.beforeHooks[id][id + "_hookIndex"]);
|
||||
delete command.beforeHooks[id][id + "_hookIndex"];
|
||||
delete command.beforeHooks[id];
|
||||
if (keys(command.beforeHooks).length == 0)
|
||||
{
|
||||
delete command.beforeHookNames;
|
||||
delete command.beforeHooks;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
arrayRemoveAt(command.afterHookNames,
|
||||
command.afterHooks[id][id + "_hookIndex"]);
|
||||
delete command.afterHooks[id][id + "_hookIndex"];
|
||||
delete command.afterHooks[id];
|
||||
if (command.afterHookNames.length == 0)
|
||||
{
|
||||
delete command.afterHookNames;
|
||||
delete command.afterHooks;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of all CommandRecords which start with the string
|
||||
* |partialName|, sorted by |label| property.
|
||||
*
|
||||
* @param partialName Prefix to search for.
|
||||
* @param flags logical ANDed with command flags.
|
||||
* @returns array Array of matching commands, sorted by |label| property.
|
||||
*/
|
||||
CommandManager.prototype.list =
|
||||
function cmgr_list (partialName, flags)
|
||||
{
|
||||
/* returns array of command objects which look like |partialName|, or
|
||||
* all commands if |partialName| is not specified */
|
||||
function compare (a, b)
|
||||
{
|
||||
a = a.labelstr.toLowerCase();
|
||||
b = b.labelstr.toLowerCase();
|
||||
|
||||
if (a == b)
|
||||
return 0;
|
||||
|
||||
if (a > b)
|
||||
return 1;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
var ary = new Array();
|
||||
var commandNames = keys(this.commands);
|
||||
|
||||
/* a command named "eval" wouldn't show up in the result of keys() because
|
||||
* eval is not-enumerable, even if overwritten. */
|
||||
if ("eval" in this.commands && typeof this.commands.eval == "object")
|
||||
commandNames.push ("eval");
|
||||
|
||||
for (var i in commandNames)
|
||||
{
|
||||
var name = commandNames[i];
|
||||
if (!flags || (this.commands[name].flags & flags))
|
||||
{
|
||||
if (!partialName ||
|
||||
this.commands[name].name.indexOf(partialName) == 0)
|
||||
{
|
||||
if (partialName &&
|
||||
partialName.length == this.commands[name].name.length)
|
||||
{
|
||||
/* exact match */
|
||||
return [this.commands[name]];
|
||||
}
|
||||
else
|
||||
{
|
||||
ary.push (this.commands[name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ary.sort(compare);
|
||||
return ary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a sorted array of the command names which start with the string
|
||||
* |partialName|.
|
||||
*
|
||||
* @param partialName Prefix to search for.
|
||||
* @param flags logical ANDed with command flags.
|
||||
* @returns array Sorted Array of matching command names.
|
||||
*/
|
||||
CommandManager.prototype.listNames =
|
||||
function cmgr_listnames (partialName, flags)
|
||||
{
|
||||
var cmds = this.list(partialName, flags);
|
||||
var cmdNames = new Array();
|
||||
|
||||
for (var c in cmds)
|
||||
cmdNames.push (cmds[c].name);
|
||||
|
||||
return cmdNames.sort();
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal use only.
|
||||
*
|
||||
* Called to parse the arguments stored in |e.inputData|, as properties of |e|,
|
||||
* for the CommandRecord stored on |e.command|.
|
||||
*
|
||||
* @params e Event object to be processed.
|
||||
*/
|
||||
CommandManager.prototype.parseArguments =
|
||||
function cmgr_parseargs (e)
|
||||
{
|
||||
var rv = this.parseArgumentsRaw(e);
|
||||
//dd("parseArguments '" + e.command.usage + "' " +
|
||||
// (rv ? "passed" : "failed") + "\n" + dumpObjectTree(e));
|
||||
delete e.currentArgIndex;
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal use only.
|
||||
*
|
||||
* Don't call parseArgumentsRaw directly, use parseArguments instead.
|
||||
*
|
||||
* Parses the arguments stored in the |inputData| property of the event object,
|
||||
* according to the format specified by the |command| property.
|
||||
*
|
||||
* On success this method returns true, and propery names corresponding to the
|
||||
* argument names used in the format spec will be created on the event object.
|
||||
* All optional parameters will be initialized to |null| if not already present
|
||||
* on the event.
|
||||
*
|
||||
* On failure this method returns false and a description of the problem
|
||||
* will be stored in the |parseError| property of the event.
|
||||
*
|
||||
* For example...
|
||||
* Given the argument spec "<int> <word> [ <word2> <word3> ]", and given the
|
||||
* input string "411 foo", stored as |e.command.usage| and |e.inputData|
|
||||
* respectively, this method would add the following propertys to the event
|
||||
* object...
|
||||
* -name---value--notes-
|
||||
* e.int 411 Parsed as an integer
|
||||
* e.word foo Parsed as a string
|
||||
* e.word2 null Optional parameters not specified will be set to null.
|
||||
* e.word3 null If word2 had been provided, word3 would be required too.
|
||||
*
|
||||
* Each parameter is parsed by calling the function with the same name, located
|
||||
* in this.argTypes. The first parameter is parsed by calling the function
|
||||
* this.argTypes["int"], for example. This function is expected to act on
|
||||
* e.unparsedData, taking it's chunk, and leaving the rest of the string.
|
||||
* The default parse functions are...
|
||||
* <word> parses contiguous non-space characters.
|
||||
* <int> parses as an int.
|
||||
* <rest> parses to the end of input data.
|
||||
* <state> parses yes, on, true, 1, 0, false, off, no as a boolean.
|
||||
* <toggle> parses like a <state>, except allows "toggle" as well.
|
||||
* <...> parses according to the parameter type before it, until the end
|
||||
* of the input data. Results are stored in an array named
|
||||
* paramnameList, where paramname is the name of the parameter before
|
||||
* <...>. The value of the parameter before this will be
|
||||
* paramnameList[0].
|
||||
*
|
||||
* If there is no parse function for an argument type, "word" will be used by
|
||||
* default. You can alias argument types with code like...
|
||||
* commandManager.argTypes["my-integer-name"] = commandManager.argTypes["int"];
|
||||
*/
|
||||
CommandManager.prototype.parseArgumentsRaw =
|
||||
function parse_parseargsraw (e)
|
||||
{
|
||||
var argc = e.command.argNames.length;
|
||||
|
||||
function initOptionals()
|
||||
{
|
||||
for (var i = 0; i < argc; ++i)
|
||||
{
|
||||
if (e.command.argNames[i] != ":" &&
|
||||
e.command.argNames[i] != "..." &&
|
||||
!(e.command.argNames[i] in e))
|
||||
{
|
||||
e[e.command.argNames[i]] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ("inputData" in e && e.inputData)
|
||||
{
|
||||
/* if data has been provided, parse it */
|
||||
e.unparsedData = e.inputData;
|
||||
var parseResult;
|
||||
var currentArg;
|
||||
e.currentArgIndex = 0;
|
||||
|
||||
if (argc)
|
||||
{
|
||||
currentArg = e.command.argNames[e.currentArgIndex];
|
||||
|
||||
while (e.unparsedData)
|
||||
{
|
||||
if (currentArg != ":")
|
||||
{
|
||||
if (!this.parseArgument (e, currentArg))
|
||||
return false;
|
||||
}
|
||||
if (++e.currentArgIndex < argc)
|
||||
currentArg = e.command.argNames[e.currentArgIndex];
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (e.currentArgIndex < argc && currentArg != ":")
|
||||
{
|
||||
/* parse loop completed because it ran out of data. We haven't
|
||||
* parsed all of the declared arguments, and we're not stopped
|
||||
* at an optional marker, so we must be missing something
|
||||
* required... */
|
||||
e.parseError = getMsg(MSN_ERR_REQUIRED_PARAM,
|
||||
e.command.argNames[e.currentArgIndex]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (e.unparsedData)
|
||||
{
|
||||
/* parse loop completed with unparsed data, which means we've
|
||||
* successfully parsed all arguments declared. Whine about the
|
||||
* extra data... */
|
||||
display (getMsg(MSN_EXTRA_PARAMS, e.unparsedData), MT_WARN);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* we've got no unparsed data, and we're not missing a required
|
||||
* argument, go back and fill in |null| for any optional arguments
|
||||
* not present on the comand line. */
|
||||
initOptionals();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if no data was provided, check to see if the event is good enough
|
||||
* on its own. */
|
||||
var rv = this.isCommandSatisfied (e);
|
||||
if (rv)
|
||||
initOptionals();
|
||||
return rv;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if |e| has the properties required to call the command |command|.
|
||||
* If |command| is not provided, |e.command| is used instead.
|
||||
* @param e Event object to test against the command.
|
||||
* @param command Command to test.
|
||||
*/
|
||||
CommandManager.prototype.isCommandSatisfied =
|
||||
function cmgr_isok (e, command)
|
||||
{
|
||||
if (typeof command == "undefined")
|
||||
command = e.command;
|
||||
|
||||
if (!command.enabled)
|
||||
return false;
|
||||
|
||||
for (var i = 0; i < command.argNames.length; ++i)
|
||||
{
|
||||
if (command.argNames[i] == ":")
|
||||
return true;
|
||||
|
||||
if (!(command.argNames[i] in e))
|
||||
{
|
||||
e.parseError = getMsg(MSN_ERR_REQUIRED_PARAM, command.argNames[i]);
|
||||
//dd ("command '" + command.name + "' unsatisfied: " + e.parseError);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//dd ("command '" + command.name + "' satisfied.");
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal use only.
|
||||
* See parseArguments above and the |argTypes| object below.
|
||||
*
|
||||
* Parses the next argument by calling an appropriate parser function, or the
|
||||
* generic "word" parser if none other is found.
|
||||
*
|
||||
* @param e event object.
|
||||
* @param name property name to use for the parse result.
|
||||
*/
|
||||
CommandManager.prototype.parseArgument =
|
||||
function cmgr_parsearg (e, name)
|
||||
{
|
||||
var parseResult;
|
||||
|
||||
if (name in this.argTypes)
|
||||
parseResult = this.argTypes[name](e, name, this);
|
||||
else
|
||||
parseResult = this.argTypes["word"](e, name, this);
|
||||
|
||||
if (!parseResult)
|
||||
e.parseError = getMsg(MSN_ERR_INVALID_PARAM,
|
||||
[name, e.unparsedData]);
|
||||
|
||||
return parseResult;
|
||||
}
|
||||
|
||||
CommandManager.prototype.argTypes = new Object();
|
||||
|
||||
/**
|
||||
* Convenience function used to map a list of new types to an existing parse
|
||||
* function.
|
||||
*/
|
||||
CommandManager.prototype.argTypes.__aliasTypes__ =
|
||||
function at_alias (list, type)
|
||||
{
|
||||
for (var i in list)
|
||||
{
|
||||
this[list[i]] = this[type];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal use only.
|
||||
*
|
||||
* Parses an integer, stores result in |e[name]|.
|
||||
*/
|
||||
CommandManager.prototype.argTypes["int"] =
|
||||
function parse_int (e, name)
|
||||
{
|
||||
var ary = e.unparsedData.match (/(\d+)(?:\s+(.*))?$/);
|
||||
if (!ary)
|
||||
return false;
|
||||
e[name] = Number(ary[1]);
|
||||
e.unparsedData = (2 in ary) ? ary[2] : "";
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal use only.
|
||||
*
|
||||
* Parses a word, which is defined as a list of nonspace characters.
|
||||
*
|
||||
* Stores result in |e[name]|.
|
||||
*/
|
||||
CommandManager.prototype.argTypes["word"] =
|
||||
function parse_word (e, name)
|
||||
{
|
||||
var ary = e.unparsedData.match (/(\S+)(?:\s+(.*))?$/);
|
||||
if (!ary)
|
||||
return false;
|
||||
e[name] = ary[1];
|
||||
e.unparsedData = (2 in ary) ? ary[2] : "";
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal use only.
|
||||
*
|
||||
* Parses a "state" which can be "true", "on", "yes", or 1 to indicate |true|,
|
||||
* or "false", "off", "no", or 0 to indicate |false|.
|
||||
*
|
||||
* Stores result in |e[name]|.
|
||||
*/
|
||||
CommandManager.prototype.argTypes["state"] =
|
||||
function parse_state (e, name)
|
||||
{
|
||||
var ary =
|
||||
e.unparsedData.match (/(true|on|yes|1|false|off|no|0)(?:\s+(.*))?$/i);
|
||||
if (!ary)
|
||||
return false;
|
||||
if (ary[1].search(/true|on|yes|1/i) != -1)
|
||||
e[name] = true;
|
||||
else
|
||||
e[name] = false;
|
||||
e.unparsedData = (2 in ary) ? ary[2] : "";
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal use only.
|
||||
*
|
||||
* Parses a "toggle" which can be "true", "on", "yes", or 1 to indicate |true|,
|
||||
* or "false", "off", "no", or 0 to indicate |false|. In addition, the string
|
||||
* "toggle" is accepted, in which case |e[name]| will be the string "toggle".
|
||||
*
|
||||
* Stores result in |e[name]|.
|
||||
*/
|
||||
CommandManager.prototype.argTypes["toggle"] =
|
||||
function parse_toggle (e, name)
|
||||
{
|
||||
var ary = e.unparsedData.match
|
||||
(/(toggle|true|on|yes|1|false|off|no|0)(?:\s+(.*))?$/i);
|
||||
|
||||
if (!ary)
|
||||
return false;
|
||||
if (ary[1].search(/toggle/i) != -1)
|
||||
e[name] = "toggle";
|
||||
else if (ary[1].search(/true|on|yes|1/i) != -1)
|
||||
e[name] = true;
|
||||
else
|
||||
e[name] = false;
|
||||
e.unparsedData = (2 in ary) ? ary[2] : "";
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal use only.
|
||||
*
|
||||
* Returns all unparsed data to the end of the line.
|
||||
*
|
||||
* Stores result in |e[name]|.
|
||||
*/
|
||||
CommandManager.prototype.argTypes["rest"] =
|
||||
function parse_rest (e, name)
|
||||
{
|
||||
e[name] = e.unparsedData;
|
||||
e.unparsedData = "";
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal use only.
|
||||
*
|
||||
* Parses the rest of the unparsed data the same way the previous argument was
|
||||
* parsed. Can't be used as the first parameter. if |name| is "..." then the
|
||||
* name of the previous argument, plus the suffix "List" will be used instead.
|
||||
*
|
||||
* Stores result in |e[name]| or |e[lastName + "List"]|.
|
||||
*/
|
||||
CommandManager.prototype.argTypes["..."] =
|
||||
function parse_repeat (e, name, cm)
|
||||
{
|
||||
ASSERT (e.currentArgIndex > 0, "<...> can't be the first argument.");
|
||||
|
||||
var lastArg = e.command.argNames[e.currentArgIndex - 1];
|
||||
if (lastArg == ":")
|
||||
lastArg = e.command.argNames[e.currentArgIndex - 2];
|
||||
|
||||
var listName = lastArg + "List";
|
||||
e[listName] = [e[lastArg]];
|
||||
|
||||
while (e.unparsedData)
|
||||
{
|
||||
if (!cm.parseArgument(e, lastArg))
|
||||
return false;
|
||||
e[listName].push(e[lastArg]);
|
||||
}
|
||||
|
||||
e[lastArg] = e[listName][0];
|
||||
return true;
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<!--
|
||||
-
|
||||
- The contents of this file are subject to the Mozilla Public License
|
||||
- Version 1.1 (the "License"); you may not use this file except in
|
||||
- compliance with the License. You may obtain a copy of the License at
|
||||
- http://www.mozilla.org/MPL/
|
||||
-
|
||||
- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
- for the specific language governing rights and limitations under the
|
||||
- License.
|
||||
-
|
||||
- The Original Code is The JavaScript Debugger
|
||||
-
|
||||
- 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.
|
||||
-
|
||||
- Alternatively, the contents of this file may be used under the
|
||||
- terms of the GNU Public License (the "GPL"), in which case the
|
||||
- provisions of the GPL are applicable instead of those above.
|
||||
- If you wish to allow use of your version of this file only
|
||||
- under the terms of the GPL and not to allow others to use your
|
||||
- version of this file under the MPL, indicate your decision by
|
||||
- deleting the provisions above and replace them with the notice
|
||||
- and other provisions required by the GPL. If you do not delete
|
||||
- the provisions above, a recipient may use your version of this
|
||||
- file under either the MPL or the GPL.
|
||||
-
|
||||
- Contributor(s):
|
||||
- Robert Ginda, <rginda@netscape.com>, original author
|
||||
-
|
||||
-->
|
||||
|
||||
<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
|
||||
|
||||
<!-- list all the packages being supplied by this jar -->
|
||||
<RDF:Seq about="urn:mozilla:package:root">
|
||||
<RDF:li resource="urn:mozilla:package:venkman"/>
|
||||
</RDF:Seq>
|
||||
|
||||
<!-- package information -->
|
||||
<RDF:Description about="urn:mozilla:package:venkman"
|
||||
chrome:displayName="JavaScript Debugger"
|
||||
chrome:author="mozilla.org"
|
||||
chrome:name="venkman">
|
||||
</RDF:Description>
|
||||
|
||||
<!-- overlay information -->
|
||||
<RDF:Seq about="urn:mozilla:overlays">
|
||||
<RDF:li resource="chrome://communicator/content/tasksOverlay.xul"/>
|
||||
</RDF:Seq>
|
||||
|
||||
<RDF:Seq about="chrome://communicator/content/tasksOverlay.xul">
|
||||
<RDF:li>chrome://venkman/content/venkman-overlay.xul</RDF:li>
|
||||
</RDF:Seq>
|
||||
</RDF:RDF>
|
||||
@@ -1,295 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is The JavaScript Debugger
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation
|
||||
* Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the MPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Robert Ginda, <rginda@netscape.com>, original author
|
||||
*
|
||||
*/
|
||||
|
||||
/* notice that these valuse are octal. */
|
||||
const PERM_IRWXU = 00700; /* read, write, execute/search by owner */
|
||||
const PERM_IRUSR = 00400; /* read permission, owner */
|
||||
const PERM_IWUSR = 00200; /* write permission, owner */
|
||||
const PERM_IXUSR = 00100; /* execute/search permission, owner */
|
||||
const PERM_IRWXG = 00070; /* read, write, execute/search by group */
|
||||
const PERM_IRGRP = 00040; /* read permission, group */
|
||||
const PERM_IWGRP = 00020; /* write permission, group */
|
||||
const PERM_IXGRP = 00010; /* execute/search permission, group */
|
||||
const PERM_IRWXO = 00007; /* read, write, execute/search by others */
|
||||
const PERM_IROTH = 00004; /* read permission, others */
|
||||
const PERM_IWOTH = 00002; /* write permission, others */
|
||||
const PERM_IXOTH = 00001; /* execute/search permission, others */
|
||||
|
||||
const MODE_RDONLY = 0x01;
|
||||
const MODE_WRONLY = 0x02;
|
||||
const MODE_RDWR = 0x04;
|
||||
const MODE_CREATE = 0x08;
|
||||
const MODE_APPEND = 0x10;
|
||||
const MODE_TRUNCATE = 0x20;
|
||||
const MODE_SYNC = 0x40;
|
||||
const MODE_EXCL = 0x80;
|
||||
|
||||
const PICK_OK = Components.interfaces.nsIFilePicker.returnOK;
|
||||
const PICK_CANCEL = Components.interfaces.nsIFilePicker.returnCancel;
|
||||
const PICK_REPLACE = Components.interfaces.nsIFilePicker.returnReplace;
|
||||
|
||||
const FILTER_ALL = Components.interfaces.nsIFilePicker.filterAll;
|
||||
const FILTER_HTML = Components.interfaces.nsIFilePicker.filterHTML;
|
||||
const FILTER_TEXT = Components.interfaces.nsIFilePicker.filterText;
|
||||
const FILTER_IMAGES = Components.interfaces.nsIFilePicker.filterImages;
|
||||
const FILTER_XML = Components.interfaces.nsIFilePicker.filterXML;
|
||||
const FILTER_XUL = Components.interfaces.nsIFilePicker.filterXUL;
|
||||
|
||||
// evald f = fopen("/home/rginda/foo.txt", MODE_WRONLY | MODE_CREATE)
|
||||
// evald f = fopen("/home/rginda/vnk.txt", MODE_RDONLY)
|
||||
|
||||
var futils = new Object();
|
||||
|
||||
futils.umask = PERM_IWOTH | PERM_IWGRP;
|
||||
futils.MSG_SAVE_AS = "Save As";
|
||||
futils.MSG_OPEN = "Open";
|
||||
|
||||
futils.getPicker =
|
||||
function futils_nosepicker(initialPath, typeList, attribs)
|
||||
{
|
||||
const classes = Components.classes;
|
||||
const interfaces = Components.interfaces;
|
||||
|
||||
const PICKER_CTRID = "@mozilla.org/filepicker;1";
|
||||
const LOCALFILE_CTRID = "@mozilla.org/file/local;1";
|
||||
|
||||
const nsIFilePicker = interfaces.nsIFilePicker;
|
||||
const nsILocalFile = interfaces.nsILocalFile;
|
||||
|
||||
var picker = classes[PICKER_CTRID].createInstance(nsIFilePicker);
|
||||
if (typeof attribs == "object")
|
||||
{
|
||||
for (var a in attribs)
|
||||
picker[a] = attribs[a];
|
||||
}
|
||||
else
|
||||
throw "bad type for param |attribs|";
|
||||
|
||||
if (initialPath)
|
||||
{
|
||||
var localFile;
|
||||
|
||||
if (typeof initialPath == "string")
|
||||
{
|
||||
localFile =
|
||||
classes[LOCALFILE_CTRID].createInstance(nsILocalFile);
|
||||
localFile.initWithPath(initialPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(initialPath instanceof nsILocalFile))
|
||||
throw "bad type for argument |initialPath|";
|
||||
|
||||
localFile = initialPath;
|
||||
}
|
||||
|
||||
picker.displayDirectory = localFile
|
||||
}
|
||||
|
||||
if (typeof typeList == "string")
|
||||
typeList = typeList.split(" ");
|
||||
|
||||
if (typeList instanceof Array)
|
||||
{
|
||||
for (var i in typeList)
|
||||
{
|
||||
switch (typeList[i])
|
||||
{
|
||||
case "$all":
|
||||
picker.appendFilters(FILTER_ALL);
|
||||
break;
|
||||
|
||||
case "$html":
|
||||
picker.appendFilters(FILTER_HTML);
|
||||
break;
|
||||
|
||||
case "$text":
|
||||
picker.appendFilters(FILTER_TEXT);
|
||||
break;
|
||||
|
||||
case "$images":
|
||||
picker.appendFilters(FILTER_IMAGES);
|
||||
break;
|
||||
|
||||
case "$xml":
|
||||
picker.appendFilters(FILTER_XML);
|
||||
break;
|
||||
|
||||
case "$xul":
|
||||
picker.appendFilters(FILTER_XUL);
|
||||
break;
|
||||
|
||||
default:
|
||||
picker.appendFilter(typeList[i], typeList[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return picker;
|
||||
}
|
||||
|
||||
function pickSaveAs (title, typeList, defaultFile, defaultDir)
|
||||
{
|
||||
if (!defaultDir && "lastSaveAsDir" in futils)
|
||||
defaultDir = futils.lastSaveAsDir;
|
||||
|
||||
var picker = futils.getPicker (defaultDir, typeList,
|
||||
{defaultString: defaultFile});
|
||||
picker.init (window, title ? title : futils.MSG_SAVE_AS,
|
||||
Components.interfaces.nsIFilePicker.modeSave);
|
||||
|
||||
var rv = picker.show();
|
||||
|
||||
if (rv != PICK_CANCEL)
|
||||
futils.lastSaveAsDir = picker.file.parent;
|
||||
|
||||
return {reason: rv, file: picker.file, picker: picker};
|
||||
}
|
||||
|
||||
function pickOpen (title, typeList, defaultFile, defaultDir)
|
||||
{
|
||||
if (!defaultDir && "lastOpenDir" in futils)
|
||||
defaultDir = futils.lastOpenDir;
|
||||
|
||||
var picker = futils.getPicker (defaultDir, typeList,
|
||||
{defaultString: defaultFile});
|
||||
picker.init (window, title ? title : futils.MSG_OPEN,
|
||||
Components.interfaces.nsIFilePicker.modeOpen);
|
||||
|
||||
var rv = picker.show();
|
||||
|
||||
if (rv != PICK_CANCEL)
|
||||
futils.lastOpenDir = picker.file.parent;
|
||||
|
||||
return {reason: rv, file: picker.file, picker: picker};
|
||||
}
|
||||
|
||||
function fopen (path, mode, perms, tmp)
|
||||
{
|
||||
return new LocalFile(path, mode, perms, tmp);
|
||||
}
|
||||
|
||||
function LocalFile(file, mode, perms, tmp)
|
||||
{
|
||||
const classes = Components.classes;
|
||||
const interfaces = Components.interfaces;
|
||||
|
||||
const LOCALFILE_CTRID = "@mozilla.org/file/local;1";
|
||||
const FILEIN_CTRID = "@mozilla.org/network/file-input-stream;1";
|
||||
const FILEOUT_CTRID = "@mozilla.org/network/file-output-stream;1";
|
||||
const SCRIPTSTREAM_CTRID = "@mozilla.org/scriptableinputstream;1";
|
||||
|
||||
const nsIFile = interfaces.nsIFile;
|
||||
const nsILocalFile = interfaces.nsILocalFile;
|
||||
const nsIFileOutputStream = interfaces.nsIFileOutputStream;
|
||||
const nsIFileInputStream = interfaces.nsIFileInputStream;
|
||||
const nsIScriptableInputStream = interfaces.nsIScriptableInputStream;
|
||||
|
||||
if (typeof perms == "undefined")
|
||||
perms = 0666 & ~futils.umask;
|
||||
|
||||
if (typeof file == "string")
|
||||
{
|
||||
this.localFile = classes[LOCALFILE_CTRID].createInstance(nsILocalFile);
|
||||
this.localFile.initWithPath(file);
|
||||
}
|
||||
else if (file instanceof nsILocalFile)
|
||||
{
|
||||
this.localFile = file;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw "bad type for argument |file|.";
|
||||
}
|
||||
|
||||
if (mode & (MODE_WRONLY | MODE_RDWR))
|
||||
{
|
||||
this.outputStream =
|
||||
classes[FILEOUT_CTRID].createInstance(nsIFileOutputStream);
|
||||
this.outputStream.init(this.localFile, mode, perms, 0);
|
||||
}
|
||||
|
||||
if (mode & (MODE_RDONLY | MODE_RDWR))
|
||||
{
|
||||
var is = classes[FILEIN_CTRID].createInstance(nsIFileInputStream);
|
||||
is.init(this.localFile, mode, perms, tmp);
|
||||
this.inputStream =
|
||||
classes[SCRIPTSTREAM_CTRID].createInstance(nsIScriptableInputStream);
|
||||
this.inputStream.init(is);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LocalFile.prototype.write =
|
||||
function fo_write(buf)
|
||||
{
|
||||
if (!("outputStream" in this))
|
||||
throw "file not open for writing.";
|
||||
|
||||
return this.outputStream.write(buf, buf.length);
|
||||
}
|
||||
|
||||
LocalFile.prototype.read =
|
||||
function fo_read(max)
|
||||
{
|
||||
if (!("inputStream" in this))
|
||||
throw "file not open for reading.";
|
||||
|
||||
var av = this.inputStream.available();
|
||||
if (typeof max == "undefined")
|
||||
max = av;
|
||||
|
||||
if (!av)
|
||||
return null;
|
||||
|
||||
var rv = this.inputStream.read(max);
|
||||
return rv;
|
||||
}
|
||||
|
||||
LocalFile.prototype.close =
|
||||
function fo_close()
|
||||
{
|
||||
if ("outputStream" in this)
|
||||
this.outputStream.close();
|
||||
if ("inputStream" in this)
|
||||
this.inputStream.close();
|
||||
}
|
||||
|
||||
LocalFile.prototype.flush =
|
||||
function fo_close()
|
||||
{
|
||||
return this.outputStream.flush();
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is The JavaScript Debugger
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation
|
||||
* Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the MPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Robert Ginda, <rginda@netscape.com>, original author
|
||||
*
|
||||
*/
|
||||
|
||||
const NS_XHTML = "http://www.w3.org/1999/xhtml";
|
||||
|
||||
const HTML_BR = "html:br";
|
||||
const HTML_IMG = "html:img";
|
||||
const HTML_SPAN = "html:span";
|
||||
const HTML_TABLE = "html:table";
|
||||
const HTML_TBODY = "html:tbody";
|
||||
const HTML_TD = "html:td";
|
||||
const HTML_TH = "html:th";
|
||||
const HTML_TR = "html:tr";
|
||||
|
||||
function HTML (tagName, attribs, args)
|
||||
{
|
||||
var elem = document.createElementNS (NS_XHTML, tagName);
|
||||
|
||||
if (typeof attribs == "string")
|
||||
elem.setAttribute ("class", attribs);
|
||||
else if (attribs && typeof attribs == "object")
|
||||
for (var p in attribs)
|
||||
elem.setAttribute (p, attribs[p]);
|
||||
|
||||
var start = 0;
|
||||
|
||||
if (args)
|
||||
{
|
||||
if (!(args instanceof Array))
|
||||
args = [args];
|
||||
else if (arguments.length > 3)
|
||||
{
|
||||
start = 2; args = arguments;
|
||||
}
|
||||
|
||||
for (var i = start; i < args.length; ++i)
|
||||
if (typeof args[i] == "string")
|
||||
elem.appendChild (document.createTextNode(args[i]));
|
||||
else if (args[i])
|
||||
elem.appendChild (args[i]);
|
||||
|
||||
}
|
||||
|
||||
return elem;
|
||||
}
|
||||
|
||||
function htmlA(attribs, href, contents)
|
||||
{
|
||||
if (typeof contents == "undefined")
|
||||
contents = href;
|
||||
|
||||
var a = HTML("html:a", attribs, contents);
|
||||
a.setAttribute ("href", href);
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
function htmlBR(attribs)
|
||||
{
|
||||
return HTML("html:br", attribs, argumentsAsArray(arguments, 1));
|
||||
}
|
||||
|
||||
function htmlWBR(attribs)
|
||||
{
|
||||
return HTML("html:wbr", attribs, argumentsAsArray(arguments, 1));
|
||||
}
|
||||
|
||||
function htmlImg(attribs, src)
|
||||
{
|
||||
var img = HTML("html:img", attribs, argumentsAsArray(arguments, 2));
|
||||
if (src)
|
||||
img.setAttribute ("src", src);
|
||||
return img;
|
||||
}
|
||||
|
||||
function htmlSpan(attribs)
|
||||
{
|
||||
return HTML("html:span", attribs, argumentsAsArray(arguments, 1));
|
||||
}
|
||||
|
||||
function htmlTable(attribs)
|
||||
{
|
||||
return HTML("html:table", attribs, argumentsAsArray(arguments, 1));
|
||||
}
|
||||
|
||||
function htmlTBody(attribs)
|
||||
{
|
||||
return HTML("html:tbody", attribs, argumentsAsArray(arguments, 1));
|
||||
}
|
||||
|
||||
function htmlText(text)
|
||||
{
|
||||
return document.createTextNode(text);
|
||||
}
|
||||
|
||||
function htmlTD(attribs)
|
||||
{
|
||||
return HTML("html:td", attribs, argumentsAsArray(arguments, 1));
|
||||
}
|
||||
|
||||
function htmlTR(attribs)
|
||||
{
|
||||
return HTML("html:tr", attribs, argumentsAsArray(arguments, 1));
|
||||
}
|
||||
|
||||
function htmlTH(attribs)
|
||||
{
|
||||
return HTML("html:th", attribs, argumentsAsArray(arguments, 1));
|
||||
}
|
||||
|
||||
@@ -1,497 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is The JavaScript Debugger
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation
|
||||
* Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the MPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Robert Ginda, <rginda@netscape.com>, original author
|
||||
*
|
||||
*/
|
||||
|
||||
function MenuManager (commandManager, menuSpecs, contextFunction, commandStr)
|
||||
{
|
||||
var menuManager = this;
|
||||
|
||||
this.commandManager = commandManager;
|
||||
this.menuSpecs = menuSpecs;
|
||||
this.contextFunction = contextFunction;
|
||||
this.commandStr = commandStr;
|
||||
|
||||
this.onPopupShowing =
|
||||
function mmgr_onshow (event) { return menuManager.showPopup (event); };
|
||||
this.onPopupHiding =
|
||||
function mmgr_onhide (event) { return menuManager.hidePopup (event); };
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal use only.
|
||||
*
|
||||
* Registers event handlers on a given menu.
|
||||
*/
|
||||
MenuManager.prototype.hookPopup =
|
||||
function mmgr_hookpop (node)
|
||||
{
|
||||
node.addEventListener ("popupshowing", this.onPopupShowing, false);
|
||||
node.addEventListener ("popuphiding", this.onPopupHiding, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal use only.
|
||||
*
|
||||
* |showPopup| is called from the "onpopupshowing" event of menus
|
||||
* managed by the CommandManager. If a command is disabled, represents a command
|
||||
* that cannot be "satisfied" by the current command context |cx|, or has an
|
||||
* "enabledif" attribute that eval()s to false, then the menuitem is disabled.
|
||||
* In addition "checkedif" and "visibleif" attributes are eval()d and
|
||||
* acted upon accordingly.
|
||||
*/
|
||||
MenuManager.prototype.showPopup =
|
||||
function mmgr_showpop (event)
|
||||
{
|
||||
//dd ("showPopup {");
|
||||
/* returns true if the command context has the properties required to
|
||||
* execute the command associated with |menuitem|.
|
||||
*/
|
||||
function satisfied()
|
||||
{
|
||||
if (menuitem.hasAttribute("isSeparator"))
|
||||
return true;
|
||||
|
||||
if (!("menuManager" in cx))
|
||||
{
|
||||
dd ("no menuManager in cx");
|
||||
return false;
|
||||
}
|
||||
|
||||
var name = menuitem.getAttribute("commandname");
|
||||
var commandManager = cx.menuManager.commandManager;
|
||||
var commands = commandManager.commands;
|
||||
|
||||
if (!ASSERT (name in commands,
|
||||
"menu contains unknown command '" + name + "'"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var rv = commandManager.isCommandSatisfied(cx, commands[name]);
|
||||
delete cx.parseError;
|
||||
return rv;
|
||||
};
|
||||
|
||||
/* Convenience function for "enabledif", etc, attributes. */
|
||||
function has (prop)
|
||||
{
|
||||
return (prop in cx);
|
||||
};
|
||||
|
||||
/* evals the attribute named |attr| on the node |node|. */
|
||||
function evalIfAttribute (node, attr)
|
||||
{
|
||||
var ex;
|
||||
var expr = node.getAttribute(attr);
|
||||
if (!expr)
|
||||
return true;
|
||||
|
||||
expr = expr.replace (/\Wand\W/gi, " && ");
|
||||
|
||||
try
|
||||
{
|
||||
return eval("(" + expr + ")");
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
dd ("caught exception evaling '" + node.getAttribute("id") + "'.'" +
|
||||
attr + "'\n" + ex);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
var cx;
|
||||
var popup = event.originalTarget;
|
||||
var menuitem = popup.firstChild;
|
||||
|
||||
|
||||
/* If the host provided a |contextFunction|, use it now. Remember the
|
||||
* return result as this.cx for use if something from this menu is actually
|
||||
* dispatched. this.cx is deleted in |hidePopup|. */
|
||||
if (typeof this.contextFunction == "function")
|
||||
{
|
||||
cx = this.cx = this.contextFunction (popup.getAttribute("menuName"),
|
||||
event);
|
||||
}
|
||||
else
|
||||
{
|
||||
cx = this.cx = { menuManager: this, originalEvent: event };
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
/* should it be visible? */
|
||||
if (menuitem.hasAttribute("visibleif"))
|
||||
{
|
||||
if (evalIfAttribute(menuitem, "visibleif"))
|
||||
menuitem.removeAttribute ("hidden");
|
||||
else
|
||||
{
|
||||
menuitem.setAttribute ("hidden", "true");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* ok, it's visible, maybe it should be disabled? */
|
||||
if (satisfied())
|
||||
{
|
||||
if (menuitem.hasAttribute("enabledif"))
|
||||
{
|
||||
if (evalIfAttribute(menuitem, "enabledif"))
|
||||
menuitem.removeAttribute ("disabled");
|
||||
else
|
||||
menuitem.setAttribute ("disabled", "true");
|
||||
}
|
||||
else
|
||||
menuitem.removeAttribute ("disabled");
|
||||
}
|
||||
else
|
||||
{
|
||||
menuitem.setAttribute ("disabled", "true");
|
||||
}
|
||||
|
||||
/* should it have a check? */
|
||||
if (menuitem.hasAttribute("checkedif"))
|
||||
{
|
||||
if (evalIfAttribute(menuitem, "checkedif"))
|
||||
menuitem.setAttribute ("checked", "true");
|
||||
else
|
||||
menuitem.removeAttribute ("checked");
|
||||
}
|
||||
|
||||
} while ((menuitem = menuitem.nextSibling));
|
||||
|
||||
//dd ("}");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal use only.
|
||||
*
|
||||
* |hidePopup| is called from the "onpopuphiding" event of menus
|
||||
* managed by the CommandManager. Nothing to do here anymore.
|
||||
* We used to just clean up this.cx, but that's a problem for nested
|
||||
* menus.
|
||||
*/
|
||||
MenuManager.prototype.hidePopup =
|
||||
function mmgr_hidepop (id)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a sub-menu to an existing menu.
|
||||
* @param parentNode DOM Node to insert into
|
||||
* @param beforeNode DOM Node already contained by parentNode, to insert before
|
||||
* @param id ID of the sub-menu to add.
|
||||
* @param label Text to use for this sub-menu. The & character can be
|
||||
* used to indicate the accesskey.
|
||||
* @param attribs Object containing CSS attributes to set on the element.
|
||||
*/
|
||||
MenuManager.prototype.appendSubMenu =
|
||||
function mmgr_addsmenu (parentNode, beforeNode, menuName, domId, label, attribs)
|
||||
{
|
||||
var document = parentNode.ownerDocument;
|
||||
|
||||
/* sometimes the menu is already there, for overlay purposes. */
|
||||
var menu = document.getElementById(domId);
|
||||
|
||||
if (!menu)
|
||||
{
|
||||
menu = document.createElement ("menu");
|
||||
menu.setAttribute ("id", domId);
|
||||
parentNode.insertBefore(menu, beforeNode);
|
||||
}
|
||||
|
||||
var menupopup = menu.firstChild;
|
||||
|
||||
if (!menupopup)
|
||||
{
|
||||
menupopup = document.createElement ("menupopup");
|
||||
menupopup.setAttribute ("id", domId + "-popup");
|
||||
menu.appendChild(menupopup);
|
||||
menupopup = menu.firstChild;
|
||||
}
|
||||
|
||||
menupopup.setAttribute ("menuName", menuName);
|
||||
|
||||
menu.setAttribute ("accesskey", getAccessKey(label));
|
||||
menu.setAttribute ("label", label.replace("&", ""));
|
||||
menu.setAttribute ("isSeparator", true);
|
||||
|
||||
if (typeof attribs == "object")
|
||||
{
|
||||
for (var p in attribs)
|
||||
menu.setAttribute (p, attribs[p]);
|
||||
}
|
||||
|
||||
this.hookPopup (menupopup);
|
||||
|
||||
return menupopup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a popup to an existing popupset.
|
||||
* @param parentNode DOM Node to insert into
|
||||
* @param beforeNode DOM Node already contained by parentNode, to insert before
|
||||
* @param id ID of the popup to add.
|
||||
* @param label Text to use for this popup. Popup menus don't normally have
|
||||
* labels, but we set a "label" attribute anyway, in case
|
||||
* the host wants it for some reason. Any "&" characters will
|
||||
* be stripped.
|
||||
* @param attribs Object containing CSS attributes to set on the element.
|
||||
*/
|
||||
MenuManager.prototype.appendPopupMenu =
|
||||
function mmgr_addpmenu (parentNode, beforeNode, menuName, id, label, attribs)
|
||||
{
|
||||
var document = parentNode.ownerDocument;
|
||||
var popup = document.createElement ("popup");
|
||||
popup.setAttribute ("id", id);
|
||||
if (label)
|
||||
popup.setAttribute ("label", label.replace("&", ""));
|
||||
if (typeof attribs == "object")
|
||||
{
|
||||
for (var p in attribs)
|
||||
popup.setAttribute (p, attribs[p]);
|
||||
}
|
||||
|
||||
popup.setAttribute ("menuName", menuName);
|
||||
|
||||
parentNode.insertBefore(popup, beforeNode);
|
||||
this.hookPopup (popup);
|
||||
|
||||
return popup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a menuitem to an existing menu or popup.
|
||||
* @param parentNode DOM Node to insert into
|
||||
* @param beforeNode DOM Node already contained by parentNode, to insert before
|
||||
* @param command A reference to the CommandRecord this menu item will represent.
|
||||
* @param attribs Object containing CSS attributes to set on the element.
|
||||
*/
|
||||
MenuManager.prototype.appendMenuItem =
|
||||
function mmgr_addmenu (parentNode, beforeNode, commandName, attribs)
|
||||
{
|
||||
var menuManager = this;
|
||||
|
||||
var document = parentNode.ownerDocument;
|
||||
if (commandName == "-")
|
||||
return this.appendMenuSeparator(parentNode, beforeNode, attribs);
|
||||
|
||||
var parentId = parentNode.getAttribute("id");
|
||||
|
||||
if (!ASSERT(commandName in this.commandManager.commands,
|
||||
"unknown command " + commandName + " targeted for " +
|
||||
parentId))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var command = this.commandManager.commands[commandName];
|
||||
var menuitem = document.createElement ("menuitem");
|
||||
menuitem.setAttribute ("id", parentId + ":" + commandName);
|
||||
menuitem.setAttribute ("commandname", command.name);
|
||||
menuitem.setAttribute ("key", "key:" + command.name);
|
||||
menuitem.setAttribute ("accesskey", getAccessKey(command.label));
|
||||
menuitem.setAttribute ("label", command.label.replace("&", ""));
|
||||
menuitem.setAttribute ("oncommand", this.commandStr);
|
||||
|
||||
if (typeof attribs == "object")
|
||||
{
|
||||
for (var p in attribs)
|
||||
menuitem.setAttribute (p, attribs[p]);
|
||||
}
|
||||
|
||||
command.uiElements.push(menuitem);
|
||||
parentNode.insertBefore (menuitem, beforeNode);
|
||||
|
||||
return menuitem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a menuseparator to an existing menu or popup.
|
||||
* @param parentNode DOM Node to insert into
|
||||
* @param beforeNode DOM Node already contained by parentNode, to insert before
|
||||
* @param attribs Object containing CSS attributes to set on the element.
|
||||
*/
|
||||
MenuManager.prototype.appendMenuSeparator =
|
||||
function mmgr_addsep (parentNode, beforeNode, attribs)
|
||||
{
|
||||
var document = parentNode.ownerDocument;
|
||||
var menuitem = document.createElement ("menuseparator");
|
||||
menuitem.setAttribute ("isSeparator", true);
|
||||
if (typeof attribs == "object")
|
||||
{
|
||||
for (var p in attribs)
|
||||
menuitem.setAttribute (p, attribs[p]);
|
||||
}
|
||||
parentNode.insertBefore (menuitem, beforeNode);
|
||||
|
||||
return menuitem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a toolbaritem to an existing box element.
|
||||
* @param parentNode DOM Node to insert into
|
||||
* @param beforeNode DOM Node already contained by parentNode, to insert before
|
||||
* @param command A reference to the CommandRecord this toolbaritem will
|
||||
* represent.
|
||||
* @param attribs Object containing CSS attributes to set on the element.
|
||||
*/
|
||||
MenuManager.prototype.appendToolbarItem =
|
||||
function mmgr_addtb (parentNode, beforeNode, commandName, attribs)
|
||||
{
|
||||
if (commandName == "-")
|
||||
return this.appendToolbarSeparator(parentNode, beforeNode, attribs);
|
||||
|
||||
var parentId = parentNode.getAttribute("id");
|
||||
|
||||
if (!ASSERT(commandName in this.commandManager.commands,
|
||||
"unknown command " + commandName + " targeted for " +
|
||||
parentId))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var command = this.commandManager.commands[commandName];
|
||||
var document = parentNode.ownerDocument;
|
||||
var tbitem = document.createElement ("toolbarbutton");
|
||||
|
||||
var id = parentNode.getAttribute("id") + ":" + commandName;
|
||||
tbitem.setAttribute ("id", id);
|
||||
tbitem.setAttribute ("class", "toolbarbutton-1");
|
||||
tbitem.setAttribute ("label", command.label.replace("&", ""));
|
||||
tbitem.setAttribute ("oncommand",
|
||||
"dispatch('" + commandName + "');");
|
||||
if (typeof attribs == "object")
|
||||
{
|
||||
for (var p in attribs)
|
||||
tbitem.setAttribute (p, attribs[p]);
|
||||
}
|
||||
|
||||
command.uiElements.push(tbitem);
|
||||
parentNode.insertBefore (tbitem, beforeNode);
|
||||
|
||||
return tbitem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a toolbarseparator to an existing box.
|
||||
* @param parentNode DOM Node to insert into
|
||||
* @param beforeNode DOM Node already contained by parentNode, to insert before
|
||||
* @param attribs Object containing CSS attributes to set on the element.
|
||||
*/
|
||||
MenuManager.prototype.appendToolbarSeparator =
|
||||
function mmgr_addmenu (parentNode, beforeNode, attribs)
|
||||
{
|
||||
var document = parentNode.ownerDocument;
|
||||
var tbitem = document.createElement ("toolbarseparator");
|
||||
tbitem.setAttribute ("isSeparator", true);
|
||||
if (typeof attribs == "object")
|
||||
{
|
||||
for (var p in attribs)
|
||||
tbitem.setAttribute (p, attribs[p]);
|
||||
}
|
||||
parentNode.appendChild (tbitem);
|
||||
|
||||
return tbitem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates menu DOM nodes from a menu specification.
|
||||
* @param parentNode DOM Node to insert into
|
||||
* @param beforeNode DOM Node already contained by parentNode, to insert before
|
||||
* @param menuSpec array of menu items
|
||||
*/
|
||||
MenuManager.prototype.createMenu =
|
||||
function mmgr_newmenu (parentNode, beforeNode, menuName, domId, attribs)
|
||||
{
|
||||
if (typeof domId == "undefined")
|
||||
domId = menuName;
|
||||
|
||||
if (!ASSERT(menuName in this.menuSpecs, "unknown menu name " + menuName))
|
||||
return null;
|
||||
|
||||
var menuSpec = this.menuSpecs[menuName];
|
||||
|
||||
var subMenu = this.appendSubMenu (parentNode, beforeNode, menuName, domId,
|
||||
menuSpec.label, attribs);
|
||||
|
||||
this.createMenuItems (subMenu, null, menuSpec.items);
|
||||
return subMenu;
|
||||
}
|
||||
|
||||
MenuManager.prototype.createMenuItems =
|
||||
function mmgr_newitems (parentNode, beforeNode, menuItems)
|
||||
{
|
||||
function itemAttribs()
|
||||
{
|
||||
return (1 in menuItems[i]) ? menuItems[i][1] : null;
|
||||
};
|
||||
|
||||
var parentId = parentNode.getAttribute("id");
|
||||
|
||||
for (var i in menuItems)
|
||||
{
|
||||
var itemName = menuItems[i][0];
|
||||
if (itemName[0] == ">")
|
||||
{
|
||||
itemName = itemName.substr(1);
|
||||
if (!ASSERT(itemName in this.menuSpecs,
|
||||
"unknown submenu " + itemName + " referenced in " +
|
||||
parentId))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
this.createMenu (parentNode, beforeNode, itemName,
|
||||
parentId + ":" + itemName, itemAttribs());
|
||||
}
|
||||
else if (itemName in this.commandManager.commands)
|
||||
{
|
||||
this.appendMenuItem (parentNode, beforeNode, itemName,
|
||||
itemAttribs());
|
||||
}
|
||||
else if (itemName == "-")
|
||||
{
|
||||
this.appendMenuSeparator (parentNode, beforeNode, itemAttribs());
|
||||
}
|
||||
else
|
||||
{
|
||||
dd ("unknown command " + itemName + " referenced in " + parentId);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
# full-url, file-name, function-name, start-line, end-line, call-count, recurse-depth, total-time, min-time, max-time, avg-time
|
||||
@-item-start
|
||||
$full-url, $file-name, $function-name, $start-line, $end-line, $call-count, $recurse-depth, $total-time, $min-time, $max-time, $avg-time
|
||||
@-item-end
|
||||
@@ -1,117 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>JavaScript Profile Data</title>
|
||||
</head>
|
||||
<style>
|
||||
.profile-file-title {
|
||||
font-size : larger;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-weight: bold;
|
||||
color: darkred;
|
||||
}
|
||||
|
||||
.value {
|
||||
color: grey;
|
||||
}
|
||||
|
||||
.graph-box {
|
||||
border : 1px grey solid;
|
||||
margin-top : 5px;
|
||||
margin-bottom : 5px;
|
||||
padding-top : 5px;
|
||||
padding-bottom: 5px;
|
||||
background : lightgrey;
|
||||
display : block;
|
||||
}
|
||||
|
||||
.graph-body {
|
||||
margin-left: 3%;
|
||||
background : white;
|
||||
display : block;
|
||||
width : 94%;
|
||||
border : 1px black solid;
|
||||
}
|
||||
|
||||
.graph-title {
|
||||
display : block;
|
||||
margin-left: 3%;
|
||||
}
|
||||
|
||||
.left-trough,
|
||||
.below-avg-trough,
|
||||
.above-avg-trough {
|
||||
border : 0px black solid;
|
||||
margin : 0px;
|
||||
padding: 0px;
|
||||
height : 20px;
|
||||
}
|
||||
|
||||
.below-avg-trough {
|
||||
border-right: 1px slategrey solid;
|
||||
border-left : 1px black solid;
|
||||
background : darkslategrey;
|
||||
}
|
||||
|
||||
.above-avg-trough {
|
||||
border-left : 1px slategrey solid;
|
||||
border-right: 1px black solid;
|
||||
background : darkslategrey;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<h1>JavaScript Profile Data</h1>
|
||||
<span class="label">Collection Date:</span>
|
||||
<span class="value">$full-date</span><br>
|
||||
<span class="label">User Agent:</span>
|
||||
<span class="value">$user-agent</span><br>
|
||||
<span class="label">JavaScript Debugger Version:</span>
|
||||
<span class="value">$venkman-agent</span><br>
|
||||
<span class="label">Sorted By:</span>
|
||||
<span class="value">$sort-key</span><br>
|
||||
<a name="section0"></a>
|
||||
@-section-start
|
||||
<hr>
|
||||
<span class="section-box">
|
||||
<a name="section$section-number"></a>
|
||||
<h2 class="section-title">$section-link</h2>
|
||||
<a name="range$section-number:0"></a>
|
||||
@-range-start
|
||||
<span class="range-box">
|
||||
<a name="range$section-number:$range-number"></a>
|
||||
<h3>$range-min - $range-max ms</h3>
|
||||
[ <a href="#section$section-number-prev">Previous File</a> |
|
||||
<a href="#section$section-number-next">Next File</a> |
|
||||
<a href="#range$section-number:$range-number-prev">Previous Range</a> |
|
||||
<a href="#range$section-number:$range-number-next">Next Range</a> ]
|
||||
@-item-start
|
||||
<span class="graph-box">
|
||||
<span class="graph-title">
|
||||
<a name="item$section-number:$range-number-next:$item-number"></a>
|
||||
<a href="#item$section-number:$range-number-next:$item-number">$item-number</a>
|
||||
<a class="graph-filename" href="$item-name">$item-name</a><br>
|
||||
<span class="graph-summary">$item-summary</span>
|
||||
</span>
|
||||
<span class="graph-body">
|
||||
<img class="left-trough"
|
||||
src="data:image/gif;base64,R0lGODdhMAAwAPAAAAAAAP///ywAAAAAMAAw"
|
||||
width="$item-min-pct%"><img class="below-avg-trough"
|
||||
src="data:image/gif;base64,R0lGODdhMAAwAPAAAAAAAP///ywAAAAAMAAw"
|
||||
width="$item-below-pct%"><img class="above-avg-trough"
|
||||
src="data:image/gif;base64,R0lGODdhMAAwAPAAAAAAAP///ywAAAAAMAAw"
|
||||
width="$item-above-pct%">
|
||||
</span>
|
||||
</span>
|
||||
@-item-end
|
||||
</span>
|
||||
@-range-end
|
||||
<br>
|
||||
</span>
|
||||
@-section-end
|
||||
<hr>
|
||||
<a href="http://www.mozilla.org/projects/venkman/">No job is too big, no fee is too big.</a>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,30 +0,0 @@
|
||||
|
||||
Venkman Profile Report
|
||||
|
||||
Created .......... $full-date
|
||||
User Agent ....... $user-agent
|
||||
Debugger Version . $venkman-agent
|
||||
Sorted By ........ $sort-key
|
||||
|
||||
=================================================================================
|
||||
@-section-start
|
||||
$section-number <$full-url>
|
||||
|
||||
@-range-start
|
||||
$file-name: $range-min - $range-max milliseconds
|
||||
@-item-start
|
||||
Function Name: $function-name (Lines $start-line - $end-line)
|
||||
Total Calls: $call-count (max recurse $recurse-depth)
|
||||
Total Time: $total-time (min/max/avg $min-time/$max-time/$avg-time)
|
||||
|
||||
@-item-end
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
@-range-end
|
||||
=================================================================================
|
||||
|
||||
@-section-end
|
||||
|
||||
|
||||
Thanks for using Venkman, the Mozilla JavaScript Debugger.
|
||||
<http://www.mozilla.org/projects/venkman>
|
||||
@@ -1,43 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://venkman/content/profile.xml" type="text/xsl"?>
|
||||
<profile xmlns="http://www.mozilla.org/venkman/0.9/profiler"
|
||||
collected="$full-date"
|
||||
useragent="$user-agent"
|
||||
version="$venkman-agent"
|
||||
sortkey="$sort-key">
|
||||
@-section-start
|
||||
<section section="S$section-number"
|
||||
prevsection="S$section-number-prev"
|
||||
nextsection="S$section-number-next"
|
||||
href="$full-url"
|
||||
filename="$file-name">
|
||||
@-range-start
|
||||
<range range="S$section-number:$range-number"
|
||||
prevsection="S$section-number-prev"
|
||||
nextsection="S$section-number-next"
|
||||
prevrange="S$section-number:$range-number-prev"
|
||||
nextrange="S$section-number:$range-number-next"
|
||||
min="$range-min"
|
||||
max="$range-max">
|
||||
@-item-start
|
||||
<item item="S$section-number:$range-number:$item-number"
|
||||
itemnumber="$item-number"
|
||||
summary="$item-summary"
|
||||
minpercent="$item-min-pct"
|
||||
belowpercent="$item-below-pct"
|
||||
abovepercent="$item-above-pct"
|
||||
mintime="$min-time"
|
||||
maxtime="$max-time"
|
||||
totaltime="$total-time"
|
||||
callcount="$call-count"
|
||||
function="$function-name"
|
||||
filename="$file-name"
|
||||
fileurl="$full-url"
|
||||
startline="$start-line"
|
||||
endline="$end-line"/>
|
||||
@-item-end
|
||||
</range>
|
||||
@-range-end
|
||||
</section>
|
||||
@-section-end
|
||||
</profile>
|
||||
@@ -1,63 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<!DOCTYPE window SYSTEM "chrome://chatzilla/locale/chatzilla.dtd">
|
||||
<?xul-overlay href="chrome://global/content/globalOverlay.xul"?>
|
||||
|
||||
<window
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
id="main-window" orient="vertical" onclose="onClose();">
|
||||
|
||||
<script>
|
||||
<![CDATA[
|
||||
var scriptHook = {
|
||||
onScriptCreated: function scripthook (script) {
|
||||
dump ("script created\n");
|
||||
},
|
||||
onScriptDestroyed: function scripthook (script) {
|
||||
dump ("script destroyed\n");
|
||||
}
|
||||
};
|
||||
|
||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
||||
const JSD_CTRID = "@mozilla.org/js/jsd/debugger-service;1";
|
||||
const jsdIDebuggerService = Components.interfaces.jsdIDebuggerService;
|
||||
|
||||
var jsds = Components.classes[JSD_CTRID].getService(jsdIDebuggerService);
|
||||
jsds.scriptHook = scriptHook;
|
||||
jsds.on();
|
||||
|
||||
function onClose ()
|
||||
{
|
||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
||||
jsds.off();
|
||||
}
|
||||
|
||||
function onKeyPress (e)
|
||||
{
|
||||
if (e.keyCode == 13)
|
||||
doEval();
|
||||
}
|
||||
|
||||
function doEval()
|
||||
{
|
||||
var ex;
|
||||
try {
|
||||
var rv = eval(document.getElementById("input-box").value);
|
||||
document.getElementById("output-box").value = rv;
|
||||
} catch (ex) {
|
||||
document.getElementById("output-box").value =
|
||||
"Caught exception: " + String(ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
document.getElementById("input-box").value = "";
|
||||
}
|
||||
}
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<textbox id="input-box" style="width:100%" onkeypress="onKeyPress(event);"/>
|
||||
<textbox id="output-box" style="width:100%" readonly="true"/>
|
||||
|
||||
</window>
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>venkman test content page</title>
|
||||
<script>
|
||||
function doDebugger()
|
||||
{
|
||||
debugger;
|
||||
}
|
||||
|
||||
function a()
|
||||
{
|
||||
var x = 1;
|
||||
var y = "b";
|
||||
var z = x + y;
|
||||
|
||||
b(x, y, z);
|
||||
}
|
||||
|
||||
function b(x, y, z)
|
||||
{
|
||||
var recurse = 3;
|
||||
|
||||
c(3);
|
||||
}
|
||||
|
||||
function c(recurse, current)
|
||||
{
|
||||
if (typeof current == "undefined")
|
||||
c(recurse, 1);
|
||||
else if (current < recurse)
|
||||
c(recurse, ++current);
|
||||
else
|
||||
debugger;
|
||||
}
|
||||
|
||||
function scriptObject(foo)
|
||||
{
|
||||
this.foo = foo;
|
||||
this.bar = "baz";
|
||||
}
|
||||
|
||||
function makeObj()
|
||||
{
|
||||
var nativeObj = new Object();
|
||||
var jsObj = new scriptObject(12345);
|
||||
|
||||
debugger;
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>venkman test content page</h1>
|
||||
|
||||
<h2>Choose your poison...</h2>
|
||||
<button onclick="doDebugger();">debugger keyword, small stack</button><br>
|
||||
<button onclick="a();">debugger keyword, interesting stack</button><br>
|
||||
<button onclick="makeObj();">debugger keyword, two objects</button>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,205 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is The JavaScript Debugger
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation
|
||||
* Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the MPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Robert Ginda, <rginda@netscape.com>, original author
|
||||
*
|
||||
*/
|
||||
|
||||
var sampleTree = new XULTreeView();
|
||||
|
||||
function SampleRecord (name, gender)
|
||||
{
|
||||
this.setColumnPropertyName ("sample-name", "name");
|
||||
this.setColumnPropertyName ("sample-gender", "gender");
|
||||
this.name = name;
|
||||
this.gender = gender;
|
||||
}
|
||||
|
||||
SampleRecord.prototype = new XULTreeViewRecord(sampleTree.share);
|
||||
|
||||
sampleTree.childData.appendChild (new SampleRecord ("vinnie", "male"));
|
||||
var betty = new SampleRecord ("betty", "female");
|
||||
betty.reserveChildren();
|
||||
betty.open()
|
||||
betty.appendChild (new SampleRecord ("kid1", "male"));
|
||||
var kid2 = new SampleRecord ("kid2", "male");
|
||||
kid2.reserveChildren();
|
||||
var kid22 = new SampleRecord ("kid22", "female");
|
||||
kid2.appendChild (kid22);
|
||||
betty.appendChild (kid2);
|
||||
sampleTree.childData.appendChild (betty);
|
||||
sampleTree.childData.appendChild (new SampleRecord ("joey", "male"));
|
||||
|
||||
function onload ()
|
||||
{
|
||||
|
||||
var tree = document.getElementById("sample-tree");
|
||||
tree.treeBoxObject.view = sampleTree;
|
||||
dt();
|
||||
// debugger;
|
||||
}
|
||||
|
||||
function toggleBetty ()
|
||||
{
|
||||
if (betty.isHidden)
|
||||
betty.unHide();
|
||||
else
|
||||
betty.hide();
|
||||
}
|
||||
|
||||
function formatRecord (rec, indent)
|
||||
{
|
||||
var str = "";
|
||||
|
||||
for (var i in rec._colValues)
|
||||
str += rec._colValues[i] + ", ";
|
||||
|
||||
str += "[";
|
||||
|
||||
str += rec.calculateVisualRow() + ", ";
|
||||
str += rec.childIndex + ", ";
|
||||
str += rec.level + ", ";
|
||||
str += rec.visualFootprint + ", ";
|
||||
str += rec.isHidden + "]";
|
||||
|
||||
dd (indent + str);
|
||||
}
|
||||
|
||||
function formatBranch (rec, indent)
|
||||
{
|
||||
for (var i = 0; i < rec.childData.length; ++i)
|
||||
{
|
||||
formatRecord (rec.childData[i], indent);
|
||||
if ("childData" in rec.childData[i])
|
||||
formatBranch(rec.childData[i], indent + " ");
|
||||
}
|
||||
}
|
||||
|
||||
function nativeFrameTest()
|
||||
{
|
||||
function compare(a, b)
|
||||
{
|
||||
if (a > b)
|
||||
return 1;
|
||||
|
||||
if (a < b)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
var ary = [2, 1];
|
||||
ary.sort(compare);
|
||||
}
|
||||
|
||||
function dbg()
|
||||
{
|
||||
var a = 0;
|
||||
dbg2();
|
||||
nativeFrameTest();
|
||||
var c = 0;
|
||||
}
|
||||
|
||||
function dbg2()
|
||||
{
|
||||
dd("dbg2");
|
||||
var nothere;
|
||||
var nope = null;
|
||||
var f = false;
|
||||
var i = 4;
|
||||
var d = Number.MAX_VALUE;
|
||||
var s = "hello world";
|
||||
var fun = dbg;
|
||||
var obj = new Object();
|
||||
debugger;
|
||||
|
||||
try
|
||||
{
|
||||
guessThis();
|
||||
throwSomething();
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
dd ("caught " + ex);
|
||||
}
|
||||
|
||||
var rv = returnSomething();
|
||||
dd ("returned " + rv);
|
||||
}
|
||||
|
||||
function throwSomething()
|
||||
{
|
||||
var str = "this is a test";
|
||||
var obj = { message: "this is only a test" };
|
||||
throw "momma from the train";
|
||||
}
|
||||
|
||||
function returnSomething()
|
||||
{
|
||||
var str = "this is a test";
|
||||
var obj = { message: "this is only a test" };
|
||||
return "your library books on time!";
|
||||
}
|
||||
|
||||
function dt()
|
||||
{
|
||||
formatBranch(sampleTree.childData, "");
|
||||
}
|
||||
|
||||
var guessThis =
|
||||
function ()
|
||||
{
|
||||
var x = 1;
|
||||
}
|
||||
|
||||
var observer = {
|
||||
onFoo: function (){}
|
||||
}
|
||||
|
||||
function switchTest ()
|
||||
{
|
||||
var x = 1;
|
||||
|
||||
switch (x)
|
||||
{
|
||||
case 1:
|
||||
++x;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
--x;
|
||||
break;
|
||||
|
||||
default:
|
||||
x += 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<?xml-stylesheet href="chrome://venkman/skin/venkman.css" type="text/css"?>
|
||||
|
||||
<window
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
orient="vertical" onload="onload();" height="300" width="200"
|
||||
persist="top left">
|
||||
<script>
|
||||
<![CDATA[
|
||||
var DEBUG = true;
|
||||
]]>
|
||||
</script>
|
||||
<script src="chrome://venkman/content/venkman-utils.js"/>
|
||||
<script>
|
||||
<![CDATA[
|
||||
dd = function (msg) { dump("-*- tree: " + msg + "\n"); }
|
||||
var ASSERT = function (expr, msg) {
|
||||
if (!expr)
|
||||
dd ("** ASSERTION FAILED: " + msg + " **\n" + getStackTrace());
|
||||
}
|
||||
]]>
|
||||
</script>
|
||||
<script src="chrome://venkman/content/tree-utils.js"/>
|
||||
<script src="chrome://venkman/content/tests/tree.js"/>
|
||||
<tree flex="1" id="sample-tree">
|
||||
<treecols>
|
||||
<treecol id="sample-name" label="Name" primary="true" flex="1"/>
|
||||
<splitter class="sample-splitter"/>
|
||||
<treecol flex="1" id="sample-gender" label="Gender"/>
|
||||
</treecols>
|
||||
<treechildren id="sample-body"/>
|
||||
</tree>
|
||||
<button onclick="document.location.href=document.location.href" label="reload"/>
|
||||
<button onclick="toggleBetty()" label="toggle betty"/>
|
||||
<button onclick="dt()" label="dump tree"/>
|
||||
<button onclick="dbg();" label="debug"/>
|
||||
</window>
|
||||
@@ -1,88 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<!--
|
||||
-
|
||||
- The contents of this file are subject to the Mozilla Public License
|
||||
- Version 1.1 (the "License"); you may not use this file except in
|
||||
- compliance with the License. You may obtain a copy of the License at
|
||||
- http://www.mozilla.org/MPL/
|
||||
-
|
||||
- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
- for the specific language governing rights and limitations under the
|
||||
- License.
|
||||
-
|
||||
- The Original Code is The JavaScript Debugger
|
||||
-
|
||||
- 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.
|
||||
-
|
||||
- Alternatively, the contents of this file may be used under the
|
||||
- terms of the GNU Public License (the "GPL"), in which case the
|
||||
- provisions of the GPL are applicable instead of those above.
|
||||
- If you wish to allow use of your version of this file only
|
||||
- under the terms of the GPL and not to allow others to use your
|
||||
- version of this file under the MPL, indicate your decision by
|
||||
- deleting the provisions above and replace them with the notice
|
||||
- and other provisions required by the GPL. If you do not delete
|
||||
- the provisions above, a recipient may use your version of this
|
||||
- file under either the MPL or the GPL.
|
||||
-
|
||||
- Contributor(s):
|
||||
- Robert Ginda, <rginda@netscape.com>, original author
|
||||
-
|
||||
-->
|
||||
|
||||
<bindings xmlns="http://www.mozilla.org/xbl"
|
||||
xmlns:xbl="http://www.mozilla.org/xbl"
|
||||
xmlns:xul=
|
||||
"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<binding id="floatingview">
|
||||
<content>
|
||||
<xul:vbox id="view-frame-p" flex="1"
|
||||
ondragover="console.dnd.dragOver(event, console.viewProxy);"
|
||||
ondragexit="console.dnd.dragExit(event, console.viewProxy);"
|
||||
ondragdrop="console.dnd.drop(event, console.viewProxy);">
|
||||
<xul:vbox class="view-outer"
|
||||
ondraggesture="console.dnd.startDrag(event, console.viewProxyTitle);">
|
||||
<xul:hbox id="view-title">
|
||||
<xul:image class="view-title-pop"
|
||||
xbl:inherits="parentid=id"
|
||||
onclick="console.dispatch('toggle-float', { viewId: this.getAttribute('parentid')});"/>
|
||||
<xul:hbox class="view-title-grippy" flex="1">
|
||||
<xul:hbox flex="1" class="view-title-margin-left"/>
|
||||
<xul:label id="view-title-text" xbl:inherits="value=title"/>
|
||||
<xul:hbox flex="1" class="view-title-margin-right"/>
|
||||
</xul:hbox>
|
||||
<xul:image class="view-title-close"
|
||||
xbl:inherits="parentid=id"
|
||||
onclick="console.dispatch('toggle-view', { viewId: this.getAttribute('parentid')});"/>
|
||||
</xul:hbox>
|
||||
</xul:vbox>
|
||||
<children/>
|
||||
</xul:vbox>
|
||||
</content>
|
||||
|
||||
<implementation>
|
||||
<property name="ownerWindow" onget="return window;"/>
|
||||
<property name="proxyIcon" onget="return document.getAnonymousNodes(this)[0].firstChild.firstChild.firstChild;"/>
|
||||
</implementation>
|
||||
</binding>
|
||||
|
||||
<binding id="viewcontainer">
|
||||
<content>
|
||||
<xul:box xbl:inherits="type" class="view-container" flex="1">
|
||||
<children/>
|
||||
</xul:box>
|
||||
</content>
|
||||
|
||||
<implementation>
|
||||
<property name="ownerWindow" onget="return window;"/>
|
||||
</implementation>
|
||||
</binding>
|
||||
|
||||
</bindings>
|
||||
@@ -1,253 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is The JavaScript Debugger
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation
|
||||
* Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the MPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Robert Ginda, <rginda@netscape.com>, original author
|
||||
*
|
||||
*/
|
||||
|
||||
function initDev()
|
||||
{
|
||||
var cmdary =
|
||||
[["dumpcontexts", cmdDumpContexts, CMD_CONSOLE | CMD_NO_HELP],
|
||||
["dumpfilters", cmdDumpFilters, CMD_CONSOLE | CMD_NO_HELP],
|
||||
["dumpprofile", cmdDumpProfile, CMD_CONSOLE | CMD_NO_HELP],
|
||||
["dumptree", cmdDumpTree, CMD_CONSOLE | CMD_NO_HELP],
|
||||
["dumpscripts", cmdDumpScripts, CMD_CONSOLE | CMD_NO_HELP],
|
||||
["reloadui", cmdReloadUI, CMD_CONSOLE | CMD_NO_HELP],
|
||||
["sync-debug", cmdSyncDebug, CMD_CONSOLE | CMD_NO_HELP],
|
||||
["testargs", cmdTestArgs, CMD_CONSOLE | CMD_NO_HELP],
|
||||
["testargs1", cmdTestArgs, CMD_CONSOLE | CMD_NO_HELP],
|
||||
["testfilters", cmdTestFilters, CMD_CONSOLE | CMD_NO_HELP],
|
||||
["treetest", cmdTreeTest, CMD_CONSOLE | CMD_NO_HELP],
|
||||
|
||||
["multialias", "help pref; help props", CMD_CONSOLE | CMD_NO_HELP]];
|
||||
|
||||
|
||||
console.commandManager.defineCommands (cmdary);
|
||||
|
||||
if (!("devState" in console.pluginState))
|
||||
{
|
||||
console.addPref ("dbgContexts", false);
|
||||
console.addPref ("dbgDispatch", false);
|
||||
console.addPref ("dbgRealize", false);
|
||||
}
|
||||
|
||||
console.pluginState.devState = true;
|
||||
|
||||
dispatch ("sync-debug");
|
||||
|
||||
return "Venkman development functions loaded OK.";
|
||||
}
|
||||
|
||||
function cmdDumpContexts()
|
||||
{
|
||||
console.contexts = new Array();
|
||||
var i = 0;
|
||||
|
||||
var enumer = {
|
||||
enumerateContext: function _ec (context) {
|
||||
if (!context.isValid)
|
||||
{
|
||||
dd("enumerate got invalid context");
|
||||
}
|
||||
else
|
||||
{
|
||||
var v = context.globalObject.getWrappedValue();
|
||||
var title = "<n/a>";
|
||||
if (v instanceof Object &&
|
||||
"document" in v)
|
||||
{
|
||||
title = v.document.title;
|
||||
}
|
||||
|
||||
dd ("enumerateContext: Index " + i +
|
||||
", Version " + context.version +
|
||||
", Options " + context.options +
|
||||
", Private " + context.privateData +
|
||||
", Tag " + context.tag +
|
||||
", Title " + title +
|
||||
", Scripts Enabled " +
|
||||
context.scriptsEnabled);
|
||||
}
|
||||
console.contexts[i++] = context;
|
||||
}
|
||||
};
|
||||
|
||||
console.jsds.enumerateContexts(enumer);
|
||||
return true;
|
||||
}
|
||||
|
||||
function cmdDumpFilters()
|
||||
{
|
||||
console.filters = new Array();
|
||||
var i = 0;
|
||||
|
||||
var enumer = {
|
||||
enumerateFilter: function enum_f (filter) {
|
||||
dd (i + ": " + filter.globalObject +
|
||||
" '" + filter.urlPattern + "' " + filter.flags);
|
||||
console.filters[i++] = filter;
|
||||
}
|
||||
};
|
||||
|
||||
console.jsds.enumerateFilters (enumer);
|
||||
}
|
||||
|
||||
function cmdDumpProfile(e)
|
||||
{
|
||||
var list = console.getProfileSummary();
|
||||
for (var i = 0; i < list.length; ++i)
|
||||
dd(list[i].str);
|
||||
}
|
||||
|
||||
function cmdDumpTree(e)
|
||||
{
|
||||
if (!e.depth)
|
||||
e.depth = 0;
|
||||
dd(e.tree + ":\n" + tov_formatBranch (eval(e.tree), "", e.depth));
|
||||
}
|
||||
|
||||
function cmdDumpScripts(e)
|
||||
{
|
||||
var nl;
|
||||
|
||||
if ("frames" in console)
|
||||
{
|
||||
frame = getCurrentFrame();
|
||||
var targetWindow = frame.executionContext.globalObject.getWrappedValue();
|
||||
nl = targetWindow.document.getElementsByTagName("script");
|
||||
}
|
||||
else
|
||||
{
|
||||
nl = document.getElementsByTagName("script");
|
||||
}
|
||||
|
||||
for (var i = 0; i < nl.length; ++i)
|
||||
dd("src: " + nl.item(i).getAttribute ("src"));
|
||||
}
|
||||
|
||||
function cmdReloadUI()
|
||||
{
|
||||
if ("frames" in console)
|
||||
{
|
||||
display (MSG_NOTE_NOSTACK, MT_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
var bs = Components.classes["@mozilla.org/intl/stringbundle;1"];
|
||||
bs = bs.createInstance(Components.interfaces.nsIStringBundleService);
|
||||
bs.flushBundles();
|
||||
window.location.href = window.location.href;
|
||||
}
|
||||
|
||||
function cmdSyncDebug()
|
||||
{
|
||||
if (eval(console.prefs["dbgContexts"]))
|
||||
console.dbgContexts = true;
|
||||
else
|
||||
delete console.dbgContexts;
|
||||
|
||||
if (eval(console.prefs["dbgDispatch"]))
|
||||
console.dbgDispatch = true;
|
||||
else
|
||||
delete console.dbgDispatch;
|
||||
|
||||
if (eval(console.prefs["dbgRealize"]))
|
||||
console.dbgRealize = true;
|
||||
else
|
||||
delete console.dbgRealize;
|
||||
}
|
||||
|
||||
function cmdTestArgs (e)
|
||||
{
|
||||
display (dumpObjectTree(e));
|
||||
}
|
||||
|
||||
function cmdTestFilters ()
|
||||
{
|
||||
var filter1 = {
|
||||
globalObject: null,
|
||||
flags: jsdIFilter.FLAG_ENABLED,
|
||||
urlPattern: "1",
|
||||
startLine: 0,
|
||||
endLine: 0
|
||||
};
|
||||
var filter2 = {
|
||||
globalObject: null,
|
||||
flags: jsdIFilter.FLAG_ENABLED,
|
||||
urlPattern: "*2",
|
||||
startLine: 0,
|
||||
endLine: 0
|
||||
};
|
||||
var filter3 = {
|
||||
globalObject: null,
|
||||
flags: jsdIFilter.FLAG_ENABLED,
|
||||
urlPattern: "3*",
|
||||
startLine: 0,
|
||||
endLine: 0
|
||||
};
|
||||
var filter4 = {
|
||||
globalObject: null,
|
||||
flags: jsdIFilter.FLAG_ENABLED,
|
||||
urlPattern: "*4*",
|
||||
startLine: 0,
|
||||
endLine: 0
|
||||
};
|
||||
|
||||
dd ("append f3 into an empty list.");
|
||||
console.jsds.appendFilter (filter3);
|
||||
console.jsds.GC();
|
||||
dd("insert f1 at the top");
|
||||
console.jsds.insertFilter (filter1, null);
|
||||
console.jsds.GC();
|
||||
dd("insert f2 after f1");
|
||||
console.jsds.insertFilter (filter2, filter1);
|
||||
console.jsds.GC();
|
||||
dd("swap f4 in, f3 out");
|
||||
console.jsds.swapFilters (filter3, filter4);
|
||||
console.jsds.GC();
|
||||
dd("append f3");
|
||||
console.jsds.appendFilter (filter3);
|
||||
console.jsds.GC();
|
||||
dd("swap f4 and f3");
|
||||
console.jsds.swapFilters (filter3, filter4);
|
||||
console.jsds.GC();
|
||||
|
||||
dumpFilters();
|
||||
}
|
||||
|
||||
|
||||
function cmdTreeTest()
|
||||
{
|
||||
var w = openDialog("chrome://venkman/content/tests/tree.xul", "", "");
|
||||
}
|
||||
|
||||
initDev();
|
||||
@@ -1,58 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is The JavaScript Debugger
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation
|
||||
* Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the MPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Robert Ginda, <rginda@netscape.com>, original author
|
||||
*
|
||||
*/
|
||||
|
||||
console.doEval =
|
||||
function con_eval(__s)
|
||||
{
|
||||
var __ex;
|
||||
|
||||
try
|
||||
{
|
||||
return eval(__s);
|
||||
}
|
||||
catch (__ex)
|
||||
{
|
||||
dd ("doEval caught: " + __ex);
|
||||
|
||||
if (__ex && typeof ex == "object" && "fileName" in __ex &&
|
||||
__ex.fileName.search (/venkman-eval.js$/) != -1)
|
||||
{
|
||||
__ex.fileName = MSG_VAL_CONSOLE;
|
||||
__ex.lineNumber = 1;
|
||||
}
|
||||
throw __ex;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is The JavaScript Debugger
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation
|
||||
* Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the MPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Robert Ginda, <rginda@netscape.com>, original author
|
||||
*
|
||||
*/
|
||||
|
||||
var dd = opener.dd;
|
||||
var console = opener.console;
|
||||
var dispatch = console.dispatch;
|
||||
var windowId;
|
||||
|
||||
function onLoad()
|
||||
{
|
||||
var ary = document.location.search.match(/(?:\?|&)id=([^&]+)/);
|
||||
if (!ary)
|
||||
{
|
||||
dd ("No window id in url " + document.location);
|
||||
return;
|
||||
}
|
||||
|
||||
windowId = ary[1];
|
||||
|
||||
if ("arguments" in window && 0 in window.arguments &&
|
||||
typeof window.arguments[0] == "function")
|
||||
{
|
||||
window.arguments[0](window);
|
||||
}
|
||||
|
||||
if (console.prefs["menubarInFloaters"])
|
||||
console.createMainMenu (window.document);
|
||||
}
|
||||
|
||||
function onClose()
|
||||
{
|
||||
window.isClosing = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
function onUnload()
|
||||
{
|
||||
console.viewManager.destroyWindow (windowId);
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<!--
|
||||
-
|
||||
- The contents of this file are subject to the Mozilla Public License
|
||||
- Version 1.1 (the "License"); you may not use this file except in
|
||||
- compliance with the License. You may obtain a copy of the License at
|
||||
- http://www.mozilla.org/MPL/
|
||||
-
|
||||
- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
- for the specific language governing rights and limitations under the
|
||||
- License.
|
||||
-
|
||||
- The Original Code is The JavaScript Debugger
|
||||
-
|
||||
- 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.
|
||||
-
|
||||
- Alternatively, the contents of this file may be used under the
|
||||
- terms of the GNU Public License (the "GPL"), in which case the
|
||||
- provisions of the GPL are applicable instead of those above.
|
||||
- If you wish to allow use of your version of this file only
|
||||
- under the terms of the GPL and not to allow others to use your
|
||||
- version of this file under the MPL, indicate your decision by
|
||||
- deleting the provisions above and replace them with the notice
|
||||
- and other provisions required by the GPL. If you do not delete
|
||||
- the provisions above, a recipient may use your version of this
|
||||
- file under either the MPL or the GPL.
|
||||
-
|
||||
- Contributor(s):
|
||||
- Robert Ginda, <rginda@netscape.com>, original author
|
||||
-
|
||||
-->
|
||||
|
||||
<!DOCTYPE window SYSTEM "chrome://venkman/locale/venkman.dtd" >
|
||||
|
||||
<?xml-stylesheet href="chrome://venkman/skin/venkman.css" type="text/css"?>
|
||||
|
||||
<?xul-overlay href="chrome://global/content/globalOverlay.xul"?>
|
||||
<?xul-overlay href="chrome://communicator/content/utilityOverlay.xul"?>
|
||||
|
||||
<?xul-overlay href="chrome://venkman/content/venkman-views.xul"?>
|
||||
<?xul-overlay href="chrome://venkman/content/venkman-menus.xul"?>
|
||||
|
||||
<window id="venkman-window"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="onLoad();" onclose="return onClose();"
|
||||
onunload="return onUnload();"
|
||||
width="320" height="200"
|
||||
persist="width height screenX screenY" title="&MainWindow.title;"
|
||||
windowtype="mozapp:venkman:floater">
|
||||
|
||||
<script>
|
||||
var DEBUG = true;
|
||||
</script>
|
||||
<script src="chrome://venkman/content/venkman-utils.js"/>
|
||||
<script src="chrome://venkman/content/venkman-floater.js"/>
|
||||
|
||||
<popupset id="dynamic-popups"/>
|
||||
|
||||
<overlaytarget id="menu-overlay-target"/>
|
||||
<overlaytarget id="views-overlay-target"/>
|
||||
|
||||
<viewcontainer id="root-container" flex="1" type="horizontal">
|
||||
<viewcontainer id="initial-container" type="vertical" flex="1"/>
|
||||
</viewcontainer>
|
||||
|
||||
<overlaytarget id="statusbar-overlay-target"/>
|
||||
|
||||
</window>
|
||||
|
||||
@@ -1,219 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is The JavaScript Debugger
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation
|
||||
* Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the MPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Robert Ginda, <rginda@netscape.com>, original author
|
||||
*
|
||||
*/
|
||||
|
||||
function initHandlers()
|
||||
{
|
||||
function wwObserve (subject, topic, data)
|
||||
{
|
||||
//dd ("wwObserver::Observe " + subject + ", " + topic);
|
||||
if (topic == "domwindowopened")
|
||||
console.onWindowOpen (subject);
|
||||
else
|
||||
console.onWindowClose (subject);
|
||||
};
|
||||
|
||||
console.wwObserver = {observe: wwObserve};
|
||||
console.windowWatcher.registerNotification (console.wwObserver);
|
||||
console.hookedWindows = new Array();
|
||||
|
||||
var enumerator = console.windowWatcher.getWindowEnumerator();
|
||||
while (enumerator.hasMoreElements())
|
||||
{
|
||||
var win = enumerator.getNext();
|
||||
if (!isWindowFiltered(win))
|
||||
{
|
||||
console.onWindowOpen(win);
|
||||
console.onWindowLoad();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function destroyHandlers()
|
||||
{
|
||||
console.windowWatcher.unregisterNotification (console.wwObserver);
|
||||
while (console.hookedWindows.length)
|
||||
{
|
||||
var win = console.hookedWindows.pop();
|
||||
win.removeEventListener ("load", console.onWindowLoad, false);
|
||||
win.removeEventListener ("unload", console.onWindowUnload, false);
|
||||
}
|
||||
}
|
||||
|
||||
function isWindowFiltered (window)
|
||||
{
|
||||
var href = window.location.href;
|
||||
var rv = ((href.search (/^chrome:\/\/venkman\//) != -1 &&
|
||||
href.search (/test/) == -1) ||
|
||||
(console.prefs["enableChromeFilter"] &&
|
||||
href.search (/navigator.xul($|\?)/) == -1));
|
||||
//dd ("isWindowFiltered " + window.location.href + ", returning " + rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
console.onWindowOpen =
|
||||
function con_winopen (win)
|
||||
{
|
||||
if ("ChromeWindow" in win && win instanceof win.ChromeWindow &&
|
||||
(win.location.href == "about:blank" || win.location.href == ""))
|
||||
{
|
||||
setTimeout (con_winopen, 0, win);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isWindowFiltered(win))
|
||||
return;
|
||||
|
||||
//dd ("window opened: " + win + " ``" + win.location + "''");
|
||||
console.hookedWindows.push(win);
|
||||
dispatch ("hook-window-opened", {window: win});
|
||||
win.addEventListener ("load", console.onWindowLoad, false);
|
||||
win.addEventListener ("unload", console.onWindowUnload, false);
|
||||
//console.scriptsView.freeze();
|
||||
}
|
||||
|
||||
console.onWindowLoad =
|
||||
function con_winload (e)
|
||||
{
|
||||
dispatch ("hook-window-loaded", {event: e});
|
||||
}
|
||||
|
||||
console.onWindowUnload =
|
||||
function con_winunload (e)
|
||||
{
|
||||
dispatch ("hook-window-unloaded", {event: e});
|
||||
// dd (dumpObjectTree(e));
|
||||
}
|
||||
|
||||
console.onWindowClose =
|
||||
function con_winclose (win)
|
||||
{
|
||||
if (isWindowFiltered(win))
|
||||
return;
|
||||
|
||||
//dd ("window closed: " + win + " ``" + win.location + "''");
|
||||
var i = arrayIndexOf(console.hookedWindows, win);
|
||||
ASSERT (i != console.hookedWindows.length,
|
||||
"WARNING: Can't find hook window for closed window " + i + ".");
|
||||
arrayRemoveAt(console.hookedWindows, i);
|
||||
dispatch ("hook-window-closed", {window: win});
|
||||
//console.scriptsView.freeze();
|
||||
}
|
||||
|
||||
console.onLoad =
|
||||
function con_load (e)
|
||||
{
|
||||
var ex;
|
||||
|
||||
dd ("Application venkman, 'JavaScript Debugger' loaded.");
|
||||
|
||||
try
|
||||
{
|
||||
init();
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
if ("bundleList" in console)
|
||||
window.alert (getMsg (MSN_ERR_STARTUP, formatException(ex)));
|
||||
else
|
||||
window.alert (formatException(ex));
|
||||
console.startupException = ex;
|
||||
}
|
||||
}
|
||||
|
||||
console.onClose =
|
||||
function con_onclose (e)
|
||||
{
|
||||
dd ("onclose");
|
||||
|
||||
if (typeof console != "object" || "startupException" in console)
|
||||
return true;
|
||||
|
||||
dd ("onclose: dispatching");
|
||||
|
||||
return dispatch ("hook-venkman-query-exit");
|
||||
}
|
||||
|
||||
console.onUnload =
|
||||
function con_unload (e)
|
||||
{
|
||||
dd ("Application venkman, 'JavaScript Debugger' unloading.");
|
||||
|
||||
if (typeof console != "object")
|
||||
return;
|
||||
|
||||
dispatch ("hook-venkman-exit");
|
||||
destroy();
|
||||
}
|
||||
|
||||
console.onMouseOver =
|
||||
function con_mouseover (e)
|
||||
{
|
||||
var element = e.originalTarget;
|
||||
if (!("_lastElement" in console))
|
||||
console._lastElement = null;
|
||||
|
||||
while (element)
|
||||
{
|
||||
if (element == console._lastElement)
|
||||
return;
|
||||
|
||||
if ("getAttribute" in element)
|
||||
{
|
||||
var status = element.getAttribute ("venkmanstatustext");
|
||||
if (status)
|
||||
{
|
||||
console.status =
|
||||
console._lastElement = element;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if ("localName" in element && element.localName == "floatingview")
|
||||
{
|
||||
console.status = console.viewManager.computeLocation (element);
|
||||
console._lastElement = element;
|
||||
return;
|
||||
}
|
||||
|
||||
element = element.parentNode;
|
||||
}
|
||||
}
|
||||
|
||||
window.onresize =
|
||||
function ()
|
||||
{
|
||||
dispatch ("hook-window-resized", { window: window });
|
||||
// console.scrollDown();
|
||||
}
|
||||
|
||||
@@ -1,275 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is The JavaScript Debugger
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation
|
||||
* Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the MPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Robert Ginda, <rginda@netscape.com>, original author
|
||||
*
|
||||
*/
|
||||
|
||||
function initMenus()
|
||||
{
|
||||
function onMenuCommand (event, window)
|
||||
{
|
||||
var params;
|
||||
var commandName = event.originalTarget.getAttribute("commandname");
|
||||
if ("cx" in console.menuManager && console.menuManager.cx)
|
||||
{
|
||||
console.menuManager.cx.sourceWindow = window;
|
||||
params = console.menuManager.cx;
|
||||
}
|
||||
else
|
||||
{
|
||||
params = { sourceWindow: window };
|
||||
}
|
||||
|
||||
dispatch (commandName, params);
|
||||
|
||||
delete console.menuManager.cx;
|
||||
};
|
||||
|
||||
console.onMenuCommand = onMenuCommand;
|
||||
console.menuSpecs = new Object();
|
||||
var menuManager =
|
||||
console.menuManager = new MenuManager(console.commandManager,
|
||||
console.menuSpecs,
|
||||
getCommandContext,
|
||||
"console.onMenuCommand(event, " +
|
||||
"window);");
|
||||
|
||||
console.menuSpecs["maintoolbar"] = {
|
||||
items:
|
||||
[
|
||||
["stop"],
|
||||
["-"],
|
||||
["cont"],
|
||||
["next"],
|
||||
["step"],
|
||||
["finish"],
|
||||
["-"],
|
||||
["profile-tb"],
|
||||
["toggle-pprint"]
|
||||
]
|
||||
};
|
||||
|
||||
console.menuSpecs["mainmenu:file"] = {
|
||||
label: MSG_MNU_FILE,
|
||||
items:
|
||||
[
|
||||
["open-url"],
|
||||
["find-file"],
|
||||
["-"],
|
||||
["close"],
|
||||
["save-source-tab", { enabledif: "console.views.source2.canSave()" }],
|
||||
["save-profile"],
|
||||
["-"],
|
||||
["quit"]
|
||||
]
|
||||
};
|
||||
|
||||
console.menuSpecs["mainmenu:view"] = {
|
||||
label: MSG_MNU_VIEW,
|
||||
items:
|
||||
[
|
||||
[">popup:showhide"],
|
||||
["-"],
|
||||
["reload-source-tab"],
|
||||
["toggle-source-coloring",
|
||||
{type: "checkbox",
|
||||
checkedif: "console.prefs['services.source.sourceColoring'] " +
|
||||
"== 'true'"} ],
|
||||
["toggle-pprint",
|
||||
{type: "checkbox",
|
||||
checkedif: "console.prefs['prettyprint']"}],
|
||||
["-"],
|
||||
[">session:colors"],
|
||||
["-"],
|
||||
["save-default-layout"],
|
||||
["toggle-save-layout",
|
||||
{type: "checkbox",
|
||||
checkedif: "console.prefs['saveLayoutOnExit']"}]
|
||||
]
|
||||
};
|
||||
|
||||
console.menuSpecs["mainmenu:debug"] = {
|
||||
label: MSG_MNU_DEBUG,
|
||||
items:
|
||||
[
|
||||
["stop",
|
||||
{type: "checkbox",
|
||||
checkedif: "console.jsds.interruptHook"}],
|
||||
["cont"],
|
||||
["next"],
|
||||
["step"],
|
||||
["finish"],
|
||||
["-"],
|
||||
[">popup:emode"],
|
||||
[">popup:tmode"],
|
||||
["-"],
|
||||
["toggle-chrome",
|
||||
{type: "checkbox",
|
||||
checkedif: "console.prefs['enableChromeFilter']"}]
|
||||
/*
|
||||
["toggle-ias",
|
||||
{type: "checkbox",
|
||||
checkedif: "console.jsds.initAtStartup"}]
|
||||
*/
|
||||
]
|
||||
};
|
||||
|
||||
console.menuSpecs["mainmenu:help"] = {
|
||||
label: MSG_MNU_HELP,
|
||||
items:
|
||||
[
|
||||
["mozilla-help"],
|
||||
["help"],
|
||||
["-"],
|
||||
["version"],
|
||||
["about-mozilla"]
|
||||
]
|
||||
};
|
||||
|
||||
console.menuSpecs["mainmenu:profile"] = {
|
||||
label: MSG_MNU_PROFILE,
|
||||
items:
|
||||
[
|
||||
["toggle-profile",
|
||||
{type: "checkbox",
|
||||
checkedif: "console.jsds.flags & COLLECT_PROFILE_DATA"}],
|
||||
["clear-profile"],
|
||||
["save-profile"]
|
||||
]
|
||||
};
|
||||
|
||||
console.menuSpecs["popup:emode"] = {
|
||||
label: MSG_MNU_EMODE,
|
||||
items:
|
||||
[
|
||||
["em-ignore",
|
||||
{type: "radio", name: "em",
|
||||
checkedif: "console.errorMode == EMODE_IGNORE"}],
|
||||
["em-trace",
|
||||
{type: "radio", name: "em",
|
||||
checkedif: "console.errorMode == EMODE_TRACE"}],
|
||||
["em-break",
|
||||
{type: "radio", name: "em",
|
||||
checkedif: "console.errorMode == EMODE_BREAK"}]
|
||||
]
|
||||
};
|
||||
|
||||
console.menuSpecs["popup:tmode"] = {
|
||||
label: MSG_MNU_TMODE,
|
||||
items:
|
||||
[
|
||||
["tm-ignore",
|
||||
{type: "radio", name: "tm",
|
||||
checkedif: "console.throwMode == TMODE_IGNORE"}],
|
||||
["tm-trace",
|
||||
{type: "radio", name: "tm",
|
||||
checkedif: "console.throwMode == TMODE_TRACE"}],
|
||||
["tm-break",
|
||||
{type: "radio", name: "tm",
|
||||
checkedif: "console.throwMode == TMODE_BREAK"}]
|
||||
]
|
||||
};
|
||||
|
||||
console.menuSpecs["popup:showhide"] = {
|
||||
label: MSG_MNU_SHOWHIDE,
|
||||
items: [ /* filled by initViews() */ ]
|
||||
};
|
||||
}
|
||||
|
||||
console.createMainMenu = createMainMenu;
|
||||
function createMainMenu(document)
|
||||
{
|
||||
var mainmenu = document.getElementById("mainmenu");
|
||||
var menuManager = console.menuManager;
|
||||
for (var id in console.menuSpecs)
|
||||
{
|
||||
if (id.indexOf("mainmenu:") == 0)
|
||||
menuManager.createMenu (mainmenu, null, id);
|
||||
}
|
||||
|
||||
mainmenu.removeAttribute ("collapsed");
|
||||
var toolbox = document.getElementById("main-toolbox");
|
||||
toolbox.removeAttribute ("collapsed");
|
||||
}
|
||||
|
||||
console.createMainToolbar = createMainToolbar;
|
||||
function createMainToolbar(document)
|
||||
{
|
||||
var maintoolbar = document.getElementById("maintoolbar");
|
||||
var menuManager = console.menuManager;
|
||||
var spec = console.menuSpecs["maintoolbar"];
|
||||
for (var i in spec.items)
|
||||
{
|
||||
menuManager.appendToolbarItem (maintoolbar, null, spec.items[i]);
|
||||
}
|
||||
|
||||
maintoolbar = document.getElementById("maintoolbar-outer");
|
||||
maintoolbar.removeAttribute ("collapsed");
|
||||
var toolbox = document.getElementById("main-toolbox");
|
||||
toolbox.removeAttribute ("collapsed");
|
||||
}
|
||||
|
||||
function getCommandContext (id, event)
|
||||
{
|
||||
var cx = { originalEvent: event };
|
||||
|
||||
if (id in console.menuSpecs)
|
||||
{
|
||||
if ("getContext" in console.menuSpecs[id])
|
||||
cx = console.menuSpecs[id].getContext(cx);
|
||||
else if ("cx" in console.menuManager)
|
||||
{
|
||||
//dd ("using existing context");
|
||||
cx = console.menuManager.cx;
|
||||
}
|
||||
else
|
||||
{
|
||||
//dd ("no context at all");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dd ("getCommandContext: unknown menu id " + id);
|
||||
}
|
||||
|
||||
if (typeof cx == "object")
|
||||
{
|
||||
if (!("menuManager" in cx))
|
||||
cx.menuManager = console.menuManager;
|
||||
if (!("contextSource" in cx))
|
||||
cx.contextSource = id;
|
||||
if ("dbgContexts" in console && console.dbgContexts)
|
||||
dd ("context '" + id + "'\n" + dumpObjectTree(cx));
|
||||
}
|
||||
|
||||
return cx;
|
||||
}
|
||||
@@ -1,157 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<!--
|
||||
-
|
||||
- The contents of this file are subject to the Mozilla Public License
|
||||
- Version 1.1 (the "License"); you may not use this file except in
|
||||
- compliance with the License. You may obtain a copy of the License at
|
||||
- http://www.mozilla.org/MPL/
|
||||
-
|
||||
- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
- for the specific language governing rights and limitations under the
|
||||
- License.
|
||||
-
|
||||
- The Original Code is The JavaScript Debugger
|
||||
-
|
||||
- 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.
|
||||
-
|
||||
- Alternatively, the contents of this file may be used under the
|
||||
- terms of the GNU Public License (the "GPL"), in which case the
|
||||
- provisions of the GPL are applicable instead of those above.
|
||||
- If you wish to allow use of your version of this file only
|
||||
- under the terms of the GPL and not to allow others to use your
|
||||
- version of this file under the MPL, indicate your decision by
|
||||
- deleting the provisions above and replace them with the notice
|
||||
- and other provisions required by the GPL. If you do not delete
|
||||
- the provisions above, a recipient may use your version of this
|
||||
- file under either the MPL or the GPL.
|
||||
-
|
||||
- Contributor(s):
|
||||
- Robert Ginda, <rginda@netscape.com>, original author
|
||||
-
|
||||
-->
|
||||
|
||||
<!DOCTYPE window SYSTEM "chrome://venkman/locale/venkman.dtd" >
|
||||
|
||||
<?xul-overlay href="chrome://communicator/content/tasksOverlay.xul"?>
|
||||
|
||||
<overlay id="venkman-menu-overlay"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<overlaytarget id="menu-overlay-target">
|
||||
|
||||
<!-- Commands -->
|
||||
<commandset id="venkman-commands">
|
||||
|
||||
<!-- Edit commands -->
|
||||
<commandset id="selectEditMenuItems"/>
|
||||
<commandset id="globalEditMenuItems"/>
|
||||
<commandset id="undoEditMenuItems"/>
|
||||
<commandset id="clipboardEditMenuItems"/>
|
||||
<command id="cmd_undo"/>
|
||||
<command id="cmd_redo"/>
|
||||
<command id="cmd_cut"/>
|
||||
<command id="cmd_copy"/>
|
||||
<command id="cmd_paste"/>
|
||||
<command id="cmd_delete"/>
|
||||
<command id="cmd_selectAll"/>
|
||||
|
||||
<!-- Tasks commands, from overlay -->
|
||||
<commandset id="tasksCommands"/>
|
||||
</commandset>
|
||||
|
||||
<!-- Keys -->
|
||||
|
||||
<keyset id="venkmanKeys">
|
||||
<key id="key:reloadui" modifiers="accel alt" key="R"
|
||||
oncommand="if (typeof cmdReloadUI =='function') cmdReloadUI(); else window.location.href = window.location.href;"/>
|
||||
|
||||
<!-- Edit keys -->
|
||||
<key id="key_undo"/>
|
||||
<key id="key_redo"/>
|
||||
<key id="key_cut"/>
|
||||
<key id="key_copy"/>
|
||||
<key id="key_paste"/>
|
||||
<key id="key_delete"/>
|
||||
<key id="key_selectAll"/>
|
||||
|
||||
<!-- Tasks keys, from overlay -->
|
||||
<keyset id="tasksKeys"/>
|
||||
</keyset>
|
||||
|
||||
<!-- Main menu bar -->
|
||||
<toolbox flex="1" id="main-toolbox" collapsed="true">
|
||||
<menubar id="mainmenu" persist="collapsed" collapsed="true"
|
||||
grippytooltiptext="&MenuBar.tooltip;">
|
||||
|
||||
<!-- File menu placeholder, see venkman-menus.js -->
|
||||
<menu id="mainmenu:file"/>
|
||||
|
||||
<!-- Edit menu -->
|
||||
<menu id="menu_Edit">
|
||||
<menupopup id="menu_Edit_Popup">
|
||||
<menuitem id="menu_undo"/>
|
||||
<menuitem id="menu_redo"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="menu_cut"/>
|
||||
<menuitem id="menu_copy"/>
|
||||
<menuitem id="menu_paste"/>
|
||||
<menuitem id="menu_delete"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="menu_selectAll"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="menu_preferences"
|
||||
oncommand="goPreferences('navigator', 'chrome://communicator/content/pref/pref-navigator.xul', 'navigator');"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
|
||||
<!-- View menu placeholder, see venkman-menus.js -->
|
||||
<menu id="mainmenu:view"/>
|
||||
|
||||
<!-- Debug menu placeholder, see venkman-menus.js -->
|
||||
<menu id="mainmenu:debug"/>
|
||||
|
||||
<!-- Profile menu placeholder, see venkman-menus.js -->
|
||||
<menu id="mainmenu:profile"/>
|
||||
|
||||
<!-- Tasks menu -->
|
||||
<menu id="tasksMenu"/>
|
||||
|
||||
<!-- Tasks menu -->
|
||||
<menu id="windowMenu"/>
|
||||
|
||||
<!-- Help menu -->
|
||||
<menu id="mainmenu:help"/>
|
||||
</menubar>
|
||||
|
||||
<!-- Debug toolbar -->
|
||||
<toolbar class="toolbar-primary chromeclass-toolbar" id="maintoolbar-outer"
|
||||
grippytooltiptext="&DebugBar.tooltip;" collapsed="true">
|
||||
<hbox id="maintoolbar">
|
||||
</hbox>
|
||||
<textbox id="paint-hack"
|
||||
style="border: none; background: none; height: 0px; width: 0px"/>
|
||||
</toolbar>
|
||||
|
||||
</toolbox>
|
||||
|
||||
</overlaytarget>
|
||||
|
||||
<!-- Statusbar (hey, it's /almost/ a menu) -->
|
||||
<overlaytarget id="statusbar-overlay-target">
|
||||
<statusbar class="chromeclass-status" id="status-bar" flex="1">
|
||||
<statusbarpanel id="component-bar"/>
|
||||
<statusbarpanel id="status-text" label="" flex="1"
|
||||
crop="right"/>
|
||||
<statusbarpanel class="statusbarpanel-iconic" id="offline-status"
|
||||
hidden="true" offline="true"/>
|
||||
</statusbar>
|
||||
</overlaytarget>
|
||||
|
||||
</overlay>
|
||||
|
||||
@@ -1,164 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is The JavaScript Debugger
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation
|
||||
* Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the MPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Robert Ginda, <rginda@netscape.com>, original author
|
||||
*
|
||||
*/
|
||||
|
||||
function initMsgs ()
|
||||
{
|
||||
console.bundleList = new Array();
|
||||
console.defaultBundle =
|
||||
initStringBundle("chrome://venkman/locale/venkman.properties");
|
||||
}
|
||||
|
||||
function initStringBundle (bundlePath)
|
||||
{
|
||||
const nsIPropertyElement = Components.interfaces.nsIPropertyElement;
|
||||
|
||||
var pfx;
|
||||
if (console.bundleList.length == 0)
|
||||
pfx = "";
|
||||
else
|
||||
pfx = console.bundleList.length + ":";
|
||||
|
||||
var bundle = srGetStrBundle(bundlePath);
|
||||
console.bundleList.push(bundle);
|
||||
var enumer = bundle.getSimpleEnumeration();
|
||||
|
||||
while (enumer.hasMoreElements())
|
||||
{
|
||||
var prop = enumer.getNext().QueryInterface(nsIPropertyElement);
|
||||
var ary = prop.key.match (/^(msg|msn)/);
|
||||
if (ary)
|
||||
{
|
||||
var constValue;
|
||||
var constName = prop.key.toUpperCase().replace (/\./g, "_");
|
||||
if (ary[1] == "msn")
|
||||
constValue = pfx + prop.key;
|
||||
else
|
||||
constValue = prop.value.replace (/^\"/, "").replace (/\"$/, "");
|
||||
|
||||
window[constName] = constValue;
|
||||
}
|
||||
}
|
||||
|
||||
return bundle;
|
||||
}
|
||||
|
||||
function getMsg (msgName, params, deflt)
|
||||
{
|
||||
try
|
||||
{
|
||||
var bundle;
|
||||
var ary = msgName.match (/(\d+):(.+)/);
|
||||
if (ary)
|
||||
{
|
||||
return (getMsgFrom(console.bundleList[ary[1]], ary[2], params,
|
||||
deflt));
|
||||
}
|
||||
|
||||
return (getMsgFrom(console.bundleList[0], msgName, params, deflt));
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
ASSERT (0, "Caught exception getting message: " + msgName + "/" +
|
||||
params);
|
||||
return deflt ? deflt : msgName;
|
||||
}
|
||||
}
|
||||
|
||||
function getMsgFrom (bundle, msgName, params, deflt)
|
||||
{
|
||||
try
|
||||
{
|
||||
var rv;
|
||||
|
||||
if (params && params instanceof Array)
|
||||
rv = bundle.formatStringFromName (msgName, params, params.length);
|
||||
else if (params)
|
||||
rv = bundle.formatStringFromName (msgName, [params], 1);
|
||||
else
|
||||
rv = bundle.GetStringFromName (msgName);
|
||||
|
||||
/* strip leading and trailing quote characters, see comment at the
|
||||
* top of venkman.properties.
|
||||
*/
|
||||
rv = rv.replace (/^\"/, "");
|
||||
rv = rv.replace (/\"$/, "");
|
||||
|
||||
return rv;
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
if (typeof deflt == "undefined")
|
||||
{
|
||||
ASSERT (0, "caught exception getting value for ``" + msgName +
|
||||
"''\n" + ex + "\n");
|
||||
return msgName;
|
||||
}
|
||||
return deflt;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/* message types, don't localize */
|
||||
const MT_CONT = "CONT";
|
||||
const MT_ERROR = "ERROR";
|
||||
const MT_HELLO = "HELLO";
|
||||
const MT_HELP = "HELP";
|
||||
const MT_WARN = "WARN";
|
||||
const MT_INFO = "INFO";
|
||||
const MT_SOURCE = "SOURCE";
|
||||
const MT_STEP = "STEP";
|
||||
const MT_STOP = "STOP";
|
||||
const MT_ETRACE = "ETRACE";
|
||||
const MT_USAGE = "USAGE";
|
||||
const MT_EVAL_IN = "EVAL-IN";
|
||||
const MT_EVAL_OUT = "EVAL-OUT";
|
||||
const MT_FEVAL_IN = "FEVAL-IN";
|
||||
const MT_FEVAL_OUT = "FEVAL-OUT";
|
||||
|
||||
/* these messages might be needed to report an exception at startup, before
|
||||
* initMsgs() has been called. */
|
||||
window.MSN_ERR_STARTUP = "msg.err.startup";
|
||||
window.MSN_FMT_JSEXCEPTION = "msn.fmt.jsexception";
|
||||
|
||||
/* exception number -> localized message name map, keep in sync with ERR_* from
|
||||
* venkman-static.js */
|
||||
const exceptionMsgNames = ["err.notimplemented",
|
||||
"err.required.param",
|
||||
"err.invalid.param",
|
||||
"err.subscript.load",
|
||||
"err.no.debugger",
|
||||
"err.failure",
|
||||
"err.no.stack"];
|
||||
@@ -1,163 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is The JavaScript Debugger
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation
|
||||
* Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the MPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Robert Ginda, <rginda@netscape.com>, original author
|
||||
*
|
||||
*/
|
||||
|
||||
function CMungerEntry (name, regex, className, tagName)
|
||||
{
|
||||
|
||||
this.name = name;
|
||||
this.tagName = (tagName) ? tagName : "html:span";
|
||||
|
||||
if (regex instanceof RegExp)
|
||||
this.regex = regex;
|
||||
else
|
||||
this.lambdaMatch = regex;
|
||||
|
||||
if (typeof className == "function")
|
||||
this.lambdaReplace = className;
|
||||
else
|
||||
this.className = className;
|
||||
|
||||
}
|
||||
|
||||
function CMunger ()
|
||||
{
|
||||
|
||||
this.entries = new Object();
|
||||
|
||||
}
|
||||
|
||||
CMunger.prototype.enabled = true;
|
||||
|
||||
CMunger.prototype.addRule =
|
||||
function mng_addrule (name, regex, className)
|
||||
{
|
||||
|
||||
this.entries[name] = new CMungerEntry (name, regex, className);
|
||||
|
||||
}
|
||||
|
||||
CMunger.prototype.delRule =
|
||||
function mng_delrule (name)
|
||||
{
|
||||
|
||||
delete this.entries[name];
|
||||
|
||||
}
|
||||
|
||||
CMunger.prototype.munge =
|
||||
function mng_munge (text, containerTag, data)
|
||||
{
|
||||
var entry;
|
||||
var ary;
|
||||
|
||||
if (!text) //(ASSERT(text, "no text to munge"))
|
||||
return "";
|
||||
|
||||
if (typeof text != "string")
|
||||
text = String(text);
|
||||
|
||||
if (!containerTag)
|
||||
containerTag =
|
||||
document.createElementNS (NS_XHTML, this.tagName);
|
||||
|
||||
if (this.enabled)
|
||||
{
|
||||
for (entry in this.entries)
|
||||
{
|
||||
if (typeof this.entries[entry].lambdaMatch == "function")
|
||||
{
|
||||
var rval;
|
||||
|
||||
rval = this.entries[entry].lambdaMatch(text, containerTag,
|
||||
data,
|
||||
this.entries[entry]);
|
||||
if (rval)
|
||||
ary = [(void 0), rval];
|
||||
else
|
||||
ary = null;
|
||||
}
|
||||
else
|
||||
ary = text.match(this.entries[entry].regex);
|
||||
|
||||
if ((ary != null) && (ary[1]))
|
||||
{
|
||||
var startPos = text.indexOf(ary[1]);
|
||||
|
||||
if (typeof this.entries[entry].lambdaReplace == "function")
|
||||
{
|
||||
this.munge (text.substr(0,startPos), containerTag,
|
||||
data);
|
||||
this.entries[entry].lambdaReplace (ary[1], containerTag,
|
||||
data,
|
||||
this.entries[entry]);
|
||||
this.munge (text.substr (startPos + ary[1].length,
|
||||
text.length), containerTag,
|
||||
data);
|
||||
|
||||
return containerTag;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.munge (text.substr(0,startPos), containerTag,
|
||||
data);
|
||||
|
||||
var subTag =
|
||||
document.createElementNS (NS_XHTML,
|
||||
this.entries[entry].tagName);
|
||||
|
||||
subTag.setAttribute ("class",
|
||||
this.entries[entry].className);
|
||||
var wordParts = splitLongWord (ary[1],
|
||||
client.MAX_WORD_DISPLAY);
|
||||
for (var i in wordParts)
|
||||
{
|
||||
subTag.appendChild (document.createTextNode (wordParts[i]));
|
||||
subTag.appendChild (htmlWBR());
|
||||
}
|
||||
|
||||
containerTag.appendChild (subTag);
|
||||
this.munge (text.substr (startPos + ary[1].length,
|
||||
text.length), containerTag, data);
|
||||
|
||||
return containerTag;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
containerTag.appendChild (document.createTextNode (text));
|
||||
return containerTag;
|
||||
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is The JavaScript Debugger
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation
|
||||
* Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the MPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Robert Ginda, <rginda@netscape.com>, original author
|
||||
*
|
||||
*/
|
||||
|
||||
a.venkman-link {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a.venkman-link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#output-table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.msg { /* .msg = a single message in the */
|
||||
width: 100%; /* output window */
|
||||
font: 11pt lucida, sans-serif;
|
||||
font-family: monospace;
|
||||
white-space: -moz-pre-wrap;
|
||||
}
|
||||
|
||||
.msg-data[msg-type="USAGE"] {
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.msg-data[msg-type="STEP"] {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.msg-data:before {
|
||||
margin-right: 5px;
|
||||
content: "-";
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.msg-data[msg-type="ERROR"]:before {
|
||||
content: "!!";
|
||||
}
|
||||
|
||||
.msg-data[msg-type="STOP"]:before,
|
||||
.msg-data[msg-type="CONT"]:before {
|
||||
content: "*";
|
||||
}
|
||||
|
||||
.msg-data[msg-type="ETRACE"]:before {
|
||||
content: "X";
|
||||
}
|
||||
|
||||
.msg-data[msg-type="HELP"]:before {
|
||||
content: "Help:";
|
||||
}
|
||||
|
||||
.msg-data[msg-type="USAGE"]:before {
|
||||
font-style: normal;
|
||||
content: "Usage:";
|
||||
}
|
||||
|
||||
.msg-data[msg-type="SOURCE"]:before {
|
||||
padding-right: 20px;
|
||||
content: ":";
|
||||
}
|
||||
|
||||
.msg-data[msg-type="STEP"]:before {
|
||||
padding-right: 20px;
|
||||
content: "|";
|
||||
}
|
||||
|
||||
.msg-data[msg-type="EVAL-IN"]:before {
|
||||
font-weight: normal;
|
||||
content: "<<";
|
||||
}
|
||||
|
||||
.msg-data[msg-type="EVAL-OUT"]:before {
|
||||
font-weight: normal;
|
||||
content: ">>";
|
||||
}
|
||||
|
||||
.msg-data[msg-type="FEVAL-IN"]:before {
|
||||
font-weight: normal;
|
||||
content: ">";
|
||||
}
|
||||
|
||||
.msg-data[msg-type="FEVAL-IN"]:before {
|
||||
font-weight: normal;
|
||||
content: "<";
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
|
||||
<html>
|
||||
<head>
|
||||
<script>
|
||||
var css = "chrome://venkman/skin/venkman-output-default.css";
|
||||
if (document.location.search)
|
||||
css = document.location.search.substr(1);
|
||||
|
||||
document.write ("<LINK REL=StyleSheet HREF='" + css +
|
||||
"' TYPE='text/css' MEDIA='screen'>");
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body id="venkman-session-body">
|
||||
|
||||
<table border="0" cellpadding="0" cellspacing="0" id="session-output-table">
|
||||
</table>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,40 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is The JavaScript Debugger
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation
|
||||
* Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the MPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Robert Ginda, <rginda@netscape.com>, original author
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
function start_venkman()
|
||||
{
|
||||
toOpenWindowByType("mozapp:venkman", "chrome://venkman/content/venkman.xul");
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<!--
|
||||
-
|
||||
- The contents of this file are subject to the Mozilla Public License
|
||||
- Version 1.1 (the "License"); you may not use this file except in
|
||||
- compliance with the License. You may obtain a copy of the License at
|
||||
- http://www.mozilla.org/MPL/
|
||||
-
|
||||
- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
- for the specific language governing rights and limitations under the
|
||||
- License.
|
||||
-
|
||||
- The Original Code is The JavaScript Debugger
|
||||
-
|
||||
- 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.
|
||||
-
|
||||
- Alternatively, the contents of this file may be used under the
|
||||
- terms of the GNU Public License (the "GPL"), in which case the
|
||||
- provisions of the GPL are applicable instead of those above.
|
||||
- If you wish to allow use of your version of this file only
|
||||
- under the terms of the GPL and not to allow others to use your
|
||||
- version of this file under the MPL, indicate your decision by
|
||||
- deleting the provisions above and replace them with the notice
|
||||
- and other provisions required by the GPL. If you do not delete
|
||||
- the provisions above, a recipient may use your version of this
|
||||
- file under either the MPL or the GPL.
|
||||
-
|
||||
- Contributor(s):
|
||||
- Robert Ginda, <rginda@netscape.com>, original author
|
||||
-
|
||||
-->
|
||||
|
||||
|
||||
<!--
|
||||
This file contains the nodes that will be overlayed on top of
|
||||
<chrome://communicator/content/tasksOverlay.xul>.
|
||||
Place JavaScript code that this file needs in venkman-overlay.js.
|
||||
Declare XMl entites that this file refers to in venkman-overlay.dtd.
|
||||
-->
|
||||
|
||||
<!DOCTYPE window SYSTEM "chrome://venkman/locale/venkman-overlay.dtd" >
|
||||
|
||||
<overlay id="venkmanTaskMenuID"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<script src="chrome://venkman/content/venkman-overlay.js"/>
|
||||
|
||||
<!--
|
||||
This is the id that the menuitem will be appended to. see tasksOverlay.xul
|
||||
-->
|
||||
<menupopup id="toolsPopup">
|
||||
<menuitem position="5" label="&venkmanCmd.label;"
|
||||
accesskey="&venkmanCmd.akey;" oncommand="start_venkman()"/>
|
||||
</menupopup>
|
||||
|
||||
</overlay>
|
||||
@@ -1,170 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is The JavaScript Debugger
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation
|
||||
* Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the MPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Robert Ginda, <rginda@netscape.com>, original author
|
||||
*
|
||||
*/
|
||||
|
||||
console.prefs = new Object();
|
||||
|
||||
const PREF_CTRID = "@mozilla.org/preferences-service;1";
|
||||
const nsIPrefService = Components.interfaces.nsIPrefService;
|
||||
const nsIPrefBranch = Components.interfaces.nsIPrefBranch;
|
||||
|
||||
function initPrefs()
|
||||
{
|
||||
|
||||
console.prefs = new Object();
|
||||
console.prefs.prefService =
|
||||
Components.classes[PREF_CTRID].getService(nsIPrefService);
|
||||
console.prefs.prefBranch =
|
||||
console.prefs.prefService.getBranch("extensions.venkman.");
|
||||
console.prefs.prefNames = new Array();
|
||||
console.prefs.prefNameMap = new Object();
|
||||
|
||||
// console.addPref ("input.commandchar", "/");
|
||||
console.addPref ("maxStringLength", 100);
|
||||
console.addPref ("startupCount", 0);
|
||||
console.addPref ("enableChromeFilter", true);
|
||||
console.addPref ("tabWidth", 4);
|
||||
console.addPref ("initialScripts", "");
|
||||
console.addPref ("prettyprint", false);
|
||||
console.addPref ("guessContext", 5);
|
||||
console.addPref ("guessPattern", "(\\w+)\\s*[:=]\\s*$");
|
||||
console.addPref ("permitStartupHit", true);
|
||||
console.addPref ("statusDuration", 5 * 1000);
|
||||
console.addPref ("menubarInFloaters",
|
||||
navigator.platform.indexOf ("Mac") != -1);
|
||||
var list = console.prefs.prefBranch.getChildList("", {});
|
||||
for (var p in list)
|
||||
{
|
||||
if (!(list[p] in console.prefs))
|
||||
{
|
||||
console.addPref(list[p]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.listPrefs =
|
||||
function con_listprefs (prefix)
|
||||
{
|
||||
var list = new Array();
|
||||
var names = console.prefs.prefNames;
|
||||
for (var i = 0; i < names.length; ++i)
|
||||
{
|
||||
if (!prefix || names[i].indexOf(prefix) == 0)
|
||||
list.push (names[i]);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
console.addPref =
|
||||
function con_addpref (prefName, defaultValue)
|
||||
{
|
||||
var realValue;
|
||||
|
||||
function prefGetter ()
|
||||
{
|
||||
if (typeof realValue == "undefined")
|
||||
{
|
||||
var type = this.prefBranch.getPrefType (prefName);
|
||||
try
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case nsIPrefBranch.PREF_STRING:
|
||||
realValue = this.prefBranch.getCharPref (prefName);
|
||||
break;
|
||||
|
||||
case nsIPrefBranch.PREF_INT:
|
||||
realValue = this.prefBranch.getIntPref (prefName);
|
||||
break;
|
||||
|
||||
case nsIPrefBranch.PREF_BOOL:
|
||||
realValue = this.prefBranch.getBoolPref (prefName);
|
||||
break;
|
||||
|
||||
default:
|
||||
realValue = defaultValue;
|
||||
}
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
//dd ("caught exception reading pref ``" + prefName + "'' " +
|
||||
// type + "\n" + ex);
|
||||
realValue = defaultValue;
|
||||
}
|
||||
}
|
||||
return realValue;
|
||||
}
|
||||
|
||||
function prefSetter (value)
|
||||
{
|
||||
try
|
||||
{
|
||||
switch (typeof value)
|
||||
{
|
||||
case "int":
|
||||
realValue = value;
|
||||
this.prefBranch.setIntPref (prefName, value);
|
||||
break;
|
||||
|
||||
case "boolean":
|
||||
realValue = value;
|
||||
this.prefBranch.setBoolPref (prefName, value);
|
||||
break;
|
||||
|
||||
default:
|
||||
realValue = value;
|
||||
this.prefBranch.setCharPref (prefName, value);
|
||||
break;
|
||||
}
|
||||
|
||||
this.prefService.savePrefFile(null);
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
dd ("caught exception writing pref ``" + prefName + "''\n" + ex);
|
||||
}
|
||||
|
||||
return value;
|
||||
|
||||
}
|
||||
|
||||
if (prefName in console.prefs)
|
||||
return;
|
||||
|
||||
console.prefs.prefNames.push(prefName);
|
||||
console.prefs.prefNames.sort();
|
||||
console.prefs.__defineGetter__(prefName, prefGetter);
|
||||
console.prefs.__defineSetter__(prefName, prefSetter);
|
||||
}
|
||||
@@ -1,384 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is The JavaScript Debugger
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation
|
||||
* Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the MPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Robert Ginda, <rginda@netscape.com>, original author
|
||||
*
|
||||
*/
|
||||
|
||||
function initProfiler ()
|
||||
{
|
||||
console.addPref ("profile.template.xml",
|
||||
"chrome://venkman/content/profile.xml.tpl");
|
||||
console.addPref ("profile.template.html",
|
||||
"chrome://venkman/content/profile.html.tpl");
|
||||
console.addPref ("profile.template.csv",
|
||||
"chrome://venkman/content/profile.csv.tpl");
|
||||
console.addPref ("profile.template.txt",
|
||||
"chrome://venkman/content/profile.txt.tpl");
|
||||
console.addPref ("profile.ranges.default",
|
||||
"1000000, 5000, 2500, 1000, 750, 500, 250, 100, 75, 50, " +
|
||||
"25, 10, 7.5, 5, 2.5, 1, 0.75, 0.5, 0.25");
|
||||
}
|
||||
|
||||
function ProfileReport (reportTemplate, file, rangeList, scriptInstanceList)
|
||||
{
|
||||
this.reportTemplate = reportTemplate;
|
||||
this.file = file;
|
||||
this.rangeList = rangeList;
|
||||
this.scriptInstanceList = scriptInstanceList;
|
||||
this.key = "total";
|
||||
}
|
||||
|
||||
console.profiler = new Object();
|
||||
|
||||
console.profiler.__defineSetter__ ("enabled", pro_setenable);
|
||||
function pro_setenable(state)
|
||||
{
|
||||
if (state)
|
||||
console.jsds.flags |= COLLECT_PROFILE_DATA;
|
||||
else
|
||||
console.jsds.flags &= ~COLLECT_PROFILE_DATA;
|
||||
}
|
||||
|
||||
console.profiler.__defineGetter__ ("enabled", pro_getenable);
|
||||
function pro_getenable(state)
|
||||
{
|
||||
return Boolean(console.jsds.flags & COLLECT_PROFILE_DATA);
|
||||
}
|
||||
|
||||
console.profiler.summarizeScriptWrapper =
|
||||
function pro_sumscript (scriptWrapper, key)
|
||||
{
|
||||
var ex;
|
||||
|
||||
try
|
||||
{
|
||||
var jsdScript = scriptWrapper.jsdScript;
|
||||
if (!jsdScript.isValid)
|
||||
return null;
|
||||
|
||||
var ccount = jsdScript.callCount;
|
||||
if (!ccount)
|
||||
return null;
|
||||
|
||||
var tot_ms = roundTo(jsdScript.totalExecutionTime, 2);
|
||||
var min_ms = roundTo(jsdScript.minExecutionTime, 2);
|
||||
var max_ms = roundTo(jsdScript.maxExecutionTime, 2);
|
||||
var avg_ms = roundTo(jsdScript.totalExecutionTime / ccount, 2);
|
||||
var recurse = jsdScript.maxRecurseDepth;
|
||||
|
||||
var summary = new Object();
|
||||
summary.total = tot_ms;
|
||||
summary.ccount = ccount;
|
||||
summary.avg = avg_ms;
|
||||
summary.min = min_ms;
|
||||
summary.max = max_ms;
|
||||
summary.recurse = recurse;
|
||||
summary.url = jsdScript.fileName;
|
||||
summary.file = getFileFromPath(summary.url);
|
||||
summary.base = jsdScript.baseLineNumber;
|
||||
summary.end = summary.base + jsdScript.lineExtent;
|
||||
summary.fun = scriptWrapper.functionName;
|
||||
summary.str = getMsg(MSN_FMT_PROFILE_STR,
|
||||
[summary.fun, summary.base, summary.end, ccount,
|
||||
(summary.recurse ?
|
||||
getMsg(MSN_FMT_PROFILE_RECURSE, recurse) : ""),
|
||||
tot_ms, min_ms, max_ms, avg_ms]);
|
||||
summary.key = summary[key];
|
||||
return summary;
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
/* This function is called under duress, and the script representd
|
||||
* by |s| may get collected at any point. When that happens,
|
||||
* attempting to access to the profile data will throw this
|
||||
* exception.
|
||||
*/
|
||||
if ("result" in ex &&
|
||||
ex.result == Components.results.NS_ERROR_NOT_AVAILABLE)
|
||||
{
|
||||
display (getMsg(MSN_PROFILE_LOST, formatScript(jsdScript)), MT_WARN);
|
||||
}
|
||||
else
|
||||
{
|
||||
dd ("rethrow");
|
||||
dd (dumpObjectTree(ex));
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
console.profiler.summarizeScriptInstance =
|
||||
function pro_suminst (scriptInstance, key)
|
||||
{
|
||||
var summaryList = new Array();
|
||||
var summary;
|
||||
|
||||
if (scriptInstance.topLevel)
|
||||
summary = this.summarizeScriptWrapper (scriptInstance.topLevel, key);
|
||||
if (summary)
|
||||
summaryList.push (summary);
|
||||
|
||||
for (var f in scriptInstance.functions)
|
||||
{
|
||||
summary = this.summarizeScriptWrapper(scriptInstance.functions[f], key);
|
||||
if (summary)
|
||||
summaryList.push(summary);
|
||||
}
|
||||
|
||||
return summaryList;
|
||||
}
|
||||
|
||||
console.profiler.generateReportSection =
|
||||
function pro_rptinst (profileReport, scriptInstance, sectionData)
|
||||
{
|
||||
function keyCompare (a, b)
|
||||
{
|
||||
if (a.key < b.key)
|
||||
return 1;
|
||||
if (a.key > b.key)
|
||||
return -1;
|
||||
return 0;
|
||||
};
|
||||
|
||||
function scale(K, x) { return roundTo(K * x, 2); };
|
||||
|
||||
const MAX_WIDTH = 90;
|
||||
|
||||
var summaryList = this.summarizeScriptInstance (scriptInstance,
|
||||
profileReport.key);
|
||||
if (!summaryList.length)
|
||||
return false;
|
||||
|
||||
summaryList = summaryList.sort(keyCompare);
|
||||
|
||||
var file = profileReport.file;
|
||||
var reportTemplate = profileReport.reportTemplate;
|
||||
var rangeList = profileReport.rangeList ? profileReport.rangeList : [1, 0];
|
||||
var finalRangeIndex = rangeList.length - 1;
|
||||
var previousRangeIndex;
|
||||
var rangeIter = 0;
|
||||
var rangeIndex = 0;
|
||||
var K = 1;
|
||||
var i;
|
||||
|
||||
if (typeof summaryList[0].key == "number")
|
||||
{
|
||||
for (i = 0; i < rangeList.length; ++i)
|
||||
rangeList[i] = Number(rangeList[i]);
|
||||
}
|
||||
|
||||
if ("sectionHeader" in reportTemplate)
|
||||
{
|
||||
file.write(replaceStrings(reportTemplate.sectionHeader,
|
||||
sectionData));
|
||||
}
|
||||
|
||||
for (i = 0; i < summaryList.length; ++i)
|
||||
{
|
||||
var summary = summaryList[i];
|
||||
var rangeData;
|
||||
|
||||
while (summary.key &&
|
||||
rangeIndex < finalRangeIndex &&
|
||||
summary.key < rangeList[rangeIndex])
|
||||
{
|
||||
++rangeIndex;
|
||||
}
|
||||
|
||||
if (previousRangeIndex != rangeIndex)
|
||||
{
|
||||
if (rangeIter > 0 && ("rangeFooter" in reportTemplate))
|
||||
{
|
||||
file.write(replaceStrings(reportTemplate.rangeFooter,
|
||||
rangeData));
|
||||
}
|
||||
|
||||
var maxRange = (rangeIndex > 0 ?
|
||||
rangeList[rangeIndex - 1] : summary.key);
|
||||
var minRange = (rangeIndex < finalRangeIndex ?
|
||||
rangeList[rangeIndex + 1] : summary.key);
|
||||
K = MAX_WIDTH / maxRange;
|
||||
|
||||
rangeData = {
|
||||
"\\$range-min" : minRange,
|
||||
"\\$range-max" : maxRange,
|
||||
"\\$range-number-prev": rangeIter > 0 ? rangeIter - 1 : 0,
|
||||
"\\$range-number-next": rangeIter + 1,
|
||||
"\\$range-number" : rangeIter,
|
||||
"__proto__" : sectionData
|
||||
};
|
||||
|
||||
if ("rangeHeader" in reportTemplate)
|
||||
{
|
||||
file.write(replaceStrings(reportTemplate.rangeHeader,
|
||||
rangeData));
|
||||
}
|
||||
|
||||
previousRangeIndex = rangeIndex;
|
||||
++rangeIter;
|
||||
}
|
||||
|
||||
var summaryData = {
|
||||
"\\$item-number-next": i + 1,
|
||||
"\\$item-number-prev": i - 1,
|
||||
"\\$item-number" : i,
|
||||
"\\$item-name" : summary.url,
|
||||
"\\$item-summary" : summary.str,
|
||||
"\\$item-min-pct" : scale(K, summary.min),
|
||||
"\\$item-below-pct" : scale(K, summary.avg - summary.min),
|
||||
"\\$item-above-pct" : scale(K, summary.max - summary.avg),
|
||||
"\\$max-time" : summary.max,
|
||||
"\\$min-time" : summary.min,
|
||||
"\\$avg-time" : summary.avg,
|
||||
"\\$total-time" : summary.total,
|
||||
"\\$call-count" : summary.ccount,
|
||||
"\\$recurse-depth" : summary.recurse,
|
||||
"\\$function-name" : summary.fun,
|
||||
"\\$start-line" : summary.base,
|
||||
"\\$end-line" : summary.end,
|
||||
"__proto__" : rangeData
|
||||
};
|
||||
|
||||
if ("itemBody" in reportTemplate)
|
||||
file.write(replaceStrings(reportTemplate.itemBody, summaryData));
|
||||
}
|
||||
|
||||
if ("rangeFooter" in reportTemplate)
|
||||
{
|
||||
/* close the final range */
|
||||
file.write(replaceStrings(reportTemplate.rangeFooter,
|
||||
rangeData));
|
||||
}
|
||||
|
||||
if ("sectionFooter" in reportTemplate)
|
||||
{
|
||||
file.write(replaceStrings(reportTemplate.sectionFooter,
|
||||
sectionData));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
console.profiler.generateReport =
|
||||
function pro_rptall (profileReport)
|
||||
{
|
||||
var profiler = this;
|
||||
var sectionCount = 0;
|
||||
|
||||
function generateReportChunk (i)
|
||||
{
|
||||
/* we build the report in chunks, with setTimeouts in between,
|
||||
* so the UI can come up for air. */
|
||||
var scriptInstance = profileReport.scriptInstanceList[i];
|
||||
var url = scriptInstance.url;
|
||||
|
||||
var sectionData = {
|
||||
"\\$section-number-prev": (sectionCount > 0) ? sectionCount - 1 : 0,
|
||||
"\\$section-number-next": sectionCount + 1,
|
||||
"\\$section-number" : sectionCount,
|
||||
"\\$section-link" : (url ? "<a class='section-link' href='" +
|
||||
url + "'>" + url + "</a>" : MSG_VAL_NA),
|
||||
"\\$full-url" : url,
|
||||
"\\$file-name" : getFileFromPath(url),
|
||||
"__proto__" : reportData
|
||||
};
|
||||
|
||||
var hadData = profiler.generateReportSection (profileReport,
|
||||
scriptInstance,
|
||||
sectionData);
|
||||
if (++i == profileReport.scriptInstanceList.length)
|
||||
{
|
||||
if ("reportFooter" in reportTemplate)
|
||||
file.write(replaceStrings(reportTemplate.reportFooter,
|
||||
reportData));
|
||||
if ("onComplete" in profileReport)
|
||||
profileReport.onComplete(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hadData)
|
||||
{
|
||||
++sectionCount;
|
||||
console.status = getMsg(MSN_PROFILE_SAVING, [i, last]);
|
||||
setTimeout (generateReportChunk, 10, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
generateReportChunk (i);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var reportData = {
|
||||
"\\$full-date" : String(Date()),
|
||||
"\\$user-agent" : navigator.userAgent,
|
||||
"\\$venkman-agent": console.userAgent,
|
||||
"\\$sort-key" : profileReport.key
|
||||
};
|
||||
|
||||
var reportTemplate = profileReport.reportTemplate;
|
||||
var file = profileReport.file;
|
||||
|
||||
if ("reportHeader" in reportTemplate)
|
||||
file.write(replaceStrings(reportTemplate.reportHeader, reportData));
|
||||
|
||||
var length = profileReport.scriptInstanceList.length;
|
||||
var last = length - 1;
|
||||
|
||||
generateReportChunk (0);
|
||||
}
|
||||
|
||||
console.profiler.loadTemplate =
|
||||
function pro_load (url)
|
||||
{
|
||||
var lines = loadURLNow(url);
|
||||
if (!lines)
|
||||
return null;
|
||||
|
||||
var sections = {
|
||||
"reportHeader" : /@-section-start/mi,
|
||||
"sectionHeader" : /@-range-start/mi,
|
||||
"rangeHeader" : /@-item-start/mi,
|
||||
"itemBody" : /@-item-end/mi,
|
||||
"rangeFooter" : /@-range-end/mi,
|
||||
"sectionFooter" : /@-section-end/mi,
|
||||
"reportFooter" : 0
|
||||
};
|
||||
|
||||
var reportTemplate = parseSections (lines, sections);
|
||||
|
||||
//dd(dumpObjectTree (reportTemplate));
|
||||
return reportTemplate;
|
||||
}
|
||||
|
||||
@@ -1,871 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is The JavaScript Debugger
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation
|
||||
* Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the MPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Robert Ginda, <rginda@netscape.com>, original author
|
||||
*
|
||||
*/
|
||||
|
||||
function initRecords()
|
||||
{
|
||||
var atomsvc = console.atomService;
|
||||
|
||||
WindowRecord.prototype.property = atomsvc.getAtom("item-window");
|
||||
|
||||
FileContainerRecord.prototype.property = atomsvc.getAtom("item-files");
|
||||
|
||||
FileRecord.prototype.property = atomsvc.getAtom("item-file");
|
||||
|
||||
FrameRecord.prototype.property = atomsvc.getAtom("item-frame");
|
||||
FrameRecord.prototype.atomCurrent = atomsvc.getAtom("current-frame-flag");
|
||||
|
||||
console.addPref ("valueRecord.brokenObjects", "^JavaPackage$");
|
||||
try
|
||||
{
|
||||
ValueRecord.prototype.brokenObjects =
|
||||
new RegExp (console.prefs["valueRecord.brokenObjects"]);
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
display (MSN_ERR_INVALID_PREF,
|
||||
["valueRecord.brokenObjects",
|
||||
console.prefs["valueRecord.brokenObjects"]], MT_ERROR);
|
||||
display (formatException(ex), MT_ERROR);
|
||||
ValueRecord.prototype.brokenObjects = /^JavaPackage$/;
|
||||
}
|
||||
|
||||
ValueRecord.prototype.atomVoid = atomsvc.getAtom("item-void");
|
||||
ValueRecord.prototype.atomNull = atomsvc.getAtom("item-null");
|
||||
ValueRecord.prototype.atomBool = atomsvc.getAtom("item-bool");
|
||||
ValueRecord.prototype.atomInt = atomsvc.getAtom("item-int");
|
||||
ValueRecord.prototype.atomDouble = atomsvc.getAtom("item-double");
|
||||
ValueRecord.prototype.atomString = atomsvc.getAtom("item-string");
|
||||
ValueRecord.prototype.atomFunction = atomsvc.getAtom("item-function");
|
||||
ValueRecord.prototype.atomObject = atomsvc.getAtom("item-object");
|
||||
ValueRecord.prototype.atomError = atomsvc.getAtom("item-error");
|
||||
ValueRecord.prototype.atomException = atomsvc.getAtom("item-exception");
|
||||
ValueRecord.prototype.atomHinted = atomsvc.getAtom("item-hinted");
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Breakpoint Record.
|
||||
* One prototype for all breakpoint types, works only in the Breakpoints View.
|
||||
*******************************************************************************/
|
||||
|
||||
function BPRecord (breakWrapper)
|
||||
{
|
||||
this.setColumnPropertyName ("col-0", "name");
|
||||
this.setColumnPropertyName ("col-1", "line");
|
||||
|
||||
this.breakWrapper = breakWrapper;
|
||||
|
||||
if ("pc" in breakWrapper)
|
||||
{
|
||||
this.type = "instance";
|
||||
this.name = breakWrapper.scriptWrapper.functionName;
|
||||
this.line = getMsg(MSN_FMT_PC, String(breakWrapper.pc));
|
||||
}
|
||||
else if (breakWrapper instanceof FutureBreakpoint)
|
||||
{
|
||||
this.type = "future";
|
||||
var ary = breakWrapper.url.match(/\/([^\/?]+)(\?|$)/);
|
||||
if (ary)
|
||||
this.name = ary[1];
|
||||
else
|
||||
this.name = breakWrapper.url;
|
||||
|
||||
this.line = breakWrapper.lineNumber;
|
||||
}
|
||||
}
|
||||
|
||||
BPRecord.prototype = new XULTreeViewRecord(console.views.breaks.share);
|
||||
|
||||
/*******************************************************************************
|
||||
* Stack Frame Record.
|
||||
* Represents a jsdIStackFrame, for use in the Stack View only.
|
||||
*******************************************************************************/
|
||||
|
||||
function FrameRecord (jsdFrame)
|
||||
{
|
||||
if (!(jsdFrame instanceof jsdIStackFrame))
|
||||
throw new BadMojo (ERR_INVALID_PARAM, "value");
|
||||
|
||||
this.setColumnPropertyName ("col-0", "functionName");
|
||||
this.setColumnPropertyName ("col-1", "location");
|
||||
|
||||
this.functionName = jsdFrame.functionName;
|
||||
if (!jsdFrame.isNative)
|
||||
{
|
||||
this.scriptWrapper = getScriptWrapper(jsdFrame.script);
|
||||
this.location = getMsg(MSN_FMT_FRAME_LOCATION,
|
||||
[getFileFromPath(jsdFrame.script.fileName),
|
||||
jsdFrame.line, jsdFrame.pc]);
|
||||
this.functionName = this.scriptWrapper.functionName;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.scriptWrapper = null;
|
||||
this.location = MSG_URL_NATIVE;
|
||||
}
|
||||
|
||||
this.jsdFrame = jsdFrame;
|
||||
}
|
||||
|
||||
FrameRecord.prototype = new XULTreeViewRecord (console.views.stack.share);
|
||||
|
||||
/*******************************************************************************
|
||||
* Window Record.
|
||||
* Represents a DOM window with files and child windows. For use in the
|
||||
* Windows View.
|
||||
*******************************************************************************/
|
||||
|
||||
function WindowRecord (win, baseURL)
|
||||
{
|
||||
function none() { return ""; };
|
||||
this.setColumnPropertyName ("col-0", "displayName");
|
||||
|
||||
this.window = win;
|
||||
this.url = win.location.href;
|
||||
if (this.url.search(/^\w+:/) == -1)
|
||||
{
|
||||
if (this.url[0] == "/")
|
||||
this.url = win.location.host + this.url;
|
||||
else
|
||||
this.url = baseURL + this.url;
|
||||
this.baseURL = baseURL;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.baseURL = getPathFromURL(this.url);
|
||||
}
|
||||
|
||||
|
||||
this.reserveChildren(true);
|
||||
this.shortName = getFileFromPath (this.url);
|
||||
if (console.prefs["enableChromeFilter"] && this.shortName == "navigator.xul")
|
||||
{
|
||||
this.displayName = MSG_NAVIGATOR_XUL;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.filesRecord = new FileContainerRecord(this);
|
||||
this.displayName = this.shortName;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
WindowRecord.prototype = new XULTreeViewRecord(console.views.windows.share);
|
||||
|
||||
WindowRecord.prototype.onPreOpen =
|
||||
function wr_preopen()
|
||||
{
|
||||
this.childData = new Array();
|
||||
|
||||
if ("filesRecord" in this)
|
||||
this.appendChild(this.filesRecord);
|
||||
|
||||
var framesLength = this.window.frames.length;
|
||||
for (var i = 0; i < framesLength; ++i)
|
||||
{
|
||||
this.appendChild(new WindowRecord(this.window.frames[i].window,
|
||||
this.baseURL));
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* "File Container" Record.
|
||||
* List of script tags found in the parent record's |window.document| property.
|
||||
* For use in the Windows View, as a child of a WindowRecord.
|
||||
*******************************************************************************/
|
||||
|
||||
function FileContainerRecord (windowRecord)
|
||||
{
|
||||
function files() { return MSG_FILES_REC; }
|
||||
function none() { return ""; }
|
||||
this.setColumnPropertyName ("col-0", files);
|
||||
this.windowRecord = windowRecord;
|
||||
this.reserveChildren(true);
|
||||
}
|
||||
|
||||
FileContainerRecord.prototype =
|
||||
new XULTreeViewRecord(console.views.windows.share);
|
||||
|
||||
FileContainerRecord.prototype.onPreOpen =
|
||||
function fcr_getkids ()
|
||||
{
|
||||
if (!("parentRecord" in this))
|
||||
return;
|
||||
|
||||
this.childData = new Array();
|
||||
var doc = this.windowRecord.window.document;
|
||||
var nodeList = doc.getElementsByTagName("script");
|
||||
dd (nodeList.length + "nodes");
|
||||
for (var i = 0; i < nodeList.length; ++i)
|
||||
{
|
||||
var url = nodeList.item(i).getAttribute("src");
|
||||
if (url)
|
||||
{
|
||||
if (url.search(/^\w+:/) == -1)
|
||||
url = getPathFromURL (this.windowRecord.url) + url;
|
||||
this.appendChild(new FileRecord(url));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* File Record
|
||||
* Represents a URL, for use in the Windows View only.
|
||||
*******************************************************************************/
|
||||
|
||||
function FileRecord (url)
|
||||
{
|
||||
function none() { return ""; }
|
||||
this.setColumnPropertyName ("col-0", "shortName");
|
||||
this.url = url;
|
||||
this.shortName = getFileFromPath(url);
|
||||
}
|
||||
|
||||
FileRecord.prototype = new XULTreeViewRecord(console.views.windows.share);
|
||||
|
||||
/*******************************************************************************
|
||||
* Script Instance Record.
|
||||
* Represents a ScriptInstance, for use in the Scripts View only.
|
||||
*******************************************************************************/
|
||||
|
||||
function ScriptInstanceRecord(scriptInstance)
|
||||
{
|
||||
if (!ASSERT(scriptInstance.isSealed,
|
||||
"Attempt to create ScriptInstanceRecord for unsealed instance"))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
this.setColumnPropertyName ("col-0", "displayName");
|
||||
this.setColumnPropertyValue ("col-1", "");
|
||||
this.setColumnPropertyValue ("col-2", "");
|
||||
this.reserveChildren(true);
|
||||
this.url = scriptInstance.url;
|
||||
var sv = console.views.scripts;
|
||||
this.fileType = sv.atomUnknown;
|
||||
this.shortName = this.url;
|
||||
this.group = 4;
|
||||
this.scriptInstance = scriptInstance;
|
||||
this.lastScriptCount = 0;
|
||||
this.sequence = scriptInstance.sequence;
|
||||
|
||||
this.shortName = getFileFromPath(this.url);
|
||||
var ary = this.shortName.match (/\.(js|html|xul|xml)$/i);
|
||||
if (ary)
|
||||
{
|
||||
switch (ary[1].toLowerCase())
|
||||
{
|
||||
case "js":
|
||||
this.fileType = sv.atomJS;
|
||||
this.group = 0;
|
||||
break;
|
||||
|
||||
case "html":
|
||||
this.group = 1;
|
||||
this.fileType = sv.atomHTML;
|
||||
break;
|
||||
|
||||
case "xul":
|
||||
this.group = 2;
|
||||
this.fileType = sv.atomXUL;
|
||||
break;
|
||||
|
||||
case "xml":
|
||||
this.group = 3;
|
||||
this.fileType = sv.atomXML;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.displayName = this.shortName;
|
||||
this.sortName = this.shortName.toLowerCase();
|
||||
return this;
|
||||
}
|
||||
|
||||
ScriptInstanceRecord.prototype =
|
||||
new XULTreeViewRecord(console.views.scripts.share);
|
||||
|
||||
ScriptInstanceRecord.prototype.onDragStart =
|
||||
function scr_dragstart (e, transferData, dragAction)
|
||||
{
|
||||
transferData.data = new TransferData();
|
||||
transferData.data.addDataForFlavour("text/x-venkman-file", this.fileName);
|
||||
transferData.data.addDataForFlavour("text/x-moz-url", this.fileName);
|
||||
transferData.data.addDataForFlavour("text/unicode", this.fileName);
|
||||
transferData.data.addDataForFlavour("text/html",
|
||||
"<a href='" + this.fileName +
|
||||
"'>" + this.fileName + "</a>");
|
||||
return true;
|
||||
}
|
||||
|
||||
ScriptInstanceRecord.prototype.super_resort = XTRootRecord.prototype.resort;
|
||||
|
||||
ScriptInstanceRecord.prototype.resort =
|
||||
function scr_resort ()
|
||||
{
|
||||
console._groupFiles = console.prefs["scriptsView.groupFiles"];
|
||||
this.super_resort();
|
||||
delete console._groupFiles;
|
||||
}
|
||||
|
||||
ScriptInstanceRecord.prototype.sortCompare =
|
||||
function scr_compare (a, b)
|
||||
{
|
||||
if (0)
|
||||
{
|
||||
if (a.group < b.group)
|
||||
return -1;
|
||||
|
||||
if (a.group > b.group)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (a.sortName < b.sortName)
|
||||
return -1;
|
||||
|
||||
if (a.sortName > b.sortName)
|
||||
return 1;
|
||||
|
||||
if (a.sequence < b.sequence)
|
||||
return -1;
|
||||
|
||||
if (a.sequence > b.sequence)
|
||||
return 1;
|
||||
|
||||
dd ("ack, all equal?");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ScriptInstanceRecord.prototype.onPreOpen =
|
||||
function scr_preopen ()
|
||||
{
|
||||
if (!this.scriptInstance.sourceText.isLoaded)
|
||||
this.scriptInstance.sourceText.loadSource();
|
||||
|
||||
if (this.lastScriptCount != this.scriptInstance.scriptCount)
|
||||
{
|
||||
var sr;
|
||||
|
||||
console.views.scripts.freeze();
|
||||
this.childData = new Array();
|
||||
var scriptWrapper = this.scriptInstance.topLevel;
|
||||
if (scriptWrapper)
|
||||
{
|
||||
sr = new ScriptRecord(scriptWrapper);
|
||||
scriptWrapper.scriptRecord = sr;
|
||||
this.appendChild(sr);
|
||||
}
|
||||
|
||||
var functions = this.scriptInstance.functions;
|
||||
for (var f in functions)
|
||||
{
|
||||
if (functions[f].jsdScript.isValid)
|
||||
{
|
||||
sr = new ScriptRecord(functions[f]);
|
||||
functions[f].scriptRecord = sr;
|
||||
this.appendChild(sr);
|
||||
}
|
||||
}
|
||||
console.views.scripts.thaw();
|
||||
this.lastScriptCount = this.scriptInstance.scriptCount;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Script Record.
|
||||
* Represents a ScriptWrapper, for use in the Scripts View only.
|
||||
*******************************************************************************/
|
||||
|
||||
function ScriptRecord(scriptWrapper)
|
||||
{
|
||||
this.setColumnPropertyName ("col-0", "functionName");
|
||||
this.setColumnPropertyName ("col-1", "baseLineNumber");
|
||||
this.setColumnPropertyName ("col-2", "lineExtent");
|
||||
|
||||
this.functionName = scriptWrapper.functionName
|
||||
this.baseLineNumber = scriptWrapper.jsdScript.baseLineNumber;
|
||||
this.lineExtent = scriptWrapper.jsdScript.lineExtent;
|
||||
this.scriptWrapper = scriptWrapper;
|
||||
|
||||
this.jsdurl = "jsd:sourcetext?url=" +
|
||||
escape(this.scriptWrapper.jsdScript.fileName) +
|
||||
"&base=" + this.baseLineNumber + "&extent=" + this.lineExtent +
|
||||
"&name=" + this.functionName;
|
||||
}
|
||||
|
||||
ScriptRecord.prototype = new XULTreeViewRecord(console.views.scripts.share);
|
||||
|
||||
ScriptRecord.prototype.onDragStart =
|
||||
function sr_dragstart (e, transferData, dragAction)
|
||||
{
|
||||
var fileName = this.script.fileName;
|
||||
transferData.data = new TransferData();
|
||||
transferData.data.addDataForFlavour("text/x-jsd-url", this.jsdurl);
|
||||
transferData.data.addDataForFlavour("text/x-moz-url", fileName);
|
||||
transferData.data.addDataForFlavour("text/unicode", fileName);
|
||||
transferData.data.addDataForFlavour("text/html",
|
||||
"<a href='" + fileName +
|
||||
"'>" + fileName + "</a>");
|
||||
return true;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Value Record.
|
||||
* Use this to show a jsdIValue in any tree.
|
||||
*******************************************************************************/
|
||||
|
||||
function ValueRecord (value, name, flags)
|
||||
{
|
||||
if (!(value instanceof jsdIValue))
|
||||
throw new BadMojo (ERR_INVALID_PARAM, "value", String(value));
|
||||
|
||||
this.setColumnPropertyName ("col-0", "displayName");
|
||||
this.setColumnPropertyName ("col-1", "displayType");
|
||||
this.setColumnPropertyName ("col-2", "displayValue");
|
||||
this.setColumnPropertyName ("col-3", "displayFlags");
|
||||
this.displayName = name;
|
||||
this.displayFlags = formatFlags(flags);
|
||||
this.name = name;
|
||||
this.flags = flags;
|
||||
this.value = value;
|
||||
this.jsType = null;
|
||||
this.onPreRefresh = false;
|
||||
this.refresh();
|
||||
delete this.onPreRefresh;
|
||||
}
|
||||
|
||||
ValueRecord.prototype = new XULTreeViewRecord (null);
|
||||
|
||||
ValueRecord.prototype.__defineGetter__("_share", vr_getshare);
|
||||
function vr_getshare()
|
||||
{
|
||||
if ("__share" in this)
|
||||
return this.__share;
|
||||
|
||||
if ("parentRecord" in this)
|
||||
return this.__share = this.parentRecord._share;
|
||||
|
||||
ASSERT (0, "ValueRecord cannot be the root of a visible tree.");
|
||||
return null;
|
||||
}
|
||||
|
||||
ValueRecord.prototype.showFunctions = true;
|
||||
ValueRecord.prototype.showECMAProps = true;
|
||||
|
||||
ValueRecord.prototype.getProperties =
|
||||
function vr_getprops (properties)
|
||||
{
|
||||
if ("valueIsException" in this || this.flags & PROP_EXCEPTION)
|
||||
properties.AppendElement (this.atomException);
|
||||
|
||||
if (this.flags & PROP_ERROR)
|
||||
properties.AppendElement (this.atomError);
|
||||
|
||||
if (this.flags & PROP_HINTED)
|
||||
properties.AppendElement (this.atomHinted);
|
||||
|
||||
properties.AppendElement (this.property);
|
||||
}
|
||||
|
||||
ValueRecord.prototype.onPreRefresh =
|
||||
function vr_prerefresh ()
|
||||
{
|
||||
if (!ASSERT("parentRecord" in this, "onPreRefresh with no parent"))
|
||||
return;
|
||||
|
||||
if ("isECMAProto" in this)
|
||||
{
|
||||
if (this.parentRecord.value.jsPrototype)
|
||||
this.value = this.parentRecord.value.jsPrototype;
|
||||
else
|
||||
this.value = console.jsds.wrapValue(null);
|
||||
}
|
||||
else if ("isECMAParent" in this)
|
||||
{
|
||||
if (this.parentRecord.value.jsParent)
|
||||
this.value = this.parentRecord.value.jsParent;
|
||||
else
|
||||
this.value = console.jsds.wrapValue(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
var value = this.parentRecord.value;
|
||||
var prop = value.getProperty (this.name);
|
||||
if (prop)
|
||||
{
|
||||
this.flags = prop.flags;
|
||||
this.value = prop.value;
|
||||
}
|
||||
else
|
||||
{
|
||||
var jsval = value.getWrappedValue();
|
||||
this.value = console.jsds.wrapValue(jsval[this.name]);
|
||||
this.flags = PROP_ENUMERATE | PROP_HINTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ValueRecord.prototype.refresh =
|
||||
function vr_refresh ()
|
||||
{
|
||||
if (this.onPreRefresh)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.onPreRefresh();
|
||||
delete this.valueIsException;
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
dd ("caught exception refreshing " + this.displayName);
|
||||
dd (dumpObjectTree(ex));
|
||||
|
||||
if (!(ex instanceof jsdIValue))
|
||||
ex = console.jsds.wrapValue(ex);
|
||||
|
||||
this.value = ex;
|
||||
this.valueIsException = true;
|
||||
}
|
||||
}
|
||||
|
||||
this.jsType = this.value.jsType;
|
||||
delete this.alwaysHasChildren;
|
||||
|
||||
var strval;
|
||||
|
||||
switch (this.jsType)
|
||||
{
|
||||
case TYPE_VOID:
|
||||
this.displayValue = MSG_TYPE_VOID
|
||||
this.displayType = MSG_TYPE_VOID;
|
||||
this.property = this.atomVoid;
|
||||
break;
|
||||
case TYPE_NULL:
|
||||
this.displayValue = MSG_TYPE_NULL;
|
||||
this.displayType = MSG_TYPE_NULL;
|
||||
this.property = this.atomNull;
|
||||
break;
|
||||
case TYPE_BOOLEAN:
|
||||
this.displayValue = this.value.stringValue;
|
||||
this.displayType = MSG_TYPE_BOOLEAN;
|
||||
this.property = this.atomBool;
|
||||
break;
|
||||
case TYPE_INT:
|
||||
this.displayValue = this.value.intValue;
|
||||
this.displayType = MSG_TYPE_INT;
|
||||
this.property = this.atomInt;
|
||||
break;
|
||||
case TYPE_DOUBLE:
|
||||
this.displayValue = this.value.doubleValue;
|
||||
this.displayType = MSG_TYPE_DOUBLE;
|
||||
this.property = this.atomDouble;
|
||||
break;
|
||||
case TYPE_STRING:
|
||||
strval = this.value.stringValue.quote();
|
||||
if (strval.length > console.prefs["maxStringLength"])
|
||||
strval = getMsg(MSN_FMT_LONGSTR, strval.length);
|
||||
this.displayValue = strval;
|
||||
this.displayType = MSG_TYPE_STRING;
|
||||
this.property = this.atomString;
|
||||
break;
|
||||
case TYPE_FUNCTION:
|
||||
case TYPE_OBJECT:
|
||||
this.displayType = MSG_TYPE_OBJECT;
|
||||
this.property = this.atomObject;
|
||||
|
||||
this.alwaysHasChildren = true;
|
||||
this.value.refresh();
|
||||
|
||||
var ctor = this.value.jsClassName;
|
||||
|
||||
if (ctor == "Function")
|
||||
{
|
||||
this.displayType = MSG_TYPE_FUNCTION;
|
||||
ctor = (this.value.isNative ? MSG_CLASS_NATIVE_FUN :
|
||||
MSG_CLASS_SCRIPT_FUN);
|
||||
this.property = this.atomFunction;
|
||||
}
|
||||
if (ctor == "Object")
|
||||
{
|
||||
if (this.value.jsConstructor)
|
||||
ctor = this.value.jsConstructor.jsFunctionName;
|
||||
}
|
||||
else if (ctor == "XPCWrappedNative_NoHelper")
|
||||
{
|
||||
ctor = MSG_CLASS_CONST_XPCOBJ;
|
||||
}
|
||||
else if (ctor == "XPC_WN_ModsAllowed_Proto_JSClass")
|
||||
{
|
||||
ctor = MSG_CLASS_XPCOBJ;
|
||||
}
|
||||
|
||||
if (ctor != "String")
|
||||
{
|
||||
var propCount;
|
||||
if (this.brokenObjects.test(ctor))
|
||||
{
|
||||
/* XXX these objects do Bad Things when you enumerate
|
||||
* over them. */
|
||||
propCount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
propCount = this.countProperties();
|
||||
}
|
||||
|
||||
this.displayValue = getMsg (MSN_FMT_OBJECT_VALUE,
|
||||
[ctor, propCount]);
|
||||
}
|
||||
else
|
||||
{
|
||||
strval = this.value.stringValue.quote();
|
||||
if (strval.length > console.prefs["maxStringLength"])
|
||||
strval = getMsg(MSN_FMT_LONGSTR, strval.length);
|
||||
this.displayValue = strval;
|
||||
}
|
||||
|
||||
/* if we have children, refresh them. */
|
||||
if ("childData" in this && this.childData.length > 0)
|
||||
{
|
||||
if (!this.refreshChildren())
|
||||
{
|
||||
dd ("refreshChilren failed for " + this.displayName);
|
||||
delete this.childData;
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ASSERT (0, "invalid value");
|
||||
}
|
||||
}
|
||||
|
||||
ValueRecord.prototype.countProperties =
|
||||
function vr_countprops ()
|
||||
{
|
||||
var c = 0;
|
||||
var jsval = this.value.getWrappedValue();
|
||||
try
|
||||
{
|
||||
for (var p in jsval)
|
||||
++c;
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
dd ("caught exception counting properties\n" + ex);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
ValueRecord.prototype.listProperties =
|
||||
function vr_listprops ()
|
||||
{
|
||||
//dd ("listProperties {");
|
||||
var i;
|
||||
var jsval = this.value.getWrappedValue();
|
||||
var propMap = new Object();
|
||||
|
||||
/* get the enumerable properties */
|
||||
for (var p in jsval)
|
||||
{
|
||||
var value;
|
||||
try
|
||||
{
|
||||
value = console.jsds.wrapValue(jsval[p]);
|
||||
if (this.showFunctions || value.jsType != TYPE_FUNCTION)
|
||||
{
|
||||
propMap[p] = { name: p, value: value,
|
||||
flags: PROP_ENUMERATE | PROP_HINTED };
|
||||
}
|
||||
else
|
||||
{
|
||||
//dd ("not including function " + name);
|
||||
propMap[p] = null;
|
||||
}
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
propMap[p] = { name: p, value: console.jsds.wrapValue(ex),
|
||||
flags: PROP_EXCEPTION };
|
||||
}
|
||||
}
|
||||
|
||||
/* get the local properties, may or may not be enumerable */
|
||||
var localProps = new Object()
|
||||
this.value.getProperties(localProps, {});
|
||||
localProps = localProps.value;
|
||||
var len = localProps.length;
|
||||
for (i = 0; i < len; ++i)
|
||||
{
|
||||
var prop = localProps[i];
|
||||
if (!ASSERT(prop, "prop[" + i + "] is null"))
|
||||
continue;
|
||||
|
||||
var name = prop.name.stringValue;
|
||||
|
||||
if (!(name in propMap))
|
||||
{
|
||||
if (this.showFunctions || prop.value.jsType != TYPE_FUNCTION)
|
||||
{
|
||||
//dd ("localProps: adding " + name + ", " + prop);
|
||||
propMap[name] = { name: name, value: prop.value,
|
||||
flags: prop.flags };
|
||||
}
|
||||
else
|
||||
{
|
||||
//dd ("not including function " + name);
|
||||
propMap[name] = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (propMap[name])
|
||||
propMap[name].flags = prop.flags;
|
||||
}
|
||||
}
|
||||
|
||||
/* sort the property list */
|
||||
var nameList = keys(propMap);
|
||||
nameList.sort();
|
||||
var propertyList = new Array();
|
||||
for (i = 0; i < nameList.length; ++i)
|
||||
{
|
||||
name = nameList[i];
|
||||
if (propMap[name])
|
||||
propertyList.push (propMap[name]);
|
||||
}
|
||||
|
||||
//dd ("} " + propertyList.length + " properties");
|
||||
|
||||
return propertyList;
|
||||
}
|
||||
|
||||
ValueRecord.prototype.refreshChildren =
|
||||
function vr_refreshkids ()
|
||||
{
|
||||
var leadingProps = 0;
|
||||
|
||||
this.propertyList = this.listProperties();
|
||||
|
||||
for (var i = 0; i < this.childData.length; ++i)
|
||||
{
|
||||
if ("isECMAParent" in this.childData[i] ||
|
||||
"isECMAProto" in this.childData[i])
|
||||
{
|
||||
++leadingProps;
|
||||
}
|
||||
else if (this.childData.length - leadingProps !=
|
||||
this.propertyList.length)
|
||||
{
|
||||
dd ("refreshChildren: property length mismatch");
|
||||
return false;
|
||||
}
|
||||
else if (this.childData[i]._colValues["col-0"] !=
|
||||
this.propertyList[i - leadingProps].name)
|
||||
{
|
||||
dd ("refreshChildren: " +
|
||||
this.childData[i]._colValues["col-0"] + " != " +
|
||||
this.propertyList[i - leadingProps].name);
|
||||
return false;
|
||||
}
|
||||
|
||||
this.childData[i].refresh();
|
||||
}
|
||||
|
||||
if (this.childData.length - leadingProps !=
|
||||
this.propertyList.length)
|
||||
{
|
||||
dd ("refreshChildren: property length mismatch");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ValueRecord.prototype.onPreOpen =
|
||||
function vr_preopen()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!ASSERT(this.value.jsType == TYPE_OBJECT ||
|
||||
this.value.jsType == TYPE_FUNCTION,
|
||||
"onPreOpen called for non object?"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.childData = new Array();
|
||||
this.propertyList = this.listProperties();
|
||||
|
||||
if (this.showECMAProps)
|
||||
{
|
||||
var rec;
|
||||
if (this.value.jsPrototype)
|
||||
{
|
||||
rec = new ValueRecord(this.value.jsPrototype,
|
||||
MSG_VAL_PROTO);
|
||||
rec.isECMAProto = true;
|
||||
this.appendChild (rec);
|
||||
}
|
||||
|
||||
if (this.value.jsParent)
|
||||
{
|
||||
rec = new ValueRecord(this.value.jsParent,
|
||||
MSG_VAL_PARENT);
|
||||
rec.isECMAParent = true;
|
||||
this.appendChild (rec);
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < this.propertyList.length; ++i)
|
||||
{
|
||||
var prop = this.propertyList[i];
|
||||
this.appendChild(new ValueRecord(prop.value,
|
||||
prop.name,
|
||||
prop.flags));
|
||||
}
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
display (getMsg (MSN_ERR_FAILURE, ex), MT_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
ValueRecord.prototype.onPostClose =
|
||||
function vr_destroy()
|
||||
{
|
||||
this.childData = new Array();
|
||||
delete this.propertyList;
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<!--
|
||||
-
|
||||
- The contents of this file are subject to the Mozilla Public License
|
||||
- Version 1.1 (the "License"); you may not use this file except in
|
||||
- compliance with the License. You may obtain a copy of the License at
|
||||
- http://www.mozilla.org/MPL/
|
||||
-
|
||||
- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
- for the specific language governing rights and limitations under the
|
||||
- License.
|
||||
-
|
||||
- The Original Code is The JavaScript Debugger
|
||||
-
|
||||
- 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.
|
||||
-
|
||||
- Alternatively, the contents of this file may be used under the
|
||||
- terms of the GNU Public License (the "GPL"), in which case the
|
||||
- provisions of the GPL are applicable instead of those above.
|
||||
- If you wish to allow use of your version of this file only
|
||||
- under the terms of the GPL and not to allow others to use your
|
||||
- version of this file under the MPL, indicate your decision by
|
||||
- deleting the provisions above and replace them with the notice
|
||||
- and other provisions required by the GPL. If you do not delete
|
||||
- the provisions above, a recipient may use your version of this
|
||||
- file under either the MPL or the GPL.
|
||||
-
|
||||
- Contributor(s):
|
||||
- Robert Ginda, <rginda@netscape.com>, original author
|
||||
-
|
||||
-->
|
||||
|
||||
<overlay id="venkman-scripts-overlay"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<overlaytarget id="scripts-overlay-target">
|
||||
<script>
|
||||
<![CDATA[
|
||||
/* set this to false to turn off dd() messages */
|
||||
var DEBUG = true;
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<script src="chrome://global/content/nsJSSupportsUtils.js"/>
|
||||
<script src="chrome://global/content/nsJSComponentManager.js"/>
|
||||
<script src="chrome://global/content/nsUserSettings.js"/>
|
||||
<script src="chrome://global/content/nsTransferable.js"/>
|
||||
<script src="chrome://global/content/nsClipboard.js"/>
|
||||
<script src="chrome://global/content/nsDragAndDrop.js"/>
|
||||
<script src="chrome://communicator/content/contentAreaUtils.js"/>
|
||||
<script src="chrome://communicator/content/contentAreaDD.js"/>
|
||||
<script src="chrome://global/content/strres.js"/>
|
||||
|
||||
<script src="chrome://venkman/content/command-manager.js"/>
|
||||
<script src="chrome://venkman/content/menu-manager.js"/>
|
||||
<script src="chrome://venkman/content/view-manager.js"/>
|
||||
<script src="chrome://venkman/content/tree-utils.js"/>
|
||||
<script src="chrome://venkman/content/file-utils.js"/>
|
||||
<script src="chrome://venkman/content/html-consts.js"/>
|
||||
|
||||
<script src="chrome://venkman/content/venkman-utils.js"/>
|
||||
<script src="chrome://venkman/content/venkman-static.js"/>
|
||||
<script src="chrome://venkman/content/venkman-handlers.js"/>
|
||||
<script src="chrome://venkman/content/venkman-debugger.js"/>
|
||||
<script src="chrome://venkman/content/venkman-profiler.js"/>
|
||||
<script src="chrome://venkman/content/venkman-jsdurl.js"/>
|
||||
<script src="chrome://venkman/content/venkman-url-loader.js"/>
|
||||
<script src="chrome://venkman/content/venkman-commands.js"/>
|
||||
<script src="chrome://venkman/content/venkman-prefs.js"/>
|
||||
<script src="chrome://venkman/content/venkman-eval.js"/>
|
||||
<script src="chrome://venkman/content/venkman-menus.js"/>
|
||||
<script src="chrome://venkman/content/venkman-msg.js"/>
|
||||
<script src="chrome://venkman/content/venkman-munger.js"/>
|
||||
<script src="chrome://venkman/content/venkman-views.js"/>
|
||||
<script src="chrome://venkman/content/venkman-records.js"/>
|
||||
|
||||
</overlaytarget>
|
||||
|
||||
</overlay>
|
||||
@@ -1,15 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
|
||||
<html>
|
||||
<head>
|
||||
<LINK REL=StyleSheet HREF='chrome://venkman/skin/venkman-source2-default.css'
|
||||
TYPE='text/css' MEDIA='screen'>
|
||||
</head>
|
||||
|
||||
<body id="venkman-source2-body">
|
||||
|
||||
<table border="0" cellpadding="0" cellspacing="0" id="source2-table">
|
||||
</table>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,103 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is The JavaScript Debugger
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation
|
||||
* Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the MPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Robert Ginda, <rginda@netscape.com>, original author
|
||||
*
|
||||
*/
|
||||
|
||||
const IOSERVICE_CTRID = "@mozilla.org/network/io-service;1";
|
||||
const nsIIOService = Components.interfaces.nsIIOService;
|
||||
const SIS_CTRID = "@mozilla.org/scriptableinputstream;1"
|
||||
const nsIScriptableInputStream = Components.interfaces.nsIScriptableInputStream;
|
||||
const nsIChannel = Components.interfaces.nsIChannel;
|
||||
const nsIInputStream = Components.interfaces.nsIInputStream;
|
||||
|
||||
function _getChannelForURL (url)
|
||||
{
|
||||
var serv = Components.classes[IOSERVICE_CTRID].getService(nsIIOService);
|
||||
if (!serv)
|
||||
throw new BadMojo(ERR_FAILURE);
|
||||
|
||||
return serv.newChannel(url, null, null);
|
||||
|
||||
}
|
||||
|
||||
function loadURLNow (url)
|
||||
{
|
||||
var chan = _getChannelForURL (url);
|
||||
|
||||
var instream =
|
||||
Components.classes[SIS_CTRID].createInstance(nsIScriptableInputStream);
|
||||
instream.init (chan.open());
|
||||
|
||||
return instream.read (instream.available());
|
||||
}
|
||||
|
||||
function loadURLAsync (url, observer)
|
||||
{
|
||||
var chan = _getChannelForURL (url);
|
||||
return chan.asyncOpen (new StreamListener (url, observer), null);
|
||||
}
|
||||
|
||||
function StreamListener(url, observer)
|
||||
{
|
||||
this.data = "";
|
||||
this.url = url;
|
||||
this.observer = observer;
|
||||
}
|
||||
|
||||
StreamListener.prototype.onStartRequest =
|
||||
function (request, data)
|
||||
{
|
||||
//dd ("onStartRequest()");
|
||||
}
|
||||
|
||||
StreamListener.prototype.onStopRequest =
|
||||
function (request, data, status)
|
||||
{
|
||||
dd ("onStopRequest(): status: " + status + "\n" /* + this.data*/);
|
||||
if (typeof this.observer.onComplete == "function")
|
||||
this.observer.onComplete (this.data, this.url, status);
|
||||
}
|
||||
|
||||
StreamListener.prototype.onDataAvailable =
|
||||
function (request, data, inStr, sourceOffset, count)
|
||||
{
|
||||
/*dd ("onDataAvailable(): " + count);*/
|
||||
if (!this._sis)
|
||||
{
|
||||
this._sis =
|
||||
Components.classes[SIS_CTRID].createInstance(nsIScriptableInputStream);
|
||||
this._sis.init(inStr);
|
||||
}
|
||||
|
||||
this.data += this._sis.read(count);
|
||||
}
|
||||
@@ -1,823 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code
|
||||
*
|
||||
* The Initial Developer of the Original Code is New Dimensions Consulting,
|
||||
* Inc. Portions created by New Dimensions Consulting, Inc. are
|
||||
* Copyright (C) 1999 New Dimensions Consulting, Inc. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Robert Ginda, rginda@ndcico.com, original author
|
||||
*
|
||||
*
|
||||
* JavaScript utility functions.
|
||||
*/
|
||||
|
||||
var dumpln;
|
||||
var dd;
|
||||
|
||||
const nsIBaseWindow = Components.interfaces.nsIBaseWindow;
|
||||
const nsIXULWindow = Components.interfaces.nsIXULWindow;
|
||||
const nsIInterfaceRequestor = Components.interfaces.nsIInterfaceRequestor;
|
||||
const nsIWebNavigation = Components.interfaces.nsIWebNavigation;
|
||||
const nsIDocShellTreeItem = Components.interfaces.nsIDocShellTreeItem;
|
||||
|
||||
if (typeof document == "undefined") /* in xpcshell */
|
||||
{
|
||||
dumpln = print;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (typeof dump == "function")
|
||||
dumpln = function (str) {dump (str + "\n");}
|
||||
else if (jsenv.HAS_RHINO)
|
||||
{
|
||||
dumpln = function (str) {
|
||||
var out = java.lang.System.out;
|
||||
out.println(str); out.flush();
|
||||
}
|
||||
}
|
||||
else
|
||||
dumpln = function () {} /* no suitable function */
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
var _dd_pfx = "";
|
||||
var _dd_singleIndent = " ";
|
||||
var _dd_indentLength = _dd_singleIndent.length;
|
||||
var _dd_currentIndent = "";
|
||||
var _dd_lastDumpWasOpen = false;
|
||||
var _dd_timeStack = new Array();
|
||||
var _dd_disableDepth = Number.MAX_VALUE;
|
||||
var _dd_currentDepth = 0;
|
||||
dd = function _dd (str) {
|
||||
if (typeof str != "string") {
|
||||
dumpln (str);
|
||||
} else if (str[str.length - 1] == "{") {
|
||||
++_dd_currentDepth;
|
||||
if (_dd_currentDepth >= _dd_disableDepth)
|
||||
return;
|
||||
if (str.indexOf("OFF") == 0)
|
||||
_dd_disableDepth = _dd_currentDepth;
|
||||
_dd_timeStack.push (new Date());
|
||||
if (_dd_lastDumpWasOpen)
|
||||
dump("\n");
|
||||
dump (_dd_pfx + _dd_currentIndent + str);
|
||||
_dd_currentIndent += _dd_singleIndent;
|
||||
_dd_lastDumpWasOpen = true;
|
||||
} else if (str[0] == "}") {
|
||||
if (--_dd_currentDepth >= _dd_disableDepth)
|
||||
return;
|
||||
_dd_disableDepth = Number.MAX_VALUE;
|
||||
var sufx = (new Date() - _dd_timeStack.pop()) / 1000 + " sec";
|
||||
_dd_currentIndent =
|
||||
_dd_currentIndent.substr (0, _dd_currentIndent.length -
|
||||
_dd_indentLength);
|
||||
if (_dd_lastDumpWasOpen)
|
||||
dumpln (str + " " + sufx);
|
||||
else
|
||||
dumpln (_dd_pfx + _dd_currentIndent + str + " " + sufx);
|
||||
_dd_lastDumpWasOpen = false;
|
||||
} else {
|
||||
if (_dd_currentDepth >= _dd_disableDepth)
|
||||
return;
|
||||
if (_dd_lastDumpWasOpen)
|
||||
dump ("\n");
|
||||
dumpln (_dd_pfx + _dd_currentIndent + str);
|
||||
_dd_lastDumpWasOpen = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
dd = function (){};
|
||||
}
|
||||
|
||||
var jsenv = new Object();
|
||||
jsenv.HAS_SECURITYMANAGER = ((typeof netscape == "object") &&
|
||||
(typeof netscape.security == "object"));
|
||||
jsenv.HAS_XPCOM = ((typeof Components == "object") &&
|
||||
(typeof Components.classes == "object"));
|
||||
jsenv.HAS_JAVA = (typeof java == "object");
|
||||
jsenv.HAS_RHINO = (typeof defineClass == "function");
|
||||
jsenv.HAS_DOCUMENT = (typeof document == "object");
|
||||
|
||||
/* Dumps an object in tree format, recurse specifiec the the number of objects
|
||||
* to recurse, compress is a boolean that can uncompress (true) the output
|
||||
* format, and level is the number of levels to intitialy indent (only useful
|
||||
* internally.) A sample dumpObjectTree (o, 1) is shown below.
|
||||
*
|
||||
* + parent (object)
|
||||
* + users (object)
|
||||
* | + jsbot (object)
|
||||
* | + mrjs (object)
|
||||
* | + nakkezzzz (object)
|
||||
* | *
|
||||
* + bans (object)
|
||||
* | *
|
||||
* + topic (string) 'ircclient.js:59: nothing is not defined'
|
||||
* + getUsersLength (function) 9 lines
|
||||
* *
|
||||
*/
|
||||
function dumpObjectTree (o, recurse, compress, level)
|
||||
{
|
||||
var s = "";
|
||||
var pfx = "";
|
||||
|
||||
if (typeof recurse == "undefined")
|
||||
recurse = 0;
|
||||
if (typeof level == "undefined")
|
||||
level = 0;
|
||||
if (typeof compress == "undefined")
|
||||
compress = true;
|
||||
|
||||
for (var i = 0; i < level; i++)
|
||||
pfx += (compress) ? "| " : "| ";
|
||||
|
||||
var tee = (compress) ? "+ " : "+- ";
|
||||
|
||||
for (i in o)
|
||||
{
|
||||
var t;
|
||||
try
|
||||
{
|
||||
t = typeof o[i];
|
||||
|
||||
switch (t)
|
||||
{
|
||||
case "function":
|
||||
var sfunc = String(o[i]).split("\n");
|
||||
if (sfunc[2] == " [native code]")
|
||||
sfunc = "[native code]";
|
||||
else
|
||||
sfunc = sfunc.length + " lines";
|
||||
s += pfx + tee + i + " (function) " + sfunc + "\n";
|
||||
break;
|
||||
|
||||
case "object":
|
||||
s += pfx + tee + i + " (object) " + o[i] + "\n";
|
||||
if (!compress)
|
||||
s += pfx + "|\n";
|
||||
if ((i != "parent") && (recurse))
|
||||
s += dumpObjectTree (o[i], recurse - 1,
|
||||
compress, level + 1);
|
||||
break;
|
||||
|
||||
case "string":
|
||||
if (o[i].length > 200)
|
||||
s += pfx + tee + i + " (" + t + ") " +
|
||||
o[i].length + " chars\n";
|
||||
else
|
||||
s += pfx + tee + i + " (" + t + ") '" + o[i] + "'\n";
|
||||
break;
|
||||
|
||||
default:
|
||||
s += pfx + tee + i + " (" + t + ") " + o[i] + "\n";
|
||||
}
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
s += pfx + tee + i + " (exception) " + ex + "\n";
|
||||
}
|
||||
|
||||
if (!compress)
|
||||
s += pfx + "|\n";
|
||||
|
||||
}
|
||||
|
||||
s += pfx + "*\n";
|
||||
|
||||
return s;
|
||||
|
||||
}
|
||||
|
||||
function getChildById (element, id)
|
||||
{
|
||||
var nl = element.getElementsByAttribute("id", id);
|
||||
return nl.item(0);
|
||||
}
|
||||
|
||||
function openTopWin (url)
|
||||
{
|
||||
var window = getWindowByType ("navigator:browser");
|
||||
if (window)
|
||||
{
|
||||
var base = getBaseWindowFromWindow (window);
|
||||
if (base.enabled)
|
||||
{
|
||||
window.focus();
|
||||
window._content.location.href = url;
|
||||
return window;
|
||||
}
|
||||
}
|
||||
|
||||
return openDialog (getBrowserURL(), "_blank", "chrome,all,dialog=no", url);
|
||||
}
|
||||
|
||||
function getWindowByType (windowType)
|
||||
{
|
||||
const MEDIATOR_CONTRACTID =
|
||||
"@mozilla.org/appshell/window-mediator;1";
|
||||
//"@mozilla.org/rdf/datasource;1?name=window-mediator";
|
||||
const nsIWindowMediator = Components.interfaces.nsIWindowMediator;
|
||||
|
||||
var windowManager =
|
||||
Components.classes[MEDIATOR_CONTRACTID].getService(nsIWindowMediator);
|
||||
|
||||
return windowManager.getMostRecentWindow(windowType);
|
||||
}
|
||||
|
||||
function htmlVA (attribs, href, contents)
|
||||
{
|
||||
if (!attribs)
|
||||
attribs = {"class": "venkman-link", target: "_content"};
|
||||
else if (attribs["class"])
|
||||
attribs["class"] += " venkman-link";
|
||||
else
|
||||
attribs["class"] = "venkman-link";
|
||||
|
||||
if (!contents)
|
||||
{
|
||||
contents = htmlSpan();
|
||||
insertHyphenatedWord (href, contents);
|
||||
}
|
||||
|
||||
return htmlA (attribs, href, contents);
|
||||
}
|
||||
|
||||
function insertHyphenatedWord (longWord, containerTag)
|
||||
{
|
||||
var wordParts = splitLongWord (longWord, MAX_WORD_LEN);
|
||||
containerTag.appendChild (htmlWBR());
|
||||
for (var i = 0; i < wordParts.length; ++i)
|
||||
{
|
||||
containerTag.appendChild (document.createTextNode (wordParts[i]));
|
||||
if (i != wordParts.length)
|
||||
containerTag.appendChild (htmlWBR());
|
||||
}
|
||||
}
|
||||
|
||||
function insertLink (matchText, containerTag)
|
||||
{
|
||||
var href;
|
||||
|
||||
if (matchText.indexOf ("://") == -1 && matchText.indexOf("x-jsd") != 0)
|
||||
href = "http://" + matchText;
|
||||
else
|
||||
href = matchText;
|
||||
|
||||
var anchor = htmlVA (null, href, matchText);
|
||||
containerTag.appendChild (anchor);
|
||||
}
|
||||
|
||||
function toBool (val)
|
||||
{
|
||||
switch (typeof val)
|
||||
{
|
||||
case "boolean":
|
||||
return val;
|
||||
|
||||
case "number":
|
||||
return val != 0;
|
||||
|
||||
default:
|
||||
val = String(val);
|
||||
/* fall through */
|
||||
|
||||
case "string":
|
||||
return (val.search(/true|on|yes|1/i) != -1);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/* some of the drag and drop code has an annoying appetite for exceptions. any
|
||||
* exception raised during a dnd operation causes the operation to fail silently.
|
||||
* passing the function through one of these adapters lets you use "return
|
||||
* false on planned failure" symantics, and dumps any exceptions caught
|
||||
* to the console. */
|
||||
function Prophylactic (parentObj, fun)
|
||||
{
|
||||
function adapter ()
|
||||
{
|
||||
var ex;
|
||||
var rv = false;
|
||||
|
||||
try
|
||||
{
|
||||
rv = fun.apply (parentObj, arguments);
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
dd ("Prophylactic caught an exception:\n" +
|
||||
dumpObjectTree(ex));
|
||||
}
|
||||
|
||||
if (!rv)
|
||||
throw "goodger";
|
||||
|
||||
return rv;
|
||||
};
|
||||
|
||||
return adapter;
|
||||
}
|
||||
|
||||
function argumentsAsArray (args, start)
|
||||
{
|
||||
if (typeof start == "undefined")
|
||||
start = 0;
|
||||
|
||||
if (start >= args.length)
|
||||
return null;
|
||||
|
||||
var rv = new Array();
|
||||
|
||||
for (var i = start; i < args.length; ++i)
|
||||
rv.push(args[i]);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
function splitLongWord (str, pos)
|
||||
{
|
||||
if (str.length <= pos)
|
||||
return [str];
|
||||
|
||||
var ary = new Array();
|
||||
var right = str;
|
||||
|
||||
while (right.length > pos)
|
||||
{
|
||||
/* search for a nice place to break the word, fuzzfactor of +/-5,
|
||||
* centered around |pos| */
|
||||
var splitPos =
|
||||
right.substring(pos - 5, pos + 5).search(/[^A-Za-z0-9]/);
|
||||
|
||||
splitPos = (splitPos != -1) ? pos - 4 + splitPos : pos;
|
||||
ary.push(right.substr (0, splitPos));
|
||||
right = right.substr (splitPos);
|
||||
}
|
||||
|
||||
ary.push (right);
|
||||
|
||||
return ary;
|
||||
}
|
||||
|
||||
function wrapText (str, width)
|
||||
{
|
||||
var rv = "";
|
||||
while (str.length > width)
|
||||
{
|
||||
rv += str.substr(0, width) + "\n";
|
||||
str = str.substr(width);
|
||||
}
|
||||
return rv + str;
|
||||
}
|
||||
|
||||
function wordCap (str)
|
||||
{
|
||||
if (!str)
|
||||
return str;
|
||||
|
||||
return str[0].toUpperCase() + str.substr(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clones an existing object (Only the enumerable properties
|
||||
* of course.) use as a function..
|
||||
* var c = Clone (obj);
|
||||
* or a constructor...
|
||||
* var c = new Clone (obj);
|
||||
*/
|
||||
function Clone (obj)
|
||||
{
|
||||
var robj = new Object();
|
||||
|
||||
for (var p in obj)
|
||||
robj[p] = obj[p];
|
||||
|
||||
return robj;
|
||||
|
||||
}
|
||||
|
||||
function getXULWindowFromWindow (win)
|
||||
{
|
||||
var rv;
|
||||
//dd ("getXULWindowFromWindow: before: getInterface is " + win.getInterface);
|
||||
try
|
||||
{
|
||||
var requestor = win.QueryInterface(nsIInterfaceRequestor);
|
||||
var nav = requestor.getInterface(nsIWebNavigation);
|
||||
var dsti = nav.QueryInterface(nsIDocShellTreeItem);
|
||||
var owner = dsti.treeOwner;
|
||||
requestor = owner.QueryInterface(nsIInterfaceRequestor);
|
||||
rv = requestor.getInterface(nsIXULWindow);
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
rv = null;
|
||||
//dd ("not a nsIXULWindow: " + formatException(ex));
|
||||
/* ignore no-interface exception */
|
||||
}
|
||||
|
||||
//dd ("getXULWindowFromWindow: after: getInterface is " + win.getInterface);
|
||||
return rv;
|
||||
}
|
||||
|
||||
function getBaseWindowFromWindow (win)
|
||||
{
|
||||
var rv;
|
||||
//dd ("getBaseWindowFromWindow: before: getInterface is " + win.getInterface);
|
||||
try
|
||||
{
|
||||
var requestor = win.QueryInterface(nsIInterfaceRequestor);
|
||||
var nav = requestor.getInterface(nsIWebNavigation);
|
||||
var dsti = nav.QueryInterface(nsIDocShellTreeItem);
|
||||
var owner = dsti.treeOwner;
|
||||
requestor = owner.QueryInterface(nsIInterfaceRequestor);
|
||||
rv = requestor.getInterface(nsIBaseWindow);
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
rv = null;
|
||||
//dd ("not a nsIXULWindow: " + formatException(ex));
|
||||
/* ignore no-interface exception */
|
||||
}
|
||||
|
||||
//dd ("getBaseWindowFromWindow: after: getInterface is " + win.getInterface);
|
||||
return rv;
|
||||
}
|
||||
|
||||
function getPathFromURL (url)
|
||||
{
|
||||
var ary = url.match(/^(.*\/)([^\/?]+)(\?|$)/);
|
||||
if (ary)
|
||||
return ary[1];
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
function getFileFromPath (path)
|
||||
{
|
||||
var ary = path.match(/\/([^\/?]+)(\?|$)/);
|
||||
if (ary)
|
||||
return ary[1];
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
function getURLSpecFromFile (file)
|
||||
{
|
||||
if (!file)
|
||||
return null;
|
||||
|
||||
const IOS_CTRID = "@mozilla.org/network/io-service;1";
|
||||
const LOCALFILE_CTRID = "@mozilla.org/file/local;1";
|
||||
|
||||
const nsIIOService = Components.interfaces.nsIIOService;
|
||||
const nsILocalFile = Components.interfaces.nsILocalFile;
|
||||
|
||||
if (typeof file == "string")
|
||||
{
|
||||
var fileObj =
|
||||
Components.classes[LOCALFILE_CTRID].createInstance(nsILocalFile);
|
||||
fileObj.initWithPath(file);
|
||||
file = fileObj;
|
||||
}
|
||||
|
||||
var service = Components.classes[IOS_CTRID].getService(nsIIOService);
|
||||
return service.getURLSpecFromFile(file);
|
||||
}
|
||||
|
||||
function getCommonPfx (list)
|
||||
{
|
||||
var pfx = list[0];
|
||||
var l = list.length;
|
||||
|
||||
for (var i = 1; i < l; i++)
|
||||
{
|
||||
for (var c = 0; c < pfx.length; c++)
|
||||
if (pfx[c] != list[i][c])
|
||||
pfx = pfx.substr (0, c);
|
||||
}
|
||||
|
||||
return pfx;
|
||||
|
||||
}
|
||||
|
||||
function renameProperty (obj, oldname, newname)
|
||||
{
|
||||
|
||||
if (oldname == newname)
|
||||
return;
|
||||
|
||||
obj[newname] = obj[oldname];
|
||||
delete obj[oldname];
|
||||
|
||||
}
|
||||
|
||||
function newObject(contractID, iface)
|
||||
{
|
||||
if (!jsenv.HAS_XPCOM)
|
||||
return null;
|
||||
|
||||
var obj = Components.classes[contractID].createInstance();
|
||||
var rv;
|
||||
|
||||
switch (typeof iface)
|
||||
{
|
||||
case "string":
|
||||
rv = obj.QueryInterface(Components.interfaces[iface]);
|
||||
break;
|
||||
|
||||
case "object":
|
||||
rv = obj.QueryInterface[iface];
|
||||
break;
|
||||
|
||||
default:
|
||||
rv = null;
|
||||
break;
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
||||
}
|
||||
|
||||
function keys (o)
|
||||
{
|
||||
var rv = new Array();
|
||||
|
||||
for (var p in o)
|
||||
rv.push(p);
|
||||
|
||||
return rv;
|
||||
|
||||
}
|
||||
|
||||
function parseSections (str, sections)
|
||||
{
|
||||
var rv = new Object();
|
||||
var currentSection;
|
||||
|
||||
for (var s in sections)
|
||||
{
|
||||
if (!currentSection)
|
||||
currentSection = s;
|
||||
|
||||
if (sections[s])
|
||||
{
|
||||
var i = str.search(sections[s]);
|
||||
if (i != -1)
|
||||
{
|
||||
rv[currentSection] = str.substr(0, i);
|
||||
currentSection = 0;
|
||||
str = RegExp.rightContext;
|
||||
str = str.replace(/^(\n|\r|\r\n)/, "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rv[currentSection] = str;
|
||||
str = "";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
function replaceStrings (str, obj)
|
||||
{
|
||||
if (!str)
|
||||
return str;
|
||||
for (var p in obj)
|
||||
str = str.replace(RegExp(p, "g"), obj[p]);
|
||||
return str;
|
||||
}
|
||||
|
||||
function stringTrim (s)
|
||||
{
|
||||
if (!s)
|
||||
return "";
|
||||
s = s.replace (/^\s+/, "");
|
||||
return s.replace (/\s+$/, "");
|
||||
}
|
||||
|
||||
function formatDateOffset (seconds, format)
|
||||
{
|
||||
seconds = parseInt(seconds);
|
||||
var minutes = parseInt(seconds / 60);
|
||||
seconds = seconds % 60;
|
||||
var hours = parseInt(minutes / 60);
|
||||
minutes = minutes % 60;
|
||||
var days = parseInt(hours / 24);
|
||||
hours = hours % 24;
|
||||
|
||||
if (!format)
|
||||
{
|
||||
var ary = new Array();
|
||||
if (days > 0)
|
||||
ary.push (days + " days");
|
||||
if (hours > 0)
|
||||
ary.push (hours + " hours");
|
||||
if (minutes > 0)
|
||||
ary.push (minutes + " minutes");
|
||||
if (seconds > 0)
|
||||
ary.push (seconds + " seconds");
|
||||
|
||||
format = ary.join(", ");
|
||||
}
|
||||
else
|
||||
{
|
||||
format = format.replace ("%d", days);
|
||||
format = format.replace ("%h", hours);
|
||||
format = format.replace ("%m", minutes);
|
||||
format = format.replace ("%s", seconds);
|
||||
}
|
||||
|
||||
return format;
|
||||
}
|
||||
|
||||
function arraySpeak (ary, single, plural)
|
||||
{
|
||||
var rv = "";
|
||||
|
||||
switch (ary.length)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case 1:
|
||||
rv = ary[0];
|
||||
if (single)
|
||||
rv += " " + single;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
rv = ary[0] + " and " + ary[1];
|
||||
if (plural)
|
||||
rv += " " + plural;
|
||||
break;
|
||||
|
||||
default:
|
||||
for (var i = 0; i < ary.length - 1; ++i)
|
||||
rv += ary[i] + ", ";
|
||||
rv += "and " + ary[ary.length - 1];
|
||||
if (plural)
|
||||
rv += " " + plural;
|
||||
break;
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
||||
}
|
||||
|
||||
function arrayOrFlag (ary, i, flag)
|
||||
{
|
||||
if (i in ary)
|
||||
ary[i] |= flag;
|
||||
else
|
||||
ary[i] = flag;
|
||||
}
|
||||
|
||||
function arrayAndFlag (ary, i, flag)
|
||||
{
|
||||
if (i in ary)
|
||||
ary[i] &= flag;
|
||||
else
|
||||
ary[i] = 0;
|
||||
}
|
||||
|
||||
function arrayContains (ary, elem)
|
||||
{
|
||||
return (arrayIndexOf (ary, elem) != -1);
|
||||
}
|
||||
|
||||
function arrayIndexOf (ary, elem)
|
||||
{
|
||||
if (!ary)
|
||||
return -1;
|
||||
|
||||
for (var i in ary)
|
||||
if (ary[i] == elem)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
function arrayInsertAt (ary, i, o)
|
||||
{
|
||||
|
||||
ary.splice (i, 0, o);
|
||||
|
||||
}
|
||||
|
||||
function arrayRemoveAt (ary, i)
|
||||
{
|
||||
|
||||
ary.splice (i, 1);
|
||||
|
||||
}
|
||||
|
||||
function getRandomElement (ary)
|
||||
{
|
||||
var i = parseInt (Math.random() * ary.length)
|
||||
if (i == ary.length) i = 0;
|
||||
|
||||
return ary[i];
|
||||
|
||||
}
|
||||
|
||||
function zeroPad (num, decimals)
|
||||
{
|
||||
var rv = String(num);
|
||||
var len = rv.length;
|
||||
for (var i = 0; i < decimals - len; ++i)
|
||||
rv = "0" + rv;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
function leftPadString (str, num, ch)
|
||||
{
|
||||
var rv = "";
|
||||
var len = rv.length;
|
||||
for (var i = len; i < num; ++i)
|
||||
rv += ch;
|
||||
|
||||
return rv + str;
|
||||
}
|
||||
|
||||
function roundTo (num, prec)
|
||||
{
|
||||
return Math.round(num * Math.pow (10, prec)) / Math.pow (10, prec);
|
||||
}
|
||||
|
||||
function randomRange (min, max)
|
||||
{
|
||||
|
||||
if (typeof min == "undefined")
|
||||
min = 0;
|
||||
|
||||
if (typeof max == "undefined")
|
||||
max = 1;
|
||||
|
||||
var rv = (parseInt(Math.round((Math.random() * (max - min)) + min )));
|
||||
|
||||
return rv;
|
||||
|
||||
}
|
||||
|
||||
function getStackTrace ()
|
||||
{
|
||||
|
||||
if (!jsenv.HAS_XPCOM)
|
||||
return "No stack trace available.";
|
||||
|
||||
var frame = Components.stack.caller;
|
||||
var str = "<top>";
|
||||
|
||||
while (frame)
|
||||
{
|
||||
var name = frame.name ? frame.name : "[anonymous]";
|
||||
str += "\n" + name + "@" + frame.lineNumber;
|
||||
frame = frame.caller;
|
||||
}
|
||||
|
||||
return str;
|
||||
|
||||
}
|
||||
|
||||
function getInterfaces (cls)
|
||||
{
|
||||
if (!jsenv.HAS_XPCOM)
|
||||
return null;
|
||||
|
||||
var rv = new Object();
|
||||
var e;
|
||||
|
||||
for (var i in Components.interfaces)
|
||||
{
|
||||
try
|
||||
{
|
||||
var ifc = Components.interfaces[i];
|
||||
cls.QueryInterface(ifc);
|
||||
rv[i] = ifc;
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
/* nada */
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
||||
}
|
||||
@@ -1,260 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<!--
|
||||
-
|
||||
- The contents of this file are subject to the Mozilla Public License
|
||||
- Version 1.1 (the "License"); you may not use this file except in
|
||||
- compliance with the License. You may obtain a copy of the License at
|
||||
- http://www.mozilla.org/MPL/
|
||||
-
|
||||
- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
- for the specific language governing rights and limitations under the
|
||||
- License.
|
||||
-
|
||||
- The Original Code is The JavaScript Debugger
|
||||
-
|
||||
- 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.
|
||||
-
|
||||
- Alternatively, the contents of this file may be used under the
|
||||
- terms of the GNU Public License (the "GPL"), in which case the
|
||||
- provisions of the GPL are applicable instead of those above.
|
||||
- If you wish to allow use of your version of this file only
|
||||
- under the terms of the GPL and not to allow others to use your
|
||||
- version of this file under the MPL, indicate your decision by
|
||||
- deleting the provisions above and replace them with the notice
|
||||
- and other provisions required by the GPL. If you do not delete
|
||||
- the provisions above, a recipient may use your version of this
|
||||
- file under either the MPL or the GPL.
|
||||
-
|
||||
- Contributor(s):
|
||||
- Robert Ginda, <rginda@netscape.com>, original author
|
||||
-
|
||||
-->
|
||||
|
||||
<!DOCTYPE window SYSTEM "chrome://venkman/locale/venkman.dtd" >
|
||||
|
||||
<overlay id="venkman-views-overlay"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<overlaytarget id="views-overlay-target" hidden="true">
|
||||
|
||||
|
||||
<!-- breakpoint view -->
|
||||
|
||||
<floatingview id="breaks" title="&Break.label;" flex="1">
|
||||
<vbox id="break-view-content" flex="1">
|
||||
<tree flex="1" id="break-tree" persist="height" hidecolumnpicker="true"
|
||||
ondblclick="console.views.breaks.onDblClick(event);"
|
||||
context="context:breaks">
|
||||
|
||||
<treecols>
|
||||
<treecol id="breaks:col-0" label="&BreakCol0.label;"
|
||||
primary="true" flex="5" persist="hidden width"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol id="breaks:col-1" flex="1" label="&BreakCol1.label;"
|
||||
persist="hidden width"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
</treecols>
|
||||
|
||||
<treechildren id="break-body"/>
|
||||
|
||||
</tree>
|
||||
</vbox>
|
||||
</floatingview>
|
||||
|
||||
<!-- locals view -->
|
||||
|
||||
<floatingview id="locals" title="&Locals.label;" flex="1">
|
||||
<vbox id="locals-view-content" flex="1">
|
||||
<tree flex="1" id="locals-tree" persist="height"
|
||||
ondblclick="console.views.locals.onDblClick(event);"
|
||||
context="context:locals">
|
||||
|
||||
<treecols>
|
||||
<treecol id="locals:col-0" label="&LocalsCol0.header;" primary="true"
|
||||
flex="1" persist="hidden width"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol id="locals:col-1" flex="1" label="&LocalsCol1.header;"
|
||||
persist="hidden width" hidden="true"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol id="locals:col-2" flex="1" label="&LocalsCol2.header;"
|
||||
persist="hidden width"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol id="locals:col-3" flex="1" label="&LocalsCol3.header;"
|
||||
persist="hidden width" hidden="true"/>
|
||||
</treecols>
|
||||
|
||||
<treechildren id="locals-body"/>
|
||||
|
||||
</tree>
|
||||
</vbox>
|
||||
</floatingview>
|
||||
|
||||
<!-- session view -->
|
||||
|
||||
<floatingview id="session" title="&Session.label;" flex="1">
|
||||
<vbox id="session-view-content" flex="1" persist="width">
|
||||
|
||||
<browser id="session-output-iframe" flex="1" type="content"
|
||||
src="about:blank" context="context:session"/>
|
||||
<textbox id="session-sl-input" class="input-widget"
|
||||
onkeypress="console.views.session.onSLKeyPress(event);"/>
|
||||
|
||||
</vbox>
|
||||
</floatingview>
|
||||
|
||||
<!-- scripts view -->
|
||||
|
||||
<floatingview id="scripts" title="&Scripts.label;" flex="1">
|
||||
<vbox id="scripts-view-content" flex="1">
|
||||
<tree flex="1" id="scripts-tree" persist="height"
|
||||
ondblclick="console.views.scripts.onDblClick(event);"
|
||||
context="context:scripts">
|
||||
|
||||
<treecols>
|
||||
<treecol id="scripts:col-0" label="&ScriptsCol0.header;"
|
||||
primary="true" flex="5" persist="hidden width"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol id="scripts:col-1" flex="1" label="&ScriptsCol1.header;"
|
||||
persist="hidden width"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol id="scripts:col-2" flex="1" label="&ScriptsCol2.header;"
|
||||
persist="hidden width" hidden="true"/>
|
||||
</treecols>
|
||||
|
||||
<treechildren id="script-list-body"/>
|
||||
|
||||
</tree>
|
||||
</vbox>
|
||||
</floatingview>
|
||||
|
||||
<!-- source2 view -->
|
||||
|
||||
<floatingview id="source2" title="&Source.label;" flex="1">
|
||||
<stack flex="1">
|
||||
<vbox flex="1" pack="center" align="center">
|
||||
<label id="source2-version-label" value="Venkman!"/>
|
||||
<label id="source2-help-label" value="I feel so funky"/>
|
||||
</vbox>
|
||||
<tabbox id="source2-tabbox" flex="1">
|
||||
<tabs id="source2-tabs">
|
||||
<!--
|
||||
We've got to put this placeholder tab in the tabs element to avoid
|
||||
bogus strict warnings and exceptions.
|
||||
-->
|
||||
<tab id="source2-bloke" hidden="true"/>
|
||||
</tabs>
|
||||
<tabpanels id="source2-deck" flex="1"/>
|
||||
</tabbox>
|
||||
</stack>
|
||||
</floatingview>
|
||||
|
||||
<!-- source view -->
|
||||
|
||||
<floatingview id="source" title="&Source.label;" flex="1">
|
||||
<vbox id="source-view-content" flex="1">
|
||||
<toolbox>
|
||||
<toolbar id="source-header" grippytooltiptext="&SourceHeader.tip;">
|
||||
<label id="source-url" flex="1" crop="left"/>
|
||||
</toolbar>
|
||||
</toolbox>
|
||||
<tree id="source-tree" flex="1" persist="width"
|
||||
onclick="console.views.source.onClick(event);"
|
||||
onselect="console.views.source.onSelect(event);"
|
||||
context="context:source">
|
||||
|
||||
<treecols>
|
||||
<treecol id="source:col-0" width="20px"
|
||||
display="&SourceCol0.display;" persist="hidden width"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol id="source:col-1" width="50px"
|
||||
display="&SourceCol1.display;" persist="hidden width"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol id="source:col-2" flex="1" display=""
|
||||
ignoreincolumnpicker="true" persist="hidden width"/>
|
||||
</treecols>
|
||||
|
||||
<treechildren id="source-tree-body"/>
|
||||
|
||||
</tree>
|
||||
</vbox>
|
||||
</floatingview>
|
||||
|
||||
<!-- stack view -->
|
||||
|
||||
<floatingview id="stack" title="&Stack.label;" flex="1"
|
||||
grippytooltiptext="&Stack.label;">
|
||||
<vbox id="stack-view-content" flex="1">
|
||||
<tree flex="2" id="stack-tree" persist="width" context="context:stack"
|
||||
ondblclick="console.views.stack.onDblClick(event);">
|
||||
|
||||
<treecols>
|
||||
<treecol id="stack:col-0" flex="1" persist="hidden width"
|
||||
label="&StackCol0.header;"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol flex="2" id="stack:col-1" persist="hidden width"
|
||||
label="&StackCol1.header;"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
</treecols>
|
||||
|
||||
<treechildren id="stack-body"/>
|
||||
|
||||
</tree>
|
||||
</vbox>
|
||||
</floatingview>
|
||||
|
||||
<!-- watch view -->
|
||||
|
||||
<floatingview id="watches" title="&Watch.label;" flex="1">
|
||||
<vbox id="watch-view-content" flex="1">
|
||||
<tree flex="1" id="watch-tree" persist="height"
|
||||
ondblclick="console.views.watches.onDblClick(event);"
|
||||
context="context:watches">
|
||||
|
||||
<treecols>
|
||||
<treecol id="watches:col-0" flex="1" persist="hidden width"
|
||||
primary="true" label="&WatchCol0.header;"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol flex="1" id="watches:col-1" persist="hidden width"
|
||||
hidden="true" label="&WatchCol1.header;"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol flex="1" id="watches:col-2" persist="hidden width"
|
||||
label="&WatchCol2.header;"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol flex="1" id="watches:col-3" persist="hidden width"
|
||||
label="&WatchCol3.header;" hidden="true"/>
|
||||
</treecols>
|
||||
|
||||
<treechildren id="watch-body" flex="1"/>
|
||||
|
||||
</tree>
|
||||
</vbox>
|
||||
</floatingview>
|
||||
|
||||
<!-- windows view -->
|
||||
|
||||
<floatingview id="windows" title="&Windows.label;" flex="1">
|
||||
<vbox id="windows-view-content" flex="1">
|
||||
<tree flex="1" id="windows-tree" persist="height"
|
||||
ondblclick="console.views.windows.onDblClick(event);"
|
||||
hidecolumnpicker="true">
|
||||
|
||||
<treecols>
|
||||
<treecol id="windows:col-0" label="&WindowsCol0.label;"
|
||||
primary="true" flex="1" persist="hidden width"/>
|
||||
</treecols>
|
||||
|
||||
<treechildren id="windows-body"/>
|
||||
|
||||
</tree>
|
||||
</vbox>
|
||||
</floatingview>
|
||||
|
||||
</overlaytarget>
|
||||
|
||||
</overlay>
|
||||
@@ -1,74 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<!--
|
||||
-
|
||||
- The contents of this file are subject to the Mozilla Public License
|
||||
- Version 1.1 (the "License"); you may not use this file except in
|
||||
- compliance with the License. You may obtain a copy of the License at
|
||||
- http://www.mozilla.org/MPL/
|
||||
-
|
||||
- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
- for the specific language governing rights and limitations under the
|
||||
- License.
|
||||
-
|
||||
- The Original Code is The JavaScript Debugger
|
||||
-
|
||||
- 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.
|
||||
-
|
||||
- Alternatively, the contents of this file may be used under the
|
||||
- terms of the GNU Public License (the "GPL"), in which case the
|
||||
- provisions of the GPL are applicable instead of those above.
|
||||
- If you wish to allow use of your version of this file only
|
||||
- under the terms of the GPL and not to allow others to use your
|
||||
- version of this file under the MPL, indicate your decision by
|
||||
- deleting the provisions above and replace them with the notice
|
||||
- and other provisions required by the GPL. If you do not delete
|
||||
- the provisions above, a recipient may use your version of this
|
||||
- file under either the MPL or the GPL.
|
||||
-
|
||||
- Contributor(s):
|
||||
- Robert Ginda, <rginda@netscape.com>, original author
|
||||
-
|
||||
-->
|
||||
|
||||
<!DOCTYPE window SYSTEM "chrome://venkman/locale/venkman.dtd">
|
||||
|
||||
<?xml-stylesheet href="chrome://venkman/skin/venkman.css" type="text/css"?>
|
||||
|
||||
<?xul-overlay href="chrome://global/content/globalOverlay.xul"?>
|
||||
<?xul-overlay href="chrome://communicator/content/utilityOverlay.xul"?>
|
||||
|
||||
<?xul-overlay href="chrome://venkman/content/venkman-menus.xul"?>
|
||||
<?xul-overlay href="chrome://venkman/content/venkman-scripts.xul"?>
|
||||
<?xul-overlay href="chrome://venkman/content/venkman-views.xul"?>
|
||||
|
||||
<window id="venkman-window"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="console.onLoad();" onclose="return console.onClose();"
|
||||
onunload="return console.onUnload();"
|
||||
onmouseover="console.onMouseOver(event);"
|
||||
width="640" height="480"
|
||||
persist="width height screenX screenY" title="&MainWindow.title;"
|
||||
windowtype="mozapp:venkman">
|
||||
|
||||
<!-- parents for the command manager-managed objects -->
|
||||
<keyset id="dynamic-keys"/>
|
||||
<popupset id="dynamic-popups"/>
|
||||
|
||||
<overlaytarget id="scripts-overlay-target"/>
|
||||
<overlaytarget id="menu-overlay-target"/>
|
||||
<overlaytarget id="views-overlay-target"/>
|
||||
|
||||
<viewcontainer id="root-container" flex="1" type="horizontal">
|
||||
<viewcontainer id="initial-container" type="vertical" flex="1"/>
|
||||
</viewcontainer>
|
||||
|
||||
<overlaytarget id="statusbar-overlay-target"/>
|
||||
|
||||
</window>
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
// this function verifies disk space in kilobytes
|
||||
function verifyDiskSpace(dirPath, spaceRequired)
|
||||
{
|
||||
var spaceAvailable;
|
||||
|
||||
// Get the available disk space on the given path
|
||||
spaceAvailable = fileGetDiskSpaceAvailable(dirPath);
|
||||
|
||||
// Convert the available disk space into kilobytes
|
||||
spaceAvailable = parseInt(spaceAvailable / 1024);
|
||||
|
||||
// do the verification
|
||||
if(spaceAvailable < spaceRequired)
|
||||
{
|
||||
logComment("Insufficient disk space: " + dirPath);
|
||||
logComment(" required : " + spaceRequired + " K");
|
||||
logComment(" available: " + spaceAvailable + " K");
|
||||
return(false);
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
var srDest = 1;
|
||||
|
||||
var err = initInstall("JavaScript Debugger", "venkman",
|
||||
"prototype_a");
|
||||
|
||||
logComment("initInstall: " + err);
|
||||
|
||||
if (verifyDiskSpace(getFolder("Program"), srDest))
|
||||
{
|
||||
addFile("JavaScript Debugger",
|
||||
"bin/chrome/venkman.jar", // jar source folder
|
||||
getFolder("Chrome"), // target folder
|
||||
""); // target subdir
|
||||
|
||||
registerChrome(PACKAGE | DELAYED_CHROME,
|
||||
getFolder("Chrome","venkman.jar"),
|
||||
"content/venkman/");
|
||||
registerChrome(LOCALE | DELAYED_CHROME, getFolder("Chrome",
|
||||
"venkman.jar"),
|
||||
"locale/en-US/venkman/");
|
||||
registerChrome(SKIN | DELAYED_CHROME, getFolder("Chrome",
|
||||
"venkman.jar"),
|
||||
"skin/modern/venkman/");
|
||||
|
||||
if (err==SUCCESS)
|
||||
performInstall();
|
||||
else
|
||||
cancelInstall(err);
|
||||
}
|
||||
else
|
||||
cancelInstall(INSUFFICIENT_DISK_SPACE);
|
||||
@@ -1,129 +0,0 @@
|
||||
venkman.jar:
|
||||
content/venkman/contents.rdf (content/contents.rdf)
|
||||
locale/en-US/venkman/contents.rdf (locale/en-US/contents.rdf)
|
||||
skin/modern/venkman/contents.rdf (skin/contents.rdf)
|
||||
content/venkman/venkman.xul (content/venkman.xul)
|
||||
content/venkman/venkman-views.xul (content/venkman-views.xul)
|
||||
content/venkman/venkman-floater.xul (content/venkman-floater.xul)
|
||||
content/venkman/venkman-floater.js (content/venkman-floater.js)
|
||||
content/venkman/venkman-bindings.xml (content/venkman-bindings.xml)
|
||||
content/venkman/venkman-menus.xul (content/venkman-menus.xul)
|
||||
content/venkman/venkman-menus.js (content/venkman-menus.js)
|
||||
content/venkman/venkman-scripts.xul (content/venkman-scripts.xul)
|
||||
content/venkman/venkman-utils.js (content/venkman-utils.js)
|
||||
content/venkman/venkman-dev.js (content/venkman-dev.js)
|
||||
content/venkman/venkman-handlers.js (content/venkman-handlers.js)
|
||||
content/venkman/venkman-static.js (content/venkman-static.js)
|
||||
content/venkman/venkman-debugger.js (content/venkman-debugger.js)
|
||||
content/venkman/venkman-profiler.js (content/venkman-profiler.js)
|
||||
content/venkman/venkman-jsdurl.js (content/venkman-jsdurl.js)
|
||||
content/venkman/venkman-url-loader.js (content/venkman-url-loader.js)
|
||||
content/venkman/venkman-commands.js (content/venkman-commands.js)
|
||||
content/venkman/venkman-prefs.js (content/venkman-prefs.js)
|
||||
content/venkman/venkman-eval.js (content/venkman-eval.js)
|
||||
content/venkman/venkman-msg.js (content/venkman-msg.js)
|
||||
content/venkman/venkman-munger.js (content/venkman-munger.js)
|
||||
content/venkman/venkman-views.js (content/venkman-views.js)
|
||||
content/venkman/venkman-records.js (content/venkman-records.js)
|
||||
content/venkman/tree-utils.js (content/tree-utils.js)
|
||||
content/venkman/file-utils.js (content/file-utils.js)
|
||||
content/venkman/html-consts.js (content/html-consts.js)
|
||||
content/venkman/command-manager.js (content/command-manager.js)
|
||||
content/venkman/menu-manager.js (content/menu-manager.js)
|
||||
content/venkman/view-manager.js (content/view-manager.js)
|
||||
content/venkman/tests/testpage.html (content/tests/testpage.html)
|
||||
content/venkman/tests/tree.js (content/tests/tree.js)
|
||||
content/venkman/tests/tree.xul (content/tests/tree.xul)
|
||||
content/venkman/venkman-overlay.xul (content/venkman-overlay.xul)
|
||||
content/venkman/venkman-overlay.js (content/venkman-overlay.js)
|
||||
skin/modern/venkman/venkman.css (skin/venkman.css)
|
||||
locale/en-US/venkman/venkman.dtd (locale/en-US/venkman.dtd)
|
||||
locale/en-US/venkman/venkman.properties (locale/en-US/venkman.properties)
|
||||
locale/en-US/venkman/venkman-overlay.dtd (locale/en-US/venkman-overlay.dtd)
|
||||
locale/en-US/venkman/venkman-help.tpl (locale/en-US/venkman-help.tpl)
|
||||
content/venkman/venkman-output-window.html (content/venkman-output-window.html)
|
||||
content/venkman/profile.csv.tpl (content/profile.csv.tpl)
|
||||
content/venkman/profile.txt.tpl (content/profile.txt.tpl)
|
||||
content/venkman/profile.html.tpl (content/profile.html.tpl)
|
||||
content/venkman/profile.xml.tpl (content/profile.xml.tpl)
|
||||
content/venkman/venkman-output-base.css (content/venkman-output-base.css)
|
||||
skin/modern/venkman/images/clear.png (skin/images/clear.png)
|
||||
skin/modern/venkman/images/shaded.png (skin/images/shaded.png)
|
||||
skin/modern/venkman/images/arrow-left.png (skin/images/arrow-left.png)
|
||||
skin/modern/venkman/images/arrow-right.png (skin/images/arrow-right.png)
|
||||
skin/modern/venkman/images/arrow-up.png (skin/images/arrow-up.png)
|
||||
skin/modern/venkman/images/arrow-down.png (skin/images/arrow-down.png)
|
||||
skin/modern/venkman/images/view-pop-button.png (skin/images/view-pop-button.png)
|
||||
skin/modern/venkman/images/view-close-button.png (skin/images/view-close-button.png)
|
||||
skin/modern/venkman/images/stop.png (skin/images/stop.png)
|
||||
skin/modern/venkman/images/stop-checked.png (skin/images/stop-checked.png)
|
||||
skin/modern/venkman/images/stop-checked-hov.png (skin/images/stop-checked-hov.png)
|
||||
skin/modern/venkman/images/stop-hov.png (skin/images/stop-hov.png)
|
||||
skin/modern/venkman/images/stop-act.png (skin/images/stop-act.png)
|
||||
skin/modern/venkman/images/stop-dis.png (skin/images/stop-dis.png)
|
||||
skin/modern/venkman/images/profile.png (skin/images/profile.png)
|
||||
skin/modern/venkman/images/profile-act.png (skin/images/profile.png)
|
||||
skin/modern/venkman/images/profile-checked.png (skin/images/profile-checked.png)
|
||||
skin/modern/venkman/images/profile-hov.png (skin/images/profile-hov.png)
|
||||
skin/modern/venkman/images/profile-checked-hov.png (skin/images/profile-checked-hov.png)
|
||||
skin/modern/venkman/images/prettyprint.png (skin/images/prettyprint.png)
|
||||
skin/modern/venkman/images/prettyprint-act.png (skin/images/prettyprint.png)
|
||||
skin/modern/venkman/images/prettyprint-checked.png (skin/images/prettyprint-checked.png)
|
||||
skin/modern/venkman/images/prettyprint-hov.png (skin/images/prettyprint-hov.png)
|
||||
skin/modern/venkman/images/prettyprint-checked-hov.png (skin/images/prettyprint-checked-hov.png)
|
||||
skin/modern/venkman/images/cont.png (skin/images/cont.png)
|
||||
skin/modern/venkman/images/cont-hov.png (skin/images/cont-hov.png)
|
||||
skin/modern/venkman/images/cont-act.png (skin/images/cont-act.png)
|
||||
skin/modern/venkman/images/cont-dis.png (skin/images/cont-dis.png)
|
||||
skin/modern/venkman/images/step-into.png (skin/images/step-into.png)
|
||||
skin/modern/venkman/images/step-into-hov.png (skin/images/step-into-hov.png)
|
||||
skin/modern/venkman/images/step-into-act.png (skin/images/step-into-act.png)
|
||||
skin/modern/venkman/images/step-into-dis.png (skin/images/step-into-dis.png)
|
||||
skin/modern/venkman/images/step-over.png (skin/images/step-over.png)
|
||||
skin/modern/venkman/images/step-over-hov.png (skin/images/step-over-hov.png)
|
||||
skin/modern/venkman/images/step-over-act.png (skin/images/step-over-act.png)
|
||||
skin/modern/venkman/images/step-over-dis.png (skin/images/step-over-dis.png)
|
||||
skin/modern/venkman/images/step-out.png (skin/images/step-out.png)
|
||||
skin/modern/venkman/images/step-out-hov.png (skin/images/step-out-hov.png)
|
||||
skin/modern/venkman/images/step-out-act.png (skin/images/step-out-act.png)
|
||||
skin/modern/venkman/images/step-out-dis.png (skin/images/step-out-dis.png)
|
||||
skin/modern/venkman/images/breakpoint-line.gif (skin/images/breakpoint-line.gif)
|
||||
skin/modern/venkman/images/breakpoint-future-line.gif (skin/images/breakpoint-future-line.gif)
|
||||
skin/modern/venkman/images/breakpoint-future.gif (skin/images/breakpoint-future.gif)
|
||||
skin/modern/venkman/images/code-line.gif (skin/images/code-line.gif)
|
||||
skin/modern/venkman/images/code-line-dis.gif (skin/images/code-line-dis.gif)
|
||||
skin/modern/venkman/images/windows.png (skin/images/windows.png)
|
||||
skin/modern/venkman/images/window.png (skin/images/window.png)
|
||||
skin/modern/venkman/images/files.png (skin/images/files.png)
|
||||
skin/modern/venkman/images/stack.png (skin/images/stack.png)
|
||||
skin/modern/venkman/images/breakpoints.png (skin/images/breakpoints.png)
|
||||
skin/modern/venkman/images/breakpoint.png (skin/images/breakpoint.png)
|
||||
skin/modern/venkman/images/file-function.png (skin/images/file-function.png)
|
||||
skin/modern/venkman/images/file-function-bp.png (skin/images/file-function-bp.png)
|
||||
skin/modern/venkman/images/file-function-guess.png (skin/images/file-function-guess.png)
|
||||
skin/modern/venkman/images/file-function-guess-bp.png (skin/images/file-function-guess-bp.png)
|
||||
skin/modern/venkman/images/file-unknown.png (skin/images/file-unknown.png)
|
||||
skin/modern/venkman/images/file-js.png (skin/images/file-js.png)
|
||||
skin/modern/venkman/images/file-html.png (skin/images/file-html.png)
|
||||
skin/modern/venkman/images/file-xul.png (skin/images/file-xul.png)
|
||||
skin/modern/venkman/images/file-xml.png (skin/images/file-xml.png)
|
||||
skin/modern/venkman/images/file-unknown-bp.png (skin/images/file-unknown-bp.png)
|
||||
skin/modern/venkman/images/file-js-bp.png (skin/images/file-js-bp.png)
|
||||
skin/modern/venkman/images/file-html-bp.png (skin/images/file-html-bp.png)
|
||||
skin/modern/venkman/images/file-xul-bp.png (skin/images/file-xul-bp.png)
|
||||
skin/modern/venkman/images/file-xml-bp.png (skin/images/file-xml-bp.png)
|
||||
skin/modern/venkman/images/value-frame.png (skin/images/value-frame.png)
|
||||
skin/modern/venkman/images/value-void.png (skin/images/value-void.png)
|
||||
skin/modern/venkman/images/value-null.png (skin/images/value-null.png)
|
||||
skin/modern/venkman/images/value-bool.png (skin/images/value-bool.png)
|
||||
skin/modern/venkman/images/value-int.png (skin/images/value-int.png)
|
||||
skin/modern/venkman/images/value-double.png (skin/images/value-double.png)
|
||||
skin/modern/venkman/images/value-string.png (skin/images/value-string.png)
|
||||
skin/modern/venkman/images/value-function.png (skin/images/value-function.png)
|
||||
skin/modern/venkman/images/value-object.png (skin/images/value-object.png)
|
||||
skin/modern/venkman/images/current-frame.gif (skin/images/current-frame.gif)
|
||||
skin/modern/venkman/venkman-help.css (skin/venkman-help.css)
|
||||
skin/modern/venkman/venkman-source.css (skin/venkman-source.css)
|
||||
skin/modern/venkman/venkman-output-default.css (skin/venkman-output-default.css)
|
||||
skin/modern/venkman/venkman-output-dark.css (skin/venkman-output-dark.css)
|
||||
skin/modern/venkman/venkman-output-light.css (skin/venkman-output-light.css)
|
||||
@@ -1,59 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<!--
|
||||
-
|
||||
- The contents of this file are subject to the Mozilla Public License
|
||||
- Version 1.1 (the "License"); you may not use this file except in
|
||||
- compliance with the License. You may obtain a copy of the License at
|
||||
- http://www.mozilla.org/MPL/
|
||||
-
|
||||
- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
- for the specific language governing rights and limitations under the
|
||||
- License.
|
||||
-
|
||||
- The Original Code is The JavaScript Debugger
|
||||
-
|
||||
- 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.
|
||||
-
|
||||
- Alternatively, the contents of this file may be used under the
|
||||
- terms of the GNU Public License (the "GPL"), in which case the
|
||||
- provisions of the GPL are applicable instead of those above.
|
||||
- If you wish to allow use of your version of this file only
|
||||
- under the terms of the GPL and not to allow others to use your
|
||||
- version of this file under the MPL, indicate your decision by
|
||||
- deleting the provisions above and replace them with the notice
|
||||
- and other provisions required by the GPL. If you do not delete
|
||||
- the provisions above, a recipient may use your version of this
|
||||
- file under either the MPL or the GPL.
|
||||
-
|
||||
- Contributor(s):
|
||||
- Robert Ginda, <rginda@netscape.com>, original author
|
||||
-
|
||||
-->
|
||||
|
||||
<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
|
||||
|
||||
<!-- list all the packages being supplied by this jar -->
|
||||
<RDF:Seq about="urn:mozilla:locale:root">
|
||||
<RDF:li resource="urn:mozilla:locale:en-US"/>
|
||||
</RDF:Seq>
|
||||
|
||||
<!-- locale information -->
|
||||
<RDF:Description about="urn:mozilla:locale:en-US"
|
||||
chrome:displayName="English(US)"
|
||||
chrome:author="app_author"
|
||||
chrome:name="en-US"
|
||||
chrome:previewURL="http://www.mozilla.org/locales/en-US.gif">
|
||||
<chrome:packages>
|
||||
<RDF:Seq about="urn:mozilla:locale:en-US:packages">
|
||||
<RDF:li resource="urn:mozilla:locale:en-US:venkman"/>
|
||||
</RDF:Seq>
|
||||
</chrome:packages>
|
||||
</RDF:Description>
|
||||
</RDF:RDF>
|
||||
@@ -1,163 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="$css" type="text/css" media="screen">
|
||||
|
||||
<title>Venkman Help System</title>
|
||||
<script>
|
||||
function onLoad ()
|
||||
{
|
||||
var searchStart = document.location.href.indexOf("?");
|
||||
if (searchStart != -1)
|
||||
{
|
||||
var href = document.location.href;
|
||||
var result = parseSearch(href.substr(searchStart + 1));
|
||||
|
||||
if ("search" in result)
|
||||
{
|
||||
document.getElementById("search").value =
|
||||
unescape(result.search);
|
||||
}
|
||||
|
||||
if ("within" in result)
|
||||
{
|
||||
var within = parseInt(result.within);
|
||||
if (within & 0x01)
|
||||
document.getElementById("command-names").checked = true;
|
||||
if (within & 0x02)
|
||||
document.getElementById("ui-labels").checked = true;
|
||||
if (within & 0x04)
|
||||
document.getElementById("help-text").checked = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
document.getElementById("command-names").checked = true;
|
||||
document.getElementById("ui-labels").checked = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
document.getElementById("command-names").checked = true;
|
||||
document.getElementById("ui-labels").checked = true;
|
||||
}
|
||||
}
|
||||
|
||||
function onKeyUp (event)
|
||||
{
|
||||
if (event.keyCode == 13)
|
||||
onSearch();
|
||||
}
|
||||
|
||||
function onSearch ()
|
||||
{
|
||||
var search = document.getElementById("search").value;
|
||||
|
||||
var within = 0;
|
||||
if (document.getElementById("command-names").checked)
|
||||
within |= 0x01;
|
||||
if (document.getElementById("ui-labels").checked)
|
||||
within |= 0x02;
|
||||
if (document.getElementById("help-text").checked)
|
||||
within |= 0x04;
|
||||
|
||||
document.location.href = "x-jsd:help?search=" + escape(search) +
|
||||
"&within=" + within;
|
||||
}
|
||||
|
||||
function parseSearch (search)
|
||||
{
|
||||
var parseResult = new Object();
|
||||
var ary = search.match(/([^&]+)/);
|
||||
|
||||
while (ary)
|
||||
{
|
||||
var rest = RegExp.rightContext.substr(1);
|
||||
var assignment = ary[1];
|
||||
ary = assignment.match(/(.+)=(.*)/);
|
||||
if (ary)
|
||||
{
|
||||
/* only set the property the first time we see it */
|
||||
if (2 in ary && !(ary[1] in parseResult))
|
||||
parseResult[ary[1]] = ary[2];
|
||||
}
|
||||
ary = rest.match(/([^&]+)/);
|
||||
}
|
||||
|
||||
return parseResult;
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body id="venkman-help" onload="onLoad();"
|
||||
hasSearched="$has-searched" matchCount="$match-count">
|
||||
|
||||
<a name="top"></a>
|
||||
<div id="help-menu">
|
||||
<span class="newbie-help">
|
||||
<p>
|
||||
Welcome to the <b>Venkman Help System</b>. From here you can search
|
||||
for help on the various commands avaialble in Venkman. To search for a
|
||||
particular command, type your search term in the box below and click
|
||||
<b>Go</b>, or press <b>Enter</b>.
|
||||
</span>
|
||||
<span class="newbie-help">
|
||||
The check boxes control which fields the search is performed on...
|
||||
<ul>
|
||||
<li><b>Command Names</b> matches the command name, as you might enter
|
||||
it in the </b>Session View</b>.
|
||||
<li><b>User Interface Labels</b> matches the label used when the
|
||||
command appears in a <b>menu</b> or <b>toolbar button</b>.
|
||||
<li><b>Descriptions</b> matches the body of the help text.
|
||||
</ul>
|
||||
</span>
|
||||
<p class="search-input">
|
||||
Search: <input type="text" id="search" onkeyup="onKeyUp(event)"/>
|
||||
<input type="button" onclick="onSearch()" value="Go">
|
||||
|
||||
<input type="checkbox" id="command-names" value="1">
|
||||
<label for="command-names">Command Names</label>
|
||||
|
||||
<input type="checkbox" id="ui-labels" value="1">
|
||||
<label for="ui-labels">User Interface Labels</label>
|
||||
|
||||
<input type="checkbox" id="help-text" value="1">
|
||||
<label for="help-text">Descriptions</label>
|
||||
<p class="quick-searches">
|
||||
[ <a href="x-jsd:help">Session View Commands</a> |
|
||||
<a href="x-jsd:help?search="><b>All</b> Commands</a> |
|
||||
<a href="x-jsd:help?search=%5E%5Ba-c%5D&within=2">A-C</a> |
|
||||
<a href="x-jsd:help?search=%5E%5Bd-f%5D&within=2">D-F</a> |
|
||||
<a href="x-jsd:help?search=%5E%5Bg-i%5D&within=2">G-I</a> |
|
||||
<a href="x-jsd:help?search=%5E%5Bj-l%5D&within=2">J-L</a> |
|
||||
<a href="x-jsd:help?search=%5E%5Bm-o%5D&within=2">M-O</a> |
|
||||
<a href="x-jsd:help?search=%5E%5Bp-r%5D&within=2">P-R</a> |
|
||||
<a href="x-jsd:help?search=%5E%5Bs-u%5D&within=2">S-U</a> |
|
||||
<a href="x-jsd:help?search=%5E%5Bv-z%5D&within=2">V-Z</a> ]
|
||||
</div>
|
||||
|
||||
<span id="match-count">Found $match-count matching command(s).</span>
|
||||
|
||||
<span id="command-list">
|
||||
@-header-end
|
||||
<span class="command">
|
||||
<span class="label" item="command-name">Command Name:</span>
|
||||
<span class="value" item="command-name"><a href="x-jsd:help?search=$command-name">$command-name</a></span><br>
|
||||
<span class="label" item="ui-label">User Interface Label:</span>
|
||||
<span class="value" item="ui-label"><a href="x-jsd:help?search=$ui-label-safe&within=2">$ui-label</a></span><br>
|
||||
<br>
|
||||
<span class="label" item="usage">Usage:</span> <span class="value" item="usage">$command-name $params</span><br>
|
||||
<br>
|
||||
<span class="label" item="accel-key">Accelerator Key:</span> $key<br>
|
||||
<br>
|
||||
<span class="label" item="description">Description:</span><br>
|
||||
<span class="value" item="description">$desc</span>
|
||||
<span class="goto-top"><a href="#top">Back To Top</a></span>
|
||||
</span>
|
||||
<hr>
|
||||
@-command-end
|
||||
<font color="red"><b>No commands found</b></font>
|
||||
@-nomatch-end
|
||||
</span>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,38 +0,0 @@
|
||||
<!--
|
||||
-
|
||||
- The contents of this file are subject to the Mozilla Public License
|
||||
- Version 1.1 (the "License"); you may not use this file except in
|
||||
- compliance with the License. You may obtain a copy of the License at
|
||||
- http://www.mozilla.org/MPL/
|
||||
-
|
||||
- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
- for the specific language governing rights and limitations under the
|
||||
- License.
|
||||
-
|
||||
- The Original Code is The JavaScript Debugger
|
||||
-
|
||||
- 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.
|
||||
-
|
||||
- Alternatively, the contents of this file may be used under the
|
||||
- terms of the GNU Public License (the "GPL"), in which case the
|
||||
- provisions of the GPL are applicable instead of those above.
|
||||
- If you wish to allow use of your version of this file only
|
||||
- under the terms of the GPL and not to allow others to use your
|
||||
- version of this file under the MPL, indicate your decision by
|
||||
- deleting the provisions above and replace them with the notice
|
||||
- and other provisions required by the GPL. If you do not delete
|
||||
- the provisions above, a recipient may use your version of this
|
||||
- file under either the MPL or the GPL.
|
||||
-
|
||||
- Contributor(s):
|
||||
- Robert Ginda, <rginda@netscape.com>, original author
|
||||
-
|
||||
-->
|
||||
|
||||
<!ENTITY venkmanCmd.label "JavaScript Debugger">
|
||||
<!ENTITY venkmanCmd.akey "D">
|
||||
@@ -1,93 +0,0 @@
|
||||
<!--
|
||||
-
|
||||
- The contents of this file are subject to the Mozilla Public License
|
||||
- Version 1.1 (the "License"); you may not use this file except in
|
||||
- compliance with the License. You may obtain a copy of the License at
|
||||
- http://www.mozilla.org/MPL/
|
||||
-
|
||||
- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
- for the specific language governing rights and limitations under the
|
||||
- License.
|
||||
-
|
||||
- The Original Code is The JavaScript Debugger
|
||||
-
|
||||
- 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.
|
||||
-
|
||||
- Alternatively, the contents of this file may be used under the
|
||||
- terms of the GNU Public License (the "GPL"), in which case the
|
||||
- provisions of the GPL are applicable instead of those above.
|
||||
- If you wish to allow use of your version of this file only
|
||||
- under the terms of the GPL and not to allow others to use your
|
||||
- version of this file under the MPL, indicate your decision by
|
||||
- deleting the provisions above and replace them with the notice
|
||||
- and other provisions required by the GPL. If you do not delete
|
||||
- the provisions above, a recipient may use your version of this
|
||||
- file under either the MPL or the GPL.
|
||||
-
|
||||
- Contributor(s):
|
||||
- Robert Ginda, <rginda@netscape.com>, original author
|
||||
-
|
||||
-->
|
||||
|
||||
<!ENTITY MainWindow.title "JavaScript Debugger">
|
||||
|
||||
<!-- help menu -->
|
||||
<!ENTITY Help.commands "Command Reference">
|
||||
<!ENTITY Help.about "About Venkman">
|
||||
|
||||
<!-- toolips -->
|
||||
<!ENTITY Cont.tooltip "Continue debugging">
|
||||
<!ENTITY Stop.tooltip "Stop the current operation">
|
||||
<!ENTITY StepOver.tooltip "Step over statement">
|
||||
<!ENTITY StepIn.tooltip "Step into statement">
|
||||
<!ENTITY StepOut.tooltip "Step out of statement">
|
||||
<!ENTITY DebugBar.tooltip "Debugging Toolbar">
|
||||
<!ENTITY MenuBar.tooltip "Menu Bar">
|
||||
|
||||
<!-- breakpoint view -->
|
||||
<!ENTITY Break.label "Breakpoints">
|
||||
<!ENTITY BreakCol0.label "Name">
|
||||
<!ENTITY BreakCol1.label "Line/PC">
|
||||
|
||||
<!-- locals view -->
|
||||
<!ENTITY Locals.label "Local Variables">
|
||||
<!ENTITY LocalsCol0.header "Name">
|
||||
<!ENTITY LocalsCol1.header "Type">
|
||||
<!ENTITY LocalsCol2.header "Value">
|
||||
<!ENTITY LocalsCol3.header "Flags">
|
||||
|
||||
<!-- session view -->
|
||||
<!ENTITY Session.label "Interactive Session">
|
||||
|
||||
<!-- script view -->
|
||||
<!ENTITY Scripts.label "Loaded Scripts">
|
||||
<!ENTITY ScriptsCol0.header "Name">
|
||||
<!ENTITY ScriptsCol1.header "Line">
|
||||
<!ENTITY ScriptsCol2.header "Length">
|
||||
|
||||
<!-- source view -->
|
||||
<!ENTITY Source.label "Source Code">
|
||||
<!ENTITY SourceHeader.tip "Source Toolbar">
|
||||
<!ENTITY SourceCol0.display "Margin">
|
||||
<!ENTITY SourceCol1.display "Line Number">
|
||||
|
||||
<!-- stack view -->
|
||||
<!ENTITY Stack.label "Call Stack">
|
||||
<!ENTITY StackCol0.header "Name">
|
||||
<!ENTITY StackCol1.header "Location">
|
||||
|
||||
<!-- watch view -->
|
||||
<!ENTITY Watch.label "Watches">
|
||||
<!ENTITY WatchCol0.header "Name">
|
||||
<!ENTITY WatchCol1.header "Type">
|
||||
<!ENTITY WatchCol2.header "Value">
|
||||
<!ENTITY WatchCol3.header "Flags">
|
||||
|
||||
<!-- window view -->
|
||||
<!ENTITY Windows.label "Open Windows">
|
||||
<!ENTITY WindowsCol0.label "File">
|
||||
@@ -1,728 +0,0 @@
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is The JavaScript Debugger
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation
|
||||
# Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation.
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU Public License (the "GPL"), in which case the
|
||||
# provisions of the GPL are applicable instead of those above.
|
||||
# If you wish to allow use of your version of this file only
|
||||
# under the terms of the GPL and not to allow others to use your
|
||||
# version of this file under the MPL, indicate your decision by
|
||||
# deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this
|
||||
# file under either the MPL or the GPL.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Robert Ginda, <rginda@netscape.com>, original author
|
||||
#
|
||||
|
||||
# NOTE ON LEADING/TRAILING SPACES AND QUOTES...
|
||||
# Strings in this file are stripped of leading and trailing qoutes, if they are
|
||||
# present. This allows you to express leading and trailing whitespace, which
|
||||
# would otherwise be trimmed by the stringbundle code. In order to express
|
||||
# a leading or trailing quote, use two of them.
|
||||
#
|
||||
# For example...
|
||||
#
|
||||
# my.message1 = " foo"
|
||||
# my.message2 = " foo
|
||||
# Both of these produce 10 spaces, followed by the word ``foo''.
|
||||
# my.message3 = "foo "
|
||||
# my.message3 = foo "
|
||||
# Both of these produce the word ``foo'', followed by 10 spaces.
|
||||
# my.message4 = A sphincter says, "what?""
|
||||
# my.message4 = "A sphincter says, "what?""
|
||||
# Both of these produce the phrase ``A sphincter says "what?"''
|
||||
#
|
||||
|
||||
msg.locale.version = 0.9.x
|
||||
msg.bad.locale = This version of Venkman is meant to work with a ``%1$S'' locale, but you are currently using a locale marked ``%2$S''. Chances are, you're going to have problems. Please change to the default locale, or upgrade your language pack.
|
||||
|
||||
msg.release.url = http://www.mozilla.org/releases/
|
||||
|
||||
## exception descriptions ##
|
||||
err.notimplemented = Not implemented
|
||||
err.required.param = Missing required parameter %1$S
|
||||
err.invalid.param = Invalid value for parameter %1$S (%2$S)
|
||||
# 1 url, 2 fileName, 3 lineNumber, 4 reason
|
||||
err.subscript.load = Error loading subscript from <%1$S>.
|
||||
err.no.debugger = JS Debugger Service is not installed.
|
||||
err.failure = Operation Failed: %1$S
|
||||
err.no.stack = No Stack
|
||||
|
||||
## error messages ##
|
||||
msn.err.unknown.reason = Unknown reason
|
||||
msn.err.required.param = Missing required parameter %1$S
|
||||
msn.err.invalid.param = Invalid value for parameter %1$S (%2$S)
|
||||
msn.err.invalid.pref = Invalid value for preference %1$S (%2$S)
|
||||
msn.err.scriptload = Error loading subscript from <%1$S>.
|
||||
msn.err.no.source = No scripts loaded match ``%1$S''.
|
||||
msn.err.no.command = No command named ``%1$S''.
|
||||
msn.err.no.such.view = No such view ``%1$S''.
|
||||
msg.err.no.stack = No stack
|
||||
msn.err.noscript = No debuggable scripts found for ``%1$S''
|
||||
msn.err.disabled = Sorry, ``%1$S'' is currently disabled
|
||||
msn.err.notimplemented = Sorry, ``%1$S'' has not been implemented
|
||||
msn.err.ambigcommand = Ambiguous command, ``%1$S'', %2$S commands match [%3$S]
|
||||
msn.err.bp.noline = No scripts matching <%1$S> contain executable code at line %2$S
|
||||
msn.err.bp.nodice = No breakpoint set at <%1$S> line %2$S
|
||||
msn.err.startup = An exception occurred while initializing, please file a bug.\n%1$S
|
||||
msn.err.cant.match = Error loading template: Can't match ``%1$S''.
|
||||
msg.err.internal.bpt = Internal error handling breakpoint.
|
||||
msn.err.internal.hook = Internal error processing hook ``%1$S''.
|
||||
msn.err.failure = Operation Failed: %1$S
|
||||
msn.err.no.section = Missing section before ``%1$S'' in <%2$S>.
|
||||
msn.err.no.template = No pref for template named ``%1$S''.
|
||||
msn.err.internal.dispatch = Internal error dispatching command ``%1$S''.
|
||||
msn.err.source.load.failed = Error loading URL <%1$S>: %2$S.
|
||||
msn.err.no.such.container = No such container ``%1$S''.
|
||||
msg.err.format.not.available = Source not available in requested format.
|
||||
|
||||
msn.jsdurl.errpage = <html><head><title>Error</title></head><body>Error loading <<b>%1$S</b>><br>%2$S</body></html>
|
||||
msg.err.jsdurl.parse = Error parsing URL.
|
||||
msg.err.jsdurl.nosource = URL has no textual source.
|
||||
msg.err.jsdurl.noservice = No such service.
|
||||
msg.err.jsdurl.search = Error in search pattern.
|
||||
msg.err.jsdurl.sourcetext = Error locating source text.
|
||||
msn.err.jsdurl.template = Error loading template named ``%1$S''.
|
||||
|
||||
|
||||
## "values" ##
|
||||
msg.val.unknown = <unknown>
|
||||
msg.val.console = <console>
|
||||
msg.val.na = <not-available>
|
||||
msg.val.none = <none>
|
||||
msg.val.object = <object>
|
||||
msg.val.expression = <expression>
|
||||
msg.val.proto = [[Prototype]]
|
||||
msg.val.parent = [[Parent]]
|
||||
|
||||
## words ##
|
||||
msg.val.min = min
|
||||
msg.val.max = max
|
||||
msg.val.this = this
|
||||
msg.val.breakpoint = breakpoint
|
||||
msg.val.debug = error handler
|
||||
msg.val.debugger = debugger keyword
|
||||
msg.val.throw = thrown exception
|
||||
msg.val.scope = scope
|
||||
msg.val.exception = exception
|
||||
msg.val.on = on
|
||||
msg.val.off = off
|
||||
msg.val.tlscript = __toplevel__
|
||||
msg.val.toscript = [TimeoutScript]
|
||||
msg.val.ivscript = [IntervalScript]
|
||||
msg.val.evscript = [EvalScript]
|
||||
msg.url.native = x-jsd:native-code
|
||||
|
||||
## types ##
|
||||
msg.type.int = integer
|
||||
msg.type.boolean = boolean
|
||||
msg.type.double = double
|
||||
msg.type.function = function
|
||||
msg.type.null = null
|
||||
msg.type.object = object
|
||||
msg.type.string = string
|
||||
msg.type.unknown = unknown
|
||||
msg.type.void = void
|
||||
|
||||
msg.class.xpcobj = XPComponent
|
||||
msg.class.const.xpcobj = const XPComponent
|
||||
msg.class.native.fun = Native Function
|
||||
msg.class.script.fun = Script Function
|
||||
|
||||
## messages ##
|
||||
msg.query.close = Debugging in progress, close anyway?
|
||||
msg.status.default = Welcome to the JavaScript Debugger
|
||||
msn.status.loading = Loading source for ``%1$S''
|
||||
msn.status.marking = Marking source for ``%1$S''
|
||||
msn.status.stopped = Stopped in %1$S, %2$S
|
||||
|
||||
msg.cant.pprint = Unable to Pretty Print this function.
|
||||
|
||||
msg.commasp = , "
|
||||
msn.stop = Stopped for %1$S.
|
||||
msn.cont = Continuing from %1$S.
|
||||
msn.subscript.loaded = Subscript <%1$S> loaded with result ``%2$S''.
|
||||
# 1 exception name, 2 fileName, 3 lineNumber
|
||||
msn.eval.error = %1$S: <%2$S>, line %3$S
|
||||
msn.eval.threw = Caught exception: %1$S
|
||||
msg.hello = Welcome to ``Venkman'', the JavaScript debugger. Please read the FAQ at <http://www.hacksrus.com/~ginda/venkman/faq/venkman-faq.html>. Visit the Venkman homepage <http://www.mozilla.org/projects/venkman/> for more information.
|
||||
msn.version = You are running Venkman version %1$S.
|
||||
msg.tip1.help = Use ``help <command-name>'' for help on specific commands.
|
||||
msg.tip2.help = Visit <x-jsd:help> for a searchable command reference.
|
||||
msg.no.breaks.set = No breakpoints set.
|
||||
msg.no.fbreaks.set = No future breakpoints set.
|
||||
msn.no.properties = %1$S has no properties.
|
||||
msn.no.cmdmatch = No commands match ``%1$S''.
|
||||
msn.cmdmatch = Commands matching ``%1$S'' are [%2$S].
|
||||
msn.cmdmatch.all = Implemented commands are %1$S.
|
||||
msn.props.header = Properties of %1$S in debug target scope:
|
||||
msn.propsd.header = Properties of %1$S in debugger scope:
|
||||
msn.bp.header = %1$S breakpoints set:
|
||||
# 1 index, 2 file name, 3 line
|
||||
msn.bp.line = #%1$S <%2$S> line %3$S
|
||||
msn.bp.created = Breakpoint at <%1$S> line %2$S created
|
||||
msn.bp.cleared = Breakpoint at <%1$S> line %2$S deleted
|
||||
msn.bp.exists = Breakpoint at <%1$S> line %2$S already set.
|
||||
msn.watch.header = %1$S watches set:
|
||||
|
||||
# 1 index, 2 file name, 3 line
|
||||
msn.fbp.line = #%1$S <%2$S> line %3$S
|
||||
msn.fbp.created = Future breakpoint at <%1$S> line %2$S created.
|
||||
msn.fbp.cleared = Future breakpoint at <%1$S> line %2$S cleared.
|
||||
msn.fbp.exists = Future breakpoint at <%1$S> line %2$S already set.
|
||||
msn.source.line = %1$S: %2$S
|
||||
msg.emode.ignore = Errors will now be ignored.
|
||||
msg.emode.trace = Errors will now be traced.
|
||||
msg.emode.break = Errors will now stop the debug target.
|
||||
msg.tmode.ignore = Exceptions will now be ignored.
|
||||
msg.tmode.trace = Exceptions will now be traced.
|
||||
msg.tmode.break = Exceptions will now stop the debug target.
|
||||
msn.iasmode = Initialize at Startup is now %1$S.
|
||||
msn.save.layout = Save Layout on Exit is now %1$S.
|
||||
msn.layout.list = The following layouts have already been saved [%1$S]. Use ``save-layout <name>'' to save the current layout, or ``restore-layout <name>'' to restore a specific layout.
|
||||
msn.chrome.filter = Chrome filtering is now %1$S.
|
||||
# 1 value, 2 frame
|
||||
msn.exception.trace = Exception ``%1$S'' thrown from %2$S.
|
||||
# 1 message, 2 flags, 3 file, 4 line, 5 pos
|
||||
msn.erpt.error = Error ``%1$S'' [%2$S] in file ``%3$S'', line %4$S, character %5$S.
|
||||
msn.erpt.warn = Warning ``%1$S'' [%2$S] in file ``%3$S'', line %4$S, character %5$S.
|
||||
msn.profile.lost = Lost profile data for script %1$S.
|
||||
msn.profile.state = Profile data collection is now %1$S.
|
||||
msn.profile.saved = Profile data saved to <%1$S>.
|
||||
msg.profile.cleared = Profile data cleared.
|
||||
msn.profile.saving = Generating profile report, file %1$S of %2$S
|
||||
msg.open.file = Open File...
|
||||
msg.open.url = Enter a URL to Load...
|
||||
msg.save.profile = Save Profile Data As...
|
||||
msg.save.source = Save Source As...
|
||||
msg.navigator.xul = Navigator Window
|
||||
|
||||
## property value flags ##
|
||||
msg.vf.enumerable = e
|
||||
msg.vf.readonly = r
|
||||
msg.vf.permanent = p
|
||||
msg.vf.alias = A
|
||||
msg.vf.argument = a
|
||||
msg.vf.variable = v
|
||||
msg.vf.error = E
|
||||
msg.vf.exception = X
|
||||
msg.vf.hinted = h
|
||||
|
||||
## formatting ##
|
||||
|
||||
# 1: argument name, 2: value
|
||||
msn.fmt.argument = %1$S=%2$S"
|
||||
# 1: property flags, 2: property name, 3: property value
|
||||
msn.fmt.property = [%1$S] %2$S = %3$S"
|
||||
# 1: function name, 2: filename
|
||||
msn.fmt.script = function %1$S in <%2$S>
|
||||
# 1: function name, 2: arguments, 3: filename, 4: line number
|
||||
msn.fmt.frame = function %1$S(%2$S) in <%3$S> line %4$S
|
||||
# 1: type, 2: class name, 3: value
|
||||
msn.fmt.value.long = [%1$S] [class: %2$S] %3$S"
|
||||
# 1: type, 2: value
|
||||
msn.fmt.value.med = [%1$S] %2$S"
|
||||
# 1: type, 2: value
|
||||
msn.fmt.value.short = %1$S:%2$S"
|
||||
# 1: property count
|
||||
msn.fmt.object = %1$S properties
|
||||
# 1: ctor name, 2: property count
|
||||
msn.fmt.object.value = {%1$S:%2$S}
|
||||
# 1: JS exception name, 2: error text, 3: file name, 4: line number
|
||||
msn.fmt.jsexception = %1$S: %2$S @ <%3$S> %4$S"
|
||||
# 1: error number, 2: error text, 3: file name, 4: line number, 5: function name
|
||||
msn.fmt.badmojo = BadMojo %1$S: %2$S @ <%3$S> line %4$S (%5$S)
|
||||
# 1: var number, 2: value
|
||||
msn.fmt.tmp.assign = $[%1$S] = %2$S"
|
||||
# 1: string length
|
||||
msn.fmt.longstr = %1$S characters
|
||||
# 1: command name 2: parameters
|
||||
msn.fmt.usage = %1$S %2$S
|
||||
# 1: function name
|
||||
msn.fmt.guessedname = [%1$S]
|
||||
# 1: program counter
|
||||
msn.fmt.pc = [%1$S]
|
||||
# 1: pref name 2: value
|
||||
msn.fmt.prefvalue = Preference ``%1$S'' is ``%2$S''
|
||||
# 1: index, 2: label, 3: value
|
||||
msn.fmt.watch.item = %1$S: %2$S = %3$S
|
||||
# 1: on|off
|
||||
msn.fmt.pprint = Pretty Print is %1$S.
|
||||
# 1: frame number, 2: frame string
|
||||
msn.fmt.frame.line = #%1$S: %2$S
|
||||
# 1: file name, 2: line number, 3: pc
|
||||
msn.fmt.frame.location = %1$S, line %2$S, pc %3$S
|
||||
# 1: function name, 2: start line, 3: end line, 4: call count, 5: recurse,
|
||||
# 6: total, 7: min, 8: max, 9: avg
|
||||
msn.fmt.profile.str = %1$S: %2$S-%3$S, %4$S call(s)%5$S, %6$Sms total, %7$Sms max, %8$Sms avg
|
||||
# 1: max recurse depth
|
||||
msn.fmt.profile.recurse = " (max depth %1$S)
|
||||
|
||||
## menu headings ##
|
||||
msg.mnu.file = &File
|
||||
msg.mnu.debug = &Debug
|
||||
msg.mnu.profile = &Profile
|
||||
msg.mnu.view = &View
|
||||
msg.mnu.help = &Help
|
||||
msg.mnu.emode = &Error Trigger
|
||||
msg.mnu.tmode = Throw Tri&gger
|
||||
msg.mnu.showhide = Sho&w/Hide
|
||||
msg.mnu.session.colors = Interactive Session Co&lors
|
||||
msg.mnu.scripts.instance = F&ile Options
|
||||
msg.mnu.scripts.wrapper = Func&tion Options
|
||||
|
||||
msn.sourceheader.url = <%1$S> Line %2$S
|
||||
msn.default.alias.help = This command is an alias for |%1$S|.
|
||||
|
||||
msn.launch.count = Recorded local starutp %1$S, global %2$S.
|
||||
msg.no.help = Help not available.
|
||||
msn.extra.params = Extra parameters ``%1$S'' ignored.
|
||||
msg.files.rec = Files
|
||||
#msg.doc.consolehdr = Console Commands
|
||||
#msg.doc.menuhdr = Menus
|
||||
#msg.doc.popuphdr = Popups
|
||||
#msg.doc.keyhdr = Keys
|
||||
|
||||
msg.note.console = This command is available from the console.
|
||||
msg.note.noconsole = This command is NOT available from the console.
|
||||
msg.note.needstack = You must be stopped at a breakpoint to use this command.
|
||||
msg.note.nostack = You CANNOT be stopped at a breakpoint to use this command.
|
||||
msn.doc.commandlabel = " Command Name: ``%1$S'' (%2$S)
|
||||
msn.doc.key = "Keyboard Shortcut: %1$S
|
||||
msn.doc.syntax = " Syntax: %1$S %2$S
|
||||
msg.doc.notes = Notes:
|
||||
msg.doc.description = Description:
|
||||
|
||||
msn.session.css = Interactive Session now using CSS from <%1$S>.
|
||||
|
||||
msg.source2.help = Please select a source file to display.
|
||||
msg.margin.break = " B "
|
||||
msg.margin.fbreak = " F "
|
||||
msg.margin.breakable = " - "
|
||||
msg.margin.none = " "
|
||||
|
||||
###################### DO NO LOCALIZE THE *.params STRINGS ######################
|
||||
|
||||
## hooks ##
|
||||
|
||||
cmd.hook-break-clear.params = <break-wrapper>
|
||||
cmd.hook-break-clear.help = Called when a breakpoint instance is cleared.
|
||||
|
||||
cmd.hook-break-set.params = <break-wrapper>
|
||||
cmd.hook-break-set.help = Called when a breakpoint instance is set.
|
||||
|
||||
cmd.hook-debug-stop.help = Called when the debugger stops execution of the debug target.
|
||||
|
||||
cmd.hook-debug-continue.help = Called when the debugger continues execution of the debug target.
|
||||
|
||||
cmd.hook-display-sourcetext.params = <source-text> [<target-line> [<details>]]
|
||||
cmd.hook-display-sourcetext.help = Called when the source text object <source-text> should be presented to the user. <target-line> is the line which should appear at or near the top of the display. If <details> is provided, it will be an object representing details about where the <source-text> object was derived from.
|
||||
|
||||
cmd.hook-display-sourcetext-soft.params = <source-text> [<target-line> [<details>]]
|
||||
cmd.hook-display-sourcetext-soft.help = Functions the same as |hook-display-sourcetext|, except the display should not be scrolled if <target-line> is already visible.
|
||||
|
||||
cmd.hook-eval-done.help = Called when an expression is evaluated.
|
||||
|
||||
cmd.hook-fbreak-clear.params = <fbreak>
|
||||
cmd.hook-fbreak-clear.help = Called when a breakpoint instace is cleared.
|
||||
|
||||
cmd.hook-fbreak-set.params = <fbreak>
|
||||
cmd.hook-fbreak-set.help = Called when a breakpoint instace is set.
|
||||
|
||||
cmd.hook-guess-complete.params = <script-instance>
|
||||
cmd.hook-guess-complete.help = Called when function name guessing has completed for the script instance <script-instance>.
|
||||
|
||||
cmd.hook-session-display.params = <message> <msgtype>
|
||||
cmd.hook-session-display.help = Called when a message should be appended to the interactive session display. <message> is the message as a string, or DOM node, <msgtype> is the message's type code.
|
||||
|
||||
cmd.hook-script-manager-created.params = <script-manager>
|
||||
cmd.hook-script-manager-created.help = Called when a new script manager is created. Script managers delegate commands to one or more script-instance objects. <script-manager> will be the new script manager object. Script managers can be found keyed by URL in the |console.scriptManagers| object.
|
||||
|
||||
cmd.hook-script-manager-destroyed.params = <script-manager>
|
||||
cmd.hook-script-manager-destroyed.help = Called after <script-manager> has been removed from the |console.scriptManagers| object. This happens after last contained script-instance is destroyed.
|
||||
|
||||
cmd.hook-script-instance-created.params = <script-instance>
|
||||
cmd.hook-script-instance-created.help = Called when a new script instance is created. Script instances delegate commands to one or more script-wrappers.
|
||||
|
||||
|
||||
cmd.hook-script-instance-sealed.params = <script-instance>
|
||||
cmd.hook-script-instance-sealed.help = Called when <script-instance> is sealed. Script instances are ``sealed'' when the top level function is created. This signifies that the script source has been completely compiled. Any non-function scripts created after this point will appear as a transient in the parent script-manager.
|
||||
|
||||
cmd.hook-script-instance-destroyed.params = <script-instance>
|
||||
cmd.hook-script-instance-destroyed.help = Called when the final script-wrapper contained by <script-instance> is invalidated.
|
||||
|
||||
cmd.hook-source-load-complete.params = <sourceText> <status>
|
||||
cmd.hook-source-load-complete.help = Called when the source text represented by the object <sourceText> is loaded (or reloaded.) <status> indicates the status of the load. A <status> of 0 indicates success, non-zero values indicate a failure.
|
||||
|
||||
cmd.hook-transient-script.params = <script-wrapper>
|
||||
cmd.hook-transient-script.help = Called when a script object that appears to be transient (the result of an eval, setTimeout, etc.) is created by the JavaScript engine.
|
||||
|
||||
cmd.hook-window-closed.params = <window>
|
||||
cmd.hook-window-closed.help = Called when a window object is destroyed. <window> is a reference to the DOM window object for the window.
|
||||
|
||||
cmd.hook-window-loaded.params = <event>
|
||||
cmd.hook-window-loaded.help = Called when a source file is loaded into a window object. <event> is a reference to the DOM event passed to the onLoad handler of the window.
|
||||
|
||||
cmd.hook-window-opened.params = <window>
|
||||
cmd.hook-window-opened.help = Called when a new window object is opened. The source for this window will most likely *not* be loaded at this point. <window> is a reference to the DOM window object for the new window.
|
||||
|
||||
cmd.hook-window-resized.params = <window>
|
||||
cmd.hook-window-resized.help = Called when the man Venkman window or a floating windoe is resized. <window> will be a reference to the window object.
|
||||
|
||||
cmd.hook-window-unloaded.params = <event>
|
||||
cmd.hook-window-unloaded.help = Called when a source file is unloaded from a window object. <event> is a reference to the DOM event passed to the onUnload handler of the window.
|
||||
|
||||
cmd.hook-venkman-exit.help = Called before the debugger exits.
|
||||
|
||||
cmd.hook-venkman-query-exit.help = Called when the debugger would like to exit. A hook function can set |returnValue| on the event to |false| to cancel the exit.
|
||||
|
||||
cmd.hook-venkman-started.help = Called when the debugger first starts up.
|
||||
|
||||
## commands ##
|
||||
|
||||
cmd.about-mozilla.label = &About Mozilla
|
||||
cmd.about-mozilla.help = Display information about your Mozilla installation.
|
||||
|
||||
cmd.break.label = S&et Breakpoint
|
||||
cmd.break.params = [<url-pattern> <line-number>]
|
||||
cmd.break.help = Set a breakpoint in all urls matching <url-pattern> at the line number <line-number>. If no parameters are specified all active breakpoints will be listed. See also: clear.
|
||||
|
||||
cmd.chrome-filter.params = [<toggle>]
|
||||
cmd.chrome-filter.help = Enables or disabled the filtering of chrome: urls. With chrome: filtering on, the JavaScript files which make up the browser will not be displayed in the Script View, and the debugger will not step through them while debugging. The value of <toggle> can be |true|, |on|, |yes|, or |1| to turn the flag on; |false|, |off|, |no|, or |0| to turn it off; or |toggle| to invert the current state. If <toggle> is not provided, the current state will be displayed.
|
||||
|
||||
cmd.clear.label = C&lear Breakpoint
|
||||
cmd.clear.params = <url-pattern> [<line-number>]
|
||||
cmd.clear.help = Clears breakpoints in files which match <url-pattern>. If <line-number> is provided, only breakpoints at that line will be cleared.
|
||||
|
||||
cmd.clear-all.label = Clear &All Breakpoints
|
||||
cmd.clear-all.help = Clears every breakpoint currently defined.
|
||||
|
||||
cmd.clear-break.label = &Clear Breakpoint(s)
|
||||
cmd.clear-break.params = <break-wrapper> [<...>]
|
||||
cmd.clear-break.help = Clear the breakpoint wrapped by <break-wrapper>. If <break-wrapper> is a future breakpoint object, all child breakpoints will be cleared, but the future breakpoint will remain.
|
||||
|
||||
cmd.clear-fbreak.label = Clear &Future Breakpoint(s)
|
||||
cmd.clear-fbreak.params = <break-wrapper> [<...>]
|
||||
cmd.clear-fbreak.help = Clear the future breakpoint wrapped by <break-wrapper>. If <break-wrapper> is a breakpoint instance object, the instance's parent future breakpoint will be cleared, but the instance will remain. If the instance has no parent future breakpoint, the wrapper will be ignored.
|
||||
|
||||
cmd.clear-profile.label = C&lear Profile Data
|
||||
cmd.clear-profile.help = Zeros out any existing profile data.
|
||||
|
||||
cmd.clear-script.label = &Clear Script Breakpoint(s)
|
||||
cmd.clear-script.params = <script-wrapper> [<...>]
|
||||
cmd.clear-script.help = Clear all breakpoints in the script wrapped by <script-wrapper>.
|
||||
|
||||
cmd.close.label = &Close
|
||||
cmd.close.key = accel W
|
||||
cmd.close.help = Close the debugger.
|
||||
|
||||
cmd.commands.params = [<pattern>]
|
||||
cmd.commands.help = Lists all command names matching <pattern>, or all command names if pattern is not specified.
|
||||
|
||||
cmd.cont.label = &Continue
|
||||
cmd.cont.key = VK_F5
|
||||
cmd.cont.help = Continue execution of the debug target.
|
||||
|
||||
cmd.debug-script.label = Don't &Debug
|
||||
cmd.debug-script.params = <toggle> <script-wrapper> [<...>]
|
||||
cmd.debug-script.help = Enable or disable debugging in the script wrapper <script-wrapper>. While debugging is disabled, Venkman will *not* stop in the disabled scripts. The value of <toggle> can be |true|, |on|, |yes|, or |1| to turn the flag on; |false|, |off|, |no|, or |0| to turn it off; or |toggle| to invert the current state.
|
||||
|
||||
cmd.debug-instance-on.label = &Don't Debug Contained Functions
|
||||
cmd.debug-instance-on.params = <script-instance> [<...>]
|
||||
cmd.debug-instance-on.help = Disable debugging in all functions contained by the script instance <script-instance>.
|
||||
|
||||
cmd.debug-instance-off.label = D&ebug Contained Functions
|
||||
cmd.debug-instance-off.params = <script-instance> [<...>]
|
||||
cmd.debug-instance-off.help = Enable debugging in all functions contained by the script instance <script-instance>.
|
||||
|
||||
cmd.debug-instance.label = &Toggle Debugging Contained Functions
|
||||
cmd.debug-instance.params = <toggle> <script-instance> [<...>]
|
||||
cmd.debug-instance.help = Enable or disable debugging in all functions contained by the script instance <script-instance>. While debugging is disabled, Venkman will *not* stop in the disabled scripts. The value of <toggle> can be |true|, |on|, |yes|, or |1| to turn the flag on; |false|, |off|, |no|, or |0| to turn it off; or |toggle| to invert the current state. If <toggle> is not provided, the current state will be displayed.
|
||||
|
||||
cmd.debug-transient.label = Don't Debug Eval/Ti&meouts
|
||||
cmd.debug-transient.params = <toggle> <url> [<...>]
|
||||
cmd.debug-transient.help = Enable or disable debugging of transient scripts (like setTimeout() or eval()) associated with the url <url>. The value of <toggle> can be |true|, |on|, |yes|, or |1| to turn the flag on; |false|, |off|, |no|, or |0| to turn it off; or |toggle| to invert the current state.
|
||||
|
||||
cmd.dumpprofile.label = Dump Profile Data
|
||||
cmd.dumpprofile.params = [<file-name>]
|
||||
|
||||
cmd.dumptree.params = <tree> [<depth>]
|
||||
|
||||
cmd.emode.params = [<mode>]
|
||||
cmd.emode.help = Sets what action the debugger should take when an error occurs in the debug target. |emode ignore| ignores all errors, |emode trace| shows a log of the error in the console, and |emode break| stops excecution when an error is thrown. |emode| without any parameter will display the current error mode. Note that |emode| controls what happens whan an exception goes uncaught, to control what happens when an exception is *thrown*, use |tmode|.
|
||||
|
||||
cmd.eval.params = <script-text>
|
||||
cmd.eval.help = Evaluates <script-text> in the scope of the debug target's current frame. See also: |frame|, |where|, |props|, and |evald|.
|
||||
|
||||
cmd.evald.params = <script-text>
|
||||
cmd.evald.help = Evaluates <script-text> in the debugger's scope. See also: |eval|.
|
||||
|
||||
cmd.em-break.label = Stop for E&rrors
|
||||
cmd.em-cycle.label = Cycle Error Mode
|
||||
cmd.em-cycle.key = accel shift E
|
||||
cmd.em-ignore.label = Ig&nore Errors
|
||||
cmd.em-trace.label = Tr&ace Errors
|
||||
|
||||
cmd.fbreak.label = Set &Future Breakpoint
|
||||
cmd.fbreak.params = [<url-pattern> <line-number>]
|
||||
cmd.fbreak.help = Sets a ``future'' breakpoint. Any time a script whose file name matches <url-pattern> is loaded, a breakpoint a <line-number> is set. Setting a breakpoint at line 1 will cause the debugger to break when the script is loaded. fbreak with no parameters will list all future breakponts. This command is the same as |set-fbreak|, except the parameters are optional. See also: |break|.
|
||||
|
||||
cmd.set-fbreak.label = Set &Future Breakpoint
|
||||
cmd.set-fbreak.params = <url-pattern> <line-number>
|
||||
cmd.set-fbreak.help = Sets a ``future'' breakpoint. Any time a script whose file name matches <url-pattern> is loaded, a breakpoint a <line-number> is set. Setting a breakpoint at line 1 will cause the debugger to break when the script is loaded. This command is the same as |fbreak|, except the parameters are not optional. See also: |break|.
|
||||
|
||||
cmd.fclear.label = Clear F&uture Breakpoint
|
||||
cmd.fclear.params = <url-pattern> [<line-number>]
|
||||
cmd.fclear.help = Clears the future breakpoint(s) set for <url-pattern>. If <line-number> is specified, only future breakpoints at that line are cleared.
|
||||
|
||||
cmd.fclear-all.label = Clear All Fu&ture Breakpoints
|
||||
cmd.fclear-all.help = Clears all future breakpoints currently defined.
|
||||
|
||||
cmd.find-bp.label = Find &Breakpoint
|
||||
cmd.find-bp.params = <breakpoint>
|
||||
cmd.find-bp.help = Focus the breakpoint specified by the Breakpoint object <breakpoint>.
|
||||
|
||||
cmd.find-creator.label = Find &Creator
|
||||
cmd.find-creator.params = <jsd-value>
|
||||
cmd.find-creator.help = Focus the creator of the object referenced by the jsdIValue <jsd-value>.
|
||||
|
||||
cmd.find-ctor.label = Find C&onstructor
|
||||
cmd.find-ctor.params = <jsd-value>
|
||||
cmd.find-ctor.help = Focus the constructor of the object referenced by the jsdIValue <jsd-value>.
|
||||
|
||||
cmd.find-file.label = &Open File...
|
||||
cmd.find-file.key = accel O
|
||||
cmd.find-file.params = [<file-name>]
|
||||
cmd.find-file.help = Displays the contents of the file located at <file-name> in the script view, where <file-name> is an operating system specific path string. If <file-name> is not provided, or is the character '?', a file chooser widget will be displayed.
|
||||
|
||||
cmd.find-frame.label = Find &Frame Source
|
||||
cmd.find-frame.params = <frame-index>
|
||||
cmd.find-frame.help = Focus the stack frame specified by the frame at index <frame-index>.
|
||||
|
||||
cmd.find-script.label = Find F&unction
|
||||
cmd.find-script.params = <script-wrapper> [<target-pc>]
|
||||
cmd.find-script.help = Focus the script wrapped by <script-wrapper>. If <target-pc> is provided, the view will be scrolled to display the associated line.
|
||||
|
||||
cmd.find-sourcetext.params = <source-text> [<range-start> [<range-end> [<details> [<target-line>]]]]
|
||||
cmd.find-sourcetext.help = Displays the source text object <sourceText>. All of the text between <range-start> and <range-end> will be highlighted. If <details> is provided, it will be an object representing details about where the <source-text> object was derived from. If <target-line> is provided, the view will be scrolled to that line, otherwise the view will be scrolled to <range-start>.
|
||||
|
||||
cmd.find-sourcetext-soft.params = <source-text> [<range-start> [<range-end> [<details> [<target-line>]]]]
|
||||
cmd.find-sourcetext-soft.help = Functions the same as |find-sourcetext|, except the view is not scrolled if <target-line> is already visible.
|
||||
|
||||
cmd.find-scriptinstance.label = &Find Script Instance
|
||||
cmd.find-scriptinstance.params = <script-instance> [<range-start> [<range-end> [<details> [<target-line>]]]]
|
||||
cmd.find-scriptinstance.help = Displays the source text associated with the script instance <script-instance>. All of the text between <range-start> and <range-end> will be highlighted. If <details> is provided, it will be an object representing details about where the <url> object was derived from. If <target-line> is provided, the view will be scrolled to that line, otherwise the view will be scrolled to <range-start>.
|
||||
|
||||
cmd.find-url.label = &Find URL
|
||||
cmd.find-url.params = <url> [<range-start> [<range-end> [<details> [<target-line>]]]]
|
||||
cmd.find-url.help = Displays the contents of the URL <url> in the source view. All of the text between <range-start> and <range-end> will be highlighted. If <details> is provided, it will be an object representing details about where the <url> object was derived from. If <target-line> is provided, the view will be scrolled to that line, otherwise the view will be scrolled to <range-start>.
|
||||
|
||||
cmd.find-url-soft.label = &Soft Focus URL
|
||||
cmd.find-url-soft.params = <url> [<range-start> [<range-end> [<details> [<target-line>]]]]
|
||||
cmd.find-url-soft.help = Functions the same as |find-sourcetext|, except the view is not scrolled if <target-line> is already visible.
|
||||
|
||||
cmd.finish.label = S&tep Out
|
||||
cmd.finish.key = shift VK_F11
|
||||
cmd.finish.help = Execute until the current stack frame returns.
|
||||
|
||||
cmd.focus-input.key = VK_ESCAPE
|
||||
cmd.focus-input.help = Places focus in the console's text input widget.
|
||||
|
||||
cmd.frame.label = Set &Current Frame
|
||||
cmd.frame.params = [<frame-index>]
|
||||
cmd.frame.help = Sets the current frame to the one numbered <frame-index>, and displays a summary of the frame. If <frame-index> is not provided, a summary of the current frame will be displayed. Use the where command to list available frames and frame numbers.
|
||||
|
||||
cmd.help.label = &Command Reference
|
||||
cmd.help.params = [<pattern>]
|
||||
cmd.help.help = Displays help on <pattern>, which can be a full command name, or the first few characters of the command name. If <pattern> matches more than one command, help on all matching commands will be displayed. If <pattern> is not provided, a command reference will be loaded in a browser window.
|
||||
|
||||
cmd.loadd.label = Load Script in Debugger Scope
|
||||
cmd.loadd.params = <url>
|
||||
cmd.loadd.help = Executes the contents of the url specified by <url> in the context of the debugger. Useful for loading debugger plugins. See also: The |initialScripts| pref.
|
||||
|
||||
cmd.move-view.params = <view-id> <location-url>
|
||||
cmd.move-view.help = Moves the view associated with <view-id> to the location specified by <location-url>.
|
||||
|
||||
cmd.mozilla-help.label = &Help Contents
|
||||
cmd.mozilla-help.help = Display the table of contents for the Mozilla help system.
|
||||
|
||||
cmd.next.label = Step &Over
|
||||
cmd.next.key = VK_F10
|
||||
cmd.next.help = Executes the next line of script. If a function call is encountered it is traced as a single instruction.
|
||||
|
||||
cmd.open-dialog.params = <url> [<window-name> [<window-flags>]]
|
||||
cmd.open-dialog.help = Opens a dialog window and loads the source from <url>. This is typically used to open a new XUL window, though it can be used to load a web page without chrome.
|
||||
|
||||
cmd.open-url.help = Prompts the user for a url to load in the source view.
|
||||
cmd.open-url.label = Open Web &Location...
|
||||
cmd.open-url.key = accel shift L
|
||||
|
||||
cmd.pprint.params = [<toggle>]
|
||||
cmd.pprint.help = Set or display the state of Pretty Print mode. The value of <toggle> can be |true|, |on|, |yes|, or |1| to turn the flag on; |false|, |off|, |no|, or |0| to turn it off; or |toggle| to invert the current state. If <toggle> is not provided, the current state will be displayed.
|
||||
|
||||
cmd.pref.params = [<pref-name> [<pref-value>]]
|
||||
cmd.pref.help = Sets the value of the preference named <pref-name> to the value of <pref-value>. If <pref-value> is not provided, the current value of <pref-name> will be displayed. If both <pref-name> and <pref-value> are omitted, all preferences will be displayed.
|
||||
|
||||
cmd.profile.params = [<toggle>]
|
||||
cmd.profile.help = Enables or disables the collection of profile data. The value of <toggle> can be |true|, |on|, |yes|, or |1| to turn the flag on; |false|, |off|, |no|, or |0| to turn it off; or |toggle| to invert the current state. If <toggle> is not provided, the current state will be displayed.
|
||||
|
||||
cmd.profile-script.label = Don't &Profile
|
||||
cmd.profile-script.params = <toggle> <script-wrapper> [<...>]
|
||||
cmd.profile-script.help = Enable or disable profiling the script <script-wrapper>. While profiling is disabled, data will be discarded. The value of <toggle> can be |true|, |on|, |yes|, or |1| to turn the flag on; |false|, |off|, |no|, or |0| to turn it off; or |toggle| to invert the current state. If <toggle> is not provided, the current state will be displayed.
|
||||
|
||||
cmd.profile-instance.label = Toggle Profilin&g Contained Functions
|
||||
cmd.profile-instance.params = <toggle> <script-instance> [<...>]
|
||||
cmd.profile-instance.help = Enable or disable profiling in all functions contained by the script instance <script-instance>. While profiling is disabled, data will be discarded. The value of <toggle> can be |true|, |on|, |yes|, or |1| to turn the flag on; |false|, |off|, |no|, or |0| to turn it off; or |toggle| to invert the current state. If <toggle> is not provided, the current state will be displayed.
|
||||
|
||||
cmd.profile-instance-on.label = Don't &Profile Contained Functions
|
||||
cmd.profile-instance-on.params = <script-instance> [<...>]
|
||||
cmd.profile-instance-on.help = Disable profiling in all functions contained by the script instance <script-instance>.
|
||||
|
||||
cmd.profile-instance-off.label = Profile &Contained Functions
|
||||
cmd.profile-instance-off.params = <script-instance> [<...>]
|
||||
cmd.profile-instance-off.help = Enable profiling in all functions contained by the script instance <script-instance>.
|
||||
|
||||
cmd.profile-tb.label = Profile
|
||||
|
||||
cmd.props.params = <script-text>
|
||||
cmd.props.help = Lists the properties of the value returned by <script-text>. The expression is evaluated in the scope of the debug target's current frame. See also: |where|, |frame|, |eval|, and |propsd|.
|
||||
|
||||
cmd.propsd.params = <script-text>
|
||||
cmd.propsd.help = Lists the properties of the value returned by <script-text>. The expression is evaluated in the debugger's scope. See also: |props|.
|
||||
|
||||
cmd.quit.label = &Quit
|
||||
cmd.quit.key = accel Q
|
||||
cmd.quit.help = Quit Mozilla.
|
||||
|
||||
cmd.reload-source-tab.label = &Reload Source
|
||||
cmd.reload-source-tab.params = [<index>]
|
||||
cmd.reload-source-tab.key = accel R
|
||||
cmd.reload-source-tab.help = Reload the source in the tab located at the index specified by <index>. If <index> is not provided, the current tab will be reloaded.
|
||||
|
||||
cmd.release-notes.label = &Release Notes
|
||||
cmd.release-notes.help = Display the Mozilla release notes.
|
||||
|
||||
cmd.close-source-tab.label = &Close Tab
|
||||
cmd.close-source-tab.params = [<index>]
|
||||
cmd.close-source-tab.help = Close the tab located at the index specified by <index>. If <index> is not provided, the current tab will be closed.
|
||||
|
||||
cmd.restore-layout.params = [<name>]
|
||||
cmd.restore-layout.help = Restores the view layout named <name>. If <name> is not provided, the list of available layouts will be displayed. The special name |factory| can be used to restore a default layout.
|
||||
|
||||
cmd.reloadui.key = accel alt R
|
||||
|
||||
cmd.save-default-layout.label = &Save Default Layout Now
|
||||
|
||||
cmd.save-layout.params = [<name>]
|
||||
cmd.save-layout.help = Saves the current window layout, giving it the name <name>. The layout can be restored later with the |restore-layout| command. If <name> is not provided, the list of available layouts will be displayed. Save to the name ``default'' to set the default layout Venkman restores on startup. The ``factory'' layout cannot be overwritten.
|
||||
|
||||
cmd.save-source-tab.label = &Save Source As...
|
||||
cmd.save-source-tab.params = [<index> [<target-file>]]
|
||||
cmd.save-source-tab.key = accel S
|
||||
cmd.save-source-tab.help = Saves the contents of the source file displayed in the tab at the position specified by <index> to a file on the local system. If <index> is not provided, the current tab is saved. If <target-file> is not provided, or is the character '?', a file chooser widget will be displayed. <target-file> is an operating system specific path string.
|
||||
|
||||
cmd.save-profile.label = Save P&rofile Data As...
|
||||
cmd.save-profile.params = [<target-file> [<url> [<...>]]
|
||||
cmd.save-profile.help = Saves the profile data collected for one or more source files specified by <url> into the file at <target-file>. If <target-file> is not provided, or is the character '?', a file chooser widget will be displayed. If <url> is not provided, all profile data is saved. <target-file> is an operating system specific path string, <url> is a complete url.
|
||||
|
||||
cmd.session-css.params = [<css>]
|
||||
cmd.session-css.help = Sets the current CSS file used to style the Interactive Session. The value of <css> can be the text "default", "dark", or "light" OR a url to the CSS file to use. The "default" css uses your browser defaults as foreground and background colors, "dark" is dark background in light text, and "light" is light background with dark text. If <css> is not provided, the current value is printed.
|
||||
|
||||
cmd.session-css-default.label = &Browser Defaults
|
||||
cmd.session-css-dark.label = &Dark Background/Light Text
|
||||
cmd.session-css-light.label = &Light Background/Dark Text
|
||||
|
||||
cmd.scope.help = Lists the properties of the topmost object in the scope chain for the current frame.
|
||||
|
||||
cmd.startup-init.label = Initialize at &Startup
|
||||
cmd.startup-init.params = [<toggle>]
|
||||
cmd.startup-init.help = Sets the state of the "Initialize at Startup" feature. With this feature enabled, the debugger will begin tracking scripts when the browser is first started, instead of waiting until the user interface is launched. This will allow the script list to display files that were loaded before you started the debugger user interface. This feature incurrs a *slight* performance hit, and so it is off by default. The value of <toggle> can be |true|, |on|, |yes|, or |1| to turn the flag on; |false|, |off|, |no|, or |0| to turn it off; or |toggle| to invert the current state. If <toggle> is not provided, the current state will be displayed.
|
||||
|
||||
cmd.source-coloring.label = Colori&ze Source
|
||||
cmd.source-coloring.params = [<toggle>]
|
||||
cmd.source-coloring.help = Enables or disables the source code coloring feature in the Source Code view. When working with large files, or on a slow machine, source coloring may take too long to be practical. Turning off source coloring will make files load much faster. You will need to reload the source code to see the effect of changing this setting. If <toggle> is not provided, the current state will be displayed.
|
||||
|
||||
cmd.stop.label = Sto&p
|
||||
cmd.stop.key = VK_F4
|
||||
cmd.stop.help = Stop before the next line of code is executed.
|
||||
|
||||
cmd.step.label = Step &Into
|
||||
cmd.step.key = VK_F11
|
||||
cmd.step.help = Executes the next line of script and stops.
|
||||
|
||||
cmd.testargs.params = <int> <word> [<word2> <word3>]
|
||||
cmd.testargs.help = Function for testing argument parsing. Pass it what it wants, and it'll spit out the event object to stdout.
|
||||
|
||||
cmd.testargs1.params = <int> [<...>]
|
||||
cmd.testargs1.help = Function for testing argument parsing. Pass it what it wants, and it'll spit out the event object to stdout.
|
||||
|
||||
cmd.tmode.params = [<mode>]
|
||||
cmd.tmode.help = Sets what action the debugger should take when an exception is thrown from the debug target. |tmode ignore| ignores all exceptions, |tmode trace| shows a log of the exception to the console, and |tmode break| stops excecution when an exception is thrown. |tmode| without any parameter will display the current throw mode. Note that |tmode| controls what happens whan an exception is *thrown*, to control what happens when an exception reaches the top level and becomes an error, use |emode|. The key combination Control + T can be used to cycle the throw mode.
|
||||
|
||||
cmd.tm-break.label = Stop for &Exceptions
|
||||
cmd.tm-cycle.label = Cycle Exception Mode
|
||||
cmd.tm-cycle.key = accel T
|
||||
cmd.tm-ignore.label = I&gnore Exceptions
|
||||
cmd.tm-trace.label = T&race Exceptions
|
||||
|
||||
cmd.toggle-float.params = <view-id>
|
||||
cmd.toggle-float.help = If the view specified by <view-id> is currently displayed in the main window, or is not visible, it will be placed in a new floating window. If <view-id> is already in a floating window, it will be placed back in the main window.
|
||||
|
||||
cmd.toggle-pprint.label = &Pretty Print
|
||||
cmd.toggle-pprint.key = accel P
|
||||
cmd.toggle-pprint.help = Toggle Pretty Print mode.
|
||||
|
||||
cmd.toggle-save-layout.label = Save Default Layout On &Exit
|
||||
cmd.toggle-save-layout.help = If set, the window layout will be saved before Venkman exits.
|
||||
|
||||
cmd.toggle-view.params = <view-id>
|
||||
cmd.toggle-view.help = If the view specified by <view-id> is currently displayed, it will be hidden. Otherwise the view will be displayed in its last known location.
|
||||
|
||||
cmd.toggle-chrome.label = E&xclude Browser Files
|
||||
cmd.toggle-profile.label = &Collect Profile Data
|
||||
|
||||
cmd.toggle-breaks.label = &Breakpoints
|
||||
cmd.toggle-stack.label = &Call Stack
|
||||
cmd.toggle-session.label = &Interactive Session
|
||||
cmd.toggle-locals.label = &Local Variables
|
||||
cmd.toggle-scripts.label = Loaded S&cripts
|
||||
cmd.toggle-windows.label = &Open Windows
|
||||
cmd.toggle-source.label = Source Code (old)
|
||||
cmd.toggle-source2.label = So&urce Code (new)
|
||||
cmd.toggle-watches.label = &Watches
|
||||
|
||||
cmd.version.label = About &Venkman
|
||||
cmd.version.help = Display version information.
|
||||
|
||||
cmd.remove-watch.label = &Remove Watch(es)
|
||||
cmd.remove-watch.params = <index> [<...>]
|
||||
cmd.remove-watch.help = Removes the watch(es) at the 0 based index specified by <index>.
|
||||
|
||||
cmd.watch-expr.params = [<expression>]
|
||||
cmd.watch-expr.help = Evaluates <expression> in the debug target scope and adds the result to the watch window. If <expression> is not provided, all watches are printed to the console.
|
||||
|
||||
cmd.watch-exprd.params = [<expression>]
|
||||
cmd.watch-exprd.help = Evaluates <expression> in the debugger scope and adds the result to the watch window. If <expression> is not provided, all watches are printed to the console.
|
||||
|
||||
cmd.watch-property.params = <jsd-value> <property-name>
|
||||
cmd.watch-property.help = Adds the property named <property-name> of the object stored in <jsd-value> to the watch window.
|
||||
|
||||
cmd.where.label = Dump &Stack to Interactive Session
|
||||
cmd.where.help = Displays a summarized list of stack frames in the current call chain.
|
||||
@@ -1,39 +0,0 @@
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is The JavaScript Debugger
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation
|
||||
# Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation.
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU Public License (the "GPL"), in which case the
|
||||
# provisions of the GPL are applicable instead of those above.
|
||||
# If you wish to allow use of your version of this file only
|
||||
# under the terms of the GPL and not to allow others to use your
|
||||
# version of this file under the MPL, indicate your decision by
|
||||
# deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this
|
||||
# file under either the MPL or the GPL.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Robert Ginda, <rginda@netscape.com>, original author
|
||||
#
|
||||
|
||||
DEPTH = ..\..\..
|
||||
|
||||
include <$(DEPTH)\config\config.mak>
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<!--
|
||||
-
|
||||
- The contents of this file are subject to the Mozilla Public License
|
||||
- Version 1.1 (the "License"); you may not use this file except in
|
||||
- compliance with the License. You may obtain a copy of the License at
|
||||
- http://www.mozilla.org/MPL/
|
||||
-
|
||||
- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
- for the specific language governing rights and limitations under the
|
||||
- License.
|
||||
-
|
||||
- The Original Code is The JavaScript Debugger
|
||||
-
|
||||
- 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.
|
||||
-
|
||||
- Alternatively, the contents of this file may be used under the
|
||||
- terms of the GNU Public License (the "GPL"), in which case the
|
||||
- provisions of the GPL are applicable instead of those above.
|
||||
- If you wish to allow use of your version of this file only
|
||||
- under the terms of the GPL and not to allow others to use your
|
||||
- version of this file under the MPL, indicate your decision by
|
||||
- deleting the provisions above and replace them with the notice
|
||||
- and other provisions required by the GPL. If you do not delete
|
||||
- the provisions above, a recipient may use your version of this
|
||||
- file under either the MPL or the GPL.
|
||||
-
|
||||
- Contributor(s):
|
||||
- Robert Ginda, <rginda@netscape.com>, original author
|
||||
-
|
||||
-->
|
||||
|
||||
<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
|
||||
|
||||
<RDF:Seq about="urn:mozilla:skin:root">
|
||||
<RDF:li resource="urn:mozilla:skin:modern/1.0" />
|
||||
</RDF:Seq>
|
||||
|
||||
<!-- skin information -->
|
||||
<RDF:Description about="urn:mozilla:skin:modern/1.0"
|
||||
chrome:displayName="Modern"
|
||||
chrome:author="mozilla.org"
|
||||
chrome:name="modern/1.0">
|
||||
<chrome:packages>
|
||||
<RDF:Seq about="urn:mozilla:skin:modern/1.0:packages">
|
||||
<RDF:li resource="urn:mozilla:skin:modern/1.0:venkman"/>
|
||||
</RDF:Seq>
|
||||
</chrome:packages>
|
||||
</RDF:Description>
|
||||
</RDF:RDF>
|
||||
|
Before Width: | Height: | Size: 318 B |
|
Before Width: | Height: | Size: 319 B |
|
Before Width: | Height: | Size: 324 B |
|
Before Width: | Height: | Size: 319 B |
|
Before Width: | Height: | Size: 158 B |
|
Before Width: | Height: | Size: 82 B |
|
Before Width: | Height: | Size: 110 B |