📄 webscriptobject.mm
字号:
/* * Copyright (C) 2004, 2006, 2007, 2008 Apple Inc. All rights reserved. * * 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. */#import "config.h"#import "WebScriptObjectPrivate.h"#import "Console.h"#import "DOMInternal.h"#import "DOMWindow.h"#import "Frame.h"#import "JSDOMWindow.h"#import "JSDOMWindowCustom.h"#import "PlatformString.h"#import "StringSourceProvider.h"#import "WebCoreObjCExtras.h"#import "objc_instance.h"#import "runtime.h"#import "runtime_object.h"#import "runtime_root.h"#import <JavaScriptCore/APICast.h>#import <interpreter/CallFrame.h>#import <runtime/InitializeThreading.h>#import <runtime/JSGlobalObject.h>#import <runtime/JSLock.h>#import <runtime/Completion.h>#import <runtime/Completion.h>#ifdef BUILDING_ON_TIGERtypedef unsigned NSUInteger;#endifusing namespace JSC;using namespace JSC::Bindings;using namespace WebCore;namespace WebCore {static NSMapTable* JSWrapperCache;NSObject* getJSWrapper(JSObject* impl){ if (!JSWrapperCache) return nil; return static_cast<NSObject*>(NSMapGet(JSWrapperCache, impl));}void addJSWrapper(NSObject* wrapper, JSObject* impl){ if (!JSWrapperCache) JSWrapperCache = createWrapperCache(); NSMapInsert(JSWrapperCache, impl, wrapper);}void removeJSWrapper(JSObject* impl){ if (!JSWrapperCache) return; NSMapRemove(JSWrapperCache, impl);}id createJSWrapper(JSC::JSObject* object, PassRefPtr<JSC::Bindings::RootObject> origin, PassRefPtr<JSC::Bindings::RootObject> root){ if (id wrapper = getJSWrapper(object)) return [[wrapper retain] autorelease]; return [[[WebScriptObject alloc] _initWithJSObject:object originRootObject:origin rootObject:root] autorelease];}static void addExceptionToConsole(ExecState* exec){ JSDOMWindow* window = asJSDOMWindow(exec->dynamicGlobalObject()); if (!window || !exec->hadException()) return; reportCurrentException(exec);}} // namespace WebCore@implementation WebScriptObjectPrivate@end@implementation WebScriptObject+ (void)initialize{ JSC::initializeThreading();#ifndef BUILDING_ON_TIGER WebCoreObjCFinalizeOnMainThread(self);#endif}+ (id)scriptObjectForJSObject:(JSObjectRef)jsObject originRootObject:(RootObject*)originRootObject rootObject:(RootObject*)rootObject{ if (id domWrapper = WebCore::createDOMWrapper(toJS(jsObject), originRootObject, rootObject)) return domWrapper; return WebCore::createJSWrapper(toJS(jsObject), originRootObject, rootObject);}static void _didExecute(WebScriptObject *obj){ ASSERT(JSLock::lockCount() > 0); RootObject* root = [obj _rootObject]; if (!root) return; ExecState* exec = root->globalObject()->globalExec(); KJSDidExecuteFunctionPtr func = Instance::didExecuteFunction(); if (func) func(exec, root->globalObject());}- (void)_setImp:(JSObject*)imp originRootObject:(PassRefPtr<RootObject>)originRootObject rootObject:(PassRefPtr<RootObject>)rootObject{ // This function should only be called once, as a (possibly lazy) initializer. ASSERT(!_private->imp); ASSERT(!_private->rootObject); ASSERT(!_private->originRootObject); ASSERT(imp); _private->imp = imp; _private->rootObject = rootObject.releaseRef(); _private->originRootObject = originRootObject.releaseRef(); WebCore::addJSWrapper(self, imp); if (_private->rootObject) _private->rootObject->gcProtect(imp);}- (void)_setOriginRootObject:(PassRefPtr<RootObject>)originRootObject andRootObject:(PassRefPtr<RootObject>)rootObject{ ASSERT(_private->imp); if (rootObject) rootObject->gcProtect(_private->imp); if (_private->rootObject && _private->rootObject->isValid()) _private->rootObject->gcUnprotect(_private->imp); if (_private->rootObject) _private->rootObject->deref(); if (_private->originRootObject) _private->originRootObject->deref(); _private->rootObject = rootObject.releaseRef(); _private->originRootObject = originRootObject.releaseRef();}- (id)_initWithJSObject:(JSC::JSObject*)imp originRootObject:(PassRefPtr<JSC::Bindings::RootObject>)originRootObject rootObject:(PassRefPtr<JSC::Bindings::RootObject>)rootObject{ ASSERT(imp); self = [super init]; _private = [[WebScriptObjectPrivate alloc] init]; [self _setImp:imp originRootObject:originRootObject rootObject:rootObject]; return self;}- (JSObject*)_imp{ // Associate the WebScriptObject with the JS wrapper for the ObjC DOM wrapper. // This is done on lazily, on demand. if (!_private->imp && _private->isCreatedByDOMWrapper) [self _initializeScriptDOMNodeImp]; return [self _rootObject] ? _private->imp : 0;}- (BOOL)_hasImp{ return _private->imp != nil;}// Node that DOMNode overrides this method. So you should almost always// use this method call instead of _private->rootObject directly.- (RootObject*)_rootObject{ return _private->rootObject && _private->rootObject->isValid() ? _private->rootObject : 0;}- (RootObject *)_originRootObject{ return _private->originRootObject && _private->originRootObject->isValid() ? _private->originRootObject : 0;}- (BOOL)_isSafeScript{ RootObject *root = [self _rootObject]; if (!root) return false; if (!_private->originRootObject) return true; if (!_private->originRootObject->isValid()) return false; return root->globalObject()->allowsAccessFrom(_private->originRootObject->globalObject());}- (void)dealloc{ if (WebCoreObjCScheduleDeallocateOnMainThread([WebScriptObject class], self)) return; if (_private->imp) WebCore::removeJSWrapper(_private->imp); if (_private->rootObject && _private->rootObject->isValid()) _private->rootObject->gcUnprotect(_private->imp); if (_private->rootObject) _private->rootObject->deref(); if (_private->originRootObject) _private->originRootObject->deref(); [_private release]; [super dealloc];}- (void)finalize{ if (_private->rootObject && _private->rootObject->isValid()) _private->rootObject->gcUnprotect(_private->imp); if (_private->rootObject) _private->rootObject->deref(); if (_private->originRootObject) _private->originRootObject->deref(); [super finalize];}+ (BOOL)throwException:(NSString *)exceptionMessage{ ObjcInstance::setGlobalException(exceptionMessage); return YES;}static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* rootObject, ArgList& aList){ int i, numObjects = array ? [array count] : 0; for (i = 0; i < numObjects; i++) { id anObject = [array objectAtIndex:i]; aList.append(convertObjcValueToValue(exec, &anObject, ObjcObjectType, rootObject)); }}- (id)callWebScriptMethod:(NSString *)name withArguments:(NSArray *)args{ if (![self _isSafeScript]) return nil; JSLock lock(false); // Look up the function object. ExecState* exec = [self _rootObject]->globalObject()->globalExec(); ASSERT(!exec->hadException()); JSValuePtr function = [self _imp]->get(exec, Identifier(exec, String(name))); CallData callData; CallType callType = function.getCallData(callData); if (callType == CallTypeNone) return nil; ArgList argList; getListFromNSArray(exec, args, [self _rootObject], argList); if (![self _isSafeScript]) return nil; [self _rootObject]->globalObject()->globalData()->timeoutChecker.start(); JSValuePtr result = call(exec, function, callType, callData, [self _imp], argList); [self _rootObject]->globalObject()->globalData()->timeoutChecker.stop(); if (exec->hadException()) { addExceptionToConsole(exec); result = jsUndefined(); exec->clearException(); } // Convert and return the result of the function call. id resultObj = [WebScriptObject _convertValueToObjcValue:result originRootObject:[self _originRootObject] rootObject:[self _rootObject]]; _didExecute(self); return resultObj;}- (id)evaluateWebScript:(NSString *)script{ if (![self _isSafeScript]) return nil; ExecState* exec = [self _rootObject]->globalObject()->globalExec(); ASSERT(!exec->hadException());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -