diff options
author | Konstantin Tokarev <annulen@yandex.ru> | 2016-08-25 19:20:41 +0300 |
---|---|---|
committer | Konstantin Tokarev <annulen@yandex.ru> | 2017-02-02 12:30:55 +0000 |
commit | 6882a04fb36642862b11efe514251d32070c3d65 (patch) | |
tree | b7959826000b061fd5ccc7512035c7478742f7b0 /Source/JavaScriptCore/API/JSValueRef.cpp | |
parent | ab6df191029eeeb0b0f16f127d553265659f739e (diff) | |
download | qtwebkit-6882a04fb36642862b11efe514251d32070c3d65.tar.gz |
Imported QtWebKit TP3 (git b57bc6801f1876c3220d5a4bfea33d620d477443)
Change-Id: I3b1d8a2808782c9f34d50240000e20cb38d3680f
Reviewed-by: Konstantin Tokarev <annulen@yandex.ru>
Diffstat (limited to 'Source/JavaScriptCore/API/JSValueRef.cpp')
-rw-r--r-- | Source/JavaScriptCore/API/JSValueRef.cpp | 210 |
1 files changed, 112 insertions, 98 deletions
diff --git a/Source/JavaScriptCore/API/JSValueRef.cpp b/Source/JavaScriptCore/API/JSValueRef.cpp index 81a2db7b7..54405e2af 100644 --- a/Source/JavaScriptCore/API/JSValueRef.cpp +++ b/Source/JavaScriptCore/API/JSValueRef.cpp @@ -10,47 +10,69 @@ * 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 + * THIS SOFTWARE IS PROVIDED BY APPLE 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 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include "JSValueRef.h" #include "APICast.h" -#include "APIShims.h" +#include "DateInstance.h" +#include "Exception.h" #include "JSAPIWrapperObject.h" +#include "JSCInlines.h" +#include "JSCJSValue.h" #include "JSCallbackObject.h" - -#include <runtime/JSCJSValue.h> -#include <runtime/JSGlobalObject.h> -#include <runtime/JSONObject.h> -#include <runtime/JSString.h> -#include <runtime/LiteralParser.h> -#include <runtime/Operations.h> -#include <runtime/Protect.h> - +#include "JSGlobalObject.h" +#include "JSONObject.h" +#include "JSString.h" +#include "LiteralParser.h" +#include "Protect.h" +#include <algorithm> #include <wtf/Assertions.h> #include <wtf/text/StringHash.h> #include <wtf/text/WTFString.h> -#include <algorithm> // for std::min - #if PLATFORM(MAC) #include <mach-o/dyld.h> #endif +#if ENABLE(REMOTE_INSPECTOR) +#include "JSGlobalObjectInspectorController.h" +#endif + using namespace JSC; +enum class ExceptionStatus { + DidThrow, + DidNotThrow +}; + +static ExceptionStatus handleExceptionIfNeeded(ExecState* exec, JSValueRef* returnedExceptionRef) +{ + if (exec->hadException()) { + Exception* exception = exec->exception(); + if (returnedExceptionRef) + *returnedExceptionRef = toRef(exec, exception->value()); + exec->clearException(); +#if ENABLE(REMOTE_INSPECTOR) + exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exception); +#endif + return ExceptionStatus::DidThrow; + } + return ExceptionStatus::DidNotThrow; +} + #if PLATFORM(MAC) static bool evernoteHackNeeded() { @@ -69,7 +91,7 @@ static bool evernoteHackNeeded() return kJSTypeUndefined; } ExecState* exec = toJS(ctx); - APIEntryShim entryShim(exec); + JSLockHolder locker(exec); JSValue jsValue = toJS(exec, value); @@ -94,10 +116,9 @@ bool JSValueIsUndefined(JSContextRef ctx, JSValueRef value) return false; } ExecState* exec = toJS(ctx); - APIEntryShim entryShim(exec); + JSLockHolder locker(exec); - JSValue jsValue = toJS(exec, value); - return jsValue.isUndefined(); + return toJS(exec, value).isUndefined(); } bool JSValueIsNull(JSContextRef ctx, JSValueRef value) @@ -107,10 +128,9 @@ bool JSValueIsNull(JSContextRef ctx, JSValueRef value) return false; } ExecState* exec = toJS(ctx); - APIEntryShim entryShim(exec); + JSLockHolder locker(exec); - JSValue jsValue = toJS(exec, value); - return jsValue.isNull(); + return toJS(exec, value).isNull(); } bool JSValueIsBoolean(JSContextRef ctx, JSValueRef value) @@ -120,10 +140,9 @@ bool JSValueIsBoolean(JSContextRef ctx, JSValueRef value) return false; } ExecState* exec = toJS(ctx); - APIEntryShim entryShim(exec); + JSLockHolder locker(exec); - JSValue jsValue = toJS(exec, value); - return jsValue.isBoolean(); + return toJS(exec, value).isBoolean(); } bool JSValueIsNumber(JSContextRef ctx, JSValueRef value) @@ -133,10 +152,9 @@ bool JSValueIsNumber(JSContextRef ctx, JSValueRef value) return false; } ExecState* exec = toJS(ctx); - APIEntryShim entryShim(exec); + JSLockHolder locker(exec); - JSValue jsValue = toJS(exec, value); - return jsValue.isNumber(); + return toJS(exec, value).isNumber(); } bool JSValueIsString(JSContextRef ctx, JSValueRef value) @@ -146,10 +164,9 @@ bool JSValueIsString(JSContextRef ctx, JSValueRef value) return false; } ExecState* exec = toJS(ctx); - APIEntryShim entryShim(exec); + JSLockHolder locker(exec); - JSValue jsValue = toJS(exec, value); - return jsValue.isString(); + return toJS(exec, value).isString(); } bool JSValueIsObject(JSContextRef ctx, JSValueRef value) @@ -159,10 +176,33 @@ bool JSValueIsObject(JSContextRef ctx, JSValueRef value) return false; } ExecState* exec = toJS(ctx); - APIEntryShim entryShim(exec); + JSLockHolder locker(exec); - JSValue jsValue = toJS(exec, value); - return jsValue.isObject(); + return toJS(exec, value).isObject(); +} + +bool JSValueIsArray(JSContextRef ctx, JSValueRef value) +{ + if (!ctx) { + ASSERT_NOT_REACHED(); + return false; + } + ExecState* exec = toJS(ctx); + JSLockHolder locker(exec); + + return toJS(exec, value).inherits(JSArray::info()); +} + +bool JSValueIsDate(JSContextRef ctx, JSValueRef value) +{ + if (!ctx) { + ASSERT_NOT_REACHED(); + return false; + } + ExecState* exec = toJS(ctx); + JSLockHolder locker(exec); + + return toJS(exec, value).inherits(DateInstance::info()); } bool JSValueIsObjectOfClass(JSContextRef ctx, JSValueRef value, JSClassRef jsClass) @@ -172,17 +212,20 @@ bool JSValueIsObjectOfClass(JSContextRef ctx, JSValueRef value, JSClassRef jsCla return false; } ExecState* exec = toJS(ctx); - APIEntryShim entryShim(exec); + JSLockHolder locker(exec); JSValue jsValue = toJS(exec, value); if (JSObject* o = jsValue.getObject()) { - if (o->inherits(&JSCallbackObject<JSGlobalObject>::s_info)) + if (o->inherits(JSProxy::info())) + o = jsCast<JSProxy*>(o)->target(); + + if (o->inherits(JSCallbackObject<JSGlobalObject>::info())) return jsCast<JSCallbackObject<JSGlobalObject>*>(o)->inherits(jsClass); - if (o->inherits(&JSCallbackObject<JSDestructibleObject>::s_info)) + if (o->inherits(JSCallbackObject<JSDestructibleObject>::info())) return jsCast<JSCallbackObject<JSDestructibleObject>*>(o)->inherits(jsClass); #if JSC_OBJC_API_ENABLED - if (o->inherits(&JSCallbackObject<JSAPIWrapperObject>::s_info)) + if (o->inherits(JSCallbackObject<JSAPIWrapperObject>::info())) return jsCast<JSCallbackObject<JSAPIWrapperObject>*>(o)->inherits(jsClass); #endif } @@ -196,17 +239,14 @@ bool JSValueIsEqual(JSContextRef ctx, JSValueRef a, JSValueRef b, JSValueRef* ex return false; } ExecState* exec = toJS(ctx); - APIEntryShim entryShim(exec); + JSLockHolder locker(exec); JSValue jsA = toJS(exec, a); JSValue jsB = toJS(exec, b); bool result = JSValue::equal(exec, jsA, jsB); // false if an exception is thrown - if (exec->hadException()) { - if (exception) - *exception = toRef(exec, exec->exception()); - exec->clearException(); - } + handleExceptionIfNeeded(exec, exception); + return result; } @@ -217,7 +257,7 @@ bool JSValueIsStrictEqual(JSContextRef ctx, JSValueRef a, JSValueRef b) return false; } ExecState* exec = toJS(ctx); - APIEntryShim entryShim(exec); + JSLockHolder locker(exec); JSValue jsA = toJS(exec, a); JSValue jsB = toJS(exec, b); @@ -232,7 +272,7 @@ bool JSValueIsInstanceOfConstructor(JSContextRef ctx, JSValueRef value, JSObject return false; } ExecState* exec = toJS(ctx); - APIEntryShim entryShim(exec); + JSLockHolder locker(exec); JSValue jsValue = toJS(exec, value); @@ -240,11 +280,7 @@ bool JSValueIsInstanceOfConstructor(JSContextRef ctx, JSValueRef value, JSObject if (!jsConstructor->structure()->typeInfo().implementsHasInstance()) return false; bool result = jsConstructor->hasInstance(exec, jsValue); // false if an exception is thrown - if (exec->hadException()) { - if (exception) - *exception = toRef(exec, exec->exception()); - exec->clearException(); - } + handleExceptionIfNeeded(exec, exception); return result; } @@ -255,7 +291,7 @@ JSValueRef JSValueMakeUndefined(JSContextRef ctx) return 0; } ExecState* exec = toJS(ctx); - APIEntryShim entryShim(exec); + JSLockHolder locker(exec); return toRef(exec, jsUndefined()); } @@ -267,7 +303,7 @@ JSValueRef JSValueMakeNull(JSContextRef ctx) return 0; } ExecState* exec = toJS(ctx); - APIEntryShim entryShim(exec); + JSLockHolder locker(exec); return toRef(exec, jsNull()); } @@ -279,7 +315,7 @@ JSValueRef JSValueMakeBoolean(JSContextRef ctx, bool value) return 0; } ExecState* exec = toJS(ctx); - APIEntryShim entryShim(exec); + JSLockHolder locker(exec); return toRef(exec, jsBoolean(value)); } @@ -291,15 +327,9 @@ JSValueRef JSValueMakeNumber(JSContextRef ctx, double value) return 0; } ExecState* exec = toJS(ctx); - APIEntryShim entryShim(exec); + JSLockHolder locker(exec); - // Our JSValue representation relies on a standard bit pattern for NaN. NaNs - // generated internally to JavaScriptCore naturally have that representation, - // but an external NaN might not. - if (std::isnan(value)) - value = QNaN; - - return toRef(exec, jsNumber(value)); + return toRef(exec, jsNumber(purifyNaN(value))); } JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string) @@ -309,9 +339,9 @@ JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string) return 0; } ExecState* exec = toJS(ctx); - APIEntryShim entryShim(exec); + JSLockHolder locker(exec); - return toRef(exec, jsString(exec, string->string())); + return toRef(exec, jsString(exec, string ? string->string() : String())); } JSValueRef JSValueMakeFromJSONString(JSContextRef ctx, JSStringRef string) @@ -321,14 +351,14 @@ JSValueRef JSValueMakeFromJSONString(JSContextRef ctx, JSStringRef string) return 0; } ExecState* exec = toJS(ctx); - APIEntryShim entryShim(exec); + JSLockHolder locker(exec); String str = string->string(); unsigned length = str.length(); - if (length && str.is8Bit()) { + if (!length || str.is8Bit()) { LiteralParser<LChar> parser(exec, str.characters8(), length, StrictJSON); return toRef(exec, parser.tryLiteralParse()); } - LiteralParser<UChar> parser(exec, str.characters(), length, StrictJSON); + LiteralParser<UChar> parser(exec, str.characters16(), length, StrictJSON); return toRef(exec, parser.tryLiteralParse()); } @@ -339,17 +369,13 @@ JSStringRef JSValueCreateJSONString(JSContextRef ctx, JSValueRef apiValue, unsig return 0; } ExecState* exec = toJS(ctx); - APIEntryShim entryShim(exec); + JSLockHolder locker(exec); JSValue value = toJS(exec, apiValue); String result = JSONStringify(exec, value, indent); if (exception) *exception = 0; - if (exec->hadException()) { - if (exception) - *exception = toRef(exec, exec->exception()); - exec->clearException(); + if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow) return 0; - } return OpaqueJSString::create(result).leakRef(); } @@ -360,7 +386,7 @@ bool JSValueToBoolean(JSContextRef ctx, JSValueRef value) return false; } ExecState* exec = toJS(ctx); - APIEntryShim entryShim(exec); + JSLockHolder locker(exec); JSValue jsValue = toJS(exec, value); return jsValue.toBoolean(exec); @@ -370,20 +396,16 @@ double JSValueToNumber(JSContextRef ctx, JSValueRef value, JSValueRef* exception { if (!ctx) { ASSERT_NOT_REACHED(); - return QNaN; + return PNaN; } ExecState* exec = toJS(ctx); - APIEntryShim entryShim(exec); + JSLockHolder locker(exec); JSValue jsValue = toJS(exec, value); double number = jsValue.toNumber(exec); - if (exec->hadException()) { - if (exception) - *exception = toRef(exec, exec->exception()); - exec->clearException(); - number = QNaN; - } + if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow) + number = PNaN; return number; } @@ -394,17 +416,13 @@ JSStringRef JSValueToStringCopy(JSContextRef ctx, JSValueRef value, JSValueRef* return 0; } ExecState* exec = toJS(ctx); - APIEntryShim entryShim(exec); + JSLockHolder locker(exec); JSValue jsValue = toJS(exec, value); RefPtr<OpaqueJSString> stringRef(OpaqueJSString::create(jsValue.toString(exec)->value(exec))); - if (exec->hadException()) { - if (exception) - *exception = toRef(exec, exec->exception()); - exec->clearException(); - stringRef.clear(); - } + if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow) + stringRef = nullptr; return stringRef.release().leakRef(); } @@ -415,19 +433,15 @@ JSObjectRef JSValueToObject(JSContextRef ctx, JSValueRef value, JSValueRef* exce return 0; } ExecState* exec = toJS(ctx); - APIEntryShim entryShim(exec); + JSLockHolder locker(exec); JSValue jsValue = toJS(exec, value); JSObjectRef objectRef = toRef(jsValue.toObject(exec)); - if (exec->hadException()) { - if (exception) - *exception = toRef(exec, exec->exception()); - exec->clearException(); + if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow) objectRef = 0; - } return objectRef; -} +} void JSValueProtect(JSContextRef ctx, JSValueRef value) { @@ -436,7 +450,7 @@ void JSValueProtect(JSContextRef ctx, JSValueRef value) return; } ExecState* exec = toJS(ctx); - APIEntryShim entryShim(exec); + JSLockHolder locker(exec); JSValue jsValue = toJSForGC(exec, value); gcProtect(jsValue); @@ -450,7 +464,7 @@ void JSValueUnprotect(JSContextRef ctx, JSValueRef value) #endif ExecState* exec = toJS(ctx); - APIEntryShim entryShim(exec); + JSLockHolder locker(exec); JSValue jsValue = toJSForGC(exec, value); gcUnprotect(jsValue); |