This commit is contained in:
rogerl%netscape.com 2000-09-07 19:22:13 +00:00
Родитель 81c812ca20
Коммит 29c3f3caa8
12 изменённых файлов: 280 добавлений и 120 удалений

Просмотреть файл

@ -537,6 +537,16 @@ GenericBranch *ICodeGenerator::branchFalse(Label *label, TypedRegister condition
return instr;
}
GenericBranch *ICodeGenerator::branchInitialized(Label *label, TypedRegister condition)
{
GenericBranch *instr = new GenericBranch(BRANCH_INITIALIZED, label, condition);
iCode->push_back(instr);
return instr;
}
void ICodeGenerator::returnStmt(TypedRegister r)
{
iCode->push_back(new Return(r));
@ -1620,9 +1630,20 @@ ICodeModule *ICodeGenerator::genFunction(FunctionStmtNode *f, bool isConstructor
while (v) { // include the rest parameter, as it may have an initializer
if (v->name && (v->name->getKind() == ExprNode::identifier)) {
icg.addParameterLabel(icg.setLabel(icg.getLabel()));
TypedRegister p = icg.genExpr(v->name);
if (v->initializer) { // might be NULL when we get to the restParameter
TypedRegister p = icg.genExpr(v->name);
Label *l = icg.getLabel();
icg.branchInitialized(l, p);
icg.move(p, icg.genExpr(v->initializer));
icg.setLabel(l);
}
else { // an un-initialized rest parameter is still an empty array
if (v == f->function.restParameter) {
Label *l = icg.getLabel();
icg.branchInitialized(l, p);
icg.move(p, icg.newArray());
icg.setLabel(l);
}
}
}
v = v->next;

Просмотреть файл

@ -187,6 +187,7 @@ namespace ICG {
void branch(Label *label);
GenericBranch *branchTrue(Label *label, TypedRegister condition);
GenericBranch *branchFalse(Label *label, TypedRegister condition);
GenericBranch *branchInitialized(Label *label, TypedRegister condition);
void beginTry(Label *catchLabel, Label *finallyLabel)
{ iCode->push_back(new Tryin(catchLabel, finallyLabel)); }

Просмотреть файл

@ -105,7 +105,11 @@ struct Activation : public gc_base {
const JSValues& params = caller->mRegisters;
for (ArgumentList::const_iterator src = list.begin(),
end = list.end(); src != end; ++src, ++dest) {
*dest = params[(*src).first.first];
Register r = (*src).first.first;
if (r != NotARegister)
*dest = params[r];
else
*dest = JSValue(JSValue::uninitialized_tag);
}
}
@ -692,56 +696,89 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
else {
ICodeModule *icm = target->getICode();
ArgumentList &args = op4(call);
ArgumentList newArgs(args.size());
uint32 argCount = args.size() + 1; // the 'this' arg is travelling separately
if (hasNamedArguments(args)) {
// find argument names that match parameter names
for (uint32 a = 0; a < args.size(); a++) {
if (args[a].second) {
VariableList::iterator i = icm->itsVariables->find(*(args[a].second));
if (i != icm->itsVariables->end()) {
TypedRegister r = (*i).second;
if (r.first < icm->mParameterCount) { // make sure we didn't match a local var
// the named argument is arriving in slot a, but needs to be r instead
newArgs[r.first - 1] = Argument(args[a].first, NULL);
}
// mParameterCount includes 'this' and also 1 for a named rest parameter
//
uint32 pCount = icm->mParameterCount - 1;
ArgumentList callArgs(pCount, Argument(TypedRegister(NotARegister, &Null_Type), NULL));
if (icm->mHasNamedRestParameter) pCount--;
// walk along the given arguments, handling each.
// might be good to optimize the case of calls without named arguments and/or rest parameters
JSArray *restArg = NULL;
uint32 restIndex = 0;
uint32 i;
for (i = 0; i < args.size(); i++) {
if (args[i].second) { // a named argument
VariableList::iterator vi = icm->itsVariables->find(*(args[i].second));
bool isParameter = false;
if (vi != icm->itsVariables->end()) { // we found the name in the target's list of variables
TypedRegister r = (*vi).second;
if (r.first < icm->mParameterCount) { // make sure we didn't match a local var
ASSERT(r.first <= callArgs.size());
// the named argument is arriving in slot i, but needs to be r instead
// r.first is the intended target register, we subtract 1 since the callArgs array doesn't include 'this'
// here's where we could detect over-writing a positional arg with a named one if that is illegal
// if (callArgs[r.first - 1].first.first != NotARegister)...
callArgs[r.first - 1] = Argument(args[i].first, NULL); // no need to copy the name through?
isParameter = true;
}
}
else
newArgs[a] = args[a];
}
args = newArgs;
}
uint32 pOffset = icm->mEntryPoint;
if (argCount < icm->mNonOptionalParameterCount)
throw new JSException("Too few arguments in call");
if (argCount >= icm->mParameterCount) {
if (icm->mHasRestParameter) {
if (icm->mHasNamedRestParameter) {
uint32 restArgsCount = argCount - icm->mParameterCount + 1;
uint32 restArgsStart = icm->mParameterCount - 2; // 1 for 'this', 1 for 0-based
JSArray *r = new JSArray(restArgsCount);
for (uint32 i = 0; i < restArgsCount; i++)
(*r)[i] = (*registers)[args[i + restArgsStart].first.first];
(*registers)[args[restArgsStart].first.first] = r;
if (!isParameter) { // wasn't a parameter, make it a property of the rest parameter (if there is one)
if (icm->mHasRestParameter) {
if (icm->mHasNamedRestParameter) {
if (restArg == NULL) {
restArg = new JSArray();
restArg->setProperty(*args[i].second, (*registers)[args[i].first.first]);
(*registers)[args[i].first.first] = restArg;
callArgs[pCount] = Argument(TypedRegister(args[i].first.first, &Array_Type), NULL);
}
else
restArg->setProperty(*args[i].second, (*registers)[args[i].first.first]);
}
// else just throw it away
}
else
throw new JSException("Named argument doesn't match parameter name in call with no rest parameter");
// what about matching the named rest parameter ? aaarrggh!
}
// else, we just ignore the other arguments
}
else {
if (argCount > icm->mParameterCount)
throw new JSException("Too many arguments in call");
if (i >= pCount) { // more args than expected
if (icm->mHasRestParameter) {
if (icm->mHasNamedRestParameter) {
if (restArg == NULL) {
restArg = new JSArray();
(*restArg)[restIndex++] = (*registers)[args[i].first.first];
(*registers)[args[i].first.first] = restArg;
callArgs[pCount] = Argument(TypedRegister(args[i].first.first, &Array_Type), NULL);
}
else
(*restArg)[restIndex++] = (*registers)[args[i].first.first];
}
// else just throw it away
}
else
throw new JSException("Too many arguments in call");
}
callArgs[i] = args[i]; // it's a positional, just slap it in place
}
}
else {
if (argCount < icm->mParameterCount)
pOffset = icm->mParameterInit[argCount - icm->mNonOptionalParameterCount];
uint32 contiguousArgs = 0;
for (i = 0; i < args.size(); i++) {
Argument &arg = args[i];
if (arg.first.first == NotARegister) break;
contiguousArgs++;
}
if ((contiguousArgs + 1) < icm->mNonOptionalParameterCount) // there's always a 'this' in R0 (even though it might be null)
throw new JSException("Too few arguments in call");
mLinkage = new Linkage(mLinkage, ++mPC, mActivation, mGlobal, op1(call));
mActivation = new Activation(icm, mActivation, (*registers)[op3(call).first], args);
mActivation = new Activation(icm, mActivation, (*registers)[op3(call).first], callArgs);
registers = &mActivation->mRegisters;
mPC = mActivation->mICode->its_iCode->begin() + pOffset;
mPC = mActivation->mICode->its_iCode->begin();
endPC = mActivation->mICode->its_iCode->end();
continue;
}
@ -1036,6 +1073,16 @@ using JSString throughout.
}
}
break;
case BRANCH_INITIALIZED:
{
GenericBranch* bc =
static_cast<GenericBranch*>(instruction);
if ((*registers)[src1(bc).first].isInitialized()) {
mPC = mActivation->mICode->its_iCode->begin() + ofs(bc);
continue;
}
}
break;
case GENERIC_BINARY_OP:
{
GenericBinaryOP* gbo = static_cast<GenericBinaryOP*>(instruction);

Просмотреть файл

@ -504,7 +504,7 @@ Formatter& operator<<(Formatter& f, const JSValue& value)
if (i < (a->length() - 1))
f << ", ";
}
f << "]";
f << "] {" << *(static_cast<JSObject*>(value.array)) << "}";
// printFormat(f, "Array @ 0x%08X", value.array);
}
break;
@ -524,6 +524,9 @@ Formatter& operator<<(Formatter& f, const JSValue& value)
printFormat(f, "Type @ 0x%08X\n", value.type);
f << *value.type;
break;
case JSValue::uninitialized_tag:
f << "uninitialized";
break;
default:
NOT_REACHED("Bad tag");
}

Просмотреть файл

@ -97,7 +97,7 @@ namespace JSTypes {
NoHint
};
enum {
typedef enum {
i8_tag, u8_tag,
i16_tag, u16_tag,
i32_tag, u32_tag,
@ -105,8 +105,10 @@ namespace JSTypes {
f32_tag, f64_tag,
integer_tag,
object_tag, array_tag, function_tag, string_tag, boolean_tag, type_tag,
undefined_tag
} tag;
undefined_tag,
uninitialized_tag
} Tag;
Tag tag;
JSValue() : f64(0.0), tag(undefined_tag) {}
explicit JSValue(int32 i32) : i32(i32), tag(i32_tag) {}
@ -118,6 +120,7 @@ namespace JSTypes {
explicit JSValue(JSString* string) : string(string), tag(string_tag) {}
explicit JSValue(bool boolean) : boolean(boolean), tag(boolean_tag) {}
explicit JSValue(JSType* type) : type(type), tag(type_tag) {}
explicit JSValue(Tag tag) : tag(tag) {}
int32& operator=(int32 i32) { return (tag = i32_tag, this->i32 = i32); }
uint32& operator=(uint32 u32) { return (tag = u32_tag, this->u32 = u32); }
@ -139,6 +142,7 @@ namespace JSTypes {
will have to be converted (to doubles?) anyway because
we can't have overflow happening in generic arithmetic */
bool isInitialized() const { return (tag != uninitialized_tag); }
bool isUndefined() const { return (tag == undefined_tag); }
bool isNull() const { return ((tag == object_tag) && (this->object == NULL)); }
bool isNaN() const;
@ -330,14 +334,15 @@ namespace JSTypes {
*/
class JSArray : public JSObject {
JSValues elements;
uint32 top;
public:
JSArray() : elements(1) {}
JSArray(uint32 size) : elements(size) {}
JSArray() : elements(1) { top = 0; }
JSArray(uint32 size) : elements(size) { top = size; }
JSArray(const JSValues &v) : elements(v) {}
uint32 length()
{
return elements.size();
return top;
}
JSValue& operator[](const JSValue& index)
@ -347,6 +352,7 @@ namespace JSTypes {
// obviously, a sparse representation might be better.
uint32 size = elements.size();
if (n >= size) expand(n, size);
markHiEnd(n);
return elements[n];
}
@ -355,15 +361,23 @@ namespace JSTypes {
// obviously, a sparse representation might be better.
uint32 size = elements.size();
if (n >= size) expand(n, size);
markHiEnd(n);
return elements[n];
}
void resize(uint32 size)
{
elements.resize(size);
top = size;
}
private:
void markHiEnd(uint32 index)
{
if ((index + 1) > top) top = index + 1;
}
void expand(uint32 n, uint32 size)
{
do {

Просмотреть файл

@ -207,13 +207,13 @@ namespace VM {
virtual Formatter& print(Formatter& f)
{
f << opcodeNames[mOpcode] << "\tR" << mOp1.first << ", R" << mOp2.first << ", R" << mOp3.first;
f << opcodeNames[mOpcode] << "\t" << mOp1 << ", " << mOp2 << ", " << mOp3;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers)
{
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first] << ", " << "R" << mOp3.first << '=' << registers[mOp3.first];
f << getRegisterValue(registers, mOp1.first) << ", " << getRegisterValue(registers, mOp2.first) << ", " << getRegisterValue(registers, mOp3.first);
return f;
}
};
@ -223,13 +223,13 @@ namespace VM {
Unary(ICodeOp aOpcode, TypedRegister aDest, TypedRegister aSrc) :
Instruction_2<TypedRegister, TypedRegister>(aOpcode, aDest, aSrc) {}
virtual Formatter& print (Formatter& f) {
f << opcodeNames[mOpcode] << "\tR" << mOp1.first << ", R" << mOp2.first;
f << opcodeNames[mOpcode] << "\t" << mOp1 << ", " << mOp2;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers)
{
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
f << getRegisterValue(registers, mOp1.first) << ", " << getRegisterValue(registers, mOp2.first);
return f;
}
};
@ -240,19 +240,13 @@ namespace VM {
TypedRegister aR = TypedRegister(NotARegister, &Any_Type) ) :
Instruction_2<Label*, TypedRegister>(aOpcode, aLabel, aR) {}
virtual Formatter& print (Formatter& f) {
f << opcodeNames[mOpcode] << "\tOffset " << mOp1->mOffset;
if (mOp2.first == NotARegister) {
f << ", R~";
} else {
f << ", R" << mOp2.first;
}
f << opcodeNames[mOpcode] << "\tOffset " << mOp1->mOffset << ", " << mOp2;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers)
{
if (mOp2.first != NotARegister)
f << "R" << mOp2.first << '=' << registers[mOp2.first];
f << getRegisterValue(registers, mOp2.first);
return f;
}

Просмотреть файл

@ -537,6 +537,16 @@ GenericBranch *ICodeGenerator::branchFalse(Label *label, TypedRegister condition
return instr;
}
GenericBranch *ICodeGenerator::branchInitialized(Label *label, TypedRegister condition)
{
GenericBranch *instr = new GenericBranch(BRANCH_INITIALIZED, label, condition);
iCode->push_back(instr);
return instr;
}
void ICodeGenerator::returnStmt(TypedRegister r)
{
iCode->push_back(new Return(r));
@ -1620,9 +1630,20 @@ ICodeModule *ICodeGenerator::genFunction(FunctionStmtNode *f, bool isConstructor
while (v) { // include the rest parameter, as it may have an initializer
if (v->name && (v->name->getKind() == ExprNode::identifier)) {
icg.addParameterLabel(icg.setLabel(icg.getLabel()));
TypedRegister p = icg.genExpr(v->name);
if (v->initializer) { // might be NULL when we get to the restParameter
TypedRegister p = icg.genExpr(v->name);
Label *l = icg.getLabel();
icg.branchInitialized(l, p);
icg.move(p, icg.genExpr(v->initializer));
icg.setLabel(l);
}
else { // an un-initialized rest parameter is still an empty array
if (v == f->function.restParameter) {
Label *l = icg.getLabel();
icg.branchInitialized(l, p);
icg.move(p, icg.newArray());
icg.setLabel(l);
}
}
}
v = v->next;

Просмотреть файл

@ -187,6 +187,7 @@ namespace ICG {
void branch(Label *label);
GenericBranch *branchTrue(Label *label, TypedRegister condition);
GenericBranch *branchFalse(Label *label, TypedRegister condition);
GenericBranch *branchInitialized(Label *label, TypedRegister condition);
void beginTry(Label *catchLabel, Label *finallyLabel)
{ iCode->push_back(new Tryin(catchLabel, finallyLabel)); }

Просмотреть файл

@ -105,7 +105,11 @@ struct Activation : public gc_base {
const JSValues& params = caller->mRegisters;
for (ArgumentList::const_iterator src = list.begin(),
end = list.end(); src != end; ++src, ++dest) {
*dest = params[(*src).first.first];
Register r = (*src).first.first;
if (r != NotARegister)
*dest = params[r];
else
*dest = JSValue(JSValue::uninitialized_tag);
}
}
@ -692,56 +696,89 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
else {
ICodeModule *icm = target->getICode();
ArgumentList &args = op4(call);
ArgumentList newArgs(args.size());
uint32 argCount = args.size() + 1; // the 'this' arg is travelling separately
if (hasNamedArguments(args)) {
// find argument names that match parameter names
for (uint32 a = 0; a < args.size(); a++) {
if (args[a].second) {
VariableList::iterator i = icm->itsVariables->find(*(args[a].second));
if (i != icm->itsVariables->end()) {
TypedRegister r = (*i).second;
if (r.first < icm->mParameterCount) { // make sure we didn't match a local var
// the named argument is arriving in slot a, but needs to be r instead
newArgs[r.first - 1] = Argument(args[a].first, NULL);
}
// mParameterCount includes 'this' and also 1 for a named rest parameter
//
uint32 pCount = icm->mParameterCount - 1;
ArgumentList callArgs(pCount, Argument(TypedRegister(NotARegister, &Null_Type), NULL));
if (icm->mHasNamedRestParameter) pCount--;
// walk along the given arguments, handling each.
// might be good to optimize the case of calls without named arguments and/or rest parameters
JSArray *restArg = NULL;
uint32 restIndex = 0;
uint32 i;
for (i = 0; i < args.size(); i++) {
if (args[i].second) { // a named argument
VariableList::iterator vi = icm->itsVariables->find(*(args[i].second));
bool isParameter = false;
if (vi != icm->itsVariables->end()) { // we found the name in the target's list of variables
TypedRegister r = (*vi).second;
if (r.first < icm->mParameterCount) { // make sure we didn't match a local var
ASSERT(r.first <= callArgs.size());
// the named argument is arriving in slot i, but needs to be r instead
// r.first is the intended target register, we subtract 1 since the callArgs array doesn't include 'this'
// here's where we could detect over-writing a positional arg with a named one if that is illegal
// if (callArgs[r.first - 1].first.first != NotARegister)...
callArgs[r.first - 1] = Argument(args[i].first, NULL); // no need to copy the name through?
isParameter = true;
}
}
else
newArgs[a] = args[a];
}
args = newArgs;
}
uint32 pOffset = icm->mEntryPoint;
if (argCount < icm->mNonOptionalParameterCount)
throw new JSException("Too few arguments in call");
if (argCount >= icm->mParameterCount) {
if (icm->mHasRestParameter) {
if (icm->mHasNamedRestParameter) {
uint32 restArgsCount = argCount - icm->mParameterCount + 1;
uint32 restArgsStart = icm->mParameterCount - 2; // 1 for 'this', 1 for 0-based
JSArray *r = new JSArray(restArgsCount);
for (uint32 i = 0; i < restArgsCount; i++)
(*r)[i] = (*registers)[args[i + restArgsStart].first.first];
(*registers)[args[restArgsStart].first.first] = r;
if (!isParameter) { // wasn't a parameter, make it a property of the rest parameter (if there is one)
if (icm->mHasRestParameter) {
if (icm->mHasNamedRestParameter) {
if (restArg == NULL) {
restArg = new JSArray();
restArg->setProperty(*args[i].second, (*registers)[args[i].first.first]);
(*registers)[args[i].first.first] = restArg;
callArgs[pCount] = Argument(TypedRegister(args[i].first.first, &Array_Type), NULL);
}
else
restArg->setProperty(*args[i].second, (*registers)[args[i].first.first]);
}
// else just throw it away
}
else
throw new JSException("Named argument doesn't match parameter name in call with no rest parameter");
// what about matching the named rest parameter ? aaarrggh!
}
// else, we just ignore the other arguments
}
else {
if (argCount > icm->mParameterCount)
throw new JSException("Too many arguments in call");
if (i >= pCount) { // more args than expected
if (icm->mHasRestParameter) {
if (icm->mHasNamedRestParameter) {
if (restArg == NULL) {
restArg = new JSArray();
(*restArg)[restIndex++] = (*registers)[args[i].first.first];
(*registers)[args[i].first.first] = restArg;
callArgs[pCount] = Argument(TypedRegister(args[i].first.first, &Array_Type), NULL);
}
else
(*restArg)[restIndex++] = (*registers)[args[i].first.first];
}
// else just throw it away
}
else
throw new JSException("Too many arguments in call");
}
callArgs[i] = args[i]; // it's a positional, just slap it in place
}
}
else {
if (argCount < icm->mParameterCount)
pOffset = icm->mParameterInit[argCount - icm->mNonOptionalParameterCount];
uint32 contiguousArgs = 0;
for (i = 0; i < args.size(); i++) {
Argument &arg = args[i];
if (arg.first.first == NotARegister) break;
contiguousArgs++;
}
if ((contiguousArgs + 1) < icm->mNonOptionalParameterCount) // there's always a 'this' in R0 (even though it might be null)
throw new JSException("Too few arguments in call");
mLinkage = new Linkage(mLinkage, ++mPC, mActivation, mGlobal, op1(call));
mActivation = new Activation(icm, mActivation, (*registers)[op3(call).first], args);
mActivation = new Activation(icm, mActivation, (*registers)[op3(call).first], callArgs);
registers = &mActivation->mRegisters;
mPC = mActivation->mICode->its_iCode->begin() + pOffset;
mPC = mActivation->mICode->its_iCode->begin();
endPC = mActivation->mICode->its_iCode->end();
continue;
}
@ -1036,6 +1073,16 @@ using JSString throughout.
}
}
break;
case BRANCH_INITIALIZED:
{
GenericBranch* bc =
static_cast<GenericBranch*>(instruction);
if ((*registers)[src1(bc).first].isInitialized()) {
mPC = mActivation->mICode->its_iCode->begin() + ofs(bc);
continue;
}
}
break;
case GENERIC_BINARY_OP:
{
GenericBinaryOP* gbo = static_cast<GenericBinaryOP*>(instruction);

Просмотреть файл

@ -504,7 +504,7 @@ Formatter& operator<<(Formatter& f, const JSValue& value)
if (i < (a->length() - 1))
f << ", ";
}
f << "]";
f << "] {" << *(static_cast<JSObject*>(value.array)) << "}";
// printFormat(f, "Array @ 0x%08X", value.array);
}
break;
@ -524,6 +524,9 @@ Formatter& operator<<(Formatter& f, const JSValue& value)
printFormat(f, "Type @ 0x%08X\n", value.type);
f << *value.type;
break;
case JSValue::uninitialized_tag:
f << "uninitialized";
break;
default:
NOT_REACHED("Bad tag");
}

Просмотреть файл

@ -97,7 +97,7 @@ namespace JSTypes {
NoHint
};
enum {
typedef enum {
i8_tag, u8_tag,
i16_tag, u16_tag,
i32_tag, u32_tag,
@ -105,8 +105,10 @@ namespace JSTypes {
f32_tag, f64_tag,
integer_tag,
object_tag, array_tag, function_tag, string_tag, boolean_tag, type_tag,
undefined_tag
} tag;
undefined_tag,
uninitialized_tag
} Tag;
Tag tag;
JSValue() : f64(0.0), tag(undefined_tag) {}
explicit JSValue(int32 i32) : i32(i32), tag(i32_tag) {}
@ -118,6 +120,7 @@ namespace JSTypes {
explicit JSValue(JSString* string) : string(string), tag(string_tag) {}
explicit JSValue(bool boolean) : boolean(boolean), tag(boolean_tag) {}
explicit JSValue(JSType* type) : type(type), tag(type_tag) {}
explicit JSValue(Tag tag) : tag(tag) {}
int32& operator=(int32 i32) { return (tag = i32_tag, this->i32 = i32); }
uint32& operator=(uint32 u32) { return (tag = u32_tag, this->u32 = u32); }
@ -139,6 +142,7 @@ namespace JSTypes {
will have to be converted (to doubles?) anyway because
we can't have overflow happening in generic arithmetic */
bool isInitialized() const { return (tag != uninitialized_tag); }
bool isUndefined() const { return (tag == undefined_tag); }
bool isNull() const { return ((tag == object_tag) && (this->object == NULL)); }
bool isNaN() const;
@ -330,14 +334,15 @@ namespace JSTypes {
*/
class JSArray : public JSObject {
JSValues elements;
uint32 top;
public:
JSArray() : elements(1) {}
JSArray(uint32 size) : elements(size) {}
JSArray() : elements(1) { top = 0; }
JSArray(uint32 size) : elements(size) { top = size; }
JSArray(const JSValues &v) : elements(v) {}
uint32 length()
{
return elements.size();
return top;
}
JSValue& operator[](const JSValue& index)
@ -347,6 +352,7 @@ namespace JSTypes {
// obviously, a sparse representation might be better.
uint32 size = elements.size();
if (n >= size) expand(n, size);
markHiEnd(n);
return elements[n];
}
@ -355,15 +361,23 @@ namespace JSTypes {
// obviously, a sparse representation might be better.
uint32 size = elements.size();
if (n >= size) expand(n, size);
markHiEnd(n);
return elements[n];
}
void resize(uint32 size)
{
elements.resize(size);
top = size;
}
private:
void markHiEnd(uint32 index)
{
if ((index + 1) > top) top = index + 1;
}
void expand(uint32 n, uint32 size)
{
do {

Просмотреть файл

@ -207,13 +207,13 @@ namespace VM {
virtual Formatter& print(Formatter& f)
{
f << opcodeNames[mOpcode] << "\tR" << mOp1.first << ", R" << mOp2.first << ", R" << mOp3.first;
f << opcodeNames[mOpcode] << "\t" << mOp1 << ", " << mOp2 << ", " << mOp3;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers)
{
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first] << ", " << "R" << mOp3.first << '=' << registers[mOp3.first];
f << getRegisterValue(registers, mOp1.first) << ", " << getRegisterValue(registers, mOp2.first) << ", " << getRegisterValue(registers, mOp3.first);
return f;
}
};
@ -223,13 +223,13 @@ namespace VM {
Unary(ICodeOp aOpcode, TypedRegister aDest, TypedRegister aSrc) :
Instruction_2<TypedRegister, TypedRegister>(aOpcode, aDest, aSrc) {}
virtual Formatter& print (Formatter& f) {
f << opcodeNames[mOpcode] << "\tR" << mOp1.first << ", R" << mOp2.first;
f << opcodeNames[mOpcode] << "\t" << mOp1 << ", " << mOp2;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers)
{
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
f << getRegisterValue(registers, mOp1.first) << ", " << getRegisterValue(registers, mOp2.first);
return f;
}
};
@ -240,19 +240,13 @@ namespace VM {
TypedRegister aR = TypedRegister(NotARegister, &Any_Type) ) :
Instruction_2<Label*, TypedRegister>(aOpcode, aLabel, aR) {}
virtual Formatter& print (Formatter& f) {
f << opcodeNames[mOpcode] << "\tOffset " << mOp1->mOffset;
if (mOp2.first == NotARegister) {
f << ", R~";
} else {
f << ", R" << mOp2.first;
}
f << opcodeNames[mOpcode] << "\tOffset " << mOp1->mOffset << ", " << mOp2;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers)
{
if (mOp2.first != NotARegister)
f << "R" << mOp2.first << '=' << registers[mOp2.first];
f << getRegisterValue(registers, mOp2.first);
return f;
}