25 class StaticExternalResource
26 :
public v8::String::ExternalOneByteStringResource {
28 StaticExternalResource(
const uint8_t* data,
size_t data_size)
29 : data_(data), data_size_(data_size) {}
33 const char* data()
const override {
34 return reinterpret_cast<const char*
>(data_);
37 size_t length()
const override {
42 void Dispose()
override {
47 ~StaticExternalResource()
override {}
53 v8::Local<v8::String> MakeExternalString(
const uint8_t* data,
56 for (
size_t i = 0; i < data_size; i++)
57 CHECK_LT(data[i], 0x80) <<
"External string must be ASCII";
60 auto* res =
new StaticExternalResource(data, data_size);
61 auto temp = v8::String::NewExternalOneByte(
GetIsolate(), res);
62 return temp.ToLocalChecked();
66 ReturnVal<JsValue> GetMemberImpl(Handle<JsObject>
object, T ind,
67 LocalVar<JsValue>* exception) {
69 v8::Local<v8::Context> context = isolate->GetCurrentContext();
71 v8::TryCatch trycatch(isolate);
72 v8::MaybeLocal<v8::Value> maybe_field =
object->Get(context, ind);
73 v8::Local<v8::Value> field;
74 if (!maybe_field.ToLocal(&field)) {
76 *exception = trycatch.Exception();
84 void SetMemberImpl(Handle<JsObject>
object, T ind, Handle<JsValue> value) {
85 auto context =
GetIsolate()->GetCurrentContext();
87 CHECK(object->Set(context, ind, value).IsJust());
90 bool RunScriptImpl(
const std::string& path, Handle<JsString>
source) {
91 v8::Isolate* isolate = v8::Isolate::GetCurrent();
92 auto context = isolate->GetCurrentContext();
97 v8::TryCatch trycatch(isolate);
98 v8::MaybeLocal<v8::Script> maybe_script =
99 v8::Script::Compile(context, source, &origin);
100 v8::Local<v8::Script> script;
101 if (!maybe_script.ToLocal(&script) || script.IsEmpty()) {
102 LOG(ERROR) <<
"Error loading script " << path;
109 if (script->Run(context).IsEmpty()) {
119 std::vector<std::string> names;
122 v8::Local<v8::Context> context = isolate->GetCurrentContext();
124 v8::MaybeLocal<v8::Array> maybe_field =
object->GetOwnPropertyNames(context);
125 v8::Local<v8::Array> array;
126 if (maybe_field.ToLocal(&array)) {
127 for (
size_t i = 0; i < array->Length(); i++) {
137 const std::string&
name,
138 LocalVar<JsValue>* exception) {
143 LocalVar<JsValue>* exception) {
144 return GetMemberImpl(
object, index, exception);
148 Handle<JsValue> value) {
153 Handle<JsValue> value) {
154 SetMemberImpl(
object, i, value);
159 Handle<JsFunction> getter,
160 Handle<JsFunction> setter) {
166 LocalVar<JsValue>* argv,
167 LocalVar<JsValue>* result_or_except) {
169 v8::Local<v8::Context> context = isolate->GetCurrentContext();
170 v8::EscapableHandleScope handles(isolate);
172 v8::TryCatch trycatch(isolate);
173 v8::MaybeLocal<v8::Object> result = ctor->NewInstance(context, argc, argv);
174 if (result.IsEmpty()) {
175 *result_or_except = handles.Escape(trycatch.Exception());
178 *result_or_except = handles.Escape(result.ToLocalChecked());
182 bool InvokeMethod(Handle<JsFunction> method, Handle<JsObject> that,
int argc,
183 LocalVar<JsValue>* argv,
184 LocalVar<JsValue>* result_or_except) {
186 v8::Local<v8::Context> context = isolate->GetCurrentContext();
187 v8::EscapableHandleScope handles(isolate);
190 that = context->Global();
192 v8::TryCatch trycatch(isolate);
193 v8::MaybeLocal<v8::Value> result = method->Call(context, that, argc, argv);
194 if (result.IsEmpty()) {
195 *result_or_except = handles.Escape(trycatch.Exception());
198 *result_or_except = handles.Escape(result.ToLocalChecked());
204 if (!value.IsEmpty() && value->IsSymbol()) {
206 return name.IsEmpty() || name->IsUndefined() ?
"" :
ConvertToString(name);
209 v8::String::Utf8Value str(
GetIsolate(), value);
210 return std::string(*str, str.length());
218 if (value.IsEmpty() || !value->IsExternal())
220 return value.As<v8::External>()->Value();
224 if (value.IsEmpty() || !value->IsObject())
227 v8::Local<v8::Object>
object = value.As<v8::Object>();
232 object->GetAlignedPointerFromInternalField(0));
241 std::vector<uint8_t>
source;
243 v8::Local<v8::String> code =
245 reinterpret_cast<const char*>(source.data()),
246 v8::NewStringType::kNormal, source.size())
248 return RunScriptImpl(path, code);
251 bool RunScript(
const std::string& path,
const uint8_t* data,
size_t data_size) {
253 return RunScriptImpl(path, source);
257 v8::Local<v8::String> source = MakeExternalString(
258 reinterpret_cast<const uint8_t*>(json.data()), json.size());
259 v8::MaybeLocal<v8::Value> value =
260 v8::JSON::Parse(
GetIsolate()->GetCurrentContext(), source);
263 return value.ToLocalChecked();
272 return v8::String::NewFromUtf8(
GetIsolate(), str.c_str(),
273 v8::NewStringType::kNormal, str.size())
279 reinterpret_cast<const char*>(data),
280 v8::NewStringType::kNormal, size)
305 Handle<JsValue> value) {
306 LocalVar<v8::Context> ctx =
GetIsolate()->GetCurrentContext();
307 CHECK(!map->Set(ctx, key, value).IsEmpty());
312 return value.IsEmpty() || value->IsNull() || value->IsUndefined();
316 return !value.IsEmpty() && value->IsObject();
323 object->ObjectProtoToString(
GetIsolate()->GetCurrentContext());
324 if (to_string.IsEmpty())
326 return ConvertToString(to_string.ToLocalChecked()) !=
"[object Object]";
332 if (value->IsUndefined())
336 if (value->IsBoolean())
338 if (value->IsNumber())
340 if (value->IsString())
342 if (value->IsFunction())
344 if (value->IsArray())
346 if (value->IsPromise())
348 if (value->IsBooleanObject())
350 if (value->IsNumberObject())
352 if (value->IsStringObject())
354 if (value->IsArrayBuffer())
356 if (value->IsInt8Array())
358 if (value->IsUint8Array())
360 if (value->IsUint8ClampedArray())
362 if (value->IsInt16Array())
364 if (value->IsUint16Array())
366 if (value->IsInt32Array())
368 if (value->IsUint32Array())
370 if (value->IsFloat32Array())
372 if (value->IsFloat64Array())
374 if (value->IsDataView())
376 if (value->IsObject())
381 LOG(WARNING) <<
"Unknown JavaScript value given=" <<
ConvertToString(value);
386 DCHECK(!value.IsEmpty());
387 if (value->IsNumber()) {
390 DCHECK(value->IsNumberObject());
395 DCHECK(!value.IsEmpty());
396 if (value->IsBoolean()) {
397 return value->IsTrue();
399 DCHECK(value->IsBooleanObject());
void SetArrayIndexRaw(Handle< JsObject > object, size_t i, Handle< JsValue > value)
ReturnVal< JsValue > ParseJsonString(const std::string &json)
ReturnVal< JsObject > CreateObject()
ReturnVal< JsValue > JsUndefined()
bool IsObject(Handle< JsValue > value)
bool IsNullOrUndefined(Handle< JsValue > value)
std::vector< std::string > GetMemberNames(Handle< JsObject > object)
ReturnVal< JsValue > JsNull()
ReturnVal< JsValue > GetArrayIndexRaw(Handle< JsObject > object, size_t index, LocalVar< JsValue > *exception=nullptr)
bool InvokeMethod(Handle< JsFunction > method, Handle< JsObject > that, int argc, LocalVar< JsValue > *argv, LocalVar< JsValue > *result_or_except)
BackingObject * GetInternalPointer(Handle< JsValue > value)
bool BooleanFromValue(Handle< JsValue > value)
bool IsDerivedFrom(BackingObject *ptr, const std::string &name)
ReturnVal< JsObject > CreateArray(size_t length)
ReturnVal< JsValue > ToJsValue(T &&source)
#define SHAKA_NON_COPYABLE_OR_MOVABLE_TYPE(Type)
bool RunScript(const std::string &path)
static constexpr const size_t kInternalFieldCount
proto::ValueType GetValueType(Handle< JsValue > value)
double NumberFromValue(Handle< JsValue > value)
ReturnVal< JsMap > CreateMap()
virtual MUST_USE_RESULT bool ReadFile(const std::string &path, std::vector< uint8_t > *data) const
void SetMemberRaw(Handle< JsObject > object, const std::string &name, Handle< JsValue > value)
void SetMapValue(Handle< JsMap > map, Handle< JsValue > key, Handle< JsValue > value)
bool DerivedFrom(const std::string &base)
std::string ConvertToString(Handle< JsValue > value)
ReturnVal< JsValue > WrapPointer(void *ptr)
void OnUncaughtException(JSValueRef exception, bool in_promise)
ReturnVal< JsString > JsStringFromUtf8(const std::string &str)
bool InvokeConstructor(Handle< JsFunction > ctor, int argc, LocalVar< JsValue > *argv, LocalVar< JsValue > *result_or_except)
v8::Isolate * GetIsolate()
ReturnVal< JsValue > GetMemberRaw(Handle< JsObject > object, const std::string &name, LocalVar< JsValue > *exception=nullptr)
void * MaybeUnwrapPointer(Handle< JsValue > value)
bool IsBuiltInObject(Handle< JsObject > object)
void SetGenericPropertyRaw(Handle< JsObject > object, const std::string &name, Handle< JsFunction > getter, Handle< JsFunction > setter)