Title: [234227] trunk/Source/_javascript_Core
Revision
234227
Author
keith_mil...@apple.com
Date
2018-07-25 19:32:25 -0700 (Wed, 25 Jul 2018)

Log Message

[JSC API] We should support the symbol type in our C/Obj-C API
https://bugs.webkit.org/show_bug.cgi?id=175836

Reviewed by Filip Pizlo.

This patch makes the following API additions:
1) Test if a JSValue/JSValueRef is a symbol via any of the methods API are able to test for the types of other JSValues.
2) Create a symbol on both APIs.
3) Get/Set/Delete/Define property now take ids in the Obj-C API.
4) Add Get/Set/Delete in the C API.

We can do 3 because it is both binary and source compatable with
the existing API. I added (4) because the current property access
APIs only have the ability to get Strings. It was possible to
merge symbols into JSStringRef but that felt confusing and exposes
implementation details of our engine. The new functions match the
same meaning that they have in JS, thus should be forward
compatible with any future language extensions.

Lastly, this patch adds the same availability preproccessing phase
in WebCore to _javascript_Core, which enables TBA features for
testing on previous releases.

* API/APICast.h:
* API/JSBasePrivate.h:
* API/JSContext.h:
* API/JSContextPrivate.h:
* API/JSContextRef.h:
* API/JSContextRefInternal.h:
* API/JSContextRefPrivate.h:
* API/JSManagedValue.h:
* API/JSObjectRef.cpp:
(JSObjectHasPropertyKey):
(JSObjectGetPropertyKey):
(JSObjectSetPropertyKey):
(JSObjectDeletePropertyKey):
* API/JSObjectRef.h:
* API/JSRemoteInspector.h:
* API/JSTypedArray.h:
* API/JSValue.h:
* API/JSValue.mm:
(+[JSValue valueWithNewSymbolFromDescription:inContext:]):
(performPropertyOperation):
(-[JSValue valueForProperty:valueForProperty:]):
(-[JSValue setValue:forProperty:setValue:forProperty:]):
(-[JSValue deleteProperty:deleteProperty:]):
(-[JSValue hasProperty:hasProperty:]):
(-[JSValue defineProperty:descriptor:defineProperty:descriptor:]):
(-[JSValue isSymbol]):
(-[JSValue objectForKeyedSubscript:]):
(-[JSValue setObject:forKeyedSubscript:]):
(-[JSValue valueForProperty:]): Deleted.
(-[JSValue setValue:forProperty:]): Deleted.
(-[JSValue deleteProperty:]): Deleted.
(-[JSValue hasProperty:]): Deleted.
(-[JSValue defineProperty:descriptor:]): Deleted.
* API/JSValueRef.cpp:
(JSValueGetType):
(JSValueIsSymbol):
(JSValueMakeSymbol):
* API/JSValueRef.h:
* API/WebKitAvailability.h:
* API/tests/CurrentThisInsideBlockGetterTest.mm:
* API/tests/CustomGlobalObjectClassTest.c:
* API/tests/DateTests.mm:
* API/tests/JSExportTests.mm:
* API/tests/JSNode.c:
* API/tests/JSNodeList.c:
* API/tests/Node.c:
* API/tests/NodeList.c:
* API/tests/minidom.c:
* API/tests/testapi.c:
(main):
* API/tests/testapi.cpp: Added.
(APIString::APIString):
(APIString::~APIString):
(APIString::operator JSStringRef):
(APIContext::APIContext):
(APIContext::~APIContext):
(APIContext::operator JSGlobalContextRef):
(APIVector::APIVector):
(APIVector::~APIVector):
(APIVector::append):
(testCAPIViaCpp):
(TestAPI::evaluateScript):
(TestAPI::callFunction):
(TestAPI::functionReturnsTrue):
(TestAPI::check):
(TestAPI::checkJSAndAPIMatch):
(TestAPI::interestingObjects):
(TestAPI::interestingKeys):
(TestAPI::run):
* API/tests/testapi.mm:
(testObjectiveCAPIMain):
* _javascript_Core.xcodeproj/project.pbxproj:
* config.h:
* postprocess-headers.sh:
* shell/CMakeLists.txt:
* testmem/testmem.mm:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/API/APICast.h (234226 => 234227)


--- trunk/Source/_javascript_Core/API/APICast.h	2018-07-26 01:29:11 UTC (rev 234226)
+++ trunk/Source/_javascript_Core/API/APICast.h	2018-07-26 02:32:25 UTC (rev 234227)
@@ -30,6 +30,7 @@
 #include "JSCJSValue.h"
 #include "JSCJSValueInlines.h"
 #include "JSGlobalObject.h"
+#include "HeapCellInlines.h"
 
 namespace JSC {
     class ExecState;

Modified: trunk/Source/_javascript_Core/API/JSBasePrivate.h (234226 => 234227)


--- trunk/Source/_javascript_Core/API/JSBasePrivate.h	2018-07-26 01:29:11 UTC (rev 234226)
+++ trunk/Source/_javascript_Core/API/JSBasePrivate.h	2018-07-26 02:32:25 UTC (rev 234227)
@@ -43,7 +43,7 @@
 garbage collector to collect soon, hoping to reclaim that large non-GC memory
 region.
 */
-JS_EXPORT void JSReportExtraMemoryCost(JSContextRef ctx, size_t size) CF_AVAILABLE(10_6, 7_0);
+JS_EXPORT void JSReportExtraMemoryCost(JSContextRef ctx, size_t size) JSC_API_AVAILABLE(macosx(10.6), ios(7.0));
 
 JS_EXPORT void JSDisableGCTimer(void);
 

Modified: trunk/Source/_javascript_Core/API/JSContext.h (234226 => 234227)


--- trunk/Source/_javascript_Core/API/JSContext.h	2018-07-26 01:29:11 UTC (rev 234226)
+++ trunk/Source/_javascript_Core/API/JSContext.h	2018-07-26 02:32:25 UTC (rev 234227)
@@ -78,7 +78,7 @@
 @param sourceURL A URL for the script's source file. Used by debuggers and when reporting exceptions. This parameter is informative only: it does not change the behavior of the script.
 @result The last value generated by the script.
 */
-- (JSValue *)evaluateScript:(NSString *)script withSourceURL:(NSURL *)sourceURL NS_AVAILABLE(10_10, 8_0);
+- (JSValue *)evaluateScript:(NSString *)script withSourceURL:(NSURL *)sourceURL JSC_API_AVAILABLE(macosx(10.10), ios(8.0));
 
 /*!
 @methodgroup Callback Accessors
@@ -101,7 +101,7 @@
  a callback from _javascript_ this method will return nil.
 @result The currently executing _javascript_ function or nil if there isn't one.
 */
-+ (JSValue *)currentCallee NS_AVAILABLE(10_10, 8_0);
++ (JSValue *)currentCallee JSC_API_AVAILABLE(macosx(10.10), ios(8.0));
 
 /*!
 @method
@@ -176,7 +176,7 @@
 @property
 @discussion Name of the JSContext. Exposed when remote debugging the context.
 */
-@property (copy) NSString *name NS_AVAILABLE(10_10, 8_0);
+@property (copy) NSString *name JSC_API_AVAILABLE(macosx(10.10), ios(8.0));
 
 @end
 

Modified: trunk/Source/_javascript_Core/API/JSContextPrivate.h (234226 => 234227)


--- trunk/Source/_javascript_Core/API/JSContextPrivate.h	2018-07-26 01:29:11 UTC (rev 234226)
+++ trunk/Source/_javascript_Core/API/JSContextPrivate.h	2018-07-26 02:32:25 UTC (rev 234227)
@@ -36,19 +36,19 @@
 @property
 @discussion Remote inspection setting of the JSContext. Default value is YES.
 */
-@property (setter=_setRemoteInspectionEnabled:) BOOL _remoteInspectionEnabled NS_AVAILABLE(10_10, 8_0);
+@property (setter=_setRemoteInspectionEnabled:) BOOL _remoteInspectionEnabled JSC_API_AVAILABLE(macosx(10.10), ios(8.0));
 
 /*!
 @property
 @discussion Set whether or not the native call stack is included when reporting exceptions. Default value is YES.
 */
-@property (setter=_setIncludesNativeCallStackWhenReportingExceptions:) BOOL _includesNativeCallStackWhenReportingExceptions NS_AVAILABLE(10_10, 8_0);
+@property (setter=_setIncludesNativeCallStackWhenReportingExceptions:) BOOL _includesNativeCallStackWhenReportingExceptions JSC_API_AVAILABLE(macosx(10.10), ios(8.0));
 
 /*!
 @property
 @discussion Set the run loop the Web Inspector debugger should use when evaluating _javascript_ in the JSContext.
 */
-@property (setter=_setDebuggerRunLoop:) CFRunLoopRef _debuggerRunLoop NS_AVAILABLE(10_10, 8_0);
+@property (setter=_setDebuggerRunLoop:) CFRunLoopRef _debuggerRunLoop JSC_API_AVAILABLE(macosx(10.10), ios(8.0));
 
 @end
 

Modified: trunk/Source/_javascript_Core/API/JSContextRef.h (234226 => 234227)


--- trunk/Source/_javascript_Core/API/JSContextRef.h	2018-07-26 01:29:11 UTC (rev 234226)
+++ trunk/Source/_javascript_Core/API/JSContextRef.h	2018-07-26 02:32:25 UTC (rev 234227)
@@ -53,7 +53,7 @@
  JSContextGroup's run loop once it has been created.
 @result The created JSContextGroup.
 */
-JS_EXPORT JSContextGroupRef JSContextGroupCreate(void) CF_AVAILABLE(10_6, 7_0);
+JS_EXPORT JSContextGroupRef JSContextGroupCreate(void) JSC_API_AVAILABLE(macosx(10.6), ios(7.0));
 
 /*!
 @function
@@ -61,7 +61,7 @@
 @param group The JSContextGroup to retain.
 @result A JSContextGroup that is the same as group.
 */
-JS_EXPORT JSContextGroupRef JSContextGroupRetain(JSContextGroupRef group) CF_AVAILABLE(10_6, 7_0);
+JS_EXPORT JSContextGroupRef JSContextGroupRetain(JSContextGroupRef group) JSC_API_AVAILABLE(macosx(10.6), ios(7.0));
 
 /*!
 @function
@@ -68,7 +68,7 @@
 @abstract Releases a _javascript_ context group.
 @param group The JSContextGroup to release.
 */
-JS_EXPORT void JSContextGroupRelease(JSContextGroupRef group) CF_AVAILABLE(10_6, 7_0);
+JS_EXPORT void JSContextGroupRelease(JSContextGroupRef group) JSC_API_AVAILABLE(macosx(10.6), ios(7.0));
 
 /*!
 @function
@@ -83,7 +83,7 @@
  NULL to use the default object class.
 @result A JSGlobalContext with a global object of class globalObjectClass.
 */
-JS_EXPORT JSGlobalContextRef JSGlobalContextCreate(JSClassRef globalObjectClass) CF_AVAILABLE(10_5, 7_0);
+JS_EXPORT JSGlobalContextRef JSGlobalContextCreate(JSClassRef globalObjectClass) JSC_API_AVAILABLE(macosx(10.5), ios(7.0));
 
 /*!
 @function
@@ -97,7 +97,7 @@
 @result A JSGlobalContext with a global object of class globalObjectClass and a context
  group equal to group.
 */
-JS_EXPORT JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClassRef globalObjectClass) CF_AVAILABLE(10_6, 7_0);
+JS_EXPORT JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClassRef globalObjectClass) JSC_API_AVAILABLE(macosx(10.6), ios(7.0));
 
 /*!
 @function
@@ -128,7 +128,7 @@
 @param ctx The JSContext whose group you want to get.
 @result ctx's group.
 */
-JS_EXPORT JSContextGroupRef JSContextGetGroup(JSContextRef ctx) CF_AVAILABLE(10_6, 7_0);
+JS_EXPORT JSContextGroupRef JSContextGetGroup(JSContextRef ctx) JSC_API_AVAILABLE(macosx(10.6), ios(7.0));
 
 /*!
 @function
@@ -136,7 +136,7 @@
 @param ctx The JSContext whose global context you want to get.
 @result ctx's global context.
 */
-JS_EXPORT JSGlobalContextRef JSContextGetGlobalContext(JSContextRef ctx) CF_AVAILABLE(10_7, 7_0);
+JS_EXPORT JSGlobalContextRef JSContextGetGlobalContext(JSContextRef ctx) JSC_API_AVAILABLE(macosx(10.7), ios(7.0));
 
 /*!
 @function
@@ -146,7 +146,7 @@
 @discussion A JSGlobalContext's name is exposed for remote debugging to make it
 easier to identify the context you would like to attach to.
 */
-JS_EXPORT JSStringRef JSGlobalContextCopyName(JSGlobalContextRef ctx) CF_AVAILABLE(10_10, 8_0);
+JS_EXPORT JSStringRef JSGlobalContextCopyName(JSGlobalContextRef ctx) JSC_API_AVAILABLE(macosx(10.10), ios(8.0));
 
 /*!
 @function
@@ -154,7 +154,7 @@
 @param ctx The JSGlobalContext that you want to name.
 @param name The remote debugging name to set on ctx.
 */
-JS_EXPORT void JSGlobalContextSetName(JSGlobalContextRef ctx, JSStringRef name) CF_AVAILABLE(10_10, 8_0);
+JS_EXPORT void JSGlobalContextSetName(JSGlobalContextRef ctx, JSStringRef name) JSC_API_AVAILABLE(macosx(10.10), ios(8.0));
 
 #ifdef __cplusplus
 }

Modified: trunk/Source/_javascript_Core/API/JSContextRefInternal.h (234226 => 234227)


--- trunk/Source/_javascript_Core/API/JSContextRefInternal.h	2018-07-26 01:29:11 UTC (rev 234226)
+++ trunk/Source/_javascript_Core/API/JSContextRefInternal.h	2018-07-26 02:32:25 UTC (rev 234227)
@@ -42,7 +42,7 @@
 @abstract Gets the run loop used by the Web Inspector debugger when evaluating _javascript_ in this context.
 @param ctx The JSGlobalContext whose setting you want to get.
 */
