mirror of
https://github.com/denoland/deno.git
synced 2024-12-22 07:14:47 -05:00
Add deno2 prototype from external repo.
This commit is contained in:
parent
fe9ea6dcf8
commit
110ddab670
24 changed files with 4668 additions and 0 deletions
38
deno2/.gclient
Normal file
38
deno2/.gclient
Normal file
|
@ -0,0 +1,38 @@
|
|||
solutions = [{
|
||||
'url': 'https://chromium.googlesource.com/v8/v8.git',
|
||||
'custom_vars': {
|
||||
'build_for_node': True
|
||||
},
|
||||
'name': 'v8',
|
||||
'deps_file': 'DEPS',
|
||||
'custom_deps': {
|
||||
'v8/third_party/catapult': None,
|
||||
'v8/third_party/colorama/src': None,
|
||||
'v8/testing/gmock': None,
|
||||
'v8/tools/swarming_client': None,
|
||||
'v8/third_party/instrumented_libraries': None,
|
||||
'v8/tools/gyp': None,
|
||||
'v8/third_party/android_tools': None,
|
||||
'v8/test/wasm-js': None,
|
||||
'v8/test/benchmarks/data': None,
|
||||
'v8/test/mozilla/data': None,
|
||||
'v8/third_party/icu': None,
|
||||
'v8/test/test262/data': None,
|
||||
'v8/test/test262/harness': None,
|
||||
'v8/tools/luci-go': None
|
||||
}
|
||||
}, {
|
||||
'url': 'https://github.com/ry/protobuf_chromium.git',
|
||||
'name': 'third_party/protobuf',
|
||||
'deps_file': 'DEPS'
|
||||
}, {
|
||||
'url':
|
||||
'https://chromium.googlesource.com/chromium/src/tools/protoc_wrapper',
|
||||
'name':
|
||||
'tools/protoc_wrapper'
|
||||
}, {
|
||||
'url':
|
||||
'https://chromium.googlesource.com/chromium/src/third_party/zlib',
|
||||
'name':
|
||||
'third_party/zlib'
|
||||
}]
|
8
deno2/.gitignore
vendored
Normal file
8
deno2/.gitignore
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
out/
|
||||
js/.cache/
|
||||
js/node_modules/
|
||||
v8/
|
||||
tools/protoc_wrapper/
|
||||
third_party/protobuf/
|
||||
third_party/zlib/
|
||||
.gclient_entries
|
61
deno2/.gn
Normal file
61
deno2/.gn
Normal file
|
@ -0,0 +1,61 @@
|
|||
# This file is used by the GN meta build system to find the root of the source
|
||||
# tree and to set startup options. For documentation on the values set in this
|
||||
# file, run "gn help dotfile" at the command line.
|
||||
|
||||
import("//v8/build/dotfile_settings.gni")
|
||||
|
||||
# The location of the build configuration file.
|
||||
buildconfig = "//v8/build/config/BUILDCONFIG.gn"
|
||||
|
||||
# The secondary source root is a parallel directory tree where
|
||||
# GN build files are placed when they can not be placed directly
|
||||
# in the source tree, e.g. for third party source trees.
|
||||
secondary_source = "//v8/"
|
||||
|
||||
# These are the targets to check headers for by default. The files in targets
|
||||
# matching these patterns (see "gn help label_pattern" for format) will have
|
||||
# their includes checked for proper dependencies when you run either
|
||||
# "gn check" or "gn gen --check".
|
||||
check_targets = []
|
||||
|
||||
# These are the list of GN files that run exec_script. This whitelist exists
|
||||
# to force additional review for new uses of exec_script, which is strongly
|
||||
# discouraged except for gypi_to_gn calls.
|
||||
exec_script_whitelist = build_dotfile_settings.exec_script_whitelist + []
|
||||
|
||||
default_args = {
|
||||
# Default to release builds for this project.
|
||||
is_component_build = false
|
||||
is_debug = false
|
||||
libcpp_is_static = false
|
||||
symbol_level = 1
|
||||
treat_warnings_as_errors = false
|
||||
use_custom_libcxx = false
|
||||
use_sysroot = false
|
||||
v8_deprecation_warnings = false
|
||||
|
||||
#v8_embedder_string = ""
|
||||
v8_enable_gdbjit = false
|
||||
v8_enable_i18n_support = false
|
||||
v8_enable_test_features = false
|
||||
v8_experimental_extra_library_files = []
|
||||
v8_extra_library_files = []
|
||||
v8_imminent_deprecation_warnings = false
|
||||
v8_monolithic = false
|
||||
v8_static_library = false
|
||||
v8_target_cpu = "x64"
|
||||
v8_untrusted_code_mitigations = false
|
||||
|
||||
# This tells V8 to write out/Default/gen/v8/snapshot.bin
|
||||
# Which we can use to build our own snapshot.
|
||||
v8_use_external_startup_data = true
|
||||
v8_use_snapshot = true
|
||||
|
||||
# Snapshot the dist/main.js bundle into V8.
|
||||
# Is ".gn" really the most appropriate place to specify this important
|
||||
# value? This is how they do it in Chrome.
|
||||
# https://cs.chromium.org/chromium/src/.gn?l=37&rcl=f1c8c3cf8bd4a63da6433ee67e2ff5ecbbdb4316
|
||||
|
||||
# "$target_gen_dir/main.js"
|
||||
#]
|
||||
}
|
134
deno2/BUILD.gn
Normal file
134
deno2/BUILD.gn
Normal file
|
@ -0,0 +1,134 @@
|
|||
import("//third_party/protobuf/proto_library.gni")
|
||||
import("//v8/gni/v8.gni")
|
||||
import("//v8/snapshot_toolchain.gni")
|
||||
|
||||
proto_library("msg_proto") {
|
||||
sources = [
|
||||
"msg.proto",
|
||||
]
|
||||
}
|
||||
|
||||
action("run_parcel") {
|
||||
sources = [
|
||||
"js/main.ts",
|
||||
]
|
||||
outputs = [
|
||||
"$target_gen_dir/main.js",
|
||||
"$target_gen_dir/main.map",
|
||||
]
|
||||
|
||||
# Our script imports this Python file so we want to rebuild if it changes.
|
||||
# inputs = [ "helper_library.py" ]
|
||||
|
||||
# Note that we have to manually pass the sources to our script if the
|
||||
# script needs them as inputs.
|
||||
script = "js/run_node.py"
|
||||
root = root_build_dir + "/../../js"
|
||||
args = [
|
||||
"./node_modules/.bin/parcel",
|
||||
"build",
|
||||
"--log-level=1",
|
||||
"--no-minify",
|
||||
"--out-dir=" + rebase_path(target_gen_dir, root),
|
||||
] + rebase_path(sources, root)
|
||||
}
|
||||
|
||||
# Template to generate different V8 snapshots based on different runtime flags.
|
||||
# Can be invoked with run_mksnapshot(<name>). The target will resolve to
|
||||
# run_mksnapshot_<name>. If <name> is "default", no file suffixes will be used.
|
||||
# Otherwise files are suffixed, e.g. embedded_<name>.cc and
|
||||
# snapshot_blob_<name>.bin.
|
||||
#
|
||||
# The template exposes the variables:
|
||||
# args: additional flags for mksnapshots
|
||||
# embedded_suffix: a camel case suffix for method names in the embedded
|
||||
# snapshot.
|
||||
template("create_snapshot") {
|
||||
name = target_name
|
||||
suffix = "_$name"
|
||||
action("create_snapshot_" + name) {
|
||||
visibility = [ ":*" ] # Only targets in this file can depend on this.
|
||||
deps = [ ":snapshot_creator" ] + invoker.deps
|
||||
script = "v8/tools/run.py"
|
||||
data = []
|
||||
exe = rebase_path(get_label_info(":snapshot_creator", "root_out_dir") +
|
||||
"/snapshot_creator")
|
||||
natives_in_bin = "$root_out_dir/natives_blob.bin"
|
||||
snapshot_in_bin = "$root_out_dir/snapshot_blob.bin"
|
||||
natives_out_cc = "$target_gen_dir/natives${suffix}.cc"
|
||||
snapshot_out_cc = "$target_gen_dir/snapshot${suffix}.cc"
|
||||
sources = [
|
||||
invoker.js,
|
||||
]
|
||||
outputs = [
|
||||
natives_out_cc,
|
||||
snapshot_out_cc,
|
||||
]
|
||||
args = [
|
||||
exe,
|
||||
rebase_path(invoker.js, root_build_dir),
|
||||
rebase_path(natives_in_bin, root_build_dir),
|
||||
rebase_path(snapshot_in_bin, root_build_dir),
|
||||
rebase_path(natives_out_cc, root_build_dir),
|
||||
rebase_path(snapshot_out_cc, root_build_dir),
|
||||
]
|
||||
data = [
|
||||
invoker.js,
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
# Generates $target_gen_dir/snapshot_bundle.cc
|
||||
create_snapshot("deno") {
|
||||
js = "$target_gen_dir/main.js"
|
||||
deps = [
|
||||
":run_parcel",
|
||||
]
|
||||
}
|
||||
|
||||
v8_executable("snapshot_creator") {
|
||||
sources = [
|
||||
"deno.cc",
|
||||
"deno.h",
|
||||
"snapshot_creator.cc",
|
||||
]
|
||||
configs = [ "v8:libplatform_config" ]
|
||||
deps = [
|
||||
"v8:v8",
|
||||
"v8:v8_libbase",
|
||||
"v8:v8_libplatform",
|
||||
"v8:v8_libsampler",
|
||||
"//build/config:exe_and_shlib_deps",
|
||||
"//build/win:default_exe_manifest",
|
||||
]
|
||||
}
|
||||
|
||||
v8_executable("deno") {
|
||||
sources = [
|
||||
"deno.cc",
|
||||
"deno.h",
|
||||
"main.cc",
|
||||
]
|
||||
include_dirs = [ target_gen_dir ]
|
||||
configs = [ "v8:libplatform_config" ]
|
||||
deps = [
|
||||
":create_snapshot_deno",
|
||||
":msg_proto",
|
||||
"v8:v8",
|
||||
"v8:v8_libbase",
|
||||
"v8:v8_libplatform",
|
||||
"v8:v8_libsampler",
|
||||
"//build/config:exe_and_shlib_deps",
|
||||
"//build/win:default_exe_manifest",
|
||||
]
|
||||
}
|
||||
|
||||
executable("deno_test") {
|
||||
testonly = true
|
||||
sources = [
|
||||
"deno_test.cc",
|
||||
]
|
||||
deps = [
|
||||
"//testing/gtest:gtest",
|
||||
]
|
||||
}
|
68
deno2/README.md
Normal file
68
deno2/README.md
Normal file
|
@ -0,0 +1,68 @@
|
|||
# Deno Prototype 2
|
||||
|
||||
## Status
|
||||
|
||||
This code is a rewrite of the unprivileged parts of Deno. It will soon become
|
||||
the root of the project.
|
||||
|
||||
There are several goals:
|
||||
|
||||
* Use the gn build system for fast builds, sane configuration, and easy
|
||||
linking into Chrome.
|
||||
|
||||
* Use V8 snapshots to improve startup time.
|
||||
|
||||
* Remove Golang. Although it has been working nicely, I am concerned the
|
||||
double GC will become a problem sometime down the road.
|
||||
|
||||
* Distribute a C++ library called libdeno, containing the snapshotted
|
||||
typescript runtime.
|
||||
|
||||
* Test the message passing and other functionality at that layer before
|
||||
involving higher level languages.
|
||||
|
||||
The contenders for building the unprivileged part of Deno are Rust and C++.
|
||||
Thanks to Chrome and gn, using C++ to link into high level libraries is not
|
||||
untenable. However, there's a lot of interest in Rust in the JS community and
|
||||
it seems like a reasonable choice. TBD.
|
||||
|
||||
There are many people exploring the project, so care will be taken to keep the
|
||||
original code functional while this is developed. However, once it's ready this
|
||||
the code in this deno2/ directory will be moved to the root.
|
||||
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Get Depot Tools and make sure it's in your path.
|
||||
http://commondatastorage.googleapis.com/chrome-infra-docs/flat/depot_tools/docs/html/depot_tools_tutorial.html#_setting_up
|
||||
|
||||
For linux you need these prereqs:
|
||||
|
||||
sudo apt-get install libgtk-3-dev pkg-config ccache
|
||||
|
||||
|
||||
## Build
|
||||
|
||||
First install the javascript deps.
|
||||
|
||||
cd js; yarn install
|
||||
|
||||
TODO(ry) Remove the above step by a deps submodule.
|
||||
|
||||
Wrapper around the gclient/gn/ninja for end users. Try this first:
|
||||
|
||||
./tools/build.py --use_ccache --debug
|
||||
|
||||
If that doesn't work, or you need more control, try calling gn manually:
|
||||
|
||||
gn gen out/Debug --args='cc_wrapper="ccache" is_debug=true '
|
||||
|
||||
Then build with ninja:
|
||||
|
||||
ninja -C out/Debug/ deno
|
||||
|
||||
|
||||
Other useful commands:
|
||||
|
||||
gn args out/Debug/ --list # List build args
|
||||
gn args out/Debug/ # Modify args in $EDITOR
|
1
deno2/build
Symbolic link
1
deno2/build
Symbolic link
|
@ -0,0 +1 @@
|
|||
v8/build
|
364
deno2/deno.cc
Normal file
364
deno2/deno.cc
Normal file
|
@ -0,0 +1,364 @@
|
|||
/*
|
||||
Copyright 2018 Ryan Dahl <ry@tinyclouds.org>. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to
|
||||
deal in the Software without restriction, including without limitation the
|
||||
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN THE SOFTWARE.
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
#include "v8/include/libplatform/libplatform.h"
|
||||
#include "v8/include/v8.h"
|
||||
|
||||
#include "./deno.h"
|
||||
|
||||
#define CHECK(x) assert(x) // TODO(ry) use V8's CHECK.
|
||||
|
||||
// Extracts a C string from a v8::V8 Utf8Value.
|
||||
const char* ToCString(const v8::String::Utf8Value& value) {
|
||||
return *value ? *value : "<string conversion failed>";
|
||||
}
|
||||
|
||||
static inline v8::Local<v8::String> v8_str(const char* x) {
|
||||
return v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), x,
|
||||
v8::NewStringType::kNormal)
|
||||
.ToLocalChecked();
|
||||
}
|
||||
|
||||
// Exits the process.
|
||||
void HandleException(Deno* d, v8::Local<v8::Value> exception) {
|
||||
v8::HandleScope handle_scope(d->isolate);
|
||||
auto context = d->context.Get(d->isolate);
|
||||
v8::Context::Scope context_scope(context);
|
||||
|
||||
auto message = v8::Exception::CreateMessage(d->isolate, exception);
|
||||
auto onerrorStr = v8::String::NewFromUtf8(d->isolate, "onerror");
|
||||
auto onerror = context->Global()->Get(onerrorStr);
|
||||
|
||||
if (onerror->IsFunction()) {
|
||||
auto func = v8::Local<v8::Function>::Cast(onerror);
|
||||
v8::Local<v8::Value> args[5];
|
||||
auto origin = message->GetScriptOrigin();
|
||||
args[0] = exception->ToString();
|
||||
args[1] = message->GetScriptResourceName();
|
||||
args[2] = origin.ResourceLineOffset();
|
||||
args[3] = origin.ResourceColumnOffset();
|
||||
args[4] = exception;
|
||||
func->Call(context->Global(), 5, args);
|
||||
/* message, source, lineno, colno, error */
|
||||
} else {
|
||||
v8::String::Utf8Value exceptionStr(d->isolate, exception);
|
||||
printf("Unhandled Exception %s\n", ToCString(exceptionStr));
|
||||
message->PrintCurrentStackTrace(d->isolate, stdout);
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
bool AbortOnUncaughtExceptionCallback(v8::Isolate* isolate) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void MessageCallback2(Local<Message> message, v8::Local<v8::Value> data) {
|
||||
printf("MessageCallback2\n\n");
|
||||
}
|
||||
|
||||
void FatalErrorCallback2(const char* location, const char* message) {
|
||||
printf("FatalErrorCallback2\n");
|
||||
}
|
||||
*/
|
||||
|
||||
void ExitOnPromiseRejectCallback(
|
||||
v8::PromiseRejectMessage promise_reject_message) {
|
||||
auto* isolate = v8::Isolate::GetCurrent();
|
||||
Deno* d = static_cast<Deno*>(isolate->GetData(0));
|
||||
assert(d->isolate == isolate);
|
||||
v8::HandleScope handle_scope(d->isolate);
|
||||
auto exception = promise_reject_message.GetValue();
|
||||
HandleException(d, exception);
|
||||
}
|
||||
|
||||
void Print(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
bool first = true;
|
||||
auto* isolate = args.GetIsolate();
|
||||
for (int i = 0; i < args.Length(); i++) {
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
printf(" ");
|
||||
}
|
||||
v8::String::Utf8Value str(isolate, args[i]);
|
||||
const char* cstr = ToCString(str);
|
||||
printf("%s", cstr);
|
||||
}
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
// Sets the recv callback.
|
||||
void Recv(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
v8::Isolate* isolate = args.GetIsolate();
|
||||
Deno* d = reinterpret_cast<Deno*>(isolate->GetData(0));
|
||||
assert(d->isolate == isolate);
|
||||
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
|
||||
v8::Local<v8::Value> v = args[0];
|
||||
assert(v->IsFunction());
|
||||
v8::Local<v8::Function> func = v8::Local<v8::Function>::Cast(v);
|
||||
|
||||
d->recv.Reset(isolate, func);
|
||||
}
|
||||
|
||||
// Called from JavaScript, routes message to golang.
|
||||
void Send(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
v8::Isolate* isolate = args.GetIsolate();
|
||||
Deno* d = static_cast<Deno*>(isolate->GetData(0));
|
||||
assert(d->isolate == isolate);
|
||||
|
||||
v8::Locker locker(d->isolate);
|
||||
v8::EscapableHandleScope handle_scope(isolate);
|
||||
|
||||
v8::Local<v8::Value> v = args[0];
|
||||
assert(v->IsArrayBuffer());
|
||||
|
||||
auto ab = v8::Local<v8::ArrayBuffer>::Cast(v);
|
||||
auto contents = ab->GetContents();
|
||||
|
||||
void* buf = contents.Data();
|
||||
int buflen = static_cast<int>(contents.ByteLength());
|
||||
|
||||
auto retbuf = d->cb(d, DenoBuf{buf, buflen});
|
||||
if (retbuf.data) {
|
||||
auto ab = v8::ArrayBuffer::New(d->isolate, retbuf.data, retbuf.len,
|
||||
v8::ArrayBufferCreationMode::kInternalized);
|
||||
/*
|
||||
// I'm slightly worried the above v8::ArrayBuffer construction leaks memory
|
||||
// the following might be a safer way to do it.
|
||||
auto ab = v8::ArrayBuffer::New(d->isolate, retbuf.len);
|
||||
auto contents = ab->GetContents();
|
||||
memcpy(contents.Data(), retbuf.data, retbuf.len);
|
||||
free(retbuf.data);
|
||||
*/
|
||||
args.GetReturnValue().Set(handle_scope.Escape(ab));
|
||||
}
|
||||
}
|
||||
|
||||
intptr_t external_references[] = {reinterpret_cast<intptr_t>(Print),
|
||||
reinterpret_cast<intptr_t>(Recv),
|
||||
reinterpret_cast<intptr_t>(Send), 0};
|
||||
|
||||
const char* v8_version() { return v8::V8::GetVersion(); }
|
||||
|
||||
void v8_set_flags(int* argc, char** argv) {
|
||||
v8::V8::SetFlagsFromCommandLine(argc, argv, true);
|
||||
}
|
||||
|
||||
const char* deno_last_exception(Deno* d) { return d->last_exception.c_str(); }
|
||||
|
||||
int deno_load(Deno* d, const char* name_s, const char* source_s) {
|
||||
v8::Locker locker(d->isolate);
|
||||
v8::Isolate::Scope isolate_scope(d->isolate);
|
||||
v8::HandleScope handle_scope(d->isolate);
|
||||
|
||||
auto context = d->context.Get(d->isolate);
|
||||
v8::Context::Scope context_scope(context);
|
||||
|
||||
v8::TryCatch try_catch(d->isolate);
|
||||
|
||||
auto name = v8_str(name_s);
|
||||
auto source = v8_str(source_s);
|
||||
|
||||
v8::ScriptOrigin origin(name);
|
||||
|
||||
auto script = v8::Script::Compile(context, source, &origin);
|
||||
|
||||
if (script.IsEmpty()) {
|
||||
assert(try_catch.HasCaught());
|
||||
HandleException(d, try_catch.Exception());
|
||||
assert(false);
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto result = script.ToLocalChecked()->Run(context);
|
||||
|
||||
if (result.IsEmpty()) {
|
||||
assert(try_catch.HasCaught());
|
||||
HandleException(d, try_catch.Exception());
|
||||
assert(false);
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Called from golang. Must route message to javascript lang.
|
||||
// non-zero return value indicates error. check deno_last_exception().
|
||||
int deno_send(Deno* d, DenoBuf buf) {
|
||||
v8::Locker locker(d->isolate);
|
||||
v8::Isolate::Scope isolate_scope(d->isolate);
|
||||
v8::HandleScope handle_scope(d->isolate);
|
||||
|
||||
auto context = d->context.Get(d->isolate);
|
||||
v8::Context::Scope context_scope(context);
|
||||
|
||||
v8::TryCatch try_catch(d->isolate);
|
||||
|
||||
v8::Local<v8::Function> recv =
|
||||
v8::Local<v8::Function>::New(d->isolate, d->recv);
|
||||
if (recv.IsEmpty()) {
|
||||
d->last_exception = "V8Deno2.recv has not been called.";
|
||||
return 1;
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> args[1];
|
||||
args[0] = v8::ArrayBuffer::New(d->isolate, buf.data, buf.len,
|
||||
v8::ArrayBufferCreationMode::kInternalized);
|
||||
assert(!args[0].IsEmpty());
|
||||
assert(!try_catch.HasCaught());
|
||||
|
||||
recv->Call(context->Global(), 1, args);
|
||||
|
||||
if (try_catch.HasCaught()) {
|
||||
HandleException(d, try_catch.Exception());
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void v8_init() {
|
||||
// v8::V8::InitializeICUDefaultLocation(argv[0]);
|
||||
// v8::V8::InitializeExternalStartupData(argv[0]);
|
||||
auto p = v8::platform::CreateDefaultPlatform();
|
||||
v8::V8::InitializePlatform(p);
|
||||
v8::V8::Initialize();
|
||||
}
|
||||
|
||||
Deno* deno_new(void* data, RecvCallback cb) {
|
||||
Deno* d = new Deno;
|
||||
d->cb = cb;
|
||||
d->data = data;
|
||||
v8::Isolate::CreateParams params;
|
||||
params.array_buffer_allocator =
|
||||
v8::ArrayBuffer::Allocator::NewDefaultAllocator();
|
||||
v8::Isolate* isolate = v8::Isolate::New(params);
|
||||
deno_add_isolate(d, isolate);
|
||||
return d;
|
||||
}
|
||||
|
||||
Deno* deno_from_snapshot(v8::StartupData* blob, void* data, RecvCallback cb) {
|
||||
Deno* d = new Deno;
|
||||
d->cb = cb;
|
||||
d->data = data;
|
||||
v8::Isolate::CreateParams params;
|
||||
params.snapshot_blob = blob;
|
||||
params.array_buffer_allocator =
|
||||
v8::ArrayBuffer::Allocator::NewDefaultAllocator();
|
||||
params.external_references = external_references;
|
||||
v8::Isolate* isolate = v8::Isolate::New(params);
|
||||
deno_add_isolate(d, isolate);
|
||||
|
||||
v8::Isolate::Scope isolate_scope(isolate);
|
||||
{
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
auto context = v8::Context::New(isolate);
|
||||
d->context.Reset(d->isolate, context);
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
void deno_add_isolate(Deno* d, v8::Isolate* isolate) {
|
||||
d->isolate = isolate;
|
||||
// Leaving this code here because it will probably be useful later on, but
|
||||
// disabling it now as I haven't got tests for the desired behavior.
|
||||
// d->isolate->SetCaptureStackTraceForUncaughtExceptions(true);
|
||||
// d->isolate->SetAbortOnUncaughtExceptionCallback(AbortOnUncaughtExceptionCallback);
|
||||
// d->isolate->AddMessageListener(MessageCallback2);
|
||||
// d->isolate->SetFatalErrorHandler(FatalErrorCallback2);
|
||||
d->isolate->SetPromiseRejectCallback(ExitOnPromiseRejectCallback);
|
||||
d->isolate->SetData(0, d);
|
||||
}
|
||||
|
||||
v8::StartupData SerializeInternalField(v8::Local<v8::Object> holder, int index,
|
||||
void* data) {
|
||||
printf("SerializeInternalField %d\n", index);
|
||||
v8::StartupData sd;
|
||||
sd.data = "a";
|
||||
sd.raw_size = 1;
|
||||
return sd;
|
||||
}
|
||||
|
||||
v8::StartupData deno_make_snapshot(const char* js_filename,
|
||||
const char* js_source) {
|
||||
auto creator = new v8::SnapshotCreator(external_references);
|
||||
auto* isolate = creator->GetIsolate();
|
||||
|
||||
Deno* d = new Deno;
|
||||
deno_add_isolate(d, isolate);
|
||||
|
||||
v8::Isolate::Scope isolate_scope(isolate);
|
||||
{
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
|
||||
v8::Local<v8::Context> context = v8::Context::New(d->isolate);
|
||||
v8::Context::Scope context_scope(context);
|
||||
|
||||
d->context.Reset(d->isolate, context);
|
||||
|
||||
auto global = context->Global();
|
||||
|
||||
auto print_tmpl = v8::FunctionTemplate::New(isolate, Print);
|
||||
auto print_val = print_tmpl->GetFunction(context).ToLocalChecked();
|
||||
CHECK(global->Set(context, v8_str("deno_print"), print_val).FromJust());
|
||||
|
||||
auto recv_tmpl = v8::FunctionTemplate::New(isolate, Recv);
|
||||
auto recv_val = recv_tmpl->GetFunction(context).ToLocalChecked();
|
||||
CHECK(global->Set(context, v8_str("deno_recv"), recv_val).FromJust());
|
||||
|
||||
auto send_tmpl = v8::FunctionTemplate::New(isolate, Send);
|
||||
auto send_val = send_tmpl->GetFunction(context).ToLocalChecked();
|
||||
CHECK(global->Set(context, v8_str("deno_send"), send_val).FromJust());
|
||||
|
||||
creator->SetDefaultContext(context);
|
||||
}
|
||||
|
||||
int r = deno_load(d, js_filename, js_source);
|
||||
assert(r == 0);
|
||||
|
||||
d->context.Reset(); // Delete persistant handles.
|
||||
d->recv.Reset(); // Delete persistant handles.
|
||||
|
||||
auto snapshot_blob =
|
||||
creator->CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kKeep);
|
||||
|
||||
return snapshot_blob;
|
||||
}
|
||||
|
||||
void deno_dispose(Deno* d) {
|
||||
d->isolate->Dispose();
|
||||
delete (d);
|
||||
}
|
||||
|
||||
void deno_terminate_execution(Deno* d) { d->isolate->TerminateExecution(); }
|
55
deno2/deno.h
Normal file
55
deno2/deno.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
// Copyright 2018 Ryan Dahl <ry@tinyclouds.org>
|
||||
// All rights reserved. MIT License.
|
||||
#ifndef DENO_H_
|
||||
#define DENO_H_
|
||||
|
||||
#include <string>
|
||||
#include "v8/include/v8.h"
|
||||
|
||||
// Data that gets transmitted.
|
||||
struct buf_s {
|
||||
void* data;
|
||||
size_t len;
|
||||
};
|
||||
typedef struct buf_s DenoBuf;
|
||||
// Deno = Wrapped Isolate.
|
||||
struct deno_s;
|
||||
typedef struct deno_s Deno;
|
||||
// The callback from V8 when data is sent.
|
||||
typedef DenoBuf (*RecvCallback)(Deno* d, DenoBuf buf);
|
||||
struct deno_s {
|
||||
v8::Isolate* isolate;
|
||||
std::string last_exception;
|
||||
v8::Persistent<v8::Function> recv;
|
||||
v8::Persistent<v8::Context> context;
|
||||
RecvCallback cb;
|
||||
void* data;
|
||||
};
|
||||
|
||||
void v8_init();
|
||||
const char* v8_version();
|
||||
void v8_set_flags(int* argc, char** argv);
|
||||
|
||||
// Constructors:
|
||||
Deno* deno_new(void* data, RecvCallback cb);
|
||||
Deno* deno_from_snapshot(v8::StartupData* blob, void* data, RecvCallback cb);
|
||||
|
||||
v8::StartupData deno_make_snapshot(const char* js_filename,
|
||||
const char* js_source);
|
||||
|
||||
void deno_add_isolate(Deno* d, v8::Isolate* isolate);
|
||||
void* deno_get_data();
|
||||
|
||||
// Returns nonzero on error.
|
||||
// Get error text with deno_last_exception().
|
||||
int deno_load(Deno* d, const char* name_s, const char* source_s);
|
||||
|
||||
// Returns nonzero on error.
|
||||
int deno_send(Deno* d, DenoBuf buf);
|
||||
|
||||
const char* deno_last_exception(Deno* d);
|
||||
|
||||
void deno_dispose(Deno* d);
|
||||
void deno_terminate_execution(Deno* d);
|
||||
|
||||
#endif // DENO_H_
|
15
deno2/deno_test.cc
Normal file
15
deno2/deno_test.cc
Normal file
|
@ -0,0 +1,15 @@
|
|||
// Copyright 2018 Ryan Dahl <ry@tinyclouds.org>
|
||||
// All rights reserved. MIT License.
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
#include "./deno.h"
|
||||
|
||||
TEST(SnapshotTest, InitializesCorrectly) {
|
||||
EXPECT_TRUE(true);
|
||||
// TODO(ry) add actual tests
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
7
deno2/js/main.ts
Normal file
7
deno2/js/main.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
const globalEval = eval;
|
||||
const window = globalEval("this");
|
||||
window['foo'] = () => {
|
||||
deno_print("Hello world from foo");
|
||||
return "foo";
|
||||
}
|
||||
|
6
deno2/js/package.json
Normal file
6
deno2/js/package.json
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"devDependencies": {
|
||||
"parcel-bundler": "^1.8.1",
|
||||
"typescript": "^2.9.1"
|
||||
}
|
||||
}
|
14
deno2/js/run_node.py
Executable file
14
deno2/js/run_node.py
Executable file
|
@ -0,0 +1,14 @@
|
|||
#!/usr/bin/env python
|
||||
"""
|
||||
gn can only run python scripts.
|
||||
Also Node programs except to be run with cwd = $root_dir/js so it can resolve
|
||||
node_modules.
|
||||
"""
|
||||
import subprocess
|
||||
import sys
|
||||
import os
|
||||
|
||||
js_path = os.path.dirname(os.path.realpath(__file__))
|
||||
os.chdir(js_path)
|
||||
args = ["node"] + sys.argv[1:]
|
||||
sys.exit(subprocess.call(args))
|
3535
deno2/js/yarn.lock
Normal file
3535
deno2/js/yarn.lock
Normal file
File diff suppressed because it is too large
Load diff
33
deno2/main.cc
Normal file
33
deno2/main.cc
Normal file
|
@ -0,0 +1,33 @@
|
|||
// Copyright 2018 Ryan Dahl <ry@tinyclouds.org>
|
||||
// All rights reserved. MIT License.
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "v8/include/v8.h"
|
||||
|
||||
#include "./deno.h"
|
||||
#include "natives_deno.cc"
|
||||
#include "snapshot_deno.cc"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
v8_init();
|
||||
|
||||
auto natives_blob = *StartupBlob_natives();
|
||||
printf("natives_blob %d bytes\n", natives_blob.raw_size);
|
||||
|
||||
auto snapshot_blob = *StartupBlob_snapshot();
|
||||
printf("snapshot_blob %d bytes\n", snapshot_blob.raw_size);
|
||||
|
||||
v8::V8::SetNativesDataBlob(&natives_blob);
|
||||
v8::V8::SetSnapshotDataBlob(&snapshot_blob);
|
||||
|
||||
Deno* d = deno_from_snapshot(&snapshot_blob, NULL, NULL);
|
||||
int r = deno_load(d, "main2.js", "foo();");
|
||||
if (r != 0) {
|
||||
printf("Error! %s\n", deno_last_exception(d));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
const char* v = v8::V8::GetVersion();
|
||||
printf("Hello World. V8 version %s\n", v);
|
||||
}
|
102
deno2/msg.proto
Normal file
102
deno2/msg.proto
Normal file
|
@ -0,0 +1,102 @@
|
|||
// Copyright 2018 Ryan Dahl <ry@tinyclouds.org>
|
||||
// All rights reserved. MIT License.
|
||||
syntax = "proto3";
|
||||
package main;
|
||||
option go_package = "deno";
|
||||
|
||||
message BaseMsg {
|
||||
string channel = 1;
|
||||
bytes payload = 2;
|
||||
}
|
||||
|
||||
message Msg {
|
||||
enum Command {
|
||||
ERROR = 0;
|
||||
START = 1;
|
||||
CODE_FETCH = 2;
|
||||
CODE_FETCH_RES = 3;
|
||||
CODE_CACHE = 4;
|
||||
EXIT = 5;
|
||||
TIMER_START = 6;
|
||||
TIMER_READY = 7;
|
||||
TIMER_CLEAR = 8;
|
||||
FETCH_REQ = 9;
|
||||
FETCH_RES = 10;
|
||||
READ_FILE_SYNC = 11;
|
||||
READ_FILE_SYNC_RES = 12;
|
||||
WRITE_FILE_SYNC = 13;
|
||||
}
|
||||
Command command = 1;
|
||||
|
||||
// We avoid creating a message for each command (and use oneof or any types)
|
||||
// In order to reduce code in the size of the generated javascript
|
||||
// "msg.pb.js". It seems that each new message adds 20k and we want to
|
||||
// potentially add many hundreds of commands. Therefore we just prefix command
|
||||
// arguments by their name.
|
||||
|
||||
// ERROR
|
||||
string error = 2;
|
||||
|
||||
// START
|
||||
string start_cwd = 10;
|
||||
repeated string start_argv = 11;
|
||||
bool start_debug_flag = 12;
|
||||
string start_main_js = 13; // The contents of dist/main.js
|
||||
string start_main_map = 14; // The contents of dist/main.map
|
||||
|
||||
// CODE_FETCH
|
||||
string code_fetch_module_specifier = 20;
|
||||
string code_fetch_containing_file = 21;
|
||||
|
||||
// CODE_FETCH_RES
|
||||
// If it's a non-http module, moduleName and filename will be the same.
|
||||
// For http modules, moduleName is its resolved http URL, and filename
|
||||
// is the location of the locally downloaded source code.
|
||||
string code_fetch_res_module_name = 30;
|
||||
string code_fetch_res_filename = 31;
|
||||
string code_fetch_res_source_code = 32;
|
||||
string code_fetch_res_output_code = 33; // Non-empty only if cached.
|
||||
|
||||
// CODE_CACHE
|
||||
string code_cache_filename = 41;
|
||||
string code_cache_source_code = 42;
|
||||
string code_cache_output_code = 43;
|
||||
|
||||
// EXIT
|
||||
int32 exit_code = 50;
|
||||
|
||||
// TIMER_START
|
||||
int32 timer_start_id = 60;
|
||||
bool timer_start_interval = 61;
|
||||
int32 timer_start_duration = 62; // In milliseconds.
|
||||
|
||||
// TIMER_READY
|
||||
int32 timer_ready_id = 70;
|
||||
bool timer_ready_done = 71;
|
||||
|
||||
// TIMER_CLEAR
|
||||
int32 timer_clear_id = 80;
|
||||
|
||||
// FETCH_REQ
|
||||
int32 fetch_req_id = 90;
|
||||
string fetch_req_url = 91;
|
||||
// repeated string fetch_req_header_line = 91
|
||||
|
||||
// FETCH_RES
|
||||
int32 fetch_res_id = 100;
|
||||
int32 fetch_res_status = 101;
|
||||
repeated string fetch_res_header_line = 102;
|
||||
bytes fetch_res_body = 103;
|
||||
|
||||
// READ_FILE_SYNC
|
||||
string read_file_sync_filename = 110;
|
||||
|
||||
// READ_FILE_SYNC_RES
|
||||
bytes read_file_sync_data = 120;
|
||||
|
||||
// WRITE_FILE_SYNC
|
||||
string write_file_sync_filename = 130;
|
||||
bytes write_file_sync_data = 131;
|
||||
uint32 write_file_sync_perm = 132;
|
||||
// write_file_sync_perm specified by https://godoc.org/os#FileMode
|
||||
}
|
145
deno2/snapshot_creator.cc
Normal file
145
deno2/snapshot_creator.cc
Normal file
|
@ -0,0 +1,145 @@
|
|||
// Copyright 2018 Ryan Dahl <ry@tinyclouds.org>
|
||||
// All rights reserved. MIT License.
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <fstream>
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
|
||||
#include "v8/include/v8.h"
|
||||
|
||||
#include "./deno.h"
|
||||
|
||||
class StartupDataCppWriter {
|
||||
public:
|
||||
StartupDataCppWriter(const char* name, const char* filename,
|
||||
v8::StartupData sd)
|
||||
: name_(name),
|
||||
filename_(filename),
|
||||
sd_(sd),
|
||||
file_(filename_, std::ios::binary) {}
|
||||
|
||||
void Write() {
|
||||
WritePrefix();
|
||||
WriteData();
|
||||
WriteSuffix();
|
||||
|
||||
file_.close();
|
||||
if (file_.bad()) {
|
||||
printf("Unable to open file \"%s\" for writing.\n", filename_);
|
||||
exit(1);
|
||||
}
|
||||
printf("Wrote %s %d %s \n", name_, sd_.raw_size, filename_);
|
||||
}
|
||||
|
||||
private:
|
||||
void WritePrefix() {
|
||||
file_ << "// Autogenerated snapshot file. Do not edit.\n\n";
|
||||
file_ << "#include \"v8/include/v8.h\"\n\n";
|
||||
}
|
||||
|
||||
void WriteSuffix() {
|
||||
char buffer[500];
|
||||
snprintf(buffer, sizeof(buffer),
|
||||
"const v8::StartupData* StartupBlob_%s() {\n", name_);
|
||||
file_ << buffer;
|
||||
snprintf(buffer, sizeof(buffer), " return &%s_blob;\n", name_);
|
||||
file_ << buffer;
|
||||
file_ << "}\n\n";
|
||||
}
|
||||
|
||||
void WriteBinaryContentsAsCArray() {
|
||||
char buffer[5];
|
||||
for (int i = 0; i < sd_.raw_size; i++) {
|
||||
if ((i & 0x1F) == 0x1F) file_ << "\n";
|
||||
if (i > 0) file_ << ",";
|
||||
snprintf(buffer, sizeof(buffer), "%u",
|
||||
static_cast<unsigned char>(sd_.data[i]));
|
||||
file_ << buffer;
|
||||
}
|
||||
file_ << "\n";
|
||||
}
|
||||
|
||||
void WriteData() {
|
||||
char buffer[500];
|
||||
snprintf(buffer, sizeof(buffer), "static const char %s_blob_data[] = {\n",
|
||||
name_);
|
||||
file_ << buffer;
|
||||
WriteBinaryContentsAsCArray();
|
||||
file_ << "};\n";
|
||||
snprintf(buffer, sizeof(buffer), "static const int %s_blob_size = %d;\n",
|
||||
name_, sd_.raw_size);
|
||||
file_ << buffer;
|
||||
snprintf(buffer, sizeof(buffer), "static const v8::StartupData %s_blob =\n",
|
||||
name_);
|
||||
file_ << buffer;
|
||||
snprintf(buffer, sizeof(buffer),
|
||||
"{ (const char*) %s_blob_data, %s_blob_size };\n", name_, name_);
|
||||
file_ << buffer;
|
||||
}
|
||||
|
||||
const char* name_;
|
||||
const char* filename_;
|
||||
v8::StartupData sd_;
|
||||
std::ofstream file_;
|
||||
};
|
||||
|
||||
// Caller must free returned value.
|
||||
static v8::StartupData ReadFile(const char* fn) {
|
||||
std::ifstream input(fn, std::ios::binary);
|
||||
if (input.bad()) {
|
||||
printf("Error reading %s\n", fn);
|
||||
exit(1);
|
||||
}
|
||||
// Note the allocated buffer is intentionally not freed in this program.
|
||||
// It may show up as a memory leak some day, but other than that it's
|
||||
// harmless.
|
||||
auto* buffer = new std::vector<char>((std::istreambuf_iterator<char>(input)),
|
||||
(std::istreambuf_iterator<char>()));
|
||||
v8::StartupData sd;
|
||||
sd.data = buffer->data();
|
||||
sd.raw_size = static_cast<int>(buffer->size());
|
||||
if (input.bad()) {
|
||||
printf("Error reading %s\n", fn);
|
||||
exit(1);
|
||||
}
|
||||
return sd;
|
||||
}
|
||||
|
||||
void WriteFile(const char* fn, v8::StartupData startup_data) {
|
||||
std::ofstream output(fn, std::ios::binary);
|
||||
output.write(startup_data.data, startup_data.raw_size);
|
||||
output.close();
|
||||
if (output.bad()) {
|
||||
printf("Error writing %s\n", fn);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
// The only documentation for this programs arguments is right here.
|
||||
const char* js_fn = argv[1];
|
||||
const char* natives_in_bin = argv[2];
|
||||
const char* snapshot_in_bin = argv[3];
|
||||
const char* natives_out_cc = argv[4];
|
||||
const char* snapshot_out_cc = argv[5];
|
||||
|
||||
v8_init();
|
||||
|
||||
auto js_data = ReadFile(js_fn);
|
||||
auto natives_blob = ReadFile(natives_in_bin);
|
||||
auto snapshot_in_blob = ReadFile(snapshot_in_bin);
|
||||
|
||||
v8::V8::SetNativesDataBlob(&natives_blob);
|
||||
v8::V8::SetSnapshotDataBlob(&snapshot_in_blob);
|
||||
|
||||
auto snapshot_blob = deno_make_snapshot(js_fn, js_data.data);
|
||||
|
||||
StartupDataCppWriter nativesWriter("natives", natives_out_cc, natives_blob);
|
||||
nativesWriter.Write();
|
||||
|
||||
StartupDataCppWriter snapshotWriter("snapshot", snapshot_out_cc,
|
||||
snapshot_blob);
|
||||
snapshotWriter.Write();
|
||||
}
|
1
deno2/testing
Symbolic link
1
deno2/testing
Symbolic link
|
@ -0,0 +1 @@
|
|||
v8/testing
|
1
deno2/third_party/googletest
vendored
Symbolic link
1
deno2/third_party/googletest
vendored
Symbolic link
|
@ -0,0 +1 @@
|
|||
../v8/third_party/googletest/
|
1
deno2/third_party/jinja2
vendored
Symbolic link
1
deno2/third_party/jinja2
vendored
Symbolic link
|
@ -0,0 +1 @@
|
|||
../v8/third_party/jinja2/
|
1
deno2/third_party/llvm-build
vendored
Symbolic link
1
deno2/third_party/llvm-build
vendored
Symbolic link
|
@ -0,0 +1 @@
|
|||
../v8/third_party/llvm-build/
|
1
deno2/third_party/markupsafe
vendored
Symbolic link
1
deno2/third_party/markupsafe
vendored
Symbolic link
|
@ -0,0 +1 @@
|
|||
../v8/third_party/markupsafe/
|
67
deno2/tools/build.py
Executable file
67
deno2/tools/build.py
Executable file
|
@ -0,0 +1,67 @@
|
|||
#!/usr/bin/env python
|
||||
# Get Depot Tools and make sure it's in your path.
|
||||
# http://commondatastorage.googleapis.com/chrome-infra-docs/flat/depot_tools/docs/html/depot_tools_tutorial.html#_setting_up
|
||||
# Use .gclient to modify the deps.
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import argparse
|
||||
|
||||
TARGET = "deno"
|
||||
|
||||
parser = argparse.ArgumentParser(description="build.py")
|
||||
parser.add_argument('--debug', dest='debug', action='store_true')
|
||||
parser.add_argument('--use_ccache', dest='use_ccache', action='store_true')
|
||||
parser.add_argument('--sync', dest='sync', action='store_true')
|
||||
parser.set_defaults(debug=False, use_ccache=False, sync=False)
|
||||
args = parser.parse_args()
|
||||
|
||||
root_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
|
||||
|
||||
|
||||
def main():
|
||||
os.chdir(root_path)
|
||||
buildName = "Debug" if args.debug else "Default"
|
||||
buildDir = os.path.join(root_path, "out", buildName)
|
||||
# Run sync if any of the dep dirs don't exist.
|
||||
# Or the user supplied the --sync flag.
|
||||
if args.sync or dirsMissing():
|
||||
run(["gclient", "sync", "--no-history"])
|
||||
|
||||
# Run gn gen out/Default if out doesn't exist.
|
||||
if not os.path.exists(buildDir):
|
||||
gn_gen = ["gn", "gen", buildDir]
|
||||
gn_args = []
|
||||
if args.debug:
|
||||
gn_args.append("is_debug=true")
|
||||
if args.use_ccache:
|
||||
gn_args.append("cc_wrapper=\"ccache\"")
|
||||
if len(gn_args) > 0:
|
||||
gn_gen += ["--args=%s" % " ".join(gn_args)]
|
||||
run(gn_gen)
|
||||
|
||||
# Always run ninja.
|
||||
run(["ninja", "-C", buildDir, TARGET])
|
||||
|
||||
|
||||
def run(args):
|
||||
print " ".join(args)
|
||||
env = os.environ.copy()
|
||||
subprocess.check_call(args, env=env)
|
||||
|
||||
|
||||
def dirsMissing():
|
||||
dirsToLoad = [
|
||||
"v8",
|
||||
"third_party/protobuf",
|
||||
"tools/protoc_wrapper",
|
||||
"third_party/zlib",
|
||||
]
|
||||
for d in dirsToLoad:
|
||||
if not os.path.exists(d):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
if '__main__' == __name__:
|
||||
main()
|
6
deno2/tools/format.sh
Executable file
6
deno2/tools/format.sh
Executable file
|
@ -0,0 +1,6 @@
|
|||
#!/bin/sh
|
||||
cd `dirname "$0"`/..
|
||||
clang-format -i -style Google *.cc *.h
|
||||
gn format BUILD.gn
|
||||
gn format .gn
|
||||
yapf -i tools/*.py
|
4
deno2/tools/lint.sh
Executable file
4
deno2/tools/lint.sh
Executable file
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
cd `dirname "$0"`/..
|
||||
set -e
|
||||
cpplint *.cc *.h
|
Loading…
Reference in a new issue