bool
CodeGeneratorX86Shared::visitPowHalfD(LPowHalfD *ins)
{
    FloatRegister input = ToFloatRegister(ins->input());
    JS_ASSERT(input == ToFloatRegister(ins->output()));

    Label done, sqrt;

    // Branch if not -Infinity.
    masm.loadConstantDouble(NegativeInfinity(), ScratchFloatReg);
    masm.branchDouble(Assembler::DoubleNotEqualOrUnordered, input, ScratchFloatReg, &sqrt);

    // Math.pow(-Infinity, 0.5) == Infinity.
    masm.xorpd(input, input);
    masm.subsd(ScratchFloatReg, input);
    masm.jump(&done);

    // Math.pow(-0, 0.5) == 0 == Math.pow(0, 0.5). Adding 0 converts any -0 to 0.
    masm.bind(&sqrt);
    masm.xorpd(ScratchFloatReg, ScratchFloatReg);
    masm.addsd(ScratchFloatReg, input);
    masm.sqrtsd(input, input);

    masm.bind(&done);
    return true;
}
Example #2
0
static void
TestExponentComponent()
{
  MOZ_ASSERT(ExponentComponent(0.0) == -int_fast16_t(DoubleExponentBias));
  MOZ_ASSERT(ExponentComponent(-0.0) == -int_fast16_t(DoubleExponentBias));
  MOZ_ASSERT(ExponentComponent(0.125) == -3);
  MOZ_ASSERT(ExponentComponent(0.5) == -1);
  MOZ_ASSERT(ExponentComponent(1.0) == 0);
  MOZ_ASSERT(ExponentComponent(1.5) == 0);
  MOZ_ASSERT(ExponentComponent(2.0) == 1);
  MOZ_ASSERT(ExponentComponent(7) == 2);
  MOZ_ASSERT(ExponentComponent(PositiveInfinity()) == DoubleExponentBias + 1);
  MOZ_ASSERT(ExponentComponent(NegativeInfinity()) == DoubleExponentBias + 1);
  MOZ_ASSERT(ExponentComponent(UnspecifiedNaN()) == DoubleExponentBias + 1);
}
Example #3
0
bool
js_math_max(JSContext *cx, unsigned argc, Value *vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);

    double maxval = NegativeInfinity();
    for (unsigned i = 0; i < args.length(); i++) {
        double x;
        if (!ToNumber(cx, args[i], &x))
            return false;
        // Math.max(num, NaN) => NaN, Math.max(-0, +0) => +0
        if (x > maxval || IsNaN(x) || (x == maxval && IsNegative(maxval)))
            maxval = x;
    }
    args.rval().setNumber(maxval);
    return true;
}
Example #4
0
JSRuntime::JSRuntime(JSUseHelperThreads useHelperThreads)
  : JS::shadow::Runtime(
#ifdef JSGC_GENERATIONAL
        &gcStoreBuffer
#endif
    ),
    mainThread(this),
    interrupt(0),
    handlingSignal(false),
    operationCallback(nullptr),
#ifdef JS_THREADSAFE
    operationCallbackLock(nullptr),
    operationCallbackOwner(nullptr),
#else
    operationCallbackLockTaken(false),
#endif
#ifdef JS_WORKER_THREADS
    workerThreadState(nullptr),
    exclusiveAccessLock(nullptr),
    exclusiveAccessOwner(nullptr),
    mainThreadHasExclusiveAccess(false),
    numExclusiveThreads(0),
#endif
    systemZone(nullptr),
    numCompartments(0),
    localeCallbacks(nullptr),
    defaultLocale(nullptr),
    defaultVersion_(JSVERSION_DEFAULT),
#ifdef JS_THREADSAFE
    ownerThread_(nullptr),
#endif
    tempLifoAlloc(TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE),
    freeLifoAlloc(TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE),
    execAlloc_(nullptr),
    bumpAlloc_(nullptr),
    jitRuntime_(nullptr),
    selfHostingGlobal_(nullptr),
    nativeStackBase(0),
    cxCallback(nullptr),
    destroyCompartmentCallback(nullptr),
    destroyZoneCallback(nullptr),
    sweepZoneCallback(nullptr),
    compartmentNameCallback(nullptr),
    activityCallback(nullptr),
    activityCallbackArg(nullptr),