-JS_EXPORT CFRunLoopRef JSGlobalContextGetDebuggerRunLoop(JSGlobalContextRef ctx) CF_AVAILABLE(10_10, 8_0);
+JS_EXPORT CFRunLoopRef JSGlobalContextGetDebuggerRunLoop(JSGlobalContextRef ctx) JSC_API_AVAILABLE(macosx(10.10), ios(8.0));
 
 /*!
 @function
@@ -50,7 +50,7 @@
 @param ctx The JSGlobalContext that you want to change.
 @param runLoop The new value of the setting for the context.
 */
-JS_EXPORT void JSGlobalContextSetDebuggerRunLoop(JSGlobalContextRef ctx, CFRunLoopRef runLoop) CF_AVAILABLE(10_10, 8_0);
+JS_EXPORT void JSGlobalContextSetDebuggerRunLoop(JSGlobalContextRef ctx, CFRunLoopRef runLoop) JSC_API_AVAILABLE(macosx(10.10), ios(8.0));
 #endif
 
 #ifdef __cplusplus

Modified: trunk/Source/_javascript_Core/API/JSContextRefPrivate.h (234226 => 234227)


--- trunk/Source/_javascript_Core/API/JSContextRefPrivate.h	2018-07-26 01:29:11 UTC (rev 234226)
+++ trunk/Source/_javascript_Core/API/JSContextRefPrivate.h	2018-07-26 02:32:25 UTC (rev 234227)
@@ -44,7 +44,7 @@
 @param ctx The JSContext whose backtrace you want to get
 @result A string containing the backtrace
 */
-JS_EXPORT JSStringRef JSContextCreateBacktrace(JSContextRef ctx, unsigned maxStackSize) CF_AVAILABLE(10_6, 7_0);
+JS_EXPORT JSStringRef JSContextCreateBacktrace(JSContextRef ctx, unsigned maxStackSize) JSC_API_AVAILABLE(macosx(10.6), ios(7.0));
     
 
 /*! 
@@ -85,7 +85,7 @@
  need to call JSContextGroupSetExecutionTimeLimit before you start executing
  any scripts.
 */
-JS_EXPORT void JSContextGroupSetExecutionTimeLimit(JSContextGroupRef group, double limit, JSShouldTerminateCallback callback, void* context) CF_AVAILABLE(10_6, 7_0);
+JS_EXPORT void JSContextGroupSetExecutionTimeLimit(JSContextGroupRef group, double limit, JSShouldTerminateCallback callback, void* context) JSC_API_AVAILABLE(macosx(10.6), ios(7.0));
 
 /*!
 @function
@@ -92,7 +92,7 @@
 @abstract Clears the script execution time limit.
 @param group The _javascript_ context group that the time limit is cleared on.
 */
-JS_EXPORT void JSContextGroupClearExecutionTimeLimit(JSContextGroupRef group) CF_AVAILABLE(10_6, 7_0);
+JS_EXPORT void JSContextGroupClearExecutionTimeLimit(JSContextGroupRef group) JSC_API_AVAILABLE(macosx(10.6), ios(7.0));
 
 /*!
 @function
@@ -101,7 +101,7 @@
 @result The value of the setting, true if remote inspection is enabled, otherwise false.
 @discussion Remote inspection is true by default.
 */
-JS_EXPORT bool JSGlobalContextGetRemoteInspectionEnabled(JSGlobalContextRef ctx) CF_AVAILABLE(10_10, 8_0);
+JS_EXPORT bool JSGlobalContextGetRemoteInspectionEnabled(JSGlobalContextRef ctx) JSC_API_AVAILABLE(macosx(10.10), ios(8.0));
 
 /*!
 @function
@@ -109,7 +109,7 @@
 @param ctx The JSGlobalContext that you want to change.
 @param enabled The new remote inspection enabled setting for the context.
 */
-JS_EXPORT void JSGlobalContextSetRemoteInspectionEnabled(JSGlobalContextRef ctx, bool enabled) CF_AVAILABLE(10_10, 8_0);    
+JS_EXPORT void JSGlobalContextSetRemoteInspectionEnabled(JSGlobalContextRef ctx, bool enabled) JSC_API_AVAILABLE(macosx(10.10), ios(8.0));    
 
 /*!
 @function
@@ -118,7 +118,7 @@
 @result The value of the setting, true if remote inspection is enabled, otherwise false.
 @discussion This setting is true by default.
 */
-JS_EXPORT bool JSGlobalContextGetIncludesNativeCallStackWhenReportingExceptions(JSGlobalContextRef ctx) CF_AVAILABLE(10_10, 8_0);
+JS_EXPORT bool JSGlobalContextGetIncludesNativeCallStackWhenReportingExceptions(JSGlobalContextRef ctx) JSC_API_AVAILABLE(macosx(10.10), ios(8.0));
 
 /*!
 @function
@@ -126,7 +126,7 @@
 @param ctx The JSGlobalContext that you want to change.
 @param includesNativeCallStack The new value of the setting for the context.
 */
-JS_EXPORT void JSGlobalContextSetIncludesNativeCallStackWhenReportingExceptions(JSGlobalContextRef ctx, bool includesNativeCallStack) CF_AVAILABLE(10_10, 8_0);
+JS_EXPORT void JSGlobalContextSetIncludesNativeCallStackWhenReportingExceptions(JSGlobalContextRef ctx, bool includesNativeCallStack) JSC_API_AVAILABLE(macosx(10.10), ios(8.0));
 
 #ifdef __cplusplus
 }

Modified: trunk/Source/_javascript_Core/API/JSManagedValue.h (234226 => 234227)


--- trunk/Source/_javascript_Core/API/JSManagedValue.h	2018-07-26 01:29:11 UTC (rev 234226)
+++ trunk/Source/_javascript_Core/API/JSManagedValue.h	2018-07-26 02:32:25 UTC (rev 234227)
@@ -57,7 +57,7 @@
 @result The new JSManagedValue.
 */
 + (JSManagedValue *)managedValueWithValue:(JSValue *)value;
-+ (JSManagedValue *)managedValueWithValue:(JSValue *)value andOwner:(id)owner NS_AVAILABLE(10_10, 8_0);
++ (JSManagedValue *)managedValueWithValue:(JSValue *)value andOwner:(id)owner JSC_API_AVAILABLE(macosx(10.10), ios(8.0));
 
 /*!
 @method

Modified: trunk/Source/_javascript_Core/API/JSObjectRef.cpp (234226 => 234227)


--- trunk/Source/_javascript_Core/API/JSObjectRef.cpp	2018-07-26 01:29:11 UTC (rev 234226)
+++ trunk/Source/_javascript_Core/API/JSObjectRef.cpp	2018-07-26 02:32:25 UTC (rev 234227)
@@ -366,6 +366,100 @@
     handleExceptionIfNeeded(scope, exec, exception);
 }
 
+bool JSObjectHasPropertyKey(JSContextRef ctx, JSObjectRef object, JSValueRef key, JSValueRef* exception)
+{
+    if (!ctx) {
+        ASSERT_NOT_REACHED();
+        return false;
+    }
+    ExecState* exec = toJS(ctx);
+    VM& vm = exec->vm();
+    JSLockHolder locker(vm);
+    auto scope = DECLARE_CATCH_SCOPE(vm);
+
+    JSObject* jsObject = toJS(object);
+    Identifier ident = toJS(exec, key).toPropertyKey(exec);
+    if (handleExceptionIfNeeded(scope, exec, exception) == ExceptionStatus::DidThrow)
+        return false;
+
+    bool result = jsObject->hasProperty(exec, ident);
+    handleExceptionIfNeeded(scope, exec, exception);
+    return result;
+}
+
+JSValueRef JSObjectGetPropertyKey(JSContextRef ctx, JSObjectRef object, JSValueRef key, JSValueRef* exception)
+{
+    if (!ctx) {
+        ASSERT_NOT_REACHED();
+        return nullptr;
+    }
+    ExecState* exec = toJS(ctx);
+    VM& vm = exec->vm();
+    JSLockHolder locker(vm);
+    auto scope = DECLARE_CATCH_SCOPE(vm);
+
+    JSObject* jsObject = toJS(object);
+    Identifier ident = toJS(exec, key).toPropertyKey(exec);
+    if (handleExceptionIfNeeded(scope, exec, exception) == ExceptionStatus::DidThrow)
+        return nullptr;
+
+    JSValue jsValue = jsObject->get(exec, ident);
+    handleExceptionIfNeeded(scope, exec, exception);
+    return toRef(exec, jsValue);
+}
+
+void JSObjectSetPropertyKey(JSContextRef ctx, JSObjectRef object, JSValueRef key, JSValueRef value, JSPropertyAttributes attributes, JSValueRef* exception)
+{
+    if (!ctx) {
+        ASSERT_NOT_REACHED();
+        return;
+    }
+    ExecState* exec = toJS(ctx);
+    VM& vm = exec->vm();
+    JSLockHolder locker(vm);
+    auto scope = DECLARE_CATCH_SCOPE(vm);
+
+    JSObject* jsObject = toJS(object);
+    JSValue jsValue = toJS(exec, value);
+
+    Identifier ident = toJS(exec, key).toPropertyKey(exec);
+    if (handleExceptionIfNeeded(scope, exec, exception) == ExceptionStatus::DidThrow)
+        return;
+
+    bool doesNotHaveProperty = attributes && !jsObject->hasProperty(exec, ident);
+    if (LIKELY(!scope.exception())) {
+        if (doesNotHaveProperty) {
+            PropertyDescriptor desc(jsValue, attributes);
+            jsObject->methodTable(vm)->defineOwnProperty(jsObject, exec, ident, desc, false);
+        } else {
+            PutPropertySlot slot(jsObject);
+            jsObject->methodTable(vm)->put(jsObject, exec, ident, jsValue, slot);
+        }
+    }
+    handleExceptionIfNeeded(scope, exec, exception);
+}
+
+bool JSObjectDeletePropertyKey(JSContextRef ctx, JSObjectRef object, JSValueRef key, JSValueRef* exception)
+{
+    if (!ctx) {
+        ASSERT_NOT_REACHED();
+        return false;
+    }
+    ExecState* exec = toJS(ctx);
+    VM& vm = exec->vm();
+    JSLockHolder locker(vm);
+    auto scope = DECLARE_CATCH_SCOPE(vm);
+
+    JSObject* jsObject = toJS(object);
+    Identifier ident = toJS(exec, key).toPropertyKey(exec);
+    if (handleExceptionIfNeeded(scope, exec, exception) == ExceptionStatus::DidThrow)
+        return false;
+
+    bool result = jsObject->methodTable(vm)->deleteProperty(jsObject, exec, ident);
+    handleExceptionIfNeeded(scope, exec, exception);
+    return result;
+}
+
 JSValueRef JSObjectGetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned propertyIndex, JSValueRef* exception)
 {
     if (!ctx) {

Modified: trunk/Source/_javascript_Core/API/JSObjectRef.h (234226 => 234227)


--- trunk/Source/_javascript_Core/API/JSObjectRef.h	2018-07-26 01:29:11 UTC (rev 234226)
+++ trunk/Source/_javascript_Core/API/JSObjectRef.h	2018-07-26 02:32:25 UTC (rev 234227)
@@ -441,7 +441,7 @@
  @discussion The behavior of this function does not exactly match the behavior of the built-in Array constructor. Specifically, if one argument 
  is supplied, this function returns an array with one element.
  */
-JS_EXPORT JSObjectRef JSObjectMakeArray(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) CF_AVAILABLE(10_6, 7_0);
+JS_EXPORT JSObjectRef JSObjectMakeArray(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) JSC_API_AVAILABLE(macosx(10.6), ios(7.0));
 
 /*!
  @function
@@ -452,7 +452,7 @@
  @param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
  @result A JSObject that is a Date.
  */
-JS_EXPORT JSObjectRef JSObjectMakeDate(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) CF_AVAILABLE(10_6, 7_0);
+JS_EXPORT JSObjectRef JSObjectMakeDate(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) JSC_API_AVAILABLE(macosx(10.6), ios(7.0));
 
 /*!
  @function
@@ -463,7 +463,7 @@
  @param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
  @result A JSObject that is a Error.
  */
-JS_EXPORT JSObjectRef JSObjectMakeError(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) CF_AVAILABLE(10_6, 7_0);
+JS_EXPORT JSObjectRef JSObjectMakeError(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) JSC_API_AVAILABLE(macosx(10.6), ios(7.0));
 
 /*!
  @function
@@ -474,7 +474,7 @@
  @param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
  @result A JSObject that is a RegExp.
  */
-JS_EXPORT JSObjectRef JSObjectMakeRegExp(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) CF_AVAILABLE(10_6, 7_0);
+JS_EXPORT JSObjectRef JSObjectMakeRegExp(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) JSC_API_AVAILABLE(macosx(10.6), ios(7.0));
 
 /*!
 @function
@@ -536,9 +536,9 @@
 @param ctx The execution context to use.
 @param object The JSObject whose property you want to set.
 @param propertyName A JSString containing the property's name.
-@param value A JSValue to use as the property's value.
+@param value A JSValueRef to use as the property's value.
+@param attributes A logically ORed set of JSPropertyAttributes to give to the property.
 @param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
-@param attributes A logically ORed set of JSPropertyAttributes to give to the property.
 */
 JS_EXPORT void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSPropertyAttributes attributes, JSValueRef* exception);
 
@@ -555,6 +555,54 @@
 
 /*!
 @function
+@abstract Tests whether an object has a given property using a JSValueRef as the property key.
+@param object The JSObject to test.
+@param propertyKey A JSValueRef containing the property key to use when looking up the property.
+@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
+@result true if the object has a property whose name matches propertyKey, otherwise false.
+@discussion This function is the same as performing "propertyKey in object" from _javascript_.
+*/
+JS_EXPORT bool JSObjectHasPropertyKey(JSContextRef ctx, JSObjectRef object, JSValueRef propertyKey, JSValueRef* exception) JSC_API_AVAILABLE(macosx(JSC_MAC_TBA), ios(JSC_IOS_TBA));
+
+/*!
+@function
+@abstract Gets a property from an object using a JSValueRef as the property key.
+@param ctx The execution context to use.
+@param object The JSObject whose property you want to get.
+@param propertyKey A JSValueRef containing the property key to use when looking up the property.
+@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
+@result The property's value if object has the property key, otherwise the undefined value.
+@discussion This function is the same as performing "object[propertyKey]" from _javascript_.
+*/
+JS_EXPORT JSValueRef JSObjectGetPropertyKey(JSContextRef ctx, JSObjectRef object, JSValueRef propertyKey, JSValueRef* exception) JSC_API_AVAILABLE(macosx(JSC_MAC_TBA), ios(JSC_IOS_TBA));
+
+/*!
+@function
+@abstract Sets a property on an object using a JSValueRef as the property key.
+@param ctx The execution context to use.
+@param object The JSObject whose property you want to set.
+@param propertyKey A JSValueRef containing the property key to use when looking up the property.
+@param value A JSValueRef to use as the property's value.
+@param attributes A logically ORed set of JSPropertyAttributes to give to the property.
+@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
+@discussion This function is the same as performing "object[propertyKey] = value" from _javascript_.
+*/
+JS_EXPORT void JSObjectSetPropertyKey(JSContextRef ctx, JSObjectRef object, JSValueRef propertyKey, JSValueRef value, JSPropertyAttributes attributes, JSValueRef* exception) JSC_API_AVAILABLE(macosx(JSC_MAC_TBA), ios(JSC_IOS_TBA));
+
+/*!
+@function
+@abstract Deletes a property from an object using a JSValueRef as the property key.
+@param ctx The execution context to use.
+@param object The JSObject whose property you want to delete.
+@param propertyKey A JSValueRef containing the property key to use when looking up the property.
+@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
+@result true if the delete operation succeeds, otherwise false (for example, if the property has the kJSPropertyAttributeDontDelete attribute set).
+@discussion This function is the same as performing "delete object[propertyKey]" from _javascript_.
+*/
+JS_EXPORT bool JSObjectDeletePropertyKey(JSContextRef ctx, JSObjectRef object, JSValueRef propertyKey, JSValueRef* exception) JSC_API_AVAILABLE(macosx(JSC_MAC_TBA), ios(JSC_IOS_TBA));
+
+/*!
+@function
 @abstract Gets a property from an object by numeric index.
 @param ctx The execution context to use.
 @param object The JSObject whose property you want to get.

Modified: trunk/Source/_javascript_Core/API/JSRemoteInspector.h (234226 => 234227)


--- trunk/Source/_javascript_Core/API/JSRemoteInspector.h	2018-07-26 01:29:11 UTC (rev 234226)
+++ trunk/Source/_javascript_Core/API/JSRemoteInspector.h	2018-07-26 02:32:25 UTC (rev 234227)
@@ -40,14 +40,14 @@
 extern "C" {
 #endif
 
-JS_EXPORT void JSRemoteInspectorDisableAutoStart(void) CF_AVAILABLE(10_11, 9_0);
-JS_EXPORT void JSRemoteInspectorStart(void) CF_AVAILABLE(10_11, 9_0);
-JS_EXPORT void JSRemoteInspectorSetParentProcessInformation(JSProcessID, const uint8_t* auditData, size_t auditLength) CF_AVAILABLE(10_11, 9_0);
+JS_EXPORT void JSRemoteInspectorDisableAutoStart(void) JSC_API_AVAILABLE(macosx(10.11), ios(9.0));
+JS_EXPORT void JSRemoteInspectorStart(void) JSC_API_AVAILABLE(macosx(10.11), ios(9.0));
+JS_EXPORT void JSRemoteInspectorSetParentProcessInformation(JSProcessID, const uint8_t* auditData, size_t auditLength) JSC_API_AVAILABLE(macosx(10.11), ios(9.0));
 
-JS_EXPORT void JSRemoteInspectorSetLogToSystemConsole(bool) CF_AVAILABLE(10_11, 9_0);
+JS_EXPORT void JSRemoteInspectorSetLogToSystemConsole(bool) JSC_API_AVAILABLE(macosx(10.11), ios(9.0));
 
-JS_EXPORT bool JSRemoteInspectorGetInspectionEnabledByDefault(void) CF_AVAILABLE(10_11, 9_0);
-JS_EXPORT void JSRemoteInspectorSetInspectionEnabledByDefault(bool) CF_AVAILABLE(10_11, 9_0);
+JS_EXPORT bool JSRemoteInspectorGetInspectionEnabledByDefault(void) JSC_API_AVAILABLE(macosx(10.11), ios(9.0));
+JS_EXPORT void JSRemoteInspectorSetInspectionEnabledByDefault(bool) JSC_API_AVAILABLE(macosx(10.11), ios(9.0));
 
 #ifdef __cplusplus
 }

Modified: trunk/Source/_javascript_Core/API/JSTypedArray.h (234226 => 234227)


--- trunk/Source/_javascript_Core/API/JSTypedArray.h	2018-07-26 01:29:11 UTC (rev 234226)
+++ trunk/Source/_javascript_Core/API/JSTypedArray.h	2018-07-26 02:32:25 UTC (rev 234227)
@@ -45,7 +45,7 @@
  @param exception    A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
  @result             A JSObjectRef that is a Typed Array with all elements set to zero or NULL if there was an error.
  */
-JS_EXPORT JSObjectRef JSObjectMakeTypedArray(JSContextRef ctx, JSTypedArrayType arrayType, size_t length, JSValueRef* exception) CF_AVAILABLE(10_12, 10_0);
+JS_EXPORT JSObjectRef JSObjectMakeTypedArray(JSContextRef ctx, JSTypedArrayType arrayType, size_t length, JSValueRef* exception) JSC_API_AVAILABLE(macosx(10.12), ios(10.0));
 
 /*!
  @function
@@ -60,7 +60,7 @@
  @result                   A JSObjectRef Typed Array whose backing store is the same as the one pointed to by bytes or NULL if there was an error.
  @discussion               If an exception is thrown during this function the bytesDeallocator will always be called.
  */
-JS_EXPORT JSObjectRef JSObjectMakeTypedArrayWithBytesNoCopy(JSContextRef ctx, JSTypedArrayType arrayType, void* bytes, size_t byteLength, JSTypedArrayBytesDeallocator bytesDeallocator, void* deallocatorContext, JSValueRef* exception) CF_AVAILABLE(10_12, 10_0);
+JS_EXPORT JSObjectRef JSObjectMakeTypedArrayWithBytesNoCopy(JSContextRef ctx, JSTypedArrayType arrayType, void* bytes, size_t byteLength, JSTypedArrayBytesDeallocator bytesDeallocator, void* deallocatorContext, JSValueRef* exception) JSC_API_AVAILABLE(macosx(10.12), ios(10.0));
 
 /*!
  @function
@@ -71,7 +71,7 @@
  @param exception    A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
  @result             A JSObjectRef that is a Typed Array or NULL if there was an error. The backing store of the Typed Array will be buffer.
  */
-JS_EXPORT JSObjectRef JSObjectMakeTypedArrayWithArrayBuffer(JSContextRef ctx, JSTypedArrayType arrayType, JSObjectRef buffer, JSValueRef* exception) CF_AVAILABLE(10_12, 10_0);
+JS_EXPORT JSObjectRef JSObjectMakeTypedArrayWithArrayBuffer(JSContextRef ctx, JSTypedArrayType arrayType, JSObjectRef buffer, JSValueRef* exception) JSC_API_AVAILABLE(macosx(10.12), ios(10.0));
 
 /*!
  @function
@@ -84,7 +84,7 @@
  @param exception    A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
  @result             A JSObjectRef that is a Typed Array or NULL if there was an error. The backing store of the Typed Array will be buffer.
  */
-JS_EXPORT JSObjectRef JSObjectMakeTypedArrayWithArrayBufferAndOffset(JSContextRef ctx, JSTypedArrayType arrayType, JSObjectRef buffer, size_t byteOffset, size_t length, JSValueRef* exception) CF_AVAILABLE(10_12, 10_0);
+JS_EXPORT JSObjectRef JSObjectMakeTypedArrayWithArrayBufferAndOffset(JSContextRef ctx, JSTypedArrayType arrayType, JSObjectRef buffer, size_t byteOffset, size_t length, JSValueRef* exception) JSC_API_AVAILABLE(macosx(10.12), ios(10.0));
 
 /*!
  @function
@@ -95,7 +95,7 @@
  @result             A pointer to the raw data buffer that serves as object's backing store or NULL if object is not a Typed Array object.
  @discussion         The pointer returned by this function is temporary and is not guaranteed to remain valid across _javascript_Core API calls.
  */
-JS_EXPORT void* JSObjectGetTypedArrayBytesPtr(JSContextRef ctx, JSObjectRef object, JSValueRef* exception) CF_AVAILABLE(10_12, 10_0);
+JS_EXPORT void* JSObjectGetTypedArrayBytesPtr(JSContextRef ctx, JSObjectRef object, JSValueRef* exception) JSC_API_AVAILABLE(macosx(10.12), ios(10.0));
 
 /*!
  @function
@@ -105,7 +105,7 @@
  @param exception    A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
  @result             The length of the Typed Array object or 0 if the object is not a Typed Array object.
  */
-JS_EXPORT size_t JSObjectGetTypedArrayLength(JSContextRef ctx, JSObjectRef object, JSValueRef* exception) CF_AVAILABLE(10_12, 10_0);
+JS_EXPORT size_t JSObjectGetTypedArrayLength(JSContextRef ctx, JSObjectRef object, JSValueRef* exception) JSC_API_AVAILABLE(macosx(10.12), ios(10.0));
 
 /*!
  @function
@@ -115,7 +115,7 @@
  @param exception    A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
  @result             The byte length of the Typed Array object or 0 if the object is not a Typed Array object.
  */
-JS_EXPORT size_t JSObjectGetTypedArrayByteLength(JSContextRef ctx, JSObjectRef object, JSValueRef* exception) CF_AVAILABLE(10_12, 10_0);
+JS_EXPORT size_t JSObjectGetTypedArrayByteLength(JSContextRef ctx, JSObjectRef object, JSValueRef* exception) JSC_API_AVAILABLE(macosx(10.12), ios(10.0));
 
 /*!
  @function
@@ -125,7 +125,7 @@
  @param exception    A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
  @result             The byte offset of the Typed Array object or 0 if the object is not a Typed Array object.
  */
-JS_EXPORT size_t JSObjectGetTypedArrayByteOffset(JSContextRef ctx, JSObjectRef object, JSValueRef* exception) CF_AVAILABLE(10_12, 10_0);
+JS_EXPORT size_t JSObjectGetTypedArrayByteOffset(JSContextRef ctx, JSObjectRef object, JSValueRef* exception) JSC_API_AVAILABLE(macosx(10.12), ios(10.0));
 
 /*!
  @function
@@ -135,7 +135,7 @@
  @param exception    A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
  @result             A JSObjectRef with a JSTypedArrayType of kJSTypedArrayTypeArrayBuffer or NULL if object is not a Typed Array.
  */
-JS_EXPORT JSObjectRef JSObjectGetTypedArrayBuffer(JSContextRef ctx, JSObjectRef object, JSValueRef* exception) CF_AVAILABLE(10_12, 10_0);
+JS_EXPORT JSObjectRef JSObjectGetTypedArrayBuffer(JSContextRef ctx, JSObjectRef object, JSValueRef* exception) JSC_API_AVAILABLE(macosx(10.12), ios(10.0));
 
 // ------------- Array Buffer functions -------------
 
@@ -151,7 +151,7 @@
  @result                   A JSObjectRef Array Buffer whose backing store is the same as the one pointed to by bytes or NULL if there was an error.
  @discussion               If an exception is thrown during this function the bytesDeallocator will always be called.
  */
-JS_EXPORT JSObjectRef JSObjectMakeArrayBufferWithBytesNoCopy(JSContextRef ctx, void* bytes, size_t byteLength, JSTypedArrayBytesDeallocator bytesDeallocator, void* deallocatorContext, JSValueRef* exception) CF_AVAILABLE(10_12, 10_0);
+JS_EXPORT JSObjectRef JSObjectMakeArrayBufferWithBytesNoCopy(JSContextRef ctx, void* bytes, size_t byteLength, JSTypedArrayBytesDeallocator bytesDeallocator, void* deallocatorContext, JSValueRef* exception) JSC_API_AVAILABLE(macosx(10.12), ios(10.0));
 
 /*!
  @function
@@ -161,7 +161,7 @@
  @result           A pointer to the raw data buffer that serves as object's backing store or NULL if object is not an Array Buffer object.
  @discussion       The pointer returned by this function is temporary and is not guaranteed to remain valid across _javascript_Core API calls.
  */
-JS_EXPORT void* JSObjectGetArrayBufferBytesPtr(JSContextRef ctx, JSObjectRef object, JSValueRef* exception) CF_AVAILABLE(10_12, 10_0);
+JS_EXPORT void* JSObjectGetArrayBufferBytesPtr(JSContextRef ctx, JSObjectRef object, JSValueRef* exception) JSC_API_AVAILABLE(macosx(10.12), ios(10.0));
 
 /*!
  @function
@@ -171,7 +171,7 @@
  @param exception  A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
  @result           The number of bytes stored in the data object.
  */
-JS_EXPORT size_t JSObjectGetArrayBufferByteLength(JSContextRef ctx, JSObjectRef object, JSValueRef* exception) CF_AVAILABLE(10_12, 10_0);
+JS_EXPORT size_t JSObjectGetArrayBufferByteLength(JSContextRef ctx, JSObjectRef object, JSValueRef* exception) JSC_API_AVAILABLE(macosx(10.12), ios(10.0));
 
 #ifdef __cplusplus
 }

Modified: trunk/Source/_javascript_Core/API/JSValue.h (234226 => 234227)


--- trunk/Source/_javascript_Core/API/JSValue.h	2018-07-26 01:29:11 UTC (rev 234226)
+++ trunk/Source/_javascript_Core/API/JSValue.h	2018-07-26 02:32:25 UTC (rev 234227)
@@ -47,6 +47,12 @@
 NS_CLASS_AVAILABLE(10_9, 7_0)
 @interface JSValue : NSObject
 
+#if (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < JSC_MAC_VERSION_TBA) || (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < JSC_IOS_VERSION_TBA)
+typedef NSString *JSValuePropertyKeyType;
+#else
+typedef id JSValuePropertyKeyType;
+#endif
+
 /*!
 @property
 @abstract The JSContext that this value originates from.
@@ -149,6 +155,15 @@
 + (JSValue *)valueWithUndefinedInContext:(JSContext *)context;
 
 /*!
+ @method
+ @abstract Create a new, unique, symbol object.
+ @param description The description of the symbol object being created.
+ @param context The JSContext to which the resulting JSValue belongs.
+ @result The JSValue representing a unique _javascript_ value with type symbol.
+ */
++ (JSValue *)valueWithNewSymbolFromDescription:(NSString *)description inContext:(JSContext *)context JSC_API_AVAILABLE(macosx(JSC_MAC_TBA), ios(JSC_IOS_TBA));
+
+/*!
 @methodgroup Converting to Objective-C Types
 @discussion When converting between _javascript_ values and Objective-C objects a copy is
  performed. Values of types listed below are copied to the corresponding
@@ -305,26 +320,30 @@
 /*!
 @methodgroup Accessing Properties
 */
+
 /*!
 @method
 @abstract Access a property of a JSValue.
 @result The JSValue for the requested property or the JSValue <code>undefined</code> 
  if the property does not exist.
+@discussion Corresponds to the _javascript_ operation <code>object[property]</code>. Pass an NSString * to access a named property. Other valid properties include symbols, numbers, and stringifiable objects. In macOS 10.13 and iOS 11 and below, 'property' was an NSString *.
 */
-- (JSValue *)valueForProperty:(NSString *)property;
+- (JSValue *)valueForProperty:(JSValuePropertyKeyType)property;
 
 /*!
 @method
 @abstract Set a property on a JSValue.
+@discussion Corresponds to the _javascript_ operation <code>object[property] = value</code>. Pass an NSString * to access a named property. Other valid properties include symbols, numbers, and stringifiable objects. In macOS 10.13 and iOS 11 and below, 'property' was an NSString *.
 */
-- (void)setValue:(id)value forProperty:(NSString *)property;
+- (void)setValue:(id)value forProperty:(JSValuePropertyKeyType)property;
 
 /*!
 @method
 @abstract Delete a property from a JSValue.
 @result YES if deletion is successful, NO otherwise.
+@discussion Corresponds to the _javascript_ operation <code>delete object[property]</code>. Pass an NSString * to access a named property. Other valid properties include symbols, numbers, and stringifiable objects. In macOS 10.13 and iOS 11 and below, 'property' was an NSString *.
 */
-- (BOOL)deleteProperty:(NSString *)property;
+- (BOOL)deleteProperty:(JSValuePropertyKeyType)property;
 
 /*!
 @method
@@ -331,8 +350,9 @@
 @abstract Check if a JSValue has a property.
 @discussion This method has the same function as the _javascript_ operator <code>in</code>.
 @result Returns YES if property is present on the value.
+@discussion Corresponds to the _javascript_ operation <code>property in object</code>. Pass an NSString * to access a named property. Other valid properties include symbols, numbers, and stringifiable objects. In macOS 10.13 and iOS 11 and below, 'property' was an NSString *.
 */
-- (BOOL)hasProperty:(NSString *)property;
+- (BOOL)hasProperty:(JSValuePropertyKeyType)property;
 
 /*!
 @method
@@ -339,9 +359,9 @@
 @abstract Define properties with custom descriptors on JSValues.
 @discussion This method may be used to create a data or accessor property on an object.
  This method operates in accordance with the Object.defineProperty method in the 
- _javascript_ language.
+ _javascript_ language. Pass an NSString * to access a named property. Other valid properties include symbols, numbers, and stringifiable objects. In macOS 10.13 and iOS 11 and below, 'property' was an NSString *.
 */
-- (void)defineProperty:(NSString *)property descriptor:(id)descriptor;
+- (void)defineProperty:(JSValuePropertyKeyType)property descriptor:(id)descriptor;
 
 /*!
 @method
@@ -404,15 +424,21 @@
 
 /*!
 @property
+@abstract Check if a JSValue is a symbol.
+*/
+@property (readonly) BOOL isSymbol JSC_API_AVAILABLE(macosx(JSC_MAC_TBA), ios(JSC_IOS_TBA));
+
+/*!
+@property
 @abstract Check if a JSValue is an array.
 */ 
-@property (readonly) BOOL isArray NS_AVAILABLE(10_11, 9_0);
+@property (readonly) BOOL isArray JSC_API_AVAILABLE(macosx(10.11), ios(9.0));
 
 /*!
 @property
 @abstract Check if a JSValue is a date.
 */ 
-@property (readonly) BOOL isDate NS_AVAILABLE(10_11, 9_0);
+@property (readonly) BOOL isDate JSC_API_AVAILABLE(macosx(10.11), ios(9.0));
 
 /*!
 @method
@@ -569,13 +595,16 @@
 @/textblock
 
  An object key passed as a subscript will be converted to a _javascript_ value,
- and then the value converted to a string used as a property name.
+ and then the value converted to a string used as a property name. In macOS
+ 10.13 and iOS 11 and below, the <code>key</code> argument of
+ <code>setObject:object forKeyedSubscript:key</code> was restricted to an
+ <code>NSString <NSCopying> *</code> but that restriction was never used.
 */
 @interface JSValue (SubscriptSupport)
 
-- (JSValue *)objectForKeyedSubscript:(id)key;
+- (JSValue *)objectForKeyedSubscript:(JSValuePropertyKeyType)key;
 - (JSValue *)objectAtIndexedSubscript:(NSUInteger)index;
-- (void)setObject:(id)object forKeyedSubscript:(NSObject <NSCopying> *)key;
+- (void)setObject:(id)object forKeyedSubscript:(JSValuePropertyKeyType)key;
 - (void)setObject:(id)object atIndexedSubscript:(NSUInteger)index;
 
 @end

Modified: trunk/Source/_javascript_Core/API/JSValue.mm (234226 => 234227)


--- trunk/Source/_javascript_Core/API/JSValue.mm	2018-07-26 01:29:11 UTC (rev 234226)
+++ trunk/Source/_javascript_Core/API/JSValue.mm	2018-07-26 02:32:25 UTC (rev 234227)
@@ -39,6 +39,7 @@
 #import "JSCJSValue.h"
 #import "Strong.h"
 #import "StrongInlines.h"
+#import <wtf/Expected.h>
 #import <wtf/HashMap.h>
 #import <wtf/HashSet.h>
 #import <wtf/Lock.h>
@@ -151,6 +152,13 @@
     return [JSValue valueWithJSValueRef:JSValueMakeUndefined([context JSGlobalContextRef]) inContext:context];
 }
 
++ (JSValue *)valueWithNewSymbolFromDescription:(NSString *)description inContext:(JSContext *)context
+{
+    JSStringRef string = JSStringCreateWithCFString(reinterpret_cast<CFStringRef>(description));
+    return [JSValue valueWithJSValueRef:JSValueMakeSymbol([context JSGlobalContextRef], string) inContext:context];
+}
+
+
 - (id)toObject
 {
     return valueToObject(_context, m_value);
@@ -234,72 +242,81 @@
     return result;
 }
 
-- (JSValue *)valueForProperty:(NSString *)propertyName
+template<typename Result, typename NSStringFunction, typename JSValueFunction, typename... Types>
+inline Expected<Result, JSValueRef> performPropertyOperation(NSStringFunction stringFunction, JSValueFunction jsFunction, JSValue* value, id propertyKey, Types... arguments)
 {
-    JSValueRef exception = 0;
-    JSObjectRef object = JSValueToObject([_context JSGlobalContextRef], m_value, &exception);
+    JSContext* context = [value context];
+    JSValueRef exception = nullptr;
+    JSObjectRef object = JSValueToObject([context JSGlobalContextRef], [value JSValueRef], &exception);
     if (exception)
-        return [_context valueFromNotifyException:exception];
+        return Unexpected<JSValueRef>(exception);
 
-    JSStringRef name = JSStringCreateWithCFString((__bridge CFStringRef)propertyName);
-    JSValueRef result = JSObjectGetProperty([_context JSGlobalContextRef], object, name, &exception);
-    JSStringRelease(name);
-    if (exception)
-        return [_context valueFromNotifyException:exception];
+    Result result;
+    // If it's a NSString already, reduce indirection and just pass the NSString.
+    if ([propertyKey isKindOfClass:[NSString class]]) {
+        JSStringRef name = JSStringCreateWithCFString((__bridge CFStringRef)propertyKey);
+        result = stringFunction([context JSGlobalContextRef], object, name, arguments..., &exception);
+        JSStringRelease(name);
+    } else
+        result = jsFunction([context JSGlobalContextRef], object, [[JSValue valueWithObject:propertyKey inContext:context] JSValueRef], arguments..., &exception);
+    return Expected<Result, JSValueRef>(result);
+}
 
-    return [JSValue valueWithJSValueRef:result inContext:_context];
+- (JSValue *)valueForProperty:(id)key
+{
+    auto result = performPropertyOperation<JSValueRef>(JSObjectGetProperty, JSObjectGetPropertyKey, self, key);
+    if (!result)
+        return [_context valueFromNotifyException:result.error()];
+
+    return [JSValue valueWithJSValueRef:result.value() inContext:_context];
 }
 
-- (void)setValue:(id)value forProperty:(NSString *)propertyName
+
+- (void)setValue:(id)value forProperty:(JSValuePropertyKeyType)key
 {
-    JSValueRef exception = 0;
-    JSObjectRef object = JSValueToObject([_context JSGlobalContextRef], m_value, &exception);
-    if (exception) {
-        [_context notifyException:exception];
-        return;
-    }
+    // We need Unit business because void can't be assigned to in performPropertyOperation and I don't want to duplicate the code...
+    using Unit = std::tuple<>;
+    auto stringSetProperty = [] (auto... args) -> Unit {
+        JSObjectSetProperty(args...);
+        return { };
+    };
 
-    JSStringRef name = JSStringCreateWithCFString((__bridge CFStringRef)propertyName);
-    JSObjectSetProperty([_context JSGlobalContextRef], object, name, objectToValue(_context, value), 0, &exception);
-    JSStringRelease(name);
-    if (exception) {
-        [_context notifyException:exception];
+    auto jsValueSetProperty = [] (auto... args) -> Unit {
+        JSObjectSetPropertyKey(args...);
+        return { };
+    };
+
+    auto result = performPropertyOperation<Unit>(stringSetProperty, jsValueSetProperty, self, key, objectToValue(_context, value), kJSPropertyAttributeNone);
+    if (!result) {
+        [_context notifyException:result.error()];
         return;
     }
 }
 
-- (BOOL)deleteProperty:(NSString *)propertyName
+- (BOOL)deleteProperty:(JSValuePropertyKeyType)key
 {
-    JSValueRef exception = 0;
-    JSObjectRef object = JSValueToObject([_context JSGlobalContextRef], m_value, &exception);
-    if (exception)
-        return [_context boolFromNotifyException:exception];
-
-    JSStringRef name = JSStringCreateWithCFString((__bridge CFStringRef)propertyName);
-    BOOL result = JSObjectDeleteProperty([_context JSGlobalContextRef], object, name, &exception);
-    JSStringRelease(name);
-    if (exception)
-        return [_context boolFromNotifyException:exception];
-
-    return result;
+    Expected<BOOL, JSValueRef> result = performPropertyOperation<BOOL>(JSObjectDeleteProperty, JSObjectDeletePropertyKey, self, key);
+    if (!result)
+        return [_context boolFromNotifyException:result.error()];
+    return result.value();
 }
 
-- (BOOL)hasProperty:(NSString *)propertyName
+- (BOOL)hasProperty:(JSValuePropertyKeyType)key
 {
-    JSValueRef exception = 0;
-    JSObjectRef object = JSValueToObject([_context JSGlobalContextRef], m_value, &exception);
-    if (exception)
-        return [_context boolFromNotifyException:exception];
+    // The C-api doesn't return an exception value for the string version of has property.
+    auto stringHasProperty = [] (JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef*) -> BOOL {
+        return JSObjectHasProperty(ctx, object, propertyName);
+    };
 
-    JSStringRef name = JSStringCreateWithCFString((__bridge CFStringRef)propertyName);
-    BOOL result = JSObjectHasProperty([_context JSGlobalContextRef], object, name);
-    JSStringRelease(name);
-    return result;
+    Expected<BOOL, JSValueRef> result = performPropertyOperation<BOOL>(stringHasProperty, JSObjectHasPropertyKey, self, key);
+    if (!result)
+        return [_context boolFromNotifyException:result.error()];
+    return result.value();
 }
 
-- (void)defineProperty:(NSString *)property descriptor:(id)descriptor
+- (void)defineProperty:(JSValuePropertyKeyType)key descriptor:(id)descriptor
 {
-    [[_context globalObject][@"Object"] invokeMethod:@"defineProperty" withArguments:@[ self, property, descriptor ]];
+    [[_context globalObject][@"Object"] invokeMethod:@"defineProperty" withArguments:@[ self, key, descriptor ]];
 }
 
 - (JSValue *)valueAtIndex:(NSUInteger)index
@@ -372,6 +389,11 @@
     return JSValueIsObject([_context JSGlobalContextRef], m_value);
 }
 
+- (BOOL)isSymbol
+{
+    return JSValueIsSymbol([_context JSGlobalContextRef], m_value);
+}
+
 - (BOOL)isArray
 {
     return JSValueIsArray([_context JSGlobalContextRef], m_value);
@@ -554,13 +576,7 @@
 
 - (JSValue *)objectForKeyedSubscript:(id)key
 {
-    if (![key isKindOfClass:[NSString class]]) {
-        key = [[JSValue valueWithObject:key inContext:_context] toString];
-        if (!key)
-            return [JSValue valueWithUndefinedInContext:_context];
-    }
-
-    return [self valueForProperty:(NSString *)key];
+    return [self valueForProperty:key];
 }
 
 - (JSValue *)objectAtIndexedSubscript:(NSUInteger)index
@@ -568,15 +584,9 @@
     return [self valueAtIndex:index];
 }
 
-- (void)setObject:(id)object forKeyedSubscript:(NSObject <NSCopying> *)key
+- (void)setObject:(id)object forKeyedSubscript:(id)key
 {
-    if (![key isKindOfClass:[NSString class]]) {
-        key = [[JSValue valueWithObject:key inContext:_context] toString];
-        if (!key)
-            return;
-    }
-
-    [self setValue:object forProperty:(NSString *)key];
+    [self setValue:object forProperty:key];
 }
 
 - (void)setObject:(id)object atIndexedSubscript:(NSUInteger)index

Modified: trunk/Source/_javascript_Core/API/JSValueRef.cpp (234226 => 234227)


--- trunk/Source/_javascript_Core/API/JSValueRef.cpp	2018-07-26 01:29:11 UTC (rev 234226)
+++ trunk/Source/_javascript_Core/API/JSValueRef.cpp	2018-07-26 02:32:25 UTC (rev 234227)
@@ -86,6 +86,8 @@
         return kJSTypeNumber;
     if (jsValue.isString())
         return kJSTypeString;
+    if (jsValue.isSymbol())
+        return kJSTypeSymbol;
     ASSERT(jsValue.isObject());
     return kJSTypeObject;
 }
@@ -162,6 +164,18 @@
     return toJS(exec, value).isObject();
 }
 
