{
Thread& thread = Thread::current();
CallbackData *entry = (CallbackData *)thread.m_apiData;
- // calleeValue may be null if we are initializing a promise.
- if (!entry || !entry->calleeValue)
+ if (!entry)
return nil;
return [JSValue valueWithJSValueRef:entry->calleeValue inContext:[JSContext currentContext]];
}
#include "JSFunction.h"
#include "JSGlobalObject.h"
#include "JSObject.h"
-#include "JSPromise.h"
-#include "JSPromiseDeferred.h"
-#include "JSRetainPtr.h"
#include "JSString.h"
#include "JSValueRef.h"
#include "ObjectConstructor.h"
return toRef(result);
}
-JSObjectRef JSObjectMakeDeferredPromise(JSContextRef ctx, JSObjectRef* resolve, JSObjectRef* reject, JSValueRef* exception)
-{
- if (!ctx) {
- ASSERT_NOT_REACHED();
- return nullptr;
- }
-
- ExecState* exec = toJS(ctx);
- VM& vm = exec->vm();
- JSLockHolder locker(exec);
- auto scope = DECLARE_CATCH_SCOPE(vm);
-
- auto* globalObject = exec->lexicalGlobalObject();
- JSPromiseDeferred::DeferredData data = JSPromiseDeferred::createDeferredData(exec, globalObject, globalObject->promiseConstructor());
- if (handleExceptionIfNeeded(scope, exec, exception) == ExceptionStatus::DidThrow)
- return nullptr;
-
- if (resolve)
- *resolve = toRef(data.resolve);
- if (reject)
- *reject = toRef(data.reject);
- return toRef(data.promise);
-}
-
JSValueRef JSObjectGetPrototype(JSContextRef ctx, JSObjectRef object)
{
if (!ctx) {
JS_EXPORT JSObjectRef JSObjectGetProxyTarget(JSObjectRef);
JS_EXPORT JSGlobalContextRef JSObjectGetGlobalContext(JSObjectRef object);
-
-/*!
- @function
- @abstract Creates a JavaScript promise object by invoking the provided executor.
- @param ctx The execution context to use.
- @param resolve A pointer to a JSObjectRef in which to store the resolve function for the new promise. Pass NULL if you do not care to store the resolve callback.
- @param reject A pointer to a JSObjectRef in which to store the reject function for the new promise. Pass NULL if you do not care to store the reject callback.
- @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 promise or NULL if an exception occurred.
- */
-JS_EXPORT JSObjectRef JSObjectMakeDeferredPromise(JSContextRef ctx, JSObjectRef* resolve, JSObjectRef* reject, JSValueRef* exception) JSC_API_AVAILABLE(macosx(JSC_MAC_TBA), ios(JSC_IOS_TBA));
#ifdef __cplusplus
}
#import "Exception.h"
#import "JavaScriptCore.h"
#import "JSContextInternal.h"
-#import "JSObjectRefPrivate.h"
#import "JSVirtualMachineInternal.h"
#import "JSValueInternal.h"
-#import "JSValuePrivate.h"
#import "JSWrapperMap.h"
#import "ObjcRuntimeExtras.h"
#import "JSCInlines.h"
return [JSValue valueWithJSValueRef:JSValueMakeSymbol([context JSGlobalContextRef], string.get()) inContext:context];
}
-+ (JSValue *)valueWithNewPromiseInContext:(JSContext *)context fromExecutor:(void (^)(JSValue *, JSValue *))executor
-{
- JSObjectRef resolve;
- JSObjectRef reject;
- JSValueRef exception = nullptr;
- JSObjectRef promise = JSObjectMakeDeferredPromise([context JSGlobalContextRef], &resolve, &reject, &exception);
- if (exception) {
- [context notifyException:exception];
- return [JSValue valueWithUndefinedInContext:context];
- }
-
- JSValue *result = [JSValue valueWithJSValueRef:promise inContext:context];
- JSValue *rejection = [JSValue valueWithJSValueRef:reject inContext:context];
- CallbackData callbackData;
- const size_t argumentCount = 2;
- JSValueRef arguments[argumentCount];
- arguments[0] = resolve;
- arguments[1] = reject;
-
- [context beginCallbackWithData:&callbackData calleeValue:nullptr thisValue:promise argumentCount:argumentCount arguments:arguments];
- executor([JSValue valueWithJSValueRef:resolve inContext:context], rejection);
- if (context.exception)
- [rejection callWithArguments:@[context.exception]];
- [context endCallbackWithData:&callbackData];
-
- return result;
-}
-
-+ (JSValue *)valueWithNewPromiseResolvedWithResult:(id)result inContext:(JSContext *)context
-{
- return [JSValue valueWithNewPromiseInContext:context fromExecutor:^(JSValue *resolve, JSValue *) {
- [resolve callWithArguments:@[result]];
- }];
-}
-
-+ (JSValue *)valueWithNewPromiseRejectedWithReason:(id)reason inContext:(JSContext *)context
-{
- return [JSValue valueWithNewPromiseInContext:context fromExecutor:^(JSValue *, JSValue *reject) {
- [reject callWithArguments:@[reason]];
- }];
-}
-
- (id)toObject
{
return valueToObject(_context, m_value);
+++ /dev/null
-/*
- * Copyright (C) 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. ``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
- * 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.
- */
-
-#if JSC_OBJC_API_ENABLED
-
-#import <JavaScriptCore/JavaScriptCore.h>
-
-@interface JSValue(JSPrivate)
-
-/*!
- @method
- @abstract Create a new promise object using the provided executor callback.
- @param callback A callback block invoked while the promise object is
- being initialized. The resolve and reject parameters are functions that
- can be called to notify any pending reactions about the state of the
- new promise object.
- @param context The JSContext to which the resulting JSValue belongs.
- @result The JSValue representing a new promise JavaScript object.
- @discussion This method is equivalent to calling the Promise constructor in JavaScript.
- the resolve and reject callbacks each normally take a single value, which they
- forward to all relevent pending reactions. While inside the executor callback context will act
- as if it were in any other callback, except calleeFunction will be <code>nil</code>. This also means
- means the new promise object may be accessed via <code>[context thisValue]</code>.
- */
-+ (JSValue *)valueWithNewPromiseInContext:(JSContext *)context fromExecutor:(void (^)(JSValue *resolve, JSValue *reject))callback JSC_API_AVAILABLE(macosx(JSC_MAC_TBA), ios(JSC_IOS_TBA));
-
-/*!
- @method
- @abstract Create a new resolved promise object with the provided value.
- @param result The result value to be passed to any reactions.
- @param context The JSContext to which the resulting JSValue belongs.
- @result The JSValue representing a new promise JavaScript object.
- @discussion This method is equivalent to calling <code>[JSValue valueWithNewPromiseFromExecutor:^(JSValue *resolve, JSValue *reject) { [resolve callWithArguments:@[result]]; } inContext:context]</code>
- */
-+ (JSValue *)valueWithNewPromiseResolvedWithResult:(id)result inContext:(JSContext *)context JSC_API_AVAILABLE(macosx(JSC_MAC_TBA), ios(JSC_IOS_TBA));
-
-/*!
- @method
- @abstract Create a new rejected promise object with the provided value.
- @param reason The result value to be passed to any reactions.
- @param context The JSContext to which the resulting JSValue belongs.
- @result The JSValue representing a new promise JavaScript object.
- @discussion This method is equivalent to calling <code>[JSValue valueWithNewPromiseFromExecutor:^(JSValue *resolve, JSValue *reject) { [reject callWithArguments:@[reason]]; } inContext:context]</code>
- */
-+ (JSValue *)valueWithNewPromiseRejectedWithReason:(id)reason inContext:(JSContext *)context JSC_API_AVAILABLE(macosx(JSC_MAC_TBA), ios(JSC_IOS_TBA));
-
-@end
-
-#endif // JSC_OBJC_API_ENABLED
#import "APICast.h"
#import "DFGWorklist.h"
#import "JSManagedValueInternal.h"
+#import "JSVirtualMachine.h"
#import "JSVirtualMachineInternal.h"
-#import "JSVirtualMachinePrivate.h"
#import "JSWrapperMap.h"
#import "SigillCrashAnalyzer.h"
#import "SlotVisitorInlines.h"
#import <mutex>
-#import <wtf/BlockPtr.h>
#import <wtf/Lock.h>
#import <wtf/spi/cocoa/NSMapTableSPI.h>
API may not synchronously free memory.
*/
-- (void)shrinkFootprintWhenIdle JSC_API_AVAILABLE(macosx(10.14), ios(12.0));
+- (void)shrinkFootprintWhenIdle NS_AVAILABLE(10_14, 12_0);
#if ENABLE(DFG_JIT)
@param numberOfThreads The number of threads the DFG compiler should use going forward
@result The previous number of threads being used by the DFG compiler
*/
-+ (NSUInteger)setNumberOfDFGCompilerThreads:(NSUInteger)numberOfThreads JSC_API_AVAILABLE(macosx(10.14), ios(12.0));
++ (NSUInteger)setNumberOfDFGCompilerThreads:(NSUInteger)numberOfThreads NS_AVAILABLE(10_14, 12_0);
/*!
@method
@param numberOfThreads The number of threads the FTL compiler should use going forward
@result The previous number of threads being used by the FTL compiler
*/
-+ (NSUInteger)setNumberOfFTLCompilerThreads:(NSUInteger)numberOfThreads JSC_API_AVAILABLE(macosx(10.14), ios(12.0));
++ (NSUInteger)setNumberOfFTLCompilerThreads:(NSUInteger)numberOfThreads NS_AVAILABLE(10_14, 12_0);
#endif // ENABLE(DFG_JIT)
void testObjectiveCAPI(void);
#endif
-int testCAPIViaCpp(const char* filter);
+int testCAPIViaCpp(void);
bool assertTrue(bool value, const char* message);
SetErrorMode(0);
#endif
+ testCompareAndSwap();
+ startMultithreadedMultiVMExecutionTest();
+
#if JSC_OBJC_API_ENABLED
testObjectiveCAPI();
#endif
+ RELEASE_ASSERT(!testCAPIViaCpp());
- const char* filter = argc > 1 ? argv[1] : NULL;
- RELEASE_ASSERT(!testCAPIViaCpp(filter));
- if (filter)
- return 0;
-
- testCompareAndSwap();
- startMultithreadedMultiVMExecutionTest();
+ const char *scriptPath = "testapi.js";
+ if (argc > 1) {
+ scriptPath = argv[1];
+ }
// Test garbage collection with a fresh context
context = JSGlobalContextCreateInGroup(NULL, NULL);
JSObjectMakeConstructor(context, nullClass, 0);
JSClassRelease(nullClass);
- const char* scriptPath = "testapi.js";
char* scriptUTF8 = createStringWithContentsOfFile(scriptPath);
if (!scriptUTF8) {
printf("FAIL: Test script could not be loaded.\n");
#include "JSCJSValueInlines.h"
#include "JSObject.h"
-#include <JavaScriptCore/JSObjectRefPrivate.h>
#include <JavaScriptCore/JavaScript.h>
#include <wtf/DataLog.h>
#include <wtf/Expected.h>
#include <wtf/Noncopyable.h>
-#include <wtf/NumberOfCores.h>
#include <wtf/Vector.h>
-extern "C" int testCAPIViaCpp(const char* filter);
+extern "C" int testCAPIViaCpp();
class APIString {
WTF_MAKE_NONCOPYABLE(APIString);
}
operator JSGlobalContextRef() { return m_context; }
- operator JSC::ExecState*() { return toJS(m_context); }
private:
JSGlobalContextRef m_context;
class TestAPI {
public:
- int run(const char* filter);
-
- void basicSymbol();
- void symbolsTypeof();
- void symbolsGetPropertyForKey();
- void symbolsSetPropertyForKey();
- void symbolsHasPropertyForKey();
- void symbolsDeletePropertyForKey();
- void promiseResolveTrue();
- void promiseRejectTrue();
-
- int failed() const { return m_failed; }
-
+ int run();
private:
template<typename... Strings>
APIVector<JSObjectRef> interestingObjects();
APIVector<JSValueRef> interestingKeys();
- int m_failed { 0 };
+ int failed { 0 };
APIContext context;
};
+int testCAPIViaCpp()
+{
+ TestAPI tester;
+ return tester.run();
+}
+
TestAPI::ScriptResult TestAPI::evaluateScript(const char* script, JSObjectRef thisObject)
{
APIString scriptAPIString(script);
{
if (!condition) {
dataLogLn(messages..., ": FAILED");
- m_failed++;
+ failed++;
} else
dataLogLn(messages..., ": PASSED");
return result;
}
-static const char* isSymbolFunction = "(function isSymbol(symbol) { return typeof(symbol) === 'symbol'; })";
-static const char* getFunction = "(function get(object, key) { return object[key]; })";
-static const char* setFunction = "(function set(object, key, value) { object[key] = value; })";
-
-void TestAPI::basicSymbol()
+int TestAPI::run()
{
- // 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");
-}
+ 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]; })";
-void TestAPI::symbolsTypeof()
-{
- APIString description("dope");
- JSValueRef symbol = JSValueMakeSymbol(context, description);
- check(functionReturnsTrue(isSymbolFunction, symbol), "JSValueMakeSymbol makes a symbol value");
-}
+ JSC::ExecState* exec = toJS(context);
-void TestAPI::symbolsGetPropertyForKey()
-{
- auto objects = interestingObjects();
- auto keys = interestingKeys();
-
- for (auto& object : objects) {
- dataLogLn("\nnext object: ", toJS(context, object));
- for (auto& key : keys) {
- dataLogLn("Using key: ", toJS(context, key));
- checkJSAndAPIMatch(
- [&] {
- return callFunction(getFunction, object, key);
- }, [&] (JSValueRef* exception) {
- return JSObjectGetPropertyForKey(context, object, key, exception);
- }, "checking get property keys");
- }
+ {
+ // 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");
}
-}
-void TestAPI::symbolsSetPropertyForKey()
-{
- 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) {
- JSObjectSetPropertyForKey(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 JSObjectGetPropertyForKey(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 JSObjectGetPropertyForKey(context, apiObject, key, exception);
- }, "getting property keys from respective objects");
- }
+ {
+ APIString description("dope");
+ JSValueRef symbol = JSValueMakeSymbol(context, description);
+ check(functionReturnsTrue(isSymbolFunction, symbol), "JSValueMakeSymbol makes a symbol value");
}
-}
-void TestAPI::symbolsHasPropertyForKey()
-{
- const char* hasFunction = "(function has(object, key) { return key in object; })";
- auto objects = interestingObjects();
- auto keys = interestingKeys();
-
- JSValueRef theAnswer = JSValueMakeNumber(context, 42);
- for (auto& object : objects) {
- dataLogLn("\nNext object: ", toJS(context, object));
- for (auto& key : keys) {
- dataLogLn("Using key: ", toJS(context, key));
- checkJSAndAPIMatch(
- [&] {
- return callFunction(hasFunction, object, key);
- }, [&] (JSValueRef* exception) {
- return JSValueMakeBoolean(context, JSObjectHasPropertyForKey(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, JSObjectHasPropertyForKey(context, object, key, exception));
- }, "checking has property keys set");
+ {
+ 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 JSObjectGetPropertyForKey(context, object, key, exception);
+ }, "checking get property keys");
+ }
}
}
-}
-
-void TestAPI::symbolsDeletePropertyForKey()
-{
- const char* deleteFunction = "(function del(object, key) { return delete object[key]; })";
- auto objects = interestingObjects();
- auto keys = interestingKeys();
-
- JSValueRef theAnswer = JSValueMakeNumber(context, 42);
- for (auto& object : objects) {
- dataLogLn("\nNext object: ", toJS(context, object));
- for (auto& key : keys) {
- dataLogLn("Using key: ", toJS(context, key));
- checkJSAndAPIMatch(
- [&] {
- return callFunction(deleteFunction, object, key);
- }, [&] (JSValueRef* exception) {
- return JSValueMakeBoolean(context, JSObjectDeletePropertyForKey(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, JSObjectDeletePropertyForKey(context, object, key, exception));
- }, "checking has property keys set");
+ {
+ 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) {
+ JSObjectSetPropertyForKey(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 JSObjectGetPropertyForKey(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 JSObjectGetPropertyForKey(context, apiObject, key, exception);
+ }, "getting property keys from respective objects");
+ }
}
}
-}
-
-void TestAPI::promiseResolveTrue()
-{
- JSObjectRef resolve;
- JSObjectRef reject;
- JSValueRef exception = nullptr;
- JSObjectRef promise = JSObjectMakeDeferredPromise(context, &resolve, &reject, &exception);
- check(!exception, "No exception should be thrown creating a deferred promise");
-
- // Ugh, we don't have any C API that takes blocks... so we do this hack to capture the runner.
- static TestAPI* tester = this;
- static bool passedTrueCalled = false;
-
- APIString trueString("passedTrue");
- auto passedTrue = [](JSContextRef ctx, JSObjectRef, JSObjectRef, size_t argumentCount, const JSValueRef arguments[], JSValueRef*) -> JSValueRef {
- tester->check(argumentCount && JSValueIsStrictEqual(ctx, arguments[0], JSValueMakeBoolean(ctx, true)), "function should have been called back with true");
- passedTrueCalled = true;
- return JSValueMakeUndefined(ctx);
- };
-
- APIString thenString("then");
- JSValueRef thenFunction = JSObjectGetProperty(context, promise, thenString, &exception);
- check(!exception && thenFunction && JSValueIsObject(context, thenFunction), "Promise should have a then object property");
-
- JSValueRef passedTrueFunction = JSObjectMakeFunctionWithCallback(context, trueString, passedTrue);
- JSObjectCallAsFunction(context, const_cast<JSObjectRef>(thenFunction), promise, 1, &passedTrueFunction, &exception);
- check(!exception, "No exception should be thrown setting up callback");
-
- auto trueValue = JSValueMakeBoolean(context, true);
- JSObjectCallAsFunction(context, resolve, resolve, 1, &trueValue, &exception);
- check(!exception, "No exception should be thrown resolve promise");
- check(passedTrueCalled, "then response function should have been called.");
-}
-
-void TestAPI::promiseRejectTrue()
-{
- JSObjectRef resolve;
- JSObjectRef reject;
- JSValueRef exception = nullptr;
- JSObjectRef promise = JSObjectMakeDeferredPromise(context, &resolve, &reject, &exception);
- check(!exception, "No exception should be thrown creating a deferred promise");
-
- // Ugh, we don't have any C API that takes blocks... so we do this hack to capture the runner.
- static TestAPI* tester = this;
- static bool passedTrueCalled = false;
-
- APIString trueString("passedTrue");
- auto passedTrue = [](JSContextRef ctx, JSObjectRef, JSObjectRef, size_t argumentCount, const JSValueRef arguments[], JSValueRef*) -> JSValueRef {
- tester->check(argumentCount && JSValueIsStrictEqual(ctx, arguments[0], JSValueMakeBoolean(ctx, true)), "function should have been called back with true");
- passedTrueCalled = true;
- return JSValueMakeUndefined(ctx);
- };
-
- APIString catchString("catch");
- JSValueRef catchFunction = JSObjectGetProperty(context, promise, catchString, &exception);
- check(!exception && catchFunction && JSValueIsObject(context, catchFunction), "Promise should have a then object property");
-
- JSValueRef passedTrueFunction = JSObjectMakeFunctionWithCallback(context, trueString, passedTrue);
- JSObjectCallAsFunction(context, const_cast<JSObjectRef>(catchFunction), promise, 1, &passedTrueFunction, &exception);
- check(!exception, "No exception should be thrown setting up callback");
-
- auto trueValue = JSValueMakeBoolean(context, true);
- JSObjectCallAsFunction(context, reject, reject, 1, &trueValue, &exception);
- check(!exception, "No exception should be thrown resolve promise");
- check(passedTrueCalled, "then response function should have been called.");
-}
-
-#define RUN(test) do { \
- if (!shouldRun(#test)) \
- break; \
- tasks.append( \
- createSharedTask<void(TestAPI&)>( \
- [&] (TestAPI& tester) { \
- tester.test; \
- dataLog(#test ": OK!\n"); \
- })); \
- } while (false)
-
-int testCAPIViaCpp(const char* filter)
-{
- dataLogLn("Starting C-API tests in C++");
-
- Deque<RefPtr<SharedTask<void(TestAPI&)>>> tasks;
-
- auto shouldRun = [&] (const char* testName) -> bool {
- return !filter || !!strcasestr(testName, filter);
- };
- RUN(basicSymbol());
- RUN(symbolsTypeof());
- RUN(symbolsGetPropertyForKey());
- RUN(symbolsSetPropertyForKey());
- RUN(symbolsHasPropertyForKey());
- RUN(symbolsDeletePropertyForKey());
- RUN(promiseResolveTrue());
- RUN(promiseRejectTrue());
-
- if (tasks.isEmpty()) {
- dataLogLn("Filtered all tests: ERROR");
- return 1;
+ {
+ 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, JSObjectHasPropertyForKey(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, JSObjectHasPropertyForKey(context, object, key, exception));
+ }, "checking has property keys set");
+ }
+ }
}
- Lock lock;
-
- static Atomic<int> failed { 0 };
- Vector<Ref<Thread>> threads;
- for (unsigned i = filter ? 1 : WTF::numberOfProcessorCores(); i--;) {
- threads.append(Thread::create(
- "Testapi via C++ thread",
- [&] () {
- TestAPI tester;
- for (;;) {
- RefPtr<SharedTask<void(TestAPI&)>> task;
- {
- LockHolder locker(lock);
- if (tasks.isEmpty())
- return;
- task = tasks.takeFirst();
- }
-
- task->run(tester);
- }
- failed.exchangeAdd(tester.failed());
- }));
+ {
+ 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, JSObjectDeletePropertyForKey(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, JSObjectDeletePropertyForKey(context, object, key, exception));
+ }, "checking has property keys set");
+ }
+ }
}
- for (auto& thread : threads)
- thread->waitForCompletion();
-
- dataLogLn("C-API tests in C++ had ", failed.load(), " failures");
- return failed.load();
+ dataLogLn("C-API tests in C++ had ", failed, " failures");
+ return failed;
}
#import "JSExportMacros.h"
#import <JavaScriptCore/JavaScriptCore.h>
+#undef NS_AVAILABLE
+#define NS_AVAILABLE(_mac, _ios)
+
#import "CurrentThisInsideBlockGetterTest.h"
#import "DFGWorklist.h"
#import "DateTests.h"
-#import "JSCast.h"
#import "JSExportTests.h"
-#import "JSValuePrivate.h"
-#import "JSVirtualMachineInternal.h"
#import "JSVirtualMachinePrivate.h"
#import "JSWrapperMapTests.h"
#import "Regress141275.h"
static void testObjectiveCAPIMain()
{
+ runJITThreadLimitTests();
+
@autoreleasepool {
JSVirtualMachine* vm = [[JSVirtualMachine alloc] init];
JSContext* context = [[JSContext alloc] initWithVirtualMachine:vm];
checkResult(@"Negative number maintained its original value", [[result toString] isEqualToString:@"-1"]);
}
-enum class Resolution {
- ResolveEager,
- RejectEager,
- ResolveLate,
- RejectLate,
-};
-
-static void promiseWithExecutor(Resolution resolution)
-{
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
-
- __block JSValue *resolveCallback;
- __block JSValue *rejectCallback;
- JSValue *promise = [JSValue valueWithNewPromiseInContext:context fromExecutor:^(JSValue *resolve, JSValue *reject) {
- if (resolution == Resolution::ResolveEager)
- [resolve callWithArguments:@[@YES]];
- if (resolution == Resolution::RejectEager)
- [reject callWithArguments:@[@YES]];
- resolveCallback = resolve;
- rejectCallback = reject;
- }];
-
- __block bool valueWasResolvedTrue = false;
- __block bool valueWasRejectedTrue = false;
- [promise invokeMethod:@"then" withArguments:@[
- ^(JSValue *value) { valueWasResolvedTrue = [value isBoolean] && [value toBool]; },
- ^(JSValue *value) { valueWasRejectedTrue = [value isBoolean] && [value toBool]; },
- ]];
-
- switch (resolution) {
- case Resolution::ResolveEager:
- checkResult(@"ResolveEager should have set resolve early.", valueWasResolvedTrue && !valueWasRejectedTrue);
- break;
- case Resolution::RejectEager:
- checkResult(@"RejectEager should have set reject early.", !valueWasResolvedTrue && valueWasRejectedTrue);
- break;
- default:
- checkResult(@"Resolve/RejectLate should have not have set anything early.", !valueWasResolvedTrue && !valueWasRejectedTrue);
- break;
- }
-
- valueWasResolvedTrue = false;
- valueWasRejectedTrue = false;
-
- // Run script to make sure reactions don't happen again
- [context evaluateScript:@"{ };"];
-
- if (resolution == Resolution::ResolveLate)
- [resolveCallback callWithArguments:@[@YES]];
- if (resolution == Resolution::RejectLate)
- [rejectCallback callWithArguments:@[@YES]];
-
- switch (resolution) {
- case Resolution::ResolveLate:
- checkResult(@"ResolveLate should have set resolve late.", valueWasResolvedTrue && !valueWasRejectedTrue);
- break;
- case Resolution::RejectLate:
- checkResult(@"RejectLate should have set reject late.", !valueWasResolvedTrue && valueWasRejectedTrue);
- break;
- default:
- checkResult(@"Resolve/RejectEarly should have not have set anything late.", !valueWasResolvedTrue && !valueWasRejectedTrue);
- break;
- }
- }
-}
-
-static void promiseRejectOnJSException()
-{
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
-
- JSValue *promise = [JSValue valueWithNewPromiseInContext:context fromExecutor:^(JSValue *, JSValue *) {
- context.exception = [JSValue valueWithNewErrorFromMessage:@"dope" inContext:context];
- }];
- checkResult(@"Exception set in callback should not propagate", !context.exception);
-
- __block bool reasonWasObject = false;
- [promise invokeMethod:@"catch" withArguments:@[^(JSValue *reason) { reasonWasObject = [reason isObject]; }]];
-
- checkResult(@"Setting an exception in executor causes the promise to be rejected", reasonWasObject);
-
- promise = [JSValue valueWithNewPromiseInContext:context fromExecutor:^(JSValue *, JSValue *) {
- [context evaluateScript:@"throw new Error('dope');"];
- }];
- checkResult(@"Exception thrown in callback should not propagate", !context.exception);
-
- reasonWasObject = false;
- [promise invokeMethod:@"catch" withArguments:@[^(JSValue *reason) { reasonWasObject = [reason isObject]; }]];
-
- checkResult(@"Running code that throws an exception in the executor causes the promise to be rejected", reasonWasObject);
- }
-}
-
-static void promiseCreateResolved()
-{
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
-
- JSValue *promise = [JSValue valueWithNewPromiseResolvedWithResult:[NSNull null] inContext:context];
- __block bool calledWithNull = false;
- [promise invokeMethod:@"then" withArguments:@[
- ^(JSValue *result) { calledWithNull = [result isNull]; }
- ]];
-
- checkResult(@"ResolvedPromise should actually resolve the promise", calledWithNull);
- }
-}
-
-static void promiseCreateRejected()
-{
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
-
- JSValue *promise = [JSValue valueWithNewPromiseRejectedWithReason:[NSNull null] inContext:context];
- __block bool calledWithNull = false;
- [promise invokeMethod:@"then" withArguments:@[
- [NSNull null],
- ^(JSValue *result) { calledWithNull = [result isNull]; }
- ]];
-
- checkResult(@"RejectedPromise should actually reject the promise", calledWithNull);
- }
-}
-
-static void parallelPromiseResolveTest()
-{
- @autoreleasepool {
- JSContext *context = [[JSContext alloc] init];
-
- __block RefPtr<Thread> thread;
-
- Atomic<bool> shouldResolveSoon { false };
- Atomic<bool> startedThread { false };
- auto* shouldResolveSoonPtr = &shouldResolveSoon;
- auto* startedThreadPtr = &startedThread;
-
- JSValue *promise = [JSValue valueWithNewPromiseInContext:context fromExecutor:^(JSValue *resolve, JSValue *) {
- thread = Thread::create("async thread", ^() {
- startedThreadPtr->store(true);
- while (!shouldResolveSoonPtr->load()) { }
- [resolve callWithArguments:@[[NSNull null]]];
- });
-
- }];
-
- shouldResolveSoon.store(true);
- while (!startedThread.load())
- [context evaluateScript:@"for (let i = 0; i < 10000; i++) { }"];
-
- thread->waitForCompletion();
-
- __block bool calledWithNull = false;
- [promise invokeMethod:@"then" withArguments:@[
- ^(JSValue *result) { calledWithNull = [result isNull]; }
- ]];
-
- checkResult(@"Promise should be resolved", calledWithNull);
- }
-}
void testObjectiveCAPI()
{
NSLog(@"Testing Objective-C API");
checkNegativeNSIntegers();
- runJITThreadLimitTests();
-
- promiseWithExecutor(Resolution::ResolveEager);
- promiseWithExecutor(Resolution::RejectEager);
- promiseWithExecutor(Resolution::ResolveLate);
- promiseWithExecutor(Resolution::RejectLate);
- promiseRejectOnJSException();
- promiseCreateResolved();
- promiseCreateRejected();
- parallelPromiseResolveTest();
-
testObjectiveCAPIMain();
}
+2018-09-21 Ryan Haddad <ryanhaddad@apple.com>
+
+ Unreviewed, rolling out r236359.
+
+ Broke the Windows build.
+
+ Reverted changeset:
+
+ "Add Promise SPI"
+ https://bugs.webkit.org/show_bug.cgi?id=189809
+ https://trac.webkit.org/changeset/236359
+
2018-09-21 Mark Lam <mark.lam@apple.com>
JSRopeString::resolveRope() wrongly assumes that tryGetValue() passes it a valid ExecState.
53C6FEEF1E8ADFA900B18425 /* WasmOpcodeOrigin.h in Headers */ = {isa = PBXBuildFile; fileRef = 53C6FEEE1E8ADFA900B18425 /* WasmOpcodeOrigin.h */; };
53CA730A1EA533D80076049D /* WasmBBQPlan.h in Headers */ = {isa = PBXBuildFile; fileRef = 53CA73081EA533D80076049D /* WasmBBQPlan.h */; };
53D444DC1DAF08AB00B92784 /* B3WasmAddressValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 53D444DB1DAF08AB00B92784 /* B3WasmAddressValue.h */; };
- 53E1F8F82154715A0001DDBC /* JSValuePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 53E1F8F7215471490001DDBC /* JSValuePrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
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, ); }; };
53CA73081EA533D80076049D /* WasmBBQPlan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmBBQPlan.h; sourceTree = "<group>"; };
53D444DB1DAF08AB00B92784 /* B3WasmAddressValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3WasmAddressValue.h; path = b3/B3WasmAddressValue.h; sourceTree = "<group>"; };
53D444DD1DAF09A000B92784 /* B3WasmAddressValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3WasmAddressValue.cpp; path = b3/B3WasmAddressValue.cpp; sourceTree = "<group>"; };
- 53E1F8F7215471490001DDBC /* JSValuePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSValuePrivate.h; sourceTree = "<group>"; };
53E777E11E92E265007CBEC4 /* WasmModuleInformation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmModuleInformation.cpp; sourceTree = "<group>"; };
53E777E21E92E265007CBEC4 /* WasmModuleInformation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmModuleInformation.h; sourceTree = "<group>"; };
53E9E0A91EAE83DE00FEE251 /* WasmMachineThreads.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmMachineThreads.cpp; sourceTree = "<group>"; };
86E3C606167BAB87006D760A /* JSValue.h */,
86E3C60D167BAB87006D760A /* JSValue.mm */,
86E3C60E167BAB87006D760A /* JSValueInternal.h */,
- 53E1F8F7215471490001DDBC /* JSValuePrivate.h */,
14BD5A2B0A3E91F600BAF59C /* JSValueRef.cpp */,
1482B6EA0A4300B300517CFC /* JSValueRef.h */,
86E3C60F167BAB87006D760A /* JSVirtualMachine.h */,
isa = PBXGroup;
children = (
99DA00991BD5992700F4575C /* __init__.py */,
+ 99DA009D1BD5992700F4575C /* wkbuiltins.py */,
99DA009E1BD5992700F4575C /* builtins_generate_combined_header.py */,
99DA009F1BD5992700F4575C /* builtins_generate_combined_implementation.py */,
412952731D2CF6AC00E78B89 /* builtins_generate_internals_wrapper_header.py */,
99DA009A1BD5992700F4575C /* builtins_generator.py */,
99DA009B1BD5992700F4575C /* builtins_model.py */,
99DA009C1BD5992700F4575C /* builtins_templates.py */,
- 99DA009D1BD5992700F4575C /* wkbuiltins.py */,
);
path = wkbuiltins;
sourceTree = "<group>";
DE26E9031CB5DD0500D2BE82 /* BuiltinExecutableCreator.h in Headers */,
A7D801A51880D66E0026C39B /* BuiltinExecutables.h in Headers */,
A75EE9B218AAB7E200AAD043 /* BuiltinNames.h in Headers */,
+ 99DA00A61BD5993100F4575C /* wkbuiltins.py in Headers */,
99DA00A71BD5993100F4575C /* builtins_generate_combined_header.py in Headers */,
99DA00A81BD5993100F4575C /* builtins_generate_combined_implementation.py in Headers */,
412952771D2CF6BC00E78B89 /* builtins_generate_internals_wrapper_header.py in Headers */,
0F2B670117B6B5AB00A7AE3F /* JSUint8ClampedArray.h in Headers */,
86E3C612167BABD7006D760A /* JSValue.h in Headers */,
86E3C61B167BABEE006D760A /* JSValueInternal.h in Headers */,
- 53E1F8F82154715A0001DDBC /* JSValuePrivate.h in Headers */,
BC18C42C0E16F5CD00B34460 /* JSValueRef.h in Headers */,
86E3C615167BABD7006D760A /* JSVirtualMachine.h in Headers */,
86E3C61D167BABEE006D760A /* JSVirtualMachineInternal.h in Headers */,
ADBC54D51DF8EA2B005BF738 /* WebAssemblyToJSCallee.h in Headers */,
52F6C35E1E71EB080081F4CC /* WebAssemblyWrapperFunction.h in Headers */,
BC18C47A0E16F5CD00B34460 /* WebKitAvailability.h in Headers */,
- 99DA00A61BD5993100F4575C /* wkbuiltins.py in Headers */,
A7DCB97312E5193F00911940 /* WriteBarrier.h in Headers */,
C2B6D75318A33793004A9301 /* WriteBarrierInlines.h in Headers */,
0FC8150A14043BF500CFA603 /* WriteBarrierSupport.h in Headers */,
VM& vm = exec->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
- DeferredData data = createDeferredData(exec, globalObject, globalObject->internalPromiseConstructor());
+ JSValue deferred = newPromiseCapability(exec, globalObject, globalObject->internalPromiseConstructor());
+ RETURN_IF_EXCEPTION(scope, nullptr);
+
+ JSValue promise = deferred.get(exec, vm.propertyNames->builtinNames().promisePrivateName());
+ RETURN_IF_EXCEPTION(scope, nullptr);
+ ASSERT(promise.inherits<JSInternalPromise>(vm));
+ JSValue resolve = deferred.get(exec, vm.propertyNames->builtinNames().resolvePrivateName());
+ RETURN_IF_EXCEPTION(scope, nullptr);
+ JSValue reject = deferred.get(exec, vm.propertyNames->builtinNames().rejectPrivateName());
RETURN_IF_EXCEPTION(scope, nullptr);
JSInternalPromiseDeferred* result = new (NotNull, allocateCell<JSInternalPromiseDeferred>(vm.heap)) JSInternalPromiseDeferred(vm);
- result->finishCreation(vm, data.promise, data.resolve, data.reject);
+ result->finishCreation(vm, jsCast<JSObject*>(promise), resolve, reject);
return result;
}
typedef JSNonFinalObject Base;
static JSPromise* create(VM&, Structure*);
- struct JSPromiseAndCallbacks {
- JSPromise* promise;
- JSFunction* resolve;
- JSFunction* reject;
- };
- static JSPromiseAndCallbacks createWithCallbacks(VM&, Structure*);
-
static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
DECLARE_EXPORT_INFO;
Structure* promiseStructure = InternalFunction::createSubclassStructure(exec, exec->newTarget(), globalObject->promiseStructure());
RETURN_IF_EXCEPTION(scope, encodedJSValue());
JSPromise* promise = JSPromise::create(vm, promiseStructure);
- promise->initialize(exec, globalObject, exec->argument(0));
+ promise->initialize(exec, globalObject, exec->argument(0));
RETURN_IF_EXCEPTION(scope, encodedJSValue());
return JSValue::encode(promise);
const ClassInfo JSPromiseDeferred::s_info = { "JSPromiseDeferred", nullptr, nullptr, nullptr, CREATE_METHOD_TABLE(JSPromiseDeferred) };
-JSPromiseDeferred::DeferredData JSPromiseDeferred::createDeferredData(ExecState* exec, JSGlobalObject* globalObject, JSPromiseConstructor* promiseConstructor)
+JSValue newPromiseCapability(ExecState* exec, JSGlobalObject* globalObject, JSPromiseConstructor* promiseConstructor)
{
- VM& vm = exec->vm();
- auto scope = DECLARE_THROW_SCOPE(vm);
-
JSFunction* newPromiseCapabilityFunction = globalObject->newPromiseCapabilityFunction();
CallData callData;
CallType callType = JSC::getCallData(exec->vm(), newPromiseCapabilityFunction, callData);
MarkedArgumentBuffer arguments;
arguments.append(promiseConstructor);
ASSERT(!arguments.hasOverflowed());
- JSValue deferred = call(exec, newPromiseCapabilityFunction, callType, callData, jsUndefined(), arguments);
- RETURN_IF_EXCEPTION(scope, { });
-
- DeferredData result;
- result.promise = jsCast<JSPromise*>(deferred.get(exec, vm.propertyNames->builtinNames().promisePrivateName()));
- RETURN_IF_EXCEPTION(scope, { });
- result.resolve = jsCast<JSFunction*>(deferred.get(exec, vm.propertyNames->builtinNames().resolvePrivateName()));
- RETURN_IF_EXCEPTION(scope, { });
- result.reject = jsCast<JSFunction*>(deferred.get(exec, vm.propertyNames->builtinNames().rejectPrivateName()));
- RETURN_IF_EXCEPTION(scope, { });
-
- return result;
+ return call(exec, newPromiseCapabilityFunction, callType, callData, jsUndefined(), arguments);
}
+
JSPromiseDeferred* JSPromiseDeferred::create(ExecState* exec, JSGlobalObject* globalObject)
{
VM& vm = exec->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
- DeferredData data = createDeferredData(exec, globalObject, globalObject->promiseConstructor());
- RETURN_IF_EXCEPTION(scope, { });
- return JSPromiseDeferred::create(vm, data.promise, data.resolve, data.reject);
+ JSValue deferred = newPromiseCapability(exec, globalObject, globalObject->promiseConstructor());
+ RETURN_IF_EXCEPTION(scope, nullptr);
+
+ JSValue promise = deferred.get(exec, vm.propertyNames->builtinNames().promisePrivateName());
+ RETURN_IF_EXCEPTION(scope, nullptr);
+ ASSERT(promise.inherits<JSPromise>(vm));
+ JSValue resolve = deferred.get(exec, vm.propertyNames->builtinNames().resolvePrivateName());
+ RETURN_IF_EXCEPTION(scope, nullptr);
+ JSValue reject = deferred.get(exec, vm.propertyNames->builtinNames().rejectPrivateName());
+ RETURN_IF_EXCEPTION(scope, nullptr);
+
+ return JSPromiseDeferred::create(vm, jsCast<JSPromise*>(promise), resolve, reject);
}
-JSPromiseDeferred* JSPromiseDeferred::create(VM& vm, JSPromise* promise, JSFunction* resolve, JSFunction* reject)
+JSPromiseDeferred* JSPromiseDeferred::create(VM& vm, JSObject* promise, JSValue resolve, JSValue reject)
{
JSPromiseDeferred* deferred = new (NotNull, allocateCell<JSPromiseDeferred>(vm.heap)) JSPromiseDeferred(vm);
deferred->finishCreation(vm, promise, resolve, reject);
reject(exec, reason->value());
}
-void JSPromiseDeferred::finishCreation(VM& vm, JSPromise* promise, JSFunction* resolve, JSFunction* reject)
+void JSPromiseDeferred::finishCreation(VM& vm, JSObject* promise, JSValue resolve, JSValue reject)
{
Base::finishCreation(vm);
m_promise.set(vm, this, promise);
#pragma once
#include "JSCast.h"
-#include "JSPromise.h"
#include "Structure.h"
namespace JSC {
class Exception;
class JSPromiseConstructor;
-class JSFunction;
class JSPromiseDeferred : public JSCell {
public:
typedef JSCell Base;
static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
- struct DeferredData {
- WTF_FORBID_HEAP_ALLOCATION;
- public:
- JSPromise* promise { nullptr };
- JSFunction* resolve { nullptr };
- JSFunction* reject { nullptr };
- };
- static DeferredData createDeferredData(ExecState*, JSGlobalObject*, JSPromiseConstructor*);
-
JS_EXPORT_PRIVATE static JSPromiseDeferred* create(ExecState*, JSGlobalObject*);
- JS_EXPORT_PRIVATE static JSPromiseDeferred* create(VM&, JSPromise*, JSFunction* resolve, JSFunction* reject);
+ JS_EXPORT_PRIVATE static JSPromiseDeferred* create(VM&, JSObject* promise, JSValue resolve, JSValue reject);
static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
DECLARE_EXPORT_INFO;
- JSPromise* promise() const { return m_promise.get(); }
- JSFunction* resolve() const { return m_resolve.get(); }
- JSFunction* reject() const { return m_reject.get(); }
+ JSObject* promise() const { return m_promise.get(); }
+ JSValue resolve() const { return m_resolve.get(); }
+ JSValue reject() const { return m_reject.get(); }
JS_EXPORT_PRIVATE void resolve(ExecState*, JSValue);
JS_EXPORT_PRIVATE void reject(ExecState*, JSValue);
protected:
JSPromiseDeferred(VM&, Structure*);
- void finishCreation(VM&, JSPromise*, JSFunction* resolve, JSFunction* reject);
+ void finishCreation(VM&, JSObject*, JSValue, JSValue);
static void visitChildren(JSCell*, SlotVisitor&);
private:
bool m_promiseIsAsyncPending { false };
#endif
- WriteBarrier<JSPromise> m_promise;
- WriteBarrier<JSFunction> m_resolve;
- WriteBarrier<JSFunction> m_reject;
+ WriteBarrier<JSObject> m_promise;
+ WriteBarrier<Unknown> m_resolve;
+ WriteBarrier<Unknown> m_reject;
};
+JSValue newPromiseCapability(ExecState*, JSGlobalObject*, JSPromiseConstructor*);
+
} // namespace JSC
+2018-09-21 Ryan Haddad <ryanhaddad@apple.com>
+
+ Unreviewed, rolling out r236359.
+
+ Broke the Windows build.
+
+ Reverted changeset:
+
+ "Add Promise SPI"
+ https://bugs.webkit.org/show_bug.cgi?id=189809
+ https://trac.webkit.org/changeset/236359
+
2018-09-21 Keith Miller <keith_miller@apple.com>
Add Promise SPI
{
return mainThread == &Thread::current();
}
-
-bool isMainThreadIfInitialized()
-{
- return isMainThread();
-}
#endif
#if PLATFORM(COCOA)
WTF_EXPORT_PRIVATE void setMainThreadCallbacksPaused(bool paused);
WTF_EXPORT_PRIVATE bool isMainThread();
-WTF_EXPORT_PRIVATE bool isMainThreadIfInitialized();
WTF_EXPORT_PRIVATE bool canAccessThreadLocalDataForThread(Thread&);
static JSWTFMainThreadCaller* staticMainThreadCaller;
static bool isTimerPosted; // This is only accessed on the main thread.
-static bool mainThreadEstablishedAsPthreadMain { false };
-static pthread_t mainThreadPthread { nullptr };
-static NSThread* mainThreadNSThread { nullptr };
+static bool mainThreadEstablishedAsPthreadMain;
+static pthread_t mainThreadPthread;
+static NSThread* mainThreadNSThread;
#if USE(WEB_THREAD)
static Thread* sApplicationUIThread;
return (isWebThread() || pthread_main_np()) && webThreadIsUninitializedOrLockedOrDisabled();
}
-bool isMainThreadIfInitialized()
-{
- return isMainThread();
-}
-
bool isUIThread()
{
return pthread_main_np();
ASSERT(mainThreadPthread);
return pthread_equal(pthread_self(), mainThreadPthread);
}
-
-bool isMainThreadIfInitialized()
-{
- if (mainThreadEstablishedAsPthreadMain)
- return pthread_main_np();
- return pthread_equal(pthread_self(), mainThreadPthread);
-}
-
#endif // USE(WEB_THREAD)
} // namespace WTF
RetainPtr<CFStringRef> StringImpl::createCFString()
{
- if (!m_length || !isMainThreadIfInitialized()) {
+ if (!m_length || !isMainThread()) {
if (is8Bit())
return adoptCF(CFStringCreateWithBytes(0, reinterpret_cast<const UInt8*>(characters8()), m_length, kCFStringEncodingISOLatin1, false));
return adoptCF(CFStringCreateWithCharacters(0, reinterpret_cast<const UniChar*>(characters16()), m_length));