Exemple #1
0
bool
js::atomics_load(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    HandleValue objv = args.get(0);
    HandleValue idxv = args.get(1);
    MutableHandleValue r = args.rval();

    Rooted<SharedTypedArrayObject*> view(cx, nullptr);
    if (!GetSharedTypedArray(cx, objv, &view))
        return false;
    uint32_t offset;
    bool inRange;
    if (!GetSharedTypedArrayIndex(cx, idxv, view, &offset, &inRange))
        return false;

    if (!inRange)
        return atomics_fence_impl(cx, r);

    switch (view->type()) {
      case Scalar::Uint8:
      case Scalar::Uint8Clamped: {
          uint8_t v = jit::AtomicOperations::loadSeqCst((uint8_t*)view->viewData() + offset);
          r.setInt32(v);
          return true;
      }
      case Scalar::Int8: {
          int8_t v = jit::AtomicOperations::loadSeqCst((uint8_t*)view->viewData() + offset);
          r.setInt32(v);
          return true;
      }
      case Scalar::Int16: {
          int16_t v = jit::AtomicOperations::loadSeqCst((int16_t*)view->viewData() + offset);
          r.setInt32(v);
          return true;
      }
      case Scalar::Uint16: {
          uint16_t v = jit::AtomicOperations::loadSeqCst((uint16_t*)view->viewData() + offset);
          r.setInt32(v);
          return true;
      }
      case Scalar::Int32: {
          int32_t v = jit::AtomicOperations::loadSeqCst((int32_t*)view->viewData() + offset);
          r.setInt32(v);
          return true;
      }
      case Scalar::Uint32: {
          uint32_t v = jit::AtomicOperations::loadSeqCst((uint32_t*)view->viewData() + offset);
          r.setNumber(v);
          return true;
      }
      default:
          return ReportBadArrayType(cx);
    }
}
Exemple #2
0
static bool
AtomicsBinop(JSContext* cx, HandleValue objv, HandleValue idxv, HandleValue valv,
             MutableHandleValue r)
{
    Rooted<TypedArrayObject*> view(cx, nullptr);
    if (!GetSharedTypedArray(cx, objv, &view))
        return false;
    uint32_t offset;
    if (!GetTypedArrayIndex(cx, idxv, view, &offset))
        return false;
    int32_t numberValue;
    if (!ToInt32(cx, valv, &numberValue))
        return false;

    SharedMem<void*> viewData = view->viewDataShared();
    switch (view->type()) {
      case Scalar::Int8: {
        int8_t v = (int8_t)numberValue;
        r.setInt32(T::operate(viewData.cast<int8_t*>() + offset, v));
        return true;
      }
      case Scalar::Uint8: {
        uint8_t v = (uint8_t)numberValue;
        r.setInt32(T::operate(viewData.cast<uint8_t*>() + offset, v));
        return true;
      }
      case Scalar::Int16: {
        int16_t v = (int16_t)numberValue;
        r.setInt32(T::operate(viewData.cast<int16_t*>() + offset, v));
        return true;
      }
      case Scalar::Uint16: {
        uint16_t v = (uint16_t)numberValue;
        r.setInt32(T::operate(viewData.cast<uint16_t*>() + offset, v));
        return true;
      }
      case Scalar::Int32: {
        int32_t v = numberValue;
        r.setInt32(T::operate(viewData.cast<int32_t*>() + offset, v));
        return true;
      }
      case Scalar::Uint32: {
        uint32_t v = (uint32_t)numberValue;
        r.setNumber((double)T::operate(viewData.cast<uint32_t*>() + offset, v));
        return true;
      }
      default:
        return ReportBadArrayType(cx);
    }
}
static JSBool
ArgGetter(JSContext *cx, HandleObject obj, HandleId id, MutableHandleValue vp)
{
    if (!obj->isNormalArguments())
        return true;

    NormalArgumentsObject &argsobj = obj->asNormalArguments();
    if (JSID_IS_INT(id)) {
        /*
         * arg can exceed the number of arguments if a script changed the
         * prototype to point to another Arguments object with a bigger argc.
         */
        unsigned arg = unsigned(JSID_TO_INT(id));
        if (arg < argsobj.initialLength() && !argsobj.isElementDeleted(arg))
            vp.set(argsobj.element(arg));
    } else if (JSID_IS_ATOM(id, cx->names().length)) {
        if (!argsobj.hasOverriddenLength())
            vp.setInt32(argsobj.initialLength());
    } else {
        JS_ASSERT(JSID_IS_ATOM(id, cx->names().callee));
        if (!argsobj.callee().isMagic(JS_OVERWRITTEN_CALLEE))
            vp.set(argsobj.callee());
    }
    return true;
}
Exemple #4
0
static bool
MappedArgGetter(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp)
{
    MappedArgumentsObject& argsobj = obj->as<MappedArgumentsObject>();
    if (JSID_IS_INT(id)) {
        /*
         * arg can exceed the number of arguments if a script changed the
         * prototype to point to another Arguments object with a bigger argc.
         */
        unsigned arg = unsigned(JSID_TO_INT(id));
        if (arg < argsobj.initialLength() && !argsobj.isElementDeleted(arg))
            vp.set(argsobj.element(arg));
    } else if (JSID_IS_ATOM(id, cx->names().length)) {
        if (!argsobj.hasOverriddenLength())
            vp.setInt32(argsobj.initialLength());
    } else {
        MOZ_ASSERT(JSID_IS_ATOM(id, cx->names().callee));
        if (!argsobj.hasOverriddenCallee()) {
            RootedFunction callee(cx, &argsobj.callee());
            if (callee->isAsync())
                vp.setObject(*GetWrappedAsyncFunction(callee));
            else
                vp.setObject(*callee);
        }
    }
    return true;
}
Exemple #5
0
static bool
ExchangeOrStore(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    HandleValue objv = args.get(0);
    HandleValue idxv = args.get(1);
    HandleValue valv = args.get(2);
    MutableHandleValue r = args.rval();

    Rooted<TypedArrayObject*> view(cx, nullptr);
    if (!GetSharedTypedArray(cx, objv, &view))
        return false;
    uint32_t offset;
    if (!GetTypedArrayIndex(cx, idxv, view, &offset))
        return false;
    double integerValue;
    if (!ToInteger(cx, valv, &integerValue))
        return false;

    bool badType = false;
    int32_t result = ExchangeOrStore<op>(view->type(), JS::ToInt32(integerValue),
                                         view->viewDataShared(), offset, &badType);

    if (badType)
        return ReportBadArrayType(cx);

    if (op == DoStore)
        r.setNumber(integerValue);
    else if (view->type() == Scalar::Uint32)
        r.setNumber((double)(uint32_t)result);
    else
        r.setInt32(result);
    return true;
}
  bool
  Compare(JSContext* cx, HandleString src1, HandleString src2, MutableHandleValue rval)
  {
    nsresult rv;

    if (!mCollation) {
      nsCOMPtr<nsILocaleService> localeService =
        do_GetService(NS_LOCALESERVICE_CONTRACTID, &rv);

      if (NS_SUCCEEDED(rv)) {
        nsCOMPtr<nsILocale> locale;
        rv = localeService->GetApplicationLocale(getter_AddRefs(locale));

        if (NS_SUCCEEDED(rv)) {
          nsCOMPtr<nsICollationFactory> colFactory =
            do_CreateInstance(NS_COLLATIONFACTORY_CONTRACTID, &rv);

          if (NS_SUCCEEDED(rv)) {
            rv = colFactory->CreateCollation(locale, getter_AddRefs(mCollation));
          }
        }
      }

      if (NS_FAILED(rv)) {
        xpc::Throw(cx, rv);
        return false;
      }
    }

    nsAutoJSString autoStr1, autoStr2;
    if (!autoStr1.init(cx, src1) || !autoStr2.init(cx, src2)) {
      return false;
    }

    int32_t result;
    rv = mCollation->CompareString(nsICollation::kCollationStrengthDefault,
                                   autoStr1, autoStr2, &result);

    if (NS_FAILED(rv)) {
      xpc::Throw(cx, rv);
      return false;
    }

    rval.setInt32(result);
    return true;
  }
