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