| OLD | NEW |
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/builtins/builtins-promise.h" | 5 #include "src/builtins/builtins-promise.h" |
| 6 #include "src/builtins/builtins-constructor.h" | 6 #include "src/builtins/builtins-constructor.h" |
| 7 #include "src/builtins/builtins-utils.h" | 7 #include "src/builtins/builtins-utils.h" |
| 8 #include "src/builtins/builtins.h" | 8 #include "src/builtins/builtins.h" |
| 9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
| 10 #include "src/code-stub-assembler.h" | 10 #include "src/code-stub-assembler.h" |
| 11 #include "src/promise-utils.h" | |
| 12 | 11 |
| 13 namespace v8 { | 12 namespace v8 { |
| 14 namespace internal { | 13 namespace internal { |
| 15 | 14 |
| 16 typedef compiler::Node Node; | 15 typedef compiler::Node Node; |
| 17 typedef CodeStubAssembler::ParameterMode ParameterMode; | 16 typedef CodeStubAssembler::ParameterMode ParameterMode; |
| 18 typedef compiler::CodeAssemblerState CodeAssemblerState; | 17 typedef compiler::CodeAssemblerState CodeAssemblerState; |
| 19 | 18 |
| 20 Node* PromiseBuiltinsAssembler::AllocateJSPromise(Node* context) { | 19 Node* PromiseBuiltinsAssembler::AllocateJSPromise(Node* context) { |
| 21 Node* const native_context = LoadNativeContext(context); | 20 Node* const native_context = LoadNativeContext(context); |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 StoreContextElementNoWriteBarrier(context, Context::EXTENSION_INDEX, | 203 StoreContextElementNoWriteBarrier(context, Context::EXTENSION_INDEX, |
| 205 TheHoleConstant()); | 204 TheHoleConstant()); |
| 206 StoreContextElementNoWriteBarrier(context, Context::NATIVE_CONTEXT_INDEX, | 205 StoreContextElementNoWriteBarrier(context, Context::NATIVE_CONTEXT_INDEX, |
| 207 native_context); | 206 native_context); |
| 208 return context; | 207 return context; |
| 209 } | 208 } |
| 210 | 209 |
| 211 Node* PromiseBuiltinsAssembler::CreatePromiseResolvingFunctionsContext( | 210 Node* PromiseBuiltinsAssembler::CreatePromiseResolvingFunctionsContext( |
| 212 Node* promise, Node* debug_event, Node* native_context) { | 211 Node* promise, Node* debug_event, Node* native_context) { |
| 213 Node* const context = | 212 Node* const context = |
| 214 CreatePromiseContext(native_context, PromiseUtils::kPromiseContextLength); | 213 CreatePromiseContext(native_context, kPromiseContextLength); |
| 215 StoreContextElementNoWriteBarrier(context, PromiseUtils::kAlreadyVisitedSlot, | 214 StoreContextElementNoWriteBarrier(context, kAlreadyVisitedSlot, |
| 216 SmiConstant(0)); | 215 SmiConstant(0)); |
| 217 StoreContextElementNoWriteBarrier(context, PromiseUtils::kPromiseSlot, | 216 StoreContextElementNoWriteBarrier(context, kPromiseSlot, promise); |
| 218 promise); | 217 StoreContextElementNoWriteBarrier(context, kDebugEventSlot, debug_event); |
| 219 StoreContextElementNoWriteBarrier(context, PromiseUtils::kDebugEventSlot, | |
| 220 debug_event); | |
| 221 return context; | 218 return context; |
| 222 } | 219 } |
| 223 | 220 |
| 224 Node* PromiseBuiltinsAssembler::CreatePromiseGetCapabilitiesExecutorContext( | 221 Node* PromiseBuiltinsAssembler::CreatePromiseGetCapabilitiesExecutorContext( |
| 225 Node* promise_capability, Node* native_context) { | 222 Node* promise_capability, Node* native_context) { |
| 226 int kContextLength = GetPromiseCapabilityExecutor::kContextLength; | 223 int kContextLength = kCapabilitiesContextLength; |
| 227 Node* context = CreatePromiseContext(native_context, kContextLength); | 224 Node* context = CreatePromiseContext(native_context, kContextLength); |
| 228 StoreContextElementNoWriteBarrier( | 225 StoreContextElementNoWriteBarrier(context, kCapabilitySlot, |
| 229 context, GetPromiseCapabilityExecutor::kCapabilitySlot, | 226 promise_capability); |
| 230 promise_capability); | |
| 231 return context; | 227 return context; |
| 232 } | 228 } |
| 233 | 229 |
| 234 Node* PromiseBuiltinsAssembler::ThrowIfNotJSReceiver( | 230 Node* PromiseBuiltinsAssembler::ThrowIfNotJSReceiver( |
| 235 Node* context, Node* value, MessageTemplate::Template msg_template, | 231 Node* context, Node* value, MessageTemplate::Template msg_template, |
| 236 const char* method_name) { | 232 const char* method_name) { |
| 237 Label out(this), throw_exception(this, Label::kDeferred); | 233 Label out(this), throw_exception(this, Label::kDeferred); |
| 238 Variable var_value_map(this, MachineRepresentation::kTagged); | 234 Variable var_value_map(this, MachineRepresentation::kTagged); |
| 239 | 235 |
| 240 GotoIf(TaggedIsSmi(value), &throw_exception); | 236 GotoIf(TaggedIsSmi(value), &throw_exception); |
| (...skipping 748 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 989 | 985 |
| 990 // ES#sec-promise-reject-functions | 986 // ES#sec-promise-reject-functions |
| 991 // Promise Reject Functions | 987 // Promise Reject Functions |
| 992 TF_BUILTIN(PromiseRejectClosure, PromiseBuiltinsAssembler) { | 988 TF_BUILTIN(PromiseRejectClosure, PromiseBuiltinsAssembler) { |
| 993 Node* const value = Parameter(1); | 989 Node* const value = Parameter(1); |
| 994 Node* const context = Parameter(4); | 990 Node* const context = Parameter(4); |
| 995 | 991 |
| 996 Label out(this); | 992 Label out(this); |
| 997 | 993 |
| 998 // 3. Let alreadyResolved be F.[[AlreadyResolved]]. | 994 // 3. Let alreadyResolved be F.[[AlreadyResolved]]. |
| 999 int has_already_visited_slot = PromiseUtils::kAlreadyVisitedSlot; | 995 int has_already_visited_slot = kAlreadyVisitedSlot; |
| 1000 | 996 |
| 1001 Node* const has_already_visited = | 997 Node* const has_already_visited = |
| 1002 LoadContextElement(context, has_already_visited_slot); | 998 LoadContextElement(context, has_already_visited_slot); |
| 1003 | 999 |
| 1004 // 4. If alreadyResolved.[[Value]] is true, return undefined. | 1000 // 4. If alreadyResolved.[[Value]] is true, return undefined. |
| 1005 GotoIf(SmiEqual(has_already_visited, SmiConstant(1)), &out); | 1001 GotoIf(SmiEqual(has_already_visited, SmiConstant(1)), &out); |
| 1006 | 1002 |
| 1007 // 5.Set alreadyResolved.[[Value]] to true. | 1003 // 5.Set alreadyResolved.[[Value]] to true. |
| 1008 StoreContextElementNoWriteBarrier(context, has_already_visited_slot, | 1004 StoreContextElementNoWriteBarrier(context, has_already_visited_slot, |
| 1009 SmiConstant(1)); | 1005 SmiConstant(1)); |
| 1010 | 1006 |
| 1011 // 2. Let promise be F.[[Promise]]. | 1007 // 2. Let promise be F.[[Promise]]. |
| 1012 Node* const promise = | 1008 Node* const promise = |
| 1013 LoadContextElement(context, IntPtrConstant(PromiseUtils::kPromiseSlot)); | 1009 LoadContextElement(context, IntPtrConstant(kPromiseSlot)); |
| 1014 Node* const debug_event = LoadContextElement( | 1010 Node* const debug_event = |
| 1015 context, IntPtrConstant(PromiseUtils::kDebugEventSlot)); | 1011 LoadContextElement(context, IntPtrConstant(kDebugEventSlot)); |
| 1016 | 1012 |
| 1017 InternalPromiseReject(context, promise, value, debug_event); | 1013 InternalPromiseReject(context, promise, value, debug_event); |
| 1018 Return(UndefinedConstant()); | 1014 Return(UndefinedConstant()); |
| 1019 | 1015 |
| 1020 Bind(&out); | 1016 Bind(&out); |
| 1021 Return(UndefinedConstant()); | 1017 Return(UndefinedConstant()); |
| 1022 } | 1018 } |
| 1023 | 1019 |
| 1024 TF_BUILTIN(PromiseConstructor, PromiseBuiltinsAssembler) { | 1020 TF_BUILTIN(PromiseConstructor, PromiseBuiltinsAssembler) { |
| 1025 Node* const executor = Parameter(1); | 1021 Node* const executor = Parameter(1); |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1196 | 1192 |
| 1197 // ES#sec-promise-resolve-functions | 1193 // ES#sec-promise-resolve-functions |
| 1198 // Promise Resolve Functions | 1194 // Promise Resolve Functions |
| 1199 TF_BUILTIN(PromiseResolveClosure, PromiseBuiltinsAssembler) { | 1195 TF_BUILTIN(PromiseResolveClosure, PromiseBuiltinsAssembler) { |
| 1200 Node* const value = Parameter(1); | 1196 Node* const value = Parameter(1); |
| 1201 Node* const context = Parameter(4); | 1197 Node* const context = Parameter(4); |
| 1202 | 1198 |
| 1203 Label out(this); | 1199 Label out(this); |
| 1204 | 1200 |
| 1205 // 3. Let alreadyResolved be F.[[AlreadyResolved]]. | 1201 // 3. Let alreadyResolved be F.[[AlreadyResolved]]. |
| 1206 int has_already_visited_slot = PromiseUtils::kAlreadyVisitedSlot; | 1202 int has_already_visited_slot = kAlreadyVisitedSlot; |
| 1207 | 1203 |
| 1208 Node* const has_already_visited = | 1204 Node* const has_already_visited = |
| 1209 LoadContextElement(context, has_already_visited_slot); | 1205 LoadContextElement(context, has_already_visited_slot); |
| 1210 | 1206 |
| 1211 // 4. If alreadyResolved.[[Value]] is true, return undefined. | 1207 // 4. If alreadyResolved.[[Value]] is true, return undefined. |
| 1212 GotoIf(SmiEqual(has_already_visited, SmiConstant(1)), &out); | 1208 GotoIf(SmiEqual(has_already_visited, SmiConstant(1)), &out); |
| 1213 | 1209 |
| 1214 // 5.Set alreadyResolved.[[Value]] to true. | 1210 // 5.Set alreadyResolved.[[Value]] to true. |
| 1215 StoreContextElementNoWriteBarrier(context, has_already_visited_slot, | 1211 StoreContextElementNoWriteBarrier(context, has_already_visited_slot, |
| 1216 SmiConstant(1)); | 1212 SmiConstant(1)); |
| 1217 | 1213 |
| 1218 // 2. Let promise be F.[[Promise]]. | 1214 // 2. Let promise be F.[[Promise]]. |
| 1219 Node* const promise = | 1215 Node* const promise = |
| 1220 LoadContextElement(context, IntPtrConstant(PromiseUtils::kPromiseSlot)); | 1216 LoadContextElement(context, IntPtrConstant(kPromiseSlot)); |
| 1221 | 1217 |
| 1222 InternalResolvePromise(context, promise, value); | 1218 InternalResolvePromise(context, promise, value); |
| 1223 Return(UndefinedConstant()); | 1219 Return(UndefinedConstant()); |
| 1224 | 1220 |
| 1225 Bind(&out); | 1221 Bind(&out); |
| 1226 Return(UndefinedConstant()); | 1222 Return(UndefinedConstant()); |
| 1227 } | 1223 } |
| 1228 | 1224 |
| 1229 TF_BUILTIN(ResolvePromise, PromiseBuiltinsAssembler) { | 1225 TF_BUILTIN(ResolvePromise, PromiseBuiltinsAssembler) { |
| 1230 Node* const promise = Parameter(1); | 1226 Node* const promise = Parameter(1); |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1463 Return(result); | 1459 Return(result); |
| 1464 } | 1460 } |
| 1465 } | 1461 } |
| 1466 } | 1462 } |
| 1467 | 1463 |
| 1468 TF_BUILTIN(PromiseGetCapabilitiesExecutor, PromiseBuiltinsAssembler) { | 1464 TF_BUILTIN(PromiseGetCapabilitiesExecutor, PromiseBuiltinsAssembler) { |
| 1469 Node* const resolve = Parameter(1); | 1465 Node* const resolve = Parameter(1); |
| 1470 Node* const reject = Parameter(2); | 1466 Node* const reject = Parameter(2); |
| 1471 Node* const context = Parameter(5); | 1467 Node* const context = Parameter(5); |
| 1472 | 1468 |
| 1473 Node* const capability = LoadContextElement( | 1469 Node* const capability = LoadContextElement(context, kCapabilitySlot); |
| 1474 context, GetPromiseCapabilityExecutor::kCapabilitySlot); | |
| 1475 | 1470 |
| 1476 Label if_alreadyinvoked(this, Label::kDeferred); | 1471 Label if_alreadyinvoked(this, Label::kDeferred); |
| 1477 GotoIf(WordNotEqual( | 1472 GotoIf(WordNotEqual( |
| 1478 LoadObjectField(capability, JSPromiseCapability::kResolveOffset), | 1473 LoadObjectField(capability, JSPromiseCapability::kResolveOffset), |
| 1479 UndefinedConstant()), | 1474 UndefinedConstant()), |
| 1480 &if_alreadyinvoked); | 1475 &if_alreadyinvoked); |
| 1481 GotoIf(WordNotEqual( | 1476 GotoIf(WordNotEqual( |
| 1482 LoadObjectField(capability, JSPromiseCapability::kRejectOffset), | 1477 LoadObjectField(capability, JSPromiseCapability::kRejectOffset), |
| 1483 UndefinedConstant()), | 1478 UndefinedConstant()), |
| 1484 &if_alreadyinvoked); | 1479 &if_alreadyinvoked); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1552 Node* const reason = Parameter(2); | 1547 Node* const reason = Parameter(2); |
| 1553 Node* const debug_event = Parameter(3); | 1548 Node* const debug_event = Parameter(3); |
| 1554 Node* const context = Parameter(6); | 1549 Node* const context = Parameter(6); |
| 1555 | 1550 |
| 1556 InternalPromiseReject(context, promise, reason, debug_event); | 1551 InternalPromiseReject(context, promise, reason, debug_event); |
| 1557 Return(UndefinedConstant()); | 1552 Return(UndefinedConstant()); |
| 1558 } | 1553 } |
| 1559 | 1554 |
| 1560 } // namespace internal | 1555 } // namespace internal |
| 1561 } // namespace v8 | 1556 } // namespace v8 |
| OLD | NEW |