diff --git a/caps/src/nsScriptSecurityManager.cpp b/caps/src/nsScriptSecurityManager.cpp index 75937d27385c..cad9d8750dda 100644 --- a/caps/src/nsScriptSecurityManager.cpp +++ b/caps/src/nsScriptSecurityManager.cpp @@ -2058,7 +2058,6 @@ nsScriptSecurityManager::old_doGetObjectPrincipal(JS::Handle aObj, JSContext* cx = nsXPConnect::XPConnect()->GetCurrentJSContext(); JS::RootedObject obj(cx, aObj); JS::RootedObject origObj(cx, obj); - js::Class *jsClass = js::GetObjectClass(obj); // A common case seen in this code is that we enter this function // with obj being a Function object, whose parent is a Call @@ -2067,28 +2066,26 @@ nsScriptSecurityManager::old_doGetObjectPrincipal(JS::Handle aObj, // avoid wasting time checking properties of their classes etc in // the loop. - if (jsClass == &js::FunctionClass) { + if (js::IsFunctionObject(obj)) { obj = js::GetObjectParent(obj); if (!obj) return nullptr; - jsClass = js::GetObjectClass(obj); - if (js::IsCallObject(obj)) { obj = js::GetObjectParentMaybeScope(obj); if (!obj) return nullptr; - - jsClass = js::GetObjectClass(obj); } } + js::Class *jsClass = js::GetObjectClass(obj); + do { // Note: jsClass is set before this loop, and also at the // *end* of this loop. - + if (IS_WN_CLASS(jsClass)) { result = nsXPConnect::XPConnect()->GetPrincipal(obj, aAllowShortCircuit); diff --git a/js/src/builtin/Eval.cpp b/js/src/builtin/Eval.cpp index c6f3e612c7e7..21dfa6960b77 100644 --- a/js/src/builtin/Eval.cpp +++ b/js/src/builtin/Eval.cpp @@ -207,8 +207,8 @@ MarkFunctionsWithinEvalScript(JSScript *script) for (size_t i = start; i < objects->length; i++) { JSObject *obj = objects->vector[i]; - if (obj->isFunction()) { - JSFunction *fun = obj->toFunction(); + if (obj->is()) { + JSFunction *fun = &obj->as(); if (fun->hasScript()) fun->nonLazyScript()->directlyInsideEval = true; else if (fun->isInterpretedLazy()) @@ -467,8 +467,9 @@ js::IsAnyBuiltinEval(JSFunction *fun) JSPrincipals * js::PrincipalsForCompiledCode(const CallReceiver &call, JSContext *cx) { - JS_ASSERT(IsAnyBuiltinEval(call.callee().toFunction()) || - IsBuiltinFunctionConstructor(call.callee().toFunction())); + JSObject &callee = call.callee(); + JS_ASSERT(IsAnyBuiltinEval(&callee.as()) || + IsBuiltinFunctionConstructor(&callee.as())); // To compute the principals of the compiled eval/Function code, we simply // use the callee's principals. To see why the caller's principals are @@ -484,5 +485,5 @@ js::PrincipalsForCompiledCode(const CallReceiver &call, JSContext *cx) // compiled code will be run with the callee's scope chain, this would make // fp->script()->compartment() != fp->compartment(). - return call.callee().compartment()->principals; + return callee.compartment()->principals; } diff --git a/js/src/builtin/Intl.cpp b/js/src/builtin/Intl.cpp index a37c9542b871..bca5a602b414 100644 --- a/js/src/builtin/Intl.cpp +++ b/js/src/builtin/Intl.cpp @@ -441,7 +441,7 @@ IntlInitialize(JSContext *cx, HandleObject obj, Handle initialize if (!cx->global()->getIntrinsicValue(cx, initializer, &initializerValue)) return false; JS_ASSERT(initializerValue.isObject()); - JS_ASSERT(initializerValue.toObject().isFunction()); + JS_ASSERT(initializerValue.toObject().is()); InvokeArgsGuard args; if (!cx->stack.pushInvokeArgs(cx, 3, &args)) @@ -507,7 +507,7 @@ GetInternals(JSContext *cx, HandleObject obj, MutableHandleObject internals) if (!cx->global()->getIntrinsicValue(cx, cx->names().getInternals, &getInternalsValue)) return false; JS_ASSERT(getInternalsValue.isObject()); - JS_ASSERT(getInternalsValue.toObject().isFunction()); + JS_ASSERT(getInternalsValue.toObject().is()); InvokeArgsGuard args; if (!cx->stack.pushInvokeArgs(cx, 1, &args)) diff --git a/js/src/builtin/ParallelArray.cpp b/js/src/builtin/ParallelArray.cpp index 802f800a4429..293bea917e32 100644 --- a/js/src/builtin/ParallelArray.cpp +++ b/js/src/builtin/ParallelArray.cpp @@ -105,8 +105,8 @@ ParallelArrayObject::getConstructor(JSContext *cx, unsigned argc) RootedValue ctorValue(cx); if (!cx->global()->getIntrinsicValue(cx, ctorName, &ctorValue)) return NULL; - JS_ASSERT(ctorValue.isObject() && ctorValue.toObject().isFunction()); - return ctorValue.toObject().toFunction(); + JS_ASSERT(ctorValue.isObject() && ctorValue.toObject().is()); + return &ctorValue.toObject().as(); } /*static*/ JSObject * diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index 4179fc5c1897..b3fcf03f9fb5 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -883,13 +883,13 @@ static JSBool DisplayName(JSContext *cx, unsigned argc, jsval *vp) { CallArgs args = CallArgsFromVp(argc, vp); - if (argc == 0 || !args[0].isObject() || !args[0].toObject().isFunction()) { + if (argc == 0 || !args[0].isObject() || !args[0].toObject().is()) { RootedObject arg(cx, &args.callee()); ReportUsageError(cx, arg, "Must have one function argument"); return false; } - JSFunction *fun = args[0].toObject().toFunction(); + JSFunction *fun = &args[0].toObject().as(); JSString *str = fun->displayAtom(); vp->setString(str == NULL ? cx->runtime()->emptyString : str); return true; @@ -928,7 +928,7 @@ SetObjectMetadataCallback(JSContext *cx, unsigned argc, jsval *vp) args.rval().setUndefined(); - if (argc == 0 || !args[0].isObject() || !args[0].toObject().isFunction()) { + if (argc == 0 || !args[0].isObject() || !args[0].toObject().is()) { if (objectMetadataFunction) JS_RemoveObjectRoot(cx, &objectMetadataFunction); objectMetadataFunction = NULL; diff --git a/js/src/frontend/ParseNode.cpp b/js/src/frontend/ParseNode.cpp index a19920dc9f8e..1953caa5c0da 100644 --- a/js/src/frontend/ParseNode.cpp +++ b/js/src/frontend/ParseNode.cpp @@ -751,7 +751,7 @@ ObjectBox::ObjectBox(JSObject *object, ObjectBox* traceLink) traceLink(traceLink), emitLink(NULL) { - JS_ASSERT(!object->isFunction()); + JS_ASSERT(!object->is()); } ObjectBox::ObjectBox(JSFunction *function, ObjectBox* traceLink) @@ -759,7 +759,7 @@ ObjectBox::ObjectBox(JSFunction *function, ObjectBox* traceLink) traceLink(traceLink), emitLink(NULL) { - JS_ASSERT(object->isFunction()); + JS_ASSERT(object->is()); JS_ASSERT(asFunctionBox()->function() == function); } diff --git a/js/src/frontend/ParseNode.h b/js/src/frontend/ParseNode.h index b526b4e1fee0..2fd4cd490843 100644 --- a/js/src/frontend/ParseNode.h +++ b/js/src/frontend/ParseNode.h @@ -1399,7 +1399,7 @@ class ObjectBox ObjectBox(JSObject *object, ObjectBox *traceLink); bool isModuleBox() { return object->is(); } - bool isFunctionBox() { return object->isFunction(); } + bool isFunctionBox() { return object->is(); } ModuleBox *asModuleBox(); FunctionBox *asFunctionBox(); void trace(JSTracer *trc); diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index 041c9569e3aa..853034c2e4df 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -2026,7 +2026,7 @@ Parser::finishFunctionDefinition(Node pn, FunctionBox *funbo lazy->setUsesArgumentsAndApply(); PropagateTransitiveParseFlags(funbox, lazy); - funbox->object->toFunction()->initLazyScript(lazy); + funbox->object->as().initLazyScript(lazy); return true; } diff --git a/js/src/frontend/SharedContext.h b/js/src/frontend/SharedContext.h index 164c40e2a028..61f3399897ef 100644 --- a/js/src/frontend/SharedContext.h +++ b/js/src/frontend/SharedContext.h @@ -226,7 +226,7 @@ class FunctionBox : public ObjectBox, public SharedContext bool strict); ObjectBox *toObjectBox() { return this; } - JSFunction *function() const { return object->toFunction(); } + JSFunction *function() const { return &object->as(); } bool isGenerator() const { return funCxFlags.isGenerator; } bool mightAliasLocals() const { return funCxFlags.mightAliasLocals; } diff --git a/js/src/gc/Nursery.cpp b/js/src/gc/Nursery.cpp index 9f00e3d09580..63cd859b9f5e 100644 --- a/js/src/gc/Nursery.cpp +++ b/js/src/gc/Nursery.cpp @@ -257,8 +257,8 @@ GetObjectAllocKindForCopy(JSRuntime *rt, JSObject *obj) return GetBackgroundAllocKind(GetGCArrayKind(nelements)); } - if (obj->isFunction()) - return obj->toFunction()->getAllocKind(); + if (obj->is()) + return obj->as().getAllocKind(); AllocKind kind = GetGCObjectFixedSlotsKind(obj->numFixedSlots()); if (CanBeFinalizedInBackground(kind, obj->getClass())) diff --git a/js/src/ion/AsmJS.cpp b/js/src/ion/AsmJS.cpp index 663b5d389943..aed9692534b5 100644 --- a/js/src/ion/AsmJS.cpp +++ b/js/src/ion/AsmJS.cpp @@ -6244,7 +6244,7 @@ IsMaybeWrappedNativeFunction(const Value &v, Native native) if (!obj) return false; - return obj->isFunction() && obj->toFunction()->maybeNative() == native; + return obj->is() && obj->as().maybeNative() == native; } JSBool diff --git a/js/src/ion/AsmJSLink.cpp b/js/src/ion/AsmJSLink.cpp index 886753edd9cb..bd0e1f500eb7 100644 --- a/js/src/ion/AsmJSLink.cpp +++ b/js/src/ion/AsmJSLink.cpp @@ -80,10 +80,10 @@ ValidateFFI(JSContext *cx, AsmJSModule::Global &global, HandleValue importVal, if (!GetProperty(cx, importVal, field, &v)) return false; - if (!v.isObject() || !v.toObject().isFunction()) + if (!v.isObject() || !v.toObject().is()) return LinkFail(cx, "FFI imports must be functions"); - (*ffis)[global.ffiIndex()] = v.toObject().toFunction(); + (*ffis)[global.ffiIndex()] = &v.toObject().as(); return true; } @@ -243,7 +243,7 @@ DynamicallyLinkModule(JSContext *cx, CallArgs args, AsmJSModule &module) } for (unsigned i = 0; i < module.numExits(); i++) - module.exitIndexToGlobalDatum(i).fun = ffis[module.exit(i).ffiIndex()]->toFunction(); + module.exitIndexToGlobalDatum(i).fun = &ffis[module.exit(i).ffiIndex()]->as(); module.setIsLinked(heap); return true; @@ -287,7 +287,7 @@ extern JSBool js::CallAsmJS(JSContext *cx, unsigned argc, Value *vp) { CallArgs callArgs = CallArgsFromVp(argc, vp); - RootedFunction callee(cx, callArgs.callee().toFunction()); + RootedFunction callee(cx, &callArgs.callee().as()); // An asm.js function stores, in its extended slots: // - a pointer to the module from which it was returned @@ -472,7 +472,7 @@ JSBool js::LinkAsmJS(JSContext *cx, unsigned argc, JS::Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); - RootedFunction fun(cx, args.callee().toFunction()); + RootedFunction fun(cx, &args.callee().as()); RootedObject moduleObj(cx, &AsmJSModuleObject(fun)); AsmJSModule &module = AsmJSModuleObjectToModule(moduleObj); diff --git a/js/src/ion/BaselineBailouts.cpp b/js/src/ion/BaselineBailouts.cpp index bcc6700d253a..aab18d9fa14b 100644 --- a/js/src/ion/BaselineBailouts.cpp +++ b/js/src/ion/BaselineBailouts.cpp @@ -913,8 +913,8 @@ InitFromBailout(JSContext *cx, HandleScript caller, jsbytecode *callerPC, Value callee = *builder.valuePointerAtStackOffset(calleeOffset); IonSpew(IonSpew_BaselineBailouts, " CalleeStackSlot=%d", (int) calleeStackSlot); IonSpew(IonSpew_BaselineBailouts, " Callee = %016llx", *((uint64_t *) &callee)); - JS_ASSERT(callee.isObject() && callee.toObject().isFunction()); - JSFunction *calleeFun = callee.toObject().toFunction(); + JS_ASSERT(callee.isObject() && callee.toObject().is()); + JSFunction *calleeFun = &callee.toObject().as(); if (!builder.writePtr(CalleeToToken(calleeFun), "CalleeToken")) return false; nextCallee.set(calleeFun); diff --git a/js/src/ion/BaselineIC.cpp b/js/src/ion/BaselineIC.cpp index 1e528409da06..a3ac9a1e87e7 100644 --- a/js/src/ion/BaselineIC.cpp +++ b/js/src/ion/BaselineIC.cpp @@ -3289,10 +3289,10 @@ IsCacheableGetPropCall(JSObject *obj, JSObject *holder, Shape *shape, bool *isSc if (!shape->hasGetterValue()) return false; - if (!shape->getterValue().isObject() || !shape->getterObject()->isFunction()) + if (!shape->getterValue().isObject() || !shape->getterObject()->is()) return false; - JSFunction *func = shape->getterObject()->toFunction(); + JSFunction *func = &shape->getterObject()->as(); if (func->isNative()) { *isScripted = false; return true; @@ -3404,10 +3404,10 @@ IsCacheableSetPropCall(JSObject *obj, JSObject *holder, Shape *shape, bool *isSc if (!shape->hasSetterValue()) return false; - if (!shape->setterValue().isObject() || !shape->setterObject()->isFunction()) + if (!shape->setterValue().isObject() || !shape->setterObject()->is()) return false; - JSFunction *func = shape->setterObject()->toFunction(); + JSFunction *func = &shape->setterObject()->as(); if (func->isNative()) { *isScripted = false; return true; @@ -5297,7 +5297,7 @@ TryAttachNativeGetPropStub(JSContext *cx, HandleScript script, jsbytecode *pc, // Try handling scripted getters. if (cacheableCall && isScripted && !isDOMProxy) { - RootedFunction callee(cx, shape->getterObject()->toFunction()); + RootedFunction callee(cx, &shape->getterObject()->as()); JS_ASSERT(obj != holder); JS_ASSERT(callee->hasScript()); @@ -5317,7 +5317,7 @@ TryAttachNativeGetPropStub(JSContext *cx, HandleScript script, jsbytecode *pc, // Try handling JSNative getters. if (cacheableCall && !isScripted) { - RootedFunction callee(cx, shape->getterObject()->toFunction()); + RootedFunction callee(cx, &shape->getterObject()->as()); JS_ASSERT(obj != holder); JS_ASSERT(callee->isNative()); @@ -6227,7 +6227,7 @@ TryAttachSetPropStub(JSContext *cx, HandleScript script, jsbytecode *pc, ICSetPr // Try handling scripted setters. if (cacheableCall && isScripted) { - RootedFunction callee(cx, shape->setterObject()->toFunction()); + RootedFunction callee(cx, &shape->setterObject()->as()); JS_ASSERT(obj != holder); JS_ASSERT(callee->hasScript()); @@ -6246,7 +6246,7 @@ TryAttachSetPropStub(JSContext *cx, HandleScript script, jsbytecode *pc, ICSetPr // Try handling JSNative setters. if (cacheableCall && !isScripted) { - RootedFunction callee(cx, shape->setterObject()->toFunction()); + RootedFunction callee(cx, &shape->setterObject()->as()); JS_ASSERT(obj != holder); JS_ASSERT(callee->isNative()); @@ -6788,9 +6788,9 @@ TryAttachFunApplyStub(JSContext *cx, ICCall_Fallback *stub, HandleScript script, if (argc != 2) return true; - if (!thisv.isObject() || !thisv.toObject().isFunction()) + if (!thisv.isObject() || !thisv.toObject().is()) return true; - RootedFunction target(cx, thisv.toObject().toFunction()); + RootedFunction target(cx, &thisv.toObject().as()); // right now, only handle situation where second argument is |arguments| if (argv[1].isMagic(JS_OPTIMIZED_ARGUMENTS) && !script->needsArgsObj()) { @@ -6836,10 +6836,10 @@ TryAttachCallStub(JSContext *cx, ICCall_Fallback *stub, HandleScript script, jsb return true; RootedObject obj(cx, &callee.toObject()); - if (!obj->isFunction()) + if (!obj->is()) return true; - RootedFunction fun(cx, obj->toFunction()); + RootedFunction fun(cx, &obj->as()); if (fun->hasScript()) { // Never attach optimized scripted call stubs for JSOP_FUNAPPLY. @@ -7081,7 +7081,8 @@ ICCallStubCompiler::guardFunApply(MacroAssembler &masm, GeneralRegisterSet regs, masm.branchTestObject(Assembler::NotEqual, val, failure); Register callee = masm.extractObject(val, ExtractTemp1); - masm.branchTestObjClass(Assembler::NotEqual, callee, regs.getAny(), &FunctionClass, failure); + masm.branchTestObjClass(Assembler::NotEqual, callee, regs.getAny(), &JSFunction::class_, + failure); masm.loadPtr(Address(callee, JSFunction::offsetOfNativeOrScript()), callee); masm.branchPtr(Assembler::NotEqual, callee, ImmWord((void*) js_fun_apply), failure); @@ -7096,7 +7097,8 @@ ICCallStubCompiler::guardFunApply(MacroAssembler &masm, GeneralRegisterSet regs, regs.add(val); regs.takeUnchecked(target); - masm.branchTestObjClass(Assembler::NotEqual, target, regs.getAny(), &FunctionClass, failure); + masm.branchTestObjClass(Assembler::NotEqual, target, regs.getAny(), &JSFunction::class_, + failure); if (checkNative) { masm.branchIfInterpreted(target, failure); @@ -7250,7 +7252,8 @@ ICCallScriptedCompiler::generateStubCode(MacroAssembler &masm) // Ensure callee is a function. Register callee = masm.extractObject(R1, ExtractTemp0); - masm.branchTestObjClass(Assembler::NotEqual, callee, regs.getAny(), &FunctionClass, &failure); + masm.branchTestObjClass(Assembler::NotEqual, callee, regs.getAny(), &JSFunction::class_, + &failure); // If calling a specific script, check if the script matches. Otherwise, ensure that // callee function is scripted. Leave calleeScript in |callee| reg. diff --git a/js/src/ion/CodeGenerator.cpp b/js/src/ion/CodeGenerator.cpp index f9d05c77f03b..b4ab818a7616 100644 --- a/js/src/ion/CodeGenerator.cpp +++ b/js/src/ion/CodeGenerator.cpp @@ -1552,7 +1552,7 @@ CodeGenerator::visitCallGeneric(LCallGeneric *call) // Guard that calleereg is actually a function object. masm.loadObjClass(calleereg, nargsreg); - masm.cmpPtr(nargsreg, ImmWord(&js::FunctionClass)); + masm.cmpPtr(nargsreg, ImmWord(&JSFunction::class_)); if (!bailoutIf(Assembler::NotEqual, call->snapshot())) return false; @@ -1875,7 +1875,7 @@ CodeGenerator::visitApplyArgsGeneric(LApplyArgsGeneric *apply) // Unless already known, guard that calleereg is actually a function object. if (!apply->hasSingleTarget()) { masm.loadObjClass(calleereg, objreg); - masm.cmpPtr(objreg, ImmWord(&js::FunctionClass)); + masm.cmpPtr(objreg, ImmWord(&JSFunction::class_)); if (!bailoutIf(Assembler::NotEqual, apply->snapshot())) return false; } @@ -6789,9 +6789,9 @@ CodeGenerator::visitIsCallable(LIsCallable *ins) masm.loadObjClass(object, output); - // An object is callable iff (isFunction() || getClass()->call). + // An object is callable iff (is() || getClass()->call). Label notFunction, done; - masm.branchPtr(Assembler::NotEqual, output, ImmWord(&js::FunctionClass), ¬Function); + masm.branchPtr(Assembler::NotEqual, output, ImmWord(&JSFunction::class_), ¬Function); masm.move32(Imm32(1), output); masm.jump(&done); diff --git a/js/src/ion/Ion.cpp b/js/src/ion/Ion.cpp index f356bcfd7473..2ac4a1c2215a 100644 --- a/js/src/ion/Ion.cpp +++ b/js/src/ion/Ion.cpp @@ -1862,7 +1862,7 @@ ion::SetEnterJitData(JSContext *cx, EnterJitData &data, RunState &state, AutoVal data.numActualArgs = args.length(); data.maxArgc = Max(args.length(), numFormals) + 1; data.scopeChain = NULL; - data.calleeToken = CalleeToToken(args.callee().toFunction()); + data.calleeToken = CalleeToToken(&args.callee().as()); if (data.numActualArgs >= numFormals) { data.maxArgv = args.base() + 1; diff --git a/js/src/ion/IonBuilder.cpp b/js/src/ion/IonBuilder.cpp index 749d8548631f..9a67087e658b 100644 --- a/js/src/ion/IonBuilder.cpp +++ b/js/src/ion/IonBuilder.cpp @@ -153,10 +153,10 @@ IonBuilder::getSingleCallTarget(types::StackTypeSet *calleeTypes) return NULL; JSObject *obj = calleeTypes->getSingleton(); - if (!obj || !obj->isFunction()) + if (!obj || !obj->is()) return NULL; - return obj->toFunction(); + return &obj->as(); } bool @@ -185,12 +185,15 @@ IonBuilder::getPolyCallTargets(types::StackTypeSet *calleeTypes, for(unsigned i = 0; i < objCount; i++) { JSObject *obj = calleeTypes->getSingleObject(i); if (obj) { - if (!obj->isFunction()) { + if (!obj->is()) { targets.clear(); return true; } - if (obj->toFunction()->isInterpreted() && !obj->toFunction()->getOrCreateScript(cx)) + if (obj->as().isInterpreted() && + !obj->as().getOrCreateScript(cx)) + { return false; + } DebugOnly appendOk = targets.append(obj); JS_ASSERT(appendOk); } else { @@ -3655,7 +3658,7 @@ IonBuilder::selectInliningTargets(AutoObjectVector &targets, CallInfo &callInfo, if (!choiceSet.reserve(targets.length())) return false; for (size_t i = 0; i < targets.length(); i++) { - JSFunction *target = targets[i]->toFunction(); + JSFunction *target = &targets[i]->as(); bool inlineable = makeInliningDecision(target, callInfo); // Enforce a maximum inlined bytecode limit at the callsite. @@ -3890,7 +3893,7 @@ IonBuilder::inlineCallsite(AutoObjectVector &targets, AutoObjectVector &original // Inline single targets -- unless they derive from a cache, in which case // avoiding the cache and guarding is still faster. if (!propCache && targets.length() == 1) { - JSFunction *target = targets[0]->toFunction(); + JSFunction *target = &targets[0]->as(); if (!makeInliningDecision(target, callInfo)) return InliningStatus_NotInlined; @@ -4126,7 +4129,7 @@ IonBuilder::inlineCalls(CallInfo &callInfo, AutoObjectVector &targets, // Inline each of the inlineable targets. JS_ASSERT(targets.length() == originals.length()); for (uint32_t i = 0; i < targets.length(); i++) { - JSFunction *target = targets[i]->toFunction(); + JSFunction *target = &targets[i]->as(); // Target must be inlineable. if (!choiceSet[i]) @@ -4145,7 +4148,7 @@ IonBuilder::inlineCalls(CallInfo &callInfo, AutoObjectVector &targets, // Create a function MConstant to use in the entry ResumePoint. // Note that guarding is on the original function pointer even // if there is a clone, since cloning occurs at the callsite. - JSFunction *original = originals[i]->toFunction(); + JSFunction *original = &originals[i]->as(); MConstant *funcDef = MConstant::New(ObjectValue(*original)); funcDef->setFoldedUnchecked(); dispatchBlock->add(funcDef); @@ -4239,7 +4242,7 @@ IonBuilder::inlineCalls(CallInfo &callInfo, AutoObjectVector &targets, if (choiceSet[i]) continue; - remaining = targets[i]->toFunction(); + remaining = &targets[i]->as(); clonedAtCallsite = targets[i] != originals[i]; break; } @@ -4481,8 +4484,8 @@ IonBuilder::anyFunctionIsCloneAtCallsite(types::StackTypeSet *funTypes) for (uint32_t i = 0; i < count; i++) { JSObject *obj = funTypes->getSingleObject(i); - if (obj->isFunction() && obj->toFunction()->isInterpreted() && - obj->toFunction()->nonLazyScript()->shouldCloneAtCallsite) + if (obj->is() && obj->as().isInterpreted() && + obj->as().nonLazyScript()->shouldCloneAtCallsite) { return true; } @@ -4730,7 +4733,7 @@ IonBuilder::jsop_call(uint32_t argc, bool constructing) RootedFunction fun(cx); RootedScript scriptRoot(cx, script()); for (uint32_t i = 0; i < originals.length(); i++) { - fun = originals[i]->toFunction(); + fun = &originals[i]->as(); if (fun->isInterpreted() && fun->nonLazyScript()->shouldCloneAtCallsite) { fun = CloneFunctionAtCallsite(cx, fun, scriptRoot, pc); if (!fun) @@ -4758,7 +4761,7 @@ IonBuilder::jsop_call(uint32_t argc, bool constructing) // No inline, just make the call. RootedFunction target(cx, NULL); if (targets.length() == 1) - target = targets[0]->toFunction(); + target = &targets[0]->as(); return makeCall(target, callInfo, hasClones); } @@ -7273,7 +7276,7 @@ IonBuilder::TestCommonPropFunc(JSContext *cx, types::StackTypeSet *types, Handle // Save the first seen, or verify uniqueness. if (!found) { - if (!curFound->isFunction()) + if (!curFound->is()) return true; found = curFound; } else if (found != curFound) { @@ -7383,7 +7386,7 @@ IonBuilder::TestCommonPropFunc(JSContext *cx, types::StackTypeSet *types, Handle } } - *funcp = found->toFunction(); + *funcp = &found->as(); *isDOM = types->isDOMClass(); return true; @@ -7444,7 +7447,7 @@ IonBuilder::annotateGetPropertyCache(JSContext *cx, MDefinition *obj, MGetProper return false; JSObject *obj = protoTypes->getSingleton(cx); - if (!obj || !obj->isFunction()) + if (!obj || !obj->is()) continue; bool knownConstant = false; @@ -7455,7 +7458,7 @@ IonBuilder::annotateGetPropertyCache(JSContext *cx, MDefinition *obj, MGetProper if (!pushedTypes->hasType(types::Type::ObjectType(obj))) continue; - if (!inlinePropTable->addEntry(typeObj, obj->toFunction())) + if (!inlinePropTable->addEntry(typeObj, &obj->as())) return false; } @@ -8471,7 +8474,7 @@ IonBuilder::jsop_instanceof() do { types::StackTypeSet *rhsTypes = rhs->resultTypeSet(); JSObject *rhsObject = rhsTypes ? rhsTypes->getSingleton() : NULL; - if (!rhsObject || !rhsObject->isFunction() || rhsObject->isBoundFunction()) + if (!rhsObject || !rhsObject->is() || rhsObject->isBoundFunction()) break; types::TypeObject *rhsType = rhsObject->getType(cx); diff --git a/js/src/ion/IonCaches.cpp b/js/src/ion/IonCaches.cpp index b88c6d528213..5bda785ca1ec 100644 --- a/js/src/ion/IonCaches.cpp +++ b/js/src/ion/IonCaches.cpp @@ -594,8 +594,8 @@ IsCacheableGetPropCallNative(JSObject *obj, JSObject *holder, Shape *shape) if (!shape->hasGetterValue() || !shape->getterValue().isObject()) return false; - return shape->getterValue().toObject().isFunction() && - shape->getterValue().toObject().toFunction()->isNative(); + return shape->getterValue().toObject().is() && + shape->getterValue().toObject().as().isNative(); } static bool @@ -890,8 +890,8 @@ GenerateCallGetter(JSContext *cx, IonScript *ion, MacroAssembler &masm, if (callNative) { JS_ASSERT(shape->hasGetterValue() && shape->getterValue().isObject() && - shape->getterValue().toObject().isFunction()); - JSFunction *target = shape->getterValue().toObject().toFunction(); + shape->getterValue().toObject().is()); + JSFunction *target = &shape->getterValue().toObject().as(); JS_ASSERT(target); JS_ASSERT(target->isNative()); @@ -3053,7 +3053,7 @@ CallsiteCloneIC::update(JSContext *cx, size_t cacheIndex, HandleObject callee) // Act as the identity for functions that are not clone-at-callsite, as we // generate this cache as long as some callees are clone-at-callsite. - RootedFunction fun(cx, callee->toFunction()); + RootedFunction fun(cx, &callee->as()); if (!fun->hasScript() || !fun->nonLazyScript()->shouldCloneAtCallsite) return fun; diff --git a/js/src/ion/IonFrames.cpp b/js/src/ion/IonFrames.cpp index 1661915939ca..6aee6f68d612 100644 --- a/js/src/ion/IonFrames.cpp +++ b/js/src/ion/IonFrames.cpp @@ -1275,7 +1275,7 @@ InlineFrameIteratorMaybeGC::findNextFrame() si_.nextFrame(); - callee_ = funval.toObject().toFunction(); + callee_ = &funval.toObject().as(); // Inlined functions may be clones that still point to the lazy script // for the executed script, if they are clones. The actual script diff --git a/js/src/ion/MCallOptimize.cpp b/js/src/ion/MCallOptimize.cpp index 217cb678a249..eb92e7441d9b 100644 --- a/js/src/ion/MCallOptimize.cpp +++ b/js/src/ion/MCallOptimize.cpp @@ -1109,8 +1109,8 @@ IonBuilder::inlineNewParallelArray(CallInfo &callInfo) types::StackTypeSet *ctorTypes = callInfo.getArg(0)->resultTypeSet(); JSObject *targetObj = ctorTypes ? ctorTypes->getSingleton() : NULL; RootedFunction target(cx); - if (targetObj && targetObj->isFunction()) - target = targetObj->toFunction(); + if (targetObj && targetObj->is()) + target = &targetObj->as(); if (target && target->isInterpreted() && target->nonLazyScript()->shouldCloneAtCallsite) { RootedScript scriptRoot(cx, script()); target = CloneFunctionAtCallsite(cx, target, scriptRoot, pc); diff --git a/js/src/ion/MIR.cpp b/js/src/ion/MIR.cpp index cf8fba7eb16a..9054d0e3f664 100644 --- a/js/src/ion/MIR.cpp +++ b/js/src/ion/MIR.cpp @@ -413,8 +413,8 @@ MConstant::printOpcode(FILE *fp) fprintf(fp, "%f", value().toDouble()); break; case MIRType_Object: - if (value().toObject().isFunction()) { - JSFunction *fun = value().toObject().toFunction(); + if (value().toObject().is()) { + JSFunction *fun = &value().toObject().as(); if (fun->displayAtom()) { fputs("function ", fp); FileEscapedString(fp, fun->displayAtom(), 0); @@ -2223,7 +2223,7 @@ InlinePropertyTable::trimTo(AutoObjectVector &targets, Vector &choiceSet) if (choiceSet[i]) continue; - JSFunction *target = targets[i]->toFunction(); + JSFunction *target = &targets[i]->as(); // Eliminate all entries containing the vetoed function from the map. size_t j = 0; @@ -2251,7 +2251,7 @@ InlinePropertyTable::trimToAndMaybePatchTargets(AutoObjectVector &targets, for (size_t j = 0; j < originals.length(); j++) { if (entries_[i]->func == originals[j]) { if (entries_[i]->func != targets[j]) - entries_[i] = new Entry(entries_[i]->typeObj, targets[j]->toFunction()); + entries_[i] = new Entry(entries_[i]->typeObj, &targets[j]->as()); foundFunc = true; break; } diff --git a/js/src/ion/MIR.h b/js/src/ion/MIR.h index a3e8b857a943..1c6dcf021619 100644 --- a/js/src/ion/MIR.h +++ b/js/src/ion/MIR.h @@ -5863,7 +5863,7 @@ class MPolyInlineDispatch : public MControlInstruction, public SingleObjectPolic } JSFunction *getFunction(size_t i) const { - return getFunctionConstant(i)->value().toObject().toFunction(); + return &getFunctionConstant(i)->value().toObject().as(); } MBasicBlock *getFunctionBlock(size_t i) const { diff --git a/js/src/ion/ParallelArrayAnalysis.cpp b/js/src/ion/ParallelArrayAnalysis.cpp index f8ce772a1a37..184bf2998d54 100644 --- a/js/src/ion/ParallelArrayAnalysis.cpp +++ b/js/src/ion/ParallelArrayAnalysis.cpp @@ -843,8 +843,8 @@ GetPossibleCallees(JSContext *cx, RootedScript rootedScript(cx); for (unsigned i = 0; i < objCount; i++) { JSObject *obj = calleeTypes->getSingleObject(i); - if (obj && obj->isFunction()) { - rootedFun = obj->toFunction(); + if (obj && obj->is()) { + rootedFun = &obj->as(); } else { types::TypeObject *typeObj = calleeTypes->getTypeObject(i); if (!typeObj) diff --git a/js/src/ion/ParallelFunctions.cpp b/js/src/ion/ParallelFunctions.cpp index d421eee9f4de..bf4c34c0f26d 100644 --- a/js/src/ion/ParallelFunctions.cpp +++ b/js/src/ion/ParallelFunctions.cpp @@ -436,12 +436,12 @@ ion::ParCallToUncompiledScript(JSFunction *func) Spew(SpewBailouts, "Call to uncompiled lazy script"); } else if (func->isBoundFunction()) { int depth = 0; - JSFunction *target = func->getBoundFunctionTarget()->toFunction(); + JSFunction *target = &func->getBoundFunctionTarget()->as(); while (depth < max_bound_function_unrolling) { if (target->hasScript()) break; if (target->isBoundFunction()) - target = target->getBoundFunctionTarget()->toFunction(); + target = &target->getBoundFunctionTarget()->as(); depth--; } if (target->hasScript()) { diff --git a/js/src/ion/VMFunctions.cpp b/js/src/ion/VMFunctions.cpp index 14925fde3baf..968f8f1b4b95 100644 --- a/js/src/ion/VMFunctions.cpp +++ b/js/src/ion/VMFunctions.cpp @@ -519,8 +519,8 @@ CreateThis(JSContext *cx, HandleObject callee, MutableHandleValue rval) { rval.set(MagicValue(JS_IS_CONSTRUCTING)); - if (callee->isFunction()) { - JSFunction *fun = callee->toFunction(); + if (callee->is()) { + JSFunction *fun = &callee->as(); if (fun->isInterpreted()) { JSScript *script = fun->getOrCreateScript(cx); if (!script || !script->ensureHasTypes(cx)) diff --git a/js/src/jsapi-tests/testLookup.cpp b/js/src/jsapi-tests/testLookup.cpp index 9776afd71099..6ac7ad90bf83 100644 --- a/js/src/jsapi-tests/testLookup.cpp +++ b/js/src/jsapi-tests/testLookup.cpp @@ -30,7 +30,7 @@ BEGIN_TEST(testLookup_bug522590) CHECK(JS_LookupProperty(cx, xobj, "f", r.address())); CHECK(r.isObject()); JSObject *funobj = &r.toObject(); - CHECK(funobj->isFunction()); + CHECK(funobj->is()); CHECK(!js::IsInternalFunctionObject(funobj)); return true; diff --git a/js/src/jsapi-tests/testOriginPrincipals.cpp b/js/src/jsapi-tests/testOriginPrincipals.cpp index 0b03014bff1a..779ec7a2ee27 100644 --- a/js/src/jsapi-tests/testOriginPrincipals.cpp +++ b/js/src/jsapi-tests/testOriginPrincipals.cpp @@ -87,7 +87,7 @@ testInner(const char *asciiChars, JSPrincipals *principal, JSPrincipals *originP JS::RootedValue rval(cx); CHECK(eval(asciiChars, principal, originPrincipal, rval.address())); - JSScript *script = JS_GetFunctionScript(cx, JSVAL_TO_OBJECT(rval)->toFunction()); + JSScript *script = JS_GetFunctionScript(cx, &rval.toObject().as()); CHECK(JS_GetScriptPrincipals(script) == principal); CHECK(JS_GetScriptOriginPrincipals(script) == originPrincipal); diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 4ca8eefd4673..713406cfaaa6 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -371,7 +371,7 @@ JS_ConvertArgumentsVA(JSContext *cx, unsigned argc, jsval *argv, const char *for if (!obj) return JS_FALSE; *sp = OBJECT_TO_JSVAL(obj); - *va_arg(ap, JSFunction **) = obj->toFunction(); + *va_arg(ap, JSFunction **) = &obj->as(); break; case 'v': *va_arg(ap, jsval *) = *sp; @@ -1806,7 +1806,7 @@ StdNameToPropertyName(JSContext *cx, const JSStdName *stdn) * If you add a "standard" class, remember to update this table. */ static const JSStdName standard_class_atoms[] = { - {js_InitFunctionClass, EAGER_ATOM_AND_CLASP(Function)}, + {js_InitFunctionClass, EAGER_CLASS_ATOM(Function), &JSFunction::class_}, {js_InitObjectClass, EAGER_ATOM_AND_CLASP(Object)}, {js_InitArrayClass, EAGER_ATOM_AND_CLASP(Array)}, {js_InitBooleanClass, EAGER_ATOM_AND_OCLASP(Boolean)}, @@ -2506,21 +2506,14 @@ JS_GetTraceThingInfo(char *buf, size_t bufsize, JSTracer *trc, void *thing, case JSTRACE_OBJECT: { JSObject *obj = (JSObject *)thing; - Class *clasp = obj->getClass(); - if (clasp == &FunctionClass) { - JSFunction *fun = obj->toFunction(); - if (!fun) { - JS_snprintf(buf, bufsize, " "); - } else if (fun != obj) { - JS_snprintf(buf, bufsize, " %p", fun); - } else { - if (fun->displayAtom()) { - *buf++ = ' '; - bufsize--; - PutEscapedString(buf, bufsize, fun->displayAtom(), 0); - } + if (obj->is()) { + JSFunction *fun = &obj->as(); + if (fun->displayAtom()) { + *buf++ = ' '; + bufsize--; + PutEscapedString(buf, bufsize, fun->displayAtom(), 0); } - } else if (clasp->flags & JSCLASS_HAS_PRIVATE) { + } else if (obj->getClass()->flags & JSCLASS_HAS_PRIVATE) { JS_snprintf(buf, bufsize, " %p", obj->getPrivate()); } else { JS_snprintf(buf, bufsize, " "); @@ -3355,7 +3348,7 @@ JS_NewObject(JSContext *cx, JSClass *jsclasp, JSObject *protoArg, JSObject *pare if (!clasp) clasp = &ObjectClass; /* default class is Object */ - JS_ASSERT(clasp != &FunctionClass); + JS_ASSERT(clasp != &JSFunction::class_); JS_ASSERT(!(clasp->flags & JSCLASS_IS_GLOBAL)); JSObject *obj = NewObjectWithClassProto(cx, clasp, proto, parent); @@ -3385,7 +3378,7 @@ JS_NewObjectWithGivenProto(JSContext *cx, JSClass *jsclasp, JSObject *protoArg, if (!clasp) clasp = &ObjectClass; /* default class is Object */ - JS_ASSERT(clasp != &FunctionClass); + JS_ASSERT(clasp != &JSFunction::class_); JS_ASSERT(!(clasp->flags & JSCLASS_IS_GLOBAL)); JSObject *obj = NewObjectWithGivenProto(cx, clasp, proto, parent); @@ -4798,7 +4791,7 @@ JS_CloneFunctionObject(JSContext *cx, JSObject *funobjArg, JSObject *parentArg) if (!parent) parent = cx->global(); - if (!funobj->isFunction()) { + if (!funobj->is()) { AutoCompartment ac(cx, funobj); ReportIsNotFunction(cx, ObjectValue(*funobj)); return NULL; @@ -4808,7 +4801,7 @@ JS_CloneFunctionObject(JSContext *cx, JSObject *funobjArg, JSObject *parentArg) * If a function was compiled to be lexically nested inside some other * script, we cannot clone it without breaking the compiler's assumptions. */ - RootedFunction fun(cx, funobj->toFunction()); + RootedFunction fun(cx, &funobj->as()); if (fun->isInterpretedLazy()) { AutoCompartment ac(cx, funobj); if (!fun->getOrCreateScript(cx)) @@ -4861,7 +4854,7 @@ JS_GetFunctionArity(JSFunction *fun) JS_PUBLIC_API(JSBool) JS_ObjectIsFunction(JSContext *cx, JSObject *obj) { - return obj->isFunction(); + return obj->is(); } JS_PUBLIC_API(JSBool) @@ -4873,9 +4866,9 @@ JS_ObjectIsCallable(JSContext *cx, JSObject *obj) JS_PUBLIC_API(JSBool) JS_IsNativeFunction(JSObject *funobj, JSNative call) { - if (!funobj->isFunction()) + if (!funobj->is()) return false; - JSFunction *fun = funobj->toFunction(); + JSFunction *fun = &funobj->as(); return fun->isNative() && fun->native() == call; } @@ -4899,7 +4892,7 @@ js_generic_native_method_dispatcher(JSContext *cx, unsigned argc, Value *vp) CallArgs args = CallArgsFromVp(argc, vp); const JSFunctionSpec *fs = (JSFunctionSpec *) - vp->toObject().toFunction()->getExtendedSlot(0).toPrivate(); + vp->toObject().as().getExtendedSlot(0).toPrivate(); JS_ASSERT((fs->flags & JSFUN_GENERIC_NATIVE) != 0); if (argc < 1) { diff --git a/js/src/jsarray.cpp b/js/src/jsarray.cpp index 67f61619fbf7..b60cb97afe7d 100644 --- a/js/src/jsarray.cpp +++ b/js/src/jsarray.cpp @@ -1521,10 +1521,10 @@ MatchNumericComparator(JSContext *cx, const Value &v) return Match_None; JSObject &obj = v.toObject(); - if (!obj.isFunction()) + if (!obj.is()) return Match_None; - JSFunction *fun = obj.toFunction(); + JSFunction *fun = &obj.as(); if (!fun->isInterpreted()) return Match_None; diff --git a/js/src/jscntxt.cpp b/js/src/jscntxt.cpp index 9ca6e5ff8015..e0a9e9367190 100644 --- a/js/src/jscntxt.cpp +++ b/js/src/jscntxt.cpp @@ -1035,7 +1035,7 @@ js_ReportMissingArg(JSContext *cx, HandleValue v, unsigned arg) JS_snprintf(argbuf, sizeof argbuf, "%u", arg); bytes = NULL; if (IsFunctionObject(v)) { - atom = v.toObject().toFunction()->atom(); + atom = v.toObject().as().atom(); bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, atom); if (!bytes) diff --git a/js/src/jscntxtinlines.h b/js/src/jscntxtinlines.h index bfae55b9969a..ea2c3f195254 100644 --- a/js/src/jscntxtinlines.h +++ b/js/src/jscntxtinlines.h @@ -395,7 +395,7 @@ CallJSNativeConstructor(JSContext *cx, Native native, const CallArgs &args) JS_ASSERT_IF(native != FunctionProxyClass.construct && native != js::CallOrConstructBoundFunction && native != js::IteratorConstructor && - (!callee->isFunction() || callee->toFunction()->native() != obj_construct), + (!callee->is() || callee->as().native() != obj_construct), !args.rval().isPrimitive() && callee != &args.rval().toObject()); return true; diff --git a/js/src/jscompartment.cpp b/js/src/jscompartment.cpp index 09013e3a0a84..29ace433fcce 100644 --- a/js/src/jscompartment.cpp +++ b/js/src/jscompartment.cpp @@ -613,7 +613,7 @@ AddInnerLazyFunctionsFromScript(JSScript *script, AutoObjectVector &lazyFunction ObjectArray *objects = script->objects(); for (size_t i = script->innerObjectsStart(); i < objects->length; i++) { JSObject *obj = objects->vector[i]; - if (obj->isFunction() && obj->toFunction()->isInterpretedLazy()) { + if (obj->is() && obj->as().isInterpretedLazy()) { if (!lazyFunctions.append(obj)) return false; } @@ -631,8 +631,8 @@ CreateLazyScriptsForCompartment(JSContext *cx) // been compiled. for (gc::CellIter i(cx->zone(), JSFunction::FinalizeKind); !i.done(); i.next()) { JSObject *obj = i.get(); - if (obj->compartment() == cx->compartment() && obj->isFunction()) { - JSFunction *fun = obj->toFunction(); + if (obj->compartment() == cx->compartment() && obj->is()) { + JSFunction *fun = &obj->as(); if (fun->isInterpretedLazy()) { LazyScript *lazy = fun->lazyScriptOrNull(); if (lazy && lazy->sourceObject() && !lazy->maybeScript()) { @@ -647,7 +647,7 @@ CreateLazyScriptsForCompartment(JSContext *cx) // process with any newly exposed inner functions in created scripts. // A function cannot be delazified until its outer script exists. for (size_t i = 0; i < lazyFunctions.length(); i++) { - JSFunction *fun = lazyFunctions[i]->toFunction(); + JSFunction *fun = &lazyFunctions[i]->as(); // lazyFunctions may have been populated with multiple functions for // a lazy script. @@ -664,8 +664,8 @@ CreateLazyScriptsForCompartment(JSContext *cx) // Repoint any clones of the original functions to their new script. for (gc::CellIter i(cx->zone(), JSFunction::FinalizeKind); !i.done(); i.next()) { JSObject *obj = i.get(); - if (obj->compartment() == cx->compartment() && obj->isFunction()) { - JSFunction *fun = obj->toFunction(); + if (obj->compartment() == cx->compartment() && obj->is()) { + JSFunction *fun = &obj->as(); if (fun->isInterpretedLazy()) { LazyScript *lazy = fun->lazyScriptOrNull(); if (lazy && lazy->maybeScript()) diff --git a/js/src/jsexn.cpp b/js/src/jsexn.cpp index b205a46effa5..fae979872194 100644 --- a/js/src/jsexn.cpp +++ b/js/src/jsexn.cpp @@ -596,7 +596,7 @@ Exception(JSContext *cx, unsigned argc, Value *vp) lineno = iter.done() ? 0 : PCToLineNumber(script, iter.pc(), &column); } - int exnType = args.callee().toFunction()->getExtendedSlot(0).toInt32(); + int exnType = args.callee().as().getExtendedSlot(0).toInt32(); if (!InitExnPrivate(cx, obj, message, filename, lineno, column, NULL, exnType)) return false; diff --git a/js/src/jsfriendapi.cpp b/js/src/jsfriendapi.cpp index 431daa95cc49..a31bf17a9000 100644 --- a/js/src/jsfriendapi.cpp +++ b/js/src/jsfriendapi.cpp @@ -86,8 +86,8 @@ JS_FindCompilationScope(JSContext *cx, JSObject *objArg) JS_FRIEND_API(JSFunction *) JS_GetObjectFunction(JSObject *obj) { - if (obj->isFunction()) - return obj->toFunction(); + if (obj->is()) + return &obj->as(); return NULL; } @@ -347,6 +347,12 @@ js::IsAtomsCompartment(JSCompartment *comp) return comp == comp->rt->atomsCompartment; } +JS_FRIEND_API(bool) +js::IsFunctionObject(JSObject *obj) +{ + return obj->is(); +} + JS_FRIEND_API(bool) js::IsScopeObject(JSObject *obj) { @@ -491,15 +497,15 @@ js::InitClassWithReserved(JSContext *cx, JSObject *objArg, JSObject *parent_prot JS_FRIEND_API(const Value &) js::GetFunctionNativeReserved(JSObject *fun, size_t which) { - JS_ASSERT(fun->toFunction()->isNative()); - return fun->toFunction()->getExtendedSlot(which); + JS_ASSERT(fun->as().isNative()); + return fun->as().getExtendedSlot(which); } JS_FRIEND_API(void) js::SetFunctionNativeReserved(JSObject *fun, size_t which, const Value &val) { - JS_ASSERT(fun->toFunction()->isNative()); - fun->toFunction()->setExtendedSlot(which, val); + JS_ASSERT(fun->as().isNative()); + fun->as().setExtendedSlot(which, val); } JS_FRIEND_API(void) diff --git a/js/src/jsfriendapi.h b/js/src/jsfriendapi.h index 59914d126c35..bb9017b615a9 100644 --- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -378,7 +378,10 @@ struct Atom { } /* namespace shadow */ -extern JS_FRIEND_DATA(js::Class) FunctionClass; +// This is equal to JSFunction::class_. Use it in places where you don't want +// to #include jsfun.h. +extern JS_FRIEND_DATA(js::Class*) FunctionClassPtr; + extern JS_FRIEND_DATA(js::Class) FunctionProxyClass; extern JS_FRIEND_DATA(js::Class) OuterWindowProxyClass; extern JS_FRIEND_DATA(js::Class) ObjectProxyClass; @@ -406,6 +409,9 @@ IsOuterObject(JSObject *obj) { return !!GetObjectClass(obj)->ext.innerObject; } +JS_FRIEND_API(bool) +IsFunctionObject(JSObject *obj); + JS_FRIEND_API(bool) IsScopeObject(JSObject *obj); @@ -1571,7 +1577,7 @@ struct JSJitInfo { static JS_ALWAYS_INLINE const JSJitInfo * FUNCTION_VALUE_TO_JITINFO(const JS::Value& v) { - JS_ASSERT(js::GetObjectClass(&v.toObject()) == &js::FunctionClass); + JS_ASSERT(js::GetObjectClass(&v.toObject()) == js::FunctionClassPtr); return reinterpret_cast(&v.toObject())->jitinfo; } diff --git a/js/src/jsfun.cpp b/js/src/jsfun.cpp index b0624abbf19b..b5e835c90dcc 100644 --- a/js/src/jsfun.cpp +++ b/js/src/jsfun.cpp @@ -58,13 +58,13 @@ static JSBool fun_getProperty(JSContext *cx, HandleObject obj_, HandleId id, MutableHandleValue vp) { RootedObject obj(cx, obj_); - while (!obj->isFunction()) { + while (!obj->is()) { if (!JSObject::getProto(cx, obj, &obj)) return false; if (!obj) return true; } - RootedFunction fun(cx, obj->toFunction()); + RootedFunction fun(cx, &obj->as()); /* Set to early to null in case of error */ vp.setNull(); @@ -117,8 +117,8 @@ fun_getProperty(JSContext *cx, HandleObject obj_, HandleId id, MutableHandleValu /* Callsite clones should never escape to script. */ JSObject &maybeClone = iter.calleev().toObject(); - if (maybeClone.isFunction() && maybeClone.toFunction()->nonLazyScript()->isCallsiteClone) - vp.setObject(*maybeClone.toFunction()->nonLazyScript()->originalFunction()); + if (maybeClone.is() && maybeClone.as().nonLazyScript()->isCallsiteClone) + vp.setObject(*maybeClone.as().nonLazyScript()->originalFunction()); else vp.set(iter.calleev()); @@ -131,8 +131,8 @@ fun_getProperty(JSContext *cx, HandleObject obj_, HandleId id, MutableHandleValu RootedObject caller(cx, &vp.toObject()); if (caller->isWrapper() && !Wrapper::wrapperHandler(caller)->isSafeToUnwrap()) { vp.setNull(); - } else if (caller->isFunction()) { - JSFunction *callerFun = caller->toFunction(); + } else if (caller->is()) { + JSFunction *callerFun = &caller->as(); if (callerFun->isInterpreted() && callerFun->strict()) { JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR, js_GetErrorMessage, NULL, JSMSG_CALLER_IS_STRICT); @@ -159,7 +159,7 @@ static const uint16_t poisonPillProps[] = { static JSBool fun_enumerate(JSContext *cx, HandleObject obj) { - JS_ASSERT(obj->isFunction()); + JS_ASSERT(obj->is()); RootedId id(cx); bool found; @@ -192,7 +192,7 @@ static JSObject * ResolveInterpretedFunctionPrototype(JSContext *cx, HandleObject obj) { #ifdef DEBUG - JSFunction *fun = obj->toFunction(); + JSFunction *fun = &obj->as(); JS_ASSERT(fun->isInterpreted()); JS_ASSERT(!fun->isFunctionPrototype()); #endif @@ -243,7 +243,7 @@ fun_resolve(JSContext *cx, HandleObject obj, HandleId id, unsigned flags, if (!JSID_IS_ATOM(id)) return true; - RootedFunction fun(cx, obj->toFunction()); + RootedFunction fun(cx, &obj->as()); if (JSID_IS_ATOM(id, cx->names().classPrototype)) { /* @@ -339,7 +339,7 @@ js::XDRInterpretedFunction(XDRState *xdr, HandleObject enclosingScope, Han RootedFunction fun(cx); RootedScript script(cx); if (mode == XDR_ENCODE) { - fun = objp->toFunction(); + fun = &objp->as(); if (!fun->isInterpreted()) { JSAutoByteString funNameBytes; if (const char *name = GetFunctionNameBytes(cx, fun, &funNameBytes)) { @@ -435,8 +435,8 @@ fun_hasInstance(JSContext *cx, HandleObject objArg, MutableHandleValue v, JSBool { RootedObject obj(cx, objArg); - while (obj->isFunction() && obj->isBoundFunction()) - obj = obj->toFunction()->getBoundFunctionTarget(); + while (obj->is() && obj->isBoundFunction()) + obj = obj->as().getBoundFunctionTarget(); RootedValue pval(cx); if (!JSObject::getProperty(cx, obj, obj, cx->names().classPrototype, &pval)) @@ -487,10 +487,10 @@ JSFunction::trace(JSTracer *trc) static void fun_trace(JSTracer *trc, JSObject *obj) { - obj->toFunction()->trace(trc); + obj->as().trace(trc); } -JS_FRIEND_DATA(Class) js::FunctionClass = { +Class JSFunction::class_ = { js_Function_str, JSCLASS_NEW_RESOLVE | JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_HAS_CACHED_PROTO(JSProto_Function), @@ -509,6 +509,7 @@ JS_FRIEND_DATA(Class) js::FunctionClass = { fun_trace }; +JS_FRIEND_DATA(Class*) js::FunctionClassPtr = &JSFunction::class_; /* Find the body of a function (not including braces). */ static bool @@ -577,7 +578,7 @@ js::FunctionToString(JSContext *cx, HandleFunction fun, bool bodyOnly, bool lamb // of the pre-binding target. if (fun->isArrow() && fun->isBoundFunction()) { JSObject *target = fun->getBoundFunctionTarget(); - RootedFunction targetFun(cx, target->toFunction()); + RootedFunction targetFun(cx, &target->as()); JS_ASSERT(targetFun->isArrow()); return FunctionToString(cx, targetFun, bodyOnly, lambdaParen); } @@ -739,7 +740,7 @@ js::FunctionToString(JSContext *cx, HandleFunction fun, bool bodyOnly, bool lamb JSString * fun_toStringHelper(JSContext *cx, HandleObject obj, unsigned indent) { - if (!obj->isFunction()) { + if (!obj->is()) { if (IsFunctionProxy(obj)) return Proxy::fun_toString(cx, obj, indent); JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, @@ -749,7 +750,7 @@ fun_toStringHelper(JSContext *cx, HandleObject obj, unsigned indent) return NULL; } - RootedFunction fun(cx, obj->toFunction()); + RootedFunction fun(cx, &obj->as()); return FunctionToString(cx, fun, false, indent != JS_DONT_PRETTY_PRINT); } @@ -802,7 +803,7 @@ js_fun_call(JSContext *cx, unsigned argc, Value *vp) RootedValue fval(cx, vp[1]); if (!js_IsCallable(fval)) { - ReportIncompatibleMethod(cx, CallReceiverFromVp(vp), &FunctionClass); + ReportIncompatibleMethod(cx, CallReceiverFromVp(vp), &JSFunction::class_); return false; } @@ -858,7 +859,7 @@ js_fun_apply(JSContext *cx, unsigned argc, Value *vp) /* Step 1. */ RootedValue fval(cx, vp[1]); if (!js_IsCallable(fval)) { - ReportIncompatibleMethod(cx, CallReceiverFromVp(vp), &FunctionClass); + ReportIncompatibleMethod(cx, CallReceiverFromVp(vp), &JSFunction::class_); return false; } @@ -994,8 +995,6 @@ inline bool JSFunction::initBoundFunction(JSContext *cx, HandleValue thisArg, const Value *args, unsigned argslen) { - JS_ASSERT(isFunction()); - RootedFunction self(cx, this); /* @@ -1023,7 +1022,6 @@ JSFunction::initBoundFunction(JSContext *cx, HandleValue thisArg, inline const js::Value & JSFunction::getBoundFunctionThis() const { - JS_ASSERT(isFunction()); JS_ASSERT(isBoundFunction()); return getSlot(JSSLOT_BOUND_FUNCTION_THIS); @@ -1032,7 +1030,6 @@ JSFunction::getBoundFunctionThis() const inline const js::Value & JSFunction::getBoundFunctionArgument(unsigned which) const { - JS_ASSERT(isFunction()); JS_ASSERT(isBoundFunction()); JS_ASSERT(which < getBoundFunctionArgumentCount()); @@ -1042,7 +1039,6 @@ JSFunction::getBoundFunctionArgument(unsigned which) const inline size_t JSFunction::getBoundFunctionArgumentCount() const { - JS_ASSERT(isFunction()); JS_ASSERT(isBoundFunction()); return getSlot(JSSLOT_BOUND_FUNCTION_ARGS_COUNT).toPrivateUint32(); @@ -1106,7 +1102,7 @@ JSFunction::createScriptForLazilyInterpretedFunction(JSContext *cx, HandleFuncti JSBool js::CallOrConstructBoundFunction(JSContext *cx, unsigned argc, Value *vp) { - RootedFunction fun(cx, vp[0].toObject().toFunction()); + RootedFunction fun(cx, &vp[0].toObject().as()); JS_ASSERT(fun->isBoundFunction()); bool constructing = IsConstructing(vp); @@ -1188,7 +1184,7 @@ fun_bind(JSContext *cx, unsigned argc, Value *vp) /* Step 2. */ if (!js_IsCallable(thisv)) { - ReportIncompatibleMethod(cx, args, &FunctionClass); + ReportIncompatibleMethod(cx, args, &JSFunction::class_); return false; } @@ -1218,14 +1214,14 @@ js_fun_bind(JSContext *cx, HandleObject target, HandleValue thisArg, { /* Steps 15-16. */ unsigned length = 0; - if (target->isFunction()) { - unsigned nargs = target->toFunction()->nargs; + if (target->is()) { + unsigned nargs = target->as().nargs; if (nargs > argslen) length = nargs - argslen; } /* Step 4-6, 10-11. */ - RootedAtom name(cx, target->isFunction() ? target->toFunction()->atom() : NULL); + RootedAtom name(cx, target->is() ? target->as().atom() : NULL); RootedObject funobj(cx, NewFunction(cx, NullPtr(), CallOrConstructBoundFunction, length, JSFunction::NATIVE_CTOR, target, name)); @@ -1236,7 +1232,7 @@ js_fun_bind(JSContext *cx, HandleObject target, HandleValue thisArg, if (!JSObject::setParent(cx, funobj, target)) return NULL; - if (!funobj->toFunction()->initBoundFunction(cx, thisArg, boundArgs, argslen)) + if (!funobj->as().initBoundFunction(cx, thisArg, boundArgs, argslen)) return NULL; /* Steps 17, 19-21 are handled by fun_resolve. */ @@ -1487,7 +1483,7 @@ js::NewFunction(JSContext *cx, HandleObject funobjArg, Native native, unsigned n RootedObject funobj(cx, funobjArg); if (funobj) { - JS_ASSERT(funobj->isFunction()); + JS_ASSERT(funobj->is()); JS_ASSERT(funobj->getParent() == parent); JS_ASSERT_IF(native && cx->typeInferenceEnabled(), funobj->hasSingletonType()); } else { @@ -1496,11 +1492,12 @@ js::NewFunction(JSContext *cx, HandleObject funobjArg, Native native, unsigned n // that hasSingletonType implies isInterpreted. if (native && !IsAsmJSModuleNative(native)) newKind = SingletonObject; - funobj = NewObjectWithClassProto(cx, &FunctionClass, NULL, SkipScopeParent(parent), allocKind, newKind); + funobj = NewObjectWithClassProto(cx, &JSFunction::class_, NULL, + SkipScopeParent(parent), allocKind, newKind); if (!funobj) return NULL; } - RootedFunction fun(cx, funobj->toFunction()); + RootedFunction fun(cx, &funobj->as()); /* Initialize all function members. */ fun->nargs = uint16_t(nargs); @@ -1538,11 +1535,11 @@ js::CloneFunctionObject(JSContext *cx, HandleFunction fun, HandleObject parent, return NULL; NewObjectKind newKind = useSameScript ? newKindArg : SingletonObject; - JSObject *cloneobj = NewObjectWithClassProto(cx, &FunctionClass, NULL, SkipScopeParent(parent), - allocKind, newKind); + JSObject *cloneobj = NewObjectWithClassProto(cx, &JSFunction::class_, NULL, + SkipScopeParent(parent), allocKind, newKind); if (!cloneobj) return NULL; - RootedFunction clone(cx, cloneobj->toFunction()); + RootedFunction clone(cx, &cloneobj->as()); clone->nargs = fun->nargs; clone->flags = fun->flags & ~JSFunction::EXTENDED; diff --git a/js/src/jsfun.h b/js/src/jsfun.h index e778d6cac4a9..c4a9313545d5 100644 --- a/js/src/jsfun.h +++ b/js/src/jsfun.h @@ -19,6 +19,8 @@ namespace js { class FunctionExtended; } class JSFunction : public JSObject { public: + static js::Class class_; + enum Flags { INTERPRETED = 0x0001, /* function has a JSScript and environment. */ NATIVE_CTOR = 0x0002, /* native that can be called as a constructor */ @@ -330,30 +332,8 @@ class JSFunction : public JSObject JS_ASSERT_IF(isTenured(), kind == tenuredGetAllocKind()); return kind; } - - private: - /* - * These member functions are inherited from JSObject, but should never be applied to - * a value statically known to be a JSFunction. - */ - inline JSFunction *toFunction() MOZ_DELETE; - inline const JSFunction *toFunction() const MOZ_DELETE; }; -inline JSFunction * -JSObject::toFunction() -{ - JS_ASSERT(JS_ObjectIsFunction(NULL, this)); - return static_cast(this); -} - -inline const JSFunction * -JSObject::toFunction() const -{ - JS_ASSERT(JS_ObjectIsFunction(NULL, const_cast(this))); - return static_cast(this); -} - extern JSString * fun_toStringHelper(JSContext *cx, js::HandleObject obj, unsigned indent); diff --git a/js/src/jsfuninlines.h b/js/src/jsfuninlines.h index 9aa27aea3a70..c334ffdcca80 100644 --- a/js/src/jsfuninlines.h +++ b/js/src/jsfuninlines.h @@ -8,6 +8,7 @@ #define jsfuninlines_h #include "jsfun.h" + #include "jsscript.h" #include "vm/GlobalObject.h" @@ -118,7 +119,7 @@ SameTraceType(const Value &lhs, const Value &rhs) { return SameType(lhs, rhs) && (lhs.isPrimitive() || - lhs.toObject().isFunction() == rhs.toObject().isFunction()); + lhs.toObject().is() == rhs.toObject().is()); } /* Valueified JS_IsConstructing. */ @@ -127,8 +128,8 @@ IsConstructing(const Value *vp) { #ifdef DEBUG JSObject *callee = &JS_CALLEE(cx, vp).toObject(); - if (callee->isFunction()) { - JSFunction *fun = callee->toFunction(); + if (callee->is()) { + JSFunction *fun = &callee->as(); JS_ASSERT(fun->isNativeConstructor()); } else { JS_ASSERT(callee->getClass()->construct != NULL); @@ -285,7 +286,6 @@ JSFunction::initLazyScript(js::LazyScript *lazy) inline JSObject * JSFunction::getBoundFunctionTarget() const { - JS_ASSERT(isFunction()); JS_ASSERT(isBoundFunction()); /* Bound functions abuse |parent| to store their target function. */ @@ -295,7 +295,7 @@ JSFunction::getBoundFunctionTarget() const inline bool js::Class::isCallable() const { - return this == &js::FunctionClass || call; + return this == &JSFunction::class_ || call; } #endif /* jsfuninlines_h */ diff --git a/js/src/jsgcinlines.h b/js/src/jsgcinlines.h index b8caf414bf20..7e9586290db3 100644 --- a/js/src/jsgcinlines.h +++ b/js/src/jsgcinlines.h @@ -73,7 +73,7 @@ GetGCObjectKind(size_t numSlots) static inline AllocKind GetGCObjectKind(Class *clasp) { - if (clasp == &FunctionClass) + if (clasp == FunctionClassPtr) return JSFunction::FinalizeKind; uint32_t nslots = JSCLASS_RESERVED_SLOTS(clasp); if (clasp->flags & JSCLASS_HAS_PRIVATE) @@ -171,7 +171,7 @@ GetGCKindSlots(AllocKind thingKind, Class *clasp) * Functions have a larger finalize kind than FINALIZE_OBJECT to reserve * space for the extra fields in JSFunction, but have no fixed slots. */ - if (clasp == &FunctionClass) + if (clasp == FunctionClassPtr) nslots = 0; return nslots; diff --git a/js/src/jsinfer.cpp b/js/src/jsinfer.cpp index 461907265995..ece91fa80538 100644 --- a/js/src/jsinfer.cpp +++ b/js/src/jsinfer.cpp @@ -1388,12 +1388,12 @@ TypeConstraintCall::newType(JSContext *cx, TypeSet *source, Type type) if (type.isSingleObject()) { RootedObject obj(cx, type.singleObject()); - if (!obj->isFunction()) { + if (!obj->is()) { /* Calls on non-functions are dynamically monitored. */ return; } - if (obj->toFunction()->isNative()) { + if (obj->as().isNative()) { /* * The return value and all side effects within native calls should * be dynamically monitored, except when the compiler is generating @@ -1409,7 +1409,7 @@ TypeConstraintCall::newType(JSContext *cx, TypeSet *source, Type type) * which specializes particular natives. */ - Native native = obj->toFunction()->native(); + Native native = obj->as().native(); if (native == js::array_push) { for (size_t i = 0; i < callsite->argumentCount; i++) { @@ -1460,7 +1460,7 @@ TypeConstraintCall::newType(JSContext *cx, TypeSet *source, Type type) return; } - callee = obj->toFunction(); + callee = &obj->as(); } else if (type.isTypeObject()) { callee = type.typeObject()->interpretedFunction; if (!callee) @@ -1547,9 +1547,9 @@ TypeConstraintPropagateThis::newType(JSContext *cx, TypeSet *source, Type type) if (type.isSingleObject()) { RootedObject object(cx, type.singleObject()); - if (!object->isFunction() || !object->toFunction()->isInterpreted()) + if (!object->is() || !object->as().isInterpreted()) return; - callee = object->toFunction(); + callee = &object->as(); } else if (type.isTypeObject()) { TypeObject *object = type.typeObject(); if (!object->interpretedFunction) @@ -2346,7 +2346,7 @@ TypeCompartment::newTypeObject(JSContext *cx, Class *clasp, Handle sizeof(TypeObject), gc::TenuredHeap); if (!object) return NULL; - new(object) TypeObject(clasp, proto, clasp == &FunctionClass, unknown); + new(object) TypeObject(clasp, proto, clasp == &JSFunction::class_, unknown); if (!cx->typeInferenceEnabled()) object->flags |= OBJECT_FLAG_UNKNOWN_MASK; @@ -4384,10 +4384,13 @@ ScriptAnalysis::analyzeTypesBytecode(JSContext *cx, unsigned offset, TypeInferen // original function, despecialize the type produced here. This includes // functions that are deep cloned at each lambda, as well as inner // functions to run-once lambdas which may actually execute multiple times. - if (script->compileAndGo && !script->treatAsRunOnce && !UseNewTypeForClone(obj->toFunction())) + if (script->compileAndGo && !script->treatAsRunOnce && + !UseNewTypeForClone(&obj->as())) + { res->addType(cx, Type::ObjectType(obj)); - else + } else { res->addType(cx, Type::AnyObjectType()); + } break; } @@ -5145,17 +5148,17 @@ AnalyzePoppedThis(JSContext *cx, SSAUseChain *use, { JSObject *funcallObj = funcallTypes->getSingleton(); JSObject *scriptObj = scriptTypes->getSingleton(); - if (!funcallObj || !funcallObj->isFunction() || - funcallObj->toFunction()->isInterpreted() || - !scriptObj || !scriptObj->isFunction() || - !scriptObj->toFunction()->isInterpreted()) + if (!funcallObj || !funcallObj->is() || + funcallObj->as().isInterpreted() || + !scriptObj || !scriptObj->is() || + !scriptObj->as().isInterpreted()) { return false; } - Native native = funcallObj->toFunction()->native(); + Native native = funcallObj->as().native(); if (native != js_fun_call && native != js_fun_apply) return false; - function = scriptObj->toFunction(); + function = &scriptObj->as(); } /* @@ -5484,8 +5487,8 @@ void types::TypeMonitorCallSlow(JSContext *cx, JSObject *callee, const CallArgs &args, bool constructing) { - unsigned nargs = callee->toFunction()->nargs; - JSScript *script = callee->toFunction()->nonLazyScript(); + unsigned nargs = callee->as().nargs; + JSScript *script = callee->as().nonLazyScript(); if (!constructing) TypeScript::SetThis(cx, script, args.thisv()); @@ -5832,7 +5835,8 @@ JSFunction::setTypeForScriptedFunction(JSContext *cx, HandleFunction fun, bool s return false; } else { RootedObject funProto(cx, fun->getProto()); - TypeObject *type = cx->compartment()->types.newTypeObject(cx, &FunctionClass, funProto); + TypeObject *type = + cx->compartment()->types.newTypeObject(cx, &JSFunction::class_, funProto); if (!type) return false; @@ -5933,8 +5937,8 @@ JSObject::makeLazyType(JSContext *cx, HandleObject obj) JS_ASSERT(cx->compartment() == obj->compartment()); /* De-lazification of functions can GC, so we need to do it up here. */ - if (obj->isFunction() && obj->toFunction()->isInterpretedLazy()) { - RootedFunction fun(cx, obj->toFunction()); + if (obj->is() && obj->as().isInterpretedLazy()) { + RootedFunction fun(cx, &obj->as()); if (!fun->getOrCreateScript(cx)) return NULL; } @@ -5958,8 +5962,8 @@ JSObject::makeLazyType(JSContext *cx, HandleObject obj) type->singleton = obj; - if (obj->isFunction() && obj->toFunction()->isInterpreted()) - type->interpretedFunction = obj->toFunction(); + if (obj->is() && obj->as().isInterpreted()) + type->interpretedFunction = &obj->as(); if (obj->lastProperty()->hasObjectFlag(BaseShape::ITERATED_SINGLETON)) type->flags |= OBJECT_FLAG_ITERATED; diff --git a/js/src/jsinferinlines.h b/js/src/jsinferinlines.h index 2892116fef34..e48265ed6898 100644 --- a/js/src/jsinferinlines.h +++ b/js/src/jsinferinlines.h @@ -551,8 +551,8 @@ void TypeMonitorCallSlow(JSContext *cx, JSObject *callee, const CallArgs &args, inline void TypeMonitorCall(JSContext *cx, const js::CallArgs &args, bool constructing) { - if (args.callee().isFunction()) { - JSFunction *fun = args.callee().toFunction(); + if (args.callee().is()) { + JSFunction *fun = &args.callee().as(); if (fun->isInterpreted() && fun->nonLazyScript()->types && cx->typeInferenceEnabled()) TypeMonitorCallSlow(cx, &args.callee(), args, constructing); } diff --git a/js/src/jsmemorymetrics.cpp b/js/src/jsmemorymetrics.cpp index 5d2898fa1bfe..4d8c9ef01123 100644 --- a/js/src/jsmemorymetrics.cpp +++ b/js/src/jsmemorymetrics.cpp @@ -173,7 +173,7 @@ StatsCellCallback(JSRuntime *rt, void *data, void *thing, JSGCTraceKind traceKin case JSTRACE_OBJECT: { JSObject *obj = static_cast(thing); CompartmentStats *cStats = GetCompartmentStats(obj->compartment()); - if (obj->isFunction()) + if (obj->is()) cStats->gcHeapObjectsFunction += thingSize; else if (obj->isArray()) cStats->gcHeapObjectsDenseArray += thingSize; diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index 22c7ab22c199..51f01178b1b2 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -1234,7 +1234,7 @@ NewObjectGCKind(js::Class *clasp) { if (clasp == &ArrayClass) return gc::FINALIZE_OBJECT8; - if (clasp == &FunctionClass) + if (clasp == &JSFunction::class_) return gc::FINALIZE_OBJECT2; return gc::FINALIZE_OBJECT4; } @@ -1244,7 +1244,7 @@ NewObject(JSContext *cx, Class *clasp, types::TypeObject *type_, JSObject *paren gc::AllocKind kind, NewObjectKind newKind) { JS_ASSERT(clasp != &ArrayClass); - JS_ASSERT_IF(clasp == &FunctionClass, + JS_ASSERT_IF(clasp == &JSFunction::class_, kind == JSFunction::FinalizeKind || kind == JSFunction::ExtendedFinalizeKind); JS_ASSERT_IF(parent, &parent->global() == cx->compartment()->maybeGlobal()); @@ -1538,7 +1538,7 @@ js::CreateThisForFunctionWithProto(JSContext *cx, HandleObject callee, JSObject JSObject *res; if (proto) { - RootedTypeObject type(cx, proto->getNewType(cx, &ObjectClass, callee->toFunction())); + RootedTypeObject type(cx, proto->getNewType(cx, &ObjectClass, &callee->as())); if (!type) return NULL; res = CreateThisForFunctionWithType(cx, type, callee->getParent(), newKind); @@ -1548,7 +1548,7 @@ js::CreateThisForFunctionWithProto(JSContext *cx, HandleObject callee, JSObject } if (res && cx->typeInferenceEnabled()) { - JSScript *script = callee->toFunction()->nonLazyScript(); + JSScript *script = callee->as().nonLazyScript(); TypeScript::SetThis(cx, script, types::Type::ObjectType(res)); } @@ -1575,7 +1575,7 @@ js::CreateThisForFunction(JSContext *cx, HandleObject callee, bool newType) /* Reshape the singleton before passing it as the 'this' value. */ JSObject::clear(cx, nobj); - JSScript *calleeScript = callee->toFunction()->nonLazyScript(); + JSScript *calleeScript = callee->as().nonLazyScript(); TypeScript::SetThis(cx, calleeScript, types::Type::ObjectType(nobj)); return nobj; @@ -1782,7 +1782,7 @@ js::CloneObject(JSContext *cx, HandleObject obj, Handle proto, if (!clone) return NULL; if (obj->isNative()) { - if (clone->isFunction() && (obj->compartment() != clone->compartment())) { + if (clone->is() && (obj->compartment() != clone->compartment())) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_CLONE_OBJECT); return NULL; @@ -1958,7 +1958,7 @@ void JSObject::TradeGuts(JSContext *cx, JSObject *a, JSObject *b, TradeGutsReserved &reserved) { JS_ASSERT(a->compartment() == b->compartment()); - JS_ASSERT(a->isFunction() == b->isFunction()); + JS_ASSERT(a->is() == b->is()); /* * Swap the object's types, to restore their initial type information. @@ -1969,7 +1969,7 @@ JSObject::TradeGuts(JSContext *cx, JSObject *a, JSObject *b, TradeGutsReserved & b->type_ = tmp; /* Don't try to swap a JSFunction for a plain function JSObject. */ - JS_ASSERT_IF(a->isFunction(), a->tenuredSizeOfThis() == b->tenuredSizeOfThis()); + JS_ASSERT_IF(a->is(), a->tenuredSizeOfThis() == b->tenuredSizeOfThis()); /* * Regexp guts are more complicated -- we would need to migrate the @@ -2199,12 +2199,12 @@ js::DefineConstructorAndPrototype(JSContext *cx, HandleObject obj, JSProtoKey ke * otherwise-uninitialized global. * * 3. NewObject allocating a JSFunction-sized GC-thing when clasp is - * &FunctionClass, not a JSObject-sized (smaller) GC-thing. + * &JSFunction::class_, not a JSObject-sized (smaller) GC-thing. * * The JS_NewObjectForGivenProto and JS_NewObject APIs also allow clasp to - * be &FunctionClass (we could break compatibility easily). But fixing - * (3) is not enough without addressing the bootstrapping dependency on (1) - * and (2). + * be &JSFunction::class_ (we could break compatibility easily). But + * fixing (3) is not enough without addressing the bootstrapping dependency + * on (1) and (2). */ /* @@ -5017,8 +5017,8 @@ dumpValue(const Value &v) fprintf(stderr, "%g", v.toDouble()); else if (v.isString()) v.toString()->dump(); - else if (v.isObject() && v.toObject().isFunction()) { - JSFunction *fun = v.toObject().toFunction(); + else if (v.isObject() && v.toObject().is()) { + JSFunction *fun = &v.toObject().as(); if (fun->displayAtom()) { fputs("displayAtom(), 0); diff --git a/js/src/jsobj.h b/js/src/jsobj.h index ae64310a3103..50b7ce6046fc 100644 --- a/js/src/jsobj.h +++ b/js/src/jsobj.h @@ -645,15 +645,6 @@ class JSObject : public js::ObjectImpl inline const js::Value &getDateUTCTime() const; inline void setDateUTCTime(const js::Value &pthis); - /* - * Function-specific getters and setters. - */ - - friend class JSFunction; - - inline JSFunction *toFunction(); - inline const JSFunction *toFunction() const; - public: /* * Iterator-specific getters and setters. @@ -938,7 +929,6 @@ class JSObject : public js::ObjectImpl inline bool isArray() const { return hasClass(&js::ArrayClass); } inline bool isDate() const { return hasClass(&js::DateClass); } inline bool isError() const { return hasClass(&js::ErrorClass); } - inline bool isFunction() const { return hasClass(&js::FunctionClass); } inline bool isObject() const { return hasClass(&js::ObjectClass); } using js::ObjectImpl::isProxy; inline bool isRegExpStatics() const { return hasClass(&js::RegExpStaticsClass); } diff --git a/js/src/jsobjinlines.h b/js/src/jsobjinlines.h index 6a7670a46f00..cef915c6e1b0 100644 --- a/js/src/jsobjinlines.h +++ b/js/src/jsobjinlines.h @@ -1250,14 +1250,14 @@ GetOuterObject(JSContext *cx, HandleObject obj) static JS_ALWAYS_INLINE bool IsFunctionObject(const js::Value &v) { - return v.isObject() && v.toObject().isFunction(); + return v.isObject() && v.toObject().is(); } static JS_ALWAYS_INLINE bool IsFunctionObject(const js::Value &v, JSFunction **fun) { - if (v.isObject() && v.toObject().isFunction()) { - *fun = v.toObject().toFunction(); + if (v.isObject() && v.toObject().is()) { + *fun = &v.toObject().as(); return true; } return false; @@ -1357,7 +1357,7 @@ ToPrimitive(JSContext *cx, JSType preferredType, MutableHandleValue vp) inline bool IsInternalFunctionObject(JSObject *funobj) { - JSFunction *fun = funobj->toFunction(); + JSFunction *fun = &funobj->as(); return fun->isLambda() && !funobj->getParent(); } diff --git a/js/src/jsopcode.cpp b/js/src/jsopcode.cpp index e99bb7101a80..4a50c5ae9c87 100644 --- a/js/src/jsopcode.cpp +++ b/js/src/jsopcode.cpp @@ -510,8 +510,8 @@ ToDisassemblySource(JSContext *cx, jsval v, JSAutoByteString *bytes) return true; } - if (obj->isFunction()) { - JSString *str = JS_DecompileFunction(cx, obj->toFunction(), JS_DONT_PRETTY_PRINT); + if (obj->is()) { + JSString *str = JS_DecompileFunction(cx, &obj->as(), JS_DONT_PRETTY_PRINT); if (!str) return false; return bytes->encodeLatin1(cx, str); diff --git a/js/src/jsproxy.cpp b/js/src/jsproxy.cpp index bfc86448ce5e..134acbe74255 100644 --- a/js/src/jsproxy.cpp +++ b/js/src/jsproxy.cpp @@ -1043,7 +1043,7 @@ ScriptedIndirectProxyHandler::fun_toString(JSContext *cx, HandleObject proxy, un assertEnteredPolicy(cx, proxy, JSID_VOID); Value fval = GetCall(proxy); if (IsFunctionProxy(proxy) && - (fval.isPrimitive() || !fval.toObject().isFunction())) { + (fval.isPrimitive() || !fval.toObject().is())) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO, js_Function_str, js_toString_str, diff --git a/js/src/jsreflect.cpp b/js/src/jsreflect.cpp index 52a37077f2a6..339c48e0dc0c 100644 --- a/js/src/jsreflect.cpp +++ b/js/src/jsreflect.cpp @@ -180,7 +180,7 @@ class NodeBuilder continue; } - if (!funv.isObject() || !funv.toObject().isFunction()) { + if (!funv.isObject() || !funv.toObject().is()) { js_ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_NOT_FUNCTION, JSDVG_SEARCH_STACK, funv, NullPtr(), NULL, NULL); return false; diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index 0f649265b7dc..34d2639a51ef 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -662,7 +662,7 @@ js::XDRScript(XDRState *xdr, HandleObject enclosingScope, HandleScript enc uint32_t isBlock; if (mode == XDR_ENCODE) { JSObject *obj = *objp; - JS_ASSERT(obj->isFunction() || obj->is()); + JS_ASSERT(obj->is() || obj->is()); isBlock = obj->is() ? 1 : 0; } if (!xdr->codeUint32(&isBlock)) @@ -671,7 +671,7 @@ js::XDRScript(XDRState *xdr, HandleObject enclosingScope, HandleScript enc /* Code the nested function's enclosing scope. */ uint32_t funEnclosingScopeIndex = 0; if (mode == XDR_ENCODE) { - JSScript *innerScript = (*objp)->toFunction()->getOrCreateScript(cx); + JSScript *innerScript = (*objp)->as().getOrCreateScript(cx); if (!innerScript) return false; RootedObject staticScope(cx, innerScript->enclosingStaticScope()); @@ -1986,8 +1986,8 @@ JSScript::enclosingScriptsCompiledSuccessfully() const */ JSObject *enclosing = enclosingStaticScope(); while (enclosing) { - if (enclosing->isFunction()) { - JSFunction *fun = enclosing->toFunction(); + if (enclosing->is()) { + JSFunction *fun = &enclosing->as(); if (!fun->hasScript() || !fun->nonLazyScript()) return false; enclosing = fun->nonLazyScript()->enclosingStaticScope(); @@ -2316,8 +2316,8 @@ js::CloneScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun, enclosingScope = fun; clone = CloneStaticBlockObject(cx, enclosingScope, innerBlock); - } else if (obj->isFunction()) { - RootedFunction innerFun(cx, obj->toFunction()); + } else if (obj->is()) { + RootedFunction innerFun(cx, &obj->as()); if (innerFun->isNative()) { assertSameCompartment(cx, innerFun); clone = innerFun; diff --git a/js/src/jsscriptinlines.h b/js/src/jsscriptinlines.h index 74d239f00807..6218aa5e10c7 100644 --- a/js/src/jsscriptinlines.h +++ b/js/src/jsscriptinlines.h @@ -96,12 +96,11 @@ JSScript::setFunction(JSFunction *fun) inline JSFunction * JSScript::getFunction(size_t index) { - JSObject *funobj = getObject(index); + JSFunction *fun = &getObject(index)->as(); #ifdef DEBUG - JSFunction *fun = funobj->toFunction(); JS_ASSERT_IF(fun->isNative(), IsAsmJSModuleNative(fun->native())); #endif - return funobj->toFunction(); + return fun; } inline JSFunction * @@ -202,13 +201,13 @@ inline JSFunction * JSScript::originalFunction() const { if (!isCallsiteClone) return NULL; - return enclosingScopeOrOriginalFunction_->toFunction(); + return &enclosingScopeOrOriginalFunction_->as(); } inline void JSScript::setOriginalFunctionObject(JSObject *fun) { JS_ASSERT(isCallsiteClone); - JS_ASSERT(fun->isFunction()); + JS_ASSERT(fun->is()); enclosingScopeOrOriginalFunction_ = fun; } diff --git a/js/src/jsstr.cpp b/js/src/jsstr.cpp index f355cb032d82..a35dbd70ec3c 100644 --- a/js/src/jsstr.cpp +++ b/js/src/jsstr.cpp @@ -43,6 +43,7 @@ #include "vm/Interpreter.h" #include "vm/NumericConversions.h" #include "vm/RegExpObject.h" +#include "vm/ScopeObject.h" #include "vm/Shape.h" #include "vm/StringBuffer.h" @@ -2690,10 +2691,10 @@ static const uint32_t ReplaceOptArg = 2; static bool LambdaIsGetElem(JSContext *cx, JSObject &lambda, MutableHandleObject pobj) { - if (!lambda.isFunction()) + if (!lambda.is()) return true; - JSFunction *fun = lambda.toFunction(); + JSFunction *fun = &lambda.as(); if (!fun->isInterpreted()) return true; diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index db7648307e6d..9ec9f1b0fd1b 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -1440,8 +1440,8 @@ ValueToScript(JSContext *cx, jsval v, JSFunction **funp = NULL) // Unwrap bound functions. while (fun->isBoundFunction()) { JSObject *target = fun->getBoundFunctionTarget(); - if (target && target->isFunction()) - fun = target->toFunction(); + if (target && target->is()) + fun = &target->as(); else break; } @@ -1494,7 +1494,7 @@ GetScriptAndPCArgs(JSContext *cx, unsigned argc, jsval *argv, MutableHandleScrip jsval v = argv[0]; unsigned intarg = 0; if (!JSVAL_IS_PRIMITIVE(v) && - JS_GetClass(&v.toObject()) == Jsvalify(&FunctionClass)) { + JS_GetClass(&v.toObject()) == Jsvalify(&JSFunction::class_)) { script = ValueToScript(cx, v); if (!script) return false; @@ -1650,7 +1650,7 @@ LineToPC(JSContext *cx, unsigned argc, jsval *vp) script = GetTopScript(cx); jsval v = args[0]; if (!JSVAL_IS_PRIMITIVE(v) && - JS_GetClass(&v.toObject()) == Jsvalify(&FunctionClass)) + JS_GetClass(&v.toObject()) == Jsvalify(&JSFunction::class_)) { script = ValueToScript(cx, v); if (!script) @@ -1894,9 +1894,9 @@ DisassembleScript(JSContext *cx, HandleScript script, HandleFunction fun, bool l ObjectArray *objects = script->objects(); for (unsigned i = 0; i != objects->length; ++i) { JSObject *obj = objects->vector[i]; - if (obj->isFunction()) { + if (obj->is()) { Sprint(sp, "\n"); - RootedFunction fun(cx, obj->toFunction()); + RootedFunction fun(cx, &obj->as()); if (fun->isInterpreted()) { RootedScript script(cx, fun->getOrCreateScript(cx)); if (!script || !DisassembleScript(cx, script, fun, lines, recursive, sp)) @@ -2322,7 +2322,7 @@ Clone(JSContext *cx, unsigned argc, jsval *vp) ac.construct(cx, obj); args[0] = ObjectValue(*obj); } - if (obj && obj->isFunction()) { + if (obj && obj->is()) { funobj = obj; } else { JSFunction *fun = JS_ValueToFunction(cx, args[0]); @@ -2332,7 +2332,7 @@ Clone(JSContext *cx, unsigned argc, jsval *vp) } } if (funobj->compartment() != cx->compartment()) { - JSFunction *fun = funobj->toFunction(); + JSFunction *fun = &funobj->as(); if (fun->hasScript() && fun->nonLazyScript()->compileAndGo) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_UNEXPECTED_TYPE, "function", "compile-and-go"); @@ -3062,7 +3062,7 @@ Timeout(JSContext *cx, unsigned argc, jsval *vp) if (argc > 1) { RootedValue value(cx, JS_ARGV(cx, vp)[1]); - if (!value.isObject() || !value.toObject().isFunction()) { + if (!value.isObject() || !value.toObject().is()) { JS_ReportError(cx, "Second argument must be a timeout function"); return false; } @@ -3330,11 +3330,11 @@ DecompileFunctionSomehow(JSContext *cx, unsigned argc, Value *vp, JSString *(*decompiler)(JSContext *, JSFunction *, unsigned)) { CallArgs args = CallArgsFromVp(argc, vp); - if (args.length() < 1 || !args[0].isObject() || !args[0].toObject().isFunction()) { + if (args.length() < 1 || !args[0].isObject() || !args[0].toObject().is()) { args.rval().setUndefined(); return true; } - JSString *result = decompiler(cx, args[0].toObject().toFunction(), 0); + JSString *result = decompiler(cx, &args[0].toObject().as(), 0); if (!result) return false; args.rval().setString(result); diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp index f60f069d8ea7..a08eab9e2494 100644 --- a/js/src/vm/Debugger.cpp +++ b/js/src/vm/Debugger.cpp @@ -2904,7 +2904,7 @@ DebuggerScript_getChildScripts(JSContext *cx, unsigned argc, Value *vp) RootedObject obj(cx), s(cx); for (uint32_t i = script->innerObjectsStart(); i < objects->length; i++) { obj = objects->vector[i]; - if (obj->isFunction()) { + if (obj->is()) { fun = static_cast(obj.get()); funScript = fun->nonLazyScript(); s = dbg->wrapScript(cx, funScript); @@ -3853,7 +3853,7 @@ static JSBool DebuggerArguments_getArg(JSContext *cx, unsigned argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); - int32_t i = args.callee().toFunction()->getExtendedSlot(0).toInt32(); + int32_t i = args.callee().as().getExtendedSlot(0).toInt32(); /* Check that the this value is an Arguments object. */ if (!args.thisv().isObject()) { @@ -4402,12 +4402,12 @@ static JSBool DebuggerObject_getName(JSContext *cx, unsigned argc, Value *vp) { THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "get name", args, dbg, obj); - if (!obj->isFunction()) { + if (!obj->is()) { args.rval().setUndefined(); return true; } - JSString *name = obj->toFunction()->atom(); + JSString *name = obj->as().atom(); if (!name) { args.rval().setUndefined(); return true; @@ -4424,12 +4424,12 @@ static JSBool DebuggerObject_getDisplayName(JSContext *cx, unsigned argc, Value *vp) { THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "get display name", args, dbg, obj); - if (!obj->isFunction()) { + if (!obj->is()) { args.rval().setUndefined(); return true; } - JSString *name = obj->toFunction()->displayAtom(); + JSString *name = obj->as().displayAtom(); if (!name) { args.rval().setUndefined(); return true; @@ -4446,12 +4446,12 @@ static JSBool DebuggerObject_getParameterNames(JSContext *cx, unsigned argc, Value *vp) { THIS_DEBUGOBJECT_REFERENT(cx, argc, vp, "get parameterNames", args, obj); - if (!obj->isFunction()) { + if (!obj->is()) { args.rval().setUndefined(); return true; } - RootedFunction fun(cx, obj->toFunction()); + RootedFunction fun(cx, &obj->as()); JSObject *result = NewDenseAllocatedArray(cx, fun->nargs); if (!result) return false; @@ -4488,12 +4488,12 @@ DebuggerObject_getScript(JSContext *cx, unsigned argc, Value *vp) { THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "get script", args, dbg, obj); - if (!obj->isFunction()) { + if (!obj->is()) { args.rval().setUndefined(); return true; } - RootedFunction fun(cx, obj->toFunction()); + RootedFunction fun(cx, &obj->as()); if (fun->isBuiltin()) { args.rval().setUndefined(); return true; @@ -4514,7 +4514,7 @@ DebuggerObject_getEnvironment(JSContext *cx, unsigned argc, Value *vp) THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "get environment", args, dbg, obj); /* Don't bother switching compartments just to check obj's type and get its env. */ - if (!obj->isFunction() || !obj->toFunction()->isInterpreted()) { + if (!obj->is() || !obj->as().isInterpreted()) { args.rval().setUndefined(); return true; } @@ -4522,7 +4522,7 @@ DebuggerObject_getEnvironment(JSContext *cx, unsigned argc, Value *vp) Rooted env(cx); { AutoCompartment ac(cx, obj); - RootedFunction fun(cx, obj->toFunction()); + RootedFunction fun(cx, &obj->as()); env = GetDebugScopeForFunction(cx, fun); if (!env) return false; diff --git a/js/src/vm/ForkJoin.cpp b/js/src/vm/ForkJoin.cpp index 2d23d5859536..82038f6cf78a 100644 --- a/js/src/vm/ForkJoin.cpp +++ b/js/src/vm/ForkJoin.cpp @@ -452,7 +452,7 @@ bool js::ForkJoin(JSContext *cx, CallArgs &args) { JS_ASSERT(args[0].isObject()); // else the self-hosted code is wrong - JS_ASSERT(args[0].toObject().isFunction()); + JS_ASSERT(args[0].toObject().is()); ForkJoinMode mode = ForkJoinModeNormal; if (args.length() > 1) { @@ -629,10 +629,10 @@ js::ParallelDo::enqueueInitialScript(ExecutionStatus *status) // RedLight: fatal error or fell back to sequential // The kernel should be a self-hosted function. - if (!fun_->isFunction()) + if (!fun_->is()) return sequentialExecution(true, status); - RootedFunction callee(cx_, fun_->toFunction()); + RootedFunction callee(cx_, &fun_->as()); if (!callee->isInterpreted() || !callee->isSelfHostedBuiltin()) return sequentialExecution(true, status); @@ -1213,7 +1213,7 @@ js::ParallelDo::recoverFromBailout(ExecutionStatus *status) // After any bailout, we always scan over callee list of main // function, if nothing else - RootedScript mainScript(cx_, fun_->toFunction()->nonLazyScript()); + RootedScript mainScript(cx_, fun_->as().nonLazyScript()); if (!addToWorklist(mainScript)) return fatalError(status); @@ -1462,8 +1462,8 @@ ForkJoinShared::executePortion(PerThreadData *perThread, JS_ASSERT(slice.bailoutRecord->topScript == NULL); RootedObject fun(perThread, fun_); - JS_ASSERT(fun->isFunction()); - RootedFunction callee(perThread, fun->toFunction()); + JS_ASSERT(fun->is()); + RootedFunction callee(perThread, &fun->as()); if (!callee->nonLazyScript()->hasParallelIonScript()) { // Sometimes, particularly with GCZeal, the parallel ion // script can be collected between starting the parallel diff --git a/js/src/vm/GlobalObject.cpp b/js/src/vm/GlobalObject.cpp index 07d40d96abb0..64ccfca8167b 100644 --- a/js/src/vm/GlobalObject.cpp +++ b/js/src/vm/GlobalObject.cpp @@ -200,11 +200,11 @@ GlobalObject::initFunctionAndObjectClasses(JSContext *cx) /* Create |Function.prototype| next so we can create other functions. */ RootedFunction functionProto(cx); { - JSObject *functionProto_ = NewObjectWithGivenProto(cx, &FunctionClass, objectProto, self, - SingletonObject); + JSObject *functionProto_ = NewObjectWithGivenProto(cx, &JSFunction::class_, + objectProto, self, SingletonObject); if (!functionProto_) return NULL; - functionProto = functionProto_->toFunction(); + functionProto = &functionProto_->as(); /* * Bizarrely, |Function.prototype| must be an interpreted function, so @@ -260,15 +260,15 @@ GlobalObject::initFunctionAndObjectClasses(JSContext *cx) * inference to have unknown properties, to simplify handling of e.g. * CloneFunctionObject. */ - if (!setNewTypeUnknown(cx, &FunctionClass, functionProto)) + if (!setNewTypeUnknown(cx, &JSFunction::class_, functionProto)) return NULL; } /* Create the Object function now that we have a [[Prototype]] for it. */ RootedFunction objectCtor(cx); { - RootedObject ctor(cx, NewObjectWithGivenProto(cx, &FunctionClass, functionProto, self, - SingletonObject)); + RootedObject ctor(cx, NewObjectWithGivenProto(cx, &JSFunction::class_, functionProto, + self, SingletonObject)); if (!ctor) return NULL; RootedAtom objectAtom(cx, cx->names().Object); @@ -288,8 +288,8 @@ GlobalObject::initFunctionAndObjectClasses(JSContext *cx) RootedFunction functionCtor(cx); { // Note that ctor is rooted purely for the JS_ASSERT at the end - RootedObject ctor(cx, NewObjectWithGivenProto(cx, &FunctionClass, functionProto, self, - SingletonObject)); + RootedObject ctor(cx, NewObjectWithGivenProto(cx, &JSFunction::class_, functionProto, + self, SingletonObject)); if (!ctor) return NULL; RootedAtom functionAtom(cx, cx->names().Function); @@ -509,7 +509,7 @@ static JSObject * CreateBlankProto(JSContext *cx, Class *clasp, JSObject &proto, GlobalObject &global) { JS_ASSERT(clasp != &ObjectClass); - JS_ASSERT(clasp != &FunctionClass); + JS_ASSERT(clasp != &JSFunction::class_); RootedObject blankProto(cx, NewObjectWithGivenProto(cx, clasp, &proto, &global, SingletonObject)); if (!blankProto) diff --git a/js/src/vm/Interpreter-inl.h b/js/src/vm/Interpreter-inl.h index a8fb6e1e5d7b..2ca61074a521 100644 --- a/js/src/vm/Interpreter-inl.h +++ b/js/src/vm/Interpreter-inl.h @@ -940,8 +940,8 @@ UrshOperation(JSContext *cx, HandleScript script, jsbytecode *pc, inline JSFunction * ReportIfNotFunction(JSContext *cx, const Value &v, MaybeConstruct construct = NO_CONSTRUCT) { - if (v.isObject() && v.toObject().isFunction()) - return v.toObject().toFunction(); + if (v.isObject() && v.toObject().is()) + return &v.toObject().as(); ReportIsNotFunction(cx, v, -1, construct); return NULL; @@ -978,8 +978,8 @@ class FastInvokeGuard } void initFunction(const Value &fval) { - if (fval.isObject() && fval.toObject().isFunction()) { - JSFunction *fun = fval.toObject().toFunction(); + if (fval.isObject() && fval.toObject().is()) { + JSFunction *fun = &fval.toObject().as(); if (fun->isInterpreted()) fun_ = fun; } diff --git a/js/src/vm/Interpreter.cpp b/js/src/vm/Interpreter.cpp index 2078428daa31..76f5cce4a997 100644 --- a/js/src/vm/Interpreter.cpp +++ b/js/src/vm/Interpreter.cpp @@ -162,7 +162,7 @@ js::BoxNonStrictThis(JSContext *cx, const CallReceiver &call) JS_ASSERT(!thisv.isMagic()); #ifdef DEBUG - JSFunction *fun = call.callee().isFunction() ? call.callee().toFunction() : NULL; + JSFunction *fun = call.callee().is() ? &call.callee().as() : NULL; JS_ASSERT_IF(fun && fun->isInterpreted(), !fun->strict()); #endif @@ -436,7 +436,7 @@ js::Invoke(JSContext *cx, CallArgs args, MaybeConstruct construct) Class *clasp = callee.getClass(); /* Invoke non-functions. */ - if (JS_UNLIKELY(clasp != &FunctionClass)) { + if (JS_UNLIKELY(clasp != &JSFunction::class_)) { #if JS_HAS_NO_SUCH_METHOD if (JS_UNLIKELY(clasp == &js_NoSuchMethodClass)) return NoSuchMethod(cx, args.length(), args.base()); @@ -448,7 +448,7 @@ js::Invoke(JSContext *cx, CallArgs args, MaybeConstruct construct) } /* Invoke native functions. */ - JSFunction *fun = callee.toFunction(); + JSFunction *fun = &callee.as(); JS_ASSERT_IF(construct, !fun->isNativeConstructor()); if (fun->isNative()) return CallJSNative(cx, fun->native(), args); @@ -511,7 +511,7 @@ js::Invoke(JSContext *cx, const Value &thisv, const Value &fval, unsigned argc, bool js::InvokeConstructor(JSContext *cx, CallArgs args) { - JS_ASSERT(!FunctionClass.construct); + JS_ASSERT(!JSFunction::class_.construct); args.setThis(MagicValue(JS_IS_CONSTRUCTING)); @@ -519,8 +519,8 @@ js::InvokeConstructor(JSContext *cx, CallArgs args) return ReportIsNotFunction(cx, args.calleev().get(), args.length() + 1, CONSTRUCT); JSObject &callee = args.callee(); - if (callee.isFunction()) { - RootedFunction fun(cx, callee.toFunction()); + if (callee.is()) { + RootedFunction fun(cx, &callee.as()); if (fun->isNativeConstructor()) { bool ok = CallJSNativeConstructor(cx, fun->native(), args); @@ -3281,7 +3281,7 @@ js::Lambda(JSContext *cx, HandleFunction fun, HandleObject parent) clone = js_fun_bind(cx, clone, thisval, NULL, 0); if (!clone) return NULL; - clone->toFunction()->flags |= JSFunction::ARROW; + clone->as().flags |= JSFunction::ARROW; } JS_ASSERT(clone->global() == clone->global()); diff --git a/js/src/vm/Interpreter.h b/js/src/vm/Interpreter.h index 9447dfaa9e2c..6e465703539d 100644 --- a/js/src/vm/Interpreter.h +++ b/js/src/vm/Interpreter.h @@ -262,7 +262,7 @@ class InvokeState : public RunState public: InvokeState(JSContext *cx, CallArgs &args, InitialFrameFlags initial) - : RunState(cx, Invoke, args.callee().toFunction()->nonLazyScript()), + : RunState(cx, Invoke, args.callee().as().nonLazyScript()), args_(args), initial_(initial), useNewType_(false) diff --git a/js/src/vm/ScopeObject-inl.h b/js/src/vm/ScopeObject-inl.h index 55ac0e616899..255037f76723 100644 --- a/js/src/vm/ScopeObject-inl.h +++ b/js/src/vm/ScopeObject-inl.h @@ -86,14 +86,14 @@ CallObject::isForEval() const { JS_ASSERT(getReservedSlot(CALLEE_SLOT).isObjectOrNull()); JS_ASSERT_IF(getReservedSlot(CALLEE_SLOT).isObject(), - getReservedSlot(CALLEE_SLOT).toObject().isFunction()); + getReservedSlot(CALLEE_SLOT).toObject().is()); return getReservedSlot(CALLEE_SLOT).isNull(); } inline JSFunction & CallObject::callee() const { - return *getReservedSlot(CALLEE_SLOT).toObject().toFunction(); + return getReservedSlot(CALLEE_SLOT).toObject().as(); } inline const Value & diff --git a/js/src/vm/ScopeObject.cpp b/js/src/vm/ScopeObject.cpp index a7e99f9c4e01..269879b6294d 100644 --- a/js/src/vm/ScopeObject.cpp +++ b/js/src/vm/ScopeObject.cpp @@ -32,7 +32,7 @@ typedef Rooted RootedArgumentsObject; StaticScopeIter::StaticScopeIter(JSContext *cx, JSObject *objArg) : obj(cx, objArg), onNamedLambda(false) { - JS_ASSERT_IF(obj, obj->is() || obj->isFunction()); + JS_ASSERT_IF(obj, obj->is() || obj->is()); } bool @@ -46,14 +46,14 @@ StaticScopeIter::operator++(int) { if (obj->is()) { obj = obj->as().enclosingStaticScope(); - } else if (onNamedLambda || !obj->toFunction()->isNamedLambda()) { + } else if (onNamedLambda || !obj->as().isNamedLambda()) { onNamedLambda = false; - obj = obj->toFunction()->nonLazyScript()->enclosingStaticScope(); + obj = obj->as().nonLazyScript()->enclosingStaticScope(); } else { onNamedLambda = true; } - JS_ASSERT_IF(obj, obj->is() || obj->isFunction()); - JS_ASSERT_IF(onNamedLambda, obj->isFunction()); + JS_ASSERT_IF(obj, obj->is() || obj->is()); + JS_ASSERT_IF(onNamedLambda, obj->is()); } bool @@ -61,7 +61,7 @@ StaticScopeIter::hasDynamicScopeObject() const { return obj->is() ? obj->as().needsClone() - : obj->toFunction()->isHeavyweight(); + : obj->as().isHeavyweight(); } Shape * @@ -93,7 +93,7 @@ JSScript * StaticScopeIter::funScript() const { JS_ASSERT(type() == FUNCTION); - return obj->toFunction()->nonLazyScript(); + return obj->as().nonLazyScript(); } /*****************************************************************************/ diff --git a/js/src/vm/SelfHosting.cpp b/js/src/vm/SelfHosting.cpp index 1d7f3f051e54..250a2c7cdffc 100644 --- a/js/src/vm/SelfHosting.cpp +++ b/js/src/vm/SelfHosting.cpp @@ -217,7 +217,7 @@ intrinsic_MakeConstructible(JSContext *cx, unsigned argc, Value *vp) CallArgs args = CallArgsFromVp(argc, vp); JS_ASSERT(args.length() == 2); JS_ASSERT(args[0].isObject()); - JS_ASSERT(args[0].toObject().isFunction()); + JS_ASSERT(args[0].toObject().is()); JS_ASSERT(args[1].isObject()); // Normal .prototype properties aren't enumerable. But for this to clone @@ -230,7 +230,7 @@ intrinsic_MakeConstructible(JSContext *cx, unsigned argc, Value *vp) return false; } - ctor->toFunction()->setIsSelfHostedConstructor(); + ctor->as().setIsSelfHostedConstructor(); args.rval().setUndefined(); return true; } @@ -241,8 +241,8 @@ intrinsic_MakeWrappable(JSContext *cx, unsigned argc, Value *vp) CallArgs args = CallArgsFromVp(argc, vp); JS_ASSERT(args.length() >= 1); JS_ASSERT(args[0].isObject()); - JS_ASSERT(args[0].toObject().isFunction()); - args[0].toObject().toFunction()->makeWrappable(); + JS_ASSERT(args[0].toObject().is()); + args[0].toObject().as().makeWrappable(); args.rval().setUndefined(); return true; } @@ -290,10 +290,10 @@ intrinsic_SetScriptHints(JSContext *cx, unsigned argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); JS_ASSERT(args.length() >= 2); - JS_ASSERT(args[0].isObject() && args[0].toObject().isFunction()); + JS_ASSERT(args[0].isObject() && args[0].toObject().is()); JS_ASSERT(args[1].isObject()); - RootedFunction fun(cx, args[0].toObject().toFunction()); + RootedFunction fun(cx, &args[0].toObject().as()); RootedScript funScript(cx, fun->nonLazyScript()); RootedObject flags(cx, &args[1].toObject()); @@ -360,9 +360,9 @@ js::intrinsic_NewParallelArray(JSContext *cx, unsigned argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); - JS_ASSERT(args[0].isObject() && args[0].toObject().isFunction()); + JS_ASSERT(args[0].isObject() && args[0].toObject().is()); - RootedFunction init(cx, args[0].toObject().toFunction()); + RootedFunction init(cx, &args[0].toObject().as()); CallArgs args0 = CallArgsFromVp(argc - 1, vp + 1); if (!js::ParallelArrayObject::constructHelper(cx, &init, args0)) return false; @@ -783,13 +783,13 @@ CloneObject(JSContext *cx, HandleObject srcObj, CloneMemory &clonedObjects) if (p) return p->value; RootedObject clone(cx); - if (srcObj->isFunction()) { - if (srcObj->toFunction()->isWrappable()) { + if (srcObj->is()) { + if (srcObj->as().isWrappable()) { clone = srcObj; if (!cx->compartment()->wrap(cx, clone.address())) return NULL; } else { - RootedFunction fun(cx, srcObj->toFunction()); + RootedFunction fun(cx, &srcObj->as()); clone = CloneFunctionObject(cx, fun, cx->global(), fun->getAllocKind(), TenuredObject); } } else if (srcObj->is()) { @@ -862,7 +862,7 @@ JSRuntime::cloneSelfHostedFunctionScript(JSContext *cx, Handle na if (!GetUnclonedValue(cx, shg, id, &funVal)) return false; - RootedFunction sourceFun(cx, funVal.toObject().toFunction()); + RootedFunction sourceFun(cx, &funVal.toObject().as()); RootedScript sourceScript(cx, sourceFun->nonLazyScript()); JS_ASSERT(!sourceScript->enclosingStaticScope()); JSScript *cscript = CloneScript(cx, NullPtr(), targetFun, sourceScript); @@ -910,7 +910,7 @@ JSRuntime::maybeWrappedSelfHostedFunction(JSContext *cx, Handle n JS_ASSERT(funVal.isObject()); JS_ASSERT(funVal.toObject().isCallable()); - if (!funVal.toObject().toFunction()->isWrappable()) { + if (!funVal.toObject().as().isWrappable()) { funVal.setUndefined(); return true; } diff --git a/js/src/vm/Stack.cpp b/js/src/vm/Stack.cpp index 567d0daf2784..0c8ef3e1b023 100644 --- a/js/src/vm/Stack.cpp +++ b/js/src/vm/Stack.cpp @@ -907,7 +907,7 @@ ContextStack::pushInvokeFrame(JSContext *cx, const CallArgs &args, InitialFrameFlags initial, InvokeFrameGuard *ifg) { JSObject &callee = args.callee(); - JSFunction *fun = callee.toFunction(); + JSFunction *fun = &callee.as(); if (!pushInvokeFrame(cx, REPORT_ERROR, args, fun, initial, ifg)) return false; return true; diff --git a/js/src/vm/Stack.h b/js/src/vm/Stack.h index 0a277ffbf9fd..a2d6345b68da 100644 --- a/js/src/vm/Stack.h +++ b/js/src/vm/Stack.h @@ -706,7 +706,7 @@ class StackFrame JSFunction &callee() const { JS_ASSERT(isFunctionFrame()); - return *calleev().toObject().toFunction(); + return calleev().toObject().as(); } const Value &calleev() const { diff --git a/xpcom/base/CycleCollectedJSRuntime.cpp b/xpcom/base/CycleCollectedJSRuntime.cpp index 3cbdea046390..4ed82709985d 100644 --- a/xpcom/base/CycleCollectedJSRuntime.cpp +++ b/xpcom/base/CycleCollectedJSRuntime.cpp @@ -538,7 +538,7 @@ CycleCollectedJSRuntime::DescribeGCThing(bool aIsMarked, void* aThing, // Give the subclass a chance to do something if (DescribeCustomObjects(obj, clasp, name)) { // Nothing else to do! - } else if (clasp == &js::FunctionClass) { + } else if (js::IsFunctionObject(obj)) { JSFunction* fun = JS_GetObjectFunction(obj); JSString* str = JS_GetFunctionDisplayId(fun); if (str) {