📄 jscallbackobjectfunctions.h
字号:
/* * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. * Copyright (C) 2007 Eric Seidel <eric@webkit.org> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#include "APICast.h"#include "Error.h"#include "JSCallbackFunction.h"#include "JSClassRef.h"#include "JSGlobalObject.h"#include "JSLock.h"#include "JSObjectRef.h"#include "JSString.h"#include "JSStringRef.h"#include "OpaqueJSString.h"#include "PropertyNameArray.h"#include <wtf/Vector.h>namespace JSC {template <class Base>inline JSCallbackObject<Base>* JSCallbackObject<Base>::asCallbackObject(JSValuePtr value){ ASSERT(asObject(value)->inherits(&info)); return static_cast<JSCallbackObject*>(asObject(value));}template <class Base>JSCallbackObject<Base>::JSCallbackObject(ExecState* exec, PassRefPtr<Structure> structure, JSClassRef jsClass, void* data) : Base(structure) , m_callbackObjectData(new JSCallbackObjectData(data, jsClass)){ init(exec);}// Global object constructor.// FIXME: Move this into a separate JSGlobalCallbackObject class derived from this one.template <class Base>JSCallbackObject<Base>::JSCallbackObject(JSClassRef jsClass) : Base() , m_callbackObjectData(new JSCallbackObjectData(0, jsClass)){ ASSERT(Base::isGlobalObject()); init(static_cast<JSGlobalObject*>(this)->globalExec());}template <class Base>void JSCallbackObject<Base>::init(ExecState* exec){ ASSERT(exec); Vector<JSObjectInitializeCallback, 16> initRoutines; JSClassRef jsClass = classRef(); do { if (JSObjectInitializeCallback initialize = jsClass->initialize) initRoutines.append(initialize); } while ((jsClass = jsClass->parentClass)); // initialize from base to derived for (int i = static_cast<int>(initRoutines.size()) - 1; i >= 0; i--) { JSLock::DropAllLocks dropAllLocks(exec); JSObjectInitializeCallback initialize = initRoutines[i]; initialize(toRef(exec), toRef(this)); }}template <class Base>JSCallbackObject<Base>::~JSCallbackObject(){ JSObjectRef thisRef = toRef(this); for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) if (JSObjectFinalizeCallback finalize = jsClass->finalize) finalize(thisRef);}template <class Base>UString JSCallbackObject<Base>::className() const{ UString thisClassName = classRef()->className(); if (!thisClassName.isNull()) return thisClassName; return Base::className();}template <class Base>bool JSCallbackObject<Base>::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot){ JSContextRef ctx = toRef(exec); JSObjectRef thisRef = toRef(this); RefPtr<OpaqueJSString> propertyNameRef; for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) { // optional optimization to bypass getProperty in cases when we only need to know if the property exists if (JSObjectHasPropertyCallback hasProperty = jsClass->hasProperty) { if (!propertyNameRef) propertyNameRef = OpaqueJSString::create(propertyName.ustring()); JSLock::DropAllLocks dropAllLocks(exec); if (hasProperty(ctx, thisRef, propertyNameRef.get())) { slot.setCustom(this, callbackGetter); return true; } } else if (JSObjectGetPropertyCallback getProperty = jsClass->getProperty) { if (!propertyNameRef) propertyNameRef = OpaqueJSString::create(propertyName.ustring()); JSLock::DropAllLocks dropAllLocks(exec); if (JSValueRef value = getProperty(ctx, thisRef, propertyNameRef.get(), toRef(exec->exceptionSlot()))) { slot.setValue(toJS(value)); return true; } } if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) { if (staticValues->contains(propertyName.ustring().rep())) { slot.setCustom(this, staticValueGetter); return true; } } if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) { if (staticFunctions->contains(propertyName.ustring().rep())) { slot.setCustom(this, staticFunctionGetter); return true; } } } return Base::getOwnPropertySlot(exec, propertyName, slot);}template <class Base>bool JSCallbackObject<Base>::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot){ return getOwnPropertySlot(exec, Identifier::from(exec, propertyName), slot);}template <class Base>void JSCallbackObject<Base>::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot){ JSContextRef ctx = toRef(exec); JSObjectRef thisRef = toRef(this); RefPtr<OpaqueJSString> propertyNameRef; JSValueRef valueRef = toRef(value); for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) { if (JSObjectSetPropertyCallback setProperty = jsClass->setProperty) { if (!propertyNameRef) propertyNameRef = OpaqueJSString::create(propertyName.ustring()); JSLock::DropAllLocks dropAllLocks(exec); if (setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, toRef(exec->exceptionSlot()))) return; } if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) { if (StaticValueEntry* entry = staticValues->get(propertyName.ustring().rep())) { if (entry->attributes & kJSPropertyAttributeReadOnly) return; if (JSObjectSetPropertyCallback setProperty = entry->setProperty) { if (!propertyNameRef) propertyNameRef = OpaqueJSString::create(propertyName.ustring()); JSLock::DropAllLocks dropAllLocks(exec); if (setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, toRef(exec->exceptionSlot()))) return; } else throwError(exec, ReferenceError, "Attempt to set a property that is not settable."); } } if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) { if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.ustring().rep())) { if (entry->attributes & kJSPropertyAttributeReadOnly) return; JSCallbackObject<Base>::putDirect(propertyName, value); // put as override property return; } } } return Base::put(exec, propertyName, value, slot);}template <class Base>bool JSCallbackObject<Base>::deleteProperty(ExecState* exec, const Identifier& propertyName){ JSContextRef ctx = toRef(exec); JSObjectRef thisRef = toRef(this); RefPtr<OpaqueJSString> propertyNameRef; for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) { if (JSObjectDeletePropertyCallback deleteProperty = jsClass->deleteProperty) { if (!propertyNameRef) propertyNameRef = OpaqueJSString::create(propertyName.ustring()); JSLock::DropAllLocks dropAllLocks(exec); if (deleteProperty(ctx, thisRef, propertyNameRef.get(), toRef(exec->exceptionSlot()))) return true; } if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) { if (StaticValueEntry* entry = staticValues->get(propertyName.ustring().rep())) { if (entry->attributes & kJSPropertyAttributeDontDelete) return false; return true; } } if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) { if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.ustring().rep())) { if (entry->attributes & kJSPropertyAttributeDontDelete) return false; return true; } } } return Base::deleteProperty(exec, propertyName);}template <class Base>bool JSCallbackObject<Base>::deleteProperty(ExecState* exec, unsigned propertyName){ return deleteProperty(exec, Identifier::from(exec, propertyName));}template <class Base>ConstructType JSCallbackObject<Base>::getConstructData(ConstructData& constructData){ for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) { if (jsClass->callAsConstructor) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -