X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/b37bf2e156556c589aea3e1f58a377f2b1189665..1981f5dfe8d77d97469d20652f712a09400c48ed:/API/JSValueRef.cpp diff --git a/API/JSValueRef.cpp b/API/JSValueRef.cpp index 468a2d1..9b7268a 100644 --- a/API/JSValueRef.cpp +++ b/API/JSValueRef.cpp @@ -1,4 +1,3 @@ -// -*- mode: c++; c-basic-offset: 4 -*- /* * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. * @@ -27,106 +26,129 @@ #include "config.h" #include "JSValueRef.h" -#include #include "APICast.h" +#include "APIShims.h" #include "JSCallbackObject.h" -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include #include // for std::min -JSType JSValueGetType(JSContextRef, JSValueRef value) +using namespace JSC; + +::JSType JSValueGetType(JSContextRef ctx, JSValueRef value) { - KJS::JSValue* jsValue = toJS(value); - switch (jsValue->type()) { - case KJS::UndefinedType: - return kJSTypeUndefined; - case KJS::NullType: - return kJSTypeNull; - case KJS::BooleanType: - return kJSTypeBoolean; - case KJS::NumberType: - return kJSTypeNumber; - case KJS::StringType: - return kJSTypeString; - case KJS::ObjectType: - return kJSTypeObject; - default: - ASSERT(!"JSValueGetType: unknown type code.\n"); - return kJSTypeUndefined; - } -} + ExecState* exec = toJS(ctx); + APIEntryShim entryShim(exec); -using namespace KJS; // placed here to avoid conflict between KJS::JSType and JSType, above. + JSValue jsValue = toJS(exec, value); -bool JSValueIsUndefined(JSContextRef, JSValueRef value) + if (jsValue.isUndefined()) + return kJSTypeUndefined; + if (jsValue.isNull()) + return kJSTypeNull; + if (jsValue.isBoolean()) + return kJSTypeBoolean; + if (jsValue.isNumber()) + return kJSTypeNumber; + if (jsValue.isString()) + return kJSTypeString; + ASSERT(jsValue.isObject()); + return kJSTypeObject; +} + +bool JSValueIsUndefined(JSContextRef ctx, JSValueRef value) { - JSValue* jsValue = toJS(value); - return jsValue->isUndefined(); + ExecState* exec = toJS(ctx); + APIEntryShim entryShim(exec); + + JSValue jsValue = toJS(exec, value); + return jsValue.isUndefined(); } -bool JSValueIsNull(JSContextRef, JSValueRef value) +bool JSValueIsNull(JSContextRef ctx, JSValueRef value) { - JSValue* jsValue = toJS(value); - return jsValue->isNull(); + ExecState* exec = toJS(ctx); + APIEntryShim entryShim(exec); + + JSValue jsValue = toJS(exec, value); + return jsValue.isNull(); } -bool JSValueIsBoolean(JSContextRef, JSValueRef value) +bool JSValueIsBoolean(JSContextRef ctx, JSValueRef value) { - JSValue* jsValue = toJS(value); - return jsValue->isBoolean(); + ExecState* exec = toJS(ctx); + APIEntryShim entryShim(exec); + + JSValue jsValue = toJS(exec, value); + return jsValue.isBoolean(); } -bool JSValueIsNumber(JSContextRef, JSValueRef value) +bool JSValueIsNumber(JSContextRef ctx, JSValueRef value) { - JSValue* jsValue = toJS(value); - return jsValue->isNumber(); + ExecState* exec = toJS(ctx); + APIEntryShim entryShim(exec); + + JSValue jsValue = toJS(exec, value); + return jsValue.isNumber(); } -bool JSValueIsString(JSContextRef, JSValueRef value) +bool JSValueIsString(JSContextRef ctx, JSValueRef value) { - JSValue* jsValue = toJS(value); - return jsValue->isString(); + ExecState* exec = toJS(ctx); + APIEntryShim entryShim(exec); + + JSValue jsValue = toJS(exec, value); + return jsValue.isString(); } -bool JSValueIsObject(JSContextRef, JSValueRef value) +bool JSValueIsObject(JSContextRef ctx, JSValueRef value) { - JSValue* jsValue = toJS(value); - return jsValue->isObject(); + ExecState* exec = toJS(ctx); + APIEntryShim entryShim(exec); + + JSValue jsValue = toJS(exec, value); + return jsValue.isObject(); } -bool JSValueIsObjectOfClass(JSContextRef, JSValueRef value, JSClassRef jsClass) +bool JSValueIsObjectOfClass(JSContextRef ctx, JSValueRef value, JSClassRef jsClass) { - JSValue* jsValue = toJS(value); + ExecState* exec = toJS(ctx); + APIEntryShim entryShim(exec); + + JSValue jsValue = toJS(exec, value); - if (JSObject* o = jsValue->getObject()) { - if (o->inherits(&JSCallbackObject::info)) - return static_cast*>(o)->inherits(jsClass); - else if (o->inherits(&JSCallbackObject::info)) - return static_cast*>(o)->inherits(jsClass); + if (JSObject* o = jsValue.getObject()) { + if (o->inherits(&JSCallbackObject::s_info)) + return jsCast*>(o)->inherits(jsClass); + if (o->inherits(&JSCallbackObject::s_info)) + return jsCast*>(o)->inherits(jsClass); } return false; } bool JSValueIsEqual(JSContextRef ctx, JSValueRef a, JSValueRef b, JSValueRef* exception) { - JSLock lock; ExecState* exec = toJS(ctx); - JSValue* jsA = toJS(a); - JSValue* jsB = toJS(b); + APIEntryShim entryShim(exec); + + JSValue jsA = toJS(exec, a); + JSValue jsB = toJS(exec, b); - bool result = equal(exec, jsA, jsB); // false if an exception is thrown + bool result = JSValue::equal(exec, jsA, jsB); // false if an exception is thrown if (exec->hadException()) { if (exception) - *exception = toRef(exec->exception()); + *exception = toRef(exec, exec->exception()); exec->clearException(); } return result; @@ -134,126 +156,184 @@ bool JSValueIsEqual(JSContextRef ctx, JSValueRef a, JSValueRef b, JSValueRef* ex bool JSValueIsStrictEqual(JSContextRef ctx, JSValueRef a, JSValueRef b) { - JSLock lock; ExecState* exec = toJS(ctx); - JSValue* jsA = toJS(a); - JSValue* jsB = toJS(b); - - bool result = strictEqual(exec, jsA, jsB); // can't throw because it doesn't perform value conversion - ASSERT(!exec->hadException()); - return result; + APIEntryShim entryShim(exec); + + JSValue jsA = toJS(exec, a); + JSValue jsB = toJS(exec, b); + + return JSValue::strictEqual(exec, jsA, jsB); } bool JSValueIsInstanceOfConstructor(JSContextRef ctx, JSValueRef value, JSObjectRef constructor, JSValueRef* exception) { - JSLock lock; ExecState* exec = toJS(ctx); - JSValue* jsValue = toJS(value); + APIEntryShim entryShim(exec); + + JSValue jsValue = toJS(exec, value); + JSObject* jsConstructor = toJS(constructor); - if (!jsConstructor->implementsHasInstance()) + if (!jsConstructor->structure()->typeInfo().implementsHasInstance()) return false; - bool result = jsConstructor->hasInstance(exec, jsValue); // false if an exception is thrown + bool result = jsConstructor->methodTable()->hasInstance(jsConstructor, exec, jsValue, jsConstructor->get(exec, exec->propertyNames().prototype)); // false if an exception is thrown if (exec->hadException()) { if (exception) - *exception = toRef(exec->exception()); + *exception = toRef(exec, exec->exception()); exec->clearException(); } return result; } -JSValueRef JSValueMakeUndefined(JSContextRef) +JSValueRef JSValueMakeUndefined(JSContextRef ctx) { - return toRef(jsUndefined()); + ExecState* exec = toJS(ctx); + APIEntryShim entryShim(exec); + + return toRef(exec, jsUndefined()); } -JSValueRef JSValueMakeNull(JSContextRef) +JSValueRef JSValueMakeNull(JSContextRef ctx) { - return toRef(jsNull()); + ExecState* exec = toJS(ctx); + APIEntryShim entryShim(exec); + + return toRef(exec, jsNull()); } -JSValueRef JSValueMakeBoolean(JSContextRef, bool value) +JSValueRef JSValueMakeBoolean(JSContextRef ctx, bool value) { - return toRef(jsBoolean(value)); + ExecState* exec = toJS(ctx); + APIEntryShim entryShim(exec); + + return toRef(exec, jsBoolean(value)); } -JSValueRef JSValueMakeNumber(JSContextRef, double value) +JSValueRef JSValueMakeNumber(JSContextRef ctx, double value) { - JSLock lock; - return toRef(jsNumber(value)); + 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 = std::numeric_limits::quiet_NaN(); + + return toRef(exec, jsNumber(value)); } -JSValueRef JSValueMakeString(JSContextRef, JSStringRef string) +JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string) { - JSLock lock; - UString::Rep* rep = toJS(string); - return toRef(jsString(UString(rep))); + ExecState* exec = toJS(ctx); + APIEntryShim entryShim(exec); + + return toRef(exec, jsString(exec, string->ustring())); +} + +JSValueRef JSValueMakeFromJSONString(JSContextRef ctx, JSStringRef string) +{ + ExecState* exec = toJS(ctx); + APIEntryShim entryShim(exec); + UString str = string->ustring(); + if (str.is8Bit()) { + LiteralParser parser(exec, str.characters8(), str.length(), StrictJSON); + return toRef(exec, parser.tryLiteralParse()); + } + LiteralParser parser(exec, str.characters16(), str.length(), StrictJSON); + return toRef(exec, parser.tryLiteralParse()); +} + +JSStringRef JSValueCreateJSONString(JSContextRef ctx, JSValueRef apiValue, unsigned indent, JSValueRef* exception) +{ + ExecState* exec = toJS(ctx); + APIEntryShim entryShim(exec); + JSValue value = toJS(exec, apiValue); + UString result = JSONStringify(exec, value, indent); + if (exception) + *exception = 0; + if (exec->hadException()) { + if (exception) + *exception = toRef(exec, exec->exception()); + exec->clearException(); + return 0; + } + return OpaqueJSString::create(result).leakRef(); } bool JSValueToBoolean(JSContextRef ctx, JSValueRef value) { ExecState* exec = toJS(ctx); - JSValue* jsValue = toJS(value); - return jsValue->toBoolean(exec); + APIEntryShim entryShim(exec); + + JSValue jsValue = toJS(exec, value); + return jsValue.toBoolean(exec); } double JSValueToNumber(JSContextRef ctx, JSValueRef value, JSValueRef* exception) { - JSLock lock; - JSValue* jsValue = toJS(value); ExecState* exec = toJS(ctx); + APIEntryShim entryShim(exec); - double number = jsValue->toNumber(exec); + JSValue jsValue = toJS(exec, value); + + double number = jsValue.toNumber(exec); if (exec->hadException()) { if (exception) - *exception = toRef(exec->exception()); + *exception = toRef(exec, exec->exception()); exec->clearException(); - number = NaN; + number = std::numeric_limits::quiet_NaN(); } return number; } JSStringRef JSValueToStringCopy(JSContextRef ctx, JSValueRef value, JSValueRef* exception) { - JSLock lock; - JSValue* jsValue = toJS(value); ExecState* exec = toJS(ctx); + APIEntryShim entryShim(exec); + + JSValue jsValue = toJS(exec, value); - JSStringRef stringRef = toRef(jsValue->toString(exec).rep()->ref()); + RefPtr stringRef(OpaqueJSString::create(jsValue.toString(exec)->value(exec))); if (exec->hadException()) { if (exception) - *exception = toRef(exec->exception()); + *exception = toRef(exec, exec->exception()); exec->clearException(); - stringRef = 0; + stringRef.clear(); } - return stringRef; + return stringRef.release().leakRef(); } JSObjectRef JSValueToObject(JSContextRef ctx, JSValueRef value, JSValueRef* exception) { - JSLock lock; ExecState* exec = toJS(ctx); - JSValue* jsValue = toJS(value); + APIEntryShim entryShim(exec); + + JSValue jsValue = toJS(exec, value); - JSObjectRef objectRef = toRef(jsValue->toObject(exec)); + JSObjectRef objectRef = toRef(jsValue.toObject(exec)); if (exec->hadException()) { if (exception) - *exception = toRef(exec->exception()); + *exception = toRef(exec, exec->exception()); exec->clearException(); objectRef = 0; } return objectRef; } -void JSValueProtect(JSContextRef, JSValueRef value) +void JSValueProtect(JSContextRef ctx, JSValueRef value) { - JSLock lock; - JSValue* jsValue = toJS(value); + ExecState* exec = toJS(ctx); + APIEntryShim entryShim(exec); + + JSValue jsValue = toJSForGC(exec, value); gcProtect(jsValue); } -void JSValueUnprotect(JSContextRef, JSValueRef value) +void JSValueUnprotect(JSContextRef ctx, JSValueRef value) { - JSLock lock; - JSValue* jsValue = toJS(value); + ExecState* exec = toJS(ctx); + APIEntryShim entryShim(exec); + + JSValue jsValue = toJSForGC(exec, value); gcUnprotect(jsValue); }