From c0404bd5e23008435e143f8808706d463d6f657d Mon Sep 17 00:00:00 2001 From: "rogerl%netscape.com" Date: Fri, 22 Mar 2002 22:58:24 +0000 Subject: [PATCH] Switched to SpiderMOnkey style jsval tagged pointer scheme. git-svn-id: svn://10.0.0.236/trunk@117240 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/js2/src/bytecodegen.cpp | 34 +- mozilla/js2/src/js2execution.cpp | 1330 ++++++++++++------------ mozilla/js2/src/js2runtime.cpp | 948 ++++++++--------- mozilla/js2/src/js2runtime.h | 466 +++++---- mozilla/js2/src/jsarray.cpp | 258 ++--- mozilla/js2/src/jsarray.h | 8 +- mozilla/js2/src/jsdate.cpp | 230 ++-- mozilla/js2/src/jsdate.h | 8 +- mozilla/js2/src/jsmath.cpp | 92 +- mozilla/js2/src/jsstring.cpp | 267 ++--- mozilla/js2/src/jsstring.h | 6 +- mozilla/js2/src/numerics.cpp | 18 +- mozilla/js2/src/property.h | 7 +- mozilla/js2/src/systemtypes.h | 5 +- mozilla/js2/tests/cpp/DikDik_Shell.cpp | 45 +- 15 files changed, 1844 insertions(+), 1878 deletions(-) diff --git a/mozilla/js2/src/bytecodegen.cpp b/mozilla/js2/src/bytecodegen.cpp index 9103d12be2c..a3e8d8e3bf3 100644 --- a/mozilla/js2/src/bytecodegen.cpp +++ b/mozilla/js2/src/bytecodegen.cpp @@ -780,16 +780,16 @@ bool ByteCodeGen::genCodeForStatement(StmtNode *p, ByteCodeGen *static_cg, uint3 } else { // initialize the variable with an appropriate value - JSValue uiv = ref->mType->getUninitializedValue(); - if (!uiv.isUndefined()) { + js2val uiv = ref->mType->getUninitializedValue(); + if (!JSValue::isUndefined(uiv)) { ref->emitImplicitLoad(this); - if (uiv.isNull()) + if (JSValue::isNull(uiv)) addOp(LoadConstantNullOp); else - if (uiv.isPositiveZero()) + if (JSValue::isPositiveZero(uiv)) addOp(LoadConstantZeroOp); else - if (uiv.isFalse()) + if (JSValue::isFalse(uiv)) addOp(LoadConstantFalseOp); else NOT_REACHED("Any more??"); @@ -1495,9 +1495,9 @@ Reference *ByteCodeGen::genReference(ExprNode *p, Access acc) if (b->op1->getKind() == ExprNode::identifier) { const StringAtom &name = checked_cast(b->op1)->name; - JSValue v = mScopeChain->getCompileTimeValue(m_cx, name, NULL); - if (v.isType()) { - lType = v.type; + js2val v = mScopeChain->getCompileTimeValue(m_cx, name, NULL); + if (JSValue::isType(v)) { + lType = JSValue::type(v); genExpr(b->op1); } } @@ -1574,9 +1574,9 @@ void ByteCodeGen::genReferencePair(ExprNode *p, Reference *&readRef, Reference * if (b->op1->getKind() == ExprNode::identifier) { const StringAtom &name = checked_cast(b->op1)->name; - JSValue v = mScopeChain->getCompileTimeValue(m_cx, name, NULL); - if (v.isType()) { - lType = v.type; + js2val v = mScopeChain->getCompileTimeValue(m_cx, name, NULL); + if (JSValue::isType(v)) { + lType = JSValue::type(v); genExpr(b->op1); } } @@ -2437,18 +2437,18 @@ BinaryOpEquals: case ExprNode::regExp: { RegExpExprNode *v = checked_cast(p); - JSValue reValue = kNullValue; - JSValue args[2]; - args[0] = JSValue(&v->re); - args[1] = JSValue(&v->flags); + js2val reValue = kNullValue; + js2val args[2]; + args[0] = JSValue::newString(&v->re); + args[1] = JSValue::newString(&v->flags); ByteCodeModule *curModule = m_cx->mCurModule; ByteCodeModule errorHandlingModule(p->pos); m_cx->mCurModule = &errorHandlingModule; reValue = RegExp_Constructor(m_cx, reValue, args, 2); m_cx->mCurModule = curModule; - ASSERT(reValue.isInstance()); + ASSERT(JSValue::isInstance(reValue)); addOp(LoadConstantRegExpOp); - addPointer(reValue.instance); + addPointer(JSValue::instance(reValue)); return RegExp_Type; } break; diff --git a/mozilla/js2/src/js2execution.cpp b/mozilla/js2/src/js2execution.cpp index fc28c404e77..99592bd16a1 100644 --- a/mozilla/js2/src/js2execution.cpp +++ b/mozilla/js2/src/js2execution.cpp @@ -63,9 +63,9 @@ namespace JS2Runtime { inline char narrow(char16 ch) { return char(ch); } -JSValue Context::readEvalString(const String &str, const String& fileName, ScopeChain *scopeChain, const JSValue& thisValue) +js2val Context::readEvalString(const String &str, const String& fileName, ScopeChain *scopeChain, const js2val thisValue) { - JSValue result = kUndefinedValue; + js2val result = kUndefinedValue; NamespaceList *useOnceNamespace = NULL; Arena a; @@ -104,12 +104,12 @@ JSValue Context::readEvalString(const String &str, const String& fileName, Scope return result; } -JSValue Context::readEvalFile(const String& fileName) +js2val Context::readEvalFile(const String& fileName) { String buffer; int ch; - JSValue result = kUndefinedValue; + js2val result = kUndefinedValue; std::string str(fileName.length(), char()); std::transform(fileName.begin(), fileName.end(), str.begin(), narrow); @@ -118,7 +118,7 @@ JSValue Context::readEvalFile(const String& fileName) while ((ch = getc(f)) != EOF) buffer += static_cast(ch); fclose(f); - result = readEvalString(buffer, fileName, NULL, JSValue(getGlobalObject())); + result = readEvalString(buffer, fileName, NULL, JSValue::newObject(getGlobalObject())); } return result; } @@ -156,9 +156,9 @@ bool Context::executeOperator(Operator op, JSType *t1, JSType *t2) JSFunction *target = (*candidate)->mImp; - JSValue newThis = kNullValue; + js2val newThis = kNullValue; if (target->isNative()) { - JSValue result = target->getNativeCode()(this, newThis, getBase(stackSize() - 2), 2); + js2val result = target->invokeNativeCode(this, newThis, getBase(stackSize() - 2), 2); resizeStack(stackSize() - 2); pushValue(result); return false; @@ -178,15 +178,15 @@ bool Context::executeOperator(Operator op, JSType *t1, JSType *t2) // Invokes either the native or bytecode implementation. Causes another interpreter loop // to begin execution, and does nothing to clean up the incoming arguments (which need // not even be on the execution stack). -JSValue Context::invokeFunction(JSFunction *target, const JSValue& thisValue, JSValue *argv, uint32 argc) +js2val Context::invokeFunction(JSFunction *target, const js2val thisValue, js2val *argv, uint32 argc) { if (target->isNative()) - return target->getNativeCode()(this, thisValue, argv, argc); + return target->invokeNativeCode(this, thisValue, argv, argc); else return interpret(target->getByteCode(), 0, target->getScopeChain(), thisValue, argv, argc); } -JSValue Context::interpret(JS2Runtime::ByteCodeModule *bcm, int offset, ScopeChain *scopeChain, const JSValue& thisValue, JSValue *argv, uint32 /*argc*/) +js2val Context::interpret(JS2Runtime::ByteCodeModule *bcm, int offset, ScopeChain *scopeChain, const js2val thisValue, js2val *argv, uint32 /*argc*/) { Activation *prev = new Activation(mLocals, mStack, mStackTop, mScopeChain, mArgumentBase, mThis, NULL, mCurModule, mNamespaceList); // use NULL pc value to force interpret loop to exit @@ -200,7 +200,7 @@ JSValue Context::interpret(JS2Runtime::ByteCodeModule *bcm, int offset, ScopeCha mScopeChain->addScope(getGlobalObject()); } -// if (mThis.isObject()) +// if (JSValue::isObject(mThis)) // mScopeChain->addScope(mThis.object); // mScopeChain->addScope(mActivationStack.top()); @@ -208,12 +208,12 @@ JSValue Context::interpret(JS2Runtime::ByteCodeModule *bcm, int offset, ScopeCha uint8 *pc = mCurModule->mCodeBase + offset; uint8 *endPC = mCurModule->mCodeBase + mCurModule->mLength; mArgumentBase = argv; - mLocals = new JSValue[mCurModule->mLocalsCount]; - mStack = new JSValue[mCurModule->mStackDepth]; + mLocals = new js2val[mCurModule->mLocalsCount]; + mStack = new js2val[mCurModule->mStackDepth]; mStackMax = mCurModule->mStackDepth; mStackTop = 0; - JSValue result; + js2val result; try { result = interpret(pc, endPC); } @@ -223,9 +223,9 @@ JSValue Context::interpret(JS2Runtime::ByteCodeModule *bcm, int offset, ScopeCha // the following (delete's) are a bit iffy - depends on whether // a closure capturing the contents has come along... -// if (mThis.isObject()) +// if (JSValue::isObject(mThis)) // mScopeChain->popScope(); - JSValue x; + js2val x; if (jsx.hasKind(Exception::userException)) x = popValue(); @@ -257,7 +257,7 @@ JSValue Context::interpret(JS2Runtime::ByteCodeModule *bcm, int offset, ScopeCha // the following (delete's) are a bit iffy - depends on whether // a closure capturing the contents has come along... -// if (mThis.isObject()) +// if (JSValue::isObject(mThis)) // mScopeChain->popScope(); delete[] mStack; delete[] mLocals; @@ -279,9 +279,9 @@ JSValue Context::interpret(JS2Runtime::ByteCodeModule *bcm, int offset, ScopeCha } // Assumes arguments are on the top of stack. argCount is the number that were pushed by user code -JSValue *Context::buildArgumentBlock(JSFunction *target, uint32 &argCount) +js2val *Context::buildArgumentBlock(JSFunction *target, uint32 &argCount) { - JSValue *argBase; + js2val *argBase; uint32 maxExpectedParameterCount = target->getRequiredParameterCount() + target->getOptionalParameterCount() + target->getNamedParameterCount(); if (target->isChecked()) { if (argCount < target->getRequiredParameterCount()) @@ -295,7 +295,7 @@ JSValue *Context::buildArgumentBlock(JSFunction *target, uint32 &argCount) uint32 argBlockSize = max(argCount, maxExpectedParameterCount) + (target->hasRestParameter() ? 1 : 0); // room for all required,optional & named arguments // plus the rest parameter if it exists. - argBase = new JSValue[argBlockSize]; + argBase = new js2val[argBlockSize]; /* * If the first parameter is required and no positional argument has been supplied for it, then raise an error unless the function @@ -320,8 +320,8 @@ JSValue *Context::buildArgumentBlock(JSFunction *target, uint32 &argCount) bool needDefault = true; if (target->parameterIsRequired(pIndex)) { if (inArgIndex < argCount) { - JSValue v = getValue(inArgIndex + argStart); - bool isPositionalArg = !v.isNamedArg(); + js2val v = getValue(inArgIndex + argStart); + bool isPositionalArg = !JSValue::isNamedArg(v); // if the next argument is named, then we've run out of positional args if (!isPositionalArg) { if (!target->isChecked()) @@ -340,8 +340,8 @@ JSValue *Context::buildArgumentBlock(JSFunction *target, uint32 &argCount) if (target->parameterIsOptional(pIndex)) { bool tookPositionalArg = false; if (inArgIndex < argCount) { - JSValue v = getValue(inArgIndex + argStart); - if (!v.isNamedArg()) { + js2val v = getValue(inArgIndex + argStart); + if (!JSValue::isNamedArg(v)) { argBase[pIndex] = v; argUsed[inArgIndex++] = true; needDefault = false; @@ -353,10 +353,10 @@ JSValue *Context::buildArgumentBlock(JSFunction *target, uint32 &argCount) const String *parameterName = target->getParameterName(pIndex); for (uint32 i = inArgIndex; i < argCount; i++) { if (!argUsed[i]) { - JSValue v = getValue(i + argStart); - if (v.isNamedArg()) { - if (v.namedArg->mName == parameterName) { - argBase[pIndex] = v.namedArg->mValue; + js2val v = getValue(i + argStart); + if (JSValue::isNamedArg(v)) { + if (JSValue::namedArg(v)->mName == parameterName) { + argBase[pIndex] = JSValue::namedArg(v)->mValue; argUsed[i] = true; needDefault = false; break; @@ -385,7 +385,7 @@ JSValue *Context::buildArgumentBlock(JSFunction *target, uint32 &argCount) * If there is no RestParameter and any arguments remain, raise an error unless the function is unchecked. */ - JSValue restArgument; + js2val restArgument; bool haveRestArg = false; if (target->hasRestParameter() && target->getParameterName(restParameterIndex)) { @@ -396,26 +396,26 @@ JSValue *Context::buildArgumentBlock(JSFunction *target, uint32 &argCount) inArgIndex = 0; // re-number the non-named arguments that end up in the rest arg for (i = 0; i < argCount; i++) { if (!argUsed[i]) { - JSValue v = getValue(i + argStart); - bool isNamedArg = v.isNamedArg(); + js2val v = getValue(i + argStart); + bool isNamedArg = JSValue::isNamedArg(v); if (isNamedArg) { - NamedArgument *arg = v.namedArg; + NamedArgument *arg = JSValue::namedArg(v); if (haveRestArg) - restArgument.object->setProperty(this, *arg->mName, (NamespaceList *)(NULL), arg->mValue); + JSValue::object(restArgument)->setProperty(this, *arg->mName, (NamespaceList *)(NULL), arg->mValue); else reportError(Exception::referenceError, "Unused named argument, no rest argument"); } else { if (haveRestArg) { const String *id = numberToString(inArgIndex++); - restArgument.object->setProperty(this, *id, (NamespaceList *)(NULL), v); + JSValue::object(restArgument)->setProperty(this, *id, (NamespaceList *)(NULL), v); } else { if (target->isChecked()) reportError(Exception::referenceError, "Extra argument, no rest argument"); else { if (isNamedArg) - argBase[i] = v.namedArg->mValue; + argBase[i] = JSValue::namedArg(v)->mValue; else argBase[i] = v; } @@ -428,10 +428,10 @@ JSValue *Context::buildArgumentBlock(JSFunction *target, uint32 &argCount) return argBase; } -JSValue Context::interpret(uint8 *pc, uint8 *endPC) +js2val Context::interpret(uint8 *pc, uint8 *endPC) { bool useOnceNamespace = false; - JSValue result = kUndefinedValue; + js2val result = kUndefinedValue; while (pc != endPC) { mPC = pc; try { @@ -472,14 +472,14 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) break; case DupOp: { - JSValue v = topValue(); + js2val v = topValue(); pushValue(v); } break; case DupInsertOp: // XXX something more efficient than pop/push? { - JSValue v1 = popValue(); - JSValue v2 = popValue(); + js2val v1 = popValue(); + js2val v2 = popValue(); pushValue(v1); pushValue(v2); pushValue(v1); @@ -489,7 +489,7 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) { uint16 count = *((uint16 *)pc); pc += sizeof(uint16); - JSValue *vp = getBase(stackSize() - count); + js2val *vp = getBase(stackSize() - count); while (count--) pushValue(*vp++); } @@ -497,7 +497,7 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) // --> case DupInsertNOp: { - JSValue v2 = topValue(); + js2val v2 = topValue(); uint16 count = *((uint16 *)pc); pc += sizeof(uint16); insertValue(v2, mStackTop - (count + 1)); @@ -505,21 +505,21 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) break; case SwapOp: // XXX something more efficient than pop/push? { - JSValue v1 = popValue(); - JSValue v2 = popValue(); + js2val v1 = popValue(); + js2val v2 = popValue(); pushValue(v1); pushValue(v2); } break; case LogicalXorOp: { - JSValue v2 = popValue(); - ASSERT(v2.isBool()); - JSValue v1 = popValue(); - ASSERT(v1.isBool()); + js2val v2 = popValue(); + ASSERT(JSValue::isBool(v2)); + js2val v1 = popValue(); + ASSERT(JSValue::isBool(v1)); - if (v1.boolean) { - if (v2.boolean) { + if (JSValue::boolean(v1)) { + if (JSValue::boolean(v2)) { popValue(); popValue(); pushValue(kFalseValue); @@ -528,13 +528,13 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) popValue(); } else { - if (v1.boolean) { + if (JSValue::boolean(v1)) { popValue(); popValue(); pushValue(kFalseValue); } else { - JSValue t = topValue(); + js2val t = topValue(); popValue(); popValue(); pushValue(t); @@ -544,9 +544,12 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) break; case LogicalNotOp: { - JSValue v = popValue(); - ASSERT(v.isBool()); - pushValue(JSValue(!v.boolean)); + js2val v = popValue(); + ASSERT(JSValue::isBool(v)); + if (JSValue::isTrue(v)) + pushValue(kFalseValue); + else + pushValue(kTrueValue); } break; case JumpOp: @@ -557,15 +560,15 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) break; case ToBooleanOp: { - JSValue v = popValue(); - pushValue(v.toBoolean(this)); + js2val v = popValue(); + pushValue(JSValue::toBoolean(this, v)); } break; case JumpFalseOp: { - JSValue v = popValue(); - ASSERT(v.isBool()); - if (!v.boolean) { + js2val v = popValue(); + ASSERT(JSValue::isBool(v)); + if (!JSValue::boolean(v)) { uint32 offset = *((uint32 *)pc); pc += offset; } @@ -575,9 +578,9 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) break; case JumpTrueOp: { - JSValue v = popValue(); - ASSERT(v.isBool()); - if (v.boolean) { + js2val v = popValue(); + ASSERT(JSValue::isBool(v)); + if (JSValue::boolean(v)) { uint32 offset = *((uint32 *)pc); pc += offset; } @@ -587,11 +590,11 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) break; case NamedArgOp: { - JSValue name = popValue(); - if (!name.isString()) + js2val name = popValue(); + if (!JSValue::isString(name)) reportError(Exception::typeError, "String needed for argument name"); - JSValue value = popValue(); - pushValue(JSValue(new NamedArgument(value, name.string))); + js2val value = popValue(); + pushValue(JSValue::newNamedArg(new NamedArgument(value, JSValue::string(name)))); } break; case InvokeOp: @@ -602,9 +605,9 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) CallFlag callFlags = (CallFlag)(*pc++); mPC = pc; - JSValue *targetValue = getBase(stackSize() - (argCount + 1)); + js2val *targetValue = getBase(stackSize() - (argCount + 1)); JSFunction *target; - JSValue oldThis = mThis; + js2val oldThis = mThis; switch (callFlags & ThisFlags) { case NoThis: mThis = kNullValue; @@ -617,15 +620,15 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) NOT_REACHED("bad bytecode"); } - if (!targetValue->isFunction()) { - if (targetValue->isType()) { + if (!JSValue::isFunction(*targetValue)) { + if (JSValue::isType(*targetValue)) { // how to distinguish between a cast and an invocation of // the superclass constructor from a constructor???? // XXX help if ((callFlags & SuperInvoke) == SuperInvoke) { // in this case, calling the constructor requires passing the 'this' value // through. - target = targetValue->type->getDefaultConstructor(); + target = JSValue::type(*targetValue)->getDefaultConstructor(); mThis = oldThis; } else { @@ -637,15 +640,15 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) // XXX Note that this is different behaviour from JS1.5, where // (e.g.) Array(2) is an invocation of the constructor. - target = targetValue->type->getTypeCastFunction(); + target = JSValue::type(*targetValue)->getTypeCastFunction(); if (target == NULL) { if ((argCount > 1) || ((callFlags & ThisFlags) != NoThis)) reportError(Exception::referenceError, "Type cast can only take one argument"); - JSValue v; + js2val v; if (argCount > 0) v = popValue(); popValue(); // don't need the target anymore - pushValue(mapValueToType(v, targetValue->type)); + pushValue(mapValueToType(v, JSValue::type(*targetValue))); mThis = oldThis; break; // all done } @@ -655,7 +658,7 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) reportError(Exception::referenceError, "Not a function"); } else { - target = targetValue->function; + target = JSValue::function(*targetValue); // an invocation of the super constructor has to pass thru the existing 'this' if (target->isConstructor() && (callFlags & SuperInvoke)) @@ -664,11 +667,11 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) if (target->hasBoundThis()) // then we use it instead of the expressed version mThis = target->getThisValue(); } - if (target->isPrototype() && mThis.isNull()) - mThis = JSValue(getGlobalObject()); + if (target->isPrototype() && JSValue::isNull(mThis)) + mThis = JSValue::newObject(getGlobalObject()); if (!target->isNative()) { - JSValue *argBase = buildArgumentBlock(target, argCount); + js2val *argBase = buildArgumentBlock(target, argCount); // XXX Optimize the more typical case in which there are no named arguments, no optional arguments // and the appropriate number of arguments have been supplied. @@ -681,9 +684,9 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) mScopeChain->addScope(target->getActivation()); if (!target->isChecked()) { - JSValue args = Array_Type->newInstance(this); + js2val args = Array_Type->newInstance(this); for (uint32 i = 0; i < argCount; i++) - args.instance->setProperty(this, *numberToString(i), NULL, argBase[i]); + JSValue::instance(args)->setProperty(this, *numberToString(i), NULL, argBase[i]); target->getActivation()->setProperty(this, Arguments_StringAtom, NULL, args); } @@ -691,20 +694,20 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) pc = mCurModule->mCodeBase; endPC = mCurModule->mCodeBase + mCurModule->mLength; mArgumentBase = argBase; - mLocals = new JSValue[mCurModule->mLocalsCount]; - mStack = new JSValue[mCurModule->mStackDepth]; + mLocals = new js2val[mCurModule->mLocalsCount]; + mStack = new js2val[mCurModule->mStackDepth]; mStackMax = mCurModule->mStackDepth; mStackTop = 0; } else { - JSValue *argBase = getBase(stackSize() - argCount); + js2val *argBase = getBase(stackSize() - argCount); // native functions may still need access to information // about the currently executing function. mActivationStack.push(new Activation(mLocals, mStack, mStackTop - (cleanUp + 1), mScopeChain, mArgumentBase, oldThis, pc, mCurModule, mNamespaceList)); - JSValue result = (target->getNativeCode())(this, mThis, argBase, argCount); + js2val result = target->invokeNativeCode(this, mThis, argBase, argCount); Activation *prev = mActivationStack.top(); delete prev; mActivationStack.pop(); @@ -750,7 +753,7 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) break; case ReturnOp: { - JSValue result = popValue(); + js2val result = popValue(); if (mActivationStack.empty()) return result; Activation *prev = mActivationStack.top(); @@ -783,26 +786,26 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) { JSType *t = *((JSType **)pc); pc += sizeof(JSType *); - pushValue(JSValue(t)); + pushValue(JSValue::newType(t)); } break; case LoadFunctionOp: { JSFunction *f = *((JSFunction **)pc); pc += sizeof(JSFunction *); - pushValue(JSValue(f)); + pushValue(JSValue::newFunction(f)); } break; case LoadConstantStringOp: { uint32 index = *((uint32 *)pc); pc += sizeof(uint32); - pushValue(JSValue(mCurModule->getString(index))); + pushValue(JSValue::newString(mCurModule->getString(index))); } break; case LoadConstantNumberOp: { - pushValue(JSValue(mCurModule->getNumber(pc))); + pushValue(JSValue::newNumber(mCurModule->getNumber(pc))); pc += sizeof(float64); } break; @@ -825,7 +828,7 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) { JSInstance *t = *((JSInstance **)pc); pc += sizeof(JSInstance *); - pushValue(JSValue(t)); + pushValue(JSValue::newInstance(t)); } break; case DeleteNameOp: @@ -841,8 +844,8 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) break; case DeleteOp: { - JSValue base = popValue(); - JSObject *obj = base.toObjectValue(this); + js2val base = popValue(); + JSObject *obj = JSValue::toObjectValue(this, base); uint32 index = *((uint32 *)pc); pc += sizeof(uint32); const StringAtom &name = *mCurModule->getString(index); @@ -858,35 +861,35 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) break; case TypeOfOp: { - JSValue v = popValue(); - if (v.isUndefined()) - pushValue(JSValue(&Undefined_StringAtom)); + js2val v = popValue(); + if (JSValue::isUndefined(v)) + pushValue(JSValue::newString(&Undefined_StringAtom)); else - if (v.isNull()) - pushValue(JSValue(&Object_StringAtom)); + if (JSValue::isNull(v)) + pushValue(JSValue::newString(&Object_StringAtom)); else - if (v.isBool()) - pushValue(JSValue(&Boolean_StringAtom)); + if (JSValue::isBool(v)) + pushValue(JSValue::newString(&Boolean_StringAtom)); else - if (v.isNumber()) - pushValue(JSValue(&Number_StringAtom)); + if (JSValue::isNumber(v)) + pushValue(JSValue::newString(&Number_StringAtom)); else - if (v.isString()) - pushValue(JSValue(&String_StringAtom)); + if (JSValue::isString(v)) + pushValue(JSValue::newString(&String_StringAtom)); else - if (v.isFunction()) - pushValue(JSValue(&Function_StringAtom)); + if (JSValue::isFunction(v)) + pushValue(JSValue::newString(&Function_StringAtom)); else - pushValue(JSValue(&Object_StringAtom)); + pushValue(JSValue::newString(&Object_StringAtom)); } break; case AsOp: { - JSValue t = popValue(); - JSValue v = popValue(); - if (t.isType()) { - if (v.isInstance() - && (v.instance->getType() == t.type)) + js2val t = popValue(); + js2val v = popValue(); + if (JSValue::isType(t)) { + if (JSValue::isInstance(v) + && (JSValue::instance(v)->getType() == JSValue::type(t))) pushValue(v); else pushValue(kNullValue); // XXX or throw an exception if @@ -898,28 +901,28 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) break; case IsOp: { - JSValue t = popValue(); - JSValue v = popValue(); - if (t.isType()) { - if (v.isNull()) - if (t.type == Object_Type) + js2val t = popValue(); + js2val v = popValue(); + if (JSValue::isType(t)) { + if (JSValue::isNull(v)) + if (JSValue::type(t) == Object_Type) pushValue(kTrueValue); else pushValue(kFalseValue); else - if (v.isInstance() - && ((v.instance->getType() == t.type) - || (v.instance->getType()->derivesFrom(t.type)))) + if (JSValue::isInstance(v) + && ((JSValue::instance(v)->getType() == JSValue::type(t)) + || (JSValue::instance(v)->getType()->derivesFrom(JSValue::type(t))))) pushValue(kTrueValue); else { - if (v.getType() == t.type) + if (JSValue::getType(v) == JSValue::type(t)) pushValue(kTrueValue); else pushValue(kFalseValue); } } else { // behave like instanceof - if (t.isObject() && t.isFunction()) { + if (JSValue::isObject(t) && JSValue::isFunction(t)) { // XXX prove that t->function["prototype"] is on t.object->mPrototype chain pushValue(kTrueValue); } @@ -930,16 +933,16 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) break; case InstanceOfOp: { - JSValue t = popValue(); - JSValue v = popValue(); - if (t.isFunction()) { - JSFunction *obj = t.function; + js2val t = popValue(); + js2val v = popValue(); + if (JSValue::isFunction(t)) { + JSFunction *obj = JSValue::function(t); PropertyIterator i; JSFunction *target = NULL; if (obj->hasProperty(this, HasInstance_StringAtom, mNamespaceList, Read, &i)) { - JSValue hi = obj->getPropertyValue(i); - if (hi.isFunction()) - target = hi.function; + js2val hi = obj->getPropertyValue(i); + if (JSValue::isFunction(hi)) + target = JSValue::function(hi); } if (target) pushValue(invokeFunction(target, t, &v, 1)); @@ -948,9 +951,9 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) } else { // XXX hack for <= ECMA 3 compatibility - if (t.isType()) { - if ((v.getType() == t.type) - || v.getType()->derivesFrom(t.type)) + if (JSValue::isType(t)) { + if ((JSValue::getType(v) == JSValue::type(t)) + || JSValue::getType(v)->derivesFrom(JSValue::type(t))) pushValue(kTrueValue); else pushValue(kFalseValue); @@ -966,15 +969,15 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) pc += sizeof(uint32); const StringAtom &name = *mCurModule->getString(index); JSObject *parent = mScopeChain->getNameValue(this, name, mNamespaceList); - JSValue result = topValue(); - if (result.isFunction() && !result.function->hasBoundThis()) { + js2val result = topValue(); + if (JSValue::isFunction(result) && !JSValue::function(result)->hasBoundThis()) { popValue(); - if (result.function->isConstructor()) + if (JSValue::function(result)->isConstructor()) // A constructor has to be called with a NULL 'this' in order to prompt it // to construct the instance object. - pushValue(JSValue((JSFunction *)(new JSBoundFunction(this, result.function, NULL)))); + pushValue(JSValue::newFunction((JSFunction *)(new JSBoundFunction(this, JSValue::function(result), NULL)))); else - pushValue(JSValue((JSFunction *)(new JSBoundFunction(this, result.function, parent)))); + pushValue(JSValue::newFunction((JSFunction *)(new JSBoundFunction(this, JSValue::function(result), parent)))); } if (useOnceNamespace) { NamespaceList *t = mNamespaceList->mNext; @@ -989,10 +992,10 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) uint32 index = *((uint32 *)pc); pc += sizeof(uint32); const StringAtom &name = *mCurModule->getString(index); - JSValue v = topValue(); - if (v.isFunction() && v.function->hasBoundThis() && !v.function->isMethod()) { + js2val v = topValue(); + if (JSValue::isFunction(v) && JSValue::function(v)->hasBoundThis() && !JSValue::function(v)->isMethod()) { popValue(); - pushValue(JSValue(v.function->getFunction())); + pushValue(JSValue::newFunction(JSValue::function(v)->getFunction())); } mScopeChain->setNameValue(this, name, mNamespaceList); if (useOnceNamespace) { @@ -1027,25 +1030,25 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) pc += sizeof(uint16); mPC = pc; - JSValue *base = getBase(stackSize() - (dimCount + 1)); + js2val *base = getBase(stackSize() - (dimCount + 1)); // Use the type of the base to dispatch on... - JSObject *obj = base->toObjectValue(this); - JSFunction *target = getUnaryOperator(base->getType(), Index); + JSObject *obj = JSValue::toObjectValue(this, *base); + JSFunction *target = getUnaryOperator(JSValue::getType(*base), Index); if (target) { - JSValue result; + js2val result; if (target->isNative()) { - JSValue *argBase = new JSValue[dimCount + 1]; + js2val *argBase = new js2val[dimCount + 1]; for (uint32 i = 0; i < (dimCount + 1); i++) argBase[i] = base[i]; resizeStack(stackSize() - (dimCount + 1)); - result = target->getNativeCode()(this, argBase[0], argBase, dimCount + 1); + result = target->invokeNativeCode(this, argBase[0], argBase, dimCount + 1); delete[] argBase; } else { uint32 argCount = dimCount + 1; - JSValue *argBase = buildArgumentBlock(target, argCount); + js2val *argBase = buildArgumentBlock(target, argCount); resizeStack(stackSize() - (dimCount + 1)); try { result = interpret(target->getByteCode(), 0, target->getScopeChain(), argBase[0], argBase, argCount); @@ -1060,22 +1063,22 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) else { // XXX or should this be implemented in Object_Type as operator "[]" ? if (dimCount != 1) reportError(Exception::typeError, "too many indices"); - JSValue index = popValue(); + js2val index = popValue(); popValue(); // discard base - const String *name = index.toString(this).string; + const String *name = JSValue::string(JSValue::toString(this, index)); obj->getProperty(this, *name, mNamespaceList); } // if the result is a method of some kind, bind // the base object to it - JSValue result = topValue(); - if (result.isFunction()) { + js2val result = topValue(); + if (JSValue::isFunction(result)) { popValue(); - if (result.function->isConstructor()) + if (JSValue::function(result)->isConstructor()) // A constructor has to be called with a NULL 'this' in order to prompt it // to construct the instance object. - pushValue(JSValue((JSFunction *)(new JSBoundFunction(this, result.function, NULL)))); + pushValue(JSValue::newFunction((JSFunction *)(new JSBoundFunction(this, JSValue::function(result), NULL)))); else - pushValue(JSValue((JSFunction *)(new JSBoundFunction(this, result.function, obj)))); + pushValue(JSValue::newFunction((JSFunction *)(new JSBoundFunction(this, JSValue::function(result), obj)))); } } break; @@ -1085,31 +1088,31 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) pc += sizeof(uint16); mPC = pc; - JSValue *base = getBase(stackSize() - (dimCount + 2)); // +1 for assigned value + js2val *base = getBase(stackSize() - (dimCount + 2)); // +1 for assigned value // Use the type of the base to dispatch on... - JSObject *obj = base->toObjectValue(this); - JSFunction *target = getUnaryOperator(base->getType(), IndexEqual); + JSObject *obj = JSValue::toObjectValue(this, *base); + JSFunction *target = getUnaryOperator(JSValue::getType(*base), IndexEqual); if (target) { - JSValue v = popValue(); // need to have this sitting right above the base value - if (v.isFunction() && v.function->hasBoundThis() && !v.function->isMethod()) { - v = JSValue(v.function->getFunction()); + js2val v = popValue(); // need to have this sitting right above the base value + if (JSValue::isFunction(v) && JSValue::function(v)->hasBoundThis() && !JSValue::function(v)->isMethod()) { + v = JSValue::newFunction(JSValue::function(v)->getFunction()); } insertValue(v, mStackTop - dimCount); - JSValue result; + js2val result; if (target->isNative()) { - JSValue *argBase = new JSValue[dimCount + 2]; + js2val *argBase = new js2val[dimCount + 2]; for (uint32 i = 0; i < (dimCount + 2); i++) argBase[i] = base[i]; resizeStack(stackSize() - (dimCount + 2)); - result = target->getNativeCode()(this, *base, base, (dimCount + 2)); + result = target->invokeNativeCode(this, *base, base, (dimCount + 2)); delete[] argBase; } else { uint32 argCount = dimCount + 2; - JSValue *argBase = buildArgumentBlock(target, argCount); + js2val *argBase = buildArgumentBlock(target, argCount); resizeStack(stackSize() - (dimCount + 2)); try { result = interpret(target->getByteCode(), 0, target->getScopeChain(), *base, argBase, argCount); @@ -1124,13 +1127,13 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) else { // XXX or should this be implemented in Object_Type as operator "[]=" ? if (dimCount != 1) reportError(Exception::typeError, "too many indices"); - JSValue v = popValue(); - if (v.isFunction() && v.function->hasBoundThis() && !v.function->isMethod()) { - v = JSValue(v.function->getFunction()); + js2val v = popValue(); + if (JSValue::isFunction(v) && JSValue::function(v)->hasBoundThis() && !JSValue::function(v)->isMethod()) { + v = JSValue::newFunction(JSValue::function(v)->getFunction()); } - JSValue index = popValue(); + js2val index = popValue(); popValue(); // discard base - const String *name = index.toString(this).string; + const String *name = JSValue::string(JSValue::toString(this, index)); obj->setProperty(this, *name, mNamespaceList, v); pushValue(v); } @@ -1142,25 +1145,25 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) pc += sizeof(uint16); mPC = pc; - JSValue *base = getBase(stackSize() - (dimCount + 1)); + js2val *base = getBase(stackSize() - (dimCount + 1)); // Use the type of the base to dispatch on... - JSObject *obj = base->toObjectValue(this); - JSFunction *target = getUnaryOperator(base->getType(), DeleteIndex); + JSObject *obj = JSValue::toObjectValue(this, *base); + JSFunction *target = getUnaryOperator(JSValue::getType(*base), DeleteIndex); if (target) { - JSValue result; + js2val result; if (target->isNative()) { - JSValue *argBase = new JSValue[dimCount + 1]; + js2val *argBase = new js2val[dimCount + 1]; for (uint32 i = 0; i < (dimCount + 1); i++) argBase[i] = base[i]; resizeStack(stackSize() - (dimCount + 1)); - result = target->getNativeCode()(this, argBase[0], argBase, dimCount + 1); + result = target->invokeNativeCode(this, argBase[0], argBase, dimCount + 1); delete[] argBase; } else { uint32 argCount = dimCount + 1; - JSValue *argBase = buildArgumentBlock(target, argCount); + js2val *argBase = buildArgumentBlock(target, argCount); resizeStack(stackSize() - (dimCount + 1)); try { result = interpret(target->getByteCode(), 0, target->getScopeChain(), kNullValue, argBase, argCount); @@ -1175,9 +1178,9 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) else { // XXX or should this be implemented in Object_Type as operator "delete[]" ? if (dimCount != 1) reportError(Exception::typeError, "too many indices"); - JSValue index = popValue(); + js2val index = popValue(); popValue(); // discard base - const String *name = index.toString(this).string; + const String *name = JSValue::string(JSValue::toString(this, index)); PropertyIterator it; if (obj->hasOwnProperty(this, *name, mNamespaceList, Read, &it)) obj->deleteProperty(this, *name, mNamespaceList); @@ -1187,8 +1190,8 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) break; case GetPropertyOp: { - JSValue base = popValue(); - JSObject *obj = base.toObjectValue(this); + js2val base = popValue(); + JSObject *obj = JSValue::toObjectValue(this, base); uint32 index = *((uint32 *)pc); pc += sizeof(uint32); mPC = pc; @@ -1196,15 +1199,15 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) obj->getProperty(this, name, mNamespaceList); // if the result is a method of some kind, bind // the base object to it - JSValue result = topValue(); - if (result.isFunction()) { + js2val result = topValue(); + if (JSValue::isFunction(result)) { popValue(); - if (result.function->isConstructor()) + if (JSValue::function(result)->isConstructor()) // A constructor has to be called with a NULL 'this' in order to prompt it // to construct the instance object. - pushValue(JSValue((JSFunction *)(new JSBoundFunction(this, result.function, NULL)))); + pushValue(JSValue::newFunction((JSFunction *)(new JSBoundFunction(this, JSValue::function(result), NULL)))); else - pushValue(JSValue((JSFunction *)(new JSBoundFunction(this, result.function, obj)))); + pushValue(JSValue::newFunction((JSFunction *)(new JSBoundFunction(this, JSValue::function(result), obj)))); } if (useOnceNamespace) { NamespaceList *t = mNamespaceList->mNext; @@ -1216,8 +1219,8 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) break; case GetInvokePropertyOp: { - JSValue base = topValue(); - JSValue baseObject = base.toObject(this); + js2val base = topValue(); + js2val baseObject = JSValue::toObject(this, base); // XXX really only need to pop/push if the base got modified popValue(); pushValue(baseObject); // want the "toObject'd" version of base @@ -1227,7 +1230,7 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) mPC = pc; const StringAtom &name = *mCurModule->getString(index); - baseObject.getObjectValue()->getProperty(this, name, mNamespaceList); + JSValue::getObjectValue(baseObject)->getProperty(this, name, mNamespaceList); if (useOnceNamespace) { NamespaceList *t = mNamespaceList->mNext; delete mNamespaceList; @@ -1238,12 +1241,12 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) break; case SetPropertyOp: { - JSValue v = popValue(); - if (v.isFunction() && v.function->hasBoundThis() && !v.function->isMethod()) { - v = JSValue(v.function->getFunction()); + js2val v = popValue(); + if (JSValue::isFunction(v) && JSValue::function(v)->hasBoundThis() && !JSValue::function(v)->isMethod()) { + v = JSValue::newFunction(JSValue::function(v)->getFunction()); } - JSValue base = popValue(); - JSObject *obj = base.toObjectValue(this); + js2val base = popValue(); + JSObject *obj = JSValue::toObjectValue(this, base); uint32 index = *((uint32 *)pc); pc += sizeof(uint32); mPC = pc; @@ -1262,11 +1265,11 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) { Operator op = (Operator)(*pc++); mPC = pc; - JSValue v = topValue(); - JSFunction *target = getUnaryOperator(v.getType(), op); + js2val v = topValue(); + JSFunction *target = getUnaryOperator(JSValue::getType(v), op); if (target) { uint32 argBase = stackSize() - 1; - JSValue newThis = kNullValue; + js2val newThis = kNullValue; if (!target->isNative()) { // lie about argCount to the activation since it // would normally expect to clean the function pointer @@ -1280,13 +1283,13 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) pc = mCurModule->mCodeBase; endPC = mCurModule->mCodeBase + mCurModule->mLength; mArgumentBase = getBase(argBase); - mLocals = new JSValue[mCurModule->mLocalsCount]; - mStack = new JSValue[mCurModule->mStackDepth]; + mLocals = new js2val[mCurModule->mLocalsCount]; + mStack = new js2val[mCurModule->mStackDepth]; mStackMax = mCurModule->mStackDepth; mStackTop = 0; } else { - JSValue result = (target->getNativeCode())(this, newThis, getBase(argBase), 0); + js2val result = target->invokeNativeCode(this, newThis, getBase(argBase), 0); resizeStack(stackSize() - 1); pushValue(result); } @@ -1299,25 +1302,25 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) case Negate: { popValue(); - JSValue n = v.toNumber(this); - if (n.isNaN()) + js2val n = JSValue::toNumber(this, v); + if (JSValue::isNaN(n)) pushValue(n); else - pushValue(JSValue(-n.f64)); + pushValue(JSValue::newNumber(-JSValue::f64(n))); } break; case Posate: { popValue(); - JSValue n = v.toNumber(this); + js2val n = JSValue::toNumber(this, v); pushValue(n); } break; case Complement: { popValue(); - JSValue n = v.toInt32(this); - pushValue(JSValue((float64)(~(int32)(n.f64)))); + js2val n = JSValue::toInt32(this, v); + pushValue(JSValue::newNumber((float64)(~(int32)JSValue::f64(n)))); } break; } @@ -1327,14 +1330,14 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) { Operator op = (Operator)(*pc++); mPC = pc; - JSValue v1 = getValue(stackSize() - 2); - JSValue v2 = getValue(stackSize() - 1); - if (executeOperator(op, v1.getType(), v2.getType())) { + js2val v1 = getValue(stackSize() - 2); + js2val v2 = getValue(stackSize() - 1); + if (executeOperator(op, JSValue::getType(v1), JSValue::getType(v2))) { // need to invoke pc = mCurModule->mCodeBase; endPC = mCurModule->mCodeBase + mCurModule->mLength; - mLocals = new JSValue[mCurModule->mLocalsCount]; - mStack = new JSValue[mCurModule->mStackDepth]; + mLocals = new js2val[mCurModule->mLocalsCount]; + mStack = new js2val[mCurModule->mStackDepth]; mStackMax = mCurModule->mStackDepth; mStackTop = 0; } @@ -1342,9 +1345,9 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) break; case GetConstructorOp: { - JSValue v = popValue(); - ASSERT(v.isType()); - pushValue(JSValue(v.type->getDefaultConstructor())); + js2val v = popValue(); + ASSERT(JSValue::isType(v)); + pushValue(JSValue::newFunction(JSValue::type(v)->getDefaultConstructor())); } break; case NewInstanceOp: @@ -1352,22 +1355,22 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) uint32 argCount = *((uint32 *)pc); pc += sizeof(uint32); uint32 cleanUp = argCount; - JSValue *argBase = getBase(stackSize() - argCount); + js2val *argBase = getBase(stackSize() - argCount); bool isPrototypeFunctionCall = false; JSFunction *target = NULL; - JSValue newThis = kNullValue; - JSValue *typeValue = getBase(stackSize() - (argCount + 1)); - if (!typeValue->isType()) { - if (typeValue->isFunction() && typeValue->function->isPrototype()) { + js2val newThis = kNullValue; + js2val *typeValue = getBase(stackSize() - (argCount + 1)); + if (!JSValue::isType(*typeValue)) { + if (JSValue::isFunction(*typeValue) && JSValue::function(*typeValue)->isPrototype()) { isPrototypeFunctionCall = true; - target = typeValue->function; + target = JSValue::function(*typeValue); newThis = Object_Type->newInstance(this); PropertyIterator i; if (target->hasProperty(this, Prototype_StringAtom, mNamespaceList, Read, &i)) { - JSValue v = target->getPropertyValue(i); - newThis.object->mPrototype = v.toObjectValue(this); - newThis.object->setProperty(this, UnderbarPrototype_StringAtom, (NamespaceList *)NULL, JSValue(newThis.object->mPrototype)); + js2val v = target->getPropertyValue(i); + JSValue::object(newThis)->mPrototype = JSValue::newObject(JSValue::toObjectValue(this, v)); + JSValue::object(newThis)->setProperty(this, UnderbarPrototype_StringAtom, (NamespaceList *)NULL, JSValue::object(newThis)->mPrototype); } } else @@ -1377,31 +1380,31 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) // if the type has an operator "new" use that, // otherwise use the default constructor (and pass NULL // for the this value) - target = getUnaryOperator(typeValue->type, New); + target = getUnaryOperator(JSValue::type(*typeValue), New); if (target) - newThis = typeValue->type->newInstance(this); + newThis = JSValue::type(*typeValue)->newInstance(this); else { newThis = kNullValue; - target = typeValue->type->getDefaultConstructor(); + target = JSValue::type(*typeValue)->getDefaultConstructor(); } } ASSERT(target); - JSValue result; + js2val result; if (target->isNative()) { - JSValue *tArgBase = new JSValue[argCount]; + js2val *tArgBase = new js2val[argCount]; for (uint32 i = 0; i < argCount; i++) tArgBase[i] = argBase[i]; resizeStack(stackSize() - cleanUp); - result = target->getNativeCode()(this, newThis, tArgBase, argCount); + result = target->invokeNativeCode(this, newThis, tArgBase, argCount); } else { argBase = buildArgumentBlock(target, argCount); resizeStack(stackSize() - cleanUp); if (!target->isChecked()) { - JSValue args = Array_Type->newInstance(this); + js2val args = Array_Type->newInstance(this); for (uint32 i = 0; i < argCount; i++) - args.instance->setProperty(this, *numberToString(i), NULL, argBase[i]); + JSValue::instance(args)->setProperty(this, *numberToString(i), NULL, argBase[i]); target->getActivation()->setProperty(this, Arguments_StringAtom, NULL, args); } try { @@ -1417,7 +1420,7 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) // If it's a prototype function, the return value is only // interesting if it's not a primitive, in which case it // overrides the newly constructed object. Weird, huh. - if (!result.isPrimitive()) + if (!JSValue::isPrimitive(result)) newThis = result; } else @@ -1430,10 +1433,10 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) break; case NewThisOp: { - JSValue v = popValue(); - if (mThis.isNull()) { - ASSERT(v.isType()); - mThis = v.type->newInstance(this); + js2val v = popValue(); + if (JSValue::isNull(mThis)) { + ASSERT(JSValue::isType(v)); + mThis = JSValue::type(v)->newInstance(this); } } break; @@ -1453,9 +1456,9 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) { uint32 index = *((uint32 *)pc); pc += sizeof(uint32); - JSValue v = topValue(); - if (v.isFunction() && v.function->hasBoundThis() && !v.function->isMethod()) { - v = JSValue(v.function->getFunction()); + js2val v = topValue(); + if (JSValue::isFunction(v) && JSValue::function(v)->hasBoundThis() && !JSValue::function(v)->isMethod()) { + v = JSValue::newFunction(JSValue::function(v)->getFunction()); } mLocals[index] = v; } @@ -1471,9 +1474,9 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) break; case SetClosureVarOp: { - JSValue v = topValue(); - if (v.isFunction() && v.function->hasBoundThis() && !v.function->isMethod()) { - v = JSValue(v.function->getFunction()); + js2val v = topValue(); + if (JSValue::isFunction(v) && JSValue::function(v)->hasBoundThis() && !JSValue::function(v)->isMethod()) { + v = JSValue::newFunction(JSValue::function(v)->getFunction()); } uint32 depth = *((uint32 *)pc); pc += sizeof(uint32); @@ -1500,9 +1503,9 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) break; case SetArgOp: { - JSValue v = topValue(); - if (v.isFunction() && v.function->hasBoundThis() && !v.function->isMethod()) { - v = JSValue(v.function->getFunction()); + js2val v = topValue(); + if (JSValue::isFunction(v) && JSValue::function(v)->hasBoundThis() && !JSValue::function(v)->isMethod()) { + v = JSValue::newFunction(JSValue::function(v)->getFunction()); } uint32 index = *((uint32 *)pc); pc += sizeof(uint32); @@ -1511,50 +1514,50 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) break; case GetMethodOp: { - JSValue base = topValue(); - ASSERT(base.isInstance()); + js2val base = topValue(); + ASSERT(JSValue::isInstance(base)); uint32 index = *((uint32 *)pc); pc += sizeof(uint32); - pushValue(JSValue(base.instance->mType->mMethods[index])); + pushValue(JSValue::newInstance(JSValue::instance(base)->mType->mMethods[index])); } break; case GetMethodRefOp: { - JSValue base = popValue(); - if (!base.isInstance()) + js2val base = popValue(); + if (!JSValue::isInstance(base)) reportError(Exception::semanticError, "Illegal method reference"); uint32 index = *((uint32 *)pc); pc += sizeof(uint32); - pushValue(JSValue(new JSBoundFunction(this, base.instance->mType->mMethods[index], base.object))); + pushValue(JSValue::newFunction(new JSBoundFunction(this, JSValue::instance(base)->mType->mMethods[index], JSValue::object(base)))); } break; case GetFieldOp: { - JSValue base = popValue(); - ASSERT(base.isInstance()); + js2val base = popValue(); + ASSERT(JSValue::isInstance(base)); uint32 index = *((uint32 *)pc); pc += sizeof(uint32); - pushValue(base.instance->mInstanceValues[index]); + pushValue(JSValue::instance(base)->mInstanceValues[index]); } break; case SetFieldOp: { - JSValue v = popValue(); - if (v.isFunction() && v.function->hasBoundThis() && !v.function->isMethod()) { - v = JSValue(v.function->getFunction()); + js2val v = popValue(); + if (JSValue::isFunction(v) && JSValue::function(v)->hasBoundThis() && !JSValue::function(v)->isMethod()) { + v = JSValue::newFunction(JSValue::function(v)->getFunction()); } - JSValue base = popValue(); - ASSERT(base.isInstance()); + js2val base = popValue(); + ASSERT(JSValue::isInstance(base)); uint32 index = *((uint32 *)pc); pc += sizeof(uint32); - base.instance->mInstanceValues[index] = v; + JSValue::instance(base)->mInstanceValues[index] = v; pushValue(v); } break; case WithinOp: { - JSValue base = popValue(); - mScopeChain->addScope(base.toObjectValue(this)); + js2val base = popValue(); + mScopeChain->addScope(JSValue::toObjectValue(this, base)); } break; case WithoutOp: @@ -1576,7 +1579,7 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) break; case LoadGlobalObjectOp: { - pushValue(JSValue(getGlobalObject())); + pushValue(JSValue::newObject(getGlobalObject())); } break; case JsrOp: @@ -1620,14 +1623,14 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) break; case JuxtaposeOp: { - JSValue v2 = popValue(); - JSValue v1 = popValue(); + js2val v2 = popValue(); + js2val v1 = popValue(); - ASSERT(v1.isAttribute()); - ASSERT(v2.isAttribute()); + ASSERT(JSValue::isAttribute(v1)); + ASSERT(JSValue::isAttribute(v2)); - Attribute *a1 = v1.attribute; - Attribute *a2 = v2.attribute; + Attribute *a1 = JSValue::attribute(v1); + Attribute *a2 = JSValue::attribute(v2); if ((a1->mTrueFlags & a2->mFalseFlags) != 0) reportError(Exception::semanticError, "Mismatched attributes"); // XXX could supply more detail @@ -1654,15 +1657,15 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) if (a2->mExtendArgument) x->mExtendArgument = a2->mExtendArgument; - pushValue(JSValue(x)); + pushValue(JSValue::newAttribute(x)); } break; case CastOp: { - JSValue t = popValue(); - ASSERT(t.isType()); - JSType *toType = t.type; - JSValue v = popValue(); + js2val t = popValue(); + ASSERT(JSValue::isType(t)); + JSType *toType = JSValue::type(t); + js2val v = popValue(); pushValue(mapValueToType(v, toType)); } @@ -1695,7 +1698,7 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) HandlerData *hndlr = (HandlerData *)mTryStack.top(); Activation *curAct = (mActivationStack.size() > 0) ? mActivationStack.top() : NULL; - JSValue x; + js2val x; if (curAct != hndlr->mActivation) { ASSERT(mActivationStack.size() > 0); Activation *prev;// = mActivationStack.top(); @@ -1727,8 +1730,8 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) // make sure there's a JS object for the catch clause to work with if (!jsx.hasKind(Exception::userException)) { - JSValue argv[1]; - argv[0] = JSValue(new String(jsx.fullMessage())); + js2val argv[1]; + argv[0] = JSValue::newString(new String(jsx.fullMessage())); switch (jsx.kind) { case Exception::syntaxError: x = SyntaxError_Constructor(this, kNullValue, argv, 1); @@ -1761,107 +1764,94 @@ JSValue Context::interpret(uint8 *pc, uint8 *endPC) // called on a JSValue to return a base object. The value may be a type, function, instance // or generic object -JSObject *JSValue::getObjectValue() const +JSObject *JSValue::getObjectValue(js2val v) { - switch (tag) { - case object_tag: - return object; - case instance_tag: - return instance; - case function_tag: - return function; - case type_tag: - return type; - case package_tag: - return package; - default: - NOT_REACHED("Bad tag"); - return NULL; - } + ASSERT(isObject(v)); + return object(v); } // called on a JSValue with type == Number_Type, which could be either a tagged // value or a Number object (actually an instance). Return the raw value in either case. -float64 JSValue::getNumberValue() const +float64 JSValue::getNumberValue(js2val v) { - if (isNumber()) - return f64; - ASSERT(isInstance() && (getType() == Number_Type)); - JSNumberInstance *numInst = checked_cast(instance); + if (JSValue::isNumber(v)) + return JSValue::f64(v); + ASSERT(JSValue::isInstance(v) && (JSValue::getType(v) == Number_Type)); + JSNumberInstance *numInst = checked_cast(JSValue::instance(v)); return numInst->mValue; } // called on a JSValue with type == String_Type, which could be either a tagged // value or a String object (actually an instance). Return the raw value in either case. -const String *JSValue::getStringValue() const +const String *JSValue::getStringValue(js2val v) { - if (isString()) - return string; - ASSERT(isInstance() && (getType() == String_Type)); - JSStringInstance *strInst = checked_cast(instance); + if (JSValue::isString(v)) + return JSValue::string(v); + ASSERT(JSValue::isInstance(v) && (JSValue::getType(v) == String_Type)); + JSStringInstance *strInst = checked_cast(JSValue::instance(v)); return strInst->mValue; } // called on a JSValue with type == Boolean_Type, which could be either a tagged // value or a Boolean object (actually an instance). Return the raw value in either case. -bool JSValue::getBoolValue() const +bool JSValue::getBoolValue(js2val v) { - if (isBool()) - return boolean; - ASSERT(isInstance() && (getType() == Boolean_Type)); - JSBooleanInstance *boolInst = checked_cast(instance); + if (JSValue::isBool(v)) + return JSValue::boolean(v); + ASSERT(JSValue::isInstance(v) && (JSValue::getType(v) == Boolean_Type)); + JSBooleanInstance *boolInst = checked_cast(JSValue::instance(v)); return boolInst->mValue; } // Implementation of '+' for two number types -static JSValue numberPlus(Context *, const JSValue& /*thisValue*/, JSValue *argv, uint32 /*argc*/) +static js2val numberPlus(Context *, const js2val /*thisValue*/, js2val argv[], uint32 /*argc*/) { - return JSValue(argv[0].getNumberValue() + argv[1].getNumberValue()); + return JSValue::newNumber(JSValue::getNumberValue(argv[0]) + JSValue::getNumberValue(argv[1])); } // Implementation of '+' for two integer types -static JSValue integerPlus(Context * /*cx*/, const JSValue& /*thisValue*/, JSValue *argv, uint32 /*argc*/) +static js2val integerPlus(Context * /*cx*/, const js2val /*thisValue*/, js2val argv[], uint32 /*argc*/) { - return JSValue(argv[0].getNumberValue() + argv[1].getNumberValue()); + return JSValue::newNumber(JSValue::getNumberValue(argv[0]) + JSValue::getNumberValue(argv[1])); } // Implementation of '+' for two 'generic' objects -static JSValue objectPlus(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 /*argc*/) +static js2val objectPlus(Context *cx, const js2val /*thisValue*/, js2val argv[], uint32 /*argc*/) { - JSValue &r1 = argv[0]; - JSValue &r2 = argv[1]; - JSType *t1 = r1.getType(); - JSType *t2 = r2.getType(); + js2val &r1 = argv[0]; + js2val &r2 = argv[1]; + JSType *t1 = JSValue::getType(r1); + JSType *t2 = JSValue::getType(r2); if ((t1 == Number_Type) && (t2 == Number_Type)) { - return JSValue(r1.getNumberValue() + r2.getNumberValue()); + return JSValue::newNumber(JSValue::getNumberValue(r1) + JSValue::getNumberValue(r2)); } if (t1 == String_Type) { if (t2 == String_Type) - return JSValue(new String(*r1.getStringValue() + *r2.getStringValue())); + return JSValue::newString(new String(*JSValue::getStringValue(r1) + *JSValue::getStringValue(r2))); else - return JSValue(new String(*r1.getStringValue() + *r2.toString(cx).string)); + return JSValue::newString(new String(*JSValue::getStringValue(r1) + *JSValue::string(JSValue::toString(cx, r2)))); } else { if (t2 == String_Type) - return JSValue(new String(*r1.toString(cx).string + *r2.getStringValue())); + return JSValue::newString(new String(*JSValue::string(JSValue::toString(cx, r1)) + *JSValue::getStringValue(r2))); else { - JSValue r1p = r1.toPrimitive(cx); - JSValue r2p = r2.toPrimitive(cx); + js2val r1p = JSValue::toPrimitive(cx, r1); + js2val r2p = JSValue::toPrimitive(cx, r2); // gar-on-teed tagged values now - if (r1p.isString()) - if (r2p.isString()) - return JSValue(new String(*r1p.string + *r2p.string)); + if (JSValue::isString(r1p)) + if (JSValue::isString(r2p)) + return JSValue::newString(new String(*JSValue::string(r1p) + *JSValue::string(r2p))); else - return JSValue(new String(*r1p.string + *r2p.toString(cx).string)); + return JSValue::newString(new String(*JSValue::string(r1p) + *JSValue::string(JSValue::toString(cx, r2p)))); else - if (r2p.isString()) - return JSValue(new String(*r1p.toString(cx).string + *r2p.string)); + if (JSValue::isString(r2p)) + return JSValue::newString(new String(*JSValue::string(JSValue::toString(cx, r1p)) + *JSValue::string(r2p))); else { - JSValue num1(r1.toNumber(cx)); - JSValue num2(r2.toNumber(cx)); - return JSValue(num1.f64 + num2.f64); + js2val num1(JSValue::toNumber(cx, r1)); + js2val num2(JSValue::toNumber(cx, r2)); + return JSValue::newNumber(JSValue::f64(num1) + JSValue::f64(num2)); } } } @@ -1870,197 +1860,197 @@ static JSValue objectPlus(Context *cx, const JSValue& /*thisValue*/, JSValue *ar // Implementation of '-' for two integer types -static JSValue integerMinus(Context * /*cx*/, const JSValue& /*thisValue*/, JSValue *argv, uint32 /*argc*/) +static js2val integerMinus(Context * /*cx*/, const js2val /*thisValue*/, js2val argv[], uint32 /*argc*/) { - return JSValue(argv[0].getNumberValue() - argv[1].getNumberValue()); + return JSValue::newNumber(JSValue::getNumberValue(argv[0]) - JSValue::getNumberValue(argv[1])); } // Implementation of '-' for two number types -static JSValue numberMinus(Context *, const JSValue& /*thisValue*/, JSValue *argv, uint32 /*argc*/) +static js2val numberMinus(Context *, const js2val /*thisValue*/, js2val argv[], uint32 /*argc*/) { - return JSValue(argv[0].getNumberValue() - argv[1].getNumberValue()); + return JSValue::newNumber(JSValue::getNumberValue(argv[0]) - JSValue::getNumberValue(argv[1])); } // Implementation of '-' for two 'generic' objects -static JSValue objectMinus(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 /*argc*/) +static js2val objectMinus(Context *cx, const js2val /*thisValue*/, js2val argv[], uint32 /*argc*/) { - JSValue &r1 = argv[0]; - JSValue &r2 = argv[1]; - return JSValue(r1.toNumber(cx).f64 - r2.toNumber(cx).f64); + js2val r1 = JSValue::toNumber(cx, argv[0]); + js2val r2 = JSValue::toNumber(cx, argv[1]); + return JSValue::newNumber(JSValue::f64(r1) - JSValue::f64(r2)); } // Implementation of '*' for two integer types -static JSValue integerMultiply(Context * /*cx*/, const JSValue& /*thisValue*/, JSValue *argv, uint32 /*argc*/) +static js2val integerMultiply(Context * /*cx*/, const js2val /*thisValue*/, js2val argv[], uint32 /*argc*/) { - return JSValue(argv[0].getNumberValue() * argv[1].getNumberValue()); + return JSValue::newNumber(JSValue::getNumberValue(argv[0]) * JSValue::getNumberValue(argv[1])); } // Implementation of '*' for two 'generic' objects -static JSValue objectMultiply(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 /*argc*/) +static js2val objectMultiply(Context *cx, const js2val /*thisValue*/, js2val argv[], uint32 /*argc*/) { - JSValue &r1 = argv[0]; - JSValue &r2 = argv[1]; - return JSValue(r1.toNumber(cx).f64 * r2.toNumber(cx).f64); + js2val r1 = JSValue::toNumber(cx, argv[0]); + js2val r2 = JSValue::toNumber(cx, argv[1]); + return JSValue::newNumber(JSValue::f64(r1) * JSValue::f64(r2)); } // Implementation of '/' for two integer types -static JSValue integerDivide(Context * /*cx*/, const JSValue& /*thisValue*/, JSValue *argv, uint32 /*argc*/) +static js2val integerDivide(Context * /*cx*/, const js2val /*thisValue*/, js2val argv[], uint32 /*argc*/) { - float64 f1 = argv[0].getNumberValue(); - float64 f2 = argv[1].getNumberValue(); + float64 f1 = JSValue::getNumberValue(argv[0]); + float64 f2 = JSValue::getNumberValue(argv[1]); float64 d = f1 / f2; bool neg = (d < 0); d = fd::floor(neg ? -d : d); d = neg ? -d : d; - return JSValue(d); + return JSValue::newNumber(d); } // Implementation of '/' for two 'generic' objects -static JSValue objectDivide(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 /*argc*/) +static js2val objectDivide(Context *cx, const js2val /*thisValue*/, js2val argv[], uint32 /*argc*/) { - JSValue &r1 = argv[0]; - JSValue &r2 = argv[1]; - return JSValue(r1.toNumber(cx).f64 / r2.toNumber(cx).f64); + js2val r1 = JSValue::toNumber(cx, argv[0]); + js2val r2 = JSValue::toNumber(cx, argv[1]); + return JSValue::newNumber(JSValue::f64(r1) / JSValue::f64(r2)); } // Implementation of '%' for two integer types -static JSValue integerRemainder(Context * /*cx*/, const JSValue& /*thisValue*/, JSValue *argv, uint32 /*argc*/) +static js2val integerRemainder(Context * /*cx*/, const js2val /*thisValue*/, js2val argv[], uint32 /*argc*/) { - float64 f1 = argv[0].getNumberValue(); - float64 f2 = argv[1].getNumberValue(); + float64 f1 = JSValue::getNumberValue(argv[0]); + float64 f2 = JSValue::getNumberValue(argv[1]); float64 d = fd::fmod(f1, f2); bool neg = (d < 0); d = fd::floor(neg ? -d : d); d = neg ? -d : d; - return JSValue(d); + return JSValue::newNumber(d); } // Implementation of '%' for two 'generic' objects -static JSValue objectRemainder(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 /*argc*/) +static js2val objectRemainder(Context *cx, const js2val /*thisValue*/, js2val argv[], uint32 /*argc*/) { - JSValue &r1 = argv[0]; - JSValue &r2 = argv[1]; + js2val r1 = JSValue::toNumber(cx, argv[0]); + js2val r2 = JSValue::toNumber(cx, argv[1]); - float64 f1 = r1.toNumber(cx).f64; - float64 f2 = r2.toNumber(cx).f64; + float64 f1 = JSValue::f64(r1); + float64 f2 = JSValue::f64(r2); #ifdef XP_PC /* Workaround MS fmod bug where 42 % (1/0) => NaN, not 42. */ if (JSDOUBLE_IS_FINITE(f1) && JSDOUBLE_IS_INFINITE(f2)) - return JSValue(f1); + return JSValue::newNumber(f1); #endif - return JSValue(fd::fmod(f1, f2)); + return JSValue::newNumber(fd::fmod(f1, f2)); } // Implementation of '<<' for two integer types -static JSValue integerShiftLeft(Context * /*cx*/, const JSValue& /*thisValue*/, JSValue *argv, uint32 /*argc*/) +static js2val integerShiftLeft(Context * /*cx*/, const js2val /*thisValue*/, js2val argv[], uint32 /*argc*/) { - float64 f1 = argv[0].getNumberValue(); - float64 f2 = argv[1].getNumberValue(); - return JSValue((float64)( (int32)(f1) << ( (uint32)(f2) & 0x1F)) ); + float64 f1 = JSValue::getNumberValue(argv[0]); + float64 f2 = JSValue::getNumberValue(argv[1]); + return JSValue::newNumber((float64)( (int32)(f1) << ( (uint32)(f2) & 0x1F)) ); } // Implementation of '<<' for two 'generic' objects -static JSValue objectShiftLeft(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 /*argc*/) +static js2val objectShiftLeft(Context *cx, const js2val /*thisValue*/, js2val argv[], uint32 /*argc*/) { - JSValue &r1 = argv[0]; - JSValue &r2 = argv[1]; - return JSValue((float64)( (int32)(r1.toInt32(cx).f64) << ( (uint32)(r2.toUInt32(cx).f64) & 0x1F)) ); + js2val r1 = JSValue::toInt32(cx, argv[0]); + js2val r2 = JSValue::toUInt32(cx, argv[1]); + return JSValue::newNumber((float64)( (int32)(JSValue::f64(r1)) << ( (uint32)(JSValue::f64(r2)) & 0x1F)) ); } // Implementation of '>>' for two integer types -static JSValue integerShiftRight(Context * /*cx*/, const JSValue& /*thisValue*/, JSValue *argv, uint32 /*argc*/) +static js2val integerShiftRight(Context * /*cx*/, const js2val /*thisValue*/, js2val argv[], uint32 /*argc*/) { - float64 f1 = argv[0].getNumberValue(); - float64 f2 = argv[1].getNumberValue(); - return JSValue((float64) ( (int32)(f1) >> ( (uint32)(f2) & 0x1F)) ); + float64 f1 = JSValue::getNumberValue(argv[0]); + float64 f2 = JSValue::getNumberValue(argv[1]); + return JSValue::newNumber((float64) ( (int32)(f1) >> ( (uint32)(f2) & 0x1F)) ); } // Implementation of '>>' for two 'generic' objects -static JSValue objectShiftRight(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 /*argc*/) +static js2val objectShiftRight(Context *cx, const js2val /*thisValue*/, js2val argv[], uint32 /*argc*/) { - JSValue &r1 = argv[0]; - JSValue &r2 = argv[1]; - return JSValue((float64) ( (int32)(r1.toInt32(cx).f64) >> ( (uint32)(r2.toUInt32(cx).f64) & 0x1F)) ); + js2val r1 = JSValue::toInt32(cx, argv[0]); + js2val r2 = JSValue::toUInt32(cx, argv[1]); + return JSValue::newNumber((float64) ( (int32)(JSValue::f64(r1)) >> ( (uint32)(JSValue::f64(r2)) & 0x1F)) ); } // Implementation of '>>>' for two integer types -static JSValue integerUShiftRight(Context * /*cx*/, const JSValue& /*thisValue*/, JSValue *argv, uint32 /*argc*/) +static js2val integerUShiftRight(Context * /*cx*/, const js2val /*thisValue*/, js2val argv[], uint32 /*argc*/) { - float64 f1 = argv[0].getNumberValue(); - float64 f2 = argv[1].getNumberValue(); - return JSValue((float64) ( (uint32)(f1) >> ( (uint32)(f2) & 0x1F)) ); + float64 f1 = JSValue::getNumberValue(argv[0]); + float64 f2 = JSValue::getNumberValue(argv[1]); + return JSValue::newNumber((float64) ( (uint32)(f1) >> ( (uint32)(f2) & 0x1F)) ); } // Implementation of '>>>' for two 'generic' objects -static JSValue objectUShiftRight(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 /*argc*/) +static js2val objectUShiftRight(Context *cx, const js2val /*thisValue*/, js2val argv[], uint32 /*argc*/) { - JSValue &r1 = argv[0]; - JSValue &r2 = argv[1]; - return JSValue((float64) ( (uint32)(r1.toUInt32(cx).f64) >> ( (uint32)(r2.toUInt32(cx).f64) & 0x1F)) ); + js2val r1 = JSValue::toUInt32(cx, argv[0]); + js2val r2 = JSValue::toUInt32(cx, argv[1]); + return JSValue::newNumber((float64) ( (uint32)(JSValue::f64(r1)) >> ( (uint32)(JSValue::f64(r2)) & 0x1F)) ); } // Implementation of '&' for two integer types -static JSValue integerBitAnd(Context * /*cx*/, const JSValue& /*thisValue*/, JSValue *argv, uint32 /*argc*/) +static js2val integerBitAnd(Context * /*cx*/, const js2val /*thisValue*/, js2val argv[], uint32 /*argc*/) { - float64 f1 = argv[0].getNumberValue(); - float64 f2 = argv[1].getNumberValue(); - return JSValue((float64)( (int32)(f1) & (int32)(f2) )); + float64 f1 = JSValue::getNumberValue(argv[0]); + float64 f2 = JSValue::getNumberValue(argv[1]); + return JSValue::newNumber((float64)( (int32)(f1) & (int32)(f2) )); } // Implementation of '&' for two 'generic' objects -static JSValue objectBitAnd(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 /*argc*/) +static js2val objectBitAnd(Context *cx, const js2val /*thisValue*/, js2val argv[], uint32 /*argc*/) { - JSValue &r1 = argv[0]; - JSValue &r2 = argv[1]; - return JSValue((float64)( (int32)(r1.toInt32(cx).f64) & (int32)(r2.toInt32(cx).f64) )); + js2val r1 = JSValue::toInt32(cx, argv[0]); + js2val r2 = JSValue::toInt32(cx, argv[1]); + return JSValue::newNumber((float64)( (int32)(JSValue::f64(r1)) & (int32)(JSValue::f64(r2)) )); } // Implementation of '^' for two integer types -static JSValue integerBitXor(Context * /*cx*/, const JSValue& /*thisValue*/, JSValue *argv, uint32 /*argc*/) +static js2val integerBitXor(Context * /*cx*/, const js2val /*thisValue*/, js2val argv[], uint32 /*argc*/) { - float64 f1 = argv[0].getNumberValue(); - float64 f2 = argv[1].getNumberValue(); - return JSValue((float64)( (int32)(f1) ^ (int32)(f2) )); + float64 f1 = JSValue::getNumberValue(argv[0]); + float64 f2 = JSValue::getNumberValue(argv[1]); + return JSValue::newNumber((float64)( (int32)(f1) ^ (int32)(f2) )); } // Implementation of '^' for two 'generic' objects -static JSValue objectBitXor(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 /*argc*/) +static js2val objectBitXor(Context *cx, const js2val /*thisValue*/, js2val argv[], uint32 /*argc*/) { - JSValue &r1 = argv[0]; - JSValue &r2 = argv[1]; - return JSValue((float64)( (int32)(r1.toInt32(cx).f64) ^ (int32)(r2.toInt32(cx).f64) )); + js2val r1 = JSValue::toInt32(cx, argv[0]); + js2val r2 = JSValue::toInt32(cx, argv[1]); + return JSValue::newNumber((float64)( (int32)(JSValue::f64(r1)) ^ (int32)(JSValue::f64(r2)) )); } // Implementation of '|' for two integer types -static JSValue integerBitOr(Context * /*cx*/, const JSValue& /*thisValue*/, JSValue *argv, uint32 /*argc*/) +static js2val integerBitOr(Context * /*cx*/, const js2val /*thisValue*/, js2val argv[], uint32 /*argc*/) { - float64 f1 = argv[0].getNumberValue(); - float64 f2 = argv[1].getNumberValue(); - return JSValue((float64)( (int32)(f1) | (int32)(f2) )); + float64 f1 = JSValue::getNumberValue(argv[0]); + float64 f2 = JSValue::getNumberValue(argv[1]); + return JSValue::newNumber((float64)( (int32)(f1) | (int32)(f2) )); } // Implementation of '|' for two 'generic' objects -static JSValue objectBitOr(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 /*argc*/) +static js2val objectBitOr(Context *cx, const js2val /*thisValue*/, js2val argv[], uint32 /*argc*/) { - JSValue &r1 = argv[0]; - JSValue &r2 = argv[1]; - return JSValue((float64)( (int32)(r1.toInt32(cx).f64) | (int32)(r2.toInt32(cx).f64) )); + js2val r1 = JSValue::toInt32(cx, argv[0]); + js2val r2 = JSValue::toInt32(cx, argv[1]); + return JSValue::newNumber((float64)( (int32)(JSValue::f64(r1)) | (int32)(JSValue::f64(r2)) )); } @@ -2068,156 +2058,149 @@ static JSValue objectBitOr(Context *cx, const JSValue& /*thisValue*/, JSValue *a // // implements r1 < r2, returning true or false or undefined // -static JSValue objectCompare(Context *cx, JSValue &r1, JSValue &r2) +static js2val objectCompare(Context *cx, js2val &r1, js2val &r2) { - JSValue r1p = r1.toPrimitive(cx, JSValue::NumberHint); - JSValue r2p = r2.toPrimitive(cx, JSValue::NumberHint); + js2val r1p = JSValue::toPrimitive(cx, r1, JSValue::NumberHint); + js2val r2p = JSValue::toPrimitive(cx, r2, JSValue::NumberHint); - if (r1p.isString() && r2p.isString()) - return JSValue(bool(r1p.string->compare(*r2p.string) < 0)); + if (JSValue::isString(r1p) && JSValue::isString(r2p)) + return JSValue::newBoolean(bool(JSValue::string(r1p)->compare(*JSValue::string(r2p)) < 0)); else { - JSValue r1n = r1p.toNumber(cx); - JSValue r2n = r2p.toNumber(cx); - if (r1n.isNaN() || r2n.isNaN()) + js2val r1n = JSValue::toNumber(cx, r1p); + js2val r2n = JSValue::toNumber(cx, r2p); + if (JSValue::isNaN(r1n) || JSValue::isNaN(r2n)) return kUndefinedValue; else - return JSValue(r1n.f64 < r2n.f64); + return JSValue::newNumber(JSValue::f64(r1n) < JSValue::f64(r2n)); } } -static JSValue objectLess(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 /*argc*/) +static js2val objectLess(Context *cx, const js2val /*thisValue*/, js2val argv[], uint32 /*argc*/) { - JSValue &r1 = argv[0]; - JSValue &r2 = argv[1]; - JSValue result = objectCompare(cx, r1, r2); - if (result.isUndefined()) + js2val result = objectCompare(cx, argv[0], argv[1]); + if (JSValue::isUndefined(result)) return kFalseValue; else return result; } -static JSValue objectLessEqual(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 /*argc*/) +static js2val objectLessEqual(Context *cx, const js2val /*thisValue*/, js2val argv[], uint32 /*argc*/) { - JSValue &r1 = argv[0]; - JSValue &r2 = argv[1]; - JSValue result = objectCompare(cx, r2, r1); - if (result.isUndefined() || result.isTrue()) + js2val result = objectCompare(cx, argv[1], argv[0]); + if (JSValue::isUndefined(result) || JSValue::isTrue(result)) return kFalseValue; else return kTrueValue; } // Compare two values for '==' -static JSValue compareEqual(Context *cx, JSValue r1, JSValue r2) +static js2val compareEqual(Context *cx, js2val r1, js2val r2) { - JSType *t1 = r1.getType(); - JSType *t2 = r2.getType(); + JSType *t1 = JSValue::getType(r1); + JSType *t2 = JSValue::getType(r2); if (t1 != t2) { - if (r1.isNull() && r2.isUndefined()) + if (JSValue::isNull(r1) && JSValue::isUndefined(r2)) return kTrueValue; - if (r1.isUndefined() && r2.isNull()) + if (JSValue::isUndefined(r1) && JSValue::isNull(r2)) return kTrueValue; if ((t1 == Number_Type) && (t2 == String_Type)) - return compareEqual(cx, r1, r2.toNumber(cx)); + return compareEqual(cx, r1, JSValue::toNumber(cx, r2)); if ((t1 == String_Type) && (t2 == Number_Type)) - return compareEqual(cx, r1.toNumber(cx), r2.toString(cx)); + return compareEqual(cx, JSValue::toNumber(cx, r1), JSValue::toString(cx, r2)); if (t1 == Boolean_Type) - return compareEqual(cx, r1.toNumber(cx), r2); + return compareEqual(cx, JSValue::toNumber(cx, r1), r2); if (t2 == Boolean_Type) - return compareEqual(cx, r1, r2.toNumber(cx)); - if ( ((t1 == String_Type) || (t1 == Number_Type)) && r2.isObject() ) - return compareEqual(cx, r1, r2.toPrimitive(cx)); - if ( (r1.isObject()) && ((t2 == String_Type) || (t2 == Number_Type)) ) - return compareEqual(cx, r1.toPrimitive(cx), r2); + return compareEqual(cx, r1, JSValue::toNumber(cx, r1)); + if ( ((t1 == String_Type) || (t1 == Number_Type)) && JSValue::isObject(r2) ) + return compareEqual(cx, r1, JSValue::toPrimitive(cx, r2)); + if ( (JSValue::isObject(r1)) && ((t2 == String_Type) || (t2 == Number_Type)) ) + return compareEqual(cx, JSValue::toPrimitive(cx, r1), r2); return kFalseValue; } else { - if (r1.isUndefined()) + if (JSValue::isUndefined(r1)) return kTrueValue; - if (r1.isNull()) + if (JSValue::isNull(r1)) return kTrueValue; - if (r1.isInstance() && r2.isInstance()) // because new Boolean()->getType() == Boolean_Type - return JSValue(r1.instance == r2.instance); - if (r1.isObject() && r2.isObject()) - return JSValue(r1.object == r2.object); - if (r1.isPackage() && r2.isPackage()) - return JSValue(r1.package == r2.package); - if (r1.isType()) - return JSValue(r1.type == r2.type); - if (r1.isFunction()) - return JSValue(r1.function->isEqual(r2.function)); + if (JSValue::isInstance(r1) && JSValue::isInstance(r2)) // because new Boolean()->getType() == Boolean_Type + return JSValue::newBoolean(JSValue::instance(r1) == JSValue::instance(r2)); + if (JSValue::isObject(r1) && JSValue::isObject(r2)) + return JSValue::newBoolean(JSValue::object(r1) == JSValue::object(r2)); + if (JSValue::isPackage(r1) && JSValue::isPackage(r2)) + return JSValue::newBoolean(JSValue::package(r1) == JSValue::package(r2)); + if (JSValue::isType(r1)) + return JSValue::newBoolean(JSValue::type(r1) == JSValue::type(r2)); + if (JSValue::isFunction(r1)) + return JSValue::newBoolean(JSValue::function(r1)->isEqual(JSValue::function(r2))); if (t1 == Number_Type) { - float64 f1 = r1.getNumberValue(); - float64 f2 = r2.getNumberValue(); + float64 f1 = JSValue::getNumberValue(r1); + float64 f2 = JSValue::getNumberValue(r2); if (JSDOUBLE_IS_NaN(f1)) return kFalseValue; if (JSDOUBLE_IS_NaN(f2)) return kFalseValue; - return JSValue(r1.f64 == r2.f64); + return JSValue::newBoolean(JSValue::f64(r1) == JSValue::f64(r2)); } else { if (t1 == String_Type) - return JSValue(bool(r1.getStringValue()->compare(*r2.getStringValue()) == 0)); + return JSValue::newBoolean(bool(JSValue::getStringValue(r1)->compare(*JSValue::getStringValue(r2)) == 0)); if (t1 == Boolean_Type) - return JSValue(r1.getBoolValue() == r2.getBoolValue()); + return JSValue::newBoolean(JSValue::getBoolValue(r1) == JSValue::getBoolValue(r2)); NOT_REACHED("unhandled type"); return kFalseValue; } } } -static JSValue objectEqual(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 /*argc*/) +static js2val objectEqual(Context *cx, const js2val /*thisValue*/, js2val argv[], uint32 /*argc*/) { - JSValue r1 = argv[0]; - JSValue r2 = argv[1]; - - return compareEqual(cx, r1, r2); + return compareEqual(cx, argv[0], argv[1]); } -static JSValue objectSpittingImage(Context * /*cx*/, const JSValue& /*thisValue*/, JSValue *argv, uint32 /*argc*/) +static js2val objectSpittingImage(Context * /*cx*/, const js2val /*thisValue*/, js2val argv[], uint32 /*argc*/) { - JSValue r1 = argv[0]; - JSValue r2 = argv[1]; + js2val r1 = argv[0]; + js2val r2 = argv[1]; - JSType *t1 = r1.getType(); - JSType *t2 = r2.getType(); + JSType *t1 = JSValue::getType(r1); + JSType *t2 = JSValue::getType(r2); - if ((t1 != t2) || (r1.isObject() != r2.isObject())) { + if ((t1 != t2) || (JSValue::isObject(r1) != JSValue::isObject(r2))) { return kFalseValue; } else { - if (r1.isUndefined()) + if (JSValue::isUndefined(r1)) return kTrueValue; - if (r1.isNull()) + if (JSValue::isNull(r1)) return kTrueValue; - if (r1.isObject() && r2.isObject()) // because new Boolean()->getType() == Boolean_Type - return JSValue(r1.object == r2.object); - if (r1.isType()) - return JSValue(r1.type == r2.type); - if (r1.isFunction()) - return JSValue(r1.function->isEqual(r2.function)); + if (JSValue::isObject(r1) && JSValue::isObject(r2)) // because new Boolean()->getType() == Boolean_Type + return JSValue::newBoolean(JSValue::object(r1) == JSValue::object(r2)); + if (JSValue::isType(r1)) + return JSValue::newBoolean(JSValue::type(r1) == JSValue::type(r2)); + if (JSValue::isFunction(r1)) + return JSValue::newBoolean(JSValue::function(r1)->isEqual(JSValue::function(r2))); if (t1 == Number_Type) { - float64 f1 = r1.getNumberValue(); - float64 f2 = r2.getNumberValue(); + float64 f1 = JSValue::getNumberValue(r1); + float64 f2 = JSValue::getNumberValue(r2); if (JSDOUBLE_IS_NaN(f1)) return kFalseValue; if (JSDOUBLE_IS_NaN(f2)) return kFalseValue; - return JSValue(r1.f64 == r2.f64); + return JSValue::newBoolean(JSValue::f64(r1) == JSValue::f64(r2)); } else { if (t1 == String_Type) - return JSValue(bool(r1.getStringValue()->compare(*r2.getStringValue()) == 0)); - if (r1.isBool() && r2.isBool()) - return JSValue(r1.getBoolValue() == r2.getBoolValue()); + return JSValue::newBoolean(bool(JSValue::getStringValue(r1)->compare(*JSValue::getStringValue(r2)) == 0)); + if (JSValue::isBool(r1) && JSValue::isBool(r2)) + return JSValue::newBoolean(JSValue::getBoolValue(r1) == JSValue::getBoolValue(r2)); return kFalseValue; } } @@ -2279,7 +2262,7 @@ void Context::initOperators() }; for (uint32 i = 0; i < sizeof(OpTable) / sizeof(OpTableEntry); i++) { - JSFunction *f = new JSFunction(this, OpTable[i].imp, OpTable[i].resType); + JSFunction *f = new JSFunction(this, OpTable[i].imp, OpTable[i].resType, NULL); OperatorDefinition *op = new OperatorDefinition(OpTable[i].op1, OpTable[i].op2, f); mBinaryOperatorTable[OpTable[i].which].push_back(op); } @@ -2292,36 +2275,32 @@ void Context::initOperators() // so that the behaviour here of constructing a new instance of those types would // be different? -JSValue JSValue::valueToObject(Context *cx, const JSValue& value) +js2val JSValue::valueToObject(Context *cx, const js2val value) { - switch (value.tag) { - case f64_tag: + switch (tag(value)) { + case JS2VAL_DOUBLE: { - JSValue result = Number_Type->newInstance(cx); - ((JSNumberInstance *)result.instance)->mValue = value.f64; - return JSValue(result); + js2val result = Number_Type->newInstance(cx); + ((JSNumberInstance *)JSValue::instance(result))->mValue = JSValue::f64(value); + return result; } - case boolean_tag: + case JS2VAL_BOOLEAN: { - JSValue result = Boolean_Type->newInstance(cx); - ((JSBooleanInstance *)result.instance)->mValue = value.boolean; - return JSValue(result); + js2val result = Boolean_Type->newInstance(cx); + ((JSBooleanInstance *)JSValue::instance(result))->mValue = JSValue::boolean(value); + return result; } - case string_tag: + case JS2VAL_STRING: { - JSValue result = String_Type->newInstance(cx); - ((JSStringInstance *)result.instance)->mValue = value.string; - return JSValue(result); + js2val result = String_Type->newInstance(cx); + ((JSStringInstance *)JSValue::instance(result))->mValue = JSValue::string(value); + return result; } - case instance_tag: - case package_tag: - case type_tag: - case object_tag: - case function_tag: + case JS2VAL_OBJECT: + if (isNull(value)) + cx->reportError(Exception::typeError, "converting null to object"); return value; - case null_tag: - cx->reportError(Exception::typeError, "converting null to object"); - case undefined_tag: + case JS2VAL_INT: cx->reportError(Exception::typeError, "converting undefined to object"); default: NOT_REACHED("Bad tag"); @@ -2338,40 +2317,32 @@ JSValue JSValue::valueToObject(Context *cx, const JSValue& value) // be different? -JSObject *JSValue::toObjectValue(Context *cx) const +JSObject *JSValue::toObjectValue(Context *cx, const js2val v) { - switch (tag) { - case f64_tag: + switch (tag(v)) { + case JS2VAL_DOUBLE: { - JSValue result = Number_Type->newInstance(cx); - ((JSNumberInstance *)result.instance)->mValue = f64; - return result.instance; + js2val result = Number_Type->newInstance(cx); + ((JSNumberInstance *)JSValue::instance(result))->mValue = JSValue::f64(v); + return JSValue::instance(result); } - case boolean_tag: + case JS2VAL_BOOLEAN: { - JSValue result = Boolean_Type->newInstance(cx); - ((JSBooleanInstance *)result.instance)->mValue = boolean; - return result.instance; + js2val result = Boolean_Type->newInstance(cx); + ((JSBooleanInstance *)JSValue::instance(result))->mValue = JSValue::boolean(v); + return JSValue::instance(result); } - case string_tag: + case JS2VAL_STRING: { - JSValue result = String_Type->newInstance(cx); - ((JSStringInstance *)result.instance)->mValue = string; - return result.instance; + js2val result = String_Type->newInstance(cx); + ((JSStringInstance *)JSValue::instance(result))->mValue = JSValue::string(v); + return JSValue::instance(result); } - case type_tag: - return type; - case object_tag: - return object; - case function_tag: - return function; - case instance_tag: - return instance; - case package_tag: - return package; - case null_tag: - cx->reportError(Exception::typeError, "converting null to object"); - case undefined_tag: + case JS2VAL_OBJECT: + if (isNull(v)) + cx->reportError(Exception::typeError, "converting null to object"); + return JSValue::object(v); + case JS2VAL_INT: cx->reportError(Exception::typeError, "converting undefined to object"); default: NOT_REACHED("Bad tag"); @@ -2406,25 +2377,22 @@ float64 stringToNumber(const String *string) } // Convert a JSValue to number-type -JSValue JSValue::valueToNumber(Context *cx, const JSValue& value) +js2val JSValue::valueToNumber(Context *cx, const js2val value) { - switch (value.tag) { - case f64_tag: + switch (tag(value)) { + case JS2VAL_DOUBLE: return value; - case string_tag: - return JSValue(stringToNumber(value.string)); - case object_tag: - case instance_tag: - case package_tag: - case type_tag: - case function_tag: - return value.toPrimitive(cx, NumberHint).toNumber(cx); - case boolean_tag: - return JSValue((value.boolean) ? 1.0 : 0.0); - case undefined_tag: + case JS2VAL_STRING: + return JSValue::newNumber(stringToNumber(JSValue::string(value))); + case JS2VAL_OBJECT: + if (isNull(value)) + return kPositiveZero; + else + return JSValue::toNumber(cx, JSValue::toPrimitive(cx, value, NumberHint)); + case JS2VAL_BOOLEAN: + return JSValue::newNumber((JSValue::boolean(value)) ? 1.0 : 0.0); + case JS2VAL_INT: return kNaNValue; - case null_tag: - return kPositiveZero; default: NOT_REACHED("Bad tag"); return kUndefinedValue; @@ -2440,39 +2408,27 @@ const String *numberToString(float64 number) } // Convert a JSValue to a string (ECMA rules) -JSValue JSValue::valueToString(Context *cx, const JSValue& value) +js2val JSValue::valueToString(Context *cx, const js2val value) { const String *strp = NULL; JSObject *obj = NULL; - switch (value.tag) { - case f64_tag: - return JSValue(numberToString(value.f64)); - case object_tag: - obj = value.object; + switch (tag(value)) { + case JS2VAL_DOUBLE: + return JSValue::newString(numberToString(JSValue::f64(value))); + case JS2VAL_OBJECT: + if (isNull(value)) + strp = &cx->Null_StringAtom; + else + obj = JSValue::object(value); break; - case function_tag: - obj = value.function; - break; - case string_tag: + case JS2VAL_STRING: return value; - case boolean_tag: - strp = (value.boolean) ? &cx->True_StringAtom : &cx->False_StringAtom; + case JS2VAL_BOOLEAN: + strp = (JSValue::boolean(value)) ? &cx->True_StringAtom : &cx->False_StringAtom; break; - case type_tag: - strp = value.type->mClassName; - break; - case undefined_tag: + case JS2VAL_INT: strp = &cx->Undefined_StringAtom; break; - case null_tag: - strp = &cx->Null_StringAtom; - break; - case instance_tag: - obj = value.instance; - break; - case package_tag: - obj = value.package; - break; default: NOT_REACHED("Bad tag"); } @@ -2480,15 +2436,15 @@ JSValue JSValue::valueToString(Context *cx, const JSValue& value) JSFunction *target = NULL; PropertyIterator i; if (obj->hasProperty(cx, cx->ToString_StringAtom, NULL, Read, &i)) { - JSValue v = obj->getPropertyValue(i); - if (v.isFunction()) - target = v.function; + js2val v = obj->getPropertyValue(i); + if (JSValue::isFunction(v)) + target = JSValue::function(v); } if (target == NULL) { if (obj->hasProperty(cx, cx->ValueOf_StringAtom, NULL, Read, &i)) { - JSValue v = obj->getPropertyValue(i); - if (v.isFunction()) - target = v.function; + js2val v = obj->getPropertyValue(i); + if (JSValue::isFunction(v)) + target = JSValue::function(v); } } if (target) @@ -2497,32 +2453,26 @@ JSValue JSValue::valueToString(Context *cx, const JSValue& value) return kUndefinedValue; // keep compilers happy } else - return JSValue(strp); + return JSValue::newString(strp); } // Convert a JSValue to a primitive type -JSValue JSValue::toPrimitive(Context *cx, Hint hint) const +js2val JSValue::toPrimitive(Context *cx, const js2val v, Hint hint) { JSObject *obj; - switch (tag) { - case f64_tag: - case string_tag: - case boolean_tag: - case undefined_tag: - return *this; + switch (tag(v)) { + case JS2VAL_DOUBLE: + case JS2VAL_STRING: + case JS2VAL_BOOLEAN: + case JS2VAL_INT: + return v; - case instance_tag: - obj = instance; - if ((hint == NoHint) && (getType() == Date_Type)) + case JS2VAL_OBJECT: + obj = JSValue::object(v); + if ((hint == NoHint) && (getType(v) == Date_Type)) hint = StringHint; break; - case object_tag: - obj = object; - break; - case function_tag: - obj = function; - break; default: NOT_REACHED("Bad tag"); @@ -2533,7 +2483,7 @@ JSValue JSValue::toPrimitive(Context *cx, Hint hint) const // ASSERT(obj); JSFunction *target = NULL; - JSValue result; + js2val result; PropertyIterator i; StringAtom *first = &cx->ValueOf_StringAtom; @@ -2546,23 +2496,23 @@ JSValue JSValue::toPrimitive(Context *cx, Hint hint) const if (obj->hasProperty(cx, *first, NULL, Read, &i)) { - JSValue v = obj->getPropertyValue(i); - if (v.isFunction()) { - target = v.function; + js2val v = obj->getPropertyValue(i); + if (JSValue::isFunction(v)) { + target = JSValue::function(v); if (target) { - result = cx->invokeFunction(target, *this, NULL, 0); - if (result.isPrimitive()) + result = cx->invokeFunction(target, v, NULL, 0); + if (JSValue::isPrimitive(result)) return result; } } } if (obj->hasProperty(cx, *second, NULL, Read, &i)) { - JSValue v = obj->getPropertyValue(i); - if (v.isFunction()) { - target = v.function; + js2val v = obj->getPropertyValue(i); + if (JSValue::isFunction(v)) { + target = JSValue::function(v); if (target) { - result = cx->invokeFunction(target, *this, NULL, 0); - if (result.isPrimitive()) + result = cx->invokeFunction(target, v, NULL, 0); + if (JSValue::isPrimitive(result)) return result; } } @@ -2571,6 +2521,7 @@ JSValue JSValue::toPrimitive(Context *cx, Hint hint) const return kUndefinedValue; } +/* int JSValue::operator==(const JSValue& value) const { if (this->tag == value.tag) { @@ -2588,7 +2539,7 @@ int JSValue::operator==(const JSValue& value) const } return 0; } - +*/ float64 JSValue::float64ToInteger(float64 d) { if (JSDOUBLE_IS_NaN(d)) @@ -2597,11 +2548,10 @@ float64 JSValue::float64ToInteger(float64 d) return (d >= 0.0) ? fd::floor(d) : -fd::floor(-d); } -JSValue JSValue::valueToInteger(Context *cx, const JSValue& value) +js2val JSValue::valueToInteger(Context *cx, const js2val value) { - JSValue v = valueToNumber(cx, value); - v.f64 = float64ToInteger(v.f64); - return v; + js2val v = valueToNumber(cx, value); + return JSValue::newNumber(float64ToInteger(JSValue::f64(v))); } int32 JSValue::float64ToInt32(float64 d) @@ -2624,23 +2574,24 @@ uint32 JSValue::float64ToUInt32(float64 d) return (uint32)d; } -JSValue JSValue::valueToInt32(Context *, const JSValue& value) +js2val JSValue::valueToInt32(Context *, const js2val value) { float64 d; - switch (value.tag) { - case f64_tag: - d = value.f64; + switch (tag(value)) { + case JS2VAL_DOUBLE: + d = JSValue::f64(value); break; - case string_tag: + case JS2VAL_STRING: { const char16 *numEnd; - d = stringToDouble(value.string->begin(), value.string->end(), numEnd); + const String *str = JSValue::string(value); + d = stringToDouble(str->begin(), str->end(), numEnd); } break; - case boolean_tag: - return JSValue((float64)((value.boolean) ? 1 : 0)); - case object_tag: - case undefined_tag: + case JS2VAL_BOOLEAN: + return JSValue::newNumber((float64)((JSValue::boolean(value)) ? 1 : 0)); + case JS2VAL_OBJECT: + case JS2VAL_INT: // toNumber(toPrimitive(hint Number)) return kUndefinedValue; default: @@ -2648,27 +2599,28 @@ JSValue JSValue::valueToInt32(Context *, const JSValue& value) return kUndefinedValue; } if ((d == 0.0) || !JSDOUBLE_IS_FINITE(d) ) - return JSValue((float64)0); - return JSValue((float64)float64ToInt32(d)); + return JSValue::newNumber((float64)0); + return JSValue::newNumber((float64)float64ToInt32(d)); } -JSValue JSValue::valueToUInt32(Context *, const JSValue& value) +js2val JSValue::valueToUInt32(Context *, const js2val value) { float64 d; - switch (value.tag) { - case f64_tag: - d = value.f64; + switch (tag(value)) { + case JS2VAL_DOUBLE: + d = JSValue::f64(value); break; - case string_tag: + case JS2VAL_STRING: { const char16 *numEnd; - d = stringToDouble(value.string->begin(), value.string->end(), numEnd); + const String *str = JSValue::string(value); + d = stringToDouble(str->begin(), str->end(), numEnd); } break; - case boolean_tag: - return JSValue((float64)((value.boolean) ? 1 : 0)); - case object_tag: - case undefined_tag: + case JS2VAL_BOOLEAN: + return JSValue::newNumber((float64)((JSValue::boolean(value)) ? 1 : 0)); + case JS2VAL_OBJECT: + case JS2VAL_INT: // toNumber(toPrimitive(hint Number)) return kUndefinedValue; default: @@ -2676,27 +2628,28 @@ JSValue JSValue::valueToUInt32(Context *, const JSValue& value) return kUndefinedValue; } if ((d == 0.0) || !JSDOUBLE_IS_FINITE(d)) - return JSValue((float64)0); - return JSValue((float64)float64ToUInt32(d)); + return JSValue::newNumber((float64)0); + return JSValue::newNumber((float64)float64ToUInt32(d)); } -JSValue JSValue::valueToUInt16(Context *, const JSValue& value) +js2val JSValue::valueToUInt16(Context *, const js2val value) { float64 d; - switch (value.tag) { - case f64_tag: - d = value.f64; + switch (tag(value)) { + case JS2VAL_DOUBLE: + d = JSValue::f64(value); break; - case string_tag: + case JS2VAL_STRING: { const char16 *numEnd; - d = stringToDouble(value.string->begin(), value.string->end(), numEnd); + const String *str = JSValue::string(value); + d = stringToDouble(str->begin(), str->end(), numEnd); } break; - case boolean_tag: - return JSValue((float64)((value.boolean) ? 1 : 0)); - case object_tag: - case undefined_tag: + case JS2VAL_BOOLEAN: + return JSValue::newNumber((float64)((JSValue::boolean(value)) ? 1 : 0)); + case JS2VAL_OBJECT: + case JS2VAL_INT: // toNumber(toPrimitive(hint Number)) return kUndefinedValue; default: @@ -2704,36 +2657,34 @@ JSValue JSValue::valueToUInt16(Context *, const JSValue& value) return kUndefinedValue; } if ((d == 0.0) || !JSDOUBLE_IS_FINITE(d)) - return JSValue((float64)0); + return JSValue::newNumber((float64)0); bool neg = (d < 0); d = fd::floor(neg ? -d : d); d = neg ? -d : d; d = fd::fmod(d, two16); d = (d >= 0) ? d : d + two16; - return JSValue((float64)d); + return JSValue::newNumber((float64)d); } -JSValue JSValue::valueToBoolean(Context * /*cx*/, const JSValue& value) +js2val JSValue::valueToBoolean(Context * /*cx*/, const js2val value) { - switch (value.tag) { - case f64_tag: - if (JSDOUBLE_IS_NaN(value.f64)) + switch (tag(value)) { + case JS2VAL_DOUBLE: + if (isNaN(value)) return kFalseValue; - if (value.f64 == 0.0) + if (f64(value) == 0.0) return kFalseValue; return kTrueValue; - case string_tag: - return JSValue(value.string->length() != 0); - case boolean_tag: + case JS2VAL_STRING: + return JSValue::newBoolean(JSValue::string(value)->length() != 0); + case JS2VAL_BOOLEAN: return value; - case type_tag: - case instance_tag: - case object_tag: - case function_tag: - return kTrueValue; - break; - case null_tag: - case undefined_tag: + case JS2VAL_OBJECT: + if (isNull(value)) + return kFalseValue; + else + return kTrueValue; + case JS2VAL_INT: return kFalseValue; default: NOT_REACHED("Bad tag"); @@ -2744,53 +2695,56 @@ JSValue JSValue::valueToBoolean(Context * /*cx*/, const JSValue& value) // See if 'v' can be represented as a 't' - works for // the built-ins by falling back to the ECMA3 behaviour -JSValue Context::mapValueToType(JSValue v, JSType *t) +js2val Context::mapValueToType(js2val v, JSType *t) { // user conversions? - if (v.getType() == t) + if (JSValue::getType(v) == t) return v; if (t == Number_Type) { - return v.toNumber(this); + return JSValue::toNumber(this, v); } else if (t == Integer_Type) { - float64 d = v.toNumber(this).f64; + js2val fv = JSValue::toNumber(this, v); + float64 d = JSValue::f64(fv); bool neg = (d < 0); d = fd::floor(neg ? -d : d); d = neg ? -d : d; - return JSValue(d); + return JSValue::newNumber(d); } else if (t == String_Type) { - return v.toString(this); + return JSValue::toString(this, v); } else if (t == Boolean_Type) { - return v.toBoolean(this); + return JSValue::toBoolean(this, v); } - if (v.isUndefined()) + if (JSValue::isUndefined(v)) return v; - if (v.getType()->derivesFrom(t)) + if (JSValue::getType(v)->derivesFrom(t)) return v; reportError(Exception::typeError, "Invalid type cast"); return kUndefinedValue; } -JSType *JSValue::getType() const { - switch (tag) { - case f64_tag: return Number_Type; - case boolean_tag: return Boolean_Type; - case string_tag: return (JSType *)String_Type; - case object_tag: return Object_Type; - case instance_tag: return instance->getType(); - case undefined_tag: return Void_Type; - case null_tag: return Null_Type; - case function_tag: return Function_Type; - case type_tag: return Type_Type; +JSType *JSValue::getType(const js2val v) { + switch (tag(v)) { + case JS2VAL_DOUBLE: return Number_Type; + case JS2VAL_BOOLEAN: return Boolean_Type; + case JS2VAL_STRING: return (JSType *)String_Type; + case JS2VAL_OBJECT: if (isNull(v)) + return Null_Type; + else + if (isInstance(v)) + return JSValue::instance(v)->getType(); + else + return Object_Type; + case JS2VAL_INT: return Void_Type; default: NOT_REACHED("bad type"); return NULL; diff --git a/mozilla/js2/src/js2runtime.cpp b/mozilla/js2/src/js2runtime.cpp index 7424eebf858..a6540935ff9 100644 --- a/mozilla/js2/src/js2runtime.cpp +++ b/mozilla/js2/src/js2runtime.cpp @@ -101,10 +101,10 @@ Attribute *Context::executeAttributes(ExprNode *attr) ByteCodeGen bcg(this, mScopeChain); ByteCodeModule *bcm = bcg.genCodeForExpression(attr); // stdOut << *bcm; - JSValue result = interpret(bcm, 0, NULL, JSValue(getGlobalObject()), NULL, 0); + js2val result = interpret(bcm, 0, NULL, JSValue::newObject(getGlobalObject()), NULL, 0); - ASSERT(result.isAttribute()); - return result.attribute; + ASSERT(JSValue::isAttribute(result)); + return JSValue::attribute(result); } @@ -177,8 +177,8 @@ bool JSObject::hasProperty(Context *cx, const String &name, NamespaceList *names if (hasOwnProperty(cx, name, names, acc, p)) return true; else - if (!mPrototype.isNull()) - return mPrototype.getObjectValue()->hasProperty(cx, name, names, acc, p); + if (!JSValue::isNull(mPrototype)) + return JSValue::getObjectValue(mPrototype)->hasProperty(cx, name, names, acc, p); else return false; } @@ -197,16 +197,16 @@ bool JSObject::deleteProperty(Context * /*cx*/, const String &name, NamespaceLis // get a property value -JSValue JSObject::getPropertyValue(PropertyIterator &i) +js2val JSObject::getPropertyValue(PropertyIterator &i) { Property *prop = PROPERTY(i); ASSERT(prop->mFlag == ValuePointer); - return *prop->mData.vp; + return prop->mData.vp; } -Property *JSObject::insertNewProperty(const String &name, NamespaceList *names, PropertyAttribute attrFlags, JSType *type, const JSValue &v) +Property *JSObject::insertNewProperty(const String &name, NamespaceList *names, PropertyAttribute attrFlags, JSType *type, const js2val v) { - Property *prop = new Property(new JSValue(v), type, attrFlags); + Property *prop = new Property(v, type, attrFlags); const PropertyMap::value_type e(name, new NamespacedProperty(prop, names)); mProperties.insert(e); return prop; @@ -273,7 +273,7 @@ Property *JSObject::defineVariable(Context *cx, const String &name, AttributeStm } } - Property *prop = new Property(new JSValue(), type, attrFlags); + Property *prop = new Property(kUndefinedValue, type, attrFlags); const PropertyMap::value_type e(name, new NamespacedProperty(prop, names)); mProperties.insert(e); return prop; @@ -288,14 +288,14 @@ Property *JSObject::defineVariable(Context *cx, const String &name, NamespaceLis } } - Property *prop = new Property(new JSValue(), type, attrFlags); + Property *prop = new Property(kUndefinedValue, type, attrFlags); const PropertyMap::value_type e(name, new NamespacedProperty(prop, names)); mProperties.insert(e); return prop; } // add a property (with a value) -Property *JSObject::defineVariable(Context *cx, const String &name, AttributeStmtNode *attr, JSType *type, const JSValue v) +Property *JSObject::defineVariable(Context *cx, const String &name, AttributeStmtNode *attr, JSType *type, const js2val v) { NamespaceList *names = (attr) ? attr->attributeValue->mNamespaceList : NULL; PropertyAttribute attrFlags = (attr) ? attr->attributeValue->mTrueFlags : 0; @@ -311,17 +311,17 @@ Property *JSObject::defineVariable(Context *cx, const String &name, AttributeStm } else { // override the existing value - PROPERTY_VALUEPOINTER(it) = new JSValue(v); + PROPERTY_VALUEPOINTER(it) = v; return PROPERTY(it); } } - Property *prop = new Property(new JSValue(v), type, attrFlags); + Property *prop = new Property(v, type, attrFlags); const PropertyMap::value_type e(name, new NamespacedProperty(prop, names)); mProperties.insert(e); return prop; } -Property *JSObject::defineVariable(Context *cx, const String &name, NamespaceList *names, PropertyAttribute attrFlags, JSType *type, const JSValue v) +Property *JSObject::defineVariable(Context *cx, const String &name, NamespaceList *names, PropertyAttribute attrFlags, JSType *type, const js2val v) { PropertyIterator it; if (hasOwnProperty(cx, name, names, Read, &it)) { @@ -330,23 +330,17 @@ Property *JSObject::defineVariable(Context *cx, const String &name, NamespaceLis } } - Property *prop = new Property(new JSValue(v), type, attrFlags); + Property *prop = new Property(v, type, attrFlags); const PropertyMap::value_type e(name, new NamespacedProperty(prop, names)); mProperties.insert(e); return prop; } -Property *JSObject::defineAlias(Context * /*cx*/, const String &name, NamespaceList *names, PropertyAttribute attrFlags, JSType *type, JSValue *vp) - +Property *JSObject::defineAlias(Context * /*cx*/, const String &name, NamespaceList *names, PropertyAttribute attrFlags, JSType *type, js2val vp) { - Property *prop = new Property(vp, type, attrFlags); - const PropertyMap::value_type e(name, new NamespacedProperty(prop, names)); - mProperties.insert(e); - return prop; - } @@ -387,10 +381,10 @@ void JSObject::getProperty(Context *cx, const String &name, NamespaceList *names Property *prop = PROPERTY(i); switch (prop->mFlag) { case ValuePointer: - cx->pushValue(*prop->mData.vp); + cx->pushValue(prop->mData.vp); break; case FunctionPair: - cx->pushValue(cx->invokeFunction(prop->mData.fPair.getterF, JSValue(this), NULL, 0)); + cx->pushValue(cx->invokeFunction(prop->mData.fPair.getterF, JSValue::newObject(this), NULL, 0)); break; default: ASSERT(false); // XXX more to implement @@ -398,8 +392,8 @@ void JSObject::getProperty(Context *cx, const String &name, NamespaceList *names } } else { - if (!mPrototype.isNull()) - mPrototype.getObjectValue()->getProperty(cx, name, names); + if (!JSValue::isNull(mPrototype)) + JSValue::getObjectValue(mPrototype)->getProperty(cx, name, names); else cx->pushValue(kUndefinedValue); } @@ -428,17 +422,17 @@ void JSInstance::getProperty(Context *cx, const String &name, NamespaceList *nam cx->pushValue(mInstanceValues[prop->mData.index]); break; case ValuePointer: - cx->pushValue(*prop->mData.vp); + cx->pushValue(prop->mData.vp); break; case FunctionPair: - cx->pushValue(cx->invokeFunction(prop->mData.fPair.getterF, JSValue(this), NULL, 0)); + cx->pushValue(cx->invokeFunction(prop->mData.fPair.getterF, JSValue::newObject(this), NULL, 0)); break; case Constructor: case Method: - cx->pushValue(JSValue(mType->mMethods[prop->mData.index])); + cx->pushValue(JSValue::newFunction(mType->mMethods[prop->mData.index])); break; case IndexPair: - cx->pushValue(cx->invokeFunction(mType->mMethods[prop->mData.iPair.getterI], JSValue(this), NULL, 0)); + cx->pushValue(cx->invokeFunction(mType->mMethods[prop->mData.iPair.getterI], JSValue::newObject(this), NULL, 0)); break; default: ASSERT(false); // XXX more to implement @@ -455,7 +449,7 @@ XXX this path allows an instance to access static fields of it's type JSObject::getProperty(cx, name, names); } -void JSObject::setProperty(Context *cx, const String &name, NamespaceList *names, const JSValue &v) +void JSObject::setProperty(Context *cx, const String &name, NamespaceList *names, const js2val v) { PropertyIterator i; if (hasOwnProperty(cx, name, names, Write, &i)) { @@ -465,12 +459,12 @@ void JSObject::setProperty(Context *cx, const String &name, NamespaceList *names case ValuePointer: if (name.compare(cx->UnderbarPrototype_StringAtom) == 0) mPrototype = v; - *prop->mData.vp = v; + prop->mData.vp = v; break; case FunctionPair: { - JSValue argv = v; - cx->invokeFunction(prop->mData.fPair.setterF, JSValue(this), &argv, 1); + js2val argv = v; + cx->invokeFunction(prop->mData.fPair.setterF, JSValue::newObject(this), &argv, 1); } break; default: @@ -482,7 +476,7 @@ void JSObject::setProperty(Context *cx, const String &name, NamespaceList *names defineVariable(cx, name, names, Property::Enumerable, Object_Type, v); } -void JSType::setProperty(Context *cx, const String &name, NamespaceList *names, const JSValue &v) +void JSType::setProperty(Context *cx, const String &name, NamespaceList *names, const js2val v) { PropertyIterator i; if (hasOwnProperty(cx, name, names, Read, &i)) @@ -494,7 +488,7 @@ void JSType::setProperty(Context *cx, const String &name, NamespaceList *names, JSObject::setProperty(cx, name, names, v); } -void JSInstance::setProperty(Context *cx, const String &name, NamespaceList *names, const JSValue &v) +void JSInstance::setProperty(Context *cx, const String &name, NamespaceList *names, const js2val v) { PropertyIterator i; if (hasOwnProperty(cx, name, names, Write, &i)) { @@ -505,18 +499,18 @@ void JSInstance::setProperty(Context *cx, const String &name, NamespaceList *nam mInstanceValues[prop->mData.index] = v; break; case ValuePointer: - *prop->mData.vp = v; + prop->mData.vp = v; break; case FunctionPair: { - JSValue argv = v; - cx->invokeFunction(prop->mData.fPair.setterF, JSValue(this), &argv, 1); + js2val argv = v; + cx->invokeFunction(prop->mData.fPair.setterF, JSValue::newObject(this), &argv, 1); } break; case IndexPair: { - JSValue argv = v; - cx->invokeFunction(mType->mMethods[prop->mData.iPair.setterI], JSValue(this), &argv, 1); + js2val argv = v; + cx->invokeFunction(mType->mMethods[prop->mData.iPair.setterI], JSValue::newObject(this), &argv, 1); } break; default: @@ -537,16 +531,16 @@ void JSInstance::setProperty(Context *cx, const String &name, NamespaceList *nam void JSArrayInstance::getProperty(Context *cx, const String &name, NamespaceList *names) { if (name.compare(cx->Length_StringAtom) == 0) - cx->pushValue(JSValue((float64)mLength)); + cx->pushValue(JSValue::newNumber((float64)mLength)); else JSInstance::getProperty(cx, name, names); } -void JSArrayInstance::setProperty(Context *cx, const String &name, NamespaceList *names, const JSValue &v) +void JSArrayInstance::setProperty(Context *cx, const String &name, NamespaceList *names, const js2val v) { if (name.compare(cx->Length_StringAtom) == 0) { - uint32 newLength = (uint32)(v.toUInt32(cx).f64); - if (newLength != v.toNumber(cx).f64) + uint32 newLength = (uint32)JSValue::f64(JSValue::toUInt32(cx, v)); + if (newLength != JSValue::f64(JSValue::toNumber(cx, v))) cx->reportError(Exception::rangeError, "out of range value for length"); for (uint32 i = newLength; i < mLength; i++) { @@ -565,13 +559,13 @@ void JSArrayInstance::setProperty(Context *cx, const String &name, NamespaceList else { Property *prop = PROPERTY(it); ASSERT(prop->mFlag == ValuePointer); - *prop->mData.vp = v; + prop->mData.vp = v; } - JSValue v = JSValue(&name); - JSValue v_int = v.toUInt32(cx); - if ((v_int.f64 != two32minus1) && (v_int.toString(cx).string->compare(name) == 0)) { - if (v_int.f64 >= mLength) - mLength = (uint32)(v_int.f64) + 1; + js2val v = JSValue::newString(&name); + js2val v_int = JSValue::toUInt32(cx, v); + if ((JSValue::f64(v_int) != two32minus1) && (JSValue::string(JSValue::toString(cx, v_int))->compare(name) == 0)) { + if (JSValue::f64(v_int) >= mLength) + mLength = (uint32)(JSValue::f64(v_int)) + 1; } } } @@ -598,12 +592,12 @@ bool JSArrayInstance::deleteProperty(Context *cx, const String &name, NamespaceL void JSStringInstance::getProperty(Context *cx, const String &name, NamespaceList *names) { if (name.compare(cx->Length_StringAtom) == 0) - cx->pushValue(JSValue((float64)(mValue->size()))); + cx->pushValue(JSValue::newNumber((float64)(mValue->size()))); else JSInstance::getProperty(cx, name, names); } -void JSStringInstance::setProperty(Context *cx, const String &name, NamespaceList *names, const JSValue &v) +void JSStringInstance::setProperty(Context *cx, const String &name, NamespaceList *names, const js2val v) { if (name.compare(cx->Length_StringAtom) == 0) { } @@ -634,7 +628,7 @@ bool JSStringInstance::deleteProperty(Context *cx, const String &name, Namespace void JSInstance::initInstance(Context *cx, JSType *type) { if (type->mVariableCount) - mInstanceValues = new JSValue[type->mVariableCount]; + mInstanceValues = new js2val[type->mVariableCount]; // copy the instance variable names into the property map for (PropertyIterator pi = type->mProperties.begin(), @@ -658,13 +652,13 @@ void JSInstance::initInstance(Context *cx, JSType *type) } } if (t->mInstanceInitializer) - cx->invokeFunction(t->mInstanceInitializer, JSValue(this), NULL, 0); + cx->invokeFunction(t->mInstanceInitializer, JSValue::newObject(this), NULL, 0); t = t->mSuperType; } // run the initializer if (type->mInstanceInitializer) { - cx->invokeFunction(type->mInstanceInitializer, JSValue(this), NULL, 0); + cx->invokeFunction(type->mInstanceInitializer, JSValue::newObject(this), NULL, 0); } mType = type; @@ -673,20 +667,20 @@ void JSInstance::initInstance(Context *cx, JSType *type) // Create a new (empty) instance of this class. The prototype // link for this new instance is established from the type's // prototype object. -JSValue JSType::newInstance(Context *cx) +js2val JSType::newInstance(Context *cx) { JSInstance *result = new JSInstance(cx, this); result->mPrototype = mPrototypeObject; result->defineVariable(cx, cx->UnderbarPrototype_StringAtom, NULL, 0, Object_Type, mPrototypeObject); - return JSValue(result); + return JSValue::newInstance(result); } -JSValue JSObjectType::newInstance(Context *cx) +js2val JSObjectType::newInstance(Context *cx) { JSObject *result = new JSObject(); result->mPrototype = mPrototypeObject; result->defineVariable(cx, cx->UnderbarPrototype_StringAtom, NULL, 0, Object_Type, mPrototypeObject); - return JSValue(result); + return JSValue::newObject(result); } @@ -701,7 +695,7 @@ void JSType::setInstanceInitializer(Context * /*cx*/, JSFunction *f) void JSType::setStaticInitializer(Context *cx, JSFunction *f) { if (f) - cx->interpret(f->getByteCode(), 0, f->getScopeChain(), JSValue(this), NULL, 0); + cx->interpret(f->getByteCode(), 0, f->getScopeChain(), JSValue::newObject(this), NULL, 0); } Property *JSType::defineVariable(Context *cx, const String& name, AttributeStmtNode *attr, JSType *type) @@ -724,59 +718,59 @@ XXX error for classes, right? but not for local variables under what circumstanc return prop; } -JSValue JSArrayType::newInstance(Context *cx) +js2val JSArrayType::newInstance(Context *cx) { JSInstance *result = new JSArrayInstance(cx); result->mPrototype = mPrototypeObject; result->defineVariable(cx, cx->UnderbarPrototype_StringAtom, NULL, 0, Object_Type, mPrototypeObject); - return JSValue(result); + return JSValue::newInstance(result); } -JSValue JSStringType::newInstance(Context *cx) +js2val JSStringType::newInstance(Context *cx) { JSInstance *result = new JSStringInstance(cx); result->mPrototype = mPrototypeObject; result->defineVariable(cx, cx->UnderbarPrototype_StringAtom, NULL, 0, Object_Type, mPrototypeObject); - return JSValue(result); + return JSValue::newInstance(result); } -JSValue JSBooleanType::newInstance(Context *cx) +js2val JSBooleanType::newInstance(Context *cx) { JSInstance *result = new JSBooleanInstance(cx); result->mPrototype = mPrototypeObject; result->defineVariable(cx, cx->UnderbarPrototype_StringAtom, NULL, 0, Object_Type, mPrototypeObject); - return JSValue(result); + return JSValue::newInstance(result); } -JSValue JSRegExpType::newInstance(Context *cx) +js2val JSRegExpType::newInstance(Context *cx) { JSInstance *result = new JSRegExpInstance(cx); result->mPrototype = mPrototypeObject; result->defineVariable(cx, cx->UnderbarPrototype_StringAtom, NULL, 0, Object_Type, mPrototypeObject); - return JSValue(result); + return JSValue::newInstance(result); } -JSValue JSDateType::newInstance(Context *cx) +js2val JSDateType::newInstance(Context *cx) { JSInstance *result = new JSDateInstance(cx); result->mPrototype = mPrototypeObject; result->defineVariable(cx, cx->UnderbarPrototype_StringAtom, NULL, 0, Object_Type, mPrototypeObject); - return JSValue(result); + return JSValue::newInstance(result); } -JSValue JSNumberType::newInstance(Context *cx) +js2val JSNumberType::newInstance(Context *cx) { JSInstance *result = new JSNumberInstance(cx); result->mPrototype = mPrototypeObject; result->defineVariable(cx, cx->UnderbarPrototype_StringAtom, NULL, 0, Object_Type, mPrototypeObject); - return JSValue(result); + return JSValue::newInstance(result); } // don't add to instances etc., climb all the way down (likely to the global object) // and add the property there. void ScopeChain::setNameValue(Context *cx, const String& name, NamespaceList *names) { - JSValue v = cx->topValue(); + js2val v = cx->topValue(); for (ScopeScanner s = mScopeStack.rbegin(), end = mScopeStack.rend(); (s != end); s++) { PropertyIterator i; @@ -784,7 +778,7 @@ void ScopeChain::setNameValue(Context *cx, const String& name, NamespaceList *na PropertyFlag flag = PROPERTY_KIND(i); switch (flag) { case ValuePointer: - *PROPERTY_VALUEPOINTER(i) = v; + PROPERTY_VALUEPOINTER(i) = v; break; case Slot: (*s)->setSlotValue(cx, PROPERTY_INDEX(i), v); @@ -821,7 +815,7 @@ JSObject *ScopeChain::getNameValue(Context *cx, const String& name, NamespaceLis PropertyFlag flag = PROPERTY_KIND(i); switch (flag) { case ValuePointer: - cx->pushValue(*PROPERTY_VALUEPOINTER(i)); + cx->pushValue(PROPERTY_VALUEPOINTER(i)); break; case Slot: cx->pushValue((*s)->getSlotValue(cx, PROPERTY_INDEX(i))); @@ -868,7 +862,7 @@ bool ScopeChain::hasNameValue(Context *cx, const String& name, NamespaceList *na // a compile time request to get the value for a name // (i.e. we're accessing a constant value) -JSValue ScopeChain::getCompileTimeValue(Context *cx, const String& name, NamespaceList *names) +js2val ScopeChain::getCompileTimeValue(Context *cx, const String& name, NamespaceList *names) { uint32 depth = 0; for (ScopeScanner s = mScopeStack.rbegin(), end = mScopeStack.rend(); (s != end); s++, depth++) @@ -928,7 +922,7 @@ Reference *ParameterBarrel::genReference(Context *cx, bool /* hasBase */, const return new ParameterReference(selectedProp->mData.index, acc, selectedProp->mType, selectedProp->mAttributes); } -JSValue ParameterBarrel::getSlotValue(Context *cx, uint32 slotIndex) +js2val ParameterBarrel::getSlotValue(Context *cx, uint32 slotIndex) { // find the appropriate activation object: if (cx->mArgumentBase == NULL) {// then must be in eval code, @@ -938,7 +932,7 @@ JSValue ParameterBarrel::getSlotValue(Context *cx, uint32 slotIndex) return cx->mArgumentBase[slotIndex]; } -void ParameterBarrel::setSlotValue(Context *cx, uint32 slotIndex, JSValue &v) +void ParameterBarrel::setSlotValue(Context *cx, uint32 slotIndex, js2val v) { // find the appropriate activation object: if (cx->mArgumentBase == NULL) {// then must be in eval code, @@ -965,7 +959,7 @@ Property *ParameterBarrel::defineVariable(Context *cx, const String& name, Attri -JSValue Activation::getSlotValue(Context *cx, uint32 slotIndex) +js2val Activation::getSlotValue(Context *cx, uint32 slotIndex) { // find the appropriate activation object: if (cx->mArgumentBase == NULL) {// then must be in eval code, @@ -975,7 +969,7 @@ JSValue Activation::getSlotValue(Context *cx, uint32 slotIndex) return cx->mLocals[slotIndex]; } -void Activation::setSlotValue(Context *cx, uint32 slotIndex, JSValue &v) +void Activation::setSlotValue(Context *cx, uint32 slotIndex, js2val v) { // find the appropriate activation object: if (cx->mArgumentBase == NULL) {// then must be in eval code, @@ -994,18 +988,18 @@ void Activation::setSlotValue(Context *cx, uint32 slotIndex, JSValue &v) JSType *ScopeChain::findType(Context *cx, const StringAtom& typeName, size_t pos) { - JSValue v = getCompileTimeValue(cx, typeName, NULL); - if (!v.isUndefined()) { - if (v.isType()) - return v.type; + js2val v = getCompileTimeValue(cx, typeName, NULL); + if (!JSValue::isUndefined(v)) { + if (JSValue::isType(v)) + return JSValue::type(v); else { // Allow finding a function that has the same name as it's containing class // i.e. the default constructor. - FunctionName *fnName = v.function->getFunctionName(); + FunctionName *fnName = JSValue::function(v)->getFunctionName(); if ((fnName->prefix == FunctionName::normal) - && v.isFunction() && v.function->getClass() - && (v.function->getClass()->mClassName->compare(*fnName->name) == 0)) - return v.function->getClass(); + && JSValue::isFunction(v) && JSValue::function(v)->getClass() + && (JSValue::function(v)->getClass()->mClassName->compare(*fnName->name) == 0)) + return JSValue::function(v)->getClass(); m_cx->reportError(Exception::semanticError, "Unknown type", pos); return NULL; } @@ -1132,33 +1126,20 @@ bool ScopeChain::isPossibleUncheckedFunction(FunctionDefinition &f) Build a name for the package from the identifier list */ - String ScopeChain::getPackageName(IdentifierList *packageIdList) - { - String packagePath; - IdentifierList *idList = packageIdList; - while (idList) { - packagePath += idList->name; - idList = idList->next; - if (idList) - packagePath += '/'; // XXX how to get path separator for OS? - } - return packagePath; - } // counts the number of pigs that can fit in a small wicker basket - void JSFunction::countParameters(Context *cx, FunctionDefinition &f) { uint32 requiredParameterCount = 0; @@ -1200,7 +1181,7 @@ void ScopeChain::collectNames(StmtNode *p) if (hasProperty(m_cx, *name, NULL, Read, &it)) m_cx->reportError(Exception::referenceError, "Duplicate class definition", p->pos); - defineVariable(m_cx, *name, classStmt, Type_Type, JSValue(thisClass)); + defineVariable(m_cx, *name, classStmt, Type_Type, JSValue::newType(thisClass)); classStmt->mType = thisClass; } break; @@ -1428,12 +1409,12 @@ void ScopeChain::collectNames(StmtNode *p) if (!m_cx->checkForPackage(packageName)) m_cx->loadPackage(packageName, packageName + ".js"); - JSValue packageValue = getCompileTimeValue(m_cx, packageName, NULL); - ASSERT(packageValue.isPackage()); - Package *package = packageValue.package; + js2val packageValue = getCompileTimeValue(m_cx, packageName, NULL); + ASSERT(JSValue::isPackage(packageValue)); + Package *package = JSValue::package(packageValue); if (i->varName) - defineVariable(m_cx, *i->varName, NULL, Package_Type, JSValue(package)); + defineVariable(m_cx, *i->varName, NULL, Package_Type, JSValue::newPackage(package)); for (PropertyIterator it = package->mProperties.begin(), end = package->mProperties.end(); (it != end); it++) @@ -1462,7 +1443,7 @@ void ScopeChain::collectNames(StmtNode *p) NamespaceStmtNode *n = checked_cast(p); Attribute *x = new Attribute(0, 0); x->mNamespaceList = new NamespaceList(n->name, x->mNamespaceList); - m_cx->getGlobalObject()->defineVariable(m_cx, n->name, (NamespaceList *)(NULL), Property::NoAttribute, Attribute_Type, JSValue(x)); + m_cx->getGlobalObject()->defineVariable(m_cx, n->name, (NamespaceList *)(NULL), Property::NoAttribute, Attribute_Type, JSValue::newAttribute(x)); } break; case StmtNode::Package: @@ -1471,7 +1452,7 @@ void ScopeChain::collectNames(StmtNode *p) String packageName = getPackageName(ps->packageIdList); Package *package = new Package(packageName); ps->scope = package; - defineVariable(m_cx, packageName, NULL, Package_Type, JSValue(package)); + defineVariable(m_cx, packageName, NULL, Package_Type, JSValue::newPackage(package)); m_cx->mPackages.push_back(package); addScope(ps->scope); @@ -1601,14 +1582,14 @@ bool JSType::derivesFrom(JSType *other) return false; } -JSValue JSType::getPropertyValue(PropertyIterator &i) +js2val JSType::getPropertyValue(PropertyIterator &i) { Property *prop = PROPERTY(i); switch (prop->mFlag) { case ValuePointer: - return *prop->mData.vp; + return prop->mData.vp; case Constructor: - return JSValue(mMethods[prop->mData.index]); + return JSValue::newFunction(mMethods[prop->mData.index]); default: return kUndefinedValue; } @@ -1667,7 +1648,7 @@ Reference *JSType::genReference(Context *cx, bool hasBase, const String& name, N // (mPrototype). Special handling throughout for handling the initialization of Object_Type which has // no super type. (Note though that it's prototype link __proto__ is the Type_Type object and it has // a prototype object - whose __proto__ is null) -JSType::JSType(Context *cx, const StringAtom *name, JSType *super, JSValue &protoObj, JSValue &typeProto) +JSType::JSType(Context *cx, const StringAtom *name, JSType *super, js2val protoObj, js2val typeProto) : JSInstance(cx, Type_Type), mSuperType(super), mVariableCount(0), @@ -1685,11 +1666,11 @@ JSType::JSType(Context *cx, const StringAtom *name, JSType *super, JSValue &prot mPrivateNamespace = &cx->mWorld.identifiers["unique id needed? private"]; // XXX. No, really? // every class gets a prototype object (used to set the __proto__ value of new instances) - if (!protoObj.isNull()) + if (!JSValue::isNull(protoObj)) mPrototypeObject = protoObj; else { JSObject *protoObj = new JSObject(); - mPrototypeObject = JSValue(protoObj); + mPrototypeObject = JSValue::newObject(protoObj); // and that object is prototype-linked to the super-type's prototype object if (mSuperType) protoObj->mPrototype = mSuperType->mPrototypeObject; @@ -1701,7 +1682,7 @@ JSType::JSType(Context *cx, const StringAtom *name, JSType *super, JSValue &prot else // must be Object_Type being initialized defineVariable(cx, cx->Prototype_StringAtom, (NamespaceList *)NULL, Property::ReadOnly | Property::DontDelete, this, mPrototypeObject); - if (!typeProto.isNull()) + if (!JSValue::isNull(typeProto)) mPrototype = typeProto; else { // the __proto__ of a type is the super-type's prototype object, or for the @@ -1713,11 +1694,11 @@ JSType::JSType(Context *cx, const StringAtom *name, JSType *super, JSValue &prot } if (mSuperType) { defineVariable(cx, cx->UnderbarPrototype_StringAtom, NULL, 0, Object_Type, mPrototype); - mPrototypeObject.getObjectValue()->defineVariable(cx, cx->Constructor_StringAtom, (NamespaceList *)NULL, 0, Object_Type, JSValue(this)); + JSValue::getObjectValue(mPrototypeObject)->defineVariable(cx, cx->Constructor_StringAtom, (NamespaceList *)NULL, 0, Object_Type, JSValue::newInstance(this)); } else { // must be Object_Type being initialized defineVariable(cx, cx->UnderbarPrototype_StringAtom, NULL, 0, this, mPrototype); - mPrototypeObject.getObjectValue()->defineVariable(cx, cx->Constructor_StringAtom, (NamespaceList *)NULL, 0, this, JSValue(this)); + JSValue::getObjectValue(mPrototypeObject)->defineVariable(cx, cx->Constructor_StringAtom, (NamespaceList *)NULL, 0, this, JSValue::newInstance(this)); } } @@ -1727,7 +1708,7 @@ void JSType::setSuperType(JSType *super) { mSuperType = super; if (mSuperType) { - mPrototypeObject.getObjectValue()->mPrototype = mSuperType->mPrototypeObject; + JSValue::getObjectValue(mPrototypeObject)->mPrototype = mSuperType->mPrototypeObject; // inherit supertype instance field and vtable slots mVariableCount = mSuperType->mVariableCount; mMethods.insert(mMethods.begin(), @@ -2025,45 +2006,45 @@ void Context::buildRuntimeForStmt(StmtNode *p) } -static JSValue Object_Constructor(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val Object_Constructor(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { - JSValue thatValue = thisValue; // incoming 'new this' potentially supplied by constructor sequence + js2val thatValue = thisValue; // incoming 'new this' potentially supplied by constructor sequence if (argc != 0) { - if (argv[0].isInstance() || argv[0].isObject() || argv[0].isFunction() || argv[0].isType()) + if (JSValue::isInstance(argv[0]) || JSValue::isObject(argv[0]) || JSValue::isFunction(argv[0]) || JSValue::isType(argv[0])) thatValue = argv[0]; else - if (argv[0].isString() || argv[0].isBool() || argv[0].isNumber()) - thatValue = argv[0].toObject(cx); + if (JSValue::isString(argv[0]) || JSValue::isBool(argv[0]) || JSValue::isNumber(argv[0])) + thatValue = JSValue::toObject(cx, argv[0]); else { - if (thatValue.isNull()) + if (JSValue::isNull(thatValue)) thatValue = Object_Type->newInstance(cx); } } else { - if (thatValue.isNull()) + if (JSValue::isNull(thatValue)) thatValue = Object_Type->newInstance(cx); } return thatValue; } -static JSValue Object_toString(Context * /* cx */, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Object_toString(Context * /* cx */, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/) { - if (thisValue.isObject() || thisValue.isInstance()) - return JSValue(new String(widenCString("[object ") + *thisValue.getType()->mClassName + widenCString("]"))); + if (JSValue::isObject(thisValue) || JSValue::isInstance(thisValue)) + return JSValue::newString(new String(widenCString("[object ") + *JSValue::getType(thisValue)->mClassName + widenCString("]"))); else - if (thisValue.isType()) // XXX why wouldn't this get handled by the above? - return JSValue(new String(widenCString("[object ") + widenCString("Type") + widenCString("]"))); + if (JSValue::isType(thisValue)) // XXX why wouldn't this get handled by the above? + return JSValue::newString(new String(widenCString("[object ") + widenCString("Type") + widenCString("]"))); else - if (thisValue.isFunction()) - return JSValue(new String(widenCString("[object ") + widenCString("Function") + widenCString("]"))); + if (JSValue::isFunction(thisValue)) + return JSValue::newString(new String(widenCString("[object ") + widenCString("Function") + widenCString("]"))); else { NOT_REACHED("Object.prototype.toString on non-object"); return kUndefinedValue; } } -static JSValue Object_valueOf(Context * /* cx */, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Object_valueOf(Context * /* cx */, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/) { return thisValue; } @@ -2080,18 +2061,18 @@ public: PropertyIterator it; }; -static JSValue Object_forin(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Object_forin(Context *cx, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/) { - JSObject *obj = thisValue.getObjectValue(); + JSObject *obj = JSValue::getObjectValue(thisValue); JSIteratorInstance *itInst = new JSIteratorInstance(cx); itInst->obj = obj; itInst->it = obj->mProperties.begin(); while (true) { while (itInst->it == itInst->obj->mProperties.end()) { - if (itInst->obj->mPrototype.isNull()) + if (JSValue::isNull(itInst->obj->mPrototype)) return kNullValue; - itInst->obj = itInst->obj->mPrototype.getObjectValue(); + itInst->obj = JSValue::getObjectValue(itInst->obj->mPrototype); itInst->it = itInst->obj->mProperties.begin(); } if (PROPERTY_ATTR(itInst->it) & Property::Enumerable) @@ -2099,35 +2080,35 @@ static JSValue Object_forin(Context *cx, const JSValue& thisValue, JSValue * /*a itInst->it++; } - JSValue v(&PROPERTY_NAME(itInst->it)); + js2val v = JSValue::newString(&PROPERTY_NAME(itInst->it)); itInst->setProperty(cx, cx->mWorld.identifiers["value"], 0, v); - return JSValue(itInst); + return JSValue::newInstance(itInst); } -static JSValue Object_next(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 /*argc*/) +static js2val Object_next(Context *cx, const js2val /*thisValue*/, js2val *argv, uint32 /*argc*/) { - JSValue iteratorValue = argv[0]; - ASSERT(iteratorValue.isInstance()); - JSIteratorInstance *itInst = checked_cast(iteratorValue.instance); + js2val iteratorValue = argv[0]; + ASSERT(JSValue::isInstance(iteratorValue)); + JSIteratorInstance *itInst = checked_cast(JSValue::instance(iteratorValue)); itInst->it++; while (true) { while (itInst->it == itInst->obj->mProperties.end()) { - if (itInst->obj->mPrototype.isNull()) + if (JSValue::isNull(itInst->obj->mPrototype)) return kNullValue; - itInst->obj = itInst->obj->mPrototype.getObjectValue(); + itInst->obj = JSValue::getObjectValue(itInst->obj->mPrototype); itInst->it = itInst->obj->mProperties.begin(); } if (PROPERTY_ATTR(itInst->it) & Property::Enumerable) break; itInst->it++; } - JSValue v(&PROPERTY_NAME(itInst->it)); + js2val v = JSValue::newString(&PROPERTY_NAME(itInst->it)); itInst->setProperty(cx, cx->mWorld.identifiers["value"], 0, v); return iteratorValue; } -static JSValue Object_done(Context *, const JSValue& /*thisValue*/, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Object_done(Context *, const js2val /*thisValue*/, js2val * /*argv*/, uint32 /*argc*/) { return kUndefinedValue; } @@ -2135,27 +2116,27 @@ static JSValue Object_done(Context *, const JSValue& /*thisValue*/, JSValue * /* -static JSValue Function_Constructor(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val Function_Constructor(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { - JSValue v = thisValue; - if (v.isNull()) + js2val v = thisValue; + if (JSValue::isNull(v)) v = Function_Type->newInstance(cx); - ASSERT(v.isInstance()); + ASSERT(JSValue::isInstance(v)); String s; if (argc == 0) s = widenCString("() { }"); else { if (argc == 1) - s = widenCString("() {") + *argv[0].toString(cx).string + "}"; + s = widenCString("() {") + *JSValue::string(JSValue::toString(cx, argv[0])) + "}"; else { s = widenCString("("); // ')' for (uint32 i = 0; i < (argc - 1); i++) { - s += *argv[i].toString(cx).string; + s += *JSValue::string(JSValue::toString(cx, argv[i])); if (i < (argc - 2)) s += widenCString(", "); } -/* ( */ s += ") {" + *argv[argc - 1].toString(cx).string + "}"; +/* ( */ s += ") {" + *JSValue::string(JSValue::toString(cx, argv[argc - 1])) + "}"; } } @@ -2188,93 +2169,93 @@ static JSValue Function_Constructor(Context *cx, const JSValue& thisValue, JSVal } /***************************************************************/ - JSValue fncPrototype = Object_Type->newInstance(cx); - ASSERT(fncPrototype.isObject()); - fncPrototype.object->defineVariable(cx, cx->Constructor_StringAtom, (NamespaceList *)NULL, Property::Enumerable, Object_Type, JSValue(fnc)); + js2val fncPrototype = Object_Type->newInstance(cx); + ASSERT(JSValue::isObject(fncPrototype)); + v = JSValue::newFunction(fnc); + JSValue::object(fncPrototype)->defineVariable(cx, cx->Constructor_StringAtom, (NamespaceList *)NULL, Property::Enumerable, Object_Type, v); fnc->defineVariable(cx, cx->Prototype_StringAtom, (NamespaceList *)NULL, Property::Enumerable, Object_Type, fncPrototype); - v = JSValue(fnc); return v; } -static JSValue Function_toString(Context *, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Function_toString(Context *, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/) { - ASSERT(thisValue.getType() == Function_Type); - return JSValue(new String(widenCString("function () { }"))); + ASSERT(JSValue::getType(thisValue) == Function_Type); + return JSValue::newString(new String(widenCString("function () { }"))); } -static JSValue Function_hasInstance(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val Function_hasInstance(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { ASSERT(argc == 1); - JSValue v = argv[0]; - if (!v.isObject()) + js2val v = argv[0]; + if (!JSValue::isObject(v)) return kFalseValue; - ASSERT(thisValue.isFunction()); - thisValue.function->getProperty(cx, cx->Prototype_StringAtom, CURRENT_ATTR); - JSValue p = cx->popValue(); + ASSERT(JSValue::isFunction(thisValue)); + JSValue::function(thisValue)->getProperty(cx, cx->Prototype_StringAtom, CURRENT_ATTR); + js2val p = cx->popValue(); - if (!p.isObject()) + if (!JSValue::isObject(p)) cx->reportError(Exception::typeError, "HasInstance: Function has non-object prototype"); - JSValue V = v.object->mPrototype; - while (!V.isNull()) { - if (V.getObjectValue() == p.object) + js2val V = JSValue::object(v)->mPrototype; + while (!JSValue::isNull(V)) { + if (JSValue::getObjectValue(V) == JSValue::object(p)) return kTrueValue; - V = V.getObjectValue()->mPrototype; + V = JSValue::getObjectValue(V)->mPrototype; } return kFalseValue; } -static JSValue Function_call(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val Function_call(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { - if (!thisValue.isFunction()) + if (!JSValue::isFunction(thisValue)) cx->reportError(Exception::typeError, "Non-callable object for Function.call"); - JSValue thisArg; + js2val thisArg; if (argc == 0) - thisArg = JSValue(cx->getGlobalObject()); + thisArg = JSValue::newObject(cx->getGlobalObject()); else { - if (argv[0].isUndefined() || argv[0].isNull()) - thisArg = JSValue(cx->getGlobalObject()); + if (JSValue::isUndefined(argv[0]) || JSValue::isNull(argv[0])) + thisArg = JSValue::newObject(cx->getGlobalObject()); else - thisArg = JSValue(argv[0].toObject(cx)); + thisArg = argv[0]; --argc; ++argv; } - return cx->invokeFunction(thisValue.function, thisArg, argv, argc); + return cx->invokeFunction(JSValue::function(thisValue), thisArg, argv, argc); } -static JSValue Function_apply(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val Function_apply(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { - if (!thisValue.isFunction()) + if (!JSValue::isFunction(thisValue)) cx->reportError(Exception::typeError, "Non-callable object for Function.call"); ContextStackReplacement csr(cx); - JSValue thisArg; + js2val thisArg; if (argc == 0) - thisArg = JSValue(cx->getGlobalObject()); + thisArg = JSValue::newObject(cx->getGlobalObject()); else { - if (argv[0].isUndefined() || argv[0].isNull()) - thisArg = JSValue(cx->getGlobalObject()); + if (JSValue::isUndefined(argv[0]) || JSValue::isNull(argv[0])) + thisArg = JSValue::newObject(cx->getGlobalObject()); else - thisArg = JSValue(argv[0].toObject(cx)); + thisArg = argv[0]; } if (argc <= 1) { argv = NULL; argc = 0; } else { - if (argv[1].getType() != Array_Type) + if (JSValue::getType(argv[1]) != Array_Type) cx->reportError(Exception::typeError, "Function.apply must have Array type argument list"); - ASSERT(argv[1].isObject()); - JSObject *argsObj = argv[1].object; + ASSERT(JSValue::isObject(argv[1])); + JSObject *argsObj = JSValue::object(argv[1]); argsObj->getProperty(cx, cx->Length_StringAtom, CURRENT_ATTR); - JSValue result = cx->popValue(); - argc = (uint32)(result.toUInt32(cx).f64); + js2val result = cx->popValue(); + argc = (uint32)JSValue::f64(JSValue::toUInt32(cx, result)); - argv = new JSValue[argc]; + argv = new js2val[argc]; for (uint32 i = 0; i < argc; i++) { const String *id = numberToString(i); argsObj->getProperty(cx, *id, CURRENT_ATTR); @@ -2283,57 +2264,57 @@ static JSValue Function_apply(Context *cx, const JSValue& thisValue, JSValue *ar } } - return cx->invokeFunction(thisValue.function, thisArg, argv, argc); + return cx->invokeFunction(JSValue::function(thisValue), thisArg, argv, argc); } -static JSValue Number_Constructor(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val Number_Constructor(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { - JSValue v = thisValue; - if (v.isNull()) + js2val v = thisValue; + if (JSValue::isNull(v)) v = Number_Type->newInstance(cx); - ASSERT(v.isInstance()); - JSNumberInstance *numInst = checked_cast(v.instance); + ASSERT(JSValue::isInstance(v)); + JSNumberInstance *numInst = checked_cast(JSValue::instance(v)); if (argc > 0) - numInst->mValue = argv[0].toNumber(cx).f64; + numInst->mValue = JSValue::f64(JSValue::toNumber(cx, argv[0])); else numInst->mValue = 0.0; return v; } -static JSValue Number_TypeCast(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 argc) +static js2val Number_TypeCast(Context *cx, const js2val /*thisValue*/, js2val *argv, uint32 argc) { if (argc == 0) return kPositiveZero; else - return argv[0].toNumber(cx); + return JSValue::toNumber(cx, argv[0]); } -static JSValue Number_toString(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Number_toString(Context *cx, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/) { - if (thisValue.getType() != Number_Type) + if (JSValue::getType(thisValue) != Number_Type) cx->reportError(Exception::typeError, "Number.toString called on something other than a Number object"); - JSNumberInstance *numInst = checked_cast(thisValue.instance); - return JSValue(numberToString(numInst->mValue)); + JSNumberInstance *numInst = checked_cast(JSValue::instance(thisValue)); + return JSValue::newString(numberToString(numInst->mValue)); } -static JSValue Number_valueOf(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Number_valueOf(Context *cx, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/) { - if (thisValue.getType() != Number_Type) + if (JSValue::getType(thisValue) != Number_Type) cx->reportError(Exception::typeError, "Number.valueOf called on something other than a Number object"); - JSNumberInstance *numInst = checked_cast(thisValue.instance); - return JSValue(numberToString(numInst->mValue)); + JSNumberInstance *numInst = checked_cast(JSValue::instance(thisValue)); + return JSValue::newString(numberToString(numInst->mValue)); } -static JSValue Integer_Constructor(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val Integer_Constructor(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { - JSValue v = thisValue; - if (v.isNull()) + js2val v = thisValue; + if (JSValue::isNull(v)) v = Integer_Type->newInstance(cx); - ASSERT(v.isInstance()); - JSNumberInstance *numInst = checked_cast(v.instance); + ASSERT(JSValue::isInstance(v)); + JSNumberInstance *numInst = checked_cast(JSValue::instance(v)); if (argc > 0) { - float64 d = argv[0].toNumber(cx).f64; + float64 d = JSValue::f64(JSValue::toNumber(cx, argv[0])); bool neg = (d < 0); d = fd::floor(neg ? -d : d); d = neg ? -d : d; @@ -2344,107 +2325,107 @@ static JSValue Integer_Constructor(Context *cx, const JSValue& thisValue, JSValu return v; } -static JSValue Integer_toString(Context *, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Integer_toString(Context *, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/) { - JSNumberInstance *numInst = checked_cast(thisValue.instance); - return JSValue(numberToString(numInst->mValue)); + JSNumberInstance *numInst = checked_cast(JSValue::instance(thisValue)); + return JSValue::newString(numberToString(numInst->mValue)); } -static JSValue Boolean_Constructor(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val Boolean_Constructor(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { - JSValue v = thisValue; - if (v.isNull()) + js2val v = thisValue; + if (JSValue::isNull(v)) v = Boolean_Type->newInstance(cx); - ASSERT(v.isInstance()); - JSBooleanInstance *thisObj = checked_cast(v.instance); + ASSERT(JSValue::isInstance(v)); + JSBooleanInstance *thisObj = checked_cast(JSValue::instance(v)); if (argc > 0) - thisObj->mValue = argv[0].toBoolean(cx).boolean; + thisObj->mValue = JSValue::boolean(JSValue::toBoolean(cx, argv[0])); else thisObj->mValue = false; return v; } -static JSValue Boolean_TypeCast(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 argc) +static js2val Boolean_TypeCast(Context *cx, const js2val /*thisValue*/, js2val *argv, uint32 argc) { if (argc == 0) return kFalseValue; else - return argv[0].toBoolean(cx); + return JSValue::boolean(JSValue::toBoolean(cx, argv[0])); } -static JSValue Boolean_toString(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Boolean_toString(Context *cx, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/) { - if (thisValue.getType() != Boolean_Type) + if (JSValue::getType(thisValue) != Boolean_Type) cx->reportError(Exception::typeError, "Boolean.toString can only be applied to Boolean objects"); - ASSERT(thisValue.isInstance()); - JSBooleanInstance *thisObj = checked_cast(thisValue.instance); + ASSERT(JSValue::isInstance(thisValue)); + JSBooleanInstance *thisObj = checked_cast(JSValue::instance(thisValue)); if (thisObj->mValue) - return JSValue(&cx->True_StringAtom); + return JSValue::newString(&cx->True_StringAtom); else - return JSValue(&cx->False_StringAtom); + return JSValue::newString(&cx->False_StringAtom); } -static JSValue Boolean_valueOf(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Boolean_valueOf(Context *cx, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/) { - if (thisValue.getType() != Boolean_Type) + if (JSValue::getType(thisValue) != Boolean_Type) cx->reportError(Exception::typeError, "Boolean.valueOf can only be applied to Boolean objects"); - ASSERT(thisValue.isInstance()); - JSBooleanInstance *thisObj = checked_cast(thisValue.instance); + ASSERT(JSValue::isInstance(thisValue)); + JSBooleanInstance *thisObj = checked_cast(JSValue::instance(thisValue)); if (thisObj->mValue) return kTrueValue; else return kFalseValue; } -static JSValue GenericError_Constructor(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc, JSType *errType) +static js2val GenericError_Constructor(Context *cx, const js2val thisValue, js2val *argv, uint32 argc, JSType *errType) { - JSValue v = thisValue; - if (v.isNull()) + js2val v = thisValue; + if (JSValue::isNull(v)) v = errType->newInstance(cx); - ASSERT(v.isInstance()); - JSObject *thisInst = v.instance; - JSValue msg; + ASSERT(JSValue::isInstance(v)); + JSObject *thisInst = JSValue::instance(v); + js2val msg; if (argc > 0) - msg = argv[0].toString(cx); + msg = JSValue::toString(cx, argv[0]); else - msg = JSValue(&cx->Empty_StringAtom); + msg = JSValue::newString(&cx->Empty_StringAtom); thisInst->defineVariable(cx, cx->Message_StringAtom, NULL, Property::NoAttribute, String_Type, msg); - thisInst->defineVariable(cx, cx->Name_StringAtom, NULL, Property::NoAttribute, String_Type, JSValue(errType->mClassName)); + thisInst->defineVariable(cx, cx->Name_StringAtom, NULL, Property::NoAttribute, String_Type, JSValue::newString(errType->mClassName)); return v; } -JSValue RegExp_Constructor(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +js2val RegExp_Constructor(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { - JSValue thatValue = thisValue; - if (thatValue.isNull()) + js2val thatValue = thisValue; + if (JSValue::isNull(thatValue)) thatValue = RegExp_Type->newInstance(cx); - ASSERT(thatValue.isInstance()); - JSRegExpInstance *thisInst = checked_cast(thatValue.instance); + ASSERT(JSValue::isInstance(thatValue)); + JSRegExpInstance *thisInst = checked_cast(JSValue::instance(thatValue)); REuint32 flags = 0; const String *regexpStr = &cx->Empty_StringAtom; const String *flagStr = &cx->Empty_StringAtom; if (argc > 0) { - if (argv[0].getType() == RegExp_Type) { - ASSERT(argv[0].isInstance()); - if ((argc == 1) || argv[1].isUndefined()) { + if (JSValue::getType(argv[0]) == RegExp_Type) { + ASSERT(JSValue::isInstance(argv[0])); + if ((argc == 1) || JSValue::isUndefined(argv[1])) { ContextStackReplacement csr(cx); - argv[0].instance->getProperty(cx, cx->Source_StringAtom, CURRENT_ATTR); - JSValue src = cx->popValue(); - ASSERT(src.isString()); - regexpStr = src.string; - REState *other = (checked_cast(argv[0].instance))->mRegExp; + JSValue::instance(argv[0])->getProperty(cx, cx->Source_StringAtom, CURRENT_ATTR); + js2val src = cx->popValue(); + ASSERT(JSValue::isString(src)); + regexpStr = JSValue::string(src); + REState *other = (checked_cast(JSValue::instance(argv[0])))->mRegExp; flags = other->flags; } else cx->reportError(Exception::typeError, "Illegal RegExp constructor args"); } else - regexpStr = argv[0].toString(cx).string; - if ((argc > 1) && !argv[1].isUndefined()) { - flagStr = argv[1].toString(cx).string; + regexpStr = JSValue::string(JSValue::toString(cx, argv[0])); + if ((argc > 1) && !JSValue::isUndefined(argv[1])) { + flagStr = JSValue::string(JSValue::toString(cx, argv[1])); if (parseFlags(flagStr->begin(), flagStr->length(), &flags) != RE_NO_ERROR) { cx->reportError(Exception::syntaxError, "Failed to parse RegExp : '{0}'", *regexpStr + "/" + *flagStr); // XXX error message? } @@ -2461,7 +2442,7 @@ JSValue RegExp_Constructor(Context *cx, const JSValue& thisValue, JSValue *argv, thisInst->defineVariable(cx, cx->Multiline_StringAtom, NULL, (Property::DontDelete | Property::ReadOnly), Boolean_Type, (pState->flags & MULTILINE) ? kTrueValue : kFalseValue); thisInst->defineVariable(cx, cx->LastIndex_StringAtom, NULL, Property::DontDelete, Number_Type, kPositiveZero); */ - thisInst->defineVariable(cx, cx->Source_StringAtom, NULL, (Property::DontDelete | Property::ReadOnly | Property::Enumerable), String_Type, JSValue(regexpStr)); + thisInst->defineVariable(cx, cx->Source_StringAtom, NULL, (Property::DontDelete | Property::ReadOnly | Property::Enumerable), String_Type, JSValue::newString(regexpStr)); thisInst->defineVariable(cx, cx->Global_StringAtom, NULL, (Property::DontDelete | Property::ReadOnly | Property::Enumerable), Boolean_Type, (pState->flags & RE_GLOBAL) ? kTrueValue : kFalseValue); thisInst->defineVariable(cx, cx->IgnoreCase_StringAtom, NULL, (Property::DontDelete | Property::ReadOnly | Property::Enumerable), Boolean_Type, (pState->flags & RE_IGNORECASE) ? kTrueValue : kFalseValue); thisInst->defineVariable(cx, cx->Multiline_StringAtom, NULL, (Property::DontDelete | Property::ReadOnly | Property::Enumerable), Boolean_Type, (pState->flags & RE_MULTILINE) ? kTrueValue : kFalseValue); @@ -2473,95 +2454,95 @@ JSValue RegExp_Constructor(Context *cx, const JSValue& thisValue, JSValue *argv, return thatValue; } -static JSValue RegExp_TypeCast(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val RegExp_TypeCast(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { if (argc > 0) { - if ((argv[0].getType() == RegExp_Type) - && ((argc == 1) || argv[1].isUndefined())) + if ((JSValue::getType(argv[0]) == RegExp_Type) + && ((argc == 1) || JSValue::isUndefined(argv[1]))) return argv[0]; } return RegExp_Constructor(cx, thisValue, argv, argc); } -static JSValue RegExp_toString(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val RegExp_toString(Context *cx, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/) { ContextStackReplacement csr(cx); - if (thisValue.getType() != RegExp_Type) + if (JSValue::getType(thisValue) != RegExp_Type) cx->reportError(Exception::typeError, "RegExp.toString can only be applied to RegExp objects"); - ASSERT(thisValue.isInstance()); - JSRegExpInstance *thisInst = checked_cast(thisValue.instance); + ASSERT(JSValue::isInstance(thisValue)); + JSRegExpInstance *thisInst = checked_cast(JSValue::instance(thisValue)); thisInst->getProperty(cx, cx->Source_StringAtom, CURRENT_ATTR); - JSValue src = cx->popValue(); + js2val src = cx->popValue(); // XXX not ever expecting this except in the one case of RegExp.prototype, which isn't a fully formed // RegExp instance, but has the appropriate type pointer. - if (src.isUndefined()) { - ASSERT(thisInst == RegExp_Type->mPrototypeObject.instance); - return JSValue(&cx->Empty_StringAtom); + if (JSValue::isUndefined(src)) { + ASSERT(thisInst == JSValue::instance(RegExp_Type->mPrototypeObject)); + return JSValue::newString(&cx->Empty_StringAtom); } - String *result = new String("/" + *src.toString(cx).string + "/"); + String *result = new String("/" + *JSValue::string(JSValue::toString(cx, src)) + "/"); REState *state = (REState *)thisInst->mRegExp; if (state->flags & RE_GLOBAL) *result += "g"; if (state->flags & RE_IGNORECASE) *result += "i"; if (state->flags & RE_MULTILINE) *result += "m"; - return JSValue(result); + return JSValue::newString(result); } -JSValue RegExp_exec(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +js2val RegExp_exec(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { - if (thisValue.getType() != RegExp_Type) + if (JSValue::getType(thisValue) != RegExp_Type) cx->reportError(Exception::typeError, "RegExp.exec can only be applied to RegExp objects"); - ASSERT(thisValue.isInstance()); - JSRegExpInstance *thisInst = checked_cast(thisValue.instance); + ASSERT(JSValue::isInstance(thisValue)); + JSRegExpInstance *thisInst = checked_cast(JSValue::instance(thisValue)); - JSValue result = kNullValue; + js2val result = kNullValue; if (argc > 0) { ContextStackReplacement csr(cx); int32 index = 0; - const String *str = argv[0].toString(cx).string; + const String *str = JSValue::string(JSValue::toString(cx, argv[0])); RegExp_Type->getProperty(cx, cx->Multiline_StringAtom, CURRENT_ATTR); - JSValue globalMultiline = cx->popValue(); + js2val globalMultiline = cx->popValue(); if (thisInst->mRegExp->flags & RE_GLOBAL) { // XXX implement lastIndex as a setter/getter pair instead ??? thisInst->getProperty(cx, cx->LastIndex_StringAtom, CURRENT_ATTR); - JSValue lastIndex = cx->popValue(); - index = (int32)(lastIndex.toInteger(cx).f64); + js2val lastIndex = cx->popValue(); + index = (int32)JSValue::f64(JSValue::toInteger(cx, lastIndex)); } - REMatchState *match = REExecute(thisInst->mRegExp, str->begin(), index, str->length(), globalMultiline.toBoolean(cx).boolean); + REMatchState *match = REExecute(thisInst->mRegExp, str->begin(), index, str->length(), JSValue::boolean(JSValue::toBoolean(cx, globalMultiline))); if (match) { result = Array_Type->newInstance(cx); String *matchStr = new String(str->substr(match->startIndex, match->endIndex - match->startIndex)); - result.instance->setProperty(cx, *numberToString(0), NULL, JSValue(matchStr)); + JSValue::instance(result)->setProperty(cx, *numberToString(0), NULL, JSValue::newString(matchStr)); String *parenStr = &cx->Empty_StringAtom; for (int32 i = 0; i < match->parenCount; i++) { if (match->parens[i].index != -1) { String *parenStr = new String(str->substr((uint32)(match->parens[i].index), (uint32)(match->parens[i].length))); - result.instance->setProperty(cx, *numberToString(i + 1), NULL, JSValue(parenStr)); + JSValue::instance(result)->setProperty(cx, *numberToString(i + 1), NULL, JSValue::newString(parenStr)); } else - result.instance->setProperty(cx, *numberToString(i + 1), NULL, kUndefinedValue); + JSValue::instance(result)->setProperty(cx, *numberToString(i + 1), NULL, kUndefinedValue); } // XXX SpiderMonkey also adds 'index' and 'input' properties to the result - result.instance->setProperty(cx, cx->Index_StringAtom, CURRENT_ATTR, JSValue((float64)(match->startIndex))); - result.instance->setProperty(cx, cx->Input_StringAtom, CURRENT_ATTR, JSValue(str)); + JSValue::instance(result)->setProperty(cx, cx->Index_StringAtom, CURRENT_ATTR, JSValue::newNumber((float64)(match->startIndex))); + JSValue::instance(result)->setProperty(cx, cx->Input_StringAtom, CURRENT_ATTR, JSValue::newString(str)); // XXX Set up the SpiderMonkey 'RegExp statics' - RegExp_Type->setProperty(cx, cx->LastMatch_StringAtom, CURRENT_ATTR, JSValue(matchStr)); - RegExp_Type->setProperty(cx, cx->LastParen_StringAtom, CURRENT_ATTR, JSValue(parenStr)); + RegExp_Type->setProperty(cx, cx->LastMatch_StringAtom, CURRENT_ATTR, JSValue::newString(matchStr)); + RegExp_Type->setProperty(cx, cx->LastParen_StringAtom, CURRENT_ATTR, JSValue::newString(parenStr)); String *contextStr = new String(str->substr(0, match->startIndex)); - RegExp_Type->setProperty(cx, cx->LeftContext_StringAtom, CURRENT_ATTR, JSValue(contextStr)); + RegExp_Type->setProperty(cx, cx->LeftContext_StringAtom, CURRENT_ATTR, JSValue::newString(contextStr)); contextStr = new String(str->substr(match->endIndex, str->length() - match->endIndex)); - RegExp_Type->setProperty(cx, cx->RightContext_StringAtom, CURRENT_ATTR, JSValue(contextStr)); + RegExp_Type->setProperty(cx, cx->RightContext_StringAtom, CURRENT_ATTR, JSValue::newString(contextStr)); if (thisInst->mRegExp->flags & RE_GLOBAL) { index = match->endIndex; - thisInst->setProperty(cx, cx->LastIndex_StringAtom, CURRENT_ATTR, JSValue((float64)index)); + thisInst->setProperty(cx, cx->LastIndex_StringAtom, CURRENT_ATTR, JSValue::newNumber((float64)index)); } } @@ -2570,18 +2551,18 @@ JSValue RegExp_exec(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 return result; } -static JSValue RegExp_test(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val RegExp_test(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { - if (thisValue.getType() != RegExp_Type) + if (JSValue::getType(thisValue) != RegExp_Type) cx->reportError(Exception::typeError, "RegExp.test can only be applied to RegExp objects"); - ASSERT(thisValue.isInstance()); - JSRegExpInstance *thisInst = checked_cast(thisValue.instance); + ASSERT(JSValue::isInstance(thisValue)); + JSRegExpInstance *thisInst = checked_cast(JSValue::instance(thisValue)); if (argc > 0) { ContextStackReplacement csr(cx); - const String *str = argv[0].toString(cx).string; + const String *str = JSValue::string(JSValue::toString(cx, argv[0])); RegExp_Type->getProperty(cx, cx->Multiline_StringAtom, CURRENT_ATTR); - JSValue globalMultiline = cx->popValue(); - REMatchState *match = REExecute(thisInst->mRegExp, str->begin(), 0, str->length(), globalMultiline.toBoolean(cx).boolean); + js2val globalMultiline = cx->popValue(); + REMatchState *match = REExecute(thisInst->mRegExp, str->begin(), 0, str->length(), JSValue::boolean(JSValue::toBoolean(cx, globalMultiline))); if (match) return kTrueValue; } @@ -2589,76 +2570,76 @@ static JSValue RegExp_test(Context *cx, const JSValue& thisValue, JSValue *argv, } -JSValue Error_Constructor(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +js2val Error_Constructor(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { return GenericError_Constructor(cx, thisValue, argv, argc, Error_Type); } -static JSValue Error_toString(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Error_toString(Context *cx, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/) { ContextStackReplacement csr(cx); - if ((thisValue.getType() != Error_Type) && !thisValue.getType()->derivesFrom(Error_Type)) + if ((JSValue::getType(thisValue) != Error_Type) && !JSValue::getType(thisValue)->derivesFrom(Error_Type)) cx->reportError(Exception::typeError, "Error.toString can only be applied to Error objects"); - ASSERT(thisValue.isInstance()); - JSInstance *thisInstance = thisValue.instance; + ASSERT(JSValue::isInstance(thisValue)); + JSInstance *thisInstance = JSValue::instance(thisValue); thisInstance->getProperty(cx, cx->Message_StringAtom, CURRENT_ATTR); - JSValue msg = cx->popValue(); + js2val msg = cx->popValue(); thisInstance->getProperty(cx, cx->Name_StringAtom, CURRENT_ATTR); - JSValue name = cx->popValue(); + js2val name = cx->popValue(); - String *result = new String(*name.toString(cx).string + ":" + *msg.toString(cx).string); - return JSValue(result); + String *result = new String(*JSValue::string(JSValue::toString(cx, name)) + ":" + *JSValue::string(JSValue::toString(cx, msg))); + return JSValue::newString(result); } -JSValue EvalError_Constructor(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +js2val EvalError_Constructor(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { return GenericError_Constructor(cx, thisValue, argv, argc, EvalError_Type); } -JSValue RangeError_Constructor(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +js2val RangeError_Constructor(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { return GenericError_Constructor(cx, thisValue, argv, argc, RangeError_Type); } -JSValue ReferenceError_Constructor(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +js2val ReferenceError_Constructor(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { return GenericError_Constructor(cx, thisValue, argv, argc, ReferenceError_Type); } -JSValue SyntaxError_Constructor(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +js2val SyntaxError_Constructor(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { return GenericError_Constructor(cx, thisValue, argv, argc, SyntaxError_Type); } -JSValue TypeError_Constructor(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +js2val TypeError_Constructor(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { return GenericError_Constructor(cx, thisValue, argv, argc, TypeError_Type); } -JSValue UriError_Constructor(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +js2val UriError_Constructor(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { return GenericError_Constructor(cx, thisValue, argv, argc, UriError_Type); } -static JSValue ExtendAttribute_Invoke(Context * /*cx*/, const JSValue& /*thisValue*/, JSValue *argv, uint32 argc) +static js2val ExtendAttribute_Invoke(Context * /*cx*/, const js2val /*thisValue*/, js2val *argv, uint32 argc) { ASSERT(argc == 1); Attribute *x = new Attribute(Property::Extend, Property::Extend | Property::Virtual); - ASSERT(argv[0].isType()); - x->mExtendArgument = (JSType *)(argv[0].type); + ASSERT(JSValue::isType(argv[0])); + x->mExtendArgument = (JSType *)(JSValue::type(argv[0])); - return JSValue(x); + return JSValue::newAttribute(x); } -static JSValue GlobalObject_Eval(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 argc) +static js2val GlobalObject_Eval(Context *cx, const js2val /*thisValue*/, js2val *argv, uint32 argc) { if (argc > 0) { - if (!argv[0].isString()) + if (!JSValue::isString(argv[0])) return argv[0]; - const String *sourceStr = argv[0].toString(cx).string; + const String *sourceStr = JSValue::string(JSValue::toString(cx, argv[0])); Activation *prev = cx->mActivationStack.top(); @@ -2667,49 +2648,49 @@ static JSValue GlobalObject_Eval(Context *cx, const JSValue& /*thisValue*/, JSVa return kUndefinedValue; } -static JSValue GlobalObject_ParseInt(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 argc) +static js2val GlobalObject_ParseInt(Context *cx, const js2val /*thisValue*/, js2val *argv, uint32 argc) { ASSERT(argc >= 1); int radix = 0; // default for stringToInteger if (argc == 2) - radix = (int)(argv[1].toInt32(cx).f64); + radix = (int)JSValue::f64(JSValue::toInt32(cx, argv[1])); if ((radix < 0) || (radix > 36)) return kNaNValue; - const String *string = argv[0].toString(cx).string; + const String *string = JSValue::string(JSValue::toString(cx, argv[0])); const char16 *numEnd; const char16 *sBegin = string->begin(); float64 f = 0.0; if (sBegin) f = stringToInteger(sBegin, string->end(), numEnd, (uint)radix); - return JSValue(f); + return JSValue::newNumber(f); } -static JSValue GlobalObject_ParseFloat(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 argc) +static js2val GlobalObject_ParseFloat(Context *cx, const js2val /*thisValue*/, js2val *argv, uint32 argc) { ASSERT(argc == 1); - const String *string = argv[0].toString(cx).string; + const String *string = JSValue::string(JSValue::toString(cx, argv[0])); const char16 *numEnd; const char16 *sBegin = string->begin(); float64 f = 0.0; if (sBegin) f = stringToDouble(sBegin, string->end(), numEnd); - return JSValue(f); + return JSValue::newNumber(f); } -static JSValue GlobalObject_isNaN(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 /*argc*/) +static js2val GlobalObject_isNaN(Context *cx, const js2val /*thisValue*/, js2val *argv, uint32 /*argc*/) { - float64 f = argv[0].toNumber(cx).f64; + float64 f = JSValue::f64(JSValue::toNumber(cx, argv[0])); if (JSDOUBLE_IS_NaN(f)) return kTrueValue; else return kFalseValue; } -static JSValue GlobalObject_isFinite(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 /*argc*/) +static js2val GlobalObject_isFinite(Context *cx, const js2val /*thisValue*/, js2val *argv, uint32 /*argc*/) { - float64 f = argv[0].toNumber(cx).f64; + float64 f = JSValue::f64(JSValue::toNumber(cx, argv[0])); if (JSDOUBLE_IS_FINITE(f)) return kTrueValue; else @@ -2747,7 +2728,7 @@ static const uint8 urlCharType[256] = #define IS_OK(C, mask) (urlCharType[((uint8) (C))] & (mask)) /* See ECMA-262 15.1.2.4. */ -static JSValue GlobalObject_escape(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 argc) +static js2val GlobalObject_escape(Context *cx, const js2val /*thisValue*/, js2val *argv, uint32 argc) { if (argc > 0) { uint32 i, ni, length, newlength; @@ -2758,12 +2739,12 @@ static JSValue GlobalObject_escape(Context *cx, const JSValue& /*thisValue*/, JS uint32 mask = URL_XALPHAS | URL_XPALPHAS | URL_PATH; if (argc > 1) { - float64 d = argv[1].toNumber(cx).f64; + float64 d = JSValue::f64(JSValue::toNumber(cx, argv[1])); if (!JSDOUBLE_IS_FINITE(d) || (mask = (uint32)d) != d || mask & ~(URL_XALPHAS | URL_XPALPHAS | URL_PATH)) cx->reportError(Exception::runtimeError, "Bad string mask for escape"); } - const String *str = argv[0].toString(cx).string; + const String *str = JSValue::string(JSValue::toString(cx, argv[0])); const char16 *chars = str->begin(); length = newlength = str->size(); @@ -2807,20 +2788,20 @@ static JSValue GlobalObject_escape(Context *cx, const JSValue& /*thisValue*/, JS String *result = new String(newchars, newlength); delete[] newchars; - return JSValue(result); + return JSValue::newString(result); } - return JSValue(&cx->Undefined_StringAtom); + return JSValue::newString(&cx->Undefined_StringAtom); } #undef IS_OK /* See ECMA-262 15.1.2.5 */ -static JSValue GlobalObject_unescape(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 argc) +static js2val GlobalObject_unescape(Context *cx, const js2val /*thisValue*/, js2val *argv, uint32 argc) { if (argc > 0) { uint32 i, ni; char16 ch; - const String *str = argv[0].toString(cx).string; + const String *str = JSValue::string(JSValue::toString(cx, argv[0])); const char16 *chars = str->begin(); uint32 length = str->size(); @@ -2854,9 +2835,9 @@ static JSValue GlobalObject_unescape(Context *cx, const JSValue& /*thisValue*/, String *result = new String(newchars, ni); delete[] newchars; - return JSValue(result); + return JSValue::newString(result); } - return JSValue(&cx->Undefined_StringAtom); + return JSValue::newString(&cx->Undefined_StringAtom); } @@ -2865,7 +2846,7 @@ JSFunction::JSFunction(Context *cx, JSType *resultType, ScopeChain *scopeChain) mParameterBarrel(NULL), mActivation(), mByteCode(NULL), - mCode(NULL), + mNativeCode(NULL), mResultType(resultType), mRequiredParameters(0), mOptionalParameters(0), @@ -2877,7 +2858,8 @@ JSFunction::JSFunction(Context *cx, JSType *resultType, ScopeChain *scopeChain) mIsChecked(true), mHasRestParameter(false), mClass(NULL), - mFunctionName(NULL) + mFunctionName(NULL), + mDispatch(NULL) { if (scopeChain) { mScopeChain = new ScopeChain(*scopeChain); @@ -2885,17 +2867,17 @@ JSFunction::JSFunction(Context *cx, JSType *resultType, ScopeChain *scopeChain) if (Function_Type) // protect against bootstrap mPrototype = Function_Type->mPrototypeObject; mActivation.mContainer = this; - defineVariable(cx, cx->Prototype_StringAtom, (NamespaceList *)NULL, 0, Object_Type, JSValue(Object_Type->newInstance(cx))); - if (!mPrototype.isNull()) + defineVariable(cx, cx->Prototype_StringAtom, (NamespaceList *)NULL, 0, Object_Type, Object_Type->newInstance(cx)); + if (!JSValue::isNull(mPrototype)) defineVariable(cx, cx->UnderbarPrototype_StringAtom, (NamespaceList *)NULL, 0, Object_Type, mPrototype); } -JSFunction::JSFunction(Context *cx, NativeCode *code, JSType *resultType) +JSFunction::JSFunction(Context *cx, NativeCode *code, JSType *resultType, NativeDispatch *dispatch) : JSInstance(cx, Function_Type), mParameterBarrel(NULL), mActivation(), mByteCode(NULL), - mCode(code), + mNativeCode(code), mResultType(resultType), mRequiredParameters(0), mOptionalParameters(0), @@ -2907,16 +2889,17 @@ JSFunction::JSFunction(Context *cx, NativeCode *code, JSType *resultType) mIsChecked(false), // native functions aren't checked (?) mHasRestParameter(false), mClass(NULL), - mFunctionName(NULL) + mFunctionName(NULL), + mDispatch(dispatch) { if (Function_Type) // protect against bootstrap mPrototype = Function_Type->mPrototypeObject; mActivation.mContainer = this; - defineVariable(cx, cx->Prototype_StringAtom, (NamespaceList *)NULL, 0, Object_Type, JSValue(Object_Type->newInstance(cx))); + defineVariable(cx, cx->Prototype_StringAtom, (NamespaceList *)NULL, 0, Object_Type, Object_Type->newInstance(cx)); defineVariable(cx, cx->UnderbarPrototype_StringAtom, (NamespaceList *)NULL, 0, Object_Type, mPrototype); } -JSValue JSFunction::runParameterInitializer(Context *cx, uint32 a, const JSValue& thisValue, JSValue *argv, uint32 argc) +js2val JSFunction::runParameterInitializer(Context *cx, uint32 a, const js2val thisValue, js2val *argv, uint32 argc) { ASSERT(mParameters && (a < maxParameterIndex())); return cx->interpret(getByteCode(), (int32)mParameters[a].mInitializer, getScopeChain(), thisValue, argv, argc); @@ -2929,16 +2912,22 @@ void JSFunction::setParameterCounts(Context *cx, uint32 r, uint32 o, uint32 n, b mOptionalParameters = o; mNamedParameters = n; mParameters = new ParameterData[mRequiredParameters + mOptionalParameters + + mNamedParameters + ((hasRest) ? 1 : 0)]; - defineVariable(cx, cx->Length_StringAtom, (NamespaceList *)NULL, Property::DontDelete | Property::ReadOnly, Number_Type, JSValue((float64)mRequiredParameters)); + defineVariable(cx, cx->Length_StringAtom, (NamespaceList *)NULL, Property::DontDelete | Property::ReadOnly, Number_Type, JSValue::newNumber((float64)mRequiredParameters)); } - +js2val JSFunction::invokeNativeCode(Context *cx, const js2val thisValue, js2val argv[], uint32 argc) +{ + if (mDispatch) + return (mDispatch)(mNativeCode, cx, thisValue, argv, argc); + else + return mNativeCode(cx, thisValue, argv, argc); +} void Context::assureStackSpace(uint32 s) { if ((mStackMax - mStackTop) < s) { - JSValue *newStack = new JSValue[mStackMax + s]; + js2val *newStack = new js2val[mStackMax + s]; for (uint32 i = 0; i < mStackTop; i++) newStack[i] = mStack[i]; delete[] mStack; @@ -2955,7 +2944,7 @@ void Context::assureStackSpace(uint32 s) void Context::initClass(JSType *type, ClassDef *cdef, PrototypeFunctions *pdef) { mScopeChain->addScope(type); - JSFunction *constructor = new JSFunction(this, cdef->defCon, Object_Type); + JSFunction *constructor = new JSFunction(this, cdef->defCon, Object_Type, NULL); constructor->setClass(type); constructor->setFunctionName(type->mClassName); type->setDefaultConstructor(this, constructor); @@ -2963,41 +2952,41 @@ void Context::initClass(JSType *type, ClassDef *cdef, PrototypeFunctions *pdef) // the prototype functions are defined in the prototype object... if (pdef) { for (uint32 i = 0; i < pdef->mCount; i++) { - JSFunction *fun = new JSFunction(this, pdef->mDef[i].imp, pdef->mDef[i].result); + JSFunction *fun = new JSFunction(this, pdef->mDef[i].imp, pdef->mDef[i].result, NULL); // fun->setClass(type); don't do this, it makes the function a method StringAtom *name = &mWorld.identifiers[widenCString(pdef->mDef[i].name)]; fun->setFunctionName(name); fun->setParameterCounts(this, pdef->mDef[i].length, 0, 0, false); - type->mPrototypeObject.getObjectValue()->defineVariable(this, *name, + JSValue::getObjectValue(type->mPrototypeObject)->defineVariable(this, *name, (NamespaceList *)(NULL), Property::NoAttribute, pdef->mDef[i].result, - JSValue(fun)); + JSValue::newFunction(fun)); } } type->completeClass(this, mScopeChain); type->setStaticInitializer(this, NULL); type->mUninitializedValue = *cdef->uninit; - getGlobalObject()->defineVariable(this, widenCString(cdef->name), (NamespaceList *)(NULL), Property::NoAttribute, Type_Type, JSValue(type)); + getGlobalObject()->defineVariable(this, widenCString(cdef->name), (NamespaceList *)(NULL), Property::NoAttribute, Type_Type, JSValue::newType(type)); mScopeChain->popScope(); if (pdef) delete pdef; } -static JSValue arrayMaker(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 argc) +static js2val arrayMaker(Context *cx, const js2val /*thisValue*/, js2val *argv, uint32 argc) { ASSERT(argc == 2); - ASSERT(argv[0].isType()); - JSType *baseType = argv[0].type; + ASSERT(JSValue::isType(argv[0])); + JSType *baseType = JSValue::type(argv[0]); - if ((baseType == Array_Type) && argv[1].isType()) { - JSType *elementType = argv[1].type; + if ((baseType == Array_Type) && JSValue::isType(argv[1])) { + JSType *elementType = JSValue::type(argv[1]); JSType *result = new JSArrayType(cx, elementType, NULL, Object_Type, kNullValue, kNullValue); result->setDefaultConstructor(cx, Array_Type->getDefaultConstructor()); - return JSValue(result); + return JSValue::newType(result); } else { // then it's just [] - an element reference - argv[0].type->getProperty(cx, *argv[1].toString(cx).string, NULL); + JSValue::type(argv[0])->getProperty(cx, *JSValue::string(JSValue::toString(cx, argv[1])), NULL); return cx->popValue(); } @@ -3048,12 +3037,12 @@ void Context::initBuiltins() // (which we don't actually have, hmm). // For String, etc. this same issue needs to be finessed - JSValue protoVal; + js2val protoVal; JSFunction *funProto = new JSFunction(this, Object_Type, NULL); funProto->mPrototype = Object_Type->mPrototypeObject; funProto->defineVariable(this, UnderbarPrototype_StringAtom, NULL, 0, Object_Type, funProto->mPrototype); - protoVal = JSValue(funProto); + protoVal = JSValue::newFunction(funProto); Function_Type = new JSType(this, &mWorld.identifiers[widenCString(builtInClasses[2].name)], Object_Type, protoVal, kNullValue); Function_Type->mPrototype = Function_Type->mPrototypeObject; funProto->mType = Function_Type; @@ -3064,32 +3053,32 @@ void Context::initBuiltins() JSNumberInstance *numProto = new JSNumberInstance(this); - protoVal = JSValue(numProto); + protoVal = JSValue::newInstance(numProto); Number_Type = new JSNumberType(this, &mWorld.identifiers[widenCString(builtInClasses[3].name)], Object_Type, protoVal, Function_Type->mPrototypeObject); numProto->mType = Number_Type; Integer_Type = new JSType(this, &mWorld.identifiers[widenCString(builtInClasses[4].name)], Object_Type, kNullValue, kNullValue); JSStringInstance *strProto = new JSStringInstance(this); - protoVal = JSValue(strProto); + protoVal = JSValue::newInstance(strProto); String_Type = new JSStringType(this, &mWorld.identifiers[widenCString(builtInClasses[5].name)], Object_Type, protoVal, Function_Type->mPrototypeObject); strProto->mValue = &Empty_StringAtom; strProto->mPrototype = Function_Type->mPrototypeObject; strProto->mType = String_Type; JSArrayInstance *arrayProto = new JSArrayInstance(this); - protoVal = JSValue(arrayProto); + protoVal = JSValue::newInstance(arrayProto); Array_Type = new JSArrayType(this, Object_Type, &mWorld.identifiers[widenCString(builtInClasses[6].name)], Object_Type, protoVal, Function_Type->mPrototypeObject); arrayProto->mType = Array_Type; JSBooleanInstance *boolProto = new JSBooleanInstance(this); - protoVal = JSValue(boolProto); + protoVal = JSValue::newInstance(boolProto); Boolean_Type = new JSBooleanType(this, &mWorld.identifiers[widenCString(builtInClasses[7].name)], Object_Type, protoVal, Function_Type->mPrototypeObject); boolProto->mValue = false; boolProto->mType = Boolean_Type; JSDateInstance *dateProto = new JSDateInstance(this); - protoVal = JSValue(dateProto); + protoVal = JSValue::newInstance(dateProto); Date_Type = new JSDateType(this, &mWorld.identifiers[widenCString(builtInClasses[12].name)], Object_Type, protoVal, Function_Type->mPrototypeObject); dateProto->mType = Date_Type; @@ -3109,7 +3098,7 @@ void Context::initBuiltins() // XXX RegExp.prototype is set to a RegExp instance, which isn't ECMA (it's supposed to be an Object instance) but // is SpiderMonkey compatible. JSRegExpInstance *regExpProto = new JSRegExpInstance(this); - protoVal = JSValue(regExpProto); + protoVal = JSValue::newInstance(regExpProto); RegExp_Type = new JSRegExpType(this, &mWorld.identifiers[widenCString(builtInClasses[21].name)], Object_Type, protoVal, Function_Type->mPrototypeObject); regExpProto->mPrototype = Object_Type->mPrototypeObject; regExpProto->mType = RegExp_Type; @@ -3174,7 +3163,7 @@ void Context::initBuiltins() }; ASSERT(mGlobal); - *mGlobal = Object_Type->newInstance(this).object; + *mGlobal = JSValue::object(Object_Type->newInstance(this)); initClass(Object_Type, &builtInClasses[0], new PrototypeFunctions(&objectProtos[0]) ); initClass(Type_Type, &builtInClasses[1], NULL ); @@ -3199,40 +3188,40 @@ void Context::initBuiltins() initClass(UriError_Type, &builtInClasses[20], new PrototypeFunctions(&errorProtos[0])); initClass(RegExp_Type, &builtInClasses[21], new PrototypeFunctions(®expProtos[0])); - defineOperator(Index, Type_Type, new JSFunction(this, arrayMaker, Type_Type)); + defineOperator(Index, Type_Type, new JSFunction(this, arrayMaker, Type_Type, NULL)); - Object_Type->mTypeCast = new JSFunction(this, Object_Constructor, Object_Type); - Function_Type->mTypeCast = new JSFunction(this, Function_Constructor, Object_Type); + Object_Type->mTypeCast = new JSFunction(this, Object_Constructor, Object_Type, NULL); + Function_Type->mTypeCast = new JSFunction(this, Function_Constructor, Object_Type, NULL); - Number_Type->mTypeCast = new JSFunction(this, Number_TypeCast, Number_Type); + Number_Type->mTypeCast = new JSFunction(this, Number_TypeCast, Number_Type, NULL); - defineOperator(Index, Array_Type, new JSFunction(this, Array_GetElement, Object_Type)); - defineOperator(IndexEqual, Array_Type, new JSFunction(this, Array_SetElement, Object_Type)); - Array_Type->mTypeCast = new JSFunction(this, Array_Constructor, Array_Type); - Array_Type->defineVariable(this, Length_StringAtom, NULL, Property::NoAttribute, Number_Type, JSValue(1.0)); + defineOperator(Index, Array_Type, new JSFunction(this, Array_GetElement, Object_Type, NULL)); + defineOperator(IndexEqual, Array_Type, new JSFunction(this, Array_SetElement, Object_Type, NULL)); + Array_Type->mTypeCast = new JSFunction(this, Array_Constructor, Array_Type, NULL); + Array_Type->defineVariable(this, Length_StringAtom, NULL, Property::NoAttribute, Number_Type, JSValue::newNumber(1.0)); - Boolean_Type->mTypeCast = new JSFunction(this, Boolean_TypeCast, Boolean_Type); - Boolean_Type->defineVariable(this, Length_StringAtom, NULL, Property::NoAttribute, Number_Type, JSValue(1.0)); + Boolean_Type->mTypeCast = new JSFunction(this, Boolean_TypeCast, Boolean_Type, NULL); + Boolean_Type->defineVariable(this, Length_StringAtom, NULL, Property::NoAttribute, Number_Type, JSValue::newNumber(1.0)); - Date_Type->mTypeCast = new JSFunction(this, Date_TypeCast, String_Type); - Date_Type->defineStaticMethod(this, widenCString("parse"), NULL, new JSFunction(this, Date_parse, Number_Type)); - Date_Type->defineStaticMethod(this, widenCString("UTC"), NULL, new JSFunction(this, Date_UTC, Number_Type)); + Date_Type->mTypeCast = new JSFunction(this, Date_TypeCast, String_Type, NULL); + Date_Type->defineStaticMethod(this, widenCString("parse"), NULL, new JSFunction(this, Date_parse, Number_Type, NULL)); + Date_Type->defineStaticMethod(this, widenCString("UTC"), NULL, new JSFunction(this, Date_UTC, Number_Type, NULL)); - JSFunction *fromCharCode = new JSFunction(this, String_fromCharCode, String_Type); - fromCharCode->defineVariable(this, Length_StringAtom, (NamespaceList *)NULL, Property::DontDelete | Property::ReadOnly, Number_Type, JSValue(1.0)); - String_Type->defineVariable(this, FromCharCode_StringAtom, NULL, String_Type, JSValue(fromCharCode)); - String_Type->mTypeCast = new JSFunction(this, String_TypeCast, String_Type); - String_Type->defineVariable(this, Length_StringAtom, NULL, Property::NoAttribute, Number_Type, JSValue(1.0)); + JSFunction *fromCharCode = new JSFunction(this, String_fromCharCode, String_Type, NULL); + fromCharCode->defineVariable(this, Length_StringAtom, (NamespaceList *)NULL, Property::DontDelete | Property::ReadOnly, Number_Type, JSValue::newNumber(1.0)); + String_Type->defineVariable(this, FromCharCode_StringAtom, NULL, String_Type, JSValue::newFunction(fromCharCode)); + String_Type->mTypeCast = new JSFunction(this, String_TypeCast, String_Type, NULL); + String_Type->defineVariable(this, Length_StringAtom, NULL, Property::NoAttribute, Number_Type, JSValue::newNumber(1.0)); - Error_Type->mTypeCast = new JSFunction(this, Error_Constructor, Error_Type); - RegExp_Type->mTypeCast = new JSFunction(this, RegExp_TypeCast, Error_Type); + Error_Type->mTypeCast = new JSFunction(this, Error_Constructor, Error_Type, NULL); + RegExp_Type->mTypeCast = new JSFunction(this, RegExp_TypeCast, Error_Type, NULL); // XXX these RegExp statics are not specified by ECMA, but implemented by SpiderMonkey - RegExp_Type->defineVariable(this, Input_StringAtom, NULL, Property::NoAttribute, String_Type, JSValue(&Empty_StringAtom)); - RegExp_Type->defineVariable(this, LastMatch_StringAtom, NULL, Property::NoAttribute, String_Type, JSValue(&Empty_StringAtom)); - RegExp_Type->defineVariable(this, LastParen_StringAtom, NULL, Property::NoAttribute, String_Type, JSValue(&Empty_StringAtom)); - RegExp_Type->defineVariable(this, LeftContext_StringAtom, NULL, Property::NoAttribute, String_Type, JSValue(&Empty_StringAtom)); - RegExp_Type->defineVariable(this, RightContext_StringAtom, NULL, Property::NoAttribute, String_Type, JSValue(&Empty_StringAtom)); + RegExp_Type->defineVariable(this, Input_StringAtom, NULL, Property::NoAttribute, String_Type, JSValue::newString(&Empty_StringAtom)); + RegExp_Type->defineVariable(this, LastMatch_StringAtom, NULL, Property::NoAttribute, String_Type, JSValue::newString(&Empty_StringAtom)); + RegExp_Type->defineVariable(this, LastParen_StringAtom, NULL, Property::NoAttribute, String_Type, JSValue::newString(&Empty_StringAtom)); + RegExp_Type->defineVariable(this, LeftContext_StringAtom, NULL, Property::NoAttribute, String_Type, JSValue::newString(&Empty_StringAtom)); + RegExp_Type->defineVariable(this, RightContext_StringAtom, NULL, Property::NoAttribute, String_Type, JSValue::newString(&Empty_StringAtom)); } @@ -3386,17 +3375,17 @@ Context::Context(JSObject **global, World &world, Arena &a, Pragma::Flags flags) } JSType *MathType = new JSType(this, &mWorld.identifiers[widenCString("Math")], Object_Type, Object_Type->mPrototypeObject, kNullValue); - JSObject *mathObj = MathType->newInstance(this).instance; + JSObject *mathObj = JSValue::instance(MathType->newInstance(this)); - getGlobalObject()->defineVariable(this, Math_StringAtom, (NamespaceList *)(NULL), Property::NoAttribute, Object_Type, JSValue(mathObj)); + getGlobalObject()->defineVariable(this, Math_StringAtom, (NamespaceList *)(NULL), Property::NoAttribute, Object_Type, JSValue::newObject(mathObj)); initMathObject(this, mathObj); initDateObject(this); - Number_Type->defineVariable(this, widenCString("MAX_VALUE"), NULL, Property::ReadOnly | Property::DontDelete, Number_Type, JSValue(maxValue)); - Number_Type->defineVariable(this, widenCString("MIN_VALUE"), NULL, Property::ReadOnly | Property::DontDelete, Number_Type, JSValue(minValue)); - Number_Type->defineVariable(this, widenCString("NaN"), NULL, Property::ReadOnly | Property::DontDelete, Number_Type, JSValue(nan)); - Number_Type->defineVariable(this, widenCString("POSITIVE_INFINITY"), NULL, Property::ReadOnly | Property::DontDelete, Number_Type, JSValue(positiveInfinity)); - Number_Type->defineVariable(this, widenCString("NEGATIVE_INFINITY"), NULL, Property::ReadOnly | Property::DontDelete, Number_Type, JSValue(negativeInfinity)); + Number_Type->defineVariable(this, widenCString("MAX_VALUE"), NULL, Property::ReadOnly | Property::DontDelete, Number_Type, JSValue::newNumber(maxValue)); + Number_Type->defineVariable(this, widenCString("MIN_VALUE"), NULL, Property::ReadOnly | Property::DontDelete, Number_Type, JSValue::newNumber(minValue)); + Number_Type->defineVariable(this, widenCString("NaN"), NULL, Property::ReadOnly | Property::DontDelete, Number_Type, JSValue::newNumber(nan)); + Number_Type->defineVariable(this, widenCString("POSITIVE_INFINITY"), NULL, Property::ReadOnly | Property::DontDelete, Number_Type, JSValue::newNumber(positiveInfinity)); + Number_Type->defineVariable(this, widenCString("NEGATIVE_INFINITY"), NULL, Property::ReadOnly | Property::DontDelete, Number_Type, JSValue::newNumber(negativeInfinity)); initOperators(); @@ -3430,11 +3419,11 @@ Context::Context(JSObject **global, World &world, Arena &a, Pragma::Flags flags) for (i = 0; i < (sizeof(attribute_init) / sizeof(Attribute_Init)); i++) { Attribute *attr = new Attribute(attribute_init[i].trueFlags, attribute_init[i].falseFlags); - getGlobalObject()->defineVariable(this, widenCString(attribute_init[i].name), (NamespaceList *)(NULL), Property::NoAttribute, Attribute_Type, JSValue(attr)); + getGlobalObject()->defineVariable(this, widenCString(attribute_init[i].name), (NamespaceList *)(NULL), Property::NoAttribute, Attribute_Type, JSValue::newAttribute(attr)); } - JSFunction *x = new JSFunction(this, ExtendAttribute_Invoke, Attribute_Type); - getGlobalObject()->defineVariable(this, Extend_StringAtom, (NamespaceList *)(NULL), Property::NoAttribute, Attribute_Type, JSValue(x)); + JSFunction *x = new JSFunction(this, ExtendAttribute_Invoke, Attribute_Type, NULL); + getGlobalObject()->defineVariable(this, Extend_StringAtom, (NamespaceList *)(NULL), Property::NoAttribute, Attribute_Type, JSValue::newFunction(x)); @@ -3450,10 +3439,10 @@ Context::Context(JSObject **global, World &world, Arena &a, Pragma::Flags flags) }; for (i = 0; i < (sizeof(globalObjectFunctions) / sizeof(ProtoFunDef)); i++) { - x = new JSFunction(this, globalObjectFunctions[i].imp, globalObjectFunctions[i].result); + x = new JSFunction(this, globalObjectFunctions[i].imp, globalObjectFunctions[i].result, NULL); x->setParameterCounts(this, globalObjectFunctions[i].length, 0, 0, false); x->setIsPrototype(true); - getGlobalObject()->defineVariable(this, widenCString(globalObjectFunctions[i].name), (NamespaceList *)(NULL), Property::NoAttribute, globalObjectFunctions[i].result, JSValue(x)); + getGlobalObject()->defineVariable(this, widenCString(globalObjectFunctions[i].name), (NamespaceList *)(NULL), Property::NoAttribute, globalObjectFunctions[i].result, JSValue::newFunction(x)); } getGlobalObject()->defineVariable(this, Undefined_StringAtom, (NamespaceList *)(NULL), Property::NoAttribute, Void_Type, kUndefinedValue); @@ -3464,63 +3453,32 @@ Context::Context(JSObject **global, World &world, Arena &a, Pragma::Flags flags) /* - See if the specified package is already loaded - return true - Throw an exception if the package is being loaded already - */ - bool Context::checkForPackage(const String &packageName) - { - // XXX linear search - for (PackageList::iterator pi = mPackages.begin(), end = mPackages.end(); (pi != end); pi++) { - if (PACKAGE_NAME(pi).compare(packageName) == 0) { - if (PACKAGE_STATUS(pi) == Package::OnItsWay) - reportError(Exception::referenceError, "Package circularity"); - else - return true; - } - } - return false; - } - /* - Load the specified package from the file - */ - void Context::loadPackage(const String & /*packageName*/, const String &filename) - { - // XXX need some rules for search path - // XXX need to extract just the target package from the file - - - readEvalFile(filename); - - - - - } @@ -3581,52 +3539,52 @@ void Context::reportError(Exception::Kind kind, char *message, size_t pos, const reportError(kind, message, pos, str.c_str()); } -Formatter& operator<<(Formatter& f, const JSValue& value) +void JSValue::print(Formatter& f, const js2val value) { - switch (value.tag) { - case JSValue::f64_tag: - f << value.f64; + switch (tag(value)) { + case JS2VAL_DOUBLE: + f << f64(value); break; - case JSValue::object_tag: - printFormat(f, "Object @ 0x%08X\n", value.object); - f << *value.object; - break; - case JSValue::type_tag: - printFormat(f, "Type @ 0x%08X\n", value.type); - f << *value.type; - break; - case JSValue::boolean_tag: - f << ((value.boolean) ? "true" : "false"); - break; - case JSValue::string_tag: - f << *value.string; - break; - case JSValue::undefined_tag: - f << "undefined"; - break; - case JSValue::null_tag: - f << "null"; - break; - case JSValue::function_tag: - if (!value.function->isNative()) { - FunctionName *fnName = value.function->getFunctionName(); - if (fnName) { - StringFormatter s; - PrettyPrinter pp(s); - fnName->print(pp); - f << "function '" << s.getString() << "'\n" << *value.function->getByteCode(); - } - else { - f << "function anonymous\n" << *value.function->getByteCode(); - } + case JS2VAL_OBJECT: + if (isNull(value)) + f << "null"; + else if (isType(value)) { + printFormat(f, "Type @ 0x%08X\n", JSValue::type(value)); + f << *JSValue::type(value); } - else - f << "function\n"; + else if (isFunction(value)) { + if (!JSValue::function(value)->isNative()) { + FunctionName *fnName = JSValue::function(value)->getFunctionName(); + if (fnName) { + StringFormatter s; + PrettyPrinter pp(s); + fnName->print(pp); + f << "function '" << s.getString() << "'\n" << *JSValue::function(value)->getByteCode(); + } + else { + f << "function anonymous\n" << *JSValue::function(value)->getByteCode(); + } + } + else + f << "function\n"; + } + else { + printFormat(f, "Object @ 0x%08X\n", object(value)); + f << *JSValue::object(value); + } + break; + case JS2VAL_BOOLEAN: + f << ((JSValue::boolean(value)) ? "true" : "false"); + break; + case JS2VAL_STRING: + f << *JSValue::string(value); + break; + case JS2VAL_INT: + f << "undefined"; break; default: NOT_REACHED("Bad tag"); } - return f; } void JSType::printSlotsNStuff(Formatter& f) const @@ -3677,16 +3635,16 @@ Formatter& operator<<(Formatter& f, const Property& prop) switch (prop.mFlag) { case ValuePointer : { - JSValue v = *prop.mData.vp; + js2val v = prop.mData.vp; f << "ValuePointer --> "; - if (v.isObject()) - printFormat(f, "Object @ 0x%08X\n", v.object); + if (JSValue::isObject(v)) + printFormat(f, "Object @ 0x%08X\n", JSValue::object(v)); else - if (v.isType()) - printFormat(f, "Type @ 0x%08X\n", v.type); + if (JSValue::isType(v)) + printFormat(f, "Type @ 0x%08X\n", JSValue::type(v)); else - if (v.isFunction()) - printFormat(f, "Function @ 0x%08X\n", v.function); + if (JSValue::isFunction(v)) + printFormat(f, "Function @ 0x%08X\n", JSValue::function(v)); else f << v << "\n"; } @@ -3705,7 +3663,7 @@ Formatter& operator<<(Formatter& f, const JSInstance& obj) const Property *prop = PROPERTY(i); f << "[" << PROPERTY_NAME(i) << "] "; switch (prop->mFlag) { - case ValuePointer : f << "ValuePointer --> " << *prop->mData.vp; break; + case ValuePointer : f << "Value --> " << prop->mData.vp; break; case FunctionPair : f << "FunctionPair\n"; break; case IndexPair : f << "IndexPair\n"; break; case Slot : f << "Slot #" << prop->mData.index diff --git a/mozilla/js2/src/js2runtime.h b/mozilla/js2/src/js2runtime.h index b21d4a2d9bd..aec49b8200b 100644 --- a/mozilla/js2/src/js2runtime.h +++ b/mozilla/js2/src/js2runtime.h @@ -131,121 +131,155 @@ static const double two31 = 2147483648.0; float64 stringToNumber(const String *string); +#define JS2_BIT(n) ((uint32)1 << (n)) +#define JS2_BITMASK(n) (JS2_BIT(n) - 1) +/* + * Type tags stored in the low bits of a js2val. + */ +#define JS2VAL_OBJECT 0x0 /* untagged reference to object */ +#define JS2VAL_INT 0x1 /* tagged 31-bit integer value */ +#define JS2VAL_DOUBLE 0x2 /* tagged reference to double */ +#define JS2VAL_STRING 0x4 /* tagged reference to string */ +#define JS2VAL_BOOLEAN 0x6 /* tagged boolean value */ + +/* Type tag bitfield length and derived macros. */ +#define JS2VAL_TAGBITS 3 +#define JS2VAL_TAGMASK JS2_BITMASK(JS2VAL_TAGBITS) +#define JS2VAL_TAG(v) ((v) & JS2VAL_TAGMASK) +#define JS2VAL_SETTAG(v,t) ((v) | (t)) +#define JS2VAL_CLRTAG(v) ((v) & ~(js2val)JS2VAL_TAGMASK) +#define JS2VAL_ALIGN JS2_BIT(JS2VAL_TAGBITS) + +#define JS2VAL_INT_POW2(n) ((js2val)1 << (n)) +#define INT_TO_JS2VAL(i) (((js2val)(i) << 1) | JS2VAL_INT) +#define JS2VAL_VOID INT_TO_JS2VAL(0 - JS2VAL_INT_POW2(30)) +#define JS2VAL_NULL OBJECT_TO_JS2VAL(0) +#define JS2VAL_FALSE BOOLEAN_TO_JS2VAL(false) +#define JS2VAL_TRUE BOOLEAN_TO_JS2VAL(true) + +/* Predicates for type testing. */ +#define JS2VAL_IS_OBJECT(v) (JS2VAL_TAG(v) == JS2VAL_OBJECT) +#define JS2VAL_IS_NUMBER(v) (JS2VAL_IS_INT(v) || JS2VAL_IS_DOUBLE(v)) +#define JS2VAL_IS_INT(v) (((v) & JS2VAL_INT) && (v) != JS2VAL_VOID) +#define JS2VAL_IS_DOUBLE(v) (JS2VAL_TAG(v) == JS2VAL_DOUBLE) +#define JS2VAL_IS_STRING(v) (JS2VAL_TAG(v) == JS2VAL_STRING) +#define JS2VAL_IS_BOOLEAN(v) (JS2VAL_TAG(v) == JS2VAL_BOOLEAN) +#define JS2VAL_IS_NULL(v) ((v) == JS2VAL_NULL) +#define JS2VAL_IS_VOID(v) ((v) == JS2VAL_VOID) +#define JS2VAL_IS_PRIMITIVE(v) (!JS2VAL_IS_OBJECT(v) || JS2VAL_IS_NULL(v)) + +/* Objects, strings, and doubles are GC'ed. */ +#define JS2VAL_IS_GCTHING(v) (!((v) & JS2VAL_INT) && !JS2VAL_IS_BOOLEAN(v)) +#define JS2VAL_TO_GCTHING(v) ((void *)JS2VAL_CLRTAG(v)) +#define JS2VAL_TO_OBJECT(v) ((JSObject *)JS2VAL_TO_GCTHING(v)) +#define JS2VAL_TO_DOUBLE(v) ((float64 *)JS2VAL_TO_GCTHING(v)) +#define JS2VAL_TO_STRING(v) ((String *)JS2VAL_TO_GCTHING(v)) +#define OBJECT_TO_JS2VAL(obj) ((js2val)(obj)) +#define DOUBLE_TO_JS2VAL(dp) JS2VAL_SETTAG((js2val)(dp), JS2VAL_DOUBLE) +#define STRING_TO_JS2VAL(str) JS2VAL_SETTAG((js2val)(str), JS2VAL_STRING) + +/* Convert between boolean and jsval. */ +#define JS2VAL_TO_BOOLEAN(v) (((v) >> JS2VAL_TAGBITS) != 0) +#define BOOLEAN_TO_JS2VAL(b) JS2VAL_SETTAG((js2val)(b) << JS2VAL_TAGBITS, \ + JS2VAL_BOOLEAN) + class JSValue { - public: - union { - float64 f64; - JSObject *object; - JSInstance *instance; - JSFunction *function; - const String *string; - JSType *type; - bool boolean; - NamedArgument *namedArg; - Attribute *attribute; - Package *package; - }; + private: + JSValue() { ASSERT(false); } + + public: + + static int32 tag(const js2val v) { return JS2VAL_TAG(v); } + static float64 f64(const js2val v) { return *JS2VAL_TO_DOUBLE(v); } + static JSObject *object(const js2val v) { return JS2VAL_TO_OBJECT(v); } + static JSInstance *instance(const js2val v) { return (JSInstance *)JS2VAL_TO_OBJECT(v); } + static JSFunction *function(const js2val v) { return (JSFunction *)JS2VAL_TO_OBJECT(v); } + static JSType *type(const js2val v) { return (JSType *)JS2VAL_TO_OBJECT(v); } + static const String *string(const js2val v) { return JS2VAL_TO_STRING(v); } + static bool boolean(const js2val v) { return JS2VAL_TO_BOOLEAN(v); } + static NamedArgument *namedArg(const js2val v) { return (NamedArgument *)JS2VAL_TO_OBJECT(v); } + static Attribute *attribute(const js2val v) { return (Attribute *)JS2VAL_TO_OBJECT(v); } + static Package *package(const js2val v) { return (Package *)JS2VAL_TO_OBJECT(v); } + + static js2val newNumber(float64 f) { return DOUBLE_TO_JS2VAL(new double(f));} + static js2val newObject(JSObject *object) { return OBJECT_TO_JS2VAL(object); } + static js2val newInstance(JSInstance *instance) { return OBJECT_TO_JS2VAL(instance); } + static js2val newFunction(JSFunction *function) { return OBJECT_TO_JS2VAL(function); } + static js2val newType(JSType *type) { return OBJECT_TO_JS2VAL(type); } + static js2val newString(const String *string) { return STRING_TO_JS2VAL(string); } + static js2val newBoolean(bool boolean) { return BOOLEAN_TO_JS2VAL(boolean); } + + static js2val newNamedArg(NamedArgument *arg) { return OBJECT_TO_JS2VAL(arg); } + static js2val newAttribute(Attribute *attr) { return OBJECT_TO_JS2VAL(attr); } + static js2val newPackage(Package *pkg) { return OBJECT_TO_JS2VAL(pkg); } + - typedef enum { - undefined_tag, - f64_tag, - object_tag, - instance_tag, - function_tag, - type_tag, - boolean_tag, - string_tag, - null_tag, - namedArg_tag, - attribute_tag, - package_tag - } Tag; - Tag tag; - - JSValue() : f64(0.0), tag(undefined_tag) {} - explicit JSValue(float64 f64) : f64(f64), tag(f64_tag) {} - explicit JSValue(JSObject *object) : object(object), tag(object_tag) { ASSERT(object); } - explicit JSValue(JSInstance *instance) : instance(instance), tag(instance_tag) { ASSERT(instance); } - explicit JSValue(JSFunction *function) : function(function), tag(function_tag) { ASSERT(function); } - explicit JSValue(JSType *type) : type(type), tag(type_tag) { ASSERT(type); } - explicit JSValue(const String *string) : string(string), tag(string_tag) { ASSERT(string); } - explicit JSValue(bool boolean) : boolean(boolean), tag(boolean_tag) {} - explicit JSValue(NamedArgument *arg) : namedArg(arg), tag(namedArg_tag) { ASSERT(arg); } - explicit JSValue(Attribute *attr) : attribute(attr), tag(attribute_tag) { ASSERT(attribute); } - explicit JSValue(Package *pkg) : package(pkg), tag(package_tag) { ASSERT(pkg); } - explicit JSValue(Tag tag) : tag(tag) {} + static bool isObject(const js2val v) { return JS2VAL_IS_OBJECT(v); } + static bool isInstance(const js2val v); + static bool isNumber(js2val v) { return JS2VAL_IS_NUMBER(v); } + static bool isBool(const js2val v) { return JS2VAL_IS_BOOLEAN(v); } + static bool isType(const js2val v); + static bool isFunction(const js2val v); + static bool isString(const js2val v) { return JS2VAL_IS_STRING(v); } + static bool isPrimitive(const js2val v) { return isNumber(v) || isBool(v) || isString(v) || isUndefined(v) || isNull(v); } + static bool isNamedArg(const js2val v); + static bool isAttribute(const js2val v); + static bool isPackage(const js2val v); - float64& operator=(float64 f64) { return (tag = f64_tag, this->f64 = f64); } - JSObject*& operator=(JSObject* object) { return (tag = object_tag, this->object = object); } - JSInstance*& operator=(JSInstance* instance) { return (tag = instance_tag, this->instance = instance); } - JSType*& operator=(JSType* type) { return (tag = type_tag, this->type = type); } - JSFunction*& operator=(JSFunction* function) { return (tag = function_tag, this->function = function); } - bool& operator=(bool boolean) { return (tag = boolean_tag, this->boolean = boolean); } - - bool isObject() const { return (tag == object_tag); } - bool isInstance() const { return (tag == instance_tag); } - bool isNumber() const { return (tag == f64_tag); } - bool isBool() const { return (tag == boolean_tag); } - bool isType() const { return (tag == type_tag); } - bool isFunction() const { return (tag == function_tag); } - bool isString() const { return (tag == string_tag); } - bool isPrimitive() const { return isNumber() || isBool() || isString() || isUndefined() || isNull(); } - bool isNamedArg() const { return (tag == namedArg_tag); } - bool isAttribute() const { return (tag == attribute_tag); } - bool isPackage() const { return (tag == package_tag); } + static bool isUndefined(const js2val v) { return JS2VAL_IS_VOID(v); } + static bool isNull(const js2val v) { return JS2VAL_IS_NULL(v); } + static bool isNaN(const js2val v) { ASSERT(isNumber(v)); return JSDOUBLE_IS_NaN(*JS2VAL_TO_DOUBLE(v)); } + static bool isNegativeInfinity(const js2val v) { ASSERT(isNumber(v)); return (*JS2VAL_TO_DOUBLE(v) < 0) && JSDOUBLE_IS_INFINITE(*JS2VAL_TO_DOUBLE(v)); } + static bool isPositiveInfinity(const js2val v) { ASSERT(isNumber(v)); return (*JS2VAL_TO_DOUBLE(v) > 0) && JSDOUBLE_IS_INFINITE(*JS2VAL_TO_DOUBLE(v)); } + static bool isNegativeZero(const js2val v) { ASSERT(isNumber(v)); return JSDOUBLE_IS_NEGZERO(*JS2VAL_TO_DOUBLE(v)); } + static bool isPositiveZero(const js2val v) { ASSERT(isNumber(v)); return JSDOUBLE_IS_POSZERO(*JS2VAL_TO_DOUBLE(v)); } - bool isUndefined() const { return (tag == undefined_tag); } - bool isNull() const { return (tag == null_tag); } - bool isNaN() const { ASSERT(isNumber()); return JSDOUBLE_IS_NaN(f64); } - bool isNegativeInfinity() const { ASSERT(isNumber()); return (f64 < 0) && JSDOUBLE_IS_INFINITE(f64); } - bool isPositiveInfinity() const { ASSERT(isNumber()); return (f64 > 0) && JSDOUBLE_IS_INFINITE(f64); } - bool isNegativeZero() const { ASSERT(isNumber()); return JSDOUBLE_IS_NEGZERO(f64); } - bool isPositiveZero() const { ASSERT(isNumber()); return JSDOUBLE_IS_POSZERO(f64); } + static bool isFalse(const js2val v) { return (v == JS2VAL_FALSE); } + static bool isTrue(const js2val v) { return (v == JS2VAL_TRUE); } - bool isTrue() const { ASSERT(isBool()); return boolean; } - bool isFalse() const { ASSERT(isBool()); return !boolean; } + static JSType *getType(const js2val v); - JSType *getType() const; + static js2val toString(Context *cx, const js2val v) { return (isString(v) ? v : valueToString(cx, v)); } + static js2val toNumber(Context *cx, const js2val v) { return (isNumber(v) ? v : valueToNumber(cx, v)); } + static js2val toInteger(Context *cx, const js2val v) { return valueToInteger(cx, v); } + static js2val toUInt32(Context *cx, const js2val v) { return valueToUInt32(cx, v); } + static js2val toUInt16(Context *cx, const js2val v) { return valueToUInt16(cx, v); } + static js2val toInt32(Context *cx, const js2val v) { return valueToInt32(cx, v); } + static js2val toObject(Context *cx, const js2val v) { return ((isObject(v) || isType(v) || isFunction(v) || isInstance(v) || isPackage(v)) ? + v : valueToObject(cx, v)); } + static js2val toBoolean(Context *cx, const js2val v) { return (isBool(v) ? v : valueToBoolean(cx, v)); } - JSValue toString(Context *cx) const { return (isString() ? *this : valueToString(cx, *this)); } - JSValue toNumber(Context *cx) const { return (isNumber() ? *this : valueToNumber(cx, *this)); } - JSValue toInteger(Context *cx) const { return valueToInteger(cx, *this); } - JSValue toUInt32(Context *cx) const { return valueToUInt32(cx, *this); } - JSValue toUInt16(Context *cx) const { return valueToUInt16(cx, *this); } - JSValue toInt32(Context *cx) const { return valueToInt32(cx, *this); } - JSValue toObject(Context *cx) const { return ((isObject() || isType() || isFunction() || isInstance() || isPackage()) ? - *this : valueToObject(cx, *this)); } - JSValue toBoolean(Context *cx) const { return (isBool() ? *this : valueToBoolean(cx, *this)); } + static float64 getNumberValue(const js2val v); + static const String *getStringValue(const js2val v); + static bool getBoolValue(const js2val v); + static JSObject *getObjectValue(const js2val v); - float64 getNumberValue() const; - const String *getStringValue() const; - bool getBoolValue() const; - JSObject *getObjectValue() const; - - JSObject *toObjectValue(Context *cx) const; + static JSObject *toObjectValue(Context *cx, const js2val v); /* These are for use in 'toPrimitive' calls */ enum Hint { NumberHint, StringHint, NoHint }; - JSValue toPrimitive(Context *cx, Hint hint = NoHint) const; + static js2val toPrimitive(Context *cx, const js2val v, Hint hint = NoHint); - static JSValue valueToNumber(Context *cx, const JSValue& value); - static JSValue valueToInteger(Context *cx, const JSValue& value); - static JSValue valueToString(Context *cx, const JSValue& value); - static JSValue valueToObject(Context *cx, const JSValue& value); - static JSValue valueToUInt32(Context *cx, const JSValue& value); - static JSValue valueToUInt16(Context *cx, const JSValue& value); - static JSValue valueToInt32(Context *cx, const JSValue& value); - static JSValue valueToBoolean(Context *cx, const JSValue& value); + static js2val valueToNumber(Context *cx, const js2val value); + static js2val valueToInteger(Context *cx, const js2val value); + static js2val valueToString(Context *cx, const js2val value); + static js2val valueToObject(Context *cx, const js2val value); + static js2val valueToUInt32(Context *cx, const js2val value); + static js2val valueToUInt16(Context *cx, const js2val value); + static js2val valueToInt32(Context *cx, const js2val value); + static js2val valueToBoolean(Context *cx, const js2val value); static float64 float64ToInteger(float64 d); static int32 float64ToInt32(float64 d); static uint32 float64ToUInt32(float64 d); - int operator==(const JSValue& value) const; - + static void print(Formatter& f, const js2val value); + + +#ifdef NOT_SCARED_OF_GC_CODE /** * Scans through the object, and copies all references. */ @@ -254,8 +288,8 @@ static const double two31 = 2147483648.0; switch (tag) { case object_tag: object = (JSObject*) collector->copy(object); break; case function_tag: function = (JSFunction*) collector->copy(function); break; - case type_tag: type = (JSType*) collector->copy(type); break; - default: break; + case type_tag: type = (JSType*) collector->copy(type); break; + default: break; } return sizeof(JSValue); } @@ -265,24 +299,24 @@ static const double two31 = 2147483648.0; static Collector::InstanceOwner owner; return gc.allocateObject(n, &owner); } +#endif #ifdef DEBUG - void* operator new(size_t s) { void *t = STD::malloc(s); trace_alloc("JSValue", s, t); return t; } + void* operator new(size_t s) { void *t = STD::malloc(s); trace_alloc("JSValue", s, t); return t; } void operator delete(void* t) { trace_release("JSValue", t); STD::free(t); } #endif }; - Formatter& operator<<(Formatter& f, const JSValue& value); - extern JSValue kUndefinedValue; - extern JSValue kNaNValue; - extern JSValue kTrueValue; - extern JSValue kFalseValue; - extern JSValue kNullValue; - extern JSValue kNegativeZero; - extern JSValue kPositiveZero; - extern JSValue kNegativeInfinity; - extern JSValue kPositiveInfinity; + extern js2val kUndefinedValue; + extern js2val kNaNValue; + extern js2val kTrueValue; + extern js2val kFalseValue; + extern js2val kNullValue; + extern js2val kNegativeZero; + extern js2val kPositiveZero; + extern js2val kNegativeInfinity; + extern js2val kPositiveInfinity; @@ -556,7 +590,7 @@ XXX ...couldn't get this to work... PropertyMap mProperties; // Every JSObject (except the Ur-object) has a prototype - JSValue mPrototype; + js2val mPrototype; virtual bool isDynamic() { return true; } @@ -573,11 +607,11 @@ XXX ...couldn't get this to work... virtual bool hasProperty(Context *cx, const String &name, NamespaceList *names, Access acc, PropertyIterator *p); - virtual JSValue getPropertyValue(PropertyIterator &i); + virtual js2val getPropertyValue(PropertyIterator &i); virtual void getProperty(Context *cx, const String &name, NamespaceList *names); - virtual void setProperty(Context *cx, const String &name, NamespaceList *names, const JSValue &v); + virtual void setProperty(Context *cx, const String &name, NamespaceList *names, const js2val v); @@ -587,7 +621,7 @@ XXX ...couldn't get this to work... // add a property/value into the map // - assumes the map doesn't already have this property - Property *insertNewProperty(const String &name, NamespaceList *names, PropertyAttribute attrFlags, JSType *type, const JSValue &v); + Property *insertNewProperty(const String &name, NamespaceList *names, PropertyAttribute attrFlags, JSType *type, const js2val v); virtual Property *defineStaticVariable(Context *cx, const String &name, AttributeStmtNode *attr, JSType *type) { @@ -598,15 +632,15 @@ XXX ...couldn't get this to work... // add a method property virtual void defineMethod(Context *cx, const String &name, AttributeStmtNode *attr, JSFunction *f) { - defineVariable(cx, name, attr, Function_Type, JSValue(f)); + defineVariable(cx, name, attr, Function_Type, JSValue::newFunction(f)); } virtual void defineStaticMethod(Context *cx, const String &name, AttributeStmtNode *attr, JSFunction *f) { - JSObject::defineVariable(cx, name, attr, Function_Type, JSValue(f)); // XXX or error? + JSObject::defineVariable(cx, name, attr, Function_Type, JSValue::newFunction(f)); // XXX or error? } virtual void defineConstructor(Context *cx, const String& name, AttributeStmtNode *attr, JSFunction *f) { - JSObject::defineVariable(cx, name, attr, Function_Type, JSValue(f)); // XXX or error? + JSObject::defineVariable(cx, name, attr, Function_Type, JSValue::newFunction(f)); // XXX or error? } virtual void defineStaticGetterMethod(Context *cx, const String &name, AttributeStmtNode *attr, JSFunction *f) { @@ -619,9 +653,9 @@ XXX ...couldn't get this to work... virtual void defineGetterMethod(Context *cx, const String &name, AttributeStmtNode *attr, JSFunction *f); virtual void defineSetterMethod(Context *cx, const String &name, AttributeStmtNode *attr, JSFunction *f); - virtual Property *defineVariable(Context *cx, const String &name, AttributeStmtNode *attr, JSType *type, const JSValue v); - virtual Property *defineVariable(Context *cx, const String &name, NamespaceList *names, PropertyAttribute attrFlags, JSType *type, const JSValue v); - virtual Property *defineAlias(Context *cx, const String &name, NamespaceList *names, PropertyAttribute attrFlags, JSType *type, JSValue *vp); + virtual Property *defineVariable(Context *cx, const String &name, AttributeStmtNode *attr, JSType *type, const js2val v); + virtual Property *defineVariable(Context *cx, const String &name, NamespaceList *names, PropertyAttribute attrFlags, JSType *type, const js2val v); + virtual Property *defineAlias(Context *cx, const String &name, NamespaceList *names, PropertyAttribute attrFlags, JSType *type, js2val vp); virtual Reference *genReference(Context *cx, bool hasBase, const String& name, NamespaceList *names, Access acc, uint32 depth); @@ -634,8 +668,8 @@ XXX ...couldn't get this to work... virtual void defineTempVariable(Context *cx, Reference *&readRef, Reference *&writeRef, JSType *type); - virtual JSValue getSlotValue(Context * /*cx*/, uint32 /*slotIndex*/) { ASSERT(false); return kUndefinedValue; } - virtual void setSlotValue(Context * /*cx*/, uint32 /*slotIndex*/, JSValue & /*v*/) { ASSERT(false); } + virtual js2val getSlotValue(Context * /*cx*/, uint32 /*slotIndex*/) { ASSERT(false); return kUndefinedValue; } + virtual void setSlotValue(Context * /*cx*/, uint32 /*slotIndex*/, js2val /*v*/) { ASSERT(false); } // debug only void printProperties(Formatter &f) const @@ -701,14 +735,14 @@ XXX ...couldn't get this to work... void initInstance(Context *cx, JSType *type); void getProperty(Context *cx, const String &name, NamespaceList *names); - void setProperty(Context *cx, const String &name, NamespaceList *names, const JSValue &v); + void setProperty(Context *cx, const String &name, NamespaceList *names, const js2val v); - JSValue getField(uint32 index) + js2val getField(uint32 index) { return mInstanceValues[index]; } - void setField(uint32 index, JSValue v) + void setField(uint32 index, js2val v) { mInstanceValues[index] = v; } @@ -720,7 +754,7 @@ XXX ...couldn't get this to work... // the class that created this instance JSType *mType; - JSValue *mInstanceValues; + js2val *mInstanceValues; protected: typedef Collector::InstanceOwner JSInstanceOwner; @@ -735,7 +769,7 @@ XXX ...couldn't get this to work... // FIXME: need some kind of array operator new[] (gc) thing. // this will have to use an extra word to keep track of the // element count. - mInstanceValues = (JSValue*) collector->copy(mInstanceValues); + mInstanceValues = (js2val*) collector->copy(mInstanceValues); return sizeof(JSInstance); } @@ -777,7 +811,7 @@ XXX ...couldn't get this to work... JSType() : JSInstance(NULL, NULL), mSuperType(NULL), mVariableCount(0), mIsDynamic(false) { } public: - JSType(Context *cx, const StringAtom *name, JSType *super, JSValue &protoObj, JSValue &typeProto); + JSType(Context *cx, const StringAtom *name, JSType *super, js2val protoObj, js2val typeProto); virtual ~JSType() { } // keeping gcc happy @@ -792,7 +826,7 @@ XXX ...couldn't get this to work... // construct a new (empty) instance of this class - virtual JSValue newInstance(Context *cx); + virtual js2val newInstance(Context *cx); Property *defineVariable(Context *cx, const String& name, AttributeStmtNode *attr, JSType *type); @@ -801,11 +835,11 @@ XXX ...couldn't get this to work... // XXX // XXX why doesn't the virtual function in JSObject get found? // XXX - Property *defineVariable(Context *cx, const String& name, AttributeStmtNode *attr, JSType *type, JSValue v) + Property *defineVariable(Context *cx, const String& name, AttributeStmtNode *attr, JSType *type, js2val v) { return JSObject::defineVariable(cx, name, attr, type, v); } - Property *defineVariable(Context *cx, const String &name, NamespaceList *names, PropertyAttribute attrFlags, JSType *type, const JSValue v) + Property *defineVariable(Context *cx, const String &name, NamespaceList *names, PropertyAttribute attrFlags, JSType *type, const js2val v) { return JSObject::defineVariable(cx, name, names, attrFlags, type, v); } @@ -831,9 +865,9 @@ XXX ...couldn't get this to work... bool derivesFrom(JSType *other); virtual void getProperty(Context *cx, const String &name, NamespaceList *names); - virtual void setProperty(Context *cx, const String &name, NamespaceList *names, const JSValue &v); + virtual void setProperty(Context *cx, const String &name, NamespaceList *names, const js2val v); - virtual JSValue getPropertyValue(PropertyIterator &i); + virtual js2val getPropertyValue(PropertyIterator &i); virtual bool hasProperty(Context *cx, const String &name, NamespaceList *names, Access acc, PropertyIterator *p); @@ -842,7 +876,7 @@ XXX ...couldn't get this to work... JSFunction *getDefaultConstructor() { return mDefaultConstructor; } JSFunction *getTypeCastFunction() { return mTypeCast; } - JSValue getUninitializedValue() { return mUninitializedValue; } + js2val getUninitializedValue() { return mUninitializedValue; } // Generates defaultConstructor if one doesn't exist - // assumes that the super types have been completed already @@ -864,9 +898,9 @@ XXX ...couldn't get this to work... const StringAtom *mPrivateNamespace; bool mIsDynamic; - JSValue mUninitializedValue; // the value for uninitialized vars + js2val mUninitializedValue; // the value for uninitialized vars - JSValue mPrototypeObject; // becomes the prototype for any instance + js2val mPrototypeObject; // becomes the prototype for any instance // DEBUG void printSlotsNStuff(Formatter& f) const; @@ -929,7 +963,7 @@ XXX ...couldn't get this to work... void* operator new(size_t s) { void *t = STD::malloc(s); trace_alloc("JSArrayInstance", s, t); return t; } void operator delete(void* t) { trace_release("JSArrayInstance", t); STD::free(t); } #endif - void setProperty(Context *cx, const String &name, NamespaceList *names, const JSValue &v); + void setProperty(Context *cx, const String &name, NamespaceList *names, const js2val v); void getProperty(Context *cx, const String &name, NamespaceList *names); bool hasOwnProperty(Context *cx, const String &name, NamespaceList *names, Access acc, PropertyIterator *p); @@ -940,7 +974,7 @@ XXX ...couldn't get this to work... class JSArrayType : public JSType { public: - JSArrayType(Context *cx, JSType *elementType, const StringAtom *name, JSType *super, JSValue &protoObj, JSValue &typeProto) + JSArrayType(Context *cx, JSType *elementType, const StringAtom *name, JSType *super, js2val protoObj, js2val typeProto) : JSType(cx, name, super, protoObj, typeProto), mElementType(elementType) { } @@ -951,7 +985,7 @@ XXX ...couldn't get this to work... void operator delete(void* t) { trace_release("JSArrayType", t); STD::free(t); } #endif - JSValue newInstance(Context *cx); + js2val newInstance(Context *cx); JSType *mElementType; }; @@ -963,7 +997,7 @@ XXX ...couldn't get this to work... void* operator new(size_t s) { void *t = STD::malloc(s); trace_alloc("JSStringInstance", s, t); return t; } void operator delete(void* t) { trace_release("JSStringInstance", t); STD::free(t); } #endif - void setProperty(Context *cx, const String &name, NamespaceList *names, const JSValue &v); + void setProperty(Context *cx, const String &name, NamespaceList *names, const js2val v); void getProperty(Context *cx, const String &name, NamespaceList *names); bool hasOwnProperty(Context *cx, const String &name, NamespaceList *names, Access acc, PropertyIterator *p); bool deleteProperty(Context *cx, const String &name, NamespaceList *names); @@ -973,7 +1007,7 @@ XXX ...couldn't get this to work... class JSStringType : public JSType { public: - JSStringType(Context *cx, const StringAtom *name, JSType *super, JSValue &protoObj, JSValue &typeProto) + JSStringType(Context *cx, const StringAtom *name, JSType *super, js2val protoObj, js2val typeProto) : JSType(cx, name, super, protoObj, typeProto) { } @@ -982,7 +1016,7 @@ XXX ...couldn't get this to work... void* operator new(size_t s) { void *t = STD::malloc(s); trace_alloc("JSStringType", s, t); return t; } void operator delete(void* t) { trace_release("JSStringType", t); STD::free(t); } #endif - JSValue newInstance(Context *cx); + js2val newInstance(Context *cx); }; class JSBooleanInstance : public JSInstance { @@ -998,7 +1032,7 @@ XXX ...couldn't get this to work... class JSBooleanType : public JSType { public: - JSBooleanType(Context *cx, const StringAtom *name, JSType *super, JSValue &protoObj, JSValue &typeProto) + JSBooleanType(Context *cx, const StringAtom *name, JSType *super, js2val protoObj, js2val typeProto) : JSType(cx, name, super, protoObj, typeProto) { } @@ -1007,7 +1041,7 @@ XXX ...couldn't get this to work... void* operator new(size_t s) { void *t = STD::malloc(s); trace_alloc("JSBooleanType", s, t); return t; } void operator delete(void* t) { trace_release("JSBooleanType", t); STD::free(t); } #endif - JSValue newInstance(Context *cx); + js2val newInstance(Context *cx); }; class JSNumberInstance : public JSInstance { @@ -1023,7 +1057,7 @@ XXX ...couldn't get this to work... class JSNumberType : public JSType { public: - JSNumberType(Context *cx, const StringAtom *name, JSType *super, JSValue &protoObj, JSValue &typeProto) + JSNumberType(Context *cx, const StringAtom *name, JSType *super, js2val protoObj, js2val typeProto) : JSType(cx, name, super, protoObj, typeProto) { } @@ -1032,7 +1066,7 @@ XXX ...couldn't get this to work... void* operator new(size_t s) { void *t = STD::malloc(s); trace_alloc("JSNumberType", s, t); return t; } void operator delete(void* t) { trace_release("JSNumberType", t); STD::free(t); } #endif - JSValue newInstance(Context *cx); + js2val newInstance(Context *cx); }; class JSDateInstance : public JSInstance { @@ -1048,7 +1082,7 @@ XXX ...couldn't get this to work... class JSDateType : public JSType { public: - JSDateType(Context *cx, const StringAtom *name, JSType *super, JSValue &protoObj, JSValue &typeProto) + JSDateType(Context *cx, const StringAtom *name, JSType *super, js2val protoObj, js2val typeProto) : JSType(cx, name, super, protoObj, typeProto) { } @@ -1057,7 +1091,7 @@ XXX ...couldn't get this to work... void* operator new(size_t s) { void *t = STD::malloc(s); trace_alloc("JSDateType", s, t); return t; } void operator delete(void* t) { trace_release("JSDateType", t); STD::free(t); } #endif - JSValue newInstance(Context *cx); + js2val newInstance(Context *cx); }; class JSRegExpInstance : public JSInstance { @@ -1074,7 +1108,7 @@ XXX ...couldn't get this to work... class JSRegExpType : public JSType { public: - JSRegExpType(Context *cx, const StringAtom *name, JSType *super, JSValue &protoObj, JSValue &typeProto) + JSRegExpType(Context *cx, const StringAtom *name, JSType *super, js2val protoObj, js2val typeProto) : JSType(cx, name, super, protoObj, typeProto) { } @@ -1083,12 +1117,12 @@ XXX ...couldn't get this to work... void* operator new(size_t s) { void *t = STD::malloc(s); trace_alloc("JSBooleanType", s, t); return t; } void operator delete(void* t) { trace_release("JSBooleanType", t); STD::free(t); } #endif - JSValue newInstance(Context *cx); + js2val newInstance(Context *cx); }; class JSObjectType : public JSType { public: - JSObjectType(Context *cx, const StringAtom *name, JSType *super, JSValue &protoObj, JSValue &typeProto) + JSObjectType(Context *cx, const StringAtom *name, JSType *super, js2val protoObj, js2val typeProto) : JSType(cx, name, super, protoObj, typeProto) { } @@ -1097,7 +1131,7 @@ XXX ...couldn't get this to work... void* operator new(size_t s) { void *t = STD::malloc(s); trace_alloc("JSObjectType", s, t); return t; } void operator delete(void* t) { trace_release("JSObjectType", t); STD::free(t); } #endif - JSValue newInstance(Context *cx); + js2val newInstance(Context *cx); }; @@ -1120,8 +1154,8 @@ XXX ...couldn't get this to work... Property *defineVariable(Context *cx, const String& name, AttributeStmtNode *attr, JSType *type); Reference *genReference(Context *cx, bool hasBase, const String& name, NamespaceList *names, Access acc, uint32 depth); - JSValue getSlotValue(Context *cx, uint32 slotIndex); - void setSlotValue(Context *cx, uint32 slotIndex, JSValue &v); + js2val getSlotValue(Context *cx, uint32 slotIndex); + void setSlotValue(Context *cx, uint32 slotIndex, js2val v); }; @@ -1152,10 +1186,10 @@ XXX ...couldn't get this to work... mNamespaceList(NULL) {} - Activation(JSValue *locals, - JSValue *stack, uint32 stackTop, + Activation(js2val *locals, + js2val *stack, uint32 stackTop, ScopeChain *scopeChain, - JSValue *argBase, JSValue curThis, + js2val *argBase, js2val curThis, uint8 *pc, ByteCodeModule *module, NamespaceList *namespaceList ) @@ -1189,12 +1223,12 @@ XXX ...couldn't get this to work... // saved values from a previous execution - JSValue *mLocals; - JSValue *mStack; + js2val *mLocals; + js2val *mStack; uint32 mStackTop; ScopeChain *mScopeChain; - JSValue *mArgumentBase; - JSValue mThis; + js2val *mArgumentBase; + js2val mThis; uint8 *mPC; ByteCodeModule *mModule; JSFunction *mContainer; @@ -1210,8 +1244,8 @@ XXX ...couldn't get this to work... Reference *genReference(Context *cx, bool hasBase, const String& name, NamespaceList *names, Access acc, uint32 depth); - JSValue getSlotValue(Context *cx, uint32 slotIndex); - void setSlotValue(Context *cx, uint32 slotIndex, JSValue &v); + js2val getSlotValue(Context *cx, uint32 slotIndex); + void setSlotValue(Context *cx, uint32 slotIndex, js2val v); }; @@ -1252,12 +1286,12 @@ XXX ...couldn't get this to work... JSObject *top = mScopeStack.back(); return top->defineVariable(cx, name, attr, type); } - Property *defineVariable(Context *cx, const String& name, AttributeStmtNode *attr, JSType *type, JSValue v) + Property *defineVariable(Context *cx, const String& name, AttributeStmtNode *attr, JSType *type, js2val v) { JSObject *top = mScopeStack.back(); return top->defineVariable(cx, name, attr, type, v); } - Property *defineAlias(Context *cx, const String &name, NamespaceList *names, PropertyAttribute attrFlags, JSType *type, JSValue *vp) + Property *defineAlias(Context *cx, const String &name, NamespaceList *names, PropertyAttribute attrFlags, JSType *type, js2val vp) { JSObject *top = mScopeStack.back(); return top->defineAlias(cx, name, names, attrFlags, type, vp); @@ -1365,7 +1399,7 @@ XXX ...couldn't get this to work... // a compile time request to get the value for a name // (i.e. we're accessing a constant value) - JSValue getCompileTimeValue(Context *cx, const String& name, NamespaceList *names); + js2val getCompileTimeValue(Context *cx, const String& name, NamespaceList *names); @@ -1433,12 +1467,13 @@ XXX ...couldn't get this to work... }; - typedef JSValue (NativeCode)(Context *cx, const JSValue &thisValue, JSValue argv[], uint32 argc); + typedef js2val (NativeCode)(Context *cx, const js2val thisValue, js2val argv[], uint32 argc); + typedef js2val (NativeDispatch)(NativeCode *target, Context *cx, const js2val thisValue, js2val argv[], uint32 argc); // XXX these should be Function_Type->newInstance() calls, no? JSFunction(Context *cx, JSType *resultType, ScopeChain *scopeChain); - JSFunction(Context *cx, NativeCode *code, JSType *resultType); + JSFunction(Context *cx, NativeCode *code, JSType *resultType, NativeDispatch *dispatch = NULL); ~JSFunction() { } // keeping gcc happy @@ -1463,18 +1498,19 @@ XXX ...couldn't get this to work... void setClass(JSType *c) { mClass = c; } virtual bool hasBoundThis() { return false; } - virtual bool isNative() { return (mCode != NULL); } + virtual bool isNative() { return (mNativeCode != NULL); } virtual bool isPrototype() { return mIsPrototype; } virtual bool isConstructor() { return mIsConstructor; } virtual bool isMethod() { return (mClass != NULL); } virtual ByteCodeModule *getByteCode() { ASSERT(!isNative()); return mByteCode; } - virtual NativeCode *getNativeCode() { ASSERT(isNative()); return mCode; } +// virtual NativeCode *getNativeCode() { ASSERT(isNative()); return mCode; } + virtual js2val invokeNativeCode(Context *cx, const js2val thisValue, js2val argv[], uint32 argc); virtual ParameterBarrel *getParameterBarrel() { return mParameterBarrel; } virtual Activation *getActivation() { return &mActivation; } virtual ScopeChain *getScopeChain() { return mScopeChain; } - virtual JSValue getThisValue() { return kNullValue; } + virtual js2val getThisValue() { return kNullValue; } virtual JSType *getClass() { return mClass; } virtual FunctionName *getFunctionName() { return mFunctionName; } @@ -1485,7 +1521,7 @@ XXX ...couldn't get this to work... { ASSERT(mParameters && (a < maxParameterIndex())); return mParameters[a].mType; } virtual bool parameterHasInitializer(uint32 a) { ASSERT(mParameters && (a < maxParameterIndex())); return (mParameters[a].mInitializer != (uint32)(-1)); } - virtual JSValue runParameterInitializer(Context *cx, uint32 a, const JSValue& thisValue, JSValue *argv, uint32 argc); + virtual js2val runParameterInitializer(Context *cx, uint32 a, const js2val thisValue, js2val *argv, uint32 argc); virtual uint32 getRequiredParameterCount() { return mRequiredParameters; } @@ -1516,7 +1552,7 @@ XXX ...couldn't get this to work... private: ByteCodeModule *mByteCode; - NativeCode *mCode; + NativeCode *mNativeCode; JSType *mResultType; uint32 mRequiredParameters; uint32 mOptionalParameters; @@ -1529,6 +1565,7 @@ XXX ...couldn't get this to work... bool mHasRestParameter; JSType *mClass; // pointer to owning class if this function is a method FunctionName *mFunctionName; + NativeDispatch *mDispatch; protected: typedef Collector::InstanceOwner JSFunctionOwner; @@ -1560,6 +1597,8 @@ XXX ...couldn't get this to work... #endif }; + + class JSBoundFunction : public JSFunction { private: JSFunction *mFunction; @@ -1576,17 +1615,18 @@ XXX ...couldn't get this to work... bool isConstructor() { return mFunction->isConstructor(); } bool isMethod() { return mFunction->isMethod(); } ByteCodeModule *getByteCode() { return mFunction->getByteCode(); } - NativeCode *getNativeCode() { return mFunction->getNativeCode(); } + js2val invokeNativeCode(Context *cx, const js2val thisValue, js2val argv[], uint32 argc) + { return mFunction->invokeNativeCode(cx, thisValue, argv, argc); } ParameterBarrel *getParameterBarrel() { return mFunction->mParameterBarrel; } Activation *getActivation() { return &mFunction->mActivation; } JSType *getResultType() { return mFunction->getResultType(); } JSType *getParameterType(uint32 a) { return mFunction->getParameterType(a); } bool parameterHasInitializer(uint32 a){ return mFunction->parameterHasInitializer(a); } - JSValue runParameterInitializer(Context *cx, uint32 a, const JSValue& thisValue, JSValue *argv, uint32 argc) + js2val runParameterInitializer(Context *cx, uint32 a, const js2val thisValue, js2val *argv, uint32 argc) { return mFunction->runParameterInitializer(cx, a, thisValue, argv, argc); } ScopeChain *getScopeChain() { return mFunction->getScopeChain(); } - JSValue getThisValue() { return (mThis) ? JSValue(mThis) : kNullValue; } + js2val getThisValue() { return (mThis) ? JSValue::newObject(mThis) : kNullValue; } JSType *getClass() { return mFunction->getClass(); } FunctionName *getFunctionName() { return mFunction->getFunctionName(); } @@ -1610,7 +1650,7 @@ XXX ...couldn't get this to work... void getProperty(Context *cx, const String &name, NamespaceList *names) { mFunction->getProperty(cx, name, names); } - void setProperty(Context *cx, const String &name, NamespaceList *names, const JSValue &v) + void setProperty(Context *cx, const String &name, NamespaceList *names, const js2val v) { mFunction->setProperty(cx, name, names, v); } bool hasProperty(Context *cx, const String &name, NamespaceList *names, Access acc, PropertyIterator *p) { return mFunction->hasProperty(cx, name, names, acc, p); } @@ -1687,19 +1727,19 @@ XXX ...couldn't get this to work... // provide access to the Error object constructors so that runtime exceptions // can be constructed for Javascript catches. - extern JSValue Error_Constructor(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc); - extern JSValue EvalError_Constructor(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc); - extern JSValue RangeError_Constructor(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc); - extern JSValue ReferenceError_Constructor(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc); - extern JSValue SyntaxError_Constructor(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc); - extern JSValue TypeError_Constructor(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc); - extern JSValue UriError_Constructor(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc); + extern js2val Error_Constructor(Context *cx, const js2val thisValue, js2val *argv, uint32 argc); + extern js2val EvalError_Constructor(Context *cx, const js2val thisValue, js2val *argv, uint32 argc); + extern js2val RangeError_Constructor(Context *cx, const js2val thisValue, js2val *argv, uint32 argc); + extern js2val ReferenceError_Constructor(Context *cx, const js2val thisValue, js2val *argv, uint32 argc); + extern js2val SyntaxError_Constructor(Context *cx, const js2val thisValue, js2val *argv, uint32 argc); + extern js2val TypeError_Constructor(Context *cx, const js2val thisValue, js2val *argv, uint32 argc); + extern js2val UriError_Constructor(Context *cx, const js2val thisValue, js2val *argv, uint32 argc); // called by bytecodegen for RegExp literals - extern JSValue RegExp_Constructor(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc); + extern js2val RegExp_Constructor(Context *cx, const js2val thisValue, js2val *argv, uint32 argc); // called directly by String.match - extern JSValue RegExp_exec(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc); + extern js2val RegExp_exec(Context *cx, const js2val thisValue, js2val *argv, uint32 argc); class Package : public JSObject { @@ -1750,7 +1790,7 @@ XXX ...couldn't get this to work... struct ClassDef { char *name; JSFunction::NativeCode *defCon; - const JSValue *uninit; + const js2val *uninit; }; Context(JSObject **global, World &world, Arena &a, Pragma::Flags flags); @@ -1840,7 +1880,7 @@ XXX ...couldn't get this to work... // Construct an array of argument values, updating argCount to // reflect the final size. Pulls incoming args from the top of // the stack. - JSValue *buildArgumentBlock(JSFunction *target, uint32 &argCount); + js2val *buildArgumentBlock(JSFunction *target, uint32 &argCount); // compiles attribute expression into an attribute object @@ -1851,10 +1891,10 @@ XXX ...couldn't get this to work... // Run the binary operator designated, after using the types to do the dispatch bool executeOperator(Operator op, JSType *t1, JSType *t2); - JSValue mapValueToType(JSValue v, JSType *t); + js2val mapValueToType(js2val v, JSType *t); // Run the interpreter loop on the function - JSValue invokeFunction(JSFunction *target, const JSValue& thisValue, JSValue *argv, uint32 argc); + js2val invokeFunction(JSFunction *target, const js2val thisValue, js2val *argv, uint32 argc); // This reader is used to generate source information // to go with exception messages. @@ -1873,28 +1913,28 @@ XXX ...couldn't get this to work... uint8 *mPC; - JSValue mThis; + js2val mThis; // this is the execution stack (for the current function) - JSValue *mStack; + js2val *mStack; uint32 mStackTop; uint32 mStackMax; NamespaceList *mNamespaceList; - void pushValue(const JSValue &v) + void pushValue(const js2val v) { ASSERT(mStackTop < mStackMax); mStack[mStackTop++] = v; } - JSValue popValue() + js2val popValue() { ASSERT(mStackTop > 0); return mStack[--mStackTop]; } - JSValue topValue() + js2val topValue() { return mStack[mStackTop - 1]; } @@ -1910,14 +1950,14 @@ XXX ...couldn't get this to work... return mStackTop; } - JSValue getValue(uint32 n) + js2val getValue(uint32 n) { ASSERT(n < mStackTop); return mStack[n]; } // put the value in at 'index', lifting everything above that up by one - void insertValue(JSValue v, uint32 index) + void insertValue(js2val v, uint32 index) { ASSERT(mStackTop < mStackMax); // we're effectively pushing one entry for (uint32 i = mStackTop - 1; i >= index; i--) @@ -1926,7 +1966,7 @@ XXX ...couldn't get this to work... mStackTop++; } - JSValue *getBase(uint32 n) + js2val *getBase(uint32 n) { ASSERT(n <= mStackTop); // s'ok to point beyond the end return &mStack[n]; @@ -1951,10 +1991,10 @@ XXX ...couldn't get this to work... std::stack mSubStack; // the locals for the current function (an array, constructed on function entry) - JSValue *mLocals; + js2val *mLocals; // the base of the incoming arguments for this function - JSValue *mArgumentBase; + js2val *mArgumentBase; typedef std::vector OperatorList; @@ -1967,16 +2007,16 @@ XXX ...couldn't get this to work... bool checkForPackage(const String &packageName); // return true if loaded, throw exception if loading void loadPackage(const String &packageName, const String &filename); // load package from file - JSValue readEvalFile(const String& fileName); - JSValue readEvalString(const String &str, const String& fileName, ScopeChain *scopeChain, const JSValue& thisValue); + js2val readEvalFile(const String& fileName); + js2val readEvalString(const String &str, const String& fileName, ScopeChain *scopeChain, const js2val thisValue); void buildRuntime(StmtNode *p); void buildRuntimeForFunction(FunctionDefinition &f, JSFunction *fnc); void buildRuntimeForStmt(StmtNode *p); ByteCodeModule *genCode(StmtNode *p, const String &sourceName); - JSValue interpret(ByteCodeModule *bcm, int offset, ScopeChain *scopeChain, const JSValue& thisValue, JSValue *argv, uint32 argc); - JSValue interpret(uint8 *pc, uint8 *endPC); + js2val interpret(ByteCodeModule *bcm, int offset, ScopeChain *scopeChain, const js2val thisValue, js2val *argv, uint32 argc); + js2val interpret(uint8 *pc, uint8 *endPC); void reportError(Exception::Kind kind, char *message, size_t pos, const char *arg = NULL); void reportError(Exception::Kind kind, char *message, const char *arg = NULL); @@ -2033,22 +2073,22 @@ XXX ...couldn't get this to work... m_cx->mStackMax = mOldStackMax; } - JSValue mStack[ReplacementStackSize]; + js2val mStack[ReplacementStackSize]; Context *m_cx; - JSValue *mOldStack; + js2val *mOldStack; uint32 mOldStackTop; uint32 mOldStackMax; }; - class NamedArgument { + class NamedArgument : public JSObject { public: - NamedArgument(JSValue &v, const String *n) : mValue(v), mName(n) { } + NamedArgument(js2val v, const String *n) : mValue(v), mName(n) { } - JSValue mValue; + js2val mValue; const String *mName; protected: @@ -2057,18 +2097,19 @@ XXX ...couldn't get this to work... /** * Scans through the object, and copies all references. */ +#ifdef NOT_SCARED_OF_GC_CODE Collector::size_type scan(Collector* collector) { mValue.scan(collector); return sizeof(NamedArgument); } - public: void* operator new(size_t n, Collector& gc) { static NamedArgumentOwner owner; return gc.allocateObject(n, &owner); } +#endif #ifdef DEBUG public: @@ -2078,7 +2119,7 @@ XXX ...couldn't get this to work... }; - class Attribute { + class Attribute : public JSObject { public: Attribute(PropertyAttribute t, PropertyAttribute f) : mTrueFlags(t), mFalseFlags(f), mExtendArgument(NULL), mNamespaceList(NULL) { } @@ -2119,7 +2160,12 @@ XXX ...couldn't get this to work... - + inline bool JSValue::isInstance(const js2val v) { return JS2VAL_IS_OBJECT(v) && dynamic_cast(JS2VAL_TO_OBJECT(v)); } + inline bool JSValue::isType(const js2val v) { return JS2VAL_IS_OBJECT(v) && dynamic_cast(JS2VAL_TO_OBJECT(v)); } + inline bool JSValue::isFunction(const js2val v) { return JS2VAL_IS_OBJECT(v) && dynamic_cast(JS2VAL_TO_OBJECT(v)); } + inline bool JSValue::isNamedArg(const js2val v) { return JS2VAL_IS_OBJECT(v) && dynamic_cast(JS2VAL_TO_OBJECT(v)); } + inline bool JSValue::isAttribute(const js2val v) { return JS2VAL_IS_OBJECT(v) && dynamic_cast(JS2VAL_TO_OBJECT(v)); } + inline bool JSValue::isPackage(const js2val v) { return JS2VAL_IS_OBJECT(v) && dynamic_cast(JS2VAL_TO_OBJECT(v)); } diff --git a/mozilla/js2/src/jsarray.cpp b/mozilla/js2/src/jsarray.cpp index aa05549f6d8..0b7c0ed38da 100644 --- a/mozilla/js2/src/jsarray.cpp +++ b/mozilla/js2/src/jsarray.cpp @@ -52,18 +52,18 @@ namespace JavaScript { namespace JS2Runtime { -JSValue Array_Constructor(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +js2val Array_Constructor(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { - JSValue thatValue = thisValue; - if (thatValue.isNull()) + js2val thatValue = thisValue; + if (JSValue::isNull(thatValue)) thatValue = Array_Type->newInstance(cx); - ASSERT(thatValue.isInstance()); - JSArrayInstance *arrInst = checked_cast(thatValue.instance); + ASSERT(JSValue::isInstance(thatValue)); + JSArrayInstance *arrInst = checked_cast(JSValue::instance(thatValue)); if (argc > 0) { if (argc == 1) { - if (argv[0].isNumber()) { - uint32 i = (uint32)(argv[0].f64); - if (i == argv[0].f64) + if (JSValue::isNumber(argv[0])) { + uint32 i = (uint32)(JSValue::f64(argv[0])); + if (i == JSValue::f64(argv[0])) arrInst->mLength = i; else cx->reportError(Exception::rangeError, "Array length too large"); @@ -86,73 +86,73 @@ JSValue Array_Constructor(Context *cx, const JSValue& thisValue, JSValue *argv, } -static JSValue Array_toString(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Array_toString(Context *cx, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/) { - if (thisValue.getType() != Array_Type) + if (JSValue::getType(thisValue) != Array_Type) cx->reportError(Exception::typeError, "Array.prototype.toString called on a non Array"); - ASSERT(thisValue.isInstance()); - JSArrayInstance *arrInst = checked_cast(thisValue.instance); + ASSERT(JSValue::isInstance(thisValue)); + JSArrayInstance *arrInst = checked_cast(JSValue::instance(thisValue)); ContextStackReplacement csr(cx); if (arrInst->mLength == 0) - return JSValue(&cx->Empty_StringAtom); + return JSValue::newString(&cx->Empty_StringAtom); else { String *s = new String(); for (uint32 i = 0; i < arrInst->mLength; i++) { const String *id = numberToString(i); arrInst->getProperty(cx, *id, NULL); - JSValue result = cx->popValue(); - if (!result.isUndefined() && !result.isNull()) - s->append(*result.toString(cx).string); + js2val result = cx->popValue(); + if (!JSValue::isUndefined(result) && !JSValue::isNull(result)) + s->append(*JSValue::string(JSValue::toString(cx, result))); if (i < (arrInst->mLength - 1)) s->append(widenCString(",")); delete id; } - return JSValue(s); + return JSValue::newString(s); } } -static JSValue Array_toSource(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Array_toSource(Context *cx, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/) { - if (thisValue.getType() != Array_Type) + if (JSValue::getType(thisValue) != Array_Type) cx->reportError(Exception::typeError, "Array.prototype.toSource called on a non Array"); - ASSERT(thisValue.isInstance()); - JSArrayInstance *arrInst = checked_cast(thisValue.instance); + ASSERT(JSValue::isInstance(thisValue)); + JSArrayInstance *arrInst = checked_cast(JSValue::instance(thisValue)); ContextStackReplacement csr(cx); if (arrInst->mLength == 0) - return JSValue(new String(widenCString("[]"))); + return JSValue::newString(new String(widenCString("[]"))); else { String *s = new String(widenCString("[")); for (uint32 i = 0; i < arrInst->mLength; i++) { const String *id = numberToString(i); arrInst->getProperty(cx, *id, NULL); - JSValue result = cx->popValue(); - if (!result.isUndefined()) - s->append(*result.toString(cx).string); + js2val result = cx->popValue(); + if (!JSValue::isUndefined(result)) + s->append(*JSValue::string(JSValue::toString(cx, result))); if (i < (arrInst->mLength - 1)) s->append(widenCString(", ")); delete id; } s->append(widenCString("]")); - return JSValue(s); + return JSValue::newString(s); } } -static JSValue Array_push(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val Array_push(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { ContextStackReplacement csr(cx); - JSObject *thisObj = thisValue.getObjectValue(); + JSObject *thisObj = JSValue::getObjectValue(thisValue); thisObj->getProperty(cx, cx->Length_StringAtom, CURRENT_ATTR); - JSValue result = cx->popValue(); - uint32 length = (uint32)(result.toUInt32(cx).f64); + js2val result = cx->popValue(); + uint32 length = (uint32)JSValue::f64(JSValue::toUInt32(cx, result)); for (uint32 i = 0; i < argc; i++) { const String *id = numberToString(i + length); @@ -160,27 +160,27 @@ static JSValue Array_push(Context *cx, const JSValue& thisValue, JSValue *argv, delete id; } length += argc; - result = JSValue((float64)length); + result = JSValue::newNumber((float64)length); thisObj->setProperty(cx, cx->Length_StringAtom, CURRENT_ATTR, result); return result; } -static JSValue Array_pop(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Array_pop(Context *cx, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/) { ContextStackReplacement csr(cx); - JSObject *thisObj = thisValue.getObjectValue(); + JSObject *thisObj = JSValue::getObjectValue(thisValue); thisObj->getProperty(cx, cx->Length_StringAtom, CURRENT_ATTR); - JSValue result = cx->popValue(); - uint32 length = (uint32)(result.toUInt32(cx).f64); + js2val result = cx->popValue(); + uint32 length = (uint32)JSValue::f64(JSValue::toUInt32(cx, result)); if (length > 0) { const String *id = numberToString(length - 1); thisObj->getProperty(cx, *id, NULL); - JSValue result = cx->popValue(); + js2val result = cx->popValue(); thisObj->deleteProperty(cx, *id, NULL); --length; - thisObj->setProperty(cx, cx->Length_StringAtom, CURRENT_ATTR, JSValue((float64)length)); + thisObj->setProperty(cx, cx->Length_StringAtom, CURRENT_ATTR, JSValue::newNumber((float64)length)); delete id; return result; } @@ -188,34 +188,34 @@ static JSValue Array_pop(Context *cx, const JSValue& thisValue, JSValue * /*argv return kUndefinedValue; } -JSValue Array_concat(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +js2val Array_concat(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { - JSValue E = thisValue; + js2val E = thisValue; - JSValue result = Array_Type->newInstance(cx); - JSArrayInstance *A = checked_cast(result.instance); + js2val result = Array_Type->newInstance(cx); + JSArrayInstance *A = checked_cast(JSValue::instance(result)); uint32 n = 0; uint32 i = 0; ContextStackReplacement csr(cx); do { - if (E.getType() != Array_Type) { + if (JSValue::getType(E) != Array_Type) { const String *id = numberToString(n++); A->setProperty(cx, *id, CURRENT_ATTR, E); delete id; } else { - JSObject *arrObj = E.getObjectValue(); + JSObject *arrObj = JSValue::getObjectValue(E); arrObj->getProperty(cx, cx->Length_StringAtom, CURRENT_ATTR); - JSValue result = cx->popValue(); - uint32 length = (uint32)(result.toUInt32(cx).f64); + js2val result = cx->popValue(); + uint32 length = (uint32)JSValue::f64(JSValue::toUInt32(cx, result)); for (uint32 k = 0; k < length; k++) { const String *id = numberToString(k); arrObj->getProperty(cx, *id, NULL); delete id; id = numberToString(n++); - JSValue result = cx->popValue(); + js2val result = cx->popValue(); A->setProperty(cx, *id, CURRENT_ATTR, result); delete id; } @@ -226,15 +226,15 @@ JSValue Array_concat(Context *cx, const JSValue& thisValue, JSValue *argv, uint3 return result; } -static JSValue Array_join(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val Array_join(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { ContextStackReplacement csr(cx); - JSObject *thisObj = thisValue.getObjectValue(); + JSObject *thisObj = JSValue::getObjectValue(thisValue); thisObj->getProperty(cx, cx->Length_StringAtom, CURRENT_ATTR); - JSValue result = cx->popValue(); - uint32 length = (uint32)(result.toUInt32(cx).f64); + js2val result = cx->popValue(); + uint32 length = (uint32)JSValue::f64(JSValue::toUInt32(cx, result)); /* XXX ECMA says that if separator is undefined we use ',', but SpiderMonkey and the test suite want 'undefined' in that case, and only use the ',' when the @@ -245,7 +245,7 @@ static JSValue Array_join(Context *cx, const JSValue& thisValue, JSValue *argv, if (argc == 0) separator = new String(widenCString(",")); else - separator = argv[0].toString(cx).string; + separator = JSValue::string(JSValue::toString(cx, argv[0])); const String *id = numberToString(0); thisObj->getProperty(cx, *id, CURRENT_ATTR); @@ -258,26 +258,26 @@ static JSValue Array_join(Context *cx, const JSValue& thisValue, JSValue *argv, id = numberToString(k); thisObj->getProperty(cx, *id, CURRENT_ATTR); result = cx->popValue(); - if (!result.isUndefined() && !result.isNull()) - *S += *result.toString(cx).string; + if (!JSValue::isUndefined(result) && !JSValue::isNull(result)) + *S += *JSValue::string(JSValue::toString(cx, result)); if (k < (length - 1)) *S += *separator; delete id; } - return JSValue(S); + return JSValue::newString(S); } -static JSValue Array_reverse(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Array_reverse(Context *cx, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/) { ContextStackReplacement csr(cx); - JSObject *thisObj = thisValue.getObjectValue(); + JSObject *thisObj = JSValue::getObjectValue(thisValue); thisObj->getProperty(cx, cx->Length_StringAtom, CURRENT_ATTR); - JSValue result = cx->popValue(); - uint32 length = (uint32)(result.toUInt32(cx).f64); + js2val result = cx->popValue(); + uint32 length = (uint32)JSValue::f64(JSValue::toUInt32(cx, result)); uint32 halfway = length / 2; @@ -317,15 +317,15 @@ static JSValue Array_reverse(Context *cx, const JSValue& thisValue, JSValue * /* return thisValue; } -static JSValue Array_shift(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Array_shift(Context *cx, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/) { ContextStackReplacement csr(cx); - JSObject *thisObj = thisValue.getObjectValue(); + JSObject *thisObj = JSValue::getObjectValue(thisValue); thisObj->getProperty(cx, cx->Length_StringAtom, CURRENT_ATTR); - JSValue result = cx->popValue(); - uint32 length = (uint32)(result.toUInt32(cx).f64); + js2val result = cx->popValue(); + uint32 length = (uint32)JSValue::f64(JSValue::toUInt32(cx, result)); if (length == 0) { thisObj->setProperty(cx, cx->Length_StringAtom, CURRENT_ATTR, result); @@ -355,29 +355,29 @@ static JSValue Array_shift(Context *cx, const JSValue& thisValue, JSValue * /*ar id = numberToString(length - 1); thisObj->deleteProperty(cx, *id, CURRENT_ATTR); delete id; - thisObj->setProperty(cx, cx->Length_StringAtom, CURRENT_ATTR, JSValue((float64)(length - 1)) ); + thisObj->setProperty(cx, cx->Length_StringAtom, CURRENT_ATTR, JSValue::newNumber((float64)(length - 1)) ); return result; } -static JSValue Array_slice(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val Array_slice(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { ContextStackReplacement csr(cx); - JSObject *thisObj = thisValue.getObjectValue(); + JSObject *thisObj = JSValue::getObjectValue(thisValue); - JSValue result = Array_Type->newInstance(cx); - JSArrayInstance *A = checked_cast(result.instance); + js2val result = Array_Type->newInstance(cx); + JSArrayInstance *A = checked_cast(JSValue::instance(result)); thisObj->getProperty(cx, cx->Length_StringAtom, CURRENT_ATTR); - JSValue lengthValue = cx->popValue(); - uint32 length = (uint32)(lengthValue.toUInt32(cx).f64); + js2val lengthValue = cx->popValue(); + uint32 length = (uint32)JSValue::f64(JSValue::toUInt32(cx, lengthValue)); uint32 start, end; if (argc < 1) start = 0; else { - int32 arg0 = (int32)(argv[0].toInt32(cx).f64); + int32 arg0 = (int32)JSValue::f64(JSValue::toInt32(cx, argv[0])); if (arg0 < 0) { arg0 += length; if (arg0 < 0) @@ -396,7 +396,7 @@ static JSValue Array_slice(Context *cx, const JSValue& thisValue, JSValue *argv, if (argc < 2) end = length; else { - int32 arg1 = (int32)(argv[1].toInt32(cx).f64); + int32 arg1 = (int32)JSValue::f64(JSValue::toInt32(cx, argv[1])); if (arg1 < 0) { arg1 += length; if (arg1 < 0) @@ -425,8 +425,8 @@ static JSValue Array_slice(Context *cx, const JSValue& thisValue, JSValue *argv, start++; delete id1; } - A->setProperty(cx, cx->Length_StringAtom, CURRENT_ATTR, JSValue((float64)n) ); - return JSValue(A); + A->setProperty(cx, cx->Length_StringAtom, CURRENT_ATTR, JSValue::newNumber((float64)n) ); + return JSValue::newInstance(A); } typedef struct CompareArgs { @@ -435,17 +435,17 @@ typedef struct CompareArgs { } CompareArgs; typedef struct QSortArgs { - JSValue *vec; - JSValue *pivot; + js2val *vec; + js2val *pivot; CompareArgs *arg; } QSortArgs; -static int32 sort_compare(JSValue *a, JSValue *b, CompareArgs *arg); +static int32 sort_compare(js2val *a, js2val *b, CompareArgs *arg); static void js_qsort_r(QSortArgs *qa, int lo, int hi) { - JSValue *pivot, *vec, *a, *b; + js2val *pivot, *vec, *a, *b; int i, j, lohi, hilo; CompareArgs *arg; @@ -492,45 +492,45 @@ js_qsort_r(QSortArgs *qa, int lo, int hi) } } -static void js_qsort(JSValue *vec, size_t nel, CompareArgs *arg) +static void js_qsort(js2val *vec, size_t nel, CompareArgs *arg) { - JSValue *pivot; + js2val *pivot; QSortArgs qa; - pivot = new JSValue(); + pivot = (js2val *)STD::malloc(nel); qa.vec = vec; qa.pivot = pivot; qa.arg = arg; js_qsort_r(&qa, 0, (int)(nel - 1)); - delete(pivot); + STD::free(pivot); } -static int32 sort_compare(JSValue *a, JSValue *b, CompareArgs *arg) +static int32 sort_compare(js2val *a, js2val *b, CompareArgs *arg) { - JSValue av = *(const JSValue *)a; - JSValue bv = *(const JSValue *)b; + js2val av = *(const js2val *)a; + js2val bv = *(const js2val *)b; CompareArgs *ca = (CompareArgs *) arg; Context *cx = ca->context; int32 result; if (ca->target == NULL) { - if (av.isUndefined() || bv.isUndefined()) { + if (JSValue::isUndefined(av) || JSValue::isUndefined(bv)) { /* Put undefined properties at the end. */ - result = (av.isUndefined()) ? 1 : -1; + result = (JSValue::isUndefined(av)) ? 1 : -1; } else { - const String *astr = av.toString(cx).string; - const String *bstr = bv.toString(cx).string; + const String *astr = JSValue::string(JSValue::toString(cx, av)); + const String *bstr = JSValue::string(JSValue::toString(cx, bv)); result = astr->compare(*bstr); } return result; } else { - JSValue argv[2]; + js2val argv[2]; argv[0] = av; argv[1] = bv; - JSValue v = cx->invokeFunction(ca->target, kNullValue, argv, 2); - float64 f = v.toNumber(cx).f64; + js2val v = cx->invokeFunction(ca->target, kNullValue, argv, 2); + float64 f = JSValue::f64(JSValue::toNumber(cx, v)); if (JSDOUBLE_IS_NaN(f) || (f == 0)) result = 0; else @@ -543,7 +543,7 @@ static int32 sort_compare(JSValue *a, JSValue *b, CompareArgs *arg) } -static JSValue Array_sort(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val Array_sort(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { ContextStackReplacement csr(cx); @@ -552,21 +552,21 @@ static JSValue Array_sort(Context *cx, const JSValue& thisValue, JSValue *argv, ca.target = NULL; if (argc > 0) { - if (!argv[0].isUndefined()) { - if (!argv[0].isFunction()) + if (!JSValue::isUndefined(argv[0])) { + if (!JSValue::isFunction(argv[0])) cx->reportError(Exception::typeError, "sort needs a compare function"); - ca.target = argv[0].function; + ca.target = JSValue::function(argv[0]); } } - JSObject *thisObj = thisValue.getObjectValue(); + JSObject *thisObj = JSValue::getObjectValue(thisValue); thisObj->getProperty(cx, cx->Length_StringAtom, CURRENT_ATTR); - JSValue result = cx->popValue(); - uint32 length = (uint32)(result.toUInt32(cx).f64); + js2val result = cx->popValue(); + uint32 length = (uint32)JSValue::f64(JSValue::toUInt32(cx, result)); if (length > 0) { uint32 i; - JSValue *vec = new JSValue[length]; + js2val *vec = new js2val[length]; for (i = 0; i < length; i++) { const String *id = numberToString(i); @@ -587,21 +587,21 @@ static JSValue Array_sort(Context *cx, const JSValue& thisValue, JSValue *argv, return thisValue; } -static JSValue Array_splice(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val Array_splice(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { if (argc > 1) { uint32 k; ContextStackReplacement csr(cx); - JSObject *thisObj = thisValue.getObjectValue(); + JSObject *thisObj = JSValue::getObjectValue(thisValue); thisObj->getProperty(cx, cx->Length_StringAtom, CURRENT_ATTR); - JSValue lengthValue = cx->popValue(); - uint32 length = (uint32)(lengthValue.toUInt32(cx).f64); + js2val lengthValue = cx->popValue(); + uint32 length = (uint32)JSValue::f64(JSValue::toUInt32(cx, lengthValue)); - JSValue result = Array_Type->newInstance(cx); - JSArrayInstance *A = checked_cast(result.instance); + js2val result = Array_Type->newInstance(cx); + JSArrayInstance *A = checked_cast(JSValue::instance(result)); - int32 arg0 = (int32)(argv[0].toInt32(cx).f64); + int32 arg0 = (int32)JSValue::f64(JSValue::toInt32(cx, argv[0])); uint32 start; if (arg0 < 0) { arg0 += length; @@ -618,7 +618,7 @@ static JSValue Array_splice(Context *cx, const JSValue& thisValue, JSValue *argv } uint32 deleteCount; - int32 arg1 = (int32)(argv[1].toInt32(cx).f64); + int32 arg1 = (int32)JSValue::f64(JSValue::toInt32(cx, argv[1])); if (arg1 < 0) deleteCount = 0; else @@ -637,7 +637,7 @@ static JSValue Array_splice(Context *cx, const JSValue& thisValue, JSValue *argv } delete id1; } - A->setProperty(cx, cx->Length_StringAtom, CURRENT_ATTR, JSValue((float64)deleteCount) ); + A->setProperty(cx, cx->Length_StringAtom, CURRENT_ATTR, JSValue::newNumber((float64)deleteCount) ); uint32 newItemCount = argc - 2; if (newItemCount < deleteCount) { @@ -682,21 +682,21 @@ static JSValue Array_splice(Context *cx, const JSValue& thisValue, JSValue *argv thisObj->setProperty(cx, *id1, CURRENT_ATTR, argv[i]); delete id1; } - thisObj->setProperty(cx, cx->Length_StringAtom, CURRENT_ATTR, JSValue((float64)(length - deleteCount + newItemCount)) ); + thisObj->setProperty(cx, cx->Length_StringAtom, CURRENT_ATTR, JSValue::newNumber((float64)(length - deleteCount + newItemCount)) ); return result; } return kUndefinedValue; } -static JSValue Array_unshift(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val Array_unshift(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { ContextStackReplacement csr(cx); - JSObject *thisObj = thisValue.getObjectValue(); + JSObject *thisObj = JSValue::getObjectValue(thisValue); thisObj->getProperty(cx, cx->Length_StringAtom, CURRENT_ATTR); - JSValue result = cx->popValue(); - uint32 length = (uint32)(result.toUInt32(cx).f64); + js2val result = cx->popValue(); + uint32 length = (uint32)JSValue::f64(JSValue::toUInt32(cx, result)); uint32 k; for (k = length; k > 0; k--) { @@ -718,7 +718,7 @@ static JSValue Array_unshift(Context *cx, const JSValue& thisValue, JSValue *arg thisObj->setProperty(cx, *id1, CURRENT_ATTR, argv[k]); delete id1; } - thisObj->setProperty(cx, cx->Length_StringAtom, CURRENT_ATTR, JSValue((float64)(length + argc)) ); + thisObj->setProperty(cx, cx->Length_StringAtom, CURRENT_ATTR, JSValue::newNumber((float64)(length + argc)) ); return thisValue; } @@ -730,44 +730,44 @@ static JSValue Array_unshift(Context *cx, const JSValue& thisValue, JSValue *arg // // isArrayIndex() is called when we know that index is a Number // -static bool isArrayIndex(Context *cx, JSValue &index, uint32 &intIndex) +static bool isArrayIndex(Context *cx, js2val index, uint32 &intIndex) { - ASSERT(index.isNumber()); - JSValue v = index.toUInt32(cx); - if ((v.f64 == index.f64) && (v.f64 < two32minus1)) { - intIndex = (uint32)v.f64; + ASSERT(JSValue::isNumber(index)); + js2val v = JSValue::toUInt32(cx, index); + if ((JSValue::f64(v) == JSValue::f64(index)) && (JSValue::f64(v) < two32minus1)) { + intIndex = (uint32)JSValue::f64(v); return true; } return false; } -JSValue Array_GetElement(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +js2val Array_GetElement(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { // the 'this' value is the first argument, then the index if (argc != 2) cx->reportError(Exception::referenceError, "[] only supports single dimension"); - JSArrayInstance *arrInst = checked_cast(thisValue.instance); + JSArrayInstance *arrInst = checked_cast(JSValue::instance(thisValue)); - JSValue index = argv[1]; - const String *name = index.toString(cx).string; + js2val index = argv[1]; + const String *name = JSValue::string(JSValue::toString(cx, index)); arrInst->getProperty(cx, *name, NULL); return cx->popValue(); } -JSValue Array_SetElement(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +js2val Array_SetElement(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { // the 'this' value is the first argument, then the rValue, and finally the index if (argc != 3) cx->reportError(Exception::referenceError, "[]= only supports single dimension"); - JSArrayInstance *arrInst = checked_cast(thisValue.instance); + JSArrayInstance *arrInst = checked_cast(JSValue::instance(thisValue)); - JSValue index = argv[2]; - const String *name = index.toString(cx).string; + js2val index = argv[2]; + const String *name = JSValue::string(JSValue::toString(cx, index)); - if (index.isNumber()) { + if (JSValue::isNumber(index)) { uint32 intIndex; if (isArrayIndex(cx, index, intIndex)) { PropertyIterator it = arrInst->findNamespacedProperty(*name, NULL); @@ -776,7 +776,7 @@ JSValue Array_SetElement(Context *cx, const JSValue& thisValue, JSValue *argv, u else { Property *prop = PROPERTY(it); ASSERT(prop->mFlag == ValuePointer); - *prop->mData.vp = argv[1]; + prop->mData.vp = argv[1]; } if (intIndex >= arrInst->mLength) arrInst->mLength = intIndex + 1; diff --git a/mozilla/js2/src/jsarray.h b/mozilla/js2/src/jsarray.h index 6f9b25aeddc..0ccc371acd7 100644 --- a/mozilla/js2/src/jsarray.h +++ b/mozilla/js2/src/jsarray.h @@ -35,13 +35,13 @@ namespace JavaScript { namespace JS2Runtime { - extern JSValue Array_Constructor(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc); - extern JSValue Array_concat(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc); + extern js2val Array_Constructor(Context *cx, const js2val thisValue, js2val *argv, uint32 argc); + extern js2val Array_concat(Context *cx, const js2val thisValue, js2val *argv, uint32 argc); Context::PrototypeFunctions *getArrayProtos(); - extern JSValue Array_GetElement(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc); - extern JSValue Array_SetElement(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc); + extern js2val Array_GetElement(Context *cx, const js2val thisValue, js2val *argv, uint32 argc); + extern js2val Array_SetElement(Context *cx, const js2val thisValue, js2val *argv, uint32 argc); } diff --git a/mozilla/js2/src/jsdate.cpp b/mozilla/js2/src/jsdate.cpp index 54d1d6b6c7d..da4bdb9e4c6 100644 --- a/mozilla/js2/src/jsdate.cpp +++ b/mozilla/js2/src/jsdate.cpp @@ -289,12 +289,12 @@ static int32 WeekDay(float64 t) return result; } -static float64 *Date_getProlog(Context *cx, const JSValue& thisValue) +static float64 *Date_getProlog(Context *cx, const js2val thisValue) { - if (thisValue.getType() != Date_Type) + if (JSValue::getType(thisValue) != Date_Type) cx->reportError(Exception::typeError, "You need a date"); - ASSERT(thisValue.isInstance()); - JSDateInstance *dateInst = checked_cast(thisValue.instance); + ASSERT(JSValue::isInstance(thisValue)); + JSDateInstance *dateInst = checked_cast(JSValue::instance(thisValue)); return &dateInst->mValue; } @@ -358,7 +358,7 @@ static int32 msFromTime(float64 t) return result; } -static JSValue Date_makeTime(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc, uint32 maxargs, bool local) +static js2val Date_makeTime(Context *cx, const js2val thisValue, js2val *argv, uint32 argc, uint32 maxargs, bool local) { uint32 i; float64 args[4], *argp, *stop; @@ -384,12 +384,12 @@ static JSValue Date_makeTime(Context *cx, const JSValue& thisValue, JSValue *arg argc = maxargs; /* clamp argc */ for (i = 0; i < argc; i++) { - argv[i] = argv[i].toNumber(cx); + argv[i] = JSValue::toNumber(cx, argv[i]); if (JSDOUBLE_IS_NaN(argv[i])) { *date = nan; return kNaNValue; } - args[i] = argv[i].toInteger(cx).f64; + args[i] = JSValue::f64(JSValue::toInteger(cx, argv[i])); } if (local) @@ -426,10 +426,10 @@ static JSValue Date_makeTime(Context *cx, const JSValue& thisValue, JSValue *arg result = UTC(result); *date = TIMECLIP(result); - return JSValue(*date); + return JSValue::newNumber(*date); } -static JSValue Date_makeDate(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc, uint32 maxargs, bool local) +static js2val Date_makeDate(Context *cx, const js2val thisValue, js2val *argv, uint32 argc, uint32 maxargs, bool local) { uint32 i; float64 lorutime; /* local or UTC version of *date */ @@ -450,12 +450,12 @@ static JSValue Date_makeDate(Context *cx, const JSValue& thisValue, JSValue *arg argc = maxargs; /* clamp argc */ for (i = 0; i < argc; i++) { - argv[i] = argv[i].toNumber(cx); + argv[i] = JSValue::toNumber(cx, argv[i]); if (JSDOUBLE_IS_NaN(argv[i])) { *date = nan; return kNaNValue; } - args[i] = argv[i].toInteger(cx).f64; + args[i] = JSValue::f64(JSValue::toInteger(cx, argv[i])); } /* return NaN if date is NaN and we're not setting the year, @@ -496,7 +496,7 @@ static JSValue Date_makeDate(Context *cx, const JSValue& thisValue, JSValue *arg result = UTC(result); *date = TIMECLIP(result); - return JSValue(*date); + return JSValue::newNumber(*date); } /* find UTC time from given date... no 1900 correction! */ @@ -741,7 +741,7 @@ static void new_explode(float64 timeval, PRMJTime *split, bool findEquivalent) } /* helper function */ -static JSValue Date_format(Context * /*cx*/, float64 date, formatspec format) +static js2val Date_format(Context * /*cx*/, float64 date, formatspec format) { StringFormatter outf; char tzbuf[100]; @@ -844,11 +844,11 @@ static JSValue Date_format(Context * /*cx*/, float64 date, formatspec format) } } - return JSValue(new String(outf.getString())); + return JSValue::newString(new String(outf.getString())); } -extern JSValue Date_TypeCast(Context *cx, const JSValue& /*thisValue*/, JSValue * /*argv*/, uint32 /*argc*/) +extern js2val Date_TypeCast(Context *cx, const js2val /*thisValue*/, js2val * /*argv*/, uint32 /*argc*/) { int64 us, ms, us2ms; float64 msec_time; @@ -865,13 +865,13 @@ extern JSValue Date_TypeCast(Context *cx, const JSValue& /*thisValue*/, JSValue } #define MAXARGS 7 -JSValue Date_Constructor(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +js2val Date_Constructor(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { - JSValue thatValue = thisValue; - if (thatValue.isNull()) + js2val thatValue = thisValue; + if (JSValue::isNull(thatValue)) thatValue = Date_Type->newInstance(cx); - ASSERT(thatValue.isInstance()); - JSDateInstance *thisInst = checked_cast(thatValue.instance); + ASSERT(JSValue::isInstance(thatValue)); + JSDateInstance *thisInst = checked_cast(JSValue::instance(thatValue)); /* Date called as constructor */ if (argc == 0) { @@ -887,13 +887,13 @@ JSValue Date_Constructor(Context *cx, const JSValue& thisValue, JSValue *argv, u } else { if (argc == 1) { - if (!argv[0].isString()) { + if (!JSValue::isString(argv[0])) { /* the argument is a millisecond number */ - float64 d = argv[0].toNumber(cx).f64; + float64 d = JSValue::f64(JSValue::toNumber(cx, argv[0])); thisInst->mValue = TIMECLIP(d); } else { /* the argument is a string; parse it. */ - const String *str = argv[0].toString(cx).string; + const String *str = JSValue::string(JSValue::toString(cx, argv[0])); float64 d = date_parseString(*str); thisInst->mValue = TIMECLIP(d); @@ -907,7 +907,7 @@ JSValue Date_Constructor(Context *cx, const JSValue& thisValue, JSValue *argv, u for (loop = 0; loop < MAXARGS; loop++) { if (loop < argc) { - float64 double_arg = argv[loop].toNumber(cx).f64; + float64 double_arg = JSValue::f64(JSValue::toNumber(cx, argv[loop])); /* if any arg is NaN, make a NaN date object and return */ if (!JSDOUBLE_IS_FINITE(double_arg)) { @@ -937,15 +937,15 @@ JSValue Date_Constructor(Context *cx, const JSValue& thisValue, JSValue *argv, u return thatValue; } -JSValue Date_parse(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 /*argc*/) +js2val Date_parse(Context *cx, const js2val /*thisValue*/, js2val *argv, uint32 /*argc*/) { - const String *str = argv[0].toString(cx).string; + const String *str = JSValue::string(JSValue::toString(cx, argv[0])); float64 d = date_parseString(*str); d = TIMECLIP(d); - return JSValue(d); + return JSValue::newNumber(d); } -JSValue Date_UTC(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 argc) +js2val Date_UTC(Context *cx, const js2val /*thisValue*/, js2val *argv, uint32 argc) { float64 array[MAXARGS]; uint32 loop; @@ -953,9 +953,9 @@ JSValue Date_UTC(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint3 for (loop = 0; loop < MAXARGS; loop++) { if (loop < argc) { - d = argv[loop].toNumber(cx).f64; + d = JSValue::f64(JSValue::toNumber(cx, argv[loop])); if (!JSDOUBLE_IS_FINITE(d)) - return JSValue(d); + return JSValue::newNumber(d); array[loop] = floor(d); } else @@ -973,11 +973,11 @@ JSValue Date_UTC(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint3 d = date_msecFromDate(array[0], array[1], array[2], array[3], array[4], array[5], array[6]); d = TIMECLIP(d); - return JSValue(d); + return JSValue::newNumber(d); } -static JSValue Date_toGMTString(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Date_toGMTString(Context *cx, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/) { StringFormatter buf; float64 *date = Date_getProlog(cx, thisValue); @@ -999,11 +999,11 @@ static JSValue Date_toGMTString(Context *cx, const JSValue& thisValue, JSValue * MinFromTime(temp), SecFromTime(temp)); } - return JSValue(new String(buf.getString())); + return JSValue::newString(new String(buf.getString())); } -static JSValue Date_toLocaleHelper(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/, char *format) +static js2val Date_toLocaleHelper(Context *cx, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/, char *format) { StringFormatter outf; char buf[100]; @@ -1035,10 +1035,10 @@ static JSValue Date_toLocaleHelper(Context *cx, const JSValue& thisValue, JSValu outf << buf; } - return JSValue(new String(outf.getString())); + return JSValue::newString(new String(outf.getString())); } -static JSValue Date_toLocaleString(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val Date_toLocaleString(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { /* Use '%#c' for windows, because '%c' is * backward-compatible and non-y2k with msvc; '%#c' requests that a @@ -1053,7 +1053,7 @@ static JSValue Date_toLocaleString(Context *cx, const JSValue& thisValue, JSValu ); } -static JSValue Date_toLocaleDateString(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val Date_toLocaleDateString(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { /* Use '%#x' for windows, because '%x' is * backward-compatible and non-y2k with msvc; '%#x' requests that a @@ -1068,44 +1068,44 @@ static JSValue Date_toLocaleDateString(Context *cx, const JSValue& thisValue, JS ); } -static JSValue Date_toLocaleTimeString(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val Date_toLocaleTimeString(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { return Date_toLocaleHelper(cx, thisValue, argv, argc, "%X"); } -static JSValue Date_toTimeString(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Date_toTimeString(Context *cx, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/) { float64 *date = Date_getProlog(cx, thisValue); return Date_format(cx, *date, FORMATSPEC_TIME); } -static JSValue Date_toDateString(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Date_toDateString(Context *cx, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/) { float64 *date = Date_getProlog(cx, thisValue); return Date_format(cx, *date, FORMATSPEC_DATE); } -static JSValue Date_toString(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Date_toString(Context *cx, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/) { float64 *date = Date_getProlog(cx, thisValue); return Date_format(cx, *date, FORMATSPEC_FULL); } -static JSValue Date_toSource(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Date_toSource(Context *cx, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/) { StringFormatter buf; float64 *date = Date_getProlog(cx, thisValue); buf << "(new Date(" << *numberToString(*date) << "))"; - return JSValue(new String(buf.getString())); + return JSValue::newString(new String(buf.getString())); } -static JSValue Date_getTime(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Date_getTime(Context *cx, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/) { float64 *date = Date_getProlog(cx, thisValue); - return JSValue(*date); + return JSValue::newNumber(*date); } -static JSValue Date_getTimezoneOffset(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Date_getTimezoneOffset(Context *cx, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/) { float64 result; float64 *date = Date_getProlog(cx, thisValue); @@ -1117,17 +1117,17 @@ static JSValue Date_getTimezoneOffset(Context *cx, const JSValue& thisValue, JSV * constant except for daylight savings time. */ result = (result - LocalTime(result)) / msPerMinute; - return JSValue(result); + return JSValue::newNumber(result); } -static JSValue Date_getYear(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Date_getYear(Context *cx, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/) { float64 result; float64 *date = Date_getProlog(cx, thisValue); result = *date; if (!JSDOUBLE_IS_FINITE(result)) - return JSValue(result); + return JSValue::newNumber(result); result = YearFromTime(LocalTime(result)); @@ -1154,147 +1154,147 @@ static JSValue Date_getYear(Context *cx, const JSValue& thisValue, JSValue * /*a #else result -= 1900; #endif - return JSValue(result); + return JSValue::newNumber(result); } -static JSValue Date_getFullYear(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Date_getFullYear(Context *cx, const js2val thisValue, js2val * /* argv */, uint32 /*argc*/) { float64 result = *Date_getProlog(cx, thisValue); if (!JSDOUBLE_IS_FINITE(result)) - return JSValue(result); + return JSValue::newNumber(result); result = YearFromTime(LocalTime(result)); - return JSValue(result); + return JSValue::newNumber(result); } -static JSValue Date_getUTCFullYear(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Date_getUTCFullYear(Context *cx, const js2val thisValue, js2val * /* argv */, uint32 /*argc*/) { float64 result = *Date_getProlog(cx, thisValue); if (!JSDOUBLE_IS_FINITE(result)) - return JSValue(result); + return JSValue::newNumber(result); result = YearFromTime(result); - return JSValue(result); + return JSValue::newNumber(result); } -static JSValue Date_getMonth(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Date_getMonth(Context *cx, const js2val thisValue, js2val * /* argv */, uint32 /*argc*/) { float64 result = *Date_getProlog(cx, thisValue); if (!JSDOUBLE_IS_FINITE(result)) - return JSValue(result); + return JSValue::newNumber(result); result = MonthFromTime(LocalTime(result)); - return JSValue(result); + return JSValue::newNumber(result); } -static JSValue Date_getUTCMonth(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Date_getUTCMonth(Context *cx, const js2val thisValue, js2val * /* argv */, uint32 /*argc*/) { float64 result = *Date_getProlog(cx, thisValue); if (!JSDOUBLE_IS_FINITE(result)) - return JSValue(result); + return JSValue::newNumber(result); result = MonthFromTime(result); - return JSValue(result); + return JSValue::newNumber(result); } -static JSValue Date_getDate(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Date_getDate(Context *cx, const js2val thisValue, js2val * /* argv */, uint32 /*argc*/) { float64 result = *Date_getProlog(cx, thisValue); if (!JSDOUBLE_IS_FINITE(result)) - return JSValue(result); + return JSValue::newNumber(result); result = DateFromTime(LocalTime(result)); - return JSValue(result); + return JSValue::newNumber(result); } -static JSValue Date_getUTCDate(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Date_getUTCDate(Context *cx, const js2val thisValue, js2val * /* argv */, uint32 /*argc*/) { float64 result = *Date_getProlog(cx, thisValue); if (!JSDOUBLE_IS_FINITE(result)) - return JSValue(result); + return JSValue::newNumber(result); result = DateFromTime(result); - return JSValue(result); + return JSValue::newNumber(result); } -static JSValue Date_getDay(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Date_getDay(Context *cx, const js2val thisValue, js2val * /* argv */, uint32 /*argc*/) { float64 result = *Date_getProlog(cx, thisValue); if (!JSDOUBLE_IS_FINITE(result)) - return JSValue(result); + return JSValue::newNumber(result); result = WeekDay(LocalTime(result)); - return JSValue(result); + return JSValue::newNumber(result); } -static JSValue Date_getUTCDay(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Date_getUTCDay(Context *cx, const js2val thisValue, js2val * /* argv */, uint32 /*argc*/) { float64 result = *Date_getProlog(cx, thisValue); if (!JSDOUBLE_IS_FINITE(result)) - return JSValue(result); + return JSValue::newNumber(result); result = WeekDay(result); - return JSValue(result); + return JSValue::newNumber(result); } -static JSValue Date_getHours(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Date_getHours(Context *cx, const js2val thisValue, js2val * /* argv */, uint32 /*argc*/) { float64 result = *Date_getProlog(cx, thisValue); if (!JSDOUBLE_IS_FINITE(result)) - return JSValue(result); + return JSValue::newNumber(result); result = HourFromTime(LocalTime(result)); - return JSValue(result); + return JSValue::newNumber(result); } -static JSValue Date_getUTCHours(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Date_getUTCHours(Context *cx, const js2val thisValue, js2val * /* argv */, uint32 /*argc*/) { float64 result = *Date_getProlog(cx, thisValue); if (!JSDOUBLE_IS_FINITE(result)) - return JSValue(result); + return JSValue::newNumber(result); result = HourFromTime(result); - return JSValue(result); + return JSValue::newNumber(result); } -static JSValue Date_getMinutes(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Date_getMinutes(Context *cx, const js2val thisValue, js2val * /* argv */, uint32 /*argc*/) { float64 result = *Date_getProlog(cx, thisValue); if (!JSDOUBLE_IS_FINITE(result)) - return JSValue(result); + return JSValue::newNumber(result); result = MinFromTime(LocalTime(result)); - return JSValue(result); + return JSValue::newNumber(result); } -static JSValue Date_getUTCMinutes(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Date_getUTCMinutes(Context *cx, const js2val thisValue, js2val * /* argv */, uint32 /*argc*/) { float64 result = *Date_getProlog(cx, thisValue); if (!JSDOUBLE_IS_FINITE(result)) - return JSValue(result); + return JSValue::newNumber(result); result = MinFromTime(result); - return JSValue(result); + return JSValue::newNumber(result); } /* Date.getSeconds is mapped to getUTCSeconds */ -static JSValue Date_getUTCSeconds(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Date_getUTCSeconds(Context *cx, const js2val thisValue, js2val * /* argv */, uint32 /*argc*/) { float64 result = *Date_getProlog(cx, thisValue); if (!JSDOUBLE_IS_FINITE(result)) - return JSValue(result); + return JSValue::newNumber(result); result = SecFromTime(result); - return JSValue(result); + return JSValue::newNumber(result); } /* Date.getMilliseconds is mapped to getUTCMilliseconds */ -static JSValue Date_getUTCMilliseconds(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Date_getUTCMilliseconds(Context *cx, const js2val thisValue, js2val * /* argv */, uint32 /*argc*/) { float64 result = *Date_getProlog(cx, thisValue); if (!JSDOUBLE_IS_FINITE(result)) - return JSValue(result); + return JSValue::newNumber(result); result = msFromTime(result); - return JSValue(result); + return JSValue::newNumber(result); } -static JSValue Date_setTime(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 /*argc*/) +static js2val Date_setTime(Context *cx, const js2val thisValue, js2val argv[], uint32 /*argc*/) { float64 *date = Date_getProlog(cx, thisValue); - float64 result = argv[0].toNumber(cx).f64; + float64 result = JSValue::f64(JSValue::toNumber(cx, argv[0])); *date = TIMECLIP(result); - return JSValue(*date); + return JSValue::newNumber(*date); } -static JSValue Date_setYear(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 /*argc*/) +static js2val Date_setYear(Context *cx, const js2val thisValue, js2val argv[], uint32 /*argc*/) { float64 t; float64 year; @@ -1303,10 +1303,10 @@ static JSValue Date_setYear(Context *cx, const JSValue& thisValue, JSValue *argv float64 *date = Date_getProlog(cx, thisValue); result = *date; - year = argv[0].toNumber(cx).f64; + year = JSValue::f64(JSValue::toNumber(cx, argv[0])); if (!JSDOUBLE_IS_FINITE(year)) { *date = nan; - return JSValue(*date); + return JSValue::newNumber(*date); } year = JSValue::float64ToInteger(year); @@ -1325,82 +1325,82 @@ static JSValue Date_setYear(Context *cx, const JSValue& thisValue, JSValue *argv result = UTC(result); *date = TIMECLIP(result); - return JSValue(*date); + return JSValue::newNumber(*date); } -static JSValue Date_setFullYear(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val Date_setFullYear(Context *cx, const js2val thisValue, js2val argv[], uint32 argc) { return Date_makeDate(cx, thisValue, argv, argc, 3, true); } -static JSValue Date_setUTCFullYear(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val Date_setUTCFullYear(Context *cx, const js2val thisValue, js2val argv[], uint32 argc) { return Date_makeDate(cx, thisValue, argv, argc, 3, false); } -static JSValue Date_setMonth(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val Date_setMonth(Context *cx, const js2val thisValue, js2val argv[], uint32 argc) { return Date_makeDate(cx, thisValue, argv, argc, 2, true); } -static JSValue Date_setUTCMonth(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val Date_setUTCMonth(Context *cx, const js2val thisValue, js2val argv[], uint32 argc) { return Date_makeDate(cx, thisValue, argv, argc, 2, false); } -static JSValue Date_setDate(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val Date_setDate(Context *cx, const js2val thisValue, js2val argv[], uint32 argc) { return Date_makeDate(cx, thisValue, argv, argc, 1, true); } -static JSValue Date_setUTCDate(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val Date_setUTCDate(Context *cx, const js2val thisValue, js2val argv[], uint32 argc) { return Date_makeDate(cx, thisValue, argv, argc, 1, false); } -static JSValue Date_setHours(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val Date_setHours(Context *cx, const js2val thisValue, js2val argv[], uint32 argc) { return Date_makeTime(cx, thisValue, argv, argc, 4, true); } -static JSValue Date_setUTCHours(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val Date_setUTCHours(Context *cx, const js2val thisValue, js2val argv[], uint32 argc) { return Date_makeTime(cx, thisValue, argv, argc, 4, false); } -static JSValue Date_setMinutes(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val Date_setMinutes(Context *cx, const js2val thisValue, js2val argv[], uint32 argc) { return Date_makeTime(cx, thisValue, argv, argc, 3, true); } -static JSValue Date_setUTCMinutes(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val Date_setUTCMinutes(Context *cx, const js2val thisValue, js2val argv[], uint32 argc) { return Date_makeTime(cx, thisValue, argv, argc, 3, false); } -static JSValue Date_setSeconds(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val Date_setSeconds(Context *cx, const js2val thisValue, js2val argv[], uint32 argc) { return Date_makeTime(cx, thisValue, argv, argc, 2, true); } -static JSValue Date_setUTCSeconds(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val Date_setUTCSeconds(Context *cx, const js2val thisValue, js2val argv[], uint32 argc) { return Date_makeTime(cx, thisValue, argv, argc, 2, true); } -static JSValue Date_setMilliseconds(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val Date_setMilliseconds(Context *cx, const js2val thisValue, js2val argv[], uint32 argc) { return Date_makeTime(cx, thisValue, argv, argc, 1, true); } -static JSValue Date_setUTCMilliseconds(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val Date_setUTCMilliseconds(Context *cx, const js2val thisValue, js2val argv[], uint32 argc) { return Date_makeTime(cx, thisValue, argv, argc, 1, true); } // SpiderMonkey has a 'hinted' version: #if JS_HAS_VALUEOF_HINT -static JSValue Date_valueOf(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val Date_valueOf(Context *cx, const js2val thisValue, js2val argv[], uint32 argc) { /* If called directly with no arguments, convert to a time number. */ if (argc == 0) @@ -1408,7 +1408,7 @@ static JSValue Date_valueOf(Context *cx, const JSValue& thisValue, JSValue *argv /* Convert to number only if the hint was given, otherwise favor string. */ if (argc == 1) { - const String *str = argv[0].toString(cx).string; + const String *str = JSValue::string(JSValue::toString(cx, argv[0])); if (str->compare(&cx->Number_StringAtom) == 0) return Date_getTime(cx, thisValue, argv, argc); } diff --git a/mozilla/js2/src/jsdate.h b/mozilla/js2/src/jsdate.h index abe897bee1f..d4f78e6b00a 100644 --- a/mozilla/js2/src/jsdate.h +++ b/mozilla/js2/src/jsdate.h @@ -36,10 +36,10 @@ namespace JavaScript { namespace JS2Runtime { - extern JSValue Date_Constructor(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc); - extern JSValue Date_TypeCast(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc); - extern JSValue Date_parse(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc); - extern JSValue Date_UTC(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc); + extern js2val Date_Constructor(Context *cx, const js2val thisValue, js2val *argv, uint32 argc); + extern js2val Date_TypeCast(Context *cx, const js2val thisValue, js2val *argv, uint32 argc); + extern js2val Date_parse(Context *cx, const js2val thisValue, js2val *argv, uint32 argc); + extern js2val Date_UTC(Context *cx, const js2val thisValue, js2val *argv, uint32 argc); Context::PrototypeFunctions *getDateProtos(); diff --git a/mozilla/js2/src/jsmath.cpp b/mozilla/js2/src/jsmath.cpp index 978d4f84801..10dde603056 100644 --- a/mozilla/js2/src/jsmath.cpp +++ b/mozilla/js2/src/jsmath.cpp @@ -80,103 +80,103 @@ namespace JS2Runtime { #define M_CONSTANTS_COUNT 8 -static JSValue Math_abs(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 argc) +static js2val Math_abs(Context *cx, const js2val /*thisValue*/, js2val *argv, uint32 argc) { if (argc == 0) return kNaNValue; else - return JSValue(fd::fabs(argv[0].toNumber(cx).f64)); + return JSValue::newNumber(fd::fabs(JSValue::f64(JSValue::toNumber(cx, argv[0])))); } -static JSValue Math_acos(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 argc) +static js2val Math_acos(Context *cx, const js2val /*thisValue*/, js2val *argv, uint32 argc) { if (argc == 0) return kNaNValue; - return JSValue(fd::acos(argv[0].toNumber(cx).f64)); + return JSValue::newNumber(fd::acos(JSValue::f64(JSValue::toNumber(cx, argv[0])))); } -static JSValue Math_asin(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 argc) +static js2val Math_asin(Context *cx, const js2val /*thisValue*/, js2val *argv, uint32 argc) { if (argc == 0) return kNaNValue; - return JSValue(fd::asin(argv[0].toNumber(cx).f64)); + return JSValue::newNumber(fd::asin(JSValue::f64(JSValue::toNumber(cx, argv[0])))); } -static JSValue Math_atan(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 argc) +static js2val Math_atan(Context *cx, const js2val /*thisValue*/, js2val *argv, uint32 argc) { if (argc == 0) return kNaNValue; - return JSValue(fd::atan(argv[0].toNumber(cx).f64)); + return JSValue::newNumber(fd::atan(JSValue::f64(JSValue::toNumber(cx, argv[0])))); } -static JSValue Math_atan2(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 argc) +static js2val Math_atan2(Context *cx, const js2val /*thisValue*/, js2val *argv, uint32 argc) { if (argc <= 1) return kNaNValue; - float64 y = argv[0].toNumber(cx).f64; - float64 x = argv[1].toNumber(cx).f64; - return JSValue(fd::atan2(y, x)); + float64 y = JSValue::f64(JSValue::toNumber(cx, argv[0])); + float64 x = JSValue::f64(JSValue::toNumber(cx, argv[1])); + return JSValue::newNumber(fd::atan2(y, x)); } -static JSValue Math_ceil(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 argc) +static js2val Math_ceil(Context *cx, const js2val /*thisValue*/, js2val *argv, uint32 argc) { if (argc == 0) return kNaNValue; - return JSValue(fd::ceil(argv[0].toNumber(cx).f64)); + return JSValue::newNumber(fd::ceil(JSValue::f64(JSValue::toNumber(cx, argv[0])))); } -static JSValue Math_cos(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 argc) +static js2val Math_cos(Context *cx, const js2val /*thisValue*/, js2val *argv, uint32 argc) { if (argc == 0) return kNaNValue; - return JSValue(fd::cos(argv[0].toNumber(cx).f64)); + return JSValue::newNumber(fd::cos(JSValue::f64(JSValue::toNumber(cx, argv[0])))); } -static JSValue Math_exp(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 argc) +static js2val Math_exp(Context *cx, const js2val /*thisValue*/, js2val *argv, uint32 argc) { if (argc == 0) return kNaNValue; - return JSValue(fd::exp(argv[0].toNumber(cx).f64)); + return JSValue::newNumber(fd::exp(JSValue::f64(JSValue::toNumber(cx, argv[0])))); } -static JSValue Math_floor(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 argc) +static js2val Math_floor(Context *cx, const js2val /*thisValue*/, js2val *argv, uint32 argc) { if (argc == 0) return kNaNValue; else - return JSValue(fd::floor(argv[0].toNumber(cx).f64)); + return JSValue::newNumber(fd::floor(JSValue::f64(JSValue::toNumber(cx, argv[0])))); } -static JSValue Math_log(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 argc) +static js2val Math_log(Context *cx, const js2val /*thisValue*/, js2val *argv, uint32 argc) { if (argc == 0) return kNaNValue; - return JSValue(fd::log(argv[0].toNumber(cx).f64)); + return JSValue::newNumber(fd::log(JSValue::f64(JSValue::toNumber(cx, argv[0])))); } -static JSValue Math_max(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 argc) +static js2val Math_max(Context *cx, const js2val /*thisValue*/, js2val *argv, uint32 argc) { if (argc == 0) return kNegativeInfinity; - float64 result = argv[0].toNumber(cx).f64; + float64 result = JSValue::f64(JSValue::toNumber(cx, argv[0])); if (JSDOUBLE_IS_NaN(result)) return kNaNValue; for (uint32 i = 1; i < argc; ++i) { - float64 arg = argv[i].toNumber(cx).f64; + float64 arg = JSValue::f64(JSValue::toNumber(cx, argv[i])); if (JSDOUBLE_IS_NaN(arg)) return kNaNValue; if (arg > result) result = arg; } - return JSValue(result); + return JSValue::newNumber(result); } -static JSValue Math_min(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 argc) +static js2val Math_min(Context *cx, const js2val /*thisValue*/, js2val *argv, uint32 argc) { if (argc == 0) return kPositiveInfinity; - float64 result = argv[0].toNumber(cx).f64; + float64 result = JSValue::f64(JSValue::toNumber(cx, argv[0])); if (JSDOUBLE_IS_NaN(result)) return kNaNValue; for (uint32 i = 1; i < argc; ++i) { - float64 arg = argv[i].toNumber(cx).f64; + float64 arg = JSValue::f64(JSValue::toNumber(cx, argv[i])); if (JSDOUBLE_IS_NaN(arg)) return kNaNValue; if ((arg < result) || (JSDOUBLE_IS_POSZERO(result) && JSDOUBLE_IS_NEGZERO(arg))) result = arg; } - return JSValue(result); + return JSValue::newNumber(result); } -static JSValue Math_pow(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 argc) +static js2val Math_pow(Context *cx, const js2val /*thisValue*/, js2val *argv, uint32 argc) { if (argc < 1) return kNaNValue; - return JSValue(fd::pow(argv[0].toNumber(cx).f64, argv[1].toNumber(cx).f64)); + return JSValue::newNumber(fd::pow(JSValue::f64(JSValue::toNumber(cx, argv[0])), JSValue::f64(JSValue::toNumber(cx, argv[1])))); } /* @@ -249,35 +249,35 @@ static float64 random_nextDouble(Context *cx) } -static JSValue Math_random(Context *cx, const JSValue& /*thisValue*/, JSValue * /*argv*/, uint32 /*argc*/) +static js2val Math_random(Context *cx, const js2val /*thisValue*/, js2val *argv, uint32 /*argc*/) { random_init(cx); - return JSValue(random_nextDouble(cx)); + return JSValue::newNumber(random_nextDouble(cx)); } -static JSValue Math_round(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 argc) +static js2val Math_round(Context *cx, const js2val /*thisValue*/, js2val *argv, uint32 argc) { if (argc == 0) return kNaNValue; - float64 x = argv[0].toNumber(cx).f64; - return JSValue( fd::copysign( fd::floor(x + 0.5), x ) ); + float64 x = JSValue::f64(JSValue::toNumber(cx, argv[0])); + return JSValue::newNumber( fd::copysign( fd::floor(x + 0.5), x ) ); } -static JSValue Math_sin(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 argc) +static js2val Math_sin(Context *cx, const js2val /*thisValue*/, js2val *argv, uint32 argc) { if (argc == 0) return kNaNValue; - return JSValue(fd::sin(argv[0].toNumber(cx).f64)); + return JSValue::newNumber(fd::sin(JSValue::f64(JSValue::toNumber(cx, argv[0])))); } -static JSValue Math_sqrt(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 argc) +static js2val Math_sqrt(Context *cx, const js2val /*thisValue*/, js2val *argv, uint32 argc) { if (argc == 0) return kNaNValue; - return JSValue(fd::sqrt(argv[0].toNumber(cx).f64)); + return JSValue::newNumber(fd::sqrt(JSValue::f64(JSValue::toNumber(cx, argv[0])))); } -static JSValue Math_tan(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 argc) +static js2val Math_tan(Context *cx, const js2val /*thisValue*/, js2val *argv, uint32 argc) { if (argc == 0) return kNaNValue; - return JSValue(fd::tan(argv[0].toNumber(cx).f64)); + return JSValue::newNumber(fd::tan(JSValue::f64(JSValue::toNumber(cx, argv[0])))); } @@ -326,14 +326,14 @@ void initMathObject(Context *cx, JSObject *mathObj) for (i = 0; i < M_CONSTANTS_COUNT; i++) mathObj->defineVariable(cx, widenCString(MathObjectConstants[i].name), (NamespaceList *)(NULL), Property::ReadOnly | Property::DontDelete, - Number_Type, JSValue(MathObjectConstants[i].value)); + Number_Type, JSValue::newNumber(MathObjectConstants[i].value)); for (i = 0; i < sizeof(MathObjectFunctions) / sizeof(MathObjectFunctionDef); i++) { - JSFunction *f = new JSFunction(cx, MathObjectFunctions[i].imp, Number_Type); + JSFunction *f = new JSFunction(cx, MathObjectFunctions[i].imp, Number_Type, NULL); f->setParameterCounts(cx, MathObjectFunctions[i].length, 0, 0, false); mathObj->defineVariable(cx, widenCString(MathObjectFunctions[i].name), (NamespaceList *)(NULL), Property::ReadOnly | Property::DontDelete, - Number_Type, JSValue(f)); + Number_Type, JSValue::newFunction(f)); } } diff --git a/mozilla/js2/src/jsstring.cpp b/mozilla/js2/src/jsstring.cpp index 178079b5668..ad316932aef 100644 --- a/mozilla/js2/src/jsstring.cpp +++ b/mozilla/js2/src/jsstring.cpp @@ -50,56 +50,56 @@ namespace JavaScript { namespace JS2Runtime { -JSValue String_Constructor(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +js2val String_Constructor(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { - JSValue thatValue = thisValue; - if (thatValue.isNull()) + js2val thatValue = thisValue; + if (JSValue::isNull(thatValue)) thatValue = String_Type->newInstance(cx); - ASSERT(thatValue.isInstance()); - JSStringInstance *strInst = checked_cast(thatValue.instance); + ASSERT(JSValue::isInstance(thatValue)); + JSStringInstance *strInst = checked_cast(JSValue::instance(thatValue)); if (argc > 0) - strInst->mValue = new String(*argv[0].toString(cx).string); + strInst->mValue = new String(*JSValue::string(JSValue::toString(cx, argv[0]))); else strInst->mValue = &cx->Empty_StringAtom; return thatValue; } -JSValue String_TypeCast(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 argc) +js2val String_TypeCast(Context *cx, const js2val /*thisValue*/, js2val *argv, uint32 argc) { if (argc == 0) - return JSValue(&cx->Empty_StringAtom); + return JSValue::newString(&cx->Empty_StringAtom); else - return argv[0].toString(cx); + return JSValue::toString(cx, argv[0]); } -JSValue String_fromCharCode(Context *cx, const JSValue& /*thisValue*/, JSValue *argv, uint32 argc) +js2val String_fromCharCode(Context *cx, const js2val /*thisValue*/, js2val *argv, uint32 argc) { String *resultStr = new String(); // can't use cx->Empty_StringAtom; because we're modifying this below resultStr->reserve(argc); for (uint32 i = 0; i < argc; i++) - *resultStr += (char16)(argv[i].toUInt16(cx).f64); + *resultStr += (char16)(JSValue::f64(JSValue::toUInt16(cx, argv[i]))); - return JSValue(resultStr); + return JSValue::newString(resultStr); } -static JSValue String_toString(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val String_toString(Context *cx, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/) { - if (thisValue.getType() != String_Type) + if (JSValue::getType(thisValue) != String_Type) cx->reportError(Exception::typeError, "String.toString called on something other than a string thing"); - ASSERT(thisValue.isInstance()); - JSStringInstance *strInst = checked_cast(thisValue.instance); - return JSValue(strInst->mValue); + ASSERT(JSValue::isInstance(thisValue)); + JSStringInstance *strInst = checked_cast(JSValue::instance(thisValue)); + return JSValue::newString(strInst->mValue); } -static JSValue String_valueOf(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val String_valueOf(Context *cx, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/) { - if (thisValue.getType() != String_Type) + if (JSValue::getType(thisValue) != String_Type) cx->reportError(Exception::typeError, "String.valueOf called on something other than a string thing"); - ASSERT(thisValue.isInstance()); - JSStringInstance *strInst = checked_cast(thisValue.instance); - return JSValue(strInst->mValue); + ASSERT(JSValue::isInstance(thisValue)); + JSStringInstance *strInst = checked_cast(JSValue::instance(thisValue)); + return JSValue::newString(strInst->mValue); } /* @@ -112,24 +112,25 @@ static JSValue String_valueOf(Context *cx, const JSValue& thisValue, JSValue * / * NOTE This method ignores the lastIndex and global properties of regexp. The lastIndex property of regexp is left * unchanged. */ -static JSValue String_search(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val String_search(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { ContextStackReplacement csr(cx); - JSValue S = thisValue.toString(cx); + js2val S = JSValue::toString(cx, thisValue); - JSValue regexp = argv[0]; - if ((argc == 0) || (regexp.getType() != RegExp_Type)) { + js2val regexp = argv[0]; + if ((argc == 0) || (JSValue::getType(regexp) != RegExp_Type)) { regexp = kNullValue; regexp = RegExp_Constructor(cx, regexp, argv, 1); } - REState *pState = (checked_cast(regexp.instance))->mRegExp; + REState *pState = (checked_cast(JSValue::instance(regexp)))->mRegExp; - REMatchState *match = REExecute(pState, S.string->begin(), 0, S.string->length(), false); + const String *str = JSValue::string(S); + REMatchState *match = REExecute(pState, str->begin(), 0, str->length(), false); if (match) - return JSValue((float64)(match->startIndex)); + return JSValue::newNumber((float64)(match->startIndex)); else - return JSValue(-1.0); + return JSValue::newNumber(-1.0); } @@ -147,39 +148,39 @@ static JSValue String_search(Context *cx, const JSValue& thisValue, JSValue *arg * first elements of the results of all matching invocations of RegExp.prototype.exec. */ -static JSValue String_match(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val String_match(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { ContextStackReplacement csr(cx); - JSValue S = thisValue.toString(cx); + js2val S = JSValue::toString(cx, thisValue); - JSValue regexp = argv[0]; - if ((argc == 0) || (regexp.getType() != RegExp_Type)) { + js2val regexp = argv[0]; + if ((argc == 0) || (JSValue::getType(regexp) != RegExp_Type)) { regexp = kNullValue; regexp = RegExp_Constructor(cx, regexp, argv, 1); } - REState *pState = (checked_cast(regexp.instance))->mRegExp; + REState *pState = (checked_cast(JSValue::instance(regexp)))->mRegExp; if ((pState->flags & RE_GLOBAL) == 0) { return RegExp_exec(cx, regexp, &S, 1); } else { - JSValue result = Array_Type->newInstance(cx); - JSArrayInstance *A = checked_cast(result.instance); + js2val result = Array_Type->newInstance(cx); + JSArrayInstance *A = checked_cast(JSValue::instance(result)); int32 index = 0; int32 lastIndex = 0; while (true) { - REMatchState *match = REExecute(pState, S.string->begin(), lastIndex, S.string->length(), false); + REMatchState *match = REExecute(pState, JSValue::string(S)->begin(), lastIndex, JSValue::string(S)->length(), false); if (match == NULL) break; if (lastIndex == match->endIndex) lastIndex++; else lastIndex = match->endIndex; - String *matchStr = new String(S.string->substr(match->startIndex, match->endIndex - match->startIndex)); - A->setProperty(cx, *numberToString(index++), NULL, JSValue(matchStr)); + String *matchStr = new String(JSValue::string(S)->substr(match->startIndex, match->endIndex - match->startIndex)); + A->setProperty(cx, *numberToString(index++), NULL, JSValue::newString(matchStr)); } - regexp.instance->setProperty(cx, cx->LastIndex_StringAtom, NULL, JSValue((float64)lastIndex)); + JSValue::instance(regexp)->setProperty(cx, cx->LastIndex_StringAtom, NULL, JSValue::newNumber((float64)lastIndex)); return result; } } @@ -257,26 +258,26 @@ static const String interpretDollar(Context *cx, const String *replaceStr, uint3 */ -static JSValue String_replace(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val String_replace(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { - JSValue S = thisValue.toString(cx); + const String *S = JSValue::string(JSValue::toString(cx, thisValue)); - JSValue searchValue; - JSValue replaceValue; + js2val searchValue; + js2val replaceValue; if (argc > 0) searchValue = argv[0]; if (argc > 1) replaceValue = argv[1]; - const String *replaceStr = replaceValue.toString(cx).string; + const String *replaceStr = JSValue::string(JSValue::toString(cx, replaceValue)); - if (searchValue.getType() == RegExp_Type) { - REState *pState = (checked_cast(searchValue.instance))->mRegExp; + if (JSValue::getType(searchValue) == RegExp_Type) { + REState *pState = (checked_cast(JSValue::instance(searchValue)))->mRegExp; REMatchState *match; uint32 m = pState->parenCount; String newString; int32 lastIndex = 0; while (true) { - match = REExecute(pState, S.string->begin(), lastIndex, S.string->length(), false); + match = REExecute(pState, S->begin(), lastIndex, S->length(), false); if (match) { String insertString; uint32 start = 0; @@ -286,7 +287,7 @@ static JSValue String_replace(Context *cx, const JSValue& thisValue, JSValue *ar if ((dollarPos != String::npos) && (dollarPos < (replaceStr->length() - 1))) { uint32 skip; insertString += replaceStr->substr(start, dollarPos - start); - insertString += interpretDollar(cx, replaceStr, dollarPos, S.string, match, skip); + insertString += interpretDollar(cx, replaceStr, dollarPos, S, match, skip); start = dollarPos + skip; } else { @@ -296,7 +297,7 @@ static JSValue String_replace(Context *cx, const JSValue& thisValue, JSValue *ar } } // grab everything preceding the match - newString += S.string->substr(lastIndex, match->startIndex - lastIndex); + newString += S->substr(lastIndex, match->startIndex - lastIndex); // and then add the replacement string newString += insertString; } @@ -306,17 +307,17 @@ static JSValue String_replace(Context *cx, const JSValue& thisValue, JSValue *ar if ((pState->flags & RE_GLOBAL) == 0) break; } - newString += S.string->substr(lastIndex, S.string->length() - lastIndex); + newString += S->substr(lastIndex, S->length() - lastIndex); if ((pState->flags & RE_GLOBAL) == 0) - searchValue.instance->setProperty(cx, cx->LastIndex_StringAtom, NULL, JSValue((float64)lastIndex)); - return JSValue(new String(newString)); + JSValue::instance(searchValue)->setProperty(cx, cx->LastIndex_StringAtom, NULL, JSValue::newNumber((float64)lastIndex)); + return JSValue::newString(new String(newString)); } else { - const String *searchStr = searchValue.toString(cx).string; + const String *searchStr = JSValue::string(JSValue::toString(cx, searchValue)); REMatchState match; - uint32 pos = S.string->find(*searchStr, 0); + uint32 pos = S->find(*searchStr, 0); if (pos == String::npos) - return JSValue(S.string); + return JSValue::newString(S); match.startIndex = (int32)pos; match.endIndex = match.startIndex + searchStr->length(); match.parenCount = 0; @@ -328,7 +329,7 @@ static JSValue String_replace(Context *cx, const JSValue& thisValue, JSValue *ar if ((dollarPos != String::npos) && (dollarPos < (replaceStr->length() - 1))) { uint32 skip; insertString += replaceStr->substr(start, dollarPos - start); - insertString += interpretDollar(cx, replaceStr, dollarPos, S.string, &match, skip); + insertString += interpretDollar(cx, replaceStr, dollarPos, S, &match, skip); start = dollarPos + skip; } else { @@ -336,11 +337,11 @@ static JSValue String_replace(Context *cx, const JSValue& thisValue, JSValue *ar break; } } - newString += S.string->substr(0, match.startIndex); + newString += S->substr(0, match.startIndex); newString += insertString; uint32 index = match.endIndex; - newString += S.string->substr(index, S.string->length() - index); - return JSValue(new String(newString)); + newString += S->substr(index, S->length() - index); + return JSValue::newString(new String(newString)); } } @@ -348,7 +349,7 @@ struct MatchResult { bool failure; uint32 endIndex; uint32 capturesCount; - JSValue *captures; + js2val *captures; }; static void strSplitMatch(const String *S, uint32 q, const String *R, MatchResult &result) @@ -381,12 +382,12 @@ static void regexpSplitMatch(const String *S, uint32 q, REState *RE, MatchResult result.failure = false; result.capturesCount = match->parenCount; if (match->parenCount) { - result.captures = new JSValue[match->parenCount]; + result.captures = new js2val[match->parenCount]; for (int32 i = 0; i < match->parenCount; i++) { if (match->parens[i].index != -1) { String *parenStr = new String(S->substr((uint32)(match->parens[i].index + q), (uint32)(match->parens[i].length))); - result.captures[i] = JSValue(parenStr); + result.captures[i] = JSValue::newString(parenStr); } else result.captures[i] = kUndefinedValue; @@ -396,32 +397,32 @@ static void regexpSplitMatch(const String *S, uint32 q, REState *RE, MatchResult } -static JSValue String_split(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val String_split(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { ContextStackReplacement csr(cx); - JSValue S = thisValue.toString(cx); + const String *S = JSValue::string(JSValue::toString(cx, thisValue)); - JSValue result = Array_Type->newInstance(cx); - JSArrayInstance *A = checked_cast(result.instance); + js2val result = Array_Type->newInstance(cx); + JSArrayInstance *A = checked_cast(JSValue::instance(result)); uint32 lim; - JSValue separatorV = (argc > 0) ? argv[0] : kUndefinedValue; - JSValue limitV = (argc > 1) ? argv[1] : kUndefinedValue; + js2val separatorV = (argc > 0) ? argv[0] : kUndefinedValue; + js2val limitV = (argc > 1) ? argv[1] : kUndefinedValue; - if (limitV.isUndefined()) + if (JSValue::isUndefined(limitV)) lim = (uint32)(two32minus1); else - lim = (uint32)(limitV.toUInt32(cx).f64); + lim = (uint32)JSValue::f64(JSValue::toUInt32(cx, limitV)); - uint32 s = S.string->size(); + uint32 s = S->size(); uint32 p = 0; REState *RE = NULL; const String *R = NULL; - if (separatorV.getType() == RegExp_Type) - RE = (checked_cast(separatorV.instance))->mRegExp; + if (JSValue::getType(separatorV) == RegExp_Type) + RE = (checked_cast(JSValue::instance(separatorV)))->mRegExp; else - R = separatorV.toString(cx).string; + R = JSValue::string(JSValue::toString(cx, separatorV)); if (lim == 0) return result; @@ -436,12 +437,12 @@ static JSValue String_split(Context *cx, const JSValue& thisValue, JSValue *argv if (s == 0) { MatchResult z; if (RE) - regexpSplitMatch(S.string, 0, RE, z); + regexpSplitMatch(S, 0, RE, z); else - strSplitMatch(S.string, 0, R, z); + strSplitMatch(S, 0, R, z); if (!z.failure) return result; - A->setProperty(cx, widenCString("0"), NULL, S); + A->setProperty(cx, widenCString("0"), NULL, JSValue::newString(S)); return result; } @@ -449,16 +450,16 @@ static JSValue String_split(Context *cx, const JSValue& thisValue, JSValue *argv uint32 q = p; step11: if (q == s) { - String *T = new String(*S.string, p, (s - p)); - JSValue v(T); + String *T = new String(*S, p, (s - p)); + js2val v = JSValue::newString(T); A->setProperty(cx, *numberToString(A->mLength), NULL, v); return result; } MatchResult z; if (RE) - regexpSplitMatch(S.string, q, RE, z); + regexpSplitMatch(S, q, RE, z); else - strSplitMatch(S.string, q, R, z); + strSplitMatch(S, q, R, z); if (z.failure) { q = q + 1; goto step11; @@ -468,73 +469,73 @@ step11: q = q + 1; goto step11; } - String *T = new String(*S.string, p, (q - p)); - JSValue v(T); + String *T = new String(*S, p, (q - p)); + js2val v = JSValue::newString(T); A->setProperty(cx, *numberToString(A->mLength), NULL, v); if (A->mLength == lim) return result; p = e; for (uint32 i = 0; i < z.capturesCount; i++) { - A->setProperty(cx, *numberToString(A->mLength), NULL, JSValue(z.captures[i])); + A->setProperty(cx, *numberToString(A->mLength), NULL, z.captures[i]); if (A->mLength == lim) return result; } } } -static JSValue String_charAt(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val String_charAt(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { - const String *str = thisValue.toString(cx).string; + const String *str = JSValue::string(JSValue::toString(cx, thisValue)); uint32 pos = 0; if (argc > 0) - pos = (uint32)(argv[0].toInt32(cx).f64); + pos = (uint32)JSValue::f64(JSValue::toInt32(cx, argv[0])); if ((pos < 0) || (pos >= str->size())) - return JSValue(&cx->Empty_StringAtom); + return JSValue::newString(&cx->Empty_StringAtom); else - return JSValue(new String(1, (*str)[pos])); + return JSValue::newString(new String(1, (*str)[pos])); } -static JSValue String_charCodeAt(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val String_charCodeAt(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { - const String *str = thisValue.toString(cx).string; + const String *str = JSValue::string(JSValue::toString(cx, thisValue)); uint32 pos = 0; if (argc > 0) - pos = (uint32)(argv[0].toInt32(cx).f64); + pos = (uint32)JSValue::f64(JSValue::toInt32(cx, argv[0])); if ((pos < 0) || (pos >= str->size())) return kNaNValue; else - return JSValue((float64)(*str)[pos]); + return JSValue::newNumber((float64)(*str)[pos]); } -static JSValue String_concat(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val String_concat(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { - const String *str = thisValue.toString(cx).string; + const String *str = JSValue::string(JSValue::toString(cx, thisValue)); String *result = new String(*str); for (uint32 i = 0; i < argc; i++) { - *result += *argv[i].toString(cx).string; + *result += *JSValue::string(JSValue::toString(cx, argv[i])); } - return JSValue(result); + return JSValue::newString(result); } -static JSValue String_indexOf(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val String_indexOf(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { if (argc == 0) - return JSValue(-1.0); + return JSValue::newNumber(-1.0); - const String *str = thisValue.toString(cx).string; - const String *searchStr = argv[0].toString(cx).string; + const String *str = JSValue::string(JSValue::toString(cx, thisValue)); + const String *searchStr = JSValue::string(JSValue::toString(cx, argv[0])); uint32 pos = 0; if (argc > 1) { - float64 fpos = argv[1].toNumber(cx).f64; + float64 fpos = JSValue::f64(JSValue::toNumber(cx, argv[1])); if (JSDOUBLE_IS_NaN(fpos)) pos = 0; if (fpos < 0) @@ -547,21 +548,21 @@ static JSValue String_indexOf(Context *cx, const JSValue& thisValue, JSValue *ar } pos = str->find(*searchStr, pos); if (pos == String::npos) - return JSValue(-1.0); - return JSValue((float64)pos); + return JSValue::newNumber(-1.0); + return JSValue::newNumber((float64)pos); } -static JSValue String_lastIndexOf(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val String_lastIndexOf(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { if (argc == 0) - return JSValue(-1.0); + return JSValue::newNumber(-1.0); - const String *str = thisValue.toString(cx).string; - const String *searchStr = argv[0].toString(cx).string; + const String *str = JSValue::string(JSValue::toString(cx, thisValue)); + const String *searchStr = JSValue::string(JSValue::toString(cx, argv[0])); uint32 pos = str->size(); if (argc > 1) { - float64 fpos = argv[1].toNumber(cx).f64; + float64 fpos = JSValue::f64(JSValue::toNumber(cx, argv[1])); if (JSDOUBLE_IS_NaN(fpos)) pos = str->size(); else { @@ -576,35 +577,35 @@ static JSValue String_lastIndexOf(Context *cx, const JSValue& thisValue, JSValue } pos = str->rfind(*searchStr, pos); if (pos == String::npos) - return JSValue(-1.0); - return JSValue((float64)pos); + return JSValue::newNumber(-1.0); + return JSValue::newNumber((float64)pos); } -static JSValue String_localeCompare(Context * /*cx*/, const JSValue& /*thisValue*/, JSValue * /*argv*/, uint32 /*argc*/) +static js2val String_localeCompare(Context * /*cx*/, const js2val /*thisValue*/, js2val * /*argv*/, uint32 /*argc*/) { return kUndefinedValue; } -static JSValue String_toLowerCase(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val String_toLowerCase(Context *cx, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/) { - JSValue S = thisValue.toString(cx); + js2val S = JSValue::toString(cx, thisValue); - String *result = new String(*S.string); + String *result = new String(*JSValue::string(S)); for (String::iterator i = result->begin(), end = result->end(); i != end; i++) *i = toLower(*i); - return JSValue(result); + return JSValue::newString(result); } -static JSValue String_toUpperCase(Context *cx, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/) +static js2val String_toUpperCase(Context *cx, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/) { - JSValue S = thisValue.toString(cx); + js2val S = JSValue::toString(cx, thisValue); - String *result = new String(*S.string); + String *result = new String(*JSValue::string(S)); for (String::iterator i = result->begin(), end = result->end(); i != end; i++) *i = toUpper(*i); - return JSValue(result); + return JSValue::newString(result); } /* @@ -628,15 +629,15 @@ static JSValue String_toUpperCase(Context *cx, const JSValue& thisValue, JSValue * position Result(5). */ -static JSValue String_slice(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val String_slice(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { - const String *sourceString = thisValue.toString(cx).string; + const String *sourceString = JSValue::string(JSValue::toString(cx, thisValue)); uint32 sourceLength = sourceString->size(); uint32 start, end; if (argc > 0) { - int32 arg0 = (int32)(argv[0].toInt32(cx).f64); + int32 arg0 = (int32)JSValue::f64(JSValue::toInt32(cx, argv[0])); if (arg0 < 0) { arg0 += sourceLength; if (arg0 < 0) @@ -655,7 +656,7 @@ static JSValue String_slice(Context *cx, const JSValue& thisValue, JSValue *argv start = 0; if (argc > 1) { - int32 arg1 = (int32)(argv[1].toInt32(cx).f64); + int32 arg1 = (int32)JSValue::f64(JSValue::toInt32(cx, argv[1])); if (arg1 < 0) { arg1 += sourceLength; if (arg1 < 0) @@ -674,8 +675,8 @@ static JSValue String_slice(Context *cx, const JSValue& thisValue, JSValue *argv end = sourceLength; if (start > end) - return JSValue(&cx->Empty_StringAtom); - return JSValue(new String(sourceString->substr(start, end - start))); + return JSValue::newString(&cx->Empty_StringAtom); + return JSValue::newString(new String(sourceString->substr(start, end - start))); } /* @@ -700,15 +701,15 @@ static JSValue String_slice(Context *cx, const JSValue& thisValue, JSValue *argv * Result(1), namely the characters with indices Result(7) through Result(8)-1, in ascending order. */ -static JSValue String_substring(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc) +static js2val String_substring(Context *cx, const js2val thisValue, js2val *argv, uint32 argc) { - const String *sourceString = thisValue.toString(cx).string; + const String *sourceString = JSValue::string(JSValue::toString(cx, thisValue)); uint32 sourceLength = sourceString->size(); uint32 start, end; if (argc > 0) { - float64 farg0 = argv[0].toNumber(cx).f64; + float64 farg0 = JSValue::f64(JSValue::toNumber(cx, argv[0])); if (JSDOUBLE_IS_NaN(farg0) || (farg0 < 0)) start = 0; else { @@ -725,7 +726,7 @@ static JSValue String_substring(Context *cx, const JSValue& thisValue, JSValue * start = 0; if (argc > 1) { - float64 farg1 = argv[1].toNumber(cx).f64; + float64 farg1 = JSValue::f64(JSValue::toNumber(cx, argv[1])); if (JSDOUBLE_IS_NaN(farg1) || (farg1 < 0)) end = 0; else { @@ -747,7 +748,7 @@ static JSValue String_substring(Context *cx, const JSValue& thisValue, JSValue * end = t; } - return JSValue(new String(sourceString->substr(start, end - start))); + return JSValue::newString(new String(sourceString->substr(start, end - start))); } diff --git a/mozilla/js2/src/jsstring.h b/mozilla/js2/src/jsstring.h index 191f046a6e6..186bfb46a87 100644 --- a/mozilla/js2/src/jsstring.h +++ b/mozilla/js2/src/jsstring.h @@ -35,9 +35,9 @@ namespace JavaScript { namespace JS2Runtime { - extern JSValue String_Constructor(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc); - extern JSValue String_TypeCast(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc); - extern JSValue String_fromCharCode(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc); + extern js2val String_Constructor(Context *cx, const js2val thisValue, js2val *argv, uint32 argc); + extern js2val String_TypeCast(Context *cx, const js2val thisValue, js2val *argv, uint32 argc); + extern js2val String_fromCharCode(Context *cx, const js2val thisValue, js2val *argv, uint32 argc); Context::PrototypeFunctions *getStringProtos(); diff --git a/mozilla/js2/src/numerics.cpp b/mozilla/js2/src/numerics.cpp index 5f67bf89e89..f3c3475f7f4 100644 --- a/mozilla/js2/src/numerics.cpp +++ b/mozilla/js2/src/numerics.cpp @@ -252,15 +252,15 @@ InitNumerics::InitNumerics() // had to move these here since they depend upon the values // initialized above, and we can't guarantee order other than // lexically in a single file. -JSValue JS::JS2Runtime::kUndefinedValue; -JSValue JS::JS2Runtime::kNaNValue = JSValue(nan); -JSValue JS::JS2Runtime::kTrueValue = JSValue(true); -JSValue JS::JS2Runtime::kFalseValue = JSValue(false); -JSValue JS::JS2Runtime::kNullValue = JSValue(JSValue::null_tag); -JSValue JS::JS2Runtime::kNegativeZero = JSValue(-0.0); -JSValue JS::JS2Runtime::kPositiveZero = JSValue(0.0); -JSValue JS::JS2Runtime::kNegativeInfinity = JSValue(negativeInfinity); -JSValue JS::JS2Runtime::kPositiveInfinity = JSValue(positiveInfinity); +js2val JS::JS2Runtime::kUndefinedValue = JS2VAL_VOID; +js2val JS::JS2Runtime::kNaNValue = JSValue::newNumber(nan); +js2val JS::JS2Runtime::kTrueValue = JSValue::newBoolean(true); +js2val JS::JS2Runtime::kFalseValue = JSValue::newBoolean(false); +js2val JS::JS2Runtime::kNullValue = JS2VAL_NULL; +js2val JS::JS2Runtime::kNegativeZero = JSValue::newNumber(-0.0); +js2val JS::JS2Runtime::kPositiveZero = JSValue::newNumber(0.0); +js2val JS::JS2Runtime::kNegativeInfinity = JSValue::newNumber(negativeInfinity); +js2val JS::JS2Runtime::kPositiveInfinity = JSValue::newNumber(positiveInfinity); // // Portable double-precision floating point to string and back conversions diff --git a/mozilla/js2/src/property.h b/mozilla/js2/src/property.h index 32c203737c8..e70e391fb5a 100644 --- a/mozilla/js2/src/property.h +++ b/mozilla/js2/src/property.h @@ -44,7 +44,6 @@ namespace JavaScript { namespace JS2Runtime { class JSFunction; - class JSValue; class JSType; typedef enum { ValuePointer, FunctionPair, IndexPair, Slot, Method, Constructor } PropertyFlag; @@ -52,6 +51,8 @@ namespace JS2Runtime { typedef uint32 PropertyAttribute; + typedef uint32 js2val; + class Property { public: @@ -83,7 +84,7 @@ namespace JS2Runtime { } // a generic property - Property(JSValue *p, JSType *type, PropertyAttribute attr) + Property(js2val p, JSType *type, PropertyAttribute attr) : mType(type), mAttributes(attr), mFlag(ValuePointer) { mData.vp = p; @@ -114,7 +115,7 @@ namespace JS2Runtime { union { - JSValue *vp; // straightforward value + js2val vp; // straightforward value struct { // getter & setter functions JSFunction *getterF; JSFunction *setterF; diff --git a/mozilla/js2/src/systemtypes.h b/mozilla/js2/src/systemtypes.h index 638e6d972ce..26891cf39b9 100644 --- a/mozilla/js2/src/systemtypes.h +++ b/mozilla/js2/src/systemtypes.h @@ -88,8 +88,10 @@ typedef float float32; #endif #ifdef _WIN32 +#ifndef IS_LITTLE_ENDIAN #define IS_LITTLE_ENDIAN #endif +#endif #ifdef __i386__ #define IS_LITTLE_ENDIAN #endif @@ -106,8 +108,9 @@ const uint basicAlignment = 1u<= 1) && (argv[0].isString())) { - const String& fileName = *argv[0].string; + if ((argc >= 1) && (JSValue::isString(argv[0]))) { + const String& fileName = *JSValue::string(argv[0]); cx->readEvalFile(fileName); } return kUndefinedValue; } -static JSValue print(Context * /*cx*/, const JSValue& /*thisValue*/, JSValue *argv, uint32 argc) +static js2val print(Context * /*cx*/, const js2val /*thisValue*/, js2val argv[], uint32 argc) { for (uint32 i = 0; i < argc; i++) { - stdOut << argv[i] << "\n"; + JSValue::print(stdOut, argv[i]); + stdOut << "\n"; } return kUndefinedValue; } -static JSValue version(Context * /*cx*/, const JSValue& /*thisValue*/, JSValue * /*argv*/, uint32 /*argc*/) +static js2val version(Context * /*cx*/, const js2val /*thisValue*/, js2val /*argv*/[], uint32 /*argc*/) { - return JSValue(2.0); + return JSValue::newNumber(2.0); } -static JSValue debug(Context *cx, const JSValue& /*thisValue*/, JSValue * /*argv*/, uint32 /*argc*/) +static js2val debug(Context *cx, const js2val /*thisValue*/, js2val /*argv*/[], uint32 /*argc*/) { cx->mDebugFlag = !cx->mDebugFlag; return kUndefinedValue; } -static JSValue trace(Context * /*cx*/, const JSValue& /*thisValue*/, JSValue * /*argv*/, uint32 /*argc*/) +static js2val trace(Context * /*cx*/, const js2val /*thisValue*/, js2val /*argv*/[], uint32 /*argc*/) { gTraceFlag = true; stdOut << "Will report allocation stats\n"; return kUndefinedValue; } -static JSValue dikdik(Context * /*cx*/, const JSValue& /*thisValue*/, JSValue * /*argv*/, uint32 /*argc*/) +static js2val dikdik(Context * /*cx*/, const js2val /*thisValue*/, js2val /*argv*/[], uint32 /*argc*/) { extern void do_dikdik(Formatter &f); do_dikdik(stdOut); return kUndefinedValue; } -static JSValue quit(Context * /*cx*/, const JSValue& /*thisValue*/, JSValue * /*argv*/, uint32 /*argc*/) +static js2val quit(Context * /*cx*/, const js2val /*thisValue*/, js2val /*argv*/[], uint32 /*argc*/) { exit(0); return kUndefinedValue; @@ -199,9 +200,11 @@ static int readEvalPrint(Context *cx, FILE *in) #endif bcm->setSource(buffer, ConsoleName); cx->setReader(NULL); - JSValue result = cx->interpret(bcm, 0, NULL, JSValue(cx->getGlobalObject()), NULL, 0); - if (!result.isUndefined()) - stdOut << result.toString(cx) << "\n"; + js2val result = cx->interpret(bcm, 0, NULL, JSValue::newObject(cx->getGlobalObject()), NULL, 0); + if (!JSValue::isUndefined(result)) { + JSValue::print(stdOut, JSValue::toString(cx, result)); + stdOut << "\n"; + } delete bcm; } #endif @@ -279,13 +282,13 @@ int main(int argc, char **argv) JSObject *globalObject; Context cx(&globalObject, world, a, Pragma::js2); - globalObject->defineVariable(&cx, widenCString("load"), (NamespaceList *)(NULL), Property::NoAttribute, NULL, JSValue(new JSFunction(&cx, load, NULL))); - globalObject->defineVariable(&cx, widenCString("print"), (NamespaceList *)(NULL), Property::NoAttribute, NULL, JSValue(new JSFunction(&cx, print, NULL))); - globalObject->defineVariable(&cx, widenCString("debug"), (NamespaceList *)(NULL), Property::NoAttribute, NULL, JSValue(new JSFunction(&cx, debug, NULL))); - globalObject->defineVariable(&cx, widenCString("trace"), (NamespaceList *)(NULL), Property::NoAttribute, NULL, JSValue(new JSFunction(&cx, trace, NULL))); - globalObject->defineVariable(&cx, widenCString("dikdik"), (NamespaceList *)(NULL), Property::NoAttribute, NULL, JSValue(new JSFunction(&cx, dikdik, NULL))); - globalObject->defineVariable(&cx, widenCString("version"), (NamespaceList *)(NULL), Property::NoAttribute, NULL, JSValue(new JSFunction(&cx, version, NULL))); - globalObject->defineVariable(&cx, widenCString("quit"), (NamespaceList *)(NULL), Property::NoAttribute, NULL, JSValue(new JSFunction(&cx, quit, NULL))); + globalObject->defineVariable(&cx, widenCString("load"), (NamespaceList *)(NULL), Property::NoAttribute, NULL, JSValue::newFunction(new JSFunction(&cx, load, NULL))); + globalObject->defineVariable(&cx, widenCString("print"), (NamespaceList *)(NULL), Property::NoAttribute, NULL, JSValue::newFunction(new JSFunction(&cx, print, NULL))); + globalObject->defineVariable(&cx, widenCString("debug"), (NamespaceList *)(NULL), Property::NoAttribute, NULL, JSValue::newFunction(new JSFunction(&cx, debug, NULL))); + globalObject->defineVariable(&cx, widenCString("trace"), (NamespaceList *)(NULL), Property::NoAttribute, NULL, JSValue::newFunction(new JSFunction(&cx, trace, NULL))); + globalObject->defineVariable(&cx, widenCString("dikdik"), (NamespaceList *)(NULL), Property::NoAttribute, NULL, JSValue::newFunction(new JSFunction(&cx, dikdik, NULL))); + globalObject->defineVariable(&cx, widenCString("version"), (NamespaceList *)(NULL), Property::NoAttribute, NULL, JSValue::newFunction(new JSFunction(&cx, version, NULL))); + globalObject->defineVariable(&cx, widenCString("quit"), (NamespaceList *)(NULL), Property::NoAttribute, NULL, JSValue::newFunction(new JSFunction(&cx, quit, NULL))); bool doInteractive = true; int result = 0;