nsresult xpcJSWeakReference::Init(JSContext* cx, const JS::Value& object)
{
    if (!object.isObject())
        return NS_OK;

    JS::RootedObject obj(cx, &object.toObject());

    XPCCallContext ccx(NATIVE_CALLER, cx);

    // See if the object is a wrapped native that supports weak references.
    nsISupports* supports =
        nsXPConnect::XPConnect()->GetNativeOfWrapper(cx, obj);
    nsCOMPtr<nsISupportsWeakReference> supportsWeakRef =
        do_QueryInterface(supports);
    if (supportsWeakRef) {
        supportsWeakRef->GetWeakReference(getter_AddRefs(mReferent));
        if (mReferent) {
            return NS_OK;
        }
    }
    // If it's not a wrapped native, or it is a wrapped native that does not
    // support weak references, fall back to getting a weak ref to the object.

    // See if object is a wrapped JSObject.
    nsRefPtr<nsXPCWrappedJS> wrapped;
    nsresult rv = nsXPCWrappedJS::GetNewOrUsed(obj,
                                               NS_GET_IID(nsISupports),
                                               getter_AddRefs(wrapped));
    if (!wrapped) {
        NS_ERROR("can't get nsISupportsWeakReference wrapper for obj");
        return rv;
    }

    return wrapped->GetWeakReference(getter_AddRefs(mReferent));
}
Example #2
0
NS_IMETHODIMP
MobileMessageManager::Delete(const JS::Value& aParam, nsIDOMDOMRequest** aRequest)
{
  if (aParam.isInt32()) {
    return Delete(aParam.toInt32(), aRequest);
  }

  if (!aParam.isObject()) {
    return NS_ERROR_INVALID_ARG;
  }

  nsresult rv;
  nsIScriptContext* sc = GetContextForEventHandlers(&rv);
  AutoPushJSContext cx(sc->GetNativeContext());
  NS_ENSURE_STATE(sc);

  int32_t id;
  nsCOMPtr<nsIDOMMozSmsMessage> smsMessage =
    do_QueryInterface(nsContentUtils::XPConnect()->GetNativeOfWrapper(cx, &aParam.toObject()));
  if (smsMessage) {
    smsMessage->GetId(&id);
  } else {
    nsCOMPtr<nsIDOMMozMmsMessage> mmsMessage =
      do_QueryInterface(nsContentUtils::XPConnect()->GetNativeOfWrapper(cx, &aParam.toObject()));
    if (mmsMessage) {
      mmsMessage->GetId(&id);
    } else {
      return NS_ERROR_INVALID_ARG;
    }
  }

  return Delete(id, aRequest);
}
NS_IMETHODIMP
TCPSocketChild::Send(const JS::Value& aData,
                     uint32_t aByteOffset,
                     uint32_t aByteLength,
                     JSContext* aCx)
{
  if (aData.isString()) {
    JSString* jsstr = aData.toString();
    nsDependentJSString str;
    bool ok = str.init(aCx, jsstr);
    NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
    SendData(str);

  } else {
    NS_ENSURE_TRUE(aData.isObject(), NS_ERROR_FAILURE);
    JS::Rooted<JSObject*> obj(aCx, &aData.toObject());
    NS_ENSURE_TRUE(JS_IsArrayBufferObject(obj), NS_ERROR_FAILURE);
    uint32_t buflen = JS_GetArrayBufferByteLength(obj);
    aByteOffset = std::min(buflen, aByteOffset);
    uint32_t nbytes = std::min(buflen - aByteOffset, aByteLength);
    uint8_t* data = JS_GetArrayBufferData(obj);
    if (!data) {
      return NS_ERROR_OUT_OF_MEMORY;
    }
    FallibleTArray<uint8_t> fallibleArr;
    if (!fallibleArr.InsertElementsAt(0, data, nbytes)) {
      return NS_ERROR_OUT_OF_MEMORY;
    }
    InfallibleTArray<uint8_t> arr;
    arr.SwapElements(fallibleArr);
    SendData(arr);
  }
  return NS_OK;
}
Example #4
0
NS_IMETHODIMP
TCPSocketParent::InitJS(const JS::Value& aIntermediary, JSContext* aCx)
{
  MOZ_ASSERT(aIntermediary.isObject());
  mIntermediaryObj = &aIntermediary.toObject();
  return NS_OK;
}
// Helper for weighted regions.
nsresult
CameraControlImpl::Set(JSContext* aCx, uint32_t aKey, const JS::Value& aValue, uint32_t aLimit)
{
  if (aLimit == 0) {
    DOM_CAMERA_LOGI("%s:%d : aLimit = 0, nothing to do\n", __func__, __LINE__);
    return NS_OK;
  }

  if (!aValue.isObject()) {
    return NS_ERROR_INVALID_ARG;
  }

  uint32_t length = 0;

  JSObject* regions = &aValue.toObject();
  if (!JS_GetArrayLength(aCx, regions, &length)) {
    return NS_ERROR_FAILURE;
  }

  DOM_CAMERA_LOGI("%s:%d : got %d regions (limited to %d)\n", __func__, __LINE__, length, aLimit);
  if (length > aLimit) {
    length = aLimit;
  }

  nsTArray<CameraRegion> regionArray;
  regionArray.SetCapacity(length);

  for (uint32_t i = 0; i < length; ++i) {
    JS::Value v;

    if (!JS_GetElement(aCx, regions, i, &v)) {
      return NS_ERROR_FAILURE;
    }

    CameraRegion* r = regionArray.AppendElement();
    /**
     * These are the default values.  We can remove these when the xpidl
     * dictionary parser gains the ability to grok default values.
     */
    r->top = -1000;
    r->left = -1000;
    r->bottom = 1000;
    r->right = 1000;
    r->weight = 1000;

    nsresult rv = r->Init(aCx, &v);
    NS_ENSURE_SUCCESS(rv, rv);

    DOM_CAMERA_LOGI("region %d: top=%d, left=%d, bottom=%d, right=%d, weight=%d\n",
      i,
      r->top,
      r->left,
      r->bottom,
      r->right,
      r->weight
    );
  }
  SetParameter(aKey, regionArray);
  return NS_OK;
}
js::DOMProxyShadowsResult
DOMProxyShadows(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id)
{
  JS::Rooted<JSObject*> expando(cx, DOMProxyHandler::GetExpandoObject(proxy));
  JS::Value v = js::GetProxyExtra(proxy, JSPROXYSLOT_EXPANDO);
  bool isOverrideBuiltins = !v.isObject() && !v.isUndefined();
  if (expando) {
    bool hasOwn;
    if (!JS_AlreadyHasOwnPropertyById(cx, expando, id, &hasOwn))
      return js::ShadowCheckFailed;

    if (hasOwn) {
      return isOverrideBuiltins ?
        js::ShadowsViaIndirectExpando : js::ShadowsViaDirectExpando;
    }
  }

  if (!isOverrideBuiltins) {
    // Our expando, if any, didn't shadow, so we're not shadowing at all.
    return js::DoesntShadow;
  }

  bool hasOwn;
  if (!GetProxyHandler(proxy)->hasOwn(cx, proxy, id, &hasOwn))
    return js::ShadowCheckFailed;

  return hasOwn ? js::Shadows : js::DoesntShadowUnique;
}
Example #7
0
JSScript *createScriptViaXDR(JSPrincipals *prin, JSPrincipals *orig, int testCase)
{
    const char src[] =
        "function f() { return 1; }\n"
        "f;\n";

    js::RootedObject global(cx, JS_GetGlobalObject(cx));
    JSScript *script = CompileScriptForPrincipalsVersionOrigin(cx, global, prin, orig,
                                                               src, strlen(src), "test", 1,
                                                               JSVERSION_DEFAULT);
    if (!script)
        return NULL;

    if (testCase == TEST_SCRIPT || testCase == TEST_SERIALIZED_FUNCTION) {
        script = FreezeThaw(cx, script);
        if (!script)
            return NULL;
        if (testCase == TEST_SCRIPT)
            return script;
    }

    JS::Value v;
    JSBool ok = JS_ExecuteScript(cx, global, script, &v);
    if (!ok || !v.isObject())
        return NULL;
    js::RootedObject funobj(cx, &v.toObject());
    if (testCase == TEST_FUNCTION) {
        funobj = FreezeThaw(cx, funobj);
        if (!funobj)
            return NULL;
    }
    return GetScript(cx, funobj);
}
Example #8
0
static inline void CheckExpandoAndGeneration(
    JSObject* proxy, js::ExpandoAndGeneration* expandoAndGeneration) {
#ifdef DEBUG
  JS::Value value = expandoAndGeneration->expando;
  if (!value.isUndefined()) CheckExpandoObject(proxy, value);
#endif
}
Example #9
0
bool
gjs_string_to_utf8 (JSContext      *context,
                    const JS::Value value,
                    char          **utf8_string_p)
{
    gsize len;
    char *bytes;

    JS_BeginRequest(context);

    if (!value.isString()) {
        gjs_throw(context,
                  "Value is not a string, cannot convert to UTF-8");
        JS_EndRequest(context);
        return false;
    }

    JS::RootedString str(context, value.toString());

    len = JS_GetStringEncodingLength(context, str);
    if (len == (gsize)(-1)) {
        JS_EndRequest(context);
        return false;
    }

    if (utf8_string_p) {
        bytes = JS_EncodeStringToUTF8(context, str);
        *utf8_string_p = bytes;
    }

    JS_EndRequest(context);

    return true;
}
Example #10
0
/**
 * gjs_string_get_char16_data:
 * @context: js context
 * @value: a JS::Value
 * @data_p: address to return allocated data buffer
 * @len_p: address to return length of data (number of 16-bit characters)
 *
 * Get the binary data (as a sequence of 16-bit characters) in the JSString
 * contained in @value.
 * Throws a JS exception if value is not a string.
 *
 * Returns: false if exception thrown
 **/
