예제 #1
0
bool AJFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    if (isHostFunction())
        return Base::getOwnPropertySlot(exec, propertyName, slot);

    if (propertyName == exec->propertyNames().prototype) {
        AJValue* location = getDirectLocation(propertyName);

        if (!location) {
            AJObject* prototype = new (exec) AJObject(scopeChain().globalObject()->emptyObjectStructure());
            prototype->putDirect(exec->propertyNames().constructor, this, DontEnum);
            putDirect(exec->propertyNames().prototype, prototype, DontDelete);
            location = getDirectLocation(propertyName);
        }

        slot.setValueSlot(this, location, offsetForLocation(location));
    }

    if (propertyName == exec->propertyNames().arguments) {
        slot.setCacheableCustom(this, argumentsGetter);
        return true;
    }

    if (propertyName == exec->propertyNames().length) {
        slot.setCacheableCustom(this, lengthGetter);
        return true;
    }

    if (propertyName == exec->propertyNames().caller) {
        slot.setCacheableCustom(this, callerGetter);
        return true;
    }

    return Base::getOwnPropertySlot(exec, propertyName, slot);
}
예제 #2
0
 bool AJFunction::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
 {
     if (isHostFunction())
         return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
     
     if (propertyName == exec->propertyNames().prototype) {
         PropertySlot slot;
         getOwnPropertySlot(exec, propertyName, slot);
         return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
     }
     
     if (propertyName == exec->propertyNames().arguments) {
         descriptor.setDescriptor(exec->interpreter()->retrieveArguments(exec, this), ReadOnly | DontEnum | DontDelete);
         return true;
     }
     
     if (propertyName == exec->propertyNames().length) {
         descriptor.setDescriptor(jsNumber(exec, jsExecutable()->parameterCount()), ReadOnly | DontEnum | DontDelete);
         return true;
     }
     
     if (propertyName == exec->propertyNames().caller) {
         descriptor.setDescriptor(exec->interpreter()->retrieveCaller(exec, this), ReadOnly | DontEnum | DontDelete);
         return true;
     }
     
     return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
 }