+bool JSValueIsSymbol(JSContextRef ctx, JSValueRef value)
+{
+    if (!ctx) {
+        ASSERT_NOT_REACHED();
+        return false;
+    }
+    ExecState* exec = toJS(ctx);
+    JSLockHolder locker(exec);
+
+    return toJS(exec, value).isSymbol();
+}
+
 bool JSValueIsArray(JSContextRef ctx, JSValueRef value)
 {
     if (!ctx) {
@@ -320,6 +334,22 @@
     return toRef(exec, jsNumber(purifyNaN(value)));
 }
 
+JSValueRef JSValueMakeSymbol(JSContextRef ctx, JSStringRef description)
+{
+    if (!ctx) {
+        ASSERT_NOT_REACHED();
+        return nullptr;
+    }
+    ExecState* exec = toJS(ctx);
+    JSLockHolder locker(exec);
+    auto scope = DECLARE_CATCH_SCOPE(exec->vm());
+
+    JSString* jsDescription = jsString(exec, description ? description->string() : String());
+    RETURN_IF_EXCEPTION(scope, nullptr);
+
+    return toRef(exec, Symbol::create(exec, jsDescription));
+}
+
 JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string)
 {
     if (!ctx) {

Modified: trunk/Source/_javascript_Core/API/JSValueRef.h (234226 => 234227)


--- trunk/Source/_javascript_Core/API/JSValueRef.h	2018-07-26 01:29:11 UTC (rev 234226)
+++ trunk/Source/_javascript_Core/API/JSValueRef.h	2018-07-26 02:32:25 UTC (rev 234227)
@@ -42,6 +42,7 @@
 @constant     kJSTypeNumber     A primitive number value.
 @constant     kJSTypeString     A primitive string value.
 @constant     kJSTypeObject     An object value (meaning that this JSValueRef is a JSObjectRef).
+@constant     kJSTypeSymbol     A primitive symbol value.
 */
 typedef enum {
     kJSTypeUndefined,
@@ -49,7 +50,8 @@
     kJSTypeBoolean,
     kJSTypeNumber,
     kJSTypeString,
-    kJSTypeObject
+    kJSTypeObject,
+    kJSTypeSymbol JSC_API_AVAILABLE(macosx(JSC_MAC_TBA), ios(JSC_IOS_TBA))
 } JSType;
 
 /*!
@@ -80,7 +82,7 @@
     kJSTypedArrayTypeFloat64Array,
     kJSTypedArrayTypeArrayBuffer,
     kJSTypedArrayTypeNone,
-} JSTypedArrayType CF_ENUM_AVAILABLE(10_12, 10_0);
+} JSTypedArrayType JSC_API_AVAILABLE(macosx(10.12), ios(10.0));
 
 #ifdef __cplusplus
 extern "C" {
@@ -151,6 +153,16 @@
 
 /*!
 @function
+@abstract       Tests whether a _javascript_ value's type is the symbol type.
+@param ctx      The execution context to use.
+@param value    The JSValue to test.
+@result         true if value's type is the symbol type, otherwise false.
+*/
+JS_EXPORT bool JSValueIsSymbol(JSContextRef ctx, JSValueRef value) JSC_API_AVAILABLE(macosx(JSC_MAC_TBA), ios(JSC_IOS_TBA));
+
+
+/*!
+@function
 @abstract Tests whether a _javascript_ value is an object with a given class in its class chain.
 @param ctx The execution context to use.
 @param value The JSValue to test.
@@ -166,7 +178,7 @@
 @param value    The JSValue to test.
 @result         true if value is an array, otherwise false.
 */
-JS_EXPORT bool JSValueIsArray(JSContextRef ctx, JSValueRef value) CF_AVAILABLE(10_11, 9_0);
+JS_EXPORT bool JSValueIsArray(JSContextRef ctx, JSValueRef value) JSC_API_AVAILABLE(macosx(10.11), ios(9.0));
 
 /*!
 @function
@@ -175,7 +187,7 @@
 @param value    The JSValue to test.
 @result         true if value is a date, otherwise false.
 */
-JS_EXPORT bool JSValueIsDate(JSContextRef ctx, JSValueRef value) CF_AVAILABLE(10_11, 9_0);
+JS_EXPORT bool JSValueIsDate(JSContextRef ctx, JSValueRef value) JSC_API_AVAILABLE(macosx(10.11), ios(9.0));
 
 /*!
 @function
@@ -185,7 +197,7 @@
 @param exception    A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
 @result             A value of type JSTypedArrayType that identifies value's Typed Array type, or kJSTypedArrayTypeNone if the value is not a Typed Array object.
  */
-JS_EXPORT JSTypedArrayType JSValueGetTypedArrayType(JSContextRef ctx, JSValueRef value, JSValueRef* exception) CF_AVAILABLE(10_12, 10_0);
+JS_EXPORT JSTypedArrayType JSValueGetTypedArrayType(JSContextRef ctx, JSValueRef value, JSValueRef* exception) JSC_API_AVAILABLE(macosx(10.12), ios(10.0));
 
 /* Comparing values */
 
@@ -259,6 +271,15 @@
 
 /*!
 @function
+@abstract            Creates a _javascript_ value of the symbol type.
+@param ctx           The execution context to use.
+@param description   A description of the newly created symbol value.
+@result              A unique JSValue of the symbol type, whose description matches the one provided.
+*/
+JS_EXPORT JSValueRef JSValueMakeSymbol(JSContextRef ctx, JSStringRef description);
+
+/*!
+@function
 @abstract       Creates a _javascript_ value of the string type.
 @param ctx  The execution context to use.
 @param string   The JSString to assign to the newly created JSValue. The
@@ -276,7 +297,7 @@
  @param string   The JSString containing the JSON string to be parsed.
  @result         A JSValue containing the parsed value, or NULL if the input is invalid.
  */
-JS_EXPORT JSValueRef JSValueMakeFromJSONString(JSContextRef ctx, JSStringRef string) CF_AVAILABLE(10_7, 7_0);
+JS_EXPORT JSValueRef JSValueMakeFromJSONString(JSContextRef ctx, JSStringRef string) JSC_API_AVAILABLE(macosx(10.7), ios(7.0));
 
 /*!
  @function
@@ -287,7 +308,7 @@
  @param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
  @result         A JSString with the result of serialization, or NULL if an exception is thrown.
  */
-JS_EXPORT JSStringRef JSValueCreateJSONString(JSContextRef ctx, JSValueRef value, unsigned indent, JSValueRef* exception) CF_AVAILABLE(10_7, 7_0);
+JS_EXPORT JSStringRef JSValueCreateJSONString(JSContextRef ctx, JSValueRef value, unsigned indent, JSValueRef* exception) JSC_API_AVAILABLE(macosx(10.7), ios(7.0));
 
 /* Converting to primitive values */
 

Modified: trunk/Source/_javascript_Core/API/WebKitAvailability.h (234226 => 234227)


--- trunk/Source/_javascript_Core/API/WebKitAvailability.h	2018-07-26 01:29:11 UTC (rev 234226)
+++ trunk/Source/_javascript_Core/API/WebKitAvailability.h	2018-07-26 02:32:25 UTC (rev 234227)
@@ -69,15 +69,12 @@
 #endif /* !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED < 101100 */
 
 #if defined(BUILDING_GTK__)
-#undef CF_AVAILABLE
-#define CF_AVAILABLE(_mac, _ios)
-#undef CF_ENUM_AVAILABLE
-#define CF_ENUM_AVAILABLE(_mac, _ios)
+#undef JSC_API_AVAILABLE
+#define JSC_API_AVAILABLE(...)
 #endif
 
 #else
-#define CF_AVAILABLE(_mac, _ios)
-#define CF_ENUM_AVAILABLE(_mac, _ios)
+#define JSC_API_AVAILABLE(...)
 #endif
 
 #endif /* __WebKitAvailability__ */

Modified: trunk/Source/_javascript_Core/API/tests/CurrentThisInsideBlockGetterTest.mm (234226 => 234227)


--- trunk/Source/_javascript_Core/API/tests/CurrentThisInsideBlockGetterTest.mm	2018-07-26 01:29:11 UTC (rev 234226)
+++ trunk/Source/_javascript_Core/API/tests/CurrentThisInsideBlockGetterTest.mm	2018-07-26 02:32:25 UTC (rev 234227)
@@ -23,6 +23,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include "config.h"
 #include "CurrentThisInsideBlockGetterTest.h"
 
 #if JSC_OBJC_API_ENABLED

Modified: trunk/Source/_javascript_Core/API/tests/CustomGlobalObjectClassTest.c (234226 => 234227)


--- trunk/Source/_javascript_Core/API/tests/CustomGlobalObjectClassTest.c	2018-07-26 01:29:11 UTC (rev 234226)
+++ trunk/Source/_javascript_Core/API/tests/CustomGlobalObjectClassTest.c	2018-07-26 02:32:25 UTC (rev 234227)
@@ -23,6 +23,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include "config.h"
 #include "CustomGlobalObjectClassTest.h"
 
 #include <_javascript_Core/JSObjectRefPrivate.h>

Modified: trunk/Source/_javascript_Core/API/tests/DateTests.mm (234226 => 234227)


--- trunk/Source/_javascript_Core/API/tests/DateTests.mm	2018-07-26 01:29:11 UTC (rev 234226)
+++ trunk/Source/_javascript_Core/API/tests/DateTests.mm	2018-07-26 02:32:25 UTC (rev 234227)
@@ -23,6 +23,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#import "config.h"
 #import "DateTests.h"
 #import <Foundation/Foundation.h>
 

Modified: trunk/Source/_javascript_Core/API/tests/JSExportTests.mm (234226 => 234227)


--- trunk/Source/_javascript_Core/API/tests/JSExportTests.mm	2018-07-26 01:29:11 UTC (rev 234226)
+++ trunk/Source/_javascript_Core/API/tests/JSExportTests.mm	2018-07-26 02:32:25 UTC (rev 234227)
@@ -23,6 +23,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#import "config.h"
 #import "JSExportTests.h"
 
 #import <objc/runtime.h>

Modified: trunk/Source/_javascript_Core/API/tests/JSNode.c (234226 => 234227)


--- trunk/Source/_javascript_Core/API/tests/JSNode.c	2018-07-26 01:29:11 UTC (rev 234226)
+++ trunk/Source/_javascript_Core/API/tests/JSNode.c	2018-07-26 02:32:25 UTC (rev 234227)
@@ -23,7 +23,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
 
-#include <wtf/Platform.h>
+#include "config.h"
 
 #include "JSNode.h"
 #include "JSNodeList.h"

Modified: trunk/Source/_javascript_Core/API/tests/JSNodeList.c (234226 => 234227)


--- trunk/Source/_javascript_Core/API/tests/JSNodeList.c	2018-07-26 01:29:11 UTC (rev 234226)
+++ trunk/Source/_javascript_Core/API/tests/JSNodeList.c	2018-07-26 02:32:25 UTC (rev 234227)
@@ -23,7 +23,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
 
-#include <wtf/Platform.h>
+#include "config.h"
 
 #include "JSNode.h"
 #include "JSNodeList.h"

Modified: trunk/Source/_javascript_Core/API/tests/Node.c (234226 => 234227)


--- trunk/Source/_javascript_Core/API/tests/Node.c	2018-07-26 01:29:11 UTC (rev 234226)
+++ trunk/Source/_javascript_Core/API/tests/Node.c	2018-07-26 02:32:25 UTC (rev 234227)
@@ -23,7 +23,9 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
 
+#include "config.h"
 #include "Node.h"
+
 #include <stddef.h>
 #include <stdlib.h>
 

Modified: trunk/Source/_javascript_Core/API/tests/NodeList.c (234226 => 234227)


--- trunk/Source/_javascript_Core/API/tests/NodeList.c	2018-07-26 01:29:11 UTC (rev 234226)
+++ trunk/Source/_javascript_Core/API/tests/NodeList.c	2018-07-26 02:32:25 UTC (rev 234227)
@@ -23,6 +23,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
 
+#include "config.h"
 #include "NodeList.h"
 
 #include <stdlib.h>

Modified: trunk/Source/_javascript_Core/API/tests/minidom.c (234226 => 234227)


--- trunk/Source/_javascript_Core/API/tests/minidom.c	2018-07-26 01:29:11 UTC (rev 234226)
+++ trunk/Source/_javascript_Core/API/tests/minidom.c	2018-07-26 02:32:25 UTC (rev 234227)
@@ -24,7 +24,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
 
-#include <wtf/Platform.h>
+#include "config.h"
 
 #include "JSContextRef.h"
 #include "JSNode.h"

Modified: trunk/Source/_javascript_Core/API/tests/testapi.c (234226 => 234227)


--- trunk/Source/_javascript_Core/API/tests/testapi.c	2018-07-26 01:29:11 UTC (rev 234226)
+++ trunk/Source/_javascript_Core/API/tests/testapi.c	2018-07-26 02:32:25 UTC (rev 234227)
@@ -23,7 +23,8 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <wtf/Platform.h>
+#define ASSERT_DISABLED 0
+#include "config.h"
 
 #if USE(CF)
 #include "_javascript_Core.h"
@@ -44,7 +45,6 @@
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
-#define ASSERT_DISABLED 0
 #include <wtf/Assertions.h>
 
 #if OS(WINDOWS)
@@ -66,6 +66,8 @@
 void testObjectiveCAPI(void);
 #endif
 
+int testCAPIViaCpp(void);
+
 bool assertTrue(bool value, const char* message);
 
 static JSGlobalContextRef context;
@@ -1361,6 +1363,7 @@
 #if JSC_OBJC_API_ENABLED
     testObjectiveCAPI();
 #endif
+    RELEASE_ASSERT(!testCAPIViaCpp());
 
     const char *scriptPath = "testapi.js";
     if (argc > 1) {

Added: trunk/Source/_javascript_Core/API/tests/testapi.cpp (0 => 234227)


--- trunk/Source/_javascript_Core/API/tests/testapi.cpp	                        (rev 0)
+++ trunk/Source/_javascript_Core/API/tests/testapi.cpp	2018-07-26 02:32:25 UTC (rev 234227)
@@ -0,0 +1,395 @@
+/*
+ * Copyright (C) 2017 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 INC. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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.
+ */
+
+#include "config.h"
+
+#include "APICast.h"
+#include "JSCJSValueInlines.h"
+#include "JSObject.h"
+
+#include <_javascript_Core/_javascript_.h>
+#include <wtf/DataLog.h>
+#include <wtf/Expected.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/Vector.h>
+
+extern "C" int testCAPIViaCpp();
+
+class APIString {
+    WTF_MAKE_NONCOPYABLE(APIString);
+public:
+
+    APIString(const char* string)
+        : m_string(JSStringCreateWithUTF8CString(string))
+    {
+    }
+
+    ~APIString()
+    {
+        JSStringRelease(m_string);
+    }
+
+    operator JSStringRef() { return m_string; }
+
+private:
+    JSStringRef m_string;
+};
+
+class APIContext {
+    WTF_MAKE_NONCOPYABLE(APIContext);
+public:
+
+    APIContext()
+        : m_context(JSGlobalContextCreate(nullptr))
+    {
+        APIString print("print");
+        JSObjectRef printFunction = JSObjectMakeFunctionWithCallback(m_context, print, [] (JSContextRef ctx, JSObjectRef, JSObjectRef, size_t argumentCount, const JSValueRef arguments[], JSValueRef*) {
+
+            JSC::ExecState* exec = toJS(ctx);
+            for (unsigned i = 0; i < argumentCount; i++)
+                dataLog(toJS(exec, arguments[i]));
+            dataLogLn();
+            return JSValueMakeUndefined(ctx);
+        });
+
+        JSObjectSetProperty(m_context, JSContextGetGlobalObject(m_context), print, printFunction, kJSPropertyAttributeNone, nullptr);
+    }
+
+    ~APIContext()
+    {
+        JSGlobalContextRelease(m_context);
+    }
+
+    operator JSGlobalContextRef() { return m_context; }
+
+private:
+    JSGlobalContextRef m_context;
+};
+
+template<typename T>
+class APIVector : protected Vector<T> {
+    using Base = Vector<T>;
+public:
+    APIVector(APIContext& context)
+        : Base()
+        , m_context(context)
+    {
+    }
+
+    ~APIVector()
+    {
+        for (auto& value : *this)
+            JSValueUnprotect(m_context, value);
+    }
+
+    using Vector<T>::operator[];
+    using Vector<T>::size;
+    using Vector<T>::begin;
+    using Vector<T>::end;
+    using typename Vector<T>::iterator;
+
+    void append(T value)
+    {
+        JSValueProtect(m_context, value);
+        Base::append(WTFMove(value));
+    }
+
+private:
+    APIContext& m_context;
+};
+
+class TestAPI {
+public:
+    int run();
+private:
+
+    template<typename... Strings>
+    bool check(bool condition, Strings... message);
+
+    template<typename JSFunctor, typename APIFunctor>
+    void checkJSAndAPIMatch(const JSFunctor&, const APIFunctor&, const char* description);
+
+    // Helper methods.
+    using ScriptResult = Expected<JSValueRef, JSValueRef>;
+    ScriptResult evaluateScript(const char* script, JSObjectRef thisObject = nullptr);
+    template<typename... ArgumentTypes>
+    ScriptResult callFunction(const char* functionSource, ArgumentTypes... arguments);
+    template<typename... ArgumentTypes>
+    bool functionReturnsTrue(const char* functionSource, ArgumentTypes... arguments);
+
+    // Ways to make sets of interesting things.
+    APIVector<JSObjectRef> interestingObjects();
+    APIVector<JSValueRef> interestingKeys();
+
+    int failed { 0 };
+    APIContext context;
+};
+
+int testCAPIViaCpp()
+{
+    TestAPI tester;
+    return tester.run();
+}
+
+TestAPI::ScriptResult TestAPI::evaluateScript(const char* script, JSObjectRef thisObject)
+{
+    APIString scriptAPIString(script);
+    JSValueRef exception = nullptr;
+
+    JSValueRef result = JSEvaluateScript(context, scriptAPIString, thisObject, nullptr, 0, &exception);
+    if (exception)
+        return Unexpected<JSValueRef>(exception);
+    return ScriptResult(result);
+}
+
+template<typename... ArgumentTypes>
+TestAPI::ScriptResult TestAPI::callFunction(const char* functionSource, ArgumentTypes... arguments)
+{
+    JSValueRef function;
+    {
+        ScriptResult functionResult = evaluateScript(functionSource);
+        if (!functionResult)
+            return functionResult;
+        function = functionResult.value();
+    }
+
+    JSValueRef exception = nullptr;
+    if (JSObjectRef functionObject = JSValueToObject(context, function, &exception)) {
+        JSValueRef args[sizeof...(arguments)] { arguments... };
+        JSValueRef result = JSObjectCallAsFunction(context, functionObject, functionObject, sizeof...(arguments), args, &exception);
+        if (!exception)
+            return ScriptResult(result);
+    }
+
+    RELEASE_ASSERT(exception);
+    return Unexpected<JSValueRef>(exception);
+}
+
+template<typename... ArgumentTypes>
+bool TestAPI::functionReturnsTrue(const char* functionSource, ArgumentTypes... arguments)
+{
+    JSValueRef trueValue = JSValueMakeBoolean(context, true);
+    ScriptResult result = callFunction(functionSource, arguments...);
+    if (!result)
+        return false;
+    return JSValueIsStrictEqual(context, trueValue, result.value());
+}
+
+template<typename... Strings>
+bool TestAPI::check(bool condition, Strings... messages)
+{
+    if (!condition) {
+        dataLogLn(messages..., ": FAILED");
+        failed++;
+    } else
+        dataLogLn(messages..., ": PASSED");
+
+    return condition;
+}
+
+template<typename JSFunctor, typename APIFunctor>
+void TestAPI::checkJSAndAPIMatch(const JSFunctor& jsFunctor, const APIFunctor& apiFunctor, const char* description)
+{
+    JSValueRef exception = nullptr;
+    JSValueRef result = apiFunctor(&exception);
+    ScriptResult jsResult = jsFunctor();
+    if (!jsResult) {
+        check(exception, "JS and API calls should both throw an exception while ", description);
+        check(functionReturnsTrue("(function(a, b) { return a.constructor === b.constructor; })", exception, jsResult.error()), "JS and API calls should both throw the same exception while ", description);
+    } else {
+        check(!exception, "JS and API calls should both not throw an exception while ", description);
+        check(JSValueIsStrictEqual(context, result, jsResult.value()), "JS result and API calls should return the same value while ", description);
+    }
+}
+
+APIVector<JSObjectRef> TestAPI::interestingObjects()
+{
+    APIVector<JSObjectRef> result(context);
+    JSObjectRef array = JSValueToObject(context, evaluateScript(
+        "[{}, [], { [Symbol.iterator]: 1 }, new Date(), new String('str'), new Map(), new Set(), new WeakMap(), new WeakSet(), new Error(), new Number(42), new Boolean(), { get length() { throw new Error(); } }];").value(), nullptr);
+
+    APIString lengthString("length");
+    unsigned length = JSValueToNumber(context, JSObjectGetProperty(context, array, lengthString, nullptr), nullptr);
+    for (unsigned i = 0; i < length; i++) {
+        JSObjectRef object = JSValueToObject(context, JSObjectGetPropertyAtIndex(context, array, i, nullptr), nullptr);
+        ASSERT(object);
+        result.append(object);
+    }
+
+    return result;
+}
+
+APIVector<JSValueRef> TestAPI::interestingKeys()
+{
+    APIVector<JSValueRef> result(context);
+    JSObjectRef array = JSValueToObject(context, evaluateScript("[{}, [], 1, Symbol.iterator, 'length']").value(), nullptr);
+
+    APIString lengthString("length");
+    unsigned length = JSValueToNumber(context, JSObjectGetProperty(context, array, lengthString, nullptr), nullptr);
+    for (unsigned i = 0; i < length; i++) {
+        JSValueRef value = JSObjectGetPropertyAtIndex(context, array, i, nullptr);
+        ASSERT(value);
+        result.append(value);
+    }
+
+    return result;
+}
+
+int TestAPI::run()
+{
+    dataLogLn("Starting C-API tests in C++");
+    const char* isSymbolFunction = "(function isSymbol(symbol) { return typeof(symbol) === 'symbol'; })";
+    const char* getFunction = "(function get(object, key) { return object[key]; })";
+    const char* setFunction = "(function set(object, key, value) { object[key] = value; })";
+    const char* hasFunction = "(function has(object, key) { return key in object; })";
+    const char* deleteFunction = "(function del(object, key) { return delete object[key]; })";
+
+    JSC::ExecState* exec = toJS(context);
+
+    {
+        // Can't call Symbol as a constructor since it's not subclassable.
+        auto result = evaluateScript("Symbol('dope');");
+        check(JSValueGetType(context, result.value()) == kJSTypeSymbol, "dope get type is a symbol");
+        check(JSValueIsSymbol(context, result.value()), "dope is a symbol");
+    }
+
+    {
+        APIString description("dope");
+        JSValueRef symbol = JSValueMakeSymbol(context, description);
+        check(functionReturnsTrue(isSymbolFunction, symbol), "JSValueMakeSymbol makes a symbol value");
+    }
+
+    {
+        auto objects = interestingObjects();
+        auto keys = interestingKeys();
+
+        for (auto& object : objects) {
+            dataLogLn("\nnext object: ", toJS(exec, object));
+            for (auto& key : keys) {
+                dataLogLn("Using key: ", toJS(exec, key));
+                checkJSAndAPIMatch(
+                    [&] {
+                        return callFunction(getFunction, object, key);
+                    }, [&] (JSValueRef* exception) {
+                        return JSObjectGetPropertyKey(context, object, key, exception);
+                    }, "checking get property keys");
+            }
+        }
+    }
+
+    {
+        auto jsObjects = interestingObjects();
+        auto apiObjects = interestingObjects();
+        auto keys = interestingKeys();
+
+        JSValueRef theAnswer = JSValueMakeNumber(context, 42);
+        for (size_t i = 0; i < jsObjects.size(); i++) {
+            for (auto& key : keys) {
+                JSObjectRef jsObject = jsObjects[i];
+                JSObjectRef apiObject = apiObjects[i];
+                checkJSAndAPIMatch(
+                    [&] {
+                        return callFunction(setFunction, jsObject, key, theAnswer);
+                    } , [&] (JSValueRef* exception) {
+                        JSObjectSetPropertyKey(context, apiObject, key, theAnswer, kJSPropertyAttributeNone, exception);
+                        return JSValueMakeUndefined(context);
+                    }, "setting property keys to the answer");
+                // Check get is the same on API object.
+                checkJSAndAPIMatch(
+                    [&] {
+                        return callFunction(getFunction, apiObject, key);
+                    }, [&] (JSValueRef* exception) {
+                        return JSObjectGetPropertyKey(context, apiObject, key, exception);
+                    }, "getting property keys from API objects");
+                // Check get is the same on respective objects.
+                checkJSAndAPIMatch(
+                    [&] {
+                        return callFunction(getFunction, jsObject, key);
+                    }, [&] (JSValueRef* exception) {
+                        return JSObjectGetPropertyKey(context, apiObject, key, exception);
+                    }, "getting property keys from respective objects");
+            }
+        }
+    }
+
+    {
+        auto objects = interestingObjects();
+        auto keys = interestingKeys();
+
+        JSValueRef theAnswer = JSValueMakeNumber(context, 42);
+        for (auto& object : objects) {
+            dataLogLn("\nNext object: ", toJS(exec, object));
+            for (auto& key : keys) {
+                dataLogLn("Using key: ", toJS(exec, key));
+                checkJSAndAPIMatch(
+                    [&] {
+                        return callFunction(hasFunction, object, key);
+                    }, [&] (JSValueRef* exception) {
+                        return JSValueMakeBoolean(context, JSObjectHasPropertyKey(context, object, key, exception));
+                    }, "checking has property keys unset");
+
+                check(!!callFunction(setFunction, object, key, theAnswer), "set property to the answer");
+
+                checkJSAndAPIMatch(
+                    [&] {
+                        return callFunction(hasFunction, object, key);
+                    }, [&] (JSValueRef* exception) {
+                        return JSValueMakeBoolean(context, JSObjectHasPropertyKey(context, object, key, exception));
+                    }, "checking has property keys set");
+            }
+        }
+    }
+
+    {
+        auto objects = interestingObjects();
+        auto keys = interestingKeys();
+
+        JSValueRef theAnswer = JSValueMakeNumber(context, 42);
+        for (auto& object : objects) {
+            dataLogLn("\nNext object: ", toJS(exec, object));
+            for (auto& key : keys) {
+                dataLogLn("Using key: ", toJS(exec, key));
+                checkJSAndAPIMatch(
+                    [&] {
+                        return callFunction(deleteFunction, object, key);
+                    }, [&] (JSValueRef* exception) {
+                        return JSValueMakeBoolean(context, JSObjectDeletePropertyKey(context, object, key, exception));
+                    }, "checking has property keys unset");
+
+                check(!!callFunction(setFunction, object, key, theAnswer), "set property to the answer");
+
+                checkJSAndAPIMatch(
+                    [&] {
+                        return callFunction(deleteFunction, object, key);
+                    }, [&] (JSValueRef* exception) {
+                        return JSValueMakeBoolean(context, JSObjectDeletePropertyKey(context, object, key, exception));
+                    }, "checking has property keys set");
+            }
+        }
+    }
+
+    dataLogLn("C-API tests in C++ had ", failed, " failures");
+    return failed;
+}

Modified: trunk/Source/_javascript_Core/API/tests/testapi.mm (234226 => 234227)


--- trunk/Source/_javascript_Core/API/tests/testapi.mm	2018-07-26 01:29:11 UTC (rev 234226)
+++ trunk/Source/_javascript_Core/API/tests/testapi.mm	2018-07-26 02:32:25 UTC (rev 234227)
@@ -23,6 +23,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#import "config.h"
 #import "JSExportMacros.h"
 #import <_javascript_Core/_javascript_Core.h>
 
@@ -42,6 +43,7 @@
 #import <vector>
 #import <wtf/MemoryFootprint.h>
 #import <wtf/Optional.h>
+#import <wtf/DataLog.h>
 
 extern "C" void JSSynchronousGarbageCollectForDebugging(JSContextRef);
 extern "C" void JSSynchronousEdenCollectForDebugging(JSContextRef);
@@ -627,6 +629,105 @@
     }
 
     @autoreleasepool {
+        JSContext *context = [[JSContext alloc] init];
+        JSValue *symbol = [context evaluateScript:@"Symbol('dope');"];
+        JSValue *notSymbol = [context evaluateScript:@"'dope'"];
+        checkResult(@"Should be a symbol value", symbol.isSymbol);
+        checkResult(@"Should not be a symbol value", !notSymbol.isSymbol);
+    }
+
+    @autoreleasepool {
+        JSContext *context = [[JSContext alloc] init];
+        JSValue *symbol = [JSValue valueWithNewSymbolFromDescription:@"dope" inContext:context];
+        checkResult(@"Should be a created from Obj-C", symbol.isSymbol);
+    }
+
+    @autoreleasepool {
+        JSContext *context = [[JSContext alloc] init];
+        JSValue *arrayIterator = [context evaluateScript:@"Array.prototype[Symbol.iterator]"];
+        JSValue *iteratorSymbol = context[@"Symbol"][@"iterator"];
+        JSValue *array = [JSValue valueWithNewArrayInContext:context];
+        checkResult(@"Looking up by subscript with symbol should work", [array[iteratorSymbol] isEqual:arrayIterator]);
+        checkResult(@"Looking up by method with symbol should work", [[array valueForProperty:iteratorSymbol] isEqual:arrayIterator]);
+    }
+
+    @autoreleasepool {
+        JSContext *context = [[JSContext alloc] init];
+        JSValue *iteratorSymbol = context[@"Symbol"][@"iterator"];
+        JSValue *object = [JSValue valueWithNewObjectInContext:context];
+        JSValue *theAnswer = [JSValue valueWithUInt32:42 inContext:context];
+        object[iteratorSymbol] = theAnswer;
+        checkResult(@"Setting by subscript with symbol should work", [object[iteratorSymbol] isEqual:theAnswer]);
+    }
+
+    @autoreleasepool {
+        JSContext *context = [[JSContext alloc] init];
+        JSValue *iteratorSymbol = context[@"Symbol"][@"iterator"];
+        JSValue *object = [JSValue valueWithNewObjectInContext:context];
+        JSValue *theAnswer = [JSValue valueWithUInt32:42 inContext:context];
+        [object setValue:theAnswer forProperty:iteratorSymbol];
+        checkResult(@"Setting by method with symbol should work", [object[iteratorSymbol] isEqual:theAnswer]);
+    }
+
+    @autoreleasepool {
+        JSContext *context = [[JSContext alloc] init];
+        JSValue *iteratorSymbol = context[@"Symbol"][@"iterator"];
+        JSValue *object = [JSValue valueWithNewObjectInContext:context];
+        JSValue *theAnswer = [JSValue valueWithUInt32:42 inContext:context];
+        object[iteratorSymbol] = theAnswer;
+        checkResult(@"has property with symbol should work", [object hasProperty:iteratorSymbol]);
+    }
+
+    @autoreleasepool {
+        JSContext *context = [[JSContext alloc] init];
+        JSValue *iteratorSymbol = context[@"Symbol"][@"iterator"];
+        JSValue *object = [JSValue valueWithNewObjectInContext:context];
+        JSValue *theAnswer = [JSValue valueWithUInt32:42 inContext:context];
+        checkResult(@"delete property with symbol should work without property", [object deleteProperty:iteratorSymbol]);
+        object[iteratorSymbol] = theAnswer;
+        checkResult(@"delete property with symbol should work with property", [object deleteProperty:iteratorSymbol]);
+        checkResult(@"delete should be false with non-configurable property", ![context[@"Array"] deleteProperty:@"prototype"]);
+    }
+
+    @autoreleasepool {
+        JSContext *context = [[JSContext alloc] init];
+        JSValue *object = [JSValue valueWithNewObjectInContext:context];
+        NSObject *objCObject = [[NSObject alloc] init];
+        JSValue *result = object[objCObject];
+        checkResult(@"getting a non-convertable object should return undefined", [result isUndefined]);
+        object[objCObject] = @(1);
+        result = object[objCObject];
+        checkResult(@"getting a non-convertable object should return the stored value", [result toUInt32] == 1);
+    }
+
+    @autoreleasepool {
+        JSContext *context = [[JSContext alloc] init];
+        JSValue *object = [JSValue valueWithNewObjectInContext:context];
+        JSValue *iteratorSymbol = context[@"Symbol"][@"iterator"];
+        object[@"value"] = @(1);
+        context[@"object"] = object;
+
+        object[iteratorSymbol] = ^{
+            JSValue *result = [JSValue valueWithNewObjectInContext:context];
+            result[@"object"] = [JSContext currentThis];
+            result[@"next"] = ^{
+                JSValue *result = [JSValue valueWithNewObjectInContext:context];
+                JSValue *value = [JSContext currentThis][@"object"][@"value"];
+                [[JSContext currentThis][@"object"] deleteProperty:@"value"];
+                result[@"value"] = value;
+                result[@"done"] = [JSValue valueWithBool:[value isUndefined] inContext:context];
+                return result;
+            };
+            return result;
+        };
+
+
+        JSValue *count = [context evaluateScript:@"let count = 0; for (let v of object) { if (v !== 1) throw new Error(); count++; } count;"];
+        checkResult(@"iterator should not throw", ![context exception]);
+        checkResult(@"iteration count should be 1", [count toUInt32] == 1);
+    }
+
+    @autoreleasepool {
         JSCollection* myPrivateProperties = [[JSCollection alloc] init];
 
         @autoreleasepool {

Modified: trunk/Source/_javascript_Core/ChangeLog (234226 => 234227)


--- trunk/Source/_javascript_Core/ChangeLog	2018-07-26 01:29:11 UTC (rev 234226)
+++ trunk/Source/_javascript_Core/ChangeLog	2018-07-26 02:32:25 UTC (rev 234227)
@@ -1,3 +1,105 @@
+2018-07-25  Keith Miller  <keith_mil...@apple.com>
+
+        [JSC API] We should support the symbol type in our C/Obj-C API
+        https://bugs.webkit.org/show_bug.cgi?id=175836
+
+        Reviewed by Filip Pizlo.
+
+        This patch makes the following API additions:
+        1) Test if a JSValue/JSValueRef is a symbol via any of the methods API are able to test for the types of other JSValues.
+        2) Create a symbol on both APIs.
+        3) Get/Set/Delete/Define property now take ids in the Obj-C API.
+        4) Add Get/Set/Delete in the C API.
+
+        We can do 3 because it is both binary and source compatable with
+        the existing API. I added (4) because the current property access
+        APIs only have the ability to get Strings. It was possible to
+        merge symbols into JSStringRef but that felt confusing and exposes
+        implementation details of our engine. The new functions match the
+        same meaning that they have in JS, thus should be forward
+        compatible with any future language extensions.
+
+        Lastly, this patch adds the same availability preproccessing phase
+        in WebCore to _javascript_Core, which enables TBA features for
+        testing on previous releases.
+
+        * API/APICast.h:
+        * API/JSBasePrivate.h:
+        * API/JSContext.h:
+        * API/JSContextPrivate.h:
+        * API/JSContextRef.h:
+        * API/JSContextRefInternal.h:
+        * API/JSContextRefPrivate.h:
+        * API/JSManagedValue.h:
+        * API/JSObjectRef.cpp:
+        (JSObjectHasPropertyKey):
+        (JSObjectGetPropertyKey):
+        (JSObjectSetPropertyKey):
+        (JSObjectDeletePropertyKey):
+        * API/JSObjectRef.h:
+        * API/JSRemoteInspector.h:
+        * API/JSTypedArray.h:
+        * API/JSValue.h:
+        * API/JSValue.mm:
+        (+[JSValue valueWithNewSymbolFromDescription:inContext:]):
+        (performPropertyOperation):
+        (-[JSValue valueForProperty:valueForProperty:]):
+        (-[JSValue setValue:forProperty:setValue:forProperty:]):
+        (-[JSValue deleteProperty:deleteProperty:]):
+        (-[JSValue hasProperty:hasProperty:]):
+        (-[JSValue defineProperty:descriptor:defineProperty:descriptor:]):
+        (-[JSValue isSymbol]):
+        (-[JSValue objectForKeyedSubscript:]):
+        (-[JSValue setObject:forKeyedSubscript:]):
+        (-[JSValue valueForProperty:]): Deleted.
+        (-[JSValue setValue:forProperty:]): Deleted.
+        (-[JSValue deleteProperty:]): Deleted.
+        (-[JSValue hasProperty:]): Deleted.
+        (-[JSValue defineProperty:descriptor:]): Deleted.
+        * API/JSValueRef.cpp:
+        (JSValueGetType):
+        (JSValueIsSymbol):
+        (JSValueMakeSymbol):
+        * API/JSValueRef.h:
+        * API/WebKitAvailability.h:
+        * API/tests/CurrentThisInsideBlockGetterTest.mm:
+        * API/tests/CustomGlobalObjectClassTest.c:
+        * API/tests/DateTests.mm:
+        * API/tests/JSExportTests.mm:
+        * API/tests/JSNode.c:
+        * API/tests/JSNodeList.c:
+        * API/tests/Node.c:
+        * API/tests/NodeList.c:
+        * API/tests/minidom.c:
+        * API/tests/testapi.c:
+        (main):
+        * API/tests/testapi.cpp: Added.
+        (APIString::APIString):
+        (APIString::~APIString):
+        (APIString::operator JSStringRef):
+        (APIContext::APIContext):
+        (APIContext::~APIContext):
+        (APIContext::operator JSGlobalContextRef):
+        (APIVector::APIVector):
+        (APIVector::~APIVector):
+        (APIVector::append):
+        (testCAPIViaCpp):
+        (TestAPI::evaluateScript):
+        (TestAPI::callFunction):
+        (TestAPI::functionReturnsTrue):
+        (TestAPI::check):
+        (TestAPI::checkJSAndAPIMatch):
+        (TestAPI::interestingObjects):
+        (TestAPI::interestingKeys):
+        (TestAPI::run):
+        * API/tests/testapi.mm:
+        (testObjectiveCAPIMain):
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * config.h:
+        * postprocess-headers.sh:
+        * shell/CMakeLists.txt:
+        * testmem/testmem.mm:
+
 2018-07-25  Andy VanWagoner  <andy@vanwagoner.family>
 
         [INTL] Call Typed Array elements toLocaleString with locale and options

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (234226 => 234227)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2018-07-26 01:29:11 UTC (rev 234226)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2018-07-26 02:32:25 UTC (rev 234227)
@@ -1040,8 +1040,9 @@
 		53E777E41E92E265007CBEC4 /* WasmModuleInformation.h in Headers */ = {isa = PBXBuildFile; fileRef = 53E777E21E92E265007CBEC4 /* WasmModuleInformation.h */; };
 		53E9E0AC1EAE83DF00FEE251 /* WasmMachineThreads.h in Headers */ = {isa = PBXBuildFile; fileRef = 53E9E0AA1EAE83DE00FEE251 /* WasmMachineThreads.h */; };
 		53E9E0AF1EAEC45700FEE251 /* WasmTierUpCount.h in Headers */ = {isa = PBXBuildFile; fileRef = 53E9E0AE1EAEC45700FEE251 /* WasmTierUpCount.h */; settings = {ATTRIBUTES = (Private, ); }; };