bool
gjs_string_get_char16_data(JSContext       *context,
                           JS::Value        value,
                           char16_t       **data_p,
                           size_t          *len_p)
{
    const char16_t *js_data;
    bool retval = false;

    JS_BeginRequest(context);

    if (!value.isString()) {
        gjs_throw(context,
                  "Value is not a string, can't return binary data from it");
        goto out;
    }

    js_data = JS_GetStringCharsAndLength(context, value.toString(), len_p);
    if (js_data == NULL)
        goto out;

    *data_p = (char16_t *) g_memdup(js_data, sizeof(*js_data) * (*len_p));

    retval = true;
out:
    JS_EndRequest(context);
    return retval;
}
Promise*
WrapperPromiseCallback::GetDependentPromise()
{
  // Per spec, various algorithms like all() and race() are actually implemented
  // in terms of calling then() but passing it the resolve/reject functions that
  // are passed as arguments to function passed to the Promise constructor.
  // That will cause the promise in question to hold on to a
  // WrapperPromiseCallback, but the dependent promise should really be the one
  // whose constructor those functions came from, not the about-to-be-ignored
  // return value of "then".  So try to determine whether we're in that case and
  // if so go ahead and dig the dependent promise out of the function we have.
  JSObject* callable = mCallback->Callable();
  // Unwrap it, in case it's a cross-compartment wrapper.  Our caller here is
  // system, so it's really ok to just go and unwrap.
  callable = js::UncheckedUnwrap(callable);
  if (JS_IsNativeFunction(callable, Promise::JSCallback)) {
    JS::Value promiseVal =
      js::GetFunctionNativeReserved(callable, Promise::SLOT_PROMISE);
    Promise* promise;
    UNWRAP_OBJECT(Promise, &promiseVal.toObject(), promise);
    return promise;
  }

  if (mNextPromise) {
    return mNextPromise;
  }

  Promise* promise;
  if (NS_SUCCEEDED(UNWRAP_OBJECT(Promise, mNextPromiseObj, promise))) {
    return promise;
  }

  // Oh, well.
  return nullptr;
}
Example #12
0
nsresult
nsJSON::EncodeInternal(JSContext* cx, const JS::Value& aValue,
                       nsJSONWriter* writer)
{
  JSAutoRequest ar(cx);

  // Backward compatibility:
  // nsIJSON does not allow to serialize anything other than objects
  if (!aValue.isObject()) {
    return NS_ERROR_INVALID_ARG;
  }

  JSObject* obj = &aValue.toObject();

  JS::Value val = aValue;

  /* Backward compatibility:
   * Manually call toJSON if implemented by the object and check that
   * the result is still an object
   * Note: It is perfectly fine to not implement toJSON, so it is
   * perfectly fine for GetMethod to fail
   */
  JS::Value toJSON;
  if (JS_GetMethod(cx, obj, "toJSON", NULL, &toJSON) &&
      !JSVAL_IS_PRIMITIVE(toJSON) &&
      JS_ObjectIsCallable(cx, JSVAL_TO_OBJECT(toJSON))) {
    // If toJSON is implemented, it must not throw
    if (!JS_CallFunctionValue(cx, obj, toJSON, 0, NULL, &val)) {
      if (JS_IsExceptionPending(cx))
        // passing NS_OK will throw the pending exception
        return NS_OK;

      // No exception, but still failed
      return NS_ERROR_FAILURE;
    }

    // Backward compatibility:
    // nsIJSON does not allow to serialize anything other than objects
    if (JSVAL_IS_PRIMITIVE(val))
      return NS_ERROR_INVALID_ARG;
  }
  // GetMethod may have thrown
  else if (JS_IsExceptionPending(cx))
    // passing NS_OK will throw the pending exception
    return NS_OK;

  // Backward compatibility:
  // function shall not pass, just "plain" objects and arrays
  JSType type = JS_TypeOfValue(cx, val);
  if (type == JSTYPE_FUNCTION)
    return NS_ERROR_INVALID_ARG;

  // We're good now; try to stringify
  if (!JS_Stringify(cx, &val, NULL, JSVAL_NULL, WriteCallback, writer))
    return NS_ERROR_FAILURE;

  return NS_OK;
}
Example #13
0
// JS-to-native helpers
// Setter for weighted regions: { top, bottom, left, right, weight }
nsresult
nsDOMCameraControl::Set(JSContext* aCx, uint32_t aKey, const JS::Value& aValue, uint32_t aLimit)
{
  if (aLimit == 0) {
    DOM_CAMERA_LOGI("%s:%d : aLimit = 0, nothing to do\n", __func__, __LINE__);
    return NS_OK;
  }

  if (!aValue.isObject()) {
    return NS_ERROR_INVALID_ARG;
  }

  uint32_t length = 0;

  JS::Rooted<JSObject*> regions(aCx, &aValue.toObject());
  if (!JS_GetArrayLength(aCx, regions, &length)) {
    return NS_ERROR_FAILURE;
  }

  DOM_CAMERA_LOGI("%s:%d : got %d regions (limited to %d)\n", __func__, __LINE__, length, aLimit);
  if (length > aLimit) {
    length = aLimit;
  }

  nsTArray<ICameraControl::Region> regionArray;
  regionArray.SetCapacity(length);

  for (uint32_t i = 0; i < length; ++i) {
    JS::Rooted<JS::Value> v(aCx);

    if (!JS_GetElement(aCx, regions, i, &v)) {
      return NS_ERROR_FAILURE;
    }

    CameraRegion region;
    if (!region.Init(aCx, v)) {
      return NS_ERROR_FAILURE;
    }

    ICameraControl::Region* r = regionArray.AppendElement();
    r->top = region.mTop;
    r->left = region.mLeft;
    r->bottom = region.mBottom;
    r->right = region.mRight;
    r->weight = region.mWeight;

    DOM_CAMERA_LOGI("region %d: top=%d, left=%d, bottom=%d, right=%d, weight=%u\n",
      i,
      r->top,
      r->left,
      r->bottom,
      r->right,
      r->weight
    );
  }
  return mCameraControl->Set(aKey, regionArray);
}
Example #14
0
NS_IMETHODIMP
nsHTMLAudioElement::MozWriteAudio(const JS::Value& aData, JSContext* aCx, uint32_t* aRetVal)
{
  if (!mAudioStream) {
    return NS_ERROR_DOM_INVALID_STATE_ERR;
  }

  if (!aData.isObject()) {
    return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
  }

  JSObject* darray = &aData.toObject();
  JS::AutoObjectRooter tvr(aCx);
  JSObject* tsrc = NULL;

  // Allow either Float32Array or plain JS Array
  if (JS_IsFloat32Array(darray)) {
    tsrc = darray;
  } else if (JS_IsArrayObject(aCx, darray)) {
    JSObject* nobj = JS_NewFloat32ArrayFromArray(aCx, darray);
    if (!nobj) {
      return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
    }
    tsrc = nobj;
  } else {
    return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
  }
  tvr.setObject(tsrc);

  uint32_t dataLength = JS_GetTypedArrayLength(tsrc);

  // Make sure that we are going to write the correct amount of data based
  // on number of channels.
  if (dataLength % mChannels != 0) {
    return NS_ERROR_DOM_INDEX_SIZE_ERR;
  }

  // Don't write more than can be written without blocking.
  uint32_t writeLen = std::min(mAudioStream->Available(), dataLength / mChannels);

  float* frames = JS_GetFloat32ArrayData(tsrc);
  // Convert the samples back to integers as we are using fixed point audio in
  // the AudioStream.
  // This could be optimized to avoid allocation and memcpy when
  // AudioDataValue is 'float', but it's not worth it for this deprecated API.
  nsAutoArrayPtr<AudioDataValue> audioData(new AudioDataValue[writeLen * mChannels]);
  ConvertAudioSamples(frames, audioData.get(), writeLen * mChannels);
  nsresult rv = mAudioStream->Write(audioData.get(), writeLen);

  if (NS_FAILED(rv)) {
    return rv;
  }

  // Return the actual amount written.
  *aRetVal = writeLen * mChannels;
  return rv;
}
void
nsGeolocationSettings::HandleGeolocationAlaEnabledChange(const JS::Value& aVal)
{
  if (!aVal.isBoolean()) {
    return;
  }

  mAlaEnabled = aVal.toBoolean();
}
NS_IMETHODIMP
nsScreen::MozLockOrientation(const JS::Value& aOrientation, JSContext* aCx,
                             bool* aReturn)
{
  if (aOrientation.isObject()) {
    JS::Rooted<JSObject*> seq(aCx, &aOrientation.toObject());
    if (IsArrayLike(aCx, seq)) {
      uint32_t length;
      // JS_GetArrayLength actually works on all objects
      if (!JS_GetArrayLength(aCx, seq, &length)) {
        return NS_ERROR_FAILURE;
      }

      Sequence<nsString> orientations;
      if (!orientations.SetCapacity(length)) {
        return NS_ERROR_OUT_OF_MEMORY;
      }

      for (uint32_t i = 0; i < length; ++i) {
        JS::Rooted<JS::Value> temp(aCx);
        if (!JS_GetElement(aCx, seq, i, &temp)) {
          return NS_ERROR_FAILURE;
        }

        JS::RootedString jsString(aCx, JS_ValueToString(aCx, temp));
        if (!jsString) {
          return NS_ERROR_FAILURE;
        }

        nsDependentJSString str;
        if (!str.init(aCx, jsString)) {
          return NS_ERROR_FAILURE;
        }

        *orientations.AppendElement() = str;
      }

      ErrorResult rv;
      *aReturn = MozLockOrientation(orientations, rv);
      return rv.ErrorCode();
    }
  }

  JS::RootedString jsString(aCx, JS_ValueToString(aCx, aOrientation));
  if (!jsString) {
    return NS_ERROR_FAILURE;
  }

  nsDependentJSString orientation;
  if (!orientation.init(aCx, jsString)) {
    return NS_ERROR_FAILURE;
  }

  ErrorResult rv;
  *aReturn = MozLockOrientation(orientation, rv);
  return rv.ErrorCode();
}
static bool VerifyJSValueIsString(
  JSContext *cx, const JS::Value &value, const char *string) {
  JSBool match;
  if (!value.isString() ||
      !JS_StringEqualsAscii(cx, value.toString(), string, &match) ||
      (match != JS_TRUE)) {
    return false;
  }
  return true;
}
Example #18
0
bool
JSCompartment::putWrapper(const CrossCompartmentKey &wrapped, const js::Value &wrapper)
{
    JS_ASSERT(wrapped.wrapped);
    JS_ASSERT_IF(wrapped.kind == CrossCompartmentKey::StringWrapper, wrapper.isString());
    JS_ASSERT_IF(wrapped.kind != CrossCompartmentKey::StringWrapper, wrapper.isObject());
    // todo: uncomment when bug 815999 is fixed:
    // JS_ASSERT(!wrapped.wrapped->isMarked(gc::GRAY));
    return crossCompartmentWrappers.put(wrapped, wrapper);
}
Example #19
0
nsresult 
nsXBLProtoImpl::InitTargetObjects(nsXBLPrototypeBinding* aBinding,
                                  nsIScriptContext* aContext, 
                                  nsIContent* aBoundElement, 
                                  nsIXPConnectJSObjectHolder** aScriptObjectHolder, 
                                  JS::MutableHandle<JSObject*> aTargetClassObject,
                                  bool* aTargetIsNew)
{
  nsresult rv = NS_OK;
  *aScriptObjectHolder = nullptr;
  
  if (!mClassObject) {
    rv = CompilePrototypeMembers(aBinding); // This is the first time we've ever installed this binding on an element.
                                 // We need to go ahead and compile all methods and properties on a class
                                 // in our prototype binding.
    if (NS_FAILED(rv))
      return rv;

    MOZ_ASSERT(mClassObject);
  }

  nsIDocument *ownerDoc = aBoundElement->OwnerDoc();
  nsIGlobalObject *sgo;

  if (!(sgo = ownerDoc->GetScopeObject())) {
    return NS_ERROR_UNEXPECTED;
  }

  // Because our prototype implementation has a class, we need to build up a corresponding
  // class for the concrete implementation in the bound document.
  AutoPushJSContext cx(aContext->GetNativeContext());
  JS::Rooted<JSObject*> global(cx, sgo->GetGlobalJSObject());
  nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
  JS::Value v;
  rv = nsContentUtils::WrapNative(cx, global, aBoundElement, &v,
                                  getter_AddRefs(wrapper));
  NS_ENSURE_SUCCESS(rv, rv);

  JS::Rooted<JSObject*> value(cx, &v.toObject());

  // All of the above code was just obtaining the bound element's script object and its immediate
  // concrete base class.  We need to alter the object so that our concrete class is interposed
  // between the object and its base class.  We become the new base class of the object, and the
  // object's old base class becomes the new class' base class.
  rv = aBinding->InitClass(mClassName, cx, global, value, aTargetClassObject, aTargetIsNew);
  if (NS_FAILED(rv)) {
    return rv;
  }

  nsContentUtils::PreserveWrapper(aBoundElement, aBoundElement);

  wrapper.swap(*aScriptObjectHolder);
  
  return rv;
}
void
nsGeolocationService::HandleMozsettingChanged(const PRUnichar* aData)
{
    // The string that we're interested in will be a JSON string that looks like:
    //  {"key":"gelocation.enabled","value":true}

    SafeAutoJSContext cx;

    nsDependentString dataStr(aData);
    JS::Value val;
    if (!JS_ParseJSON(cx, dataStr.get(), dataStr.Length(), &val) || !val.isObject()) {
      return;
    }

    JSObject &obj(val.toObject());
    JS::Value key;
    if (!JS_GetProperty(cx, &obj, "key", &key) || !key.isString()) {
      return;
    }

    JSBool match;
    if (!JS_StringEqualsAscii(cx, key.toString(), GEO_SETINGS_ENABLED, &match) || (match != JS_TRUE)) {
      return;
    }

    JS::Value value;
    if (!JS_GetProperty(cx, &obj, "value", &value) || !value.isBoolean()) {
      return;
    }

    HandleMozsettingValue(value.toBoolean());
}
Example #21
0
bool
JSCompartment::putWrapper(const CrossCompartmentKey &wrapped, const js::Value &wrapper)
{
    JS_ASSERT(wrapped.wrapped);
    JS_ASSERT(!IsPoisonedPtr(wrapped.wrapped));
    JS_ASSERT(!IsPoisonedPtr(wrapped.debugger));
    JS_ASSERT(!IsPoisonedPtr(wrapper.toGCThing()));
    JS_ASSERT_IF(wrapped.kind == CrossCompartmentKey::StringWrapper, wrapper.isString());
    JS_ASSERT_IF(wrapped.kind != CrossCompartmentKey::StringWrapper, wrapper.isObject());
    return crossCompartmentWrappers.put(wrapped, wrapper);
}
Example #22
0
Promise*
GetPromise(JSContext* aCx, JS::Handle<JSObject*> aFunc)
{
  JS::Value promiseVal = js::GetFunctionNativeReserved(aFunc, SLOT_PROMISE);

  MOZ_ASSERT(promiseVal.isObject());

  Promise* promise;
  UNWRAP_OBJECT(Promise, &promiseVal.toObject(), promise);
  return promise;
}
Example #23
0
nsresult
nsJSON::EncodeInternal(JSContext* cx, const JS::Value& aValue,
                       nsJSONWriter* writer)
{
    // Backward compatibility:
    // nsIJSON does not allow to serialize anything other than objects
    if (!aValue.isObject()) {
        return NS_ERROR_INVALID_ARG;
    }
    JS::Rooted<JSObject*> obj(cx, &aValue.toObject());

    /* Backward compatibility:
     * Manually call toJSON if implemented by the object and check that
     * the result is still an object
     * Note: It is perfectly fine to not implement toJSON, so it is
     * perfectly fine for GetMethod to fail
     */
    JS::Rooted<JS::Value> val(cx, aValue);
    JS::Rooted<JS::Value> toJSON(cx);
    if (JS_GetProperty(cx, obj, "toJSON", &toJSON) &&
            toJSON.isObject() &&
            JS_ObjectIsCallable(cx, &toJSON.toObject())) {
        // If toJSON is implemented, it must not throw
        if (!JS_CallFunctionValue(cx, obj, toJSON, JS::HandleValueArray::empty(), &val)) {
            if (JS_IsExceptionPending(cx))
                // passing NS_OK will throw the pending exception
                return NS_OK;

            // No exception, but still failed
            return NS_ERROR_FAILURE;
        }

        // Backward compatibility:
        // nsIJSON does not allow to serialize anything other than objects
        if (val.isPrimitive())
            return NS_ERROR_INVALID_ARG;
    }
    // GetMethod may have thrown
    else if (JS_IsExceptionPending(cx))
        // passing NS_OK will throw the pending exception
        return NS_OK;

    // Backward compatibility:
    // function shall not pass, just "plain" objects and arrays
    JSType type = JS_TypeOfValue(cx, val);
    if (type == JSTYPE_FUNCTION)
        return NS_ERROR_INVALID_ARG;

    // We're good now; try to stringify
    if (!JS_Stringify(cx, &val, JS::NullPtr(), JS::NullHandleValue, WriteCallback, writer))
        return NS_ERROR_FAILURE;

    return NS_OK;
}
Example #24
0
JSObject*
XPCWrappedNativeScope::EnsureXBLScope(JSContext *cx)
{
    JSObject *global = GetGlobalJSObject();
    MOZ_ASSERT(js::IsObjectInContextCompartment(global, cx));
    MOZ_ASSERT(!mIsXBLScope);
    MOZ_ASSERT(strcmp(js::GetObjectClass(global)->name,
                      "nsXBLPrototypeScript compilation scope"));

    // If we already have a special XBL scope object, we know what to use.
    if (mXBLScope)
        return mXBLScope;

    // If this scope doesn't need an XBL scope, just return the global.
    if (!mUseXBLScope)
        return global;

    // Set up the sandbox options. Note that we use the DOM global as the
    // sandboxPrototype so that the XBL scope can access all the DOM objects
    // it's accustomed to accessing.
    //
    // NB: One would think that wantXrays wouldn't make a difference here.
    // However, wantXrays lives a secret double life, and one of its other
    // hobbies is to waive Xray on the returned sandbox when set to false.
    // So make sure to keep this set to true, here.
    SandboxOptions options;
    options.wantXrays = true;
    options.wantComponents = true;
    options.wantXHRConstructor = false;
    options.proto = global;
    options.sameZoneAs = global;

    // Use an nsExpandedPrincipal to create asymmetric security.
    nsIPrincipal *principal = GetPrincipal();
    nsCOMPtr<nsIExpandedPrincipal> ep;
    MOZ_ASSERT(!(ep = do_QueryInterface(principal)));
    nsTArray< nsCOMPtr<nsIPrincipal> > principalAsArray(1);
    principalAsArray.AppendElement(principal);
    ep = new nsExpandedPrincipal(principalAsArray);

    // Create the sandbox.
    JSAutoRequest ar(cx);
    JS::Value v = JS::UndefinedValue();
    nsresult rv = xpc_CreateSandboxObject(cx, &v, ep, options);
    NS_ENSURE_SUCCESS(rv, nullptr);
    mXBLScope = &v.toObject();

    // Tag it.
    EnsureCompartmentPrivate(js::UnwrapObject(mXBLScope))->scope->mIsXBLScope = true;

    // Good to go!
    return mXBLScope;
}
Example #25
0
bool CoerceDouble(const JS::Value& v, double* d) {
  if (v.isDouble()) {
    *d = v.toDouble();
  } else if (v.isInt32()) {
    *d = double(v.toInt32());
  } else if (v.isUndefined()) {
    *d = 0.0;
  } else {
    return false;
  }
  return true;
}
nsresult
DOMEventTargetHelper::SetEventHandler(nsIAtom* aType,
                                      JSContext* aCx,
                                      const JS::Value& aValue)
{
  RefPtr<EventHandlerNonNull> handler;
  JS::Rooted<JSObject*> callable(aCx);
  if (aValue.isObject() && JS::IsCallable(callable = &aValue.toObject())) {
    handler = new EventHandlerNonNull(aCx, callable, dom::GetIncumbentGlobal());
  }
  SetEventHandler(aType, EmptyString(), handler);
  return NS_OK;
}
Example #27
0
    NS_IMETHOD Handle(const nsAString& aName, const JS::Value& aResult)
    {
        MOZ_ASSERT(NS_IsMainThread());

        // The geolocation is enabled by default:
        bool value = true;
        if (aResult.isBoolean()) {
            value = aResult.toBoolean();
        }

        MozSettingValue(value);
        return NS_OK;
    }
