1 // Copyright 2018 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 V8_API_API_INL_H_
6 #define V8_API_API_INL_H_
7
8 #include "src/api/api.h"
9 #include "src/handles/handles-inl.h"
10 #include "src/objects/foreign-inl.h"
11 #include "src/objects/js-weak-refs.h"
12 #include "src/objects/objects-inl.h"
13 #include "src/objects/stack-frame-info.h"
14
15 namespace v8 {
16
17 template <typename T>
ToCData(v8::internal::Object obj)18 inline T ToCData(v8::internal::Object obj) {
19 STATIC_ASSERT(sizeof(T) == sizeof(v8::internal::Address));
20 if (obj == v8::internal::Smi::zero()) return nullptr;
21 return reinterpret_cast<T>(
22 v8::internal::Foreign::cast(obj).foreign_address());
23 }
24
25 template <>
ToCData(v8::internal::Object obj)26 inline v8::internal::Address ToCData(v8::internal::Object obj) {
27 if (obj == v8::internal::Smi::zero()) return v8::internal::kNullAddress;
28 return v8::internal::Foreign::cast(obj).foreign_address();
29 }
30
31 template <typename T>
FromCData(v8::internal::Isolate * isolate,T obj)32 inline v8::internal::Handle<v8::internal::Object> FromCData(
33 v8::internal::Isolate* isolate, T obj) {
34 STATIC_ASSERT(sizeof(T) == sizeof(v8::internal::Address));
35 if (obj == nullptr) return handle(v8::internal::Smi::zero(), isolate);
36 return isolate->factory()->NewForeign(
37 reinterpret_cast<v8::internal::Address>(obj));
38 }
39
40 template <>
FromCData(v8::internal::Isolate * isolate,v8::internal::Address obj)41 inline v8::internal::Handle<v8::internal::Object> FromCData(
42 v8::internal::Isolate* isolate, v8::internal::Address obj) {
43 if (obj == v8::internal::kNullAddress) {
44 return handle(v8::internal::Smi::zero(), isolate);
45 }
46 return isolate->factory()->NewForeign(obj);
47 }
48
49 template <class From, class To>
Convert(v8::internal::Handle<From> obj)50 inline Local<To> Utils::Convert(v8::internal::Handle<From> obj) {
51 DCHECK(obj.is_null() || (obj->IsSmi() || !obj->IsTheHole()));
52 return Local<To>(reinterpret_cast<To*>(obj.location()));
53 }
54
55 // Implementations of ToLocal
56
57 #define MAKE_TO_LOCAL(Name, From, To) \
58 Local<v8::To> Utils::Name(v8::internal::Handle<v8::internal::From> obj) { \
59 return Convert<v8::internal::From, v8::To>(obj); \
60 }
61
62 #define MAKE_TO_LOCAL_TYPED_ARRAY(Type, typeName, TYPE, ctype) \
63 Local<v8::Type##Array> Utils::ToLocal##Type##Array( \
64 v8::internal::Handle<v8::internal::JSTypedArray> obj) { \
65 DCHECK(obj->type() == v8::internal::kExternal##Type##Array); \
66 return Convert<v8::internal::JSTypedArray, v8::Type##Array>(obj); \
67 }
68
MAKE_TO_LOCAL(ToLocal,AccessorPair,debug::AccessorPair)69 MAKE_TO_LOCAL(ToLocal, AccessorPair, debug::AccessorPair)
70 MAKE_TO_LOCAL(ToLocal, Context, Context)
71 MAKE_TO_LOCAL(ToLocal, Object, Value)
72 MAKE_TO_LOCAL(ToLocal, Module, Module)
73 MAKE_TO_LOCAL(ToLocal, Name, Name)
74 MAKE_TO_LOCAL(ToLocal, String, String)
75 MAKE_TO_LOCAL(ToLocal, Symbol, Symbol)
76 MAKE_TO_LOCAL(ToLocal, JSRegExp, RegExp)
77 MAKE_TO_LOCAL(ToLocal, JSReceiver, Object)
78 MAKE_TO_LOCAL(ToLocal, JSObject, Object)
79 MAKE_TO_LOCAL(ToLocal, JSFunction, Function)
80 MAKE_TO_LOCAL(ToLocal, JSArray, Array)
81 MAKE_TO_LOCAL(ToLocal, JSMap, Map)
82 MAKE_TO_LOCAL(ToLocal, JSSet, Set)
83 MAKE_TO_LOCAL(ToLocal, JSProxy, Proxy)
84 MAKE_TO_LOCAL(ToLocal, JSArrayBuffer, ArrayBuffer)
85 MAKE_TO_LOCAL(ToLocal, JSArrayBufferView, ArrayBufferView)
86 MAKE_TO_LOCAL(ToLocal, JSDataView, DataView)
87 MAKE_TO_LOCAL(ToLocal, JSTypedArray, TypedArray)
88 MAKE_TO_LOCAL(ToLocalShared, JSArrayBuffer, SharedArrayBuffer)
89
90 TYPED_ARRAYS(MAKE_TO_LOCAL_TYPED_ARRAY)
91
92 MAKE_TO_LOCAL(ToLocal, FunctionTemplateInfo, FunctionTemplate)
93 MAKE_TO_LOCAL(ToLocal, ObjectTemplateInfo, ObjectTemplate)
94 MAKE_TO_LOCAL(SignatureToLocal, FunctionTemplateInfo, Signature)
95 MAKE_TO_LOCAL(AccessorSignatureToLocal, FunctionTemplateInfo, AccessorSignature)
96 MAKE_TO_LOCAL(MessageToLocal, Object, Message)
97 MAKE_TO_LOCAL(PromiseToLocal, JSObject, Promise)
98 MAKE_TO_LOCAL(StackTraceToLocal, FixedArray, StackTrace)
99 MAKE_TO_LOCAL(StackFrameToLocal, StackTraceFrame, StackFrame)
100 MAKE_TO_LOCAL(NumberToLocal, Object, Number)
101 MAKE_TO_LOCAL(IntegerToLocal, Object, Integer)
102 MAKE_TO_LOCAL(Uint32ToLocal, Object, Uint32)
103 MAKE_TO_LOCAL(ToLocal, BigInt, BigInt)
104 MAKE_TO_LOCAL(ExternalToLocal, JSObject, External)
105 MAKE_TO_LOCAL(CallableToLocal, JSReceiver, Function)
106 MAKE_TO_LOCAL(ToLocalPrimitive, Object, Primitive)
107 MAKE_TO_LOCAL(ToLocal, FixedArray, PrimitiveArray)
108 MAKE_TO_LOCAL(ScriptOrModuleToLocal, Script, ScriptOrModule)
109
110 #undef MAKE_TO_LOCAL_TYPED_ARRAY
111 #undef MAKE_TO_LOCAL
112
113 // Implementations of OpenHandle
114
115 #define MAKE_OPEN_HANDLE(From, To) \
116 v8::internal::Handle<v8::internal::To> Utils::OpenHandle( \
117 const v8::From* that, bool allow_empty_handle) { \
118 DCHECK(allow_empty_handle || that != nullptr); \
119 DCHECK(that == nullptr || \
120 v8::internal::Object( \
121 *reinterpret_cast<const v8::internal::Address*>(that)) \
122 .Is##To()); \
123 return v8::internal::Handle<v8::internal::To>( \
124 reinterpret_cast<v8::internal::Address*>( \
125 const_cast<v8::From*>(that))); \
126 }
127
128 OPEN_HANDLE_LIST(MAKE_OPEN_HANDLE)
129
130 #undef MAKE_OPEN_HANDLE
131 #undef OPEN_HANDLE_LIST
132
133 namespace internal {
134
135 Handle<Context> HandleScopeImplementer::LastEnteredContext() {
136 DCHECK_EQ(entered_contexts_.size(), is_microtask_context_.size());
137
138 for (size_t i = 0; i < entered_contexts_.size(); ++i) {
139 size_t j = entered_contexts_.size() - i - 1;
140 if (!is_microtask_context_.at(j)) {
141 return Handle<Context>(entered_contexts_.at(j), isolate_);
142 }
143 }
144
145 return Handle<Context>::null();
146 }
147
148 Handle<Context> HandleScopeImplementer::LastEnteredOrMicrotaskContext() {
149 if (entered_contexts_.empty()) return Handle<Context>::null();
150 return Handle<Context>(entered_contexts_.back(), isolate_);
151 }
152
153 } // namespace internal
154 } // namespace v8
155
156 #endif // V8_API_API_INL_H_
157