示例#1
0
JSBool JavaObject::getProperty(JSContext* ctx, JSObject* obj, jsid id,
    jsval* rval) {
  Debug::log(Debug::Spam) << "JavaObject::getProperty obj=" << obj << Debug::flush;
  SessionData* data = JavaObject::getSessionData(ctx, obj);
  if (!data) {
    // TODO: replace the frame with an error page instead?
    *rval = JSVAL_VOID;
    return JS_TRUE;
  }
  int objectRef = JavaObject::getObjectId(ctx, obj);
  if (JSID_IS_STRING(id)) {
    JSString* str = JSID_TO_STRING(id);
    if ((JS_GetStringEncodingLength(ctx, str) == 8) && !strncmp("toString",
          JS_EncodeString(ctx, str), 8)) {
      *rval = data->getToStringTearOff();
      return JS_TRUE;
    }
    if ((JS_GetStringEncodingLength(ctx, str) == 2) && !strncmp("id",
          JS_EncodeString(ctx, str), 2)) {
      *rval = INT_TO_JSVAL(objectRef);
      return JS_TRUE;
    }
    if ((JS_GetStringEncodingLength(ctx, str) == 16) && !strncmp("__noSuchMethod__",
          JS_EncodeString(ctx, str), 16)) {
      // Avoid error spew if we are disconnected
      *rval = JSVAL_VOID;
      return JS_TRUE;
    }
    Debug::log(Debug::Error) << "Getting unexpected string property "
        << dumpJsVal(ctx, id) << Debug::flush;
    // TODO: throw a better exception here
    return JS_FALSE;
  }
  if (!JSID_IS_INT(id)) {
    Debug::log(Debug::Error) << "Getting non-int/non-string property "
          << dumpJsVal(ctx, id) << Debug::flush;
    // TODO: throw a better exception here
    return JS_FALSE;
  }
  int dispId = JSID_TO_INT(id);

  HostChannel* channel = data->getHostChannel();
  SessionHandler* handler = data->getSessionHandler();

  Value value = ServerMethods::getProperty(*channel, handler, objectRef, dispId);
  data->makeJsvalFromValue(*rval, ctx, value);
  return JS_TRUE;
}
void FFSessionHandler::getToStringTearOff(JSContext* ctx) {
  jsval funcVal;

  Debug::log(Debug::Debugging) << "Getting function \"__gwt_makeTearOff\""
        << Debug::flush;

  if (!JS_GetProperty(ctx, global, "__gwt_makeTearOff", &funcVal)
      || funcVal == JSVAL_VOID) {
    Debug::log(Debug::Error) << "Could not get function \"__gwt_makeTearOff\""
        << Debug::flush;
    return;
  }
  jsval jsargs[3] = {
    JSVAL_NULL,                                     // no proxy
    INT_TO_JSVAL(InvokeMessage::TOSTRING_DISP_ID),  // dispId
    JSVAL_ZERO                                      // arg count is zero
  };
  if (!JS_CallFunctionValue(ctx, global, funcVal, 3, jsargs, &toStringTearOff)) {
    jsval exc;
    if (JS_GetPendingException(ctx, &exc)) {
      Debug::log(Debug::Error)
          << "__gwt_makeTearOff(null,0,0) threw exception "
          << dumpJsVal(ctx, exc) << Debug::flush;
    } else {
      Debug::log(Debug::Error) << "Error creating toString tear-off"
          << Debug::flush;
    }
    // TODO(jat): show some crash page and die
  }
}
示例#3
0
/**
 * Called when the JavaObject is invoked as a function.
 * We ignore the JSObject* argument, which is the 'this' context, which is
 * usually the window object. The JavaObject instance is in argv[-2].
 *
 * Returns a JS array, with the first element being a boolean indicating that
 * an exception occured, and the second element is either the return value or
 * the exception which was thrown.  In this case, we always return false and
 * raise the exception ourselves.
 */
JSBool JavaObject::call(JSContext* ctx, JSObject*, uintN argc, jsval* argv,
    jsval* rval) {
  // Get the JavaObject called as a function
  JSObject* obj = JSVAL_TO_OBJECT(argv[-2]);
  if (argc < 2 || !JSVAL_IS_INT(argv[0]) ||
#ifdef JSVAL_IS_OBJECT
  !JSVAL_IS_OBJECT(argv[1])) {
#else
    (JSVAL_IS_PRIMITIVE(argv[1]) && !JSVAL_IS_NULL(argv[1]))) {
#endif
    Debug::log(Debug::Error) << "JavaObject::call incorrect arguments" << Debug::flush;
    return JS_FALSE;
  }
  int dispId = JSVAL_TO_INT(argv[0]);
  if (Debug::level(Debug::Spam)) {
    Debug::DebugStream& dbg = Debug::log(Debug::Spam) << "JavaObject::call oid="
        << JavaObject::getObjectId(ctx, obj) << ",dispId=" << dispId << " (";
    for (unsigned i = 2; i < argc; ++i) {
      if (i > 2) {
        dbg << ", ";
      }
      dbg << dumpJsVal(ctx, argv[i]);
    }
    dbg << ")" << Debug::flush;
  }

  SessionData* data = JavaObject::getSessionData(ctx, obj);
  if (!data) {
    *rval = JSVAL_VOID;
    return JS_TRUE;
  }
  Debug::log(Debug::Spam) << "Data = " << data << Debug::flush;

  gwt::Value javaThis;
  if (!JSVAL_IS_NULL(argv[1])) {
    JSObject* thisObj = JSVAL_TO_OBJECT(argv[1]);
    if (isJavaObject(ctx, thisObj)) {
      javaThis.setJavaObject(getObjectId(ctx, thisObj));
    } else {
      data->makeValueFromJsval(javaThis, ctx, argv[1]);
    }
  } else {
    int oid = getObjectId(ctx, obj);
    javaThis.setJavaObject(oid);
  }
  return invokeJava(ctx, data, javaThis, dispId, argc - 2, &argv[2], rval);
}