summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Dahl <ry@tinyclouds.org>2018-06-13 19:38:22 +0200
committerRyan Dahl <ry@tinyclouds.org>2018-06-14 14:19:17 +0200
commit4ac67cf3435b3e15f95fadc20c98e37abf706ea4 (patch)
tree651b18c568e6ca8130d3d37de60a6a44e12e855b
parentf97216609d1705a21ddbe6ca3efb04817f026fc3 (diff)
Demo protobufs in deno2.
Adds deno_set_response() to allow stack allocated responses.
-rw-r--r--deno2/BUILD.gn9
-rw-r--r--deno2/deno.cc22
-rw-r--r--deno2/deno_internal.h1
-rw-r--r--deno2/from_snapshot.cc1
-rw-r--r--deno2/include/deno.h8
-rw-r--r--deno2/js/main.ts31
-rw-r--r--deno2/main.cc22
-rw-r--r--deno2/mock_runtime_test.cc23
-rw-r--r--deno2/snapshot_creator.cc4
-rwxr-xr-xdeno2/tools/lint.sh2
10 files changed, 88 insertions, 35 deletions
diff --git a/deno2/BUILD.gn b/deno2/BUILD.gn
index 7b358e7c6..564d8f8fb 100644
--- a/deno2/BUILD.gn
+++ b/deno2/BUILD.gn
@@ -8,6 +8,8 @@ executable("deno") {
]
deps = [
":libdeno",
+ ":msg_proto",
+ "//third_party/protobuf:protoc_lib",
]
}
@@ -45,7 +47,6 @@ source_set("deno_nosnapshot") {
]
include_dirs = [ "include/" ]
deps = [
- ":msg_proto",
"v8:v8",
"v8:v8_libbase",
"v8:v8_libplatform",
@@ -66,6 +67,7 @@ proto_library("msg_proto") {
sources = [
"msg.proto",
]
+ generate_python = false
}
template("run_node") {
@@ -78,13 +80,15 @@ template("run_node") {
run_node("bundle") {
out_dir = "$target_gen_dir/bundle/"
sources = [
- "$target_gen_dir/tsc_dist/main.js", # Not real input. See run_tsc comment.
"js/main.ts",
+ "js/msg.pb.d.ts",
+ "js/msg.pb.js",
]
outputs = [
out_dir + "main.js",
]
deps = [
+ ":protobufjs",
":run_tsc",
]
args = [
@@ -111,7 +115,6 @@ run_node("run_tsc") {
]
outputs = [
out_dir + "/main.js",
- out_dir + "/main.map",
]
deps = [
":protobufjs",
diff --git a/deno2/deno.cc b/deno2/deno.cc
index 27dfefb8e..d59f49065 100644
--- a/deno2/deno.cc
+++ b/deno2/deno.cc
@@ -154,15 +154,12 @@ void Pub(const v8::FunctionCallbackInfo<v8::Value>& args) {
const_cast<const char*>(reinterpret_cast<char*>(contents.Data()));
deno_buf buf{data, contents.ByteLength()};
- auto retbuf = d->cb(d, channel, buf);
- if (retbuf.data) {
- // TODO(ry) Support zero-copy.
- auto ab = v8::ArrayBuffer::New(d->isolate, retbuf.len);
- memcpy(ab->GetContents().Data(), retbuf.data, retbuf.len);
- args.GetReturnValue().Set(handle_scope.Escape(ab));
- } else {
- args.GetReturnValue().Set(v8::Null(d->isolate));
- }
+ assert(d->currentArgs == nullptr);
+ d->currentArgs = &args;
+
+ d->cb(d, channel, buf);
+
+ d->currentArgs = nullptr;
}
bool Execute(v8::Local<v8::Context> context, const char* js_filename,
@@ -334,6 +331,13 @@ bool deno_pub(Deno* d, const char* channel, deno_buf buf) {
return true;
}
+void deno_set_response(Deno* d, deno_buf buf) {
+ // TODO(ry) Support zero-copy.
+ auto ab = v8::ArrayBuffer::New(d->isolate, buf.len);
+ memcpy(ab->GetContents().Data(), buf.data, buf.len);
+ d->currentArgs->GetReturnValue().Set(ab);
+}
+
void deno_delete(Deno* d) {
d->isolate->Dispose();
delete d;
diff --git a/deno2/deno_internal.h b/deno2/deno_internal.h
index 2ecd5d1f4..0c3d4fd77 100644
--- a/deno2/deno_internal.h
+++ b/deno2/deno_internal.h
@@ -11,6 +11,7 @@ extern "C" {
// deno_s = Wrapped Isolate.
struct deno_s {
v8::Isolate* isolate;
+ const v8::FunctionCallbackInfo<v8::Value>* currentArgs;
std::string last_exception;
v8::Persistent<v8::Function> sub;
v8::Persistent<v8::Context> context;
diff --git a/deno2/from_snapshot.cc b/deno2/from_snapshot.cc
index 68185ce6d..5f954dc09 100644
--- a/deno2/from_snapshot.cc
+++ b/deno2/from_snapshot.cc
@@ -45,6 +45,7 @@ Deno* NewFromSnapshot(void* data, deno_sub_cb cb) {
v8::DeserializeInternalFieldsCallback(DeserializeInternalFields, nullptr);
Deno* d = new Deno;
+ d->currentArgs = nullptr;
d->cb = cb;
d->data = data;
v8::Isolate::CreateParams params;
diff --git a/deno2/include/deno.h b/deno2/include/deno.h
index 3c42abd72..72318677a 100644
--- a/deno2/include/deno.h
+++ b/deno2/include/deno.h
@@ -19,8 +19,7 @@ typedef struct deno_s Deno;
// A callback to receive a message from deno_pub javascript call.
// buf is valid only for the lifetime of the call.
-// The returned deno_buf is returned from deno_pub in javascript.
-typedef deno_buf (*deno_sub_cb)(Deno* d, const char* channel, deno_buf buf);
+typedef void (*deno_sub_cb)(Deno* d, const char* channel, deno_buf buf);
void deno_init();
const char* deno_v8_version();
@@ -37,6 +36,11 @@ bool deno_execute(Deno* d, const char* js_filename, const char* js_source);
// value indicates error. Check deno_last_exception() for exception text.
bool deno_pub(Deno* d, const char* channel, deno_buf buf);
+// Call this inside a deno_sub_cb to respond synchronously to messages.
+// If this is not called during the life time of a deno_sub_cb callback
+// the denoPub() call in javascript will return null.
+void deno_set_response(Deno* d, deno_buf buf);
+
const char* deno_last_exception(Deno* d);
void deno_terminate_execution(Deno* d);
diff --git a/deno2/js/main.ts b/deno2/js/main.ts
index c5d490b0b..750813293 100644
--- a/deno2/js/main.ts
+++ b/deno2/js/main.ts
@@ -4,11 +4,32 @@ import * as ts from "typescript";
const globalEval = eval;
const window = globalEval("this");
+
window["denoMain"] = () => {
- denoPrint("Hello world");
- const msg = pb.Msg.fromObject({});
- denoPrint(`msg.command: ${msg.command}`);
denoPrint(`ts.version: ${ts.version}`);
- denoPrint("Hello world from foo");
- return "foo";
+ const res = denoPub("startDeno2", emptyArrayBuffer());
+ //denoPrint(`after`);
+ const resUi8 = new Uint8Array(res);
+ denoPrint(`before`);
+ const msg = pb.Msg.decode(resUi8);
+ denoPrint(`after`);
+ const {
+ startCwd: cwd,
+ startArgv: argv,
+ startDebugFlag: debugFlag,
+ startMainJs: mainJs,
+ startMainMap: mainMap
+ } = msg;
+ denoPrint(`cwd: ${cwd}`);
};
+
+function typedArrayToArrayBuffer(ta: Uint8Array): ArrayBuffer {
+ return ta.buffer.slice(
+ ta.byteOffset,
+ ta.byteOffset + ta.byteLength
+ ) as ArrayBuffer;
+}
+
+function emptyArrayBuffer(): ArrayBuffer {
+ return typedArrayToArrayBuffer(new Uint8Array([]));
+}
diff --git a/deno2/main.cc b/deno2/main.cc
index 2c0b1b298..506469dfa 100644
--- a/deno2/main.cc
+++ b/deno2/main.cc
@@ -3,13 +3,33 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
+#include <unistd.h>
+#include <string>
+#include "./msg.pb.h"
#include "include/deno.h"
+void MessagesFromJS(Deno* d, const char* channel, deno_buf buf) {
+ printf("MessagesFromJS %s\n", channel);
+
+ char cwdbuf[1024];
+ std::string cwd(getcwd(cwdbuf, sizeof(cwdbuf)));
+
+ deno::Msg response;
+ response.set_command(deno::Msg_Command_START);
+ response.set_start_cwd(cwd);
+
+ std::string output;
+ assert(response.SerializeToString(&output) == true);
+
+ auto bufout = deno_buf{output.c_str(), output.length()};
+ deno_set_response(d, bufout);
+}
+
int main(int argc, char** argv) {
deno_init();
- Deno* d = deno_new(NULL, NULL);
+ Deno* d = deno_new(NULL, MessagesFromJS);
bool r = deno_execute(d, "deno_main.js", "denoMain();");
if (!r) {
printf("Error! %s\n", deno_last_exception(d));
diff --git a/deno2/mock_runtime_test.cc b/deno2/mock_runtime_test.cc
index bdaf30416..908e2a7e6 100644
--- a/deno2/mock_runtime_test.cc
+++ b/deno2/mock_runtime_test.cc
@@ -5,20 +5,20 @@
#include "include/deno.h"
TEST(MockRuntimeTest, InitializesCorrectly) {
- Deno* d = deno_new(NULL, NULL);
+ Deno* d = deno_new(nullptr, nullptr);
EXPECT_TRUE(deno_execute(d, "a.js", "1 + 2"));
deno_delete(d);
}
TEST(MockRuntimeTest, CanCallFunction) {
- Deno* d = deno_new(NULL, NULL);
+ Deno* d = deno_new(nullptr, nullptr);
EXPECT_TRUE(deno_execute(d, "a.js",
"if (CanCallFunction() != 'foo') throw Error();"));
deno_delete(d);
}
TEST(MockRuntimeTest, ErrorsCorrectly) {
- Deno* d = deno_new(NULL, NULL);
+ Deno* d = deno_new(nullptr, nullptr);
EXPECT_FALSE(deno_execute(d, "a.js", "throw Error()"));
deno_delete(d);
}
@@ -26,14 +26,14 @@ TEST(MockRuntimeTest, ErrorsCorrectly) {
deno_buf strbuf(const char* str) { return deno_buf{str, strlen(str)}; }
TEST(MockRuntimeTest, PubSuccess) {
- Deno* d = deno_new(NULL, NULL);
+ Deno* d = deno_new(nullptr, nullptr);
EXPECT_TRUE(deno_execute(d, "a.js", "PubSuccess()"));
EXPECT_TRUE(deno_pub(d, "PubSuccess", strbuf("abc")));
deno_delete(d);
}
TEST(MockRuntimeTest, PubByteLength) {
- Deno* d = deno_new(NULL, NULL);
+ Deno* d = deno_new(nullptr, nullptr);
EXPECT_TRUE(deno_execute(d, "a.js", "PubByteLength()"));
// We pub the wrong sized message, it should throw.
EXPECT_FALSE(deno_pub(d, "PubByteLength", strbuf("abcd")));
@@ -41,7 +41,7 @@ TEST(MockRuntimeTest, PubByteLength) {
}
TEST(MockRuntimeTest, PubNoCallback) {
- Deno* d = deno_new(NULL, NULL);
+ Deno* d = deno_new(nullptr, nullptr);
// We didn't call deno_sub(), pubing should fail.
EXPECT_FALSE(deno_pub(d, "PubNoCallback", strbuf("abc")));
deno_delete(d);
@@ -49,14 +49,13 @@ TEST(MockRuntimeTest, PubNoCallback) {
TEST(MockRuntimeTest, SubReturnEmpty) {
static int count = 0;
- Deno* d = deno_new(NULL, [](auto _, auto channel, auto buf) {
+ Deno* d = deno_new(nullptr, [](auto _, auto channel, auto buf) {
count++;
EXPECT_STREQ(channel, "SubReturnEmpty");
EXPECT_EQ(static_cast<size_t>(3), buf.len);
EXPECT_EQ(buf.data[0], 'a');
EXPECT_EQ(buf.data[1], 'b');
EXPECT_EQ(buf.data[2], 'c');
- return deno_buf{nullptr, 0};
});
EXPECT_TRUE(deno_execute(d, "a.js", "SubReturnEmpty()"));
EXPECT_EQ(count, 2);
@@ -65,14 +64,14 @@ TEST(MockRuntimeTest, SubReturnEmpty) {
TEST(MockRuntimeTest, SubReturnBar) {
static int count = 0;
- Deno* d = deno_new(NULL, [](auto _, auto channel, auto buf) {
+ Deno* d = deno_new(nullptr, [](auto deno, auto channel, auto buf) {
count++;
EXPECT_STREQ(channel, "SubReturnBar");
EXPECT_EQ(static_cast<size_t>(3), buf.len);
EXPECT_EQ(buf.data[0], 'a');
EXPECT_EQ(buf.data[1], 'b');
EXPECT_EQ(buf.data[2], 'c');
- return strbuf("bar");
+ deno_set_response(deno, strbuf("bar"));
});
EXPECT_TRUE(deno_execute(d, "a.js", "SubReturnBar()"));
EXPECT_EQ(count, 1);
@@ -80,13 +79,13 @@ TEST(MockRuntimeTest, SubReturnBar) {
}
TEST(MockRuntimeTest, DoubleSubFails) {
- Deno* d = deno_new(NULL, NULL);
+ Deno* d = deno_new(nullptr, nullptr);
EXPECT_FALSE(deno_execute(d, "a.js", "DoubleSubFails()"));
deno_delete(d);
}
TEST(MockRuntimeTest, TypedArraySnapshots) {
- Deno* d = deno_new(NULL, NULL);
+ Deno* d = deno_new(nullptr, nullptr);
EXPECT_TRUE(deno_execute(d, "a.js", "TypedArraySnapshots()"));
deno_delete(d);
}
diff --git a/deno2/snapshot_creator.cc b/deno2/snapshot_creator.cc
index 1cd39cce5..10ddc1500 100644
--- a/deno2/snapshot_creator.cc
+++ b/deno2/snapshot_creator.cc
@@ -136,8 +136,8 @@ int main(int argc, char** argv) {
auto snapshot_in_blob = ReadFile(snapshot_in_bin);
deno_init();
- auto snapshot_blob =
- deno::MakeSnapshot(&natives_blob, &snapshot_in_blob, js_fn, js_source.c_str());
+ auto snapshot_blob = deno::MakeSnapshot(&natives_blob, &snapshot_in_blob,
+ js_fn, js_source.c_str());
StartupDataCppWriter nativesWriter("natives", natives_out_cc, natives_blob);
nativesWriter.Write();
diff --git a/deno2/tools/lint.sh b/deno2/tools/lint.sh
index ed7831e29..64a452f0a 100755
--- a/deno2/tools/lint.sh
+++ b/deno2/tools/lint.sh
@@ -1,4 +1,4 @@
#!/bin/sh
cd `dirname "$0"`/..
set -e -v
-cpplint --repository=. *.cc *.h include/*.h
+cpplint --filter=-build/include_subdir --repository=. *.cc *.h include/*.h