-		53F11F41209138D700E411A7 /* JSImmutableButterfly.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F11F40209138D700E411A7 /* JSImmutableButterfly.h */; };
-		53F40E851D58F9770099A1B6 /* WasmSections.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F40E841D58F9770099A1B6 /* WasmSections.h */; };
+                53F11F41209138D700E411A7 /* JSImmutableButterfly.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F11F40209138D700E411A7 /* JSImmutableButterfly.h */; };
+                53EAFE2F208DFAB4007D524B /* testapi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 531D4E191F59CDD200EC836C /* testapi.cpp */; };
+                53F40E851D58F9770099A1B6 /* WasmSections.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F40E841D58F9770099A1B6 /* WasmSections.h */; };
 		53F40E8B1D5901BB0099A1B6 /* WasmFunctionParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F40E8A1D5901BB0099A1B6 /* WasmFunctionParser.h */; };
 		53F40E8D1D5901F20099A1B6 /* WasmParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F40E8C1D5901F20099A1B6 /* WasmParser.h */; };
 		53F40E931D5A4AB30099A1B6 /* WasmB3IRGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F40E921D5A4AB30099A1B6 /* WasmB3IRGenerator.h */; };
@@ -3305,6 +3306,7 @@
 		5311BD491EA581E500525281 /* WasmOMGPlan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmOMGPlan.h; sourceTree = "<group>"; };
 		531374BC1D5CE67600AF7A0B /* WasmPlan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmPlan.h; sourceTree = "<group>"; };
 		531374BE1D5CE95000AF7A0B /* WasmPlan.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmPlan.cpp; sourceTree = "<group>"; };
+		531D4E191F59CDD200EC836C /* testapi.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = testapi.cpp; path = API/tests/testapi.cpp; sourceTree = "<group>"; };
 		533B15DE1DC7F463004D500A /* WasmOps.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmOps.h; sourceTree = "<group>"; };
 		5341FC6F1DAC33E500E7E4D7 /* B3WasmBoundsCheckValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3WasmBoundsCheckValue.cpp; path = b3/B3WasmBoundsCheckValue.cpp; sourceTree = "<group>"; };
 		5341FC711DAC343C00E7E4D7 /* B3WasmBoundsCheckValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3WasmBoundsCheckValue.h; path = b3/B3WasmBoundsCheckValue.h; sourceTree = "<group>"; };
@@ -3475,7 +3477,6 @@
 		53917E7A1B7906E4000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGenericTypedArrayViewPrototypeFunctions.h; sourceTree = "<group>"; };
 		53917E7C1B791106000EBD33 /* JSTypedArrayViewPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTypedArrayViewPrototype.h; sourceTree = "<group>"; };
 		53917E831B791CB8000EBD33 /* TypedArrayPrototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; name = TypedArrayPrototype.js; path = builtins/TypedArrayPrototype.js; sourceTree = SOURCE_ROOT; };
-		539EB0711D553DF800C82EF7 /* testWasm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = testWasm.cpp; sourceTree = "<group>"; };
 		539FB8B91C99DA7C00940FA1 /* JSArrayInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSArrayInlines.h; sourceTree = "<group>"; };
 		53B0BE331E561AC900A8FC29 /* GetterSetterAccessCase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GetterSetterAccessCase.cpp; sourceTree = "<group>"; };
 		53B0BE351E561B0900A8FC29 /* ProxyableAccessCase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProxyableAccessCase.cpp; sourceTree = "<group>"; };
@@ -5467,10 +5468,10 @@
 				FEB51F6B1A97B688001F921C /* Regress141809.mm */,
 				FECB8B291D25CABB006F2463 /* testapi-function-overrides.js */,
 				14BD5A2D0A3E91F600BAF59C /* testapi.c */,