#ifdef JS_THREADSAFE
    requestDepth(0),
# ifdef DEBUG
    checkRequestDepth(0),
# endif
#endif
    gcSystemAvailableChunkListHead(nullptr),
    gcUserAvailableChunkListHead(nullptr),
    gcBytes(0),
    gcMaxBytes(0),
    gcMaxMallocBytes(0),
    gcNumArenasFreeCommitted(0),
    gcMarker(this),
    gcVerifyPreData(nullptr),
    gcVerifyPostData(nullptr),
    gcChunkAllocationSinceLastGC(false),
    gcNextFullGCTime(0),
    gcLastGCTime(0),
    gcJitReleaseTime(0),
    gcAllocationThreshold(30 * 1024 * 1024),
    gcHighFrequencyGC(false),
    gcHighFrequencyTimeThreshold(1000),
    gcHighFrequencyLowLimitBytes(100 * 1024 * 1024),
    gcHighFrequencyHighLimitBytes(500 * 1024 * 1024),
    gcHighFrequencyHeapGrowthMax(3.0),
    gcHighFrequencyHeapGrowthMin(1.5),
    gcLowFrequencyHeapGrowth(1.5),
    gcDynamicHeapGrowth(false),
    gcDynamicMarkSlice(false),
    gcDecommitThreshold(32 * 1024 * 1024),
    gcShouldCleanUpEverything(false),
    gcGrayBitsValid(false),
    gcIsNeeded(0),
    gcStats(thisFromCtor()),
    gcNumber(0),
    gcStartNumber(0),
    gcIsFull(false),
    gcTriggerReason(JS::gcreason::NO_REASON),
    gcStrictCompartmentChecking(false),
#ifdef DEBUG
    gcDisableStrictProxyCheckingCount(0),
#endif
    gcIncrementalState(gc::NO_INCREMENTAL),
    gcLastMarkSlice(false),
    gcSweepOnBackgroundThread(false),
    gcFoundBlackGrayEdges(false),
    gcSweepingZones(nullptr),
    gcZoneGroupIndex(0),
    gcZoneGroups(nullptr),
    gcCurrentZoneGroup(nullptr),
    gcSweepPhase(0),
    gcSweepZone(nullptr),
    gcSweepKindIndex(0),
    gcAbortSweepAfterCurrentGroup(false),
    gcArenasAllocatedDuringSweep(nullptr),
#ifdef DEBUG
    gcMarkingValidator(nullptr),
#endif
    gcInterFrameGC(0),
    gcSliceBudget(SliceBudget::Unlimited),
    gcIncrementalEnabled(true),
    gcGenerationalEnabled(true),
    gcManipulatingDeadZones(false),
    gcObjectsMarkedInDeadZones(0),
    gcPoke(false),
    heapState(Idle),
#ifdef JSGC_GENERATIONAL
    gcNursery(thisFromCtor()),
    gcStoreBuffer(thisFromCtor(), gcNursery),
#endif
#ifdef JS_GC_ZEAL
    gcZeal_(0),
    gcZealFrequency(0),
    gcNextScheduled(0),
    gcDeterministicOnly(false),
    gcIncrementalLimit(0),
#endif
    gcValidate(true),
    gcFullCompartmentChecks(false),
    gcCallback(nullptr),
    gcSliceCallback(nullptr),
    gcFinalizeCallback(nullptr),
    gcMallocBytes(0),
    gcMallocGCTriggered(false),
    scriptAndCountsVector(nullptr),
    NaNValue(DoubleNaNValue()),
    negativeInfinityValue(DoubleValue(NegativeInfinity())),
    positiveInfinityValue(DoubleValue(PositiveInfinity())),
    emptyString(nullptr),
    debugMode(false),
    spsProfiler(thisFromCtor()),
    profilingScripts(false),
    alwaysPreserveCode(false),
    hadOutOfMemory(false),
    haveCreatedContext(false),
    data(nullptr),
    gcLock(nullptr),
    gcLockOwner(nullptr),
    gcHelperThread(thisFromCtor()),
    signalHandlersInstalled_(false),
    defaultFreeOp_(thisFromCtor(), false),
    debuggerMutations(0),
    securityCallbacks(const_cast<JSSecurityCallbacks *>(&NullSecurityCallbacks)),
    DOMcallbacks(nullptr),
    destroyPrincipals(nullptr),
    structuredCloneCallbacks(nullptr),
    telemetryCallback(nullptr),
    propertyRemovals(0),
