コンテキストをまたいでevalでcallerにアクセスできないのはなぜか

~/mozilla/js/src/jsfun.c

static JSBool
fun_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
....
      case FUN_CALLER:
        if (fp && fp->down && fp->down->fun)
            *vp = OBJECT_TO_JSVAL(fp->down->callee);
        else
            *vp = JSVAL_NULL;
        if (!JSVAL_IS_PRIMITIVE(*vp) && cx->runtime->checkObjectAccess) {
            id = ATOM_KEY(cx->runtime->atomState.callerAtom);
            if (!cx->runtime->checkObjectAccess(cx, obj, id, JSACC_READ, vp))
                return JS_FALSE;
        }
        break;

checkObjectAccessを調べると

~/mozilla/js/src/jscntxt.h

    /*
     * Check property accessibility for objects of arbitrary class.  Used at
     * present to check f.caller accessibility for any function object f.
     */
    JSCheckAccessOp     checkObjectAccess;

callerのアクセスチェックだけに用意されている。
代入される実体はnsScriptSecurityManager::CheckObjectAccessになっている。

///////////////// Security Checks /////////////////
JSBool JS_DLL_CALLBACK
nsScriptSecurityManager::CheckObjectAccess(JSContext *cx, JSObject *obj,
                                           jsval id, JSAccessMode mode,
                                           jsval *vp)
{
    // Get the security manager
    nsScriptSecurityManager *ssm =
        nsScriptSecurityManager::GetScriptSecurityManager();

    NS_ASSERTION(ssm, "Failed to get security manager service");
    if (!ssm)
        return JS_FALSE;

    // Get the object being accessed.  We protect these cases:
    // 1. The Function.prototype.caller property's value, which might lead
    //    an attacker up a call-stack to a function or another object from
    //    a different trust domain.
    // 2. A user-defined getter or setter function accessible on another
    //    trust domain's window or document object.
    // *vp can be a primitive, in that case, we use obj as the target
    // object.
    JSObject* target = JSVAL_IS_PRIMITIVE(*vp) ? obj : JSVAL_TO_OBJECT(*vp);

    // Do the same-origin check -- this sets a JS exception if the check fails.
    // Pass the parent object's class name, as we have no class-info for it.
    nsresult rv =
        ssm->CheckPropertyAccess(cx, target, JS_GetClass(cx, obj)->name, id,
                                 (mode & JSACC_WRITE) ?
                                 nsIXPCSecurityManager::ACCESS_SET_PROPERTY :
                                 nsIXPCSecurityManager::ACCESS_GET_PROPERTY);

前回のComponents.classesと同じところでチェックが行われる。

nsIXPCNativeCallContext aCallContextがNULLになってる。
FirebugコンソールからComponents.classesを参照したときはnot NULLだった。名前からすると呼び出し元がネイティブのコードかどうか。
GMの場合scripted functionからなのでnullなのだと予想される。

gmのなかで eval("", arguments.callee.caller) するとclassnameはFunction. subjectのprincipalはsystem.

same originが適用される。
subject principal がページのcodebaseなのにたいしてobject principalはsystem になっていてNG.