mirror of
https://github.com/denoland/deno.git
synced 2024-11-28 16:20:57 -05:00
Demo protobufs in deno2.
Adds deno_set_response() to allow stack allocated responses.
This commit is contained in:
parent
f97216609d
commit
4ac67cf343
10 changed files with 88 additions and 35 deletions
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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([]));
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue