File: | out/../deps/v8/include/v8-maybe.h |
Warning: | line 62, column 5 Undefined or garbage value returned to caller |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | // Copyright 2019 the V8 project authors. All rights reserved. | |||
2 | // Use of this source code is governed by a BSD-style license that can be | |||
3 | // found in the LICENSE file. | |||
4 | ||||
5 | #include "src/objects/synthetic-module.h" | |||
6 | ||||
7 | #include "src/api/api-inl.h" | |||
8 | #include "src/builtins/accessors.h" | |||
9 | #include "src/objects/js-generator-inl.h" | |||
10 | #include "src/objects/module-inl.h" | |||
11 | #include "src/objects/objects-inl.h" | |||
12 | #include "src/objects/shared-function-info.h" | |||
13 | #include "src/objects/synthetic-module-inl.h" | |||
14 | #include "src/utils/ostreams.h" | |||
15 | ||||
16 | namespace v8 { | |||
17 | namespace internal { | |||
18 | ||||
19 | // Implements SetSyntheticModuleBinding: | |||
20 | // https://heycam.github.io/webidl/#setsyntheticmoduleexport | |||
21 | Maybe<bool> SyntheticModule::SetExport(Isolate* isolate, | |||
22 | Handle<SyntheticModule> module, | |||
23 | Handle<String> export_name, | |||
24 | Handle<Object> export_value) { | |||
25 | Handle<ObjectHashTable> exports(module->exports(), isolate); | |||
26 | Handle<Object> export_object(exports->Lookup(export_name), isolate); | |||
27 | ||||
28 | if (!export_object->IsCell()) { | |||
29 | isolate->Throw(*isolate->factory()->NewReferenceError( | |||
30 | MessageTemplate::kModuleExportUndefined, export_name)); | |||
31 | return Nothing<bool>(); | |||
32 | } | |||
33 | ||||
34 | // Spec step 2: Set the mutable binding of export_name to export_value | |||
35 | Cell::cast(*export_object).set_value(*export_value); | |||
36 | ||||
37 | return Just(true); | |||
38 | } | |||
39 | ||||
40 | void SyntheticModule::SetExportStrict(Isolate* isolate, | |||
41 | Handle<SyntheticModule> module, | |||
42 | Handle<String> export_name, | |||
43 | Handle<Object> export_value) { | |||
44 | Handle<ObjectHashTable> exports(module->exports(), isolate); | |||
45 | Handle<Object> export_object(exports->Lookup(export_name), isolate); | |||
46 | CHECK(export_object->IsCell())do { if ((__builtin_expect(!!(!(export_object->IsCell())), 0))) { V8_Fatal("Check failed: %s.", "export_object->IsCell()" ); } } while (false); | |||
| ||||
47 | Maybe<bool> set_export_result = | |||
48 | SetExport(isolate, module, export_name, export_value); | |||
49 | CHECK(set_export_result.FromJust())do { if ((__builtin_expect(!!(!(set_export_result.FromJust()) ), 0))) { V8_Fatal("Check failed: %s.", "set_export_result.FromJust()" ); } } while (false); | |||
50 | } | |||
51 | ||||
52 | // Implements Synthetic Module Record's ResolveExport concrete method: | |||
53 | // https://heycam.github.io/webidl/#smr-resolveexport | |||
54 | MaybeHandle<Cell> SyntheticModule::ResolveExport( | |||
55 | Isolate* isolate, Handle<SyntheticModule> module, | |||
56 | Handle<String> module_specifier, Handle<String> export_name, | |||
57 | MessageLocation loc, bool must_resolve) { | |||
58 | Handle<Object> object(module->exports().Lookup(export_name), isolate); | |||
59 | if (object->IsCell()) return Handle<Cell>::cast(object); | |||
60 | ||||
61 | if (!must_resolve) return MaybeHandle<Cell>(); | |||
62 | ||||
63 | return isolate->ThrowAt<Cell>( | |||
64 | isolate->factory()->NewSyntaxError(MessageTemplate::kUnresolvableExport, | |||
65 | module_specifier, export_name), | |||
66 | &loc); | |||
67 | } | |||
68 | ||||
69 | // Implements Synthetic Module Record's Instantiate concrete method : | |||
70 | // https://heycam.github.io/webidl/#smr-instantiate | |||
71 | bool SyntheticModule::PrepareInstantiate(Isolate* isolate, | |||
72 | Handle<SyntheticModule> module, | |||
73 | v8::Local<v8::Context> context) { | |||
74 | Handle<ObjectHashTable> exports(module->exports(), isolate); | |||
75 | Handle<FixedArray> export_names(module->export_names(), isolate); | |||
76 | // Spec step 7: For each export_name in module->export_names... | |||
77 | for (int i = 0, n = export_names->length(); i < n; ++i) { | |||
78 | // Spec step 7.1: Create a new mutable binding for export_name. | |||
79 | // Spec step 7.2: Initialize the new mutable binding to undefined. | |||
80 | Handle<Cell> cell = | |||
81 | isolate->factory()->NewCell(isolate->factory()->undefined_value()); | |||
82 | Handle<String> name(String::cast(export_names->get(i)), isolate); | |||
83 | CHECK(exports->Lookup(name).IsTheHole(isolate))do { if ((__builtin_expect(!!(!(exports->Lookup(name).IsTheHole (isolate))), 0))) { V8_Fatal("Check failed: %s.", "exports->Lookup(name).IsTheHole(isolate)" ); } } while (false); | |||
84 | exports = ObjectHashTable::Put(exports, name, cell); | |||
85 | } | |||
86 | module->set_exports(*exports); | |||
87 | return true; | |||
88 | } | |||
89 | ||||
90 | // Second step of module instantiation. No real work to do for SyntheticModule | |||
91 | // as there are no imports or indirect exports to resolve; | |||
92 | // just update status. | |||
93 | bool SyntheticModule::FinishInstantiate(Isolate* isolate, | |||
94 | Handle<SyntheticModule> module) { | |||
95 | module->SetStatus(kLinked); | |||
96 | return true; | |||
97 | } | |||
98 | ||||
99 | // Implements Synthetic Module Record's Evaluate concrete method: | |||
100 | // https://heycam.github.io/webidl/#smr-evaluate | |||
101 | MaybeHandle<Object> SyntheticModule::Evaluate(Isolate* isolate, | |||
102 | Handle<SyntheticModule> module) { | |||
103 | module->SetStatus(kEvaluating); | |||
104 | ||||
105 | v8::Module::SyntheticModuleEvaluationSteps evaluation_steps = | |||
106 | FUNCTION_CAST<v8::Module::SyntheticModuleEvaluationSteps>( | |||
107 | module->evaluation_steps().foreign_address()); | |||
108 | v8::Local<v8::Value> result; | |||
109 | if (!evaluation_steps( | |||
110 | Utils::ToLocal(Handle<Context>::cast(isolate->native_context())), | |||
111 | Utils::ToLocal(Handle<Module>::cast(module))) | |||
112 | .ToLocal(&result)) { | |||
113 | isolate->PromoteScheduledException(); | |||
114 | Module::RecordErrorUsingPendingException(isolate, module); | |||
115 | return MaybeHandle<Object>(); | |||
116 | } | |||
117 | ||||
118 | module->SetStatus(kEvaluated); | |||
119 | ||||
120 | Handle<Object> result_from_callback = Utils::OpenHandle(*result); | |||
121 | ||||
122 | Handle<JSPromise> capability; | |||
123 | if (result_from_callback->IsJSPromise()) { | |||
124 | capability = Handle<JSPromise>::cast(result_from_callback); | |||
125 | } else { | |||
126 | // The host's evaluation steps should have returned a resolved Promise, | |||
127 | // but as an allowance to hosts that have not yet finished the migration | |||
128 | // to top-level await, create a Promise if the callback result didn't give | |||
129 | // us one. | |||
130 | capability = isolate->factory()->NewJSPromise(); | |||
131 | JSPromise::Resolve(capability, isolate->factory()->undefined_value()) | |||
132 | .ToHandleChecked(); | |||
133 | } | |||
134 | ||||
135 | module->set_top_level_capability(*capability); | |||
136 | ||||
137 | return result_from_callback; | |||
138 | } | |||
139 | ||||
140 | } // namespace internal | |||
141 | } // namespace v8 |
1 | // Copyright 2021 the V8 project authors. All rights reserved. | |||
2 | // Use of this source code is governed by a BSD-style license that can be | |||
3 | // found in the LICENSE file. | |||
4 | ||||
5 | #ifndef INCLUDE_V8_MAYBE_H_ | |||
6 | #define INCLUDE_V8_MAYBE_H_ | |||
7 | ||||
8 | #include "v8-internal.h" // NOLINT(build/include_directory) | |||
9 | #include "v8config.h" // NOLINT(build/include_directory) | |||
10 | ||||
11 | namespace v8 { | |||
12 | ||||
13 | namespace api_internal { | |||
14 | // Called when ToChecked is called on an empty Maybe. | |||
15 | V8_EXPORT void FromJustIsNothing(); | |||
16 | } // namespace api_internal | |||
17 | ||||
18 | /** | |||
19 | * A simple Maybe type, representing an object which may or may not have a | |||
20 | * value, see https://hackage.haskell.org/package/base/docs/Data-Maybe.html. | |||
21 | * | |||
22 | * If an API method returns a Maybe<>, the API method can potentially fail | |||
23 | * either because an exception is thrown, or because an exception is pending, | |||
24 | * e.g. because a previous API call threw an exception that hasn't been caught | |||
25 | * yet, or because a TerminateExecution exception was thrown. In that case, a | |||
26 | * "Nothing" value is returned. | |||
27 | */ | |||
28 | template <class T> | |||
29 | class Maybe { | |||
30 | public: | |||
31 | V8_INLINEinline __attribute__((always_inline)) bool IsNothing() const { return !has_value_; } | |||
32 | V8_INLINEinline __attribute__((always_inline)) bool IsJust() const { return has_value_; } | |||
33 | ||||
34 | /** | |||
35 | * An alias for |FromJust|. Will crash if the Maybe<> is nothing. | |||
36 | */ | |||
37 | V8_INLINEinline __attribute__((always_inline)) T ToChecked() const { return FromJust(); } | |||
38 | ||||
39 | /** | |||
40 | * Short-hand for ToChecked(), which doesn't return a value. To be used, where | |||
41 | * the actual value of the Maybe is not needed like Object::Set. | |||
42 | */ | |||
43 | V8_INLINEinline __attribute__((always_inline)) void Check() const { | |||
44 | if (V8_UNLIKELY(!IsJust())(__builtin_expect(!!(!IsJust()), 0))) api_internal::FromJustIsNothing(); | |||
45 | } | |||
46 | ||||
47 | /** | |||
48 | * Converts this Maybe<> to a value of type T. If this Maybe<> is | |||
49 | * nothing (empty), |false| is returned and |out| is left untouched. | |||
50 | */ | |||
51 | V8_WARN_UNUSED_RESULT__attribute__((warn_unused_result)) V8_INLINEinline __attribute__((always_inline)) bool To(T* out) const { | |||
52 | if (V8_LIKELY(IsJust())(__builtin_expect(!!(IsJust()), 1))) *out = value_; | |||
53 | return IsJust(); | |||
54 | } | |||
55 | ||||
56 | /** | |||
57 | * Converts this Maybe<> to a value of type T. If this Maybe<> is | |||
58 | * nothing (empty), V8 will crash the process. | |||
59 | */ | |||
60 | V8_INLINEinline __attribute__((always_inline)) T FromJust() const { | |||
61 | if (V8_UNLIKELY(!IsJust())(__builtin_expect(!!(!IsJust()), 0))) api_internal::FromJustIsNothing(); | |||
62 | return value_; | |||
| ||||
63 | } | |||
64 | ||||
65 | /** | |||
66 | * Converts this Maybe<> to a value of type T, using a default value if this | |||
67 | * Maybe<> is nothing (empty). | |||
68 | */ | |||
69 | V8_INLINEinline __attribute__((always_inline)) T FromMaybe(const T& default_value) const { | |||
70 | return has_value_ ? value_ : default_value; | |||
71 | } | |||
72 | ||||
73 | V8_INLINEinline __attribute__((always_inline)) bool operator==(const Maybe& other) const { | |||
74 | return (IsJust() == other.IsJust()) && | |||
75 | (!IsJust() || FromJust() == other.FromJust()); | |||
76 | } | |||
77 | ||||
78 | V8_INLINEinline __attribute__((always_inline)) bool operator!=(const Maybe& other) const { | |||
79 | return !operator==(other); | |||
80 | } | |||
81 | ||||
82 | private: | |||
83 | Maybe() : has_value_(false) {} | |||
84 | explicit Maybe(const T& t) : has_value_(true), value_(t) {} | |||
85 | ||||
86 | bool has_value_; | |||
87 | T value_; | |||
88 | ||||
89 | template <class U> | |||
90 | friend Maybe<U> Nothing(); | |||
91 | template <class U> | |||
92 | friend Maybe<U> Just(const U& u); | |||
93 | }; | |||
94 | ||||
95 | template <class T> | |||
96 | inline Maybe<T> Nothing() { | |||
97 | return Maybe<T>(); | |||
98 | } | |||
99 | ||||
100 | template <class T> | |||
101 | inline Maybe<T> Just(const T& t) { | |||
102 | return Maybe<T>(t); | |||
103 | } | |||
104 | ||||
105 | // A template specialization of Maybe<T> for the case of T = void. | |||
106 | template <> | |||
107 | class Maybe<void> { | |||
108 | public: | |||
109 | V8_INLINEinline __attribute__((always_inline)) bool IsNothing() const { return !is_valid_; } | |||
110 | V8_INLINEinline __attribute__((always_inline)) bool IsJust() const { return is_valid_; } | |||
111 | ||||
112 | V8_INLINEinline __attribute__((always_inline)) bool operator==(const Maybe& other) const { | |||
113 | return IsJust() == other.IsJust(); | |||
114 | } | |||
115 | ||||
116 | V8_INLINEinline __attribute__((always_inline)) bool operator!=(const Maybe& other) const { | |||
117 | return !operator==(other); | |||
118 | } | |||
119 | ||||
120 | private: | |||
121 | struct JustTag {}; | |||
122 | ||||
123 | Maybe() : is_valid_(false) {} | |||
124 | explicit Maybe(JustTag) : is_valid_(true) {} | |||
125 | ||||
126 | bool is_valid_; | |||
127 | ||||
128 | template <class U> | |||
129 | friend Maybe<U> Nothing(); | |||
130 | friend Maybe<void> JustVoid(); | |||
131 | }; | |||
132 | ||||
133 | inline Maybe<void> JustVoid() { return Maybe<void>(Maybe<void>::JustTag()); } | |||
134 | ||||
135 | } // namespace v8 | |||
136 | ||||
137 | #endif // INCLUDE_V8_MAYBE_H_ |