2019-01-21 14:03:30 -05:00
|
|
|
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
2018-07-06 03:19:19 -04:00
|
|
|
#ifndef INTERNAL_H_
|
|
|
|
#define INTERNAL_H_
|
2018-06-09 23:34:03 -04:00
|
|
|
|
2018-10-18 11:44:45 -04:00
|
|
|
#include <map>
|
2018-06-09 23:34:03 -04:00
|
|
|
#include <string>
|
2019-01-29 21:31:59 -05:00
|
|
|
#include <utility>
|
2019-01-30 17:21:31 -05:00
|
|
|
#include <vector>
|
2019-04-28 15:31:10 -04:00
|
|
|
|
|
|
|
#include "buffer.h"
|
2018-07-06 03:19:19 -04:00
|
|
|
#include "deno.h"
|
2018-07-03 04:15:32 -04:00
|
|
|
#include "third_party/v8/include/v8.h"
|
2018-10-23 23:58:20 -04:00
|
|
|
#include "third_party/v8/src/base/logging.h"
|
|
|
|
|
|
|
|
namespace deno {
|
2018-06-09 23:34:03 -04:00
|
|
|
|
2019-01-30 17:21:31 -05:00
|
|
|
struct ModuleInfo {
|
2019-02-26 13:29:45 -05:00
|
|
|
bool main;
|
2019-01-30 17:21:31 -05:00
|
|
|
std::string name;
|
|
|
|
v8::Persistent<v8::Module> handle;
|
|
|
|
std::vector<std::string> import_specifiers;
|
|
|
|
|
2019-02-26 13:29:45 -05:00
|
|
|
ModuleInfo(v8::Isolate* isolate, v8::Local<v8::Module> module, bool main_,
|
2019-01-30 17:21:31 -05:00
|
|
|
const char* name_, std::vector<std::string> import_specifiers_)
|
2019-02-26 13:29:45 -05:00
|
|
|
: main(main_), name(name_), import_specifiers(import_specifiers_) {
|
2019-01-30 17:21:31 -05:00
|
|
|
handle.Reset(isolate, module);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-06-09 23:34:03 -04:00
|
|
|
// deno_s = Wrapped Isolate.
|
2018-10-23 23:58:20 -04:00
|
|
|
class DenoIsolate {
|
|
|
|
public:
|
2019-01-29 21:31:59 -05:00
|
|
|
explicit DenoIsolate(deno_config config)
|
2018-10-23 23:58:20 -04:00
|
|
|
: isolate_(nullptr),
|
2019-02-26 17:36:05 -05:00
|
|
|
locker_(nullptr),
|
2018-12-04 18:06:20 -05:00
|
|
|
shared_(config.shared),
|
2018-10-23 23:58:20 -04:00
|
|
|
current_args_(nullptr),
|
2018-10-24 01:12:13 -04:00
|
|
|
snapshot_creator_(nullptr),
|
2018-10-23 23:58:20 -04:00
|
|
|
global_import_buf_ptr_(nullptr),
|
2018-12-04 18:06:20 -05:00
|
|
|
recv_cb_(config.recv_cb),
|
2019-01-30 17:21:31 -05:00
|
|
|
user_data_(nullptr),
|
2019-04-24 21:43:06 -04:00
|
|
|
resolve_cb_(nullptr),
|
|
|
|
has_snapshotted_(false) {
|
2018-12-13 16:25:42 -05:00
|
|
|
if (config.load_snapshot.data_ptr) {
|
|
|
|
snapshot_.data =
|
|
|
|
reinterpret_cast<const char*>(config.load_snapshot.data_ptr);
|
|
|
|
snapshot_.raw_size = static_cast<int>(config.load_snapshot.data_len);
|
2018-10-23 23:58:20 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-03 14:22:26 -05:00
|
|
|
~DenoIsolate() {
|
2019-02-08 23:32:17 -05:00
|
|
|
shared_ab_.Reset();
|
2019-02-26 17:36:05 -05:00
|
|
|
if (locker_) {
|
|
|
|
delete locker_;
|
|
|
|
}
|
2018-12-03 14:22:26 -05:00
|
|
|
if (snapshot_creator_) {
|
2019-04-24 21:43:06 -04:00
|
|
|
// TODO(ry) V8 has a strange assert which prevents a SnapshotCreator from
|
|
|
|
// being deallocated if it hasn't created a snapshot yet.
|
|
|
|
// https://github.com/v8/v8/blob/73212783fbd534fac76cc4b66aac899c13f71fc8/src/api.cc#L603
|
|
|
|
// If that assert is removed, this if guard could be removed.
|
|
|
|
// WARNING: There may be false positive LSAN errors here.
|
|
|
|
if (has_snapshotted_) {
|
|
|
|
delete snapshot_creator_;
|
|
|
|
}
|
2018-12-03 14:22:26 -05:00
|
|
|
} else {
|
|
|
|
isolate_->Dispose();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-29 11:32:40 -05:00
|
|
|
static inline DenoIsolate* FromIsolate(v8::Isolate* isolate) {
|
|
|
|
return static_cast<DenoIsolate*>(isolate->GetData(0));
|
|
|
|
}
|
|
|
|
|
2018-10-23 23:58:20 -04:00
|
|
|
void AddIsolate(v8::Isolate* isolate);
|
|
|
|
|
2019-02-26 13:29:45 -05:00
|
|
|
deno_mod RegisterModule(bool main, const char* name, const char* source);
|
2019-01-30 17:21:31 -05:00
|
|
|
void ClearModules();
|
|
|
|
|
|
|
|
ModuleInfo* GetModuleInfo(deno_mod id) {
|
|
|
|
if (id == 0) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
auto it = mods_.find(id);
|
|
|
|
if (it != mods_.end()) {
|
|
|
|
return &it->second;
|
|
|
|
} else {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
}
|
2019-01-06 16:32:21 -05:00
|
|
|
|
2018-10-23 23:58:20 -04:00
|
|
|
v8::Isolate* isolate_;
|
2019-02-26 17:36:05 -05:00
|
|
|
v8::Locker* locker_;
|
2018-10-24 02:17:10 -04:00
|
|
|
deno_buf shared_;
|
2018-10-23 23:58:20 -04:00
|
|
|
const v8::FunctionCallbackInfo<v8::Value>* current_args_;
|
2018-10-24 01:12:13 -04:00
|
|
|
v8::SnapshotCreator* snapshot_creator_;
|
2018-10-23 23:58:20 -04:00
|
|
|
void* global_import_buf_ptr_;
|
2019-03-30 14:45:36 -04:00
|
|
|
deno_recv_cb recv_cb_;
|
2018-10-23 23:58:20 -04:00
|
|
|
void* user_data_;
|
|
|
|
|
2019-01-30 17:21:31 -05:00
|
|
|
std::map<deno_mod, ModuleInfo> mods_;
|
|
|
|
std::map<std::string, deno_mod> mods_by_name_;
|
|
|
|
deno_resolve_cb resolve_cb_;
|
2019-01-06 16:32:21 -05:00
|
|
|
|
2018-10-23 23:58:20 -04:00
|
|
|
v8::Persistent<v8::Context> context_;
|
2018-12-06 23:05:36 -05:00
|
|
|
std::map<int, v8::Persistent<v8::Value>> pending_promise_map_;
|
2018-10-23 23:58:20 -04:00
|
|
|
std::string last_exception_;
|
|
|
|
v8::Persistent<v8::Function> recv_;
|
|
|
|
v8::StartupData snapshot_;
|
|
|
|
v8::Persistent<v8::ArrayBuffer> global_import_buf_;
|
2019-02-08 23:32:17 -05:00
|
|
|
v8::Persistent<v8::SharedArrayBuffer> shared_ab_;
|
2019-04-24 21:43:06 -04:00
|
|
|
bool has_snapshotted_;
|
2018-06-09 23:34:03 -04:00
|
|
|
};
|
2018-06-10 08:18:15 -04:00
|
|
|
|
2018-10-23 23:58:20 -04:00
|
|
|
class UserDataScope {
|
2018-12-04 18:06:20 -05:00
|
|
|
DenoIsolate* deno_;
|
|
|
|
void* prev_data_;
|
|
|
|
void* data_; // Not necessary; only for sanity checking.
|
2018-10-23 23:58:20 -04:00
|
|
|
|
|
|
|
public:
|
2018-12-04 18:06:20 -05:00
|
|
|
UserDataScope(DenoIsolate* deno, void* data) : deno_(deno), data_(data) {
|
2018-10-23 23:58:20 -04:00
|
|
|
CHECK(deno->user_data_ == nullptr || deno->user_data_ == data_);
|
2018-12-04 18:06:20 -05:00
|
|
|
prev_data_ = deno->user_data_;
|
2018-10-23 23:58:20 -04:00
|
|
|
deno->user_data_ = data;
|
|
|
|
}
|
|
|
|
|
|
|
|
~UserDataScope() {
|
2018-12-04 18:06:20 -05:00
|
|
|
CHECK(deno_->user_data_ == data_);
|
|
|
|
deno_->user_data_ = prev_data_;
|
2018-10-23 23:58:20 -04:00
|
|
|
}
|
|
|
|
};
|
2018-06-10 08:18:15 -04:00
|
|
|
|
2018-06-12 00:36:01 -04:00
|
|
|
struct InternalFieldData {
|
|
|
|
uint32_t data;
|
|
|
|
};
|
|
|
|
|
2019-02-01 23:26:33 -05:00
|
|
|
static inline v8::Local<v8::String> v8_str(const char* x) {
|
2019-01-01 11:22:23 -05:00
|
|
|
return v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), x,
|
2019-02-01 23:26:33 -05:00
|
|
|
v8::NewStringType::kNormal)
|
2019-01-01 11:22:23 -05:00
|
|
|
.ToLocalChecked();
|
|
|
|
}
|
|
|
|
|
2018-06-10 08:18:15 -04:00
|
|
|
void Print(const v8::FunctionCallbackInfo<v8::Value>& args);
|
2018-07-01 12:07:12 -04:00
|
|
|
void Recv(const v8::FunctionCallbackInfo<v8::Value>& args);
|
|
|
|
void Send(const v8::FunctionCallbackInfo<v8::Value>& args);
|
2019-02-09 16:55:40 -05:00
|
|
|
void EvalContext(const v8::FunctionCallbackInfo<v8::Value>& args);
|
|
|
|
void ErrorToJSON(const v8::FunctionCallbackInfo<v8::Value>& args);
|
2018-10-24 02:17:10 -04:00
|
|
|
void Shared(v8::Local<v8::Name> property,
|
|
|
|
const v8::PropertyCallbackInfo<v8::Value>& info);
|
2019-01-29 11:32:40 -05:00
|
|
|
void MessageCallback(v8::Local<v8::Message> message, v8::Local<v8::Value> data);
|
2018-08-26 13:22:07 -04:00
|
|
|
static intptr_t external_references[] = {
|
2019-01-06 16:32:21 -05:00
|
|
|
reinterpret_cast<intptr_t>(Print),
|
|
|
|
reinterpret_cast<intptr_t>(Recv),
|
|
|
|
reinterpret_cast<intptr_t>(Send),
|
2019-02-09 16:55:40 -05:00
|
|
|
reinterpret_cast<intptr_t>(EvalContext),
|
|
|
|
reinterpret_cast<intptr_t>(ErrorToJSON),
|
2019-01-06 16:32:21 -05:00
|
|
|
reinterpret_cast<intptr_t>(Shared),
|
2019-01-29 11:32:40 -05:00
|
|
|
reinterpret_cast<intptr_t>(MessageCallback),
|
2019-01-06 16:32:21 -05:00
|
|
|
0};
|
2018-06-10 08:18:15 -04:00
|
|
|
|
2019-04-28 15:31:10 -04:00
|
|
|
static const deno_buf empty_buf = {nullptr, 0, nullptr, 0};
|
2019-04-08 10:12:43 -04:00
|
|
|
static const deno_snapshot empty_snapshot = {nullptr, 0};
|
2018-10-24 01:12:13 -04:00
|
|
|
|
2019-03-30 14:45:36 -04:00
|
|
|
Deno* NewFromSnapshot(void* user_data, deno_recv_cb cb);
|
2018-06-10 08:18:15 -04:00
|
|
|
|
2018-12-13 16:25:42 -05:00
|
|
|
void InitializeContext(v8::Isolate* isolate, v8::Local<v8::Context> context);
|
2018-06-13 14:55:08 -04:00
|
|
|
|
2018-10-23 23:58:20 -04:00
|
|
|
void DeserializeInternalFields(v8::Local<v8::Object> holder, int index,
|
|
|
|
v8::StartupData payload, void* data);
|
|
|
|
|
2018-10-24 01:12:13 -04:00
|
|
|
v8::StartupData SerializeInternalFields(v8::Local<v8::Object> holder, int index,
|
|
|
|
void* data);
|
|
|
|
|
2018-10-23 23:58:20 -04:00
|
|
|
v8::Local<v8::Uint8Array> ImportBuf(DenoIsolate* d, deno_buf buf);
|
|
|
|
|
|
|
|
bool Execute(v8::Local<v8::Context> context, const char* js_filename,
|
|
|
|
const char* js_source);
|
2018-11-29 15:40:04 -05:00
|
|
|
bool ExecuteMod(v8::Local<v8::Context> context, const char* js_filename,
|
2019-01-15 12:19:58 -05:00
|
|
|
const char* js_source, bool resolve_only);
|
2018-06-09 23:34:03 -04:00
|
|
|
|
|
|
|
} // namespace deno
|
2018-10-23 23:58:20 -04:00
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
// This is just to workaround the linker.
|
|
|
|
struct deno_s {
|
|
|
|
deno::DenoIsolate isolate;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2018-07-06 03:19:19 -04:00
|
|
|
#endif // INTERNAL_H_
|