static bool
UnmappedArgGetter(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp)
{
    UnmappedArgumentsObject& argsobj = obj->as<UnmappedArgumentsObject>();

    if (JSID_IS_INT(id)) {
        /*
         * arg can exceed the number of arguments if a script changed the
         * prototype to point to another Arguments object with a bigger argc.
         */
        unsigned arg = unsigned(JSID_TO_INT(id));
        if (arg < argsobj.initialLength() && !argsobj.isElementDeleted(arg))
            vp.set(argsobj.element(arg));
    } else {
        MOZ_ASSERT(JSID_IS_ATOM(id, cx->names().length));
        if (!argsobj.hasOverriddenLength())
            vp.setInt32(argsobj.initialLength());
    }
    return true;
}
Exemple #8
0
bool
js::atomics_compareExchange(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    HandleValue objv = args.get(0);
    HandleValue idxv = args.get(1);
    HandleValue oldv = args.get(2);
    HandleValue newv = args.get(3);
    MutableHandleValue r = args.rval();

    Rooted<SharedTypedArrayObject*> view(cx, nullptr);
    if (!GetSharedTypedArray(cx, objv, &view))
        return false;
    uint32_t offset;
    bool inRange;
    if (!GetSharedTypedArrayIndex(cx, idxv, view, &offset, &inRange))
        return false;
    int32_t oldCandidate;
    if (!ToInt32(cx, oldv, &oldCandidate))
        return false;
    int32_t newCandidate;
    if (!ToInt32(cx, newv, &newCandidate))
        return false;

    if (!inRange)
        return atomics_fence_impl(cx, r);

    bool badType = false;
    int32_t result = do_cmpxchg(view->type(), oldCandidate, newCandidate, view->viewData(), offset, &badType);

    if (badType)
        return ReportBadArrayType(cx);

    if (view->type() == Scalar::Uint32)
        r.setNumber((double)(uint32_t)result);
    else
        r.setInt32(result);
    return true;
}
Exemple #9
0
static bool
ExchangeOrStore(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    HandleValue objv = args.get(0);
    HandleValue idxv = args.get(1);
    HandleValue valv = args.get(2);
    MutableHandleValue r = args.rval();

    Rooted<SharedTypedArrayObject*> view(cx, nullptr);
    if (!GetSharedTypedArray(cx, objv, &view))
        return false;
    uint32_t offset;
    bool inRange;
    if (!GetSharedTypedArrayIndex(cx, idxv, view, &offset, &inRange))
        return false;
    int32_t numberValue;
    if (!ToInt32(cx, valv, &numberValue))
        return false;

    if (!inRange) {
        atomics_fullMemoryBarrier();
        r.set(valv);
        return true;
    }

    bool badType = false;
    int32_t result = ExchangeOrStore<op>(view->type(), numberValue, view->viewData(), offset, &badType);

    if (badType)
        return ReportBadArrayType(cx);

    if (view->type() == Scalar::Uint32)
        r.setNumber((double)(uint32_t)result);
    else
        r.setInt32(result);
    return true;
}
Exemple #10
0
static bool
atomics_binop_impl(JSContext* cx, HandleValue objv, HandleValue idxv, HandleValue valv,
                   MutableHandleValue r)
{
    Rooted<SharedTypedArrayObject*> view(cx, nullptr);
    if (!GetSharedTypedArray(cx, objv, &view))
        return false;
    uint32_t offset;
    bool inRange;
    if (!GetSharedTypedArrayIndex(cx, idxv, view, &offset, &inRange))
        return false;
    int32_t numberValue;
    if (!ToInt32(cx, valv, &numberValue))
        return false;

    if (!inRange)
        return atomics_fence_impl(cx, r);

    switch (view->type()) {
      case Scalar::Int8: {
          int8_t v = (int8_t)numberValue;
          r.setInt32(T::operate((int8_t*)view->viewData() + offset, v));
          return true;
      }
      case Scalar::Uint8: {
          uint8_t v = (uint8_t)numberValue;
          r.setInt32(T::operate((uint8_t*)view->viewData() + offset, v));
          return true;
      }
      case Scalar::Uint8Clamped: {
          // Spec says:
          //  - clamp the input value
          //  - perform the operation
          //  - clamp the result
          //  - store the result
          // This requires a CAS loop.
          int32_t value = ClampIntForUint8Array(numberValue);
          uint8_t* loc = (uint8_t*)view->viewData() + offset;
          for (;;) {
              uint8_t old = *loc;
              uint8_t result = (uint8_t)ClampIntForUint8Array(T::perform(old, value));
              uint8_t tmp = jit::AtomicOperations::compareExchangeSeqCst(loc, old, result);
              if (tmp == old) {
                  r.setInt32(old);
                  break;
              }
          }
          return true;
      }
      case Scalar::Int16: {
          int16_t v = (int16_t)numberValue;
          r.setInt32(T::operate((int16_t*)view->viewData() + offset, v));
          return true;
      }
      case Scalar::Uint16: {
          uint16_t v = (uint16_t)numberValue;
          r.setInt32(T::operate((uint16_t*)view->viewData() + offset, v));
          return true;
      }
      case Scalar::Int32: {
          int32_t v = numberValue;
          r.setInt32(T::operate((int32_t*)view->viewData() + offset, v));
          return true;
      }
      case Scalar::Uint32: {
          uint32_t v = (uint32_t)numberValue;
          r.setNumber((double)T::operate((uint32_t*)view->viewData() + offset, v));
          return true;
      }
      default:
        return ReportBadArrayType(cx);
    }
}
Exemple #11
0
bool
js::atomics_store(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    HandleValue objv = args.get(0);
    HandleValue idxv = args.get(1);
    HandleValue valv = args.get(2);
    MutableHandleValue r = args.rval();

    Rooted<SharedTypedArrayObject*> view(cx, nullptr);
    if (!GetSharedTypedArray(cx, objv, &view))
        return false;
    uint32_t offset;
    bool inRange;
    if (!GetSharedTypedArrayIndex(cx, idxv, view, &offset, &inRange))
        return false;
    int32_t numberValue;
    if (!ToInt32(cx, valv, &numberValue))
        return false;

    if (!inRange) {
        atomics_fullMemoryBarrier();
        r.set(valv);
        return true;
    }

    switch (view->type()) {
      case Scalar::Int8: {
          int8_t value = (int8_t)numberValue;
          jit::AtomicOperations::storeSeqCst((int8_t*)view->viewData() + offset, value);
          r.setInt32(value);
          return true;
      }
      case Scalar::Uint8: {
          uint8_t value = (uint8_t)numberValue;
          jit::AtomicOperations::storeSeqCst((uint8_t*)view->viewData() + offset, value);
          r.setInt32(value);
          return true;
      }
      case Scalar::Uint8Clamped: {
          uint8_t value = ClampIntForUint8Array(numberValue);
          jit::AtomicOperations::storeSeqCst((uint8_t*)view->viewData() + offset, value);
          r.setInt32(value);
          return true;
      }
      case Scalar::Int16: {
          int16_t value = (int16_t)numberValue;
          jit::AtomicOperations::storeSeqCst((int16_t*)view->viewData() + offset, value);
          r.setInt32(value);
          return true;
      }
      case Scalar::Uint16: {
          uint16_t value = (uint16_t)numberValue;
          jit::AtomicOperations::storeSeqCst((uint16_t*)view->viewData() + offset, value);
          r.setInt32(value);
          return true;
      }
      case Scalar::Int32: {
          int32_t value = numberValue;
          jit::AtomicOperations::storeSeqCst((int32_t*)view->viewData() + offset, value);
          r.setInt32(value);
          return true;
      }
      case Scalar::Uint32: {
          uint32_t value = (uint32_t)numberValue;
          jit::AtomicOperations::storeSeqCst((uint32_t*)view->viewData() + offset, value);
          r.setNumber((double)value);
          return true;
      }
      default:
        return ReportBadArrayType(cx);
    }
}
Exemple #12
0
bool
js::atomics_store(JSContext *cx, unsigned argc, Value *vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    HandleValue objv = args.get(0);
    HandleValue idxv = args.get(1);
    HandleValue valv = args.get(2);
    MutableHandleValue r = args.rval();

    Rooted<SharedTypedArrayObject *> view(cx, nullptr);
    if (!GetSharedTypedArray(cx, objv, &view))
        return false;
    uint32_t offset;
    bool inRange;
    if (!GetSharedTypedArrayIndex(cx, idxv, view, &offset, &inRange))
        return false;
    int32_t numberValue;
    if (!ToInt32(cx, valv, &numberValue))
        return false;

    if (!inRange) {
        atomics_fullMemoryBarrier();
        r.set(valv);
        return true;
    }

    // STORE stores value in *addr
    // addr must be a T*, and value should be of type T

#if defined(CXX11_ATOMICS)
# define STORE(T, addr, value)                                           \
    do {                                                                \
        std::atomic_store(reinterpret_cast<std::atomic<T>*>(addr), (T)value); \
} while(0)
#elif defined(GNU_ATOMICS)
# define STORE(T, addr, value)                   \
    do {                                        \
        __sync_synchronize();                   \
        *(addr) = value;                        \
        __sync_synchronize();                   \
    } while(0)
#else
# define STORE(a, b, c)  (void)0
#endif

    switch (view->type()) {
      case Scalar::Int8: {
          int8_t value = (int8_t)numberValue;
          STORE(int8_t, (int8_t*)view->viewData() + offset, value);
          r.setInt32(value);
          return true;
      }
      case Scalar::Uint8: {
          uint8_t value = (uint8_t)numberValue;
          STORE(uint8_t, (uint8_t*)view->viewData() + offset, value);
          r.setInt32(value);
          return true;
      }
      case Scalar::Uint8Clamped: {
          uint8_t value = ClampIntForUint8Array(numberValue);
          STORE(uint8_t, (uint8_t*)view->viewData() + offset, value);
          r.setInt32(value);
          return true;
      }
      case Scalar::Int16: {
          int16_t value = (int16_t)numberValue;
          STORE(int16_t, (int16_t*)view->viewData() + offset, value);
          r.setInt32(value);
          return true;
      }
      case Scalar::Uint16: {
          uint16_t value = (uint16_t)numberValue;
          STORE(uint16_t, (uint16_t*)view->viewData() + offset, value);
          r.setInt32(value);
          return true;
      }
      case Scalar::Int32: {
          int32_t value = numberValue;
          STORE(int32_t, (int32_t*)view->viewData() + offset, value);
          r.setInt32(value);
          return true;
      }
      case Scalar::Uint32: {
          uint32_t value = (uint32_t)numberValue;
          STORE(uint32_t, (uint32_t*)view->viewData() + offset, value);
          r.setNumber((double)value);
          return true;
      }
      default:
        return ReportBadArrayType(cx);
    }

#undef STORE
}
Exemple #13
0
bool
js::atomics_load(JSContext *cx, unsigned argc, Value *vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    HandleValue objv = args.get(0);
    HandleValue idxv = args.get(1);
    MutableHandleValue r = args.rval();

    Rooted<SharedTypedArrayObject *> view(cx, nullptr);
    if (!GetSharedTypedArray(cx, objv, &view))
        return false;
    uint32_t offset;
    bool inRange;
    if (!GetSharedTypedArrayIndex(cx, idxv, view, &offset, &inRange))
        return false;

    if (!inRange)
        return atomics_fence_impl(cx, r);

    // LOAD sets v to the value of *addr
    // addr must be a T*, and v must be a variable of type T

#if defined(CXX11_ATOMICS)
# define LOAD(T, addr, v)                                                \
    do {                                                                \
        v = std::atomic_load(reinterpret_cast<std::atomic<T>*>(addr));  \
    } while(0)
#elif defined(GNU_ATOMICS)
# define LOAD(T, addr, v)                        \
    do {                                        \
        __sync_synchronize();                   \
        v = *(addr);                            \
        __sync_synchronize();                   \
    } while(0)
#else
# define LOAD(a, b, v)  v = 0
#endif

    switch (view->type()) {
      case Scalar::Uint8:
      case Scalar::Uint8Clamped: {
          uint8_t v;
          LOAD(uint8_t, (uint8_t*)view->viewData() + offset, v);
          r.setInt32(v);
          return true;
      }
      case Scalar::Int8: {
          int8_t v;
          LOAD(int8_t, (int8_t*)view->viewData() + offset, v);
          r.setInt32(v);
          return true;
      }
      case Scalar::Int16: {
          int16_t v;
          LOAD(int16_t, (int16_t*)view->viewData() + offset, v);
          r.setInt32(v);
          return true;
      }
      case Scalar::Uint16: {
          uint16_t v;
          LOAD(uint16_t, (uint16_t*)view->viewData() + offset, v);
          r.setInt32(v);
          return true;
      }
      case Scalar::Int32: {
          int32_t v;
          LOAD(int32_t, (int32_t*)view->viewData() + offset, v);
          r.setInt32(v);
          return true;
      }
      case Scalar::Uint32: {
          uint32_t v;
          LOAD(uint32_t, (uint32_t*)view->viewData() + offset, v);
          r.setNumber(v);
          return true;
      }
      default:
          return ReportBadArrayType(cx);
    }

#undef LOAD

}
Exemple #14
0
bool
js::atomics_compareExchange(JSContext *cx, unsigned argc, Value *vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    HandleValue objv = args.get(0);
    HandleValue idxv = args.get(1);
    HandleValue oldv = args.get(2);
    HandleValue newv = args.get(3);
    MutableHandleValue r = args.rval();

    Rooted<SharedTypedArrayObject *> view(cx, nullptr);
    if (!GetSharedTypedArray(cx, objv, &view))
        return false;
    uint32_t offset;
    bool inRange;
    if (!GetSharedTypedArrayIndex(cx, idxv, view, &offset, &inRange))
        return false;
    int32_t oldCandidate;
    if (!ToInt32(cx, oldv, &oldCandidate))
        return false;
    int32_t newCandidate;
    if (!ToInt32(cx, newv, &newCandidate))
        return false;

    if (!inRange)
        return atomics_fence_impl(cx, r);

    // CAS always sets oldval to the old value of the cell.
    // addr must be a T*, and oldval and newval should be variables of type T

#if defined(CXX11_ATOMICS)
# define CAS(T, addr, oldval, newval)                                    \
    do {                                                                \
        std::atomic_compare_exchange_strong(reinterpret_cast<std::atomic<T>*>(addr), &oldval, newval); \
    } while(0)
#elif defined(GNU_ATOMICS)
# define CAS(T, addr, oldval, newval)                                    \
    do {                                                                \
        oldval = __sync_val_compare_and_swap(addr, (oldval), (newval)); \
    } while(0)
#else
# define CAS(a, b, c, newval)  (void)newval
#endif

    switch (view->type()) {
      case Scalar::Int8: {
          int8_t oldval = (int8_t)oldCandidate;
          int8_t newval = (int8_t)newCandidate;
          CAS(int8_t, (int8_t*)view->viewData() + offset, oldval, newval);
          r.setInt32(oldval);
          return true;
      }
      case Scalar::Uint8: {
          uint8_t oldval = (uint8_t)oldCandidate;
          uint8_t newval = (uint8_t)newCandidate;
          CAS(uint8_t, (uint8_t*)view->viewData() + offset, oldval, newval);
          r.setInt32(oldval);
          return true;
      }
      case Scalar::Uint8Clamped: {
          uint8_t oldval = ClampIntForUint8Array(oldCandidate);
          uint8_t newval = ClampIntForUint8Array(newCandidate);
          CAS(uint8_t, (uint8_t*)view->viewData() + offset, oldval, newval);
          r.setInt32(oldval);
          return true;
      }
      case Scalar::Int16: {
          int16_t oldval = (int16_t)oldCandidate;
          int16_t newval = (int16_t)newCandidate;
          CAS(int16_t, (int16_t*)view->viewData() + offset, oldval, newval);
          r.setInt32(oldval);
          return true;
      }
      case Scalar::Uint16: {
          uint16_t oldval = (uint16_t)oldCandidate;
          uint16_t newval = (uint16_t)newCandidate;
          CAS(uint16_t, (uint16_t*)view->viewData() + offset, oldval, newval);
          r.setInt32(oldval);
          return true;
      }
      case Scalar::Int32: {
          int32_t oldval = oldCandidate;
          int32_t newval = newCandidate;
          CAS(int32_t, (int32_t*)view->viewData() + offset, oldval, newval);
          r.setInt32(oldval);
          return true;
      }
      case Scalar::Uint32: {
          uint32_t oldval = (uint32_t)oldCandidate;
          uint32_t newval = (uint32_t)newCandidate;
          CAS(uint32_t, (uint32_t*)view->viewData() + offset, oldval, newval);
          r.setNumber((double)oldval);
          return true;
      }
      default:
        return ReportBadArrayType(cx);
    }

    // Do not undef CAS, it is used later
}