Example #1
0
JSBool PJS_invoke_perl_property_getter(JSContext *cx, JSObject *obj, jsval id, jsval *vp) {
    dSP;
    PJS_Context *pcx;
    PJS_Class *pcls;
    PJS_Property *pprop;
    SV *caller;
    char *name;
    jsint slot;
    U8 invocation_mode;

    if (!(JSVAL_IS_INT(id) || JSVAL_IS_STRING(id))) {
        return JS_TRUE;
    }
    
    if((pcx = PJS_GET_CONTEXT(cx)) == NULL) {
        JS_ReportError(cx, "Can't find context %d", cx);
        return JS_FALSE;
    }

    if (JS_TypeOfValue(cx, OBJECT_TO_JSVAL(obj)) == JSTYPE_OBJECT) {
        /* Called as instsance */
        JSClass *clasp = PJS_GET_CLASS(cx, obj);
        name = (char *) clasp->name;
        invocation_mode = 1;
    }
    else {
        /* Called as static */
        JSFunction *parent_jfunc = JS_ValueToFunction(cx, OBJECT_TO_JSVAL(obj));
        if (parent_jfunc == NULL) {
            JS_ReportError(cx, "Failed to extract class for static property getter");
            return JS_FALSE;
        }
        name = (char *) JS_GetFunctionName(parent_jfunc);
        invocation_mode = 0;
    }
    
    if ((pcls = PJS_GetClassByName(pcx, name)) == NULL) {
        JS_ReportError(cx, "Can't find class '%s'", name);
        return JS_FALSE;
    }
    
    if (invocation_mode) {
        caller = (SV *) JS_GetPrivate(cx, obj);
    }
    else {
        caller = newSVpv(pcls->pkg, 0);
    }
    
    if (JSVAL_IS_INT(id)) {
      slot = JSVAL_TO_INT(id);
    
      if ((pprop = PJS_get_property_by_id(pcls,  (int8) slot)) == NULL) {
        if (SvTRUE(pcls->property_getter)) {
            if (perl_call_sv_with_jsvals(cx, obj, pcls->property_getter, caller, 1, &id, vp) < 0) {
                return JS_FALSE;
            }
            return JS_TRUE;
        }
        JS_ReportError(cx, "Can't find property handler");
        return JS_FALSE;
      }

      if (pprop->getter == NULL) {
        JS_ReportError(cx, "Property is write-only");
        return JS_FALSE;
      }

      if (perl_call_sv_with_jsvals(cx, obj, pprop->getter, caller, 0, NULL, vp) < 0) {
        return JS_FALSE;
      }
    }
    else if (JSVAL_IS_STRING(id) && SvTRUE(pcls->property_getter)) {
      SV *sv = sv_newmortal();
#ifdef JS_C_STRINGS_ARE_UTF8
      char *tmp = JS_smprintf("%hs", JS_GetStringChars(JSVAL_TO_STRING(id)));
      sv_setpv(sv, tmp);
      SvUTF8_on(sv);
      free(tmp);
#else
      sv_setpv(sv, JS_GetStringBytes(JSVAL_TO_STRING(id)));
#endif         

      if (PJS_get_method_by_name(pcls, SvPV_nolen(sv))) {
        return JS_TRUE;
      }
      
      if (perl_call_sv_with_jsvals(cx, obj, pcls->property_getter, caller, 1, &id, vp) < 0) {
        return JS_FALSE;
      }      
    }

    return JS_TRUE;
}
Example #2
0
JSBool PJS_invoke_perl_object_method(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) {
    PJS_Context *pcx;
    PJS_Class *pcls;
    PJS_Function *pfunc;
    JSFunction *jfunc = PJS_FUNC_SELF;
    SV *caller;
    char *name;
    U8 invocation_mode;
    
    if((pcx = PJS_GET_CONTEXT(cx)) == NULL) {
        JS_ReportError(cx, "Can't find context %d", cx);
        return JS_FALSE;
    }

    if (JS_TypeOfValue(cx, OBJECT_TO_JSVAL(obj)) == JSTYPE_OBJECT) {
        /* Called as instsance */
        JSClass *clasp = PJS_GET_CLASS(cx, obj);
        name = (char *) clasp->name;
        invocation_mode = 1;
    }
    else {
        /* Called as static */
        JSFunction *parent_jfunc = JS_ValueToFunction(cx, OBJECT_TO_JSVAL(obj));
        if (parent_jfunc == NULL) {
            JS_ReportError(cx, "Failed to extract class for static property getter");
            return JS_FALSE;
        }
        name = (char *) JS_GetFunctionName(parent_jfunc);
        invocation_mode = 0;
    }

    if (!(pcls = PJS_GetClassByName(pcx, name))) {
        JS_ReportError(cx, "Can't find class '%s'", name);
        return JS_FALSE;
    }

    name = (char *) JS_GetFunctionName(jfunc);

    if((pfunc = PJS_get_method_by_name(pcls, name)) == NULL) {
        JS_ReportError(cx, "Can't find method '%s' in '%s'", name, pcls->clasp->name);
        return JS_FALSE;
    }

    if (invocation_mode) {
        caller = (SV *) JS_GetPrivate(cx, obj);
    }
    else {
        caller = newSVpv(pcls->pkg, 0);
    }

    /* XXX: the original invocation here has slightly different
       retrun value handling.  if the returned value is reference
       same as priv, don't return it.  While the case is not
       covered by the tets */
    
    if (perl_call_sv_with_jsvals(cx, obj, pfunc->callback,
                                 caller, argc, argv, rval) < 0) {
        return JS_FALSE;
    }

    return JS_TRUE;
}