#if !EXPOSE_INTL_API
    thousandsSeparator(0),
    decimalSeparator(0),
    numGrouping(0),
#endif
    heapProtected_(false),
    mathCache_(nullptr),
    activeCompilations_(0),
    keepAtoms_(0),
    trustedPrincipals_(nullptr),
    atomsCompartment_(nullptr),
    beingDestroyed_(false),
    wrapObjectCallback(TransparentObjectWrapper),
    sameCompartmentWrapObjectCallback(nullptr),
    preWrapObjectCallback(nullptr),
    preserveWrapperCallback(nullptr),
#ifdef DEBUG
    noGCOrAllocationCheck(0),
#endif
    jitHardening(false),
    jitSupportsFloatingPoint(false),
    ionPcScriptCache(nullptr),
    threadPool(this),
    defaultJSContextCallback(nullptr),
    ctypesActivityCallback(nullptr),
    parallelWarmup(0),
    ionReturnOverride_(MagicValue(JS_ARG_POISON)),
    useHelperThreads_(useHelperThreads),
#ifdef JS_THREADSAFE
    cpuCount_(GetCPUCount()),
#else
    cpuCount_(1),
#endif
    parallelIonCompilationEnabled_(true),
    parallelParsingEnabled_(true),
    isWorkerRuntime_(false)
#ifdef DEBUG
    , enteredPolicy(nullptr)
