示例#1
0
ArgumentsObject*
ArgumentsObject::createTemplateObject(JSContext* cx, bool mapped)
{
    const Class* clasp = mapped
                         ? &MappedArgumentsObject::class_
                         : &UnmappedArgumentsObject::class_;

    RootedObject proto(cx, cx->global()->getOrCreateObjectPrototype(cx));
    if (!proto)
        return nullptr;

    RootedObjectGroup group(cx, ObjectGroup::defaultNewGroup(cx, clasp, TaggedProto(proto.get())));
    if (!group)
        return nullptr;

    RootedShape shape(cx, EmptyShape::getInitialShape(cx, clasp, TaggedProto(proto),
                                                      FINALIZE_KIND, BaseShape::INDEXED));
    if (!shape)
        return nullptr;

    AutoSetNewObjectMetadata metadata(cx);
    JSObject* base = JSObject::create(cx, FINALIZE_KIND, gc::TenuredHeap, shape, group);
    if (!base)
        return nullptr;

    ArgumentsObject* obj = &base->as<js::ArgumentsObject>();
    obj->initFixedSlot(ArgumentsObject::DATA_SLOT, PrivateValue(nullptr));
    return obj;
}
示例#2
0
/* static */ ArgumentsObject*
ArgumentsObject::create(JSContext* cx, HandleFunction callee, unsigned numActuals, CopyArgs& copy)
{
    bool mapped = callee->nonLazyScript()->hasMappedArgsObj();
    ArgumentsObject* templateObj = cx->compartment()->getOrCreateArgumentsTemplateObject(cx, mapped);
    if (!templateObj)
        return nullptr;

    RootedShape shape(cx, templateObj->lastProperty());
    RootedObjectGroup group(cx, templateObj->group());

    unsigned numFormals = callee->nargs();
    unsigned numArgs = Max(numActuals, numFormals);
    unsigned numBytes = ArgumentsData::bytesRequired(numArgs);

    Rooted<ArgumentsObject*> obj(cx);
    ArgumentsData* data = nullptr;
    {
        // The copyArgs call below can allocate objects, so add this block scope
        // to make sure we set the metadata for this arguments object first.
        AutoSetNewObjectMetadata metadata(cx);

        JSObject* base = JSObject::create(cx, FINALIZE_KIND, gc::DefaultHeap, shape, group);
        if (!base)
            return nullptr;
        obj = &base->as<ArgumentsObject>();

        data =
            reinterpret_cast<ArgumentsData*>(AllocateObjectBuffer<uint8_t>(cx, obj, numBytes));
        if (!data) {
            // Make the object safe for GC.
            obj->initFixedSlot(DATA_SLOT, PrivateValue(nullptr));
            return nullptr;
        }

        data->numArgs = numArgs;
        data->rareData = nullptr;

        // Zero the argument Values. This sets each value to DoubleValue(0), which
        // is safe for GC tracing.
        memset(data->args, 0, numArgs * sizeof(Value));
        MOZ_ASSERT(DoubleValue(0).asRawBits() == 0x0);
        MOZ_ASSERT_IF(numArgs > 0, data->args[0].asRawBits() == 0x0);

        obj->initFixedSlot(DATA_SLOT, PrivateValue(data));
        obj->initFixedSlot(CALLEE_SLOT, ObjectValue(*callee));
    }
    MOZ_ASSERT(data != nullptr);

    /* Copy [0, numArgs) into data->slots. */
    copy.copyArgs(cx, data->args, numArgs);

    obj->initFixedSlot(INITIAL_LENGTH_SLOT, Int32Value(numActuals << PACKED_BITS_COUNT));

    copy.maybeForwardToCallObject(obj, data);

    MOZ_ASSERT(obj->initialLength() == numActuals);
    MOZ_ASSERT(!obj->hasOverriddenLength());
    return obj;
}
示例#3
0
/* static */ size_t
ArgumentsObject::objectMoved(JSObject* dst, JSObject* src)
{
    ArgumentsObject* ndst = &dst->as<ArgumentsObject>();
    const ArgumentsObject* nsrc = &src->as<ArgumentsObject>();
    MOZ_ASSERT(ndst->data() == nsrc->data());

    if (!IsInsideNursery(src))
        return 0;

    Nursery& nursery = dst->zone()->group()->nursery();

    size_t nbytesTotal = 0;
    if (!nursery.isInside(nsrc->data())) {
        nursery.removeMallocedBuffer(nsrc->data());
    } else {
        AutoEnterOOMUnsafeRegion oomUnsafe;
        uint32_t nbytes = ArgumentsData::bytesRequired(nsrc->data()->numArgs);
        uint8_t* data = nsrc->zone()->pod_malloc<uint8_t>(nbytes);
        if (!data)
            oomUnsafe.crash("Failed to allocate ArgumentsObject data while tenuring.");
        ndst->initFixedSlot(DATA_SLOT, PrivateValue(data));

        mozilla::PodCopy(data, reinterpret_cast<uint8_t*>(nsrc->data()), nbytes);
        nbytesTotal += nbytes;
    }

    if (RareArgumentsData* srcRareData = nsrc->maybeRareData()) {
        if (!nursery.isInside(srcRareData)) {
            nursery.removeMallocedBuffer(srcRareData);
        } else {
            AutoEnterOOMUnsafeRegion oomUnsafe;
            uint32_t nbytes = RareArgumentsData::bytesRequired(nsrc->initialLength());
            uint8_t* dstRareData = nsrc->zone()->pod_malloc<uint8_t>(nbytes);
            if (!dstRareData)
                oomUnsafe.crash("Failed to allocate RareArgumentsData data while tenuring.");
            ndst->data()->rareData = (RareArgumentsData*)dstRareData;

            mozilla::PodCopy(dstRareData, reinterpret_cast<uint8_t*>(srcRareData), nbytes);
            nbytesTotal += nbytes;
        }
    }

    return nbytesTotal;
}
示例#4
0
ArgumentsObject *
ArgumentsObject::create(JSContext *cx, StackFrame *fp)
{
    JS_ASSERT(fp->script()->needsArgsObj());

    ArgumentsObject *argsobj = ArgumentsObject::create(cx, fp->numActualArgs(),
                                                       RootedVarObject(cx, &fp->callee()));
    if (!argsobj)
        return NULL;

    /*
     * Strict mode functions have arguments objects that copy the initial
     * actual parameter values. Non-strict mode arguments use the frame pointer
     * to retrieve up-to-date parameter values.
     */
    if (argsobj->isStrictArguments())
        fp->forEachCanonicalActualArg(PutArg(cx->compartment, *argsobj));
    else
        argsobj->setStackFrame(fp);

    fp->initArgsObj(*argsobj);
    return argsobj;
}
示例#5
0
/* static */ size_t
ArgumentsObject::objectMovedDuringMinorGC(JSTracer* trc, JSObject* dst, JSObject* src)
{
    ArgumentsObject* ndst = &dst->as<ArgumentsObject>();
    ArgumentsObject* nsrc = &src->as<ArgumentsObject>();
    MOZ_ASSERT(ndst->data() == nsrc->data());

    Nursery& nursery = trc->runtime()->gc.nursery;

    if (!nursery.isInside(nsrc->data())) {
        nursery.removeMallocedBuffer(nsrc->data());
        return 0;
    }

    AutoEnterOOMUnsafeRegion oomUnsafe;
    uint32_t nbytes = nsrc->data()->dataBytes;
    uint8_t* data = nsrc->zone()->pod_malloc<uint8_t>(nbytes);
    if (!data)
        oomUnsafe.crash("Failed to allocate ArgumentsObject data while tenuring.");
    ndst->initFixedSlot(DATA_SLOT, PrivateValue(data));

    mozilla::PodCopy(data, reinterpret_cast<uint8_t*>(nsrc->data()), nbytes);

    ArgumentsData* dstData = ndst->data();
    dstData->deletedBits = reinterpret_cast<size_t*>(dstData->args + dstData->numArgs);

    return nbytes;
}
示例#6
0
 PutArg(JSCompartment *comp, ArgumentsObject &argsobj)
   : compartment(comp), argsobj(argsobj), dst(argsobj.data()->slots) {}