예제 #3
0
// ECMA 13.2.2 [[Construct]]
ConstructType AJFunction::getConstructData(ConstructData& constructData)
{
    if (isHostFunction())
        return ConstructTypeNone;
    constructData.js.functionExecutable = jsExecutable();
    constructData.js.scopeChain = scopeChain().node();
    return ConstructTypeJS;
}
예제 #4
0
void AJFunction::markChildren(MarkStack& markStack)
{
    Base::markChildren(markStack);
    if (!isHostFunction()) {
        jsExecutable()->markAggregate(markStack);
        scopeChain().markAggregate(markStack);
    }
}
예제 #5
0
bool AJFunction::deleteProperty(ExecState* exec, const Identifier& propertyName)
{
    if (isHostFunction())
        return Base::deleteProperty(exec, propertyName);
    if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
        return false;
    return Base::deleteProperty(exec, propertyName);
}
예제 #6
0
void AJFunction::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
{
    if (!isHostFunction() && (mode == IncludeDontEnumProperties)) {
        propertyNames.add(exec->propertyNames().arguments);
        propertyNames.add(exec->propertyNames().callee);
        propertyNames.add(exec->propertyNames().caller);
        propertyNames.add(exec->propertyNames().length);
    }
    Base::getOwnPropertyNames(exec, propertyNames, mode);
}
예제 #7
0
void AJFunction::put(ExecState* exec, const Identifier& propertyName, AJValue value, PutPropertySlot& slot)
{
    if (isHostFunction()) {
        Base::put(exec, propertyName, value, slot);
        return;
    }
    if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
        return;
    Base::put(exec, propertyName, value, slot);
}
예제 #8
0
CallType AJFunction::getCallData(CallData& callData)
{
    if (isHostFunction()) {
        callData.native.function = nativeFunction();
        return CallTypeHost;
    }
    callData.js.functionExecutable = jsExecutable();
    callData.js.scopeChain = scopeChain().node();
    return CallTypeJS;
}
예제 #9
0
CallType JSFunction::getCallData(CallData& callData)
{
#if ENABLE(JIT)
    if (isHostFunction()) {
        callData.native.function = nativeFunction();
        return CallTypeHost;
    }
#endif
    callData.js.functionExecutable = jsExecutable();
    callData.js.scopeChain = scope().node();
    return CallTypeJS;
}
예제 #10
0
void JSFunction::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
{
    if (!isHostFunction() && (mode == IncludeDontEnumProperties)) {
        // Make sure prototype has been reified.
        PropertySlot slot;
        getOwnPropertySlotVirtual(exec, exec->propertyNames().prototype, slot);

        propertyNames.add(exec->propertyNames().arguments);
        propertyNames.add(exec->propertyNames().caller);
        propertyNames.add(exec->propertyNames().length);
    }
    Base::getOwnPropertyNames(exec, propertyNames, mode);
}
예제 #11
0
const String JSFunction::calculatedDisplayName(ExecState* exec)
{
    const String explicitName = displayName(exec);
    
    if (!explicitName.isEmpty())
        return explicitName;
    
    const String actualName = name(exec);
    if (!actualName.isEmpty() || isHostFunction())
        return actualName;
    
    return jsExecutable()->inferredName().string();
}
예제 #12
0
JSFunction::~JSFunction()
{
    // JIT code for other functions may have had calls linked directly to the code for this function; these links
    // are based on a check for the this pointer value for this JSFunction - which will no longer be valid once
    // this memory is freed and may be reused (potentially for another, different JSFunction).
    if (!isHostFunction()) {
#if ENABLE(JIT_OPTIMIZE_CALL)
        ASSERT(m_executable);
        if (jsExecutable()->isGenerated())
            jsExecutable()->generatedBytecode().unlinkCallers();
#endif
        scopeChain().~ScopeChain(); // FIXME: Don't we need to do this in the interpreter too?
    }
}
예제 #13
0
AJObject* AJFunction::construct(ExecState* exec, const ArgList& args)
{
    ASSERT(!isHostFunction());
    Structure* structure;
    AJValue prototype = get(exec, exec->propertyNames().prototype);
    if (prototype.isObject())
        structure = asObject(prototype)->inheritorID();
    else
        structure = exec->lexicalGlobalObject()->emptyObjectStructure();
    AJObject* thisObj = new (exec) AJObject(structure);

    AJValue result = exec->interpreter()->execute(jsExecutable(), exec, this, thisObj, args, scopeChain().node(), exec->exceptionSlot());
    if (exec->hadException() || !result.isObject())
        return thisObj;
    return asObject(result);
}
예제 #14
0
bool JSFunction::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    if (isHostFunction())
        return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
    
    if (propertyName == exec->propertyNames().prototype) {
        PropertySlot slot;
        getOwnPropertySlotVirtual(exec, propertyName, slot);
        return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
    }
    
    if (propertyName == exec->propertyNames().arguments) {
        if (jsExecutable()->isStrictMode()) {
            bool result = Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
            if (!result) {
                initializeGetterSetterProperty(exec, propertyName, globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Getter | Setter);
                result = Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
                ASSERT(result);
            }
            return result;
        }
        descriptor.setDescriptor(exec->interpreter()->retrieveArguments(exec, this), ReadOnly | DontEnum | DontDelete);
        return true;
    }
    
    if (propertyName == exec->propertyNames().length) {
        descriptor.setDescriptor(jsNumber(jsExecutable()->parameterCount()), ReadOnly | DontEnum | DontDelete);
        return true;
    }
    
    if (propertyName == exec->propertyNames().caller) {
        if (jsExecutable()->isStrictMode()) {
            bool result = Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
            if (!result) {
                initializeGetterSetterProperty(exec, propertyName, globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Getter | Setter);
                result = Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
                ASSERT(result);
            }
            return result;
        }
        descriptor.setDescriptor(exec->interpreter()->retrieveCaller(exec, this), ReadOnly | DontEnum | DontDelete);
        return true;
    }
    
    return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
}
예제 #15
0
JSFunction::~JSFunction()
{
    ASSERT(vptr() == JSGlobalData::jsFunctionVPtr);

    // JIT code for other functions may have had calls linked directly to the code for this function; these links
    // are based on a check for the this pointer value for this JSFunction - which will no longer be valid once
    // this memory is freed and may be reused (potentially for another, different JSFunction).
    if (!isHostFunction()) {
#if ENABLE(JIT_OPTIMIZE_CALL)
        ASSERT(m_executable);
        if (jsExecutable()->isGeneratedForCall())
            jsExecutable()->generatedBytecodeForCall().unlinkCallers();
        if (jsExecutable()->isGeneratedForConstruct())
            jsExecutable()->generatedBytecodeForConstruct().unlinkCallers();
#endif
    }
}
예제 #16
0
// Property access sequence is:
// (1) indexed properties,
// (2) regular own properties,
// (3) named properties (in fact, these shouldn't be on the window, should be on the NPO).
bool JSDOMWindow::getOwnPropertySlot(JSObject* object, ExecState* state, PropertyName propertyName, PropertySlot& slot)
{
    // (1) First, indexed properties.
    // Hand off all indexed access to getOwnPropertySlotByIndex, which supports the indexed getter.
    if (Optional<unsigned> index = parseIndex(propertyName))
        return getOwnPropertySlotByIndex(object, state, index.value(), slot);

    auto* thisObject = jsCast<JSDOMWindow*>(object);
    auto* frame = thisObject->wrapped().frame();

    // Hand off all cross-domain/frameless access to jsDOMWindowGetOwnPropertySlotRestrictedAccess.
    String errorMessage;
    if (!frame || !BindingSecurity::shouldAllowAccessToDOMWindow(*state, thisObject->wrapped(), errorMessage))
        return jsDOMWindowGetOwnPropertySlotRestrictedAccess(thisObject, frame, state, propertyName, slot, errorMessage);
    
    // FIXME: this need more explanation.
    // (Particularly, is it correct that this exists here but not in getOwnPropertySlotByIndex?)
    slot.setWatchpointSet(thisObject->m_windowCloseWatchpoints);

    // (2) Regular own properties.
    PropertySlot slotCopy = slot;
    if (Base::getOwnPropertySlot(thisObject, state, propertyName, slot)) {
        // Detect when we're getting the property 'showModalDialog', this is disabled, and has its original value.
        bool isShowModalDialogAndShouldHide = propertyName == state->propertyNames().showModalDialog
            && !DOMWindow::canShowModalDialog(frame)
            && slot.isValue() && isHostFunction(slot.getValue(state, propertyName), jsDOMWindowInstanceFunctionShowModalDialog);
        // Unless we're in the showModalDialog special case, we're done.
        if (!isShowModalDialogAndShouldHide)
            return true;
        slot = slotCopy;
    }

#if ENABLE(USER_MESSAGE_HANDLERS)
    if (propertyName == state->propertyNames().webkit && thisObject->wrapped().shouldHaveWebKitNamespaceForWorld(thisObject->world())) {
        slot.setCacheableCustom(thisObject, DontDelete | ReadOnly, jsDOMWindowWebKit);
        return true;
    }
#endif

    return false;
}
예제 #17
0
const SourceCode* JSFunction::sourceCode() const
{
    if (isHostFunction())
        return 0;
    return &jsExecutable()->source();
}
예제 #18
0
AJValue AJFunction::call(ExecState* exec, AJValue thisValue, const ArgList& args)
{
    ASSERT(!isHostFunction());
    return exec->interpreter()->execute(jsExecutable(), exec, this, thisValue.toThisObject(exec), args, scopeChain().node(), exec->exceptionSlot());
}
예제 #19
0
bool JSFunction::isBuiltinFunction() const
{
    return !isHostFunction() && jsExecutable()->isBuiltinFunction();
}
예제 #20
0
bool AJFunction::isHostFunctionNonInline() const
{
    return isHostFunction();
}
예제 #21
0
bool JSFunction::isHostOrBuiltinFunction() const
{
    return isHostFunction() || isBuiltinFunction();
}