#endif
{
    MOZ_ASSERT(cpuCount_ > 0, "GetCPUCount() seems broken");

    liveRuntimesCount++;

    setGCMode(JSGC_MODE_GLOBAL);

    /* Initialize infallibly first, so we can goto bad and JS_DestroyRuntime. */
    JS_INIT_CLIST(&onNewGlobalObjectWatchers);

    PodZero(&debugHooks);
    PodZero(&atomState);
    PodArrayZero(nativeStackQuota);
    PodZero(&asmJSCacheOps);

#if JS_STACK_GROWTH_DIRECTION > 0
    nativeStackLimit = UINTPTR_MAX;
#endif
}
static void
TestDoublesAreIdentical()
{
  ShouldBeIdentical(+0.0, +0.0);
  ShouldBeIdentical(-0.0, -0.0);
  ShouldNotBeIdentical(+0.0, -0.0);

  ShouldBeIdentical(1.0, 1.0);
  ShouldNotBeIdentical(-1.0, 1.0);
  ShouldBeIdentical(4294967295.0, 4294967295.0);
  ShouldNotBeIdentical(-4294967295.0, 4294967295.0);
  ShouldBeIdentical(4294967296.0, 4294967296.0);
  ShouldBeIdentical(4294967297.0, 4294967297.0);
  ShouldBeIdentical(1e300, 1e300);

  ShouldBeIdentical(PositiveInfinity(), PositiveInfinity());
  ShouldBeIdentical(NegativeInfinity(), NegativeInfinity());
  ShouldNotBeIdentical(PositiveInfinity(), NegativeInfinity());

  ShouldNotBeIdentical(-0.0, NegativeInfinity());
  ShouldNotBeIdentical(+0.0, NegativeInfinity());
  ShouldNotBeIdentical(1e300, NegativeInfinity());
  ShouldNotBeIdentical(3.141592654, NegativeInfinity());

  ShouldBeIdentical(UnspecifiedNaN(), UnspecifiedNaN());
  ShouldBeIdentical(-UnspecifiedNaN(), UnspecifiedNaN());
  ShouldBeIdentical(UnspecifiedNaN(), -UnspecifiedNaN());

  ShouldBeIdentical(SpecificNaN(0, 17), SpecificNaN(0, 42));
  ShouldBeIdentical(SpecificNaN(1, 17), SpecificNaN(1, 42));
  ShouldBeIdentical(SpecificNaN(0, 17), SpecificNaN(1, 42));
  ShouldBeIdentical(SpecificNaN(1, 17), SpecificNaN(0, 42));

  const uint64_t Mask = 0xfffffffffffffULL;
  for (unsigned i = 0; i < 52; i++) {
    for (unsigned j = 0; j < 52; j++) {
      for (unsigned sign = 0; i < 2; i++) {
        ShouldBeIdentical(SpecificNaN(0, 1ULL << i), SpecificNaN(sign, 1ULL << j));
        ShouldBeIdentical(SpecificNaN(1, 1ULL << i), SpecificNaN(sign, 1ULL << j));

        ShouldBeIdentical(SpecificNaN(0, Mask & ~(1ULL << i)),
                          SpecificNaN(sign, Mask & ~(1ULL << j)));
        ShouldBeIdentical(SpecificNaN(1, Mask & ~(1ULL << i)),
                          SpecificNaN(sign, Mask & ~(1ULL << j)));
      }
    }
  }
  ShouldBeIdentical(SpecificNaN(0, 17), SpecificNaN(0, 0x8000000000000ULL));
  ShouldBeIdentical(SpecificNaN(0, 17), SpecificNaN(0, 0x4000000000000ULL));
  ShouldBeIdentical(SpecificNaN(0, 17), SpecificNaN(0, 0x2000000000000ULL));
  ShouldBeIdentical(SpecificNaN(0, 17), SpecificNaN(0, 0x1000000000000ULL));
  ShouldBeIdentical(SpecificNaN(0, 17), SpecificNaN(0, 0x0800000000000ULL));
  ShouldBeIdentical(SpecificNaN(0, 17), SpecificNaN(0, 0x0400000000000ULL));
  ShouldBeIdentical(SpecificNaN(0, 17), SpecificNaN(0, 0x0200000000000ULL));
  ShouldBeIdentical(SpecificNaN(0, 17), SpecificNaN(0, 0x0100000000000ULL));
  ShouldBeIdentical(SpecificNaN(0, 17), SpecificNaN(0, 0x0080000000000ULL));
  ShouldBeIdentical(SpecificNaN(0, 17), SpecificNaN(0, 0x0040000000000ULL));
  ShouldBeIdentical(SpecificNaN(0, 17), SpecificNaN(0, 0x0020000000000ULL));
  ShouldBeIdentical(SpecificNaN(0, 17), SpecificNaN(0, 0x0010000000000ULL));
  ShouldBeIdentical(SpecificNaN(1, 17), SpecificNaN(0, 0xff0ffffffffffULL));
  ShouldBeIdentical(SpecificNaN(1, 17), SpecificNaN(0, 0xfffffffffff0fULL));

  ShouldNotBeIdentical(UnspecifiedNaN(), +0.0);
  ShouldNotBeIdentical(UnspecifiedNaN(), -0.0);
  ShouldNotBeIdentical(UnspecifiedNaN(), 1.0);
  ShouldNotBeIdentical(UnspecifiedNaN(), -1.0);
  ShouldNotBeIdentical(UnspecifiedNaN(), PositiveInfinity());
  ShouldNotBeIdentical(UnspecifiedNaN(), NegativeInfinity());
}
Example #6
0
static void
TestPredicates()
{
  MOZ_ASSERT(IsNaN(UnspecifiedNaN()));
  MOZ_ASSERT(IsNaN(SpecificNaN(1, 17)));;
  MOZ_ASSERT(IsNaN(SpecificNaN(0, 0xfffffffffff0fULL)));
  MOZ_ASSERT(!IsNaN(0));
  MOZ_ASSERT(!IsNaN(-0.0));
  MOZ_ASSERT(!IsNaN(1.0));
  MOZ_ASSERT(!IsNaN(PositiveInfinity()));
  MOZ_ASSERT(!IsNaN(NegativeInfinity()));

  MOZ_ASSERT(IsInfinite(PositiveInfinity()));
  MOZ_ASSERT(IsInfinite(NegativeInfinity()));
  MOZ_ASSERT(!IsInfinite(UnspecifiedNaN()));
  MOZ_ASSERT(!IsInfinite(0));
  MOZ_ASSERT(!IsInfinite(-0.0));
  MOZ_ASSERT(!IsInfinite(1.0));

  MOZ_ASSERT(!IsFinite(PositiveInfinity()));
  MOZ_ASSERT(!IsFinite(NegativeInfinity()));
  MOZ_ASSERT(!IsFinite(UnspecifiedNaN()));
  MOZ_ASSERT(IsFinite(0));
  MOZ_ASSERT(IsFinite(-0.0));
  MOZ_ASSERT(IsFinite(1.0));

  MOZ_ASSERT(!IsNegative(PositiveInfinity()));
  MOZ_ASSERT(IsNegative(NegativeInfinity()));
  MOZ_ASSERT(IsNegative(-0.0));
  MOZ_ASSERT(!IsNegative(0.0));
  MOZ_ASSERT(IsNegative(-1.0));
  MOZ_ASSERT(!IsNegative(1.0));

  MOZ_ASSERT(!IsNegativeZero(PositiveInfinity()));
  MOZ_ASSERT(!IsNegativeZero(NegativeInfinity()));
  MOZ_ASSERT(!IsNegativeZero(SpecificNaN(1, 17)));;
  MOZ_ASSERT(!IsNegativeZero(SpecificNaN(1, 0xfffffffffff0fULL)));
  MOZ_ASSERT(!IsNegativeZero(SpecificNaN(0, 17)));;
  MOZ_ASSERT(!IsNegativeZero(SpecificNaN(0, 0xfffffffffff0fULL)));
  MOZ_ASSERT(!IsNegativeZero(UnspecifiedNaN()));
  MOZ_ASSERT(IsNegativeZero(-0.0));
  MOZ_ASSERT(!IsNegativeZero(0.0));
  MOZ_ASSERT(!IsNegativeZero(-1.0));
  MOZ_ASSERT(!IsNegativeZero(1.0));

  int32_t i;
  MOZ_ASSERT(DoubleIsInt32(0.0, &i)); MOZ_ASSERT(i == 0);
  MOZ_ASSERT(!DoubleIsInt32(-0.0, &i));
  MOZ_ASSERT(DoubleEqualsInt32(0.0, &i)); MOZ_ASSERT(i == 0);
  MOZ_ASSERT(DoubleEqualsInt32(-0.0, &i)); MOZ_ASSERT(i == 0);
  MOZ_ASSERT(DoubleIsInt32(INT32_MIN, &i)); MOZ_ASSERT(i == INT32_MIN);
  MOZ_ASSERT(DoubleIsInt32(INT32_MAX, &i)); MOZ_ASSERT(i == INT32_MAX);
  MOZ_ASSERT(DoubleEqualsInt32(INT32_MIN, &i)); MOZ_ASSERT(i == INT32_MIN);
  MOZ_ASSERT(DoubleEqualsInt32(INT32_MAX, &i)); MOZ_ASSERT(i == INT32_MAX);
  MOZ_ASSERT(!DoubleIsInt32(0.5, &i));
  MOZ_ASSERT(!DoubleIsInt32(double(INT32_MAX) + 0.1, &i));
  MOZ_ASSERT(!DoubleIsInt32(double(INT32_MIN) - 0.1, &i));
  MOZ_ASSERT(!DoubleIsInt32(NegativeInfinity(), &i));
  MOZ_ASSERT(!DoubleIsInt32(PositiveInfinity(), &i));
  MOZ_ASSERT(!DoubleIsInt32(UnspecifiedNaN(), &i));
  MOZ_ASSERT(!DoubleEqualsInt32(0.5, &i));
  MOZ_ASSERT(!DoubleEqualsInt32(double(INT32_MAX) + 0.1, &i));
  MOZ_ASSERT(!DoubleEqualsInt32(double(INT32_MIN) - 0.1, &i));
  MOZ_ASSERT(!DoubleEqualsInt32(NegativeInfinity(), &i));
  MOZ_ASSERT(!DoubleEqualsInt32(PositiveInfinity(), &i));
  MOZ_ASSERT(!DoubleEqualsInt32(UnspecifiedNaN(), &i));
}