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
14namespace v8 {
15
16template <typename T>
17inline 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
24template <>
25inline 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
30template <typename T>
31inline 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
39template <>
40inline 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
48template <class From, class To>
49inline 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
68MAKE_TO_LOCAL(ToLocal, Context, Context)
69MAKE_TO_LOCAL(ToLocal, Object, Value)
70MAKE_TO_LOCAL(ToLocal, Module, Module)
71MAKE_TO_LOCAL(ToLocal, Name, Name)
72MAKE_TO_LOCAL(ToLocal, String, String)
73MAKE_TO_LOCAL(ToLocal, Symbol, Symbol)
74MAKE_TO_LOCAL(ToLocal, JSRegExp, RegExp)
75MAKE_TO_LOCAL(ToLocal, JSReceiver, Object)
76MAKE_TO_LOCAL(ToLocal, JSObject, Object)
77MAKE_TO_LOCAL(ToLocal, JSFunction, Function)
78MAKE_TO_LOCAL(ToLocal, JSArray, Array)
79MAKE_TO_LOCAL(ToLocal, JSMap, Map)
80MAKE_TO_LOCAL(ToLocal, JSSet, Set)
81MAKE_TO_LOCAL(ToLocal, JSProxy, Proxy)
82MAKE_TO_LOCAL(ToLocal, JSArrayBuffer, ArrayBuffer)
83MAKE_TO_LOCAL(ToLocal, JSArrayBufferView, ArrayBufferView)
84MAKE_TO_LOCAL(ToLocal, JSDataView, DataView)
85MAKE_TO_LOCAL(ToLocal, JSTypedArray, TypedArray)
86MAKE_TO_LOCAL(ToLocalShared, JSArrayBuffer, SharedArrayBuffer)
87
88TYPED_ARRAYS(MAKE_TO_LOCAL_TYPED_ARRAY)
89
90MAKE_TO_LOCAL(ToLocal, FunctionTemplateInfo, FunctionTemplate)
91MAKE_TO_LOCAL(ToLocal, ObjectTemplateInfo, ObjectTemplate)
92MAKE_TO_LOCAL(SignatureToLocal, FunctionTemplateInfo, Signature)
93MAKE_TO_LOCAL(AccessorSignatureToLocal, FunctionTemplateInfo, AccessorSignature)
94MAKE_TO_LOCAL(MessageToLocal, Object, Message)
95MAKE_TO_LOCAL(PromiseToLocal, JSObject, Promise)
96MAKE_TO_LOCAL(StackTraceToLocal, FixedArray, StackTrace)
97MAKE_TO_LOCAL(StackFrameToLocal, StackTraceFrame, StackFrame)
98MAKE_TO_LOCAL(NumberToLocal, Object, Number)
99MAKE_TO_LOCAL(IntegerToLocal, Object, Integer)
100MAKE_TO_LOCAL(Uint32ToLocal, Object, Uint32)
101MAKE_TO_LOCAL(ToLocal, BigInt, BigInt)
102MAKE_TO_LOCAL(ExternalToLocal, JSObject, External)
103MAKE_TO_LOCAL(CallableToLocal, JSReceiver, Function)
104MAKE_TO_LOCAL(ToLocalPrimitive, Object, Primitive)
105MAKE_TO_LOCAL(ToLocal, FixedArray, PrimitiveArray)
106MAKE_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
126OPEN_HANDLE_LIST(MAKE_OPEN_HANDLE)
127
128#undef MAKE_OPEN_HANDLE
129#undef OPEN_HANDLE_LIST
130
131namespace internal {
132
133Handle<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
146Handle<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