X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/81345200c95645a1b0d2635520f96ad55dfde63f..refs/heads/master:/runtime/JSPromiseDeferred.cpp diff --git a/runtime/JSPromiseDeferred.cpp b/runtime/JSPromiseDeferred.cpp index 67fd550..1add652 100644 --- a/runtime/JSPromiseDeferred.cpp +++ b/runtime/JSPromiseDeferred.cpp @@ -28,30 +28,38 @@ #if ENABLE(PROMISES) +#include "BuiltinNames.h" #include "Error.h" +#include "Exception.h" #include "JSCJSValueInlines.h" #include "JSCellInlines.h" #include "JSPromise.h" #include "JSPromiseConstructor.h" -#include "JSPromiseFunctions.h" #include "SlotVisitorInlines.h" #include "StructureInlines.h" namespace JSC { -const ClassInfo JSPromiseDeferred::s_info = { "JSPromiseDeferred", 0, 0, 0, CREATE_METHOD_TABLE(JSPromiseDeferred) }; +const ClassInfo JSPromiseDeferred::s_info = { "JSPromiseDeferred", 0, 0, CREATE_METHOD_TABLE(JSPromiseDeferred) }; JSPromiseDeferred* JSPromiseDeferred::create(ExecState* exec, JSGlobalObject* globalObject) { VM& vm = exec->vm(); - - JSFunction* resolver = createDeferredConstructionFunction(vm, globalObject); - JSPromise* promise = constructPromise(exec, globalObject, resolver); - JSValue resolve = resolver->get(exec, vm.propertyNames->resolvePrivateName); - JSValue reject = resolver->get(exec, vm.propertyNames->rejectPrivateName); + JSFunction* newPromiseDeferredFunction = globalObject->newPromiseDeferredFunction(); + CallData callData; + CallType callType = JSC::getCallData(newPromiseDeferredFunction, callData); + ASSERT(callType != CallTypeNone); - return JSPromiseDeferred::create(vm, promise, resolve, reject); + MarkedArgumentBuffer arguments; + JSValue deferred = call(exec, newPromiseDeferredFunction, callType, callData, jsUndefined(), arguments); + + JSValue promise = deferred.get(exec, vm.propertyNames->promisePrivateName); + ASSERT(promise.inherits(JSPromise::info())); + JSValue resolve = deferred.get(exec, vm.propertyNames->builtinNames().resolvePrivateName()); + JSValue reject = deferred.get(exec, vm.propertyNames->builtinNames().rejectPrivateName()); + + return JSPromiseDeferred::create(vm, jsCast(promise), resolve, reject); } JSPromiseDeferred* JSPromiseDeferred::create(VM& vm, JSObject* promise, JSValue resolve, JSValue reject) @@ -78,8 +86,6 @@ void JSPromiseDeferred::visitChildren(JSCell* cell, SlotVisitor& visitor) { JSPromiseDeferred* thisObject = jsCast(cell); ASSERT_GC_OBJECT_INHERITS(thisObject, info()); - COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag); - ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); Base::visitChildren(thisObject, visitor); @@ -88,164 +94,6 @@ void JSPromiseDeferred::visitChildren(JSCell* cell, SlotVisitor& visitor) visitor.append(&thisObject->m_reject); } -JSValue createJSPromiseDeferredFromConstructor(ExecState* exec, JSValue C) -{ - // -- This implements the GetDeferred(C) abstract operation -- - - // 1. If IsConstructor(C) is false, throw a TypeError. - if (!C.isObject()) - return throwTypeError(exec); - - ConstructData constructData; - ConstructType constructType = getConstructData(C, constructData); - if (constructType == ConstructTypeNone) - return throwTypeError(exec); - - VM& vm = exec->vm(); - - // 2. Let 'resolver' be a new built-in function object as defined in Deferred Construction Functions. - JSFunction* resolver = createDeferredConstructionFunction(vm, asObject(C)->globalObject()); - - // 3. Let 'promise' be the result of calling the [[Construct]] internal method of 'C' with - // an argument list containing the single item resolver. - MarkedArgumentBuffer constructArguments; - constructArguments.append(resolver); - JSObject* promise = construct(exec, C, constructType, constructData, constructArguments); - - // 4. ReturnIfAbrupt(promise). - if (exec->hadException()) - return jsUndefined(); - - // 5. Let 'resolve' be the value of resolver's [[Resolve]] internal slot. - JSValue resolve = resolver->get(exec, vm.propertyNames->resolvePrivateName); - - // 6. If IsCallable(resolve) is false, throw a TypeError. - CallData resolveCallData; - CallType resolveCallType = getCallData(resolve, resolveCallData); - if (resolveCallType == CallTypeNone) - return throwTypeError(exec); - - // 7. Let 'reject' be the value of resolver's [[Reject]] internal slot. - JSValue reject = resolver->get(exec, vm.propertyNames->rejectPrivateName); - - // 8. If IsCallable(reject) is false, throw a TypeError. - CallData rejectCallData; - CallType rejectCallType = getCallData(reject, rejectCallData); - if (rejectCallType == CallTypeNone) - return throwTypeError(exec); - - // 9. Return the Deferred { [[Promise]]: promise, [[Resolve]]: resolve, [[Reject]]: reject }. - return JSPromiseDeferred::create(exec->vm(), promise, resolve, reject); -} - -ThenableStatus updateDeferredFromPotentialThenable(ExecState* exec, JSValue x, JSPromiseDeferred* deferred) -{ - // 1. If Type(x) is not Object, return "not a thenable". - if (!x.isObject()) - return NotAThenable; - - // 2. Let 'then' be the result of calling Get(x, "then"). - JSValue thenValue = x.get(exec, exec->vm().propertyNames->then); - - // 3. If then is an abrupt completion, - if (exec->hadException()) { - // i. Let 'rejectResult' be the result of calling the [[Call]] internal method of - // deferred.[[Reject]] with undefined as thisArgument and a List containing - // then.[[value]] as argumentsList. - JSValue exception = exec->exception(); - exec->clearException(); - - performDeferredReject(exec, deferred, exception); - - // ii. ReturnIfAbrupt(rejectResult). - // NOTE: Nothing to do. - - // iii. Return. - return WasAThenable; - } - - // 4. Let 'then' be then.[[value]]. - // Note: Nothing to do. - - // 5. If IsCallable(then) is false, return "not a thenable". - CallData thenCallData; - CallType thenCallType = getCallData(thenValue, thenCallData); - if (thenCallType == CallTypeNone) - return NotAThenable; - - // 6. Let 'thenCallResult' be the result of calling the [[Call]] internal method of - // 'then' passing x as thisArgument and a List containing deferred.[[Resolve]] and - // deferred.[[Reject]] as argumentsList. - MarkedArgumentBuffer thenArguments; - thenArguments.append(deferred->resolve()); - thenArguments.append(deferred->reject()); - - call(exec, thenValue, thenCallType, thenCallData, x, thenArguments); - - // 7. If 'thenCallResult' is an abrupt completion, - if (exec->hadException()) { - // i. Let 'rejectResult' be the result of calling the [[Call]] internal method of - // deferred.[[Reject]] with undefined as thisArgument and a List containing - // thenCallResult.[[value]] as argumentsList. - JSValue exception = exec->exception(); - exec->clearException(); - - performDeferredReject(exec, deferred, exception); - - // ii. ReturnIfAbrupt(rejectResult). - // NOTE: Nothing to do. - } - - return WasAThenable; -} - -void performDeferredResolve(ExecState* exec, JSPromiseDeferred* deferred, JSValue argument) -{ - JSValue deferredResolve = deferred->resolve(); - - CallData resolveCallData; - CallType resolveCallType = getCallData(deferredResolve, resolveCallData); - ASSERT(resolveCallType != CallTypeNone); - - MarkedArgumentBuffer arguments; - arguments.append(argument); - - call(exec, deferredResolve, resolveCallType, resolveCallData, jsUndefined(), arguments); -} - -void performDeferredReject(ExecState* exec, JSPromiseDeferred* deferred, JSValue argument) -{ - JSValue deferredReject = deferred->reject(); - - CallData rejectCallData; - CallType rejectCallType = getCallData(deferredReject, rejectCallData); - ASSERT(rejectCallType != CallTypeNone); - - MarkedArgumentBuffer arguments; - arguments.append(argument); - - call(exec, deferredReject, rejectCallType, rejectCallData, jsUndefined(), arguments); -} - -JSValue abruptRejection(ExecState* exec, JSPromiseDeferred* deferred) -{ - ASSERT(exec->hadException()); - JSValue argument = exec->exception(); - exec->clearException(); - - // i. Let 'rejectResult' be the result of calling the [[Call]] internal method - // of deferred.[[Reject]] with undefined as thisArgument and a List containing - // argument.[[value]] as argumentsList. - performDeferredReject(exec, deferred, argument); - - // ii. ReturnIfAbrupt(rejectResult). - if (exec->hadException()) - return jsUndefined(); - - // iii. Return deferred.[[Promise]]. - return deferred->promise(); -} - } // namespace JSC #endif // ENABLE(PROMISES)