| 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_ |