PromiseConstructor.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*
  2. * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <LibJS/Interpreter.h>
  7. #include <LibJS/Runtime/Error.h>
  8. #include <LibJS/Runtime/Function.h>
  9. #include <LibJS/Runtime/GlobalObject.h>
  10. #include <LibJS/Runtime/Promise.h>
  11. #include <LibJS/Runtime/PromiseConstructor.h>
  12. #include <LibJS/Runtime/PromiseReaction.h>
  13. namespace JS {
  14. PromiseConstructor::PromiseConstructor(GlobalObject& global_object)
  15. : NativeFunction(vm().names.Promise, *global_object.function_prototype())
  16. {
  17. }
  18. void PromiseConstructor::initialize(GlobalObject& global_object)
  19. {
  20. auto& vm = this->vm();
  21. NativeFunction::initialize(global_object);
  22. // 27.2.4.4 Promise.prototype, https://tc39.es/ecma262/#sec-promise.prototype
  23. define_property(vm.names.prototype, global_object.promise_prototype(), 0);
  24. define_property(vm.names.length, Value(1), Attribute::Configurable);
  25. u8 attr = Attribute::Writable | Attribute::Configurable;
  26. // TODO: Implement these functions below and uncomment this.
  27. // define_native_function(vm.names.all, all, 1, attr);
  28. // define_native_function(vm.names.allSettled, all_settled, 1, attr);
  29. // define_native_function(vm.names.any, any, 1, attr);
  30. // define_native_function(vm.names.race, race, 1, attr);
  31. define_native_function(vm.names.reject, reject, 1, attr);
  32. define_native_function(vm.names.resolve, resolve, 1, attr);
  33. define_native_accessor(vm.well_known_symbol_species(), symbol_species_getter, {}, Attribute::Configurable);
  34. }
  35. // 27.2.3.1 Promise ( executor ), https://tc39.es/ecma262/#sec-promise-executor
  36. Value PromiseConstructor::call()
  37. {
  38. auto& vm = this->vm();
  39. vm.throw_exception<TypeError>(global_object(), ErrorType::ConstructorWithoutNew, vm.names.Promise);
  40. return {};
  41. }
  42. // 27.2.3.1 Promise ( executor ), https://tc39.es/ecma262/#sec-promise-executor
  43. Value PromiseConstructor::construct(Function&)
  44. {
  45. auto& vm = this->vm();
  46. auto executor = vm.argument(0);
  47. if (!executor.is_function()) {
  48. vm.throw_exception<TypeError>(global_object(), ErrorType::PromiseExecutorNotAFunction);
  49. return {};
  50. }
  51. auto* promise = Promise::create(global_object());
  52. auto [resolve_function, reject_function] = promise->create_resolving_functions();
  53. auto completion_value = vm.call(executor.as_function(), js_undefined(), &resolve_function, &reject_function);
  54. if (vm.exception()) {
  55. vm.clear_exception();
  56. vm.stop_unwind();
  57. [[maybe_unused]] auto result = vm.call(reject_function, js_undefined(), completion_value);
  58. }
  59. return promise;
  60. }
  61. // 27.2.4.1 Promise.all ( iterable ), https://tc39.es/ecma262/#sec-promise.all
  62. JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::all)
  63. {
  64. TODO();
  65. }
  66. // 27.2.4.2 Promise.allSettled ( iterable ), https://tc39.es/ecma262/#sec-promise.allsettled
  67. JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::all_settled)
  68. {
  69. TODO();
  70. }
  71. // 27.2.4.3 Promise.any ( iterable ), https://tc39.es/ecma262/#sec-promise.any
  72. JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::any)
  73. {
  74. TODO();
  75. }
  76. // 27.2.4.5 Promise.race ( iterable ), https://tc39.es/ecma262/#sec-promise.race
  77. JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::race)
  78. {
  79. TODO();
  80. }
  81. // 27.2.4.6 Promise.reject ( r ), https://tc39.es/ecma262/#sec-promise.reject
  82. JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::reject)
  83. {
  84. auto* constructor = vm.this_value(global_object).to_object(global_object);
  85. if (!constructor)
  86. return {};
  87. auto promise_capability = new_promise_capability(global_object, constructor);
  88. if (vm.exception())
  89. return {};
  90. auto reason = vm.argument(0);
  91. [[maybe_unused]] auto result = vm.call(*promise_capability.reject, js_undefined(), reason);
  92. return promise_capability.promise;
  93. }
  94. // 27.2.4.7 Promise.resolve ( x ), https://tc39.es/ecma262/#sec-promise.resolve
  95. JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::resolve)
  96. {
  97. auto* constructor = vm.this_value(global_object).to_object(global_object);
  98. if (!constructor)
  99. return {};
  100. auto value = vm.argument(0);
  101. return promise_resolve(global_object, *constructor, value);
  102. }
  103. // 27.2.4.8 get Promise [ @@species ], https://tc39.es/ecma262/#sec-get-promise-@@species
  104. JS_DEFINE_NATIVE_GETTER(PromiseConstructor::symbol_species_getter)
  105. {
  106. return vm.this_value(global_object);
  107. }
  108. }