Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Unified Diff: src/builtins/builtins-promise.cc

Issue 2497523002: [promises] Move promise constructor to TFS (Closed)
Patch Set: fix nits Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/builtins/builtins.h ('k') | src/contexts.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/builtins/builtins-promise.cc
diff --git a/src/builtins/builtins-promise.cc b/src/builtins/builtins-promise.cc
index 9f5d7c88d7885e8bfbcefe65fdc80c729301b305..c12d1ebc9e221c9330f7613294e17c1fa3be960f 100644
--- a/src/builtins/builtins-promise.cc
+++ b/src/builtins/builtins-promise.cc
@@ -5,6 +5,7 @@
#include "src/builtins/builtins-utils.h"
#include "src/builtins/builtins.h"
+#include "src/code-factory.h"
#include "src/promise-utils.h"
namespace v8 {
@@ -80,5 +81,163 @@ BUILTIN(CreateResolvingFunctions) {
NOT_TENURED);
}
+void Builtins::Generate_PromiseConstructor(
+ compiler::CodeAssemblerState* state) {
+ CodeStubAssembler a(state);
+ typedef CodeStubAssembler::Variable Variable;
+ typedef CodeStubAssembler::Label Label;
+ typedef compiler::Node Node;
+
+ Node* const executor = a.Parameter(1);
+ Node* const new_target = a.Parameter(2);
+ Node* const context = a.Parameter(4);
+ Isolate* isolate = a.isolate();
+
+ Label if_targetisundefined(&a, Label::kDeferred);
+
+ a.GotoIf(a.IsUndefined(new_target), &if_targetisundefined);
+
+ Label if_notcallable(&a, Label::kDeferred);
+
+ a.GotoIf(a.TaggedIsSmi(executor), &if_notcallable);
+
+ Node* const executor_map = a.LoadMap(executor);
+ a.GotoUnless(a.IsCallableMap(executor_map), &if_notcallable);
+
+ Node* const native_context = a.LoadNativeContext(context);
+ Node* const promise_fun =
+ a.LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
+ Node* const is_debug_active = a.IsDebugActive();
+
+ Label if_targetisnotmodified(&a), if_targetismodified(&a, Label::kDeferred),
+ run_executor(&a), debug_push(&a, Label::kDeferred);
+ a.Branch(a.WordEqual(promise_fun, new_target), &if_targetisnotmodified,
+ &if_targetismodified);
+
+ Variable var_result(&a, MachineRepresentation::kTagged),
+ var_reject_call(&a, MachineRepresentation::kTagged),
+ var_reason(&a, MachineRepresentation::kTagged);
+
+ a.Bind(&if_targetisnotmodified);
+ {
+ Node* const initial_map = a.LoadObjectField(
+ promise_fun, JSFunction::kPrototypeOrInitialMapOffset);
+
+ Node* const instance = a.AllocateJSObjectFromMap(initial_map);
+ var_result.Bind(instance);
+ a.Branch(is_debug_active, &debug_push, &run_executor);
+ }
+
+ a.Bind(&if_targetismodified);
+ {
+ Callable fast_new_object_stub = CodeFactory::FastNewObject(isolate);
+ Node* const instance =
+ a.CallStub(fast_new_object_stub, context, promise_fun, new_target);
+
+ var_result.Bind(instance);
+ a.Branch(is_debug_active, &debug_push, &run_executor);
+ }
+
+ a.Bind(&debug_push);
+ {
+ a.CallRuntime(Runtime::kDebugPushPromise, context, var_result.value());
+ a.Goto(&run_executor);
+ }
+
+ a.Bind(&run_executor);
+ {
+ Label out(&a), if_rejectpromise(&a), debug_pop(&a, Label::kDeferred);
+
+ Node* const key = a.LoadRoot(Heap::kpromise_state_symbolRootIndex);
+ Node* const value = a.SmiConstant(kPromisePending);
+ Node* const language_mode = a.SmiConstant(STRICT);
+ // TODO(ishell): Use SetProperty stub once available.
+ a.CallRuntime(Runtime::kSetProperty, context, var_result.value(), key,
+ value, language_mode);
+ Node* const resolving_functions = a.CallRuntime(
+ Runtime::kCreateResolvingFunctions, context, var_result.value());
+ Node* const resolve =
+ a.LoadFixedArrayElement(resolving_functions, a.IntPtrConstant(0));
+ Node* const reject =
+ a.LoadFixedArrayElement(resolving_functions, a.IntPtrConstant(1));
+ Callable call_callable = CodeFactory::Call(isolate);
+
+ Node* const maybe_exception =
+ a.CallJS(call_callable, context, executor, a.UndefinedConstant(),
+ resolve, reject);
+
+ a.GotoIfException(maybe_exception, &if_rejectpromise, &var_reason);
+ a.Branch(is_debug_active, &debug_pop, &out);
+
+ a.Bind(&if_rejectpromise);
+ {
+ Callable call_callable = CodeFactory::Call(isolate);
+ a.CallJS(call_callable, context, reject, a.UndefinedConstant(),
+ var_reason.value());
+ a.Branch(is_debug_active, &debug_pop, &out);
+ }
+
+ a.Bind(&debug_pop);
+ {
+ a.CallRuntime(Runtime::kDebugPopPromise, context);
+ a.Goto(&out);
+ }
+ a.Bind(&out);
+ a.Return(var_result.value());
+ }
+
+ // 1. If NewTarget is undefined, throw a TypeError exception.
+ a.Bind(&if_targetisundefined);
+ {
+ Node* const message_id = a.SmiConstant(MessageTemplate::kNotAPromise);
+ a.CallRuntime(Runtime::kThrowTypeError, context, message_id, new_target);
+ a.Return(a.UndefinedConstant()); // Never reached.
+ }
+
+ // 2. If IsCallable(executor) is false, throw a TypeError exception.
+ a.Bind(&if_notcallable);
+ {
+ Node* const message_id =
+ a.SmiConstant(MessageTemplate::kResolverNotAFunction);
+ a.CallRuntime(Runtime::kThrowTypeError, context, message_id, executor);
+ a.Return(a.UndefinedConstant()); // Never reached.
+ }
+}
+
+void Builtins::Generate_PromiseInternalConstructor(
+ compiler::CodeAssemblerState* state) {
+ typedef compiler::Node Node;
+ CodeStubAssembler a(state);
+
+ Node* const context = a.Parameter(3);
+ Node* const native_context = a.LoadNativeContext(context);
+ Node* const promise_fun =
+ a.LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
+ Node* const initial_map =
+ a.LoadObjectField(promise_fun, JSFunction::kPrototypeOrInitialMapOffset);
+ Node* const instance = a.AllocateJSObjectFromMap(initial_map);
+ a.Return(instance);
+}
+
+// TODO(gsathya): Refactor promise.js::IsPromise to use this.
+void Builtins::Generate_IsPromise(compiler::CodeAssemblerState* state) {
+ CodeStubAssembler a(state);
+ typedef compiler::Node Node;
+ typedef CodeStubAssembler::Label Label;
+
+ Node* const maybe_promise = a.Parameter(1);
+ Label if_ispromise(&a), if_isnotpromise(&a, Label::kDeferred);
+ a.GotoIf(a.TaggedIsSmi(maybe_promise), &if_isnotpromise);
+
+ a.Branch(a.HasInstanceType(maybe_promise, JS_PROMISE_TYPE), &if_ispromise,
+ &if_isnotpromise);
+
+ a.Bind(&if_ispromise);
+ a.Return(a.BooleanConstant(true));
+
+ a.Bind(&if_isnotpromise);
+ a.Return(a.BooleanConstant(false));
+}
+
} // namespace internal
} // namespace v8
« no previous file with comments | « src/builtins/builtins.h ('k') | src/contexts.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698