| 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 738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 979 | 975 |
| 980 // ES#sec-promise-reject-functions | 976 // ES#sec-promise-reject-functions |
| 981 // Promise Reject Functions | 977 // Promise Reject Functions |
| 982 TF_BUILTIN(PromiseRejectClosure, PromiseBuiltinsAssembler) { | 978 TF_BUILTIN(PromiseRejectClosure, PromiseBuiltinsAssembler) { |
| 983 Node* const value = Parameter(1); | 979 Node* const value = Parameter(1); |
| 984 Node* const context = Parameter(4); | 980 Node* const context = Parameter(4); |
| 985 | 981 |
| 986 Label out(this); | 982 Label out(this); |
| 987 | 983 |
| 988 // 3. Let alreadyResolved be F.[[AlreadyResolved]]. | 984 // 3. Let alreadyResolved be F.[[AlreadyResolved]]. |
| 989 int has_already_visited_slot = PromiseUtils::kAlreadyVisitedSlot; | 985 int has_already_visited_slot = kAlreadyVisitedSlot; |
| 990 | 986 |
| 991 Node* const has_already_visited = | 987 Node* const has_already_visited = |
| 992 LoadContextElement(context, has_already_visited_slot); | 988 LoadContextElement(context, has_already_visited_slot); |
| 993 | 989 |
| 994 // 4. If alreadyResolved.[[Value]] is true, return undefined. | 990 // 4. If alreadyResolved.[[Value]] is true, return undefined. |
| 995 GotoIf(SmiEqual(has_already_visited, SmiConstant(1)), &out); | 991 GotoIf(SmiEqual(has_already_visited, SmiConstant(1)), &out); |
| 996 | 992 |
| 997 // 5.Set alreadyResolved.[[Value]] to true. | 993 // 5.Set alreadyResolved.[[Value]] to true. |
| 998 StoreContextElementNoWriteBarrier(context, has_already_visited_slot, | 994 StoreContextElementNoWriteBarrier(context, has_already_visited_slot, |
| 999 SmiConstant(1)); | 995 SmiConstant(1)); |
| 1000 | 996 |
| 1001 // 2. Let promise be F.[[Promise]]. | 997 // 2. Let promise be F.[[Promise]]. |
| 1002 Node* const promise = | 998 Node* const promise = |
| 1003 LoadContextElement(context, IntPtrConstant(PromiseUtils::kPromiseSlot)); | 999 LoadContextElement(context, IntPtrConstant(kPromiseSlot)); |
| 1004 Node* const debug_event = LoadContextElement( | 1000 Node* const debug_event = |
| 1005 context, IntPtrConstant(PromiseUtils::kDebugEventSlot)); | 1001 LoadContextElement(context, IntPtrConstant(kDebugEventSlot)); |
| 1006 | 1002 |
| 1007 InternalPromiseReject(context, promise, value, debug_event); | 1003 InternalPromiseReject(context, promise, value, debug_event); |
| 1008 Return(UndefinedConstant()); | 1004 Return(UndefinedConstant()); |
| 1009 | 1005 |
| 1010 Bind(&out); | 1006 Bind(&out); |
| 1011 Return(UndefinedConstant()); | 1007 Return(UndefinedConstant()); |
| 1012 } | 1008 } |
| 1013 | 1009 |
| 1014 TF_BUILTIN(PromiseConstructor, PromiseBuiltinsAssembler) { | 1010 TF_BUILTIN(PromiseConstructor, PromiseBuiltinsAssembler) { |
| 1015 Node* const executor = Parameter(1); | 1011 Node* const executor = Parameter(1); |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1186 | 1182 |
| 1187 // ES#sec-promise-resolve-functions | 1183 // ES#sec-promise-resolve-functions |
| 1188 // Promise Resolve Functions | 1184 // Promise Resolve Functions |
| 1189 TF_BUILTIN(PromiseResolveClosure, PromiseBuiltinsAssembler) { | 1185 TF_BUILTIN(PromiseResolveClosure, PromiseBuiltinsAssembler) { |
| 1190 Node* const value = Parameter(1); | 1186 Node* const value = Parameter(1); |
| 1191 Node* const context = Parameter(4); | 1187 Node* const context = Parameter(4); |
| 1192 | 1188 |
| 1193 Label out(this); | 1189 Label out(this); |
| 1194 | 1190 |
| 1195 // 3. Let alreadyResolved be F.[[AlreadyResolved]]. | 1191 // 3. Let alreadyResolved be F.[[AlreadyResolved]]. |
| 1196 int has_already_visited_slot = PromiseUtils::kAlreadyVisitedSlot; | 1192 int has_already_visited_slot = kAlreadyVisitedSlot; |
| 1197 | 1193 |
| 1198 Node* const has_already_visited = | 1194 Node* const has_already_visited = |
| 1199 LoadContextElement(context, has_already_visited_slot); | 1195 LoadContextElement(context, has_already_visited_slot); |
| 1200 | 1196 |
| 1201 // 4. If alreadyResolved.[[Value]] is true, return undefined. | 1197 // 4. If alreadyResolved.[[Value]] is true, return undefined. |
| 1202 GotoIf(SmiEqual(has_already_visited, SmiConstant(1)), &out); | 1198 GotoIf(SmiEqual(has_already_visited, SmiConstant(1)), &out); |
| 1203 | 1199 |
| 1204 // 5.Set alreadyResolved.[[Value]] to true. | 1200 // 5.Set alreadyResolved.[[Value]] to true. |
| 1205 StoreContextElementNoWriteBarrier(context, has_already_visited_slot, | 1201 StoreContextElementNoWriteBarrier(context, has_already_visited_slot, |
| 1206 SmiConstant(1)); | 1202 SmiConstant(1)); |
| 1207 | 1203 |
| 1208 // 2. Let promise be F.[[Promise]]. | 1204 // 2. Let promise be F.[[Promise]]. |
| 1209 Node* const promise = | 1205 Node* const promise = |
| 1210 LoadContextElement(context, IntPtrConstant(PromiseUtils::kPromiseSlot)); | 1206 LoadContextElement(context, IntPtrConstant(kPromiseSlot)); |
| 1211 | 1207 |
| 1212 InternalResolvePromise(context, promise, value); | 1208 InternalResolvePromise(context, promise, value); |
| 1213 Return(UndefinedConstant()); | 1209 Return(UndefinedConstant()); |
| 1214 | 1210 |
| 1215 Bind(&out); | 1211 Bind(&out); |
| 1216 Return(UndefinedConstant()); | 1212 Return(UndefinedConstant()); |
| 1217 } | 1213 } |
| 1218 | 1214 |
| 1219 TF_BUILTIN(ResolvePromise, PromiseBuiltinsAssembler) { | 1215 TF_BUILTIN(ResolvePromise, PromiseBuiltinsAssembler) { |
| 1220 Node* const promise = Parameter(1); | 1216 Node* const promise = Parameter(1); |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1453 Return(result); | 1449 Return(result); |
| 1454 } | 1450 } |
| 1455 } | 1451 } |
| 1456 } | 1452 } |
| 1457 | 1453 |
| 1458 TF_BUILTIN(PromiseGetCapabilitiesExecutor, PromiseBuiltinsAssembler) { | 1454 TF_BUILTIN(PromiseGetCapabilitiesExecutor, PromiseBuiltinsAssembler) { |
| 1459 Node* const resolve = Parameter(1); | 1455 Node* const resolve = Parameter(1); |
| 1460 Node* const reject = Parameter(2); | 1456 Node* const reject = Parameter(2); |
| 1461 Node* const context = Parameter(5); | 1457 Node* const context = Parameter(5); |
| 1462 | 1458 |
| 1463 Node* const capability = LoadContextElement( | 1459 Node* const capability = LoadContextElement(context, kCapabilitySlot); |
| 1464 context, GetPromiseCapabilityExecutor::kCapabilitySlot); | |
| 1465 | 1460 |
| 1466 Label if_alreadyinvoked(this, Label::kDeferred); | 1461 Label if_alreadyinvoked(this, Label::kDeferred); |
| 1467 GotoIf(WordNotEqual( | 1462 GotoIf(WordNotEqual( |
| 1468 LoadObjectField(capability, JSPromiseCapability::kResolveOffset), | 1463 LoadObjectField(capability, JSPromiseCapability::kResolveOffset), |
| 1469 UndefinedConstant()), | 1464 UndefinedConstant()), |
| 1470 &if_alreadyinvoked); | 1465 &if_alreadyinvoked); |
| 1471 GotoIf(WordNotEqual( | 1466 GotoIf(WordNotEqual( |
| 1472 LoadObjectField(capability, JSPromiseCapability::kRejectOffset), | 1467 LoadObjectField(capability, JSPromiseCapability::kRejectOffset), |
| 1473 UndefinedConstant()), | 1468 UndefinedConstant()), |
| 1474 &if_alreadyinvoked); | 1469 &if_alreadyinvoked); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1542 Node* const reason = Parameter(2); | 1537 Node* const reason = Parameter(2); |
| 1543 Node* const debug_event = Parameter(3); | 1538 Node* const debug_event = Parameter(3); |
| 1544 Node* const context = Parameter(6); | 1539 Node* const context = Parameter(6); |
| 1545 | 1540 |
| 1546 InternalPromiseReject(context, promise, reason, debug_event); | 1541 InternalPromiseReject(context, promise, reason, debug_event); |
| 1547 Return(UndefinedConstant()); | 1542 Return(UndefinedConstant()); |
| 1548 } | 1543 } |
| 1549 | 1544 |
| 1550 } // namespace internal | 1545 } // namespace internal |
| 1551 } // namespace v8 | 1546 } // namespace v8 |
| OLD | NEW |