#include "APICast.h"
#include "APIShims.h"
+#include "JSAPIWrapperObject.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 <runtime/UString.h>
-#include <runtime/JSValue.h>
#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
+
using namespace JSC;
+#if PLATFORM(MAC)
+static bool evernoteHackNeeded()
+{
+ static const int32_t webkitLastVersionWithEvernoteHack = 35133959;
+ static bool hackNeeded = CFEqual(CFBundleGetIdentifier(CFBundleGetMainBundle()), CFSTR("com.evernote.Evernote"))
+ && NSVersionOfLinkTimeLibrary("JavaScriptCore") <= webkitLastVersionWithEvernoteHack;
+
+ return hackNeeded;
+}
+#endif
+
::JSType JSValueGetType(JSContextRef ctx, JSValueRef value)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return kJSTypeUndefined;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
bool JSValueIsUndefined(JSContextRef ctx, JSValueRef value)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
bool JSValueIsNull(JSContextRef ctx, JSValueRef value)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
bool JSValueIsBoolean(JSContextRef ctx, JSValueRef value)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
bool JSValueIsNumber(JSContextRef ctx, JSValueRef value)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
bool JSValueIsString(JSContextRef ctx, JSValueRef value)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
bool JSValueIsObject(JSContextRef ctx, JSValueRef value)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
bool JSValueIsObjectOfClass(JSContextRef ctx, JSValueRef value, JSClassRef jsClass)
{
+ if (!ctx || !jsClass) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
if (JSObject* o = jsValue.getObject()) {
if (o->inherits(&JSCallbackObject<JSGlobalObject>::s_info))
- return static_cast<JSCallbackObject<JSGlobalObject>*>(o)->inherits(jsClass);
- if (o->inherits(&JSCallbackObject<JSObjectWithGlobalObject>::s_info))
- return static_cast<JSCallbackObject<JSObjectWithGlobalObject>*>(o)->inherits(jsClass);
+ return jsCast<JSCallbackObject<JSGlobalObject>*>(o)->inherits(jsClass);
+ if (o->inherits(&JSCallbackObject<JSDestructibleObject>::s_info))
+ return jsCast<JSCallbackObject<JSDestructibleObject>*>(o)->inherits(jsClass);
+#if JSC_OBJC_API_ENABLED
+ if (o->inherits(&JSCallbackObject<JSAPIWrapperObject>::s_info))
+ return jsCast<JSCallbackObject<JSAPIWrapperObject>*>(o)->inherits(jsClass);
+#endif
}
return false;
}
bool JSValueIsEqual(JSContextRef ctx, JSValueRef a, JSValueRef b, JSValueRef* exception)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
bool JSValueIsStrictEqual(JSContextRef ctx, JSValueRef a, JSValueRef b)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
bool JSValueIsInstanceOfConstructor(JSContextRef ctx, JSValueRef value, JSObjectRef constructor, JSValueRef* exception)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
JSObject* jsConstructor = toJS(constructor);
if (!jsConstructor->structure()->typeInfo().implementsHasInstance())
return false;
- bool result = jsConstructor->hasInstance(exec, jsValue, jsConstructor->get(exec, exec->propertyNames().prototype)); // false if an exception is thrown
+ bool result = jsConstructor->hasInstance(exec, jsValue); // false if an exception is thrown
if (exec->hadException()) {
if (exception)
*exception = toRef(exec, exec->exception());
JSValueRef JSValueMakeUndefined(JSContextRef ctx)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
JSValueRef JSValueMakeNull(JSContextRef ctx)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
JSValueRef JSValueMakeBoolean(JSContextRef ctx, bool value)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
JSValueRef JSValueMakeNumber(JSContextRef ctx, double value)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(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 (isnan(value))
- value = NaN;
+ if (std::isnan(value))
+ value = QNaN;
return toRef(exec, jsNumber(value));
}
JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
- return toRef(exec, jsString(exec, string->ustring()));
+ return toRef(exec, jsString(exec, string->string()));
}
JSValueRef JSValueMakeFromJSONString(JSContextRef ctx, JSStringRef string)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
- UString str = string->ustring();
- LiteralParser parser(exec, str.characters(), str.length(), LiteralParser::StrictJSON);
+ String str = string->string();
+ unsigned length = str.length();
+ 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);
return toRef(exec, parser.tryLiteralParse());
}
JSStringRef JSValueCreateJSONString(JSContextRef ctx, JSValueRef apiValue, unsigned indent, JSValueRef* exception)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
JSValue value = toJS(exec, apiValue);
- UString result = JSONStringify(exec, value, indent);
+ String result = JSONStringify(exec, value, indent);
if (exception)
*exception = 0;
if (exec->hadException()) {
bool JSValueToBoolean(JSContextRef ctx, JSValueRef value)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
double JSValueToNumber(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return QNaN;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
if (exception)
*exception = toRef(exec, exec->exception());
exec->clearException();
- number = NaN;
+ number = QNaN;
}
return number;
}
JSStringRef JSValueToStringCopy(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
JSValue jsValue = toJS(exec, value);
- RefPtr<OpaqueJSString> stringRef(OpaqueJSString::create(jsValue.toString(exec)));
+ RefPtr<OpaqueJSString> stringRef(OpaqueJSString::create(jsValue.toString(exec)->value(exec)));
if (exec->hadException()) {
if (exception)
*exception = toRef(exec, exec->exception());
JSObjectRef JSValueToObject(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
void JSValueProtect(JSContextRef ctx, JSValueRef value)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
void JSValueUnprotect(JSContextRef ctx, JSValueRef value)
{
+#if PLATFORM(MAC)
+ if ((!value || !ctx) && evernoteHackNeeded())
+ return;
+#endif
+
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);