/*
- * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
#include "CallFrame.h"
#include "JSObject.h"
+#include "VirtualRegister.h"
+
#include <wtf/PrintStream.h>
#include <wtf/Vector.h>
namespace JSC {
-// argument 0 is 'this'.
-inline bool operandIsArgument(int operand) { return operand < 0; }
-inline int operandToArgument(int operand) { return -operand + CallFrame::thisArgumentOffset(); }
-inline int argumentToOperand(int argument) { return -argument + CallFrame::thisArgumentOffset(); }
-
template<typename T> struct OperandValueTraits;
template<typename T>
struct OperandValueTraits {
static T defaultValue() { return T(); }
- static void dump(const T& value, PrintStream& out) { value.dump(out); }
+ static bool isEmptyForDump(const T& value) { return !value; }
};
enum OperandKind { ArgumentOperand, LocalOperand };
-template<typename T, typename Traits = OperandValueTraits<T> >
+enum OperandsLikeTag { OperandsLike };
+
+template<typename T, typename Traits = OperandValueTraits<T>>
class Operands {
public:
Operands() { }
m_locals.fill(Traits::defaultValue(), numLocals);
}
+ template<typename U, typename OtherTraits>
+ explicit Operands(OperandsLikeTag, const Operands<U, OtherTraits>& other)
+ {
+ m_arguments.fill(Traits::defaultValue(), other.numberOfArguments());
+ m_locals.fill(Traits::defaultValue(), other.numberOfLocals());
+ }
+
size_t numberOfArguments() const { return m_arguments.size(); }
size_t numberOfLocals() const { return m_locals.size(); }
T& operand(int operand)
{
if (operandIsArgument(operand)) {
- int argument = operandToArgument(operand);
+ int argument = VirtualRegister(operand).toArgument();
return m_arguments[argument];
}
-
- return m_locals[operand];
+
+ return m_locals[VirtualRegister(operand).toLocal()];
}
-
+
+ T& operand(VirtualRegister virtualRegister)
+ {
+ return operand(virtualRegister.offset());
+ }
+
const T& operand(int operand) const { return const_cast<const T&>(const_cast<Operands*>(this)->operand(operand)); }
bool hasOperand(int operand) const
{
if (operandIsArgument(operand))
return true;
- return static_cast<size_t>(operand) < numberOfLocals();
+ return static_cast<size_t>(VirtualRegister(operand).toLocal()) < numberOfLocals();
+ }
+ bool hasOperand(VirtualRegister reg) const
+ {
+ return hasOperand(reg.offset());
}
void setOperand(int operand, const T& value)
{
if (operandIsArgument(operand)) {
- int argument = operandToArgument(operand);
+ int argument = VirtualRegister(operand).toArgument();
m_arguments[argument] = value;
return;
}
- setLocal(operand, value);
+ setLocal(VirtualRegister(operand).toLocal(), value);
}
+ void setOperand(VirtualRegister virtualRegister, const T& value)
+ {
+ setOperand(virtualRegister.offset(), value);
+ }
+
size_t size() const { return numberOfArguments() + numberOfLocals(); }
const T& at(size_t index) const
{
int operandForIndex(size_t index) const
{
if (index < numberOfArguments())
- return argumentToOperand(index);
- return index - numberOfArguments();
+ return virtualRegisterForArgument(index).offset();
+ return virtualRegisterForLocal(index - numberOfArguments()).offset();
+ }
+ size_t indexForOperand(int operand) const
+ {
+ if (operandIsArgument(operand))
+ return static_cast<size_t>(VirtualRegister(operand).toArgument());
+ return static_cast<size_t>(VirtualRegister(operand).toLocal()) + numberOfArguments();
+ }
+ size_t indexForOperand(VirtualRegister reg) const
+ {
+ return indexForOperand(reg.offset());
}
void setOperandFirstTime(int operand, const T& value)
{
if (operandIsArgument(operand)) {
- setArgumentFirstTime(operandToArgument(operand), value);
+ setArgumentFirstTime(VirtualRegister(operand).toArgument(), value);
return;
}
- setLocalFirstTime(operand, value);
+ setLocalFirstTime(VirtualRegister(operand).toLocal(), value);
}
- void clear()
+ void fill(T value)
{
for (size_t i = 0; i < m_arguments.size(); ++i)
- m_arguments[i] = Traits::defaultValue();
+ m_arguments[i] = value;
for (size_t i = 0; i < m_locals.size(); ++i)
- m_locals[i] = Traits::defaultValue();
+ m_locals[i] = value;
+ }
+
+ void clear()
+ {
+ fill(Traits::defaultValue());
+ }
+
+ bool operator==(const Operands& other) const
+ {
+ ASSERT(numberOfArguments() == other.numberOfArguments());
+ ASSERT(numberOfLocals() == other.numberOfLocals());
+
+ return m_arguments == other.m_arguments && m_locals == other.m_locals;
+ }
+
+ void dumpInContext(PrintStream& out, DumpContext* context) const;
+
+ void dump(PrintStream& out) const
+ {
+ dumpInContext(out, 0);
}
private:
Vector<T, 16> m_locals;
};
-template<typename T, typename Traits>
-void dumpOperands(const Operands<T, Traits>& operands, PrintStream& out)
-{
- for (size_t argument = operands.numberOfArguments(); argument--;) {
- if (argument != operands.numberOfArguments() - 1)
- out.printf(" ");
- out.print("arg", argument, ":");
- Traits::dump(operands.argument(argument), out);
- }
- out.printf(" : ");
- for (size_t local = 0; local < operands.numberOfLocals(); ++local) {
- if (local)
- out.printf(" ");
- out.print("r", local, ":");
- Traits::dump(operands.local(local), out);
- }
-}
-
} // namespace JSC
#endif // Operands_h