X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/93a3786624b2768d89bfa27e46598dc64e2fb70a..ed1e77d3adeb83d26fd1dfb16dd84cabdcefd250:/API/JSValue.mm?ds=sidebyside diff --git a/API/JSValue.mm b/API/JSValue.mm index a380964..11be6b6 100644 --- a/API/JSValue.mm +++ b/API/JSValue.mm @@ -20,30 +20,39 @@ * 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. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #import "APICast.h" -#import "APIShims.h" #import "DateInstance.h" #import "Error.h" +#import "Exception.h" #import "JavaScriptCore.h" #import "JSContextInternal.h" #import "JSVirtualMachineInternal.h" #import "JSValueInternal.h" #import "JSWrapperMap.h" #import "ObjcRuntimeExtras.h" -#import "Operations.h" +#import "JSCInlines.h" #import "JSCJSValue.h" +#import "Strong.h" +#import "StrongInlines.h" #import #import +#import +#import #import -#import #import #import +#if ENABLE(REMOTE_INSPECTOR) +#import "CallFrame.h" +#import "JSGlobalObject.h" +#import "JSGlobalObjectInspectorController.h" +#endif + #if JSC_OBJC_API_ENABLED NSString * const JSPropertyDescriptorWritableKey = @"writable"; @@ -348,6 +357,16 @@ NSString * const JSPropertyDescriptorSetKey = @"set"; return JSValueIsObject([_context JSGlobalContextRef], m_value); } +- (BOOL)isArray +{ + return JSValueIsArray([_context JSGlobalContextRef], m_value); +} + +- (BOOL)isDate +{ + return JSValueIsDate([_context JSGlobalContextRef], m_value); +} + - (BOOL)isEqualToObject:(id)value { return JSValueIsStrictEqual([_context JSGlobalContextRef], m_value, objectToValue(_context, value)); @@ -554,14 +573,14 @@ NSString * const JSPropertyDescriptorSetKey = @"set"; inline bool isDate(JSObjectRef object, JSGlobalContextRef context) { - JSC::APIEntryShim entryShim(toJS(context)); - return toJS(object)->inherits(&JSC::DateInstance::s_info); + JSC::JSLockHolder locker(toJS(context)); + return toJS(object)->inherits(JSC::DateInstance::info()); } inline bool isArray(JSObjectRef object, JSGlobalContextRef context) { - JSC::APIEntryShim entryShim(toJS(context)); - return toJS(object)->inherits(&JSC::JSArray::s_info); + JSC::JSLockHolder locker(toJS(context)); + return toJS(object)->inherits(JSC::JSArray::info()); } @implementation JSValue(Internal) @@ -594,6 +613,7 @@ private: JSGlobalContextRef m_context; HashMap m_objectMap; Vector m_worklist; + Vector> m_jsValues; }; inline id JSContainerConvertor::convert(JSValueRef value) @@ -610,6 +630,8 @@ inline id JSContainerConvertor::convert(JSValueRef value) void JSContainerConvertor::add(Task task) { + JSC::ExecState* exec = toJS(m_context); + m_jsValues.append(JSC::Strong(exec->vm(), toJSForGC(exec, task.js))); m_objectMap.add(task.js, task.objc); if (task.type != ContainerNone) m_worklist.append(task); @@ -623,6 +645,15 @@ JSContainerConvertor::Task JSContainerConvertor::take() return last; } +#if ENABLE(REMOTE_INSPECTOR) +static void reportExceptionToInspector(JSGlobalContextRef context, JSC::JSValue exceptionValue) +{ + JSC::ExecState* exec = toJS(context); + JSC::Exception* exception = JSC::Exception::create(exec->vm(), exceptionValue); + exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exception); +} +#endif + static JSContainerConvertor::Task valueToObjectWithoutCopy(JSGlobalContextRef context, JSValueRef value) { if (!JSValueIsObject(context, value)) { @@ -655,7 +686,7 @@ static JSContainerConvertor::Task valueToObjectWithoutCopy(JSGlobalContextRef co return (JSContainerConvertor::Task){ object, wrapped, ContainerNone }; if (isDate(object, context)) - return (JSContainerConvertor::Task){ object, [NSDate dateWithTimeIntervalSince1970:JSValueToNumber(context, object, 0)], ContainerNone }; + return (JSContainerConvertor::Task){ object, [NSDate dateWithTimeIntervalSince1970:JSValueToNumber(context, object, 0) / 1000.0], ContainerNone }; if (isArray(object, context)) return (JSContainerConvertor::Task){ object, [NSMutableArray array], ContainerArray }; @@ -666,6 +697,7 @@ static JSContainerConvertor::Task valueToObjectWithoutCopy(JSGlobalContextRef co static id containerValueToObject(JSGlobalContextRef context, JSContainerConvertor::Task task) { ASSERT(task.type != ContainerNone); + JSC::JSLockHolder locker(toJS(context)); JSContainerConvertor convertor(context); convertor.add(task); ASSERT(!convertor.isWorkListEmpty()); @@ -691,6 +723,8 @@ static id containerValueToObject(JSGlobalContextRef context, JSContainerConverto ASSERT([current.objc isKindOfClass:[NSMutableDictionary class]]); NSMutableDictionary *dictionary = (NSMutableDictionary *)current.objc; + JSC::JSLockHolder locker(toJS(context)); + JSPropertyNameArrayRef propertyNameArray = JSObjectCopyPropertyNames(context, js); size_t length = JSPropertyNameArrayGetCount(propertyNameArray); @@ -745,9 +779,9 @@ id valueToString(JSGlobalContextRef context, JSValueRef value, JSValueRef* excep return nil; } - NSString *stringNS = [(NSString *)JSStringCopyCFString(kCFAllocatorDefault, jsstring) autorelease]; + RetainPtr stringCF = adoptCF(JSStringCopyCFString(kCFAllocatorDefault, jsstring)); JSStringRelease(jsstring); - return stringNS; + return (NSString *)stringCF.autorelease(); } id valueToDate(JSGlobalContextRef context, JSValueRef value, JSValueRef* exception) @@ -758,7 +792,7 @@ id valueToDate(JSGlobalContextRef context, JSValueRef value, JSValueRef* excepti return wrapped; } - double result = JSValueToNumber(context, value, exception); + double result = JSValueToNumber(context, value, exception) / 1000.0; return *exception ? nil : [NSDate dateWithTimeIntervalSince1970:result]; } @@ -773,8 +807,14 @@ id valueToArray(JSGlobalContextRef context, JSValueRef value, JSValueRef* except if (JSValueIsObject(context, value)) return containerValueToObject(context, (JSContainerConvertor::Task){ value, [NSMutableArray array], ContainerArray}); - if (!(JSValueIsNull(context, value) || JSValueIsUndefined(context, value))) - *exception = toRef(JSC::createTypeError(toJS(context), "Cannot convert primitive to NSArray")); + JSC::JSLockHolder locker(toJS(context)); + if (!(JSValueIsNull(context, value) || JSValueIsUndefined(context, value))) { + JSC::JSObject* exceptionObject = JSC::createTypeError(toJS(context), ASCIILiteral("Cannot convert primitive to NSArray")); + *exception = toRef(exceptionObject); +#if ENABLE(REMOTE_INSPECTOR) + reportExceptionToInspector(context, exceptionObject); +#endif + } return nil; } @@ -789,8 +829,14 @@ id valueToDictionary(JSGlobalContextRef context, JSValueRef value, JSValueRef* e if (JSValueIsObject(context, value)) return containerValueToObject(context, (JSContainerConvertor::Task){ value, [NSMutableDictionary dictionary], ContainerDictionary}); - if (!(JSValueIsNull(context, value) || JSValueIsUndefined(context, value))) - *exception = toRef(JSC::createTypeError(toJS(context), "Cannot convert primitive to NSDictionary")); + JSC::JSLockHolder locker(toJS(context)); + if (!(JSValueIsNull(context, value) || JSValueIsUndefined(context, value))) { + JSC::JSObject* exceptionObject = JSC::createTypeError(toJS(context), ASCIILiteral("Cannot convert primitive to NSDictionary")); + *exception = toRef(exceptionObject); +#if ENABLE(REMOTE_INSPECTOR) + reportExceptionToInspector(context, exceptionObject); +#endif + } return nil; } @@ -816,6 +862,7 @@ private: JSContext *m_context; HashMap m_objectMap; Vector m_worklist; + Vector> m_jsValues; }; JSValueRef ObjcContainerConvertor::convert(id object) @@ -833,6 +880,8 @@ JSValueRef ObjcContainerConvertor::convert(id object) void ObjcContainerConvertor::add(ObjcContainerConvertor::Task task) { + JSC::ExecState* exec = toJS(m_context.JSGlobalContextRef); + m_jsValues.append(JSC::Strong(exec->vm(), toJSForGC(exec, task.js))); m_objectMap.add(task.objc, task.js); if (task.type != ContainerNone) m_worklist.append(task); @@ -888,7 +937,7 @@ static ObjcContainerConvertor::Task objectToValueWithoutCopy(JSContext *context, } if ([object isKindOfClass:[NSDate class]]) { - JSValueRef argument = JSValueMakeNumber(contextRef, [object timeIntervalSince1970]); + JSValueRef argument = JSValueMakeNumber(contextRef, [object timeIntervalSince1970] * 1000.0); JSObjectRef result = JSObjectMakeDate(contextRef, 1, &argument, 0); return (ObjcContainerConvertor::Task){ object, result, ContainerNone }; } @@ -912,6 +961,7 @@ JSValueRef objectToValue(JSContext *context, id object) if (task.type == ContainerNone) return task.js; + JSC::JSLockHolder locker(toJS(contextRef)); ObjcContainerConvertor convertor(context); convertor.add(task); ASSERT(!convertor.isWorkListEmpty()); @@ -1064,7 +1114,7 @@ static StructHandlers* createStructHandlerMap() static StructTagHandler* handerForStructTag(const char* encodedType) { - static SpinLock handerForStructTagLock = SPINLOCK_INITIALIZER; + static StaticSpinLock handerForStructTagLock; SpinLockHolder lockHolder(&handerForStructTagLock); static StructHandlers* structHandlers = createStructHandlerMap();