+				531D4E191F59CDD200EC836C /* testapi.cpp */,
 				14D857740A4696C80032146C /* testapi.js */,
 				86D22219167EF9440024C804 /* testapi.mm */,
 				651122E5140469BA002B101D /* testRegExp.cpp */,
-				539EB0711D553DF800C82EF7 /* testWasm.cpp */,
 				534902821C7242C80012BCB8 /* TypedArrayCTest.cpp */,
 				534902831C7242C80012BCB8 /* TypedArrayCTest.h */,
 			);
@@ -8982,8 +8983,8 @@
 				0FB467801FDDA6F1003FCB09 /* IsoCellSet.h in Headers */,
 				0FB467811FDDA6F7003FCB09 /* IsoCellSetInlines.h in Headers */,
 				0FDCE12D1FAFB4E5006F3901 /* IsoSubspace.h in Headers */,
-				0FD2FD9520B52BE200F09441 /* IsoSubspaceInlines.h in Headers */,
-				0F5E0FE72086AD480097F0DE /* IsoSubspacePerVM.h in Headers */,
+                                0FD2FD9520B52BE200F09441 /* IsoSubspaceInlines.h in Headers */,
+                                0F5E0FE72086AD480097F0DE /* IsoSubspacePerVM.h in Headers */,
 				8B9F6D561D5912FA001C739F /* IterationKind.h in Headers */,
 				FE4D55B81AE716CA0052E459 /* IterationStatus.h in Headers */,
 				70113D4C1A8DB093003848C4 /* IteratorOperations.h in Headers */,
@@ -10203,6 +10204,7 @@
 				65570F5A1AA4C3EA009B3C23 /* Regress141275.mm in Sources */,
 				FEB51F6C1A97B688001F921C /* Regress141809.mm in Sources */,
 				1440F6100A4F85670005F061 /* testapi.c in Sources */,
+				53EAFE2F208DFAB4007D524B /* testapi.cpp in Sources */,
 				86D2221A167EF9440024C804 /* testapi.mm in Sources */,
 				534902851C7276B70012BCB8 /* TypedArrayCTest.cpp in Sources */,
 			);
@@ -10670,6 +10672,10 @@
 			isa = XCBuildConfiguration;
 			baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */;
 			buildSettings = {
+				HEADER_SEARCH_PATHS = (
+					"\"$(_javascript_CORE_FRAMEWORKS_DIR)/_javascript_Core.framework/PrivateHeaders\"",
+					"$(inherited)",
+				);
 			};
 			name = Debug;
 		};
@@ -10677,6 +10683,10 @@
 			isa = XCBuildConfiguration;
 			baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */;
 			buildSettings = {
+				HEADER_SEARCH_PATHS = (
+					"\"$(_javascript_CORE_FRAMEWORKS_DIR)/_javascript_Core.framework/PrivateHeaders\"",
+					"$(inherited)",
+				);
 			};
 			name = Release;
 		};
@@ -10684,6 +10694,10 @@
 			isa = XCBuildConfiguration;
 			baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */;
 			buildSettings = {
+				HEADER_SEARCH_PATHS = (
+					"\"$(_javascript_CORE_FRAMEWORKS_DIR)/_javascript_Core.framework/PrivateHeaders\"",
+					"$(inherited)",
+				);
 			};
 			name = Production;
 		};
@@ -11008,6 +11022,10 @@
 			isa = XCBuildConfiguration;
 			baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */;
 			buildSettings = {
+				HEADER_SEARCH_PATHS = (
+					"\"$(_javascript_CORE_FRAMEWORKS_DIR)/_javascript_Core.framework/PrivateHeaders\"",
+					"$(inherited)",
+				);
 			};
 			name = Profiling;
 		};

Modified: trunk/Source/_javascript_Core/config.h (234226 => 234227)


--- trunk/Source/_javascript_Core/config.h	2018-07-26 01:29:11 UTC (rev 234226)
+++ trunk/Source/_javascript_Core/config.h	2018-07-26 02:32:25 UTC (rev 234227)
@@ -23,6 +23,11 @@
 #include "cmakeconfig.h"
 #endif
 
+#define JSC_API_AVAILABLE(...)
+// Use zero since it will be less than any possible version number.
+#define JSC_MAC_VERSION_TBA 0
+#define JSC_IOS_VERSION_TBA 0
+
 #include "JSExportMacros.h"
 
 #ifdef __cplusplus

Modified: trunk/Source/_javascript_Core/postprocess-headers.sh (234226 => 234227)


--- trunk/Source/_javascript_Core/postprocess-headers.sh	2018-07-26 01:29:11 UTC (rev 234226)
+++ trunk/Source/_javascript_Core/postprocess-headers.sh	2018-07-26 02:32:25 UTC (rev 234227)
@@ -1,18 +1,100 @@
-cd "${TARGET_BUILD_DIR}/${PUBLIC_HEADERS_FOLDER_PATH}"
+#!/bin/sh
+#
+# Copyright (C) 2014-2018 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 INC. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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.
+#
 
-UNIFDEF_OPTIONS="-D__MAC_OS_X_VERSION_MIN_REQUIRED=${TARGET_MAC_OS_X_VERSION_MAJOR}"
+if [[ "${JSC_FRAMEWORK_HEADER_POSTPROCESSING_DISABLED}" == "YES" ]]; then
+    exit 0;
+fi
 
-for ((i = 0; i < ${SCRIPT_INPUT_FILE_COUNT}; ++i)); do
-    eval HEADER=\${SCRIPT_INPUT_FILE_${i}};
-    unifdef -B ${UNIFDEF_OPTIONS} -o "${HEADER}".unifdef "${HEADER}"
-    case $? in
-    0)
-        rm "${HEADER}".unifdef
-        ;;
-    1)
-        mv "${HEADER}"{.unifdef,}
-        ;;
-    *)
-        exit 1
-    esac
-done
+TIMESTAMP_PATH=${TARGET_TEMP_DIR}/${0##*/}
+
+if [[ -e $TIMESTAMP_PATH && $0 -nt $TIMESTAMP_PATH ]]; then
+    rm "${TIMESTAMP_PATH}";
+fi
+
+function process_definitions () {
+    local DEFINITIONS_FILE=$1
+
+    if [[ ! -f "${DEFINITIONS_FILE}" ]]; then
+        return 1
+    fi
+
+    if [[ -e $TIMESTAMP_PATH && "${DEFINITIONS_FILE}" -nt $TIMESTAMP_PATH ]]; then
+        rm "${TIMESTAMP_PATH}";
+    fi
+
+    source "${DEFINITIONS_FILE}"
+}
+
+function rewrite_headers () {
+    if [[ "${PLATFORM_NAME}" == "macosx" ]]; then
+        [[ -n ${OSX_VERSION} ]] || OSX_VERSION=${MACOSX_DEPLOYMENT_TARGET}
+        [[ -n ${IOS_VERSION} ]] || IOS_VERSION="NA"
+        [[ -n ${OSX_VERSION_NUMBER} ]] || OSX_VERSION_NUMBER=${TARGET_MAC_OS_X_VERSION_MAJOR}
+        [[ -n ${IOS_VERSION_NUMBER} ]] || IOS_VERSION_NUMBER="0"
+    elif [[ "${PLATFORM_NAME}" =~ "iphone" ]]; then
+        [[ -n ${IOS_VERSION} ]] || IOS_VERSION=${IPHONEOS_DEPLOYMENT_TARGET}
+        [[ -n ${OSX_VERSION} ]] || OSX_VERSION="NA"
+        [[ -n ${OSX_VERSION_NUMBER} ]] || OSX_VERSION_NUMBER="0"
+        [[ -n ${IOS_VERSION_NUMBER} ]] || IOS_VERSION_NUMBER=${SDK_VERSION_MAJOR}
+    fi
+
+    SED_OPTIONS=(
+    )
+
+    if [[ -n "$OSX_VERSION" && -n "$IOS_VERSION" ]]; then
+        SED_OPTIONS+=(
+            -e s/JSC_MAC_TBA/${OSX_VERSION}/g
+            -e s/JSC_IOS_TBA/${IOS_VERSION}/g
+            -e s/JSC_MAC_VERSION_TBA/${OSX_VERSION_NUMBER}/g
+            -e s/JSC_IOS_VERSION_TBA/${IOS_VERSION_NUMBER}/g
+            -e s/JSC_API_AVAILABLE/API_AVAILABLE/
+            -e s/JSC_API_DEPRECATED/API_DEPRECATED/
+            -e "s/^JSC_CLASS_AVAILABLE/JSC_EXTERN API_AVAILABLE/"
+            -e "s/^JSC_CLASS_DEPRECATED/JSC_EXTERN API_DEPRECATED/"
+        )
+    else
+        SED_OPTIONS+=(-e 's/JSC_(API_|CLASS_)AVAILABLE\(.*\)\s*\)//g' -e 's/JSC_(API_|CLASS_)DEPRECATED(_WITH_REPLACEMENT)?\(.*\)\s*\)//g')
+    fi
+
+    SED_OPTIONS+=(${OTHER_SED_OPTIONS[*]})
+
+    for HEADER_PATH in "${1}/"*.h; do
+        if [[ "$HEADER_PATH" -nt $TIMESTAMP_PATH ]]; then
+            ditto "${HEADER_PATH}" "${TARGET_TEMP_DIR}/${HEADER_PATH##*/}"
+            sed -i .tmp -E "${SED_OPTIONS[@]}" "${TARGET_TEMP_DIR}/${HEADER_PATH##*/}" || exit $?
+            mv "${TARGET_TEMP_DIR}/${HEADER_PATH##*/}" "$HEADER_PATH"
+        fi
+    done
+}
+
+DEFINITIONS_PATH=usr/local/include/WebKitAdditions/Scripts/postprocess-framework-headers-definitions
+
+process_definitions "${BUILT_PRODUCTS_DIR}/${DEFINITIONS_PATH}" || process_definitions "${SDKROOT}/${DEFINITIONS_PATH}"
+
+rewrite_headers "${TARGET_BUILD_DIR}/${PUBLIC_HEADERS_FOLDER_PATH}"
+rewrite_headers "${TARGET_BUILD_DIR}/${PRIVATE_HEADERS_FOLDER_PATH}"
+
+touch ${TIMESTAMP_PATH}

Modified: trunk/Source/_javascript_Core/shell/CMakeLists.txt (234226 => 234227)


--- trunk/Source/_javascript_Core/shell/CMakeLists.txt	2018-07-26 01:29:11 UTC (rev 234226)
+++ trunk/Source/_javascript_Core/shell/CMakeLists.txt	2018-07-26 02:32:25 UTC (rev 234227)
@@ -28,6 +28,7 @@
     ../API/tests/PingPongStackOverflowTest.cpp
     ../API/tests/TypedArrayCTest.cpp
     ../API/tests/testapi.c
+    ../API/tests/testapi.cpp
 )
 
 WEBKIT_INCLUDE_CONFIG_FILES_IF_EXISTS()

Modified: trunk/Source/_javascript_Core/testmem/testmem.mm (234226 => 234227)


--- trunk/Source/_javascript_Core/testmem/testmem.mm	2018-07-26 01:29:11 UTC (rev 234226)
+++ trunk/Source/_javascript_Core/testmem/testmem.mm	2018-07-26 02:32:25 UTC (rev 234227)
@@ -23,6 +23,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#import "config.h"
 #import <_javascript_Core/_javascript_Core.h>
 #import <inttypes.h>
 #import <stdio.h>
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to