Example #28
0
JS_BINDED_FUNC_IMPL(FakeAudio, addEventListener) {
	JS::CallArgs args = CallArgsFromVp(argc, vp);
	if (args.length() >=2) {
		JSStringWrapper wrapper(args[0]);
		string str((const char*)wrapper);
		if (str.compare("ended") == 0) {
			JS::Value jsthis = JS_THIS(cx, vp);
			shared_ptr<OpenALCallback> cb(new OpenALCallback(cx, args[1], jsthis.toObjectOrNull()));
			buffer->registerCallback(AudioEnded, cb);
		}
	}
	return JS_TRUE;
}
NS_IMETHODIMP
TCPSocketChild::SetSocketAndWindow(nsITCPSocketInternal *aSocket,
                          const JS::Value& aWindowObj,
                          JSContext* aCx)
{
  mSocket = aSocket;
  MOZ_ASSERT(aWindowObj.isObject());
  mWindowObj = js::CheckedUnwrap(&aWindowObj.toObject());
  if (!mWindowObj) {
    return NS_ERROR_FAILURE;
  }
  return NS_OK;
}
/**
 * Extract the FinalizationEvent from an instance of FinalizationWitness
 * and clear the slot containing the FinalizationEvent.
 */
already_AddRefed<FinalizationEvent>
ExtractFinalizationEvent(JSObject *objSelf)
{
  JS::Value slotEvent = JS_GetReservedSlot(objSelf, WITNESS_SLOT_EVENT);
  if (slotEvent.isUndefined()) {
    // Forget() has been called
    return nullptr;
  }

  JS_SetReservedSlot(objSelf, WITNESS_SLOT_EVENT, JS::UndefinedValue());

  return dont_AddRef(static_cast<FinalizationEvent*>(slotEvent.toPrivate()));
}