mirror of
https://github.com/denoland/deno.git
synced 2025-02-01 12:16:11 -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 = [
|
deps = [
|
||||||
":libdeno",
|
":libdeno",
|
||||||
|
":msg_proto",
|
||||||
|
"//third_party/protobuf:protoc_lib",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +47,6 @@ source_set("deno_nosnapshot") {
|
||||||
]
|
]
|
||||||
include_dirs = [ "include/" ]
|
include_dirs = [ "include/" ]
|
||||||
deps = [
|
deps = [
|
||||||
":msg_proto",
|
|
||||||
"v8:v8",
|
"v8:v8",
|
||||||
"v8:v8_libbase",
|
"v8:v8_libbase",
|
||||||
"v8:v8_libplatform",
|
"v8:v8_libplatform",
|
||||||
|
@ -66,6 +67,7 @@ proto_library("msg_proto") {
|
||||||
sources = [
|
sources = [
|
||||||
"msg.proto",
|
"msg.proto",
|
||||||
]
|
]
|
||||||
|
generate_python = false
|
||||||
}
|
}
|
||||||
|
|
||||||
template("run_node") {
|
template("run_node") {
|
||||||
|
@ -78,13 +80,15 @@ template("run_node") {
|
||||||
run_node("bundle") {
|
run_node("bundle") {
|
||||||
out_dir = "$target_gen_dir/bundle/"
|
out_dir = "$target_gen_dir/bundle/"
|
||||||
sources = [
|
sources = [
|
||||||
"$target_gen_dir/tsc_dist/main.js", # Not real input. See run_tsc comment.
|
|
||||||
"js/main.ts",
|
"js/main.ts",
|
||||||
|
"js/msg.pb.d.ts",
|
||||||
|
"js/msg.pb.js",
|
||||||
]
|
]
|
||||||
outputs = [
|
outputs = [
|
||||||
out_dir + "main.js",
|
out_dir + "main.js",
|
||||||
]
|
]
|
||||||
deps = [
|
deps = [
|
||||||
|
":protobufjs",
|
||||||
":run_tsc",
|
":run_tsc",
|
||||||
]
|
]
|
||||||
args = [
|
args = [
|
||||||
|
@ -111,7 +115,6 @@ run_node("run_tsc") {
|
||||||
]
|
]
|
||||||
outputs = [
|
outputs = [
|
||||||
out_dir + "/main.js",
|
out_dir + "/main.js",
|
||||||
out_dir + "/main.map",
|
|
||||||
]
|
]
|
||||||
deps = [
|
deps = [
|
||||||
":protobufjs",
|
":protobufjs",
|
||||||
|
|
|
@ -154,15 +154,12 @@ void Pub(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||||
const_cast<const char*>(reinterpret_cast<char*>(contents.Data()));
|
const_cast<const char*>(reinterpret_cast<char*>(contents.Data()));
|
||||||
deno_buf buf{data, contents.ByteLength()};
|
deno_buf buf{data, contents.ByteLength()};
|
||||||
|
|
||||||
auto retbuf = d->cb(d, channel, buf);
|
assert(d->currentArgs == nullptr);
|
||||||
if (retbuf.data) {
|
d->currentArgs = &args;
|
||||||
// TODO(ry) Support zero-copy.
|
|
||||||
auto ab = v8::ArrayBuffer::New(d->isolate, retbuf.len);
|
d->cb(d, channel, buf);
|
||||||
memcpy(ab->GetContents().Data(), retbuf.data, retbuf.len);
|
|
||||||
args.GetReturnValue().Set(handle_scope.Escape(ab));
|
d->currentArgs = nullptr;
|
||||||
} else {
|
|
||||||
args.GetReturnValue().Set(v8::Null(d->isolate));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Execute(v8::Local<v8::Context> context, const char* js_filename,
|
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;
|
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) {
|
void deno_delete(Deno* d) {
|
||||||
d->isolate->Dispose();
|
d->isolate->Dispose();
|
||||||
delete d;
|
delete d;
|
||||||
|
|
|
@ -11,6 +11,7 @@ extern "C" {
|
||||||
// deno_s = Wrapped Isolate.
|
// deno_s = Wrapped Isolate.
|
||||||
struct deno_s {
|
struct deno_s {
|
||||||
v8::Isolate* isolate;
|
v8::Isolate* isolate;
|
||||||
|
const v8::FunctionCallbackInfo<v8::Value>* currentArgs;
|
||||||
std::string last_exception;
|
std::string last_exception;
|
||||||
v8::Persistent<v8::Function> sub;
|
v8::Persistent<v8::Function> sub;
|
||||||
v8::Persistent<v8::Context> context;
|
v8::Persistent<v8::Context> context;
|
||||||
|
|
|
@ -45,6 +45,7 @@ Deno* NewFromSnapshot(void* data, deno_sub_cb cb) {
|
||||||
v8::DeserializeInternalFieldsCallback(DeserializeInternalFields, nullptr);
|
v8::DeserializeInternalFieldsCallback(DeserializeInternalFields, nullptr);
|
||||||
|
|
||||||
Deno* d = new Deno;
|
Deno* d = new Deno;
|
||||||
|
d->currentArgs = nullptr;
|
||||||
d->cb = cb;
|
d->cb = cb;
|
||||||
d->data = data;
|
d->data = data;
|
||||||
v8::Isolate::CreateParams params;
|
v8::Isolate::CreateParams params;
|
||||||
|
|
|
@ -19,8 +19,7 @@ typedef struct deno_s Deno;
|
||||||
|
|
||||||
// A callback to receive a message from deno_pub javascript call.
|
// A callback to receive a message from deno_pub javascript call.
|
||||||
// buf is valid only for the lifetime of the call.
|
// buf is valid only for the lifetime of the call.
|
||||||
// The returned deno_buf is returned from deno_pub in javascript.
|
typedef void (*deno_sub_cb)(Deno* d, const char* channel, deno_buf buf);
|
||||||
typedef deno_buf (*deno_sub_cb)(Deno* d, const char* channel, deno_buf buf);
|
|
||||||
|
|
||||||
void deno_init();
|
void deno_init();
|
||||||
const char* deno_v8_version();
|
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.
|
// value indicates error. Check deno_last_exception() for exception text.
|
||||||
bool deno_pub(Deno* d, const char* channel, deno_buf buf);
|
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);
|
const char* deno_last_exception(Deno* d);
|
||||||
|
|
||||||
void deno_terminate_execution(Deno* d);
|
void deno_terminate_execution(Deno* d);
|
||||||
|
|
|
@ -4,11 +4,32 @@ import * as ts from "typescript";
|
||||||
|
|
||||||
const globalEval = eval;
|
const globalEval = eval;
|
||||||
const window = globalEval("this");
|
const window = globalEval("this");
|
||||||
|
|
||||||
window["denoMain"] = () => {
|
window["denoMain"] = () => {
|
||||||
denoPrint("Hello world");
|
|
||||||
const msg = pb.Msg.fromObject({});
|
|
||||||
denoPrint(`msg.command: ${msg.command}`);
|
|
||||||
denoPrint(`ts.version: ${ts.version}`);
|
denoPrint(`ts.version: ${ts.version}`);
|
||||||
denoPrint("Hello world from foo");
|
const res = denoPub("startDeno2", emptyArrayBuffer());
|
||||||
return "foo";
|
//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 <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "./msg.pb.h"
|
||||||
#include "include/deno.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) {
|
int main(int argc, char** argv) {
|
||||||
deno_init();
|
deno_init();
|
||||||
|
|
||||||
Deno* d = deno_new(NULL, NULL);
|
Deno* d = deno_new(NULL, MessagesFromJS);
|
||||||
bool r = deno_execute(d, "deno_main.js", "denoMain();");
|
bool r = deno_execute(d, "deno_main.js", "denoMain();");
|
||||||
if (!r) {
|
if (!r) {
|
||||||
printf("Error! %s\n", deno_last_exception(d));
|
printf("Error! %s\n", deno_last_exception(d));
|
||||||
|
|
|
@ -5,20 +5,20 @@
|
||||||
#include "include/deno.h"
|
#include "include/deno.h"
|
||||||
|
|
||||||
TEST(MockRuntimeTest, InitializesCorrectly) {
|
TEST(MockRuntimeTest, InitializesCorrectly) {
|
||||||
Deno* d = deno_new(NULL, NULL);
|
Deno* d = deno_new(nullptr, nullptr);
|
||||||
EXPECT_TRUE(deno_execute(d, "a.js", "1 + 2"));
|
EXPECT_TRUE(deno_execute(d, "a.js", "1 + 2"));
|
||||||
deno_delete(d);
|
deno_delete(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(MockRuntimeTest, CanCallFunction) {
|
TEST(MockRuntimeTest, CanCallFunction) {
|
||||||
Deno* d = deno_new(NULL, NULL);
|
Deno* d = deno_new(nullptr, nullptr);
|
||||||
EXPECT_TRUE(deno_execute(d, "a.js",
|
EXPECT_TRUE(deno_execute(d, "a.js",
|
||||||
"if (CanCallFunction() != 'foo') throw Error();"));
|
"if (CanCallFunction() != 'foo') throw Error();"));
|
||||||
deno_delete(d);
|
deno_delete(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(MockRuntimeTest, ErrorsCorrectly) {
|
TEST(MockRuntimeTest, ErrorsCorrectly) {
|
||||||
Deno* d = deno_new(NULL, NULL);
|
Deno* d = deno_new(nullptr, nullptr);
|
||||||
EXPECT_FALSE(deno_execute(d, "a.js", "throw Error()"));
|
EXPECT_FALSE(deno_execute(d, "a.js", "throw Error()"));
|
||||||
deno_delete(d);
|
deno_delete(d);
|
||||||
}
|
}
|
||||||
|
@ -26,14 +26,14 @@ TEST(MockRuntimeTest, ErrorsCorrectly) {
|
||||||
deno_buf strbuf(const char* str) { return deno_buf{str, strlen(str)}; }
|
deno_buf strbuf(const char* str) { return deno_buf{str, strlen(str)}; }
|
||||||
|
|
||||||
TEST(MockRuntimeTest, PubSuccess) {
|
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_execute(d, "a.js", "PubSuccess()"));
|
||||||
EXPECT_TRUE(deno_pub(d, "PubSuccess", strbuf("abc")));
|
EXPECT_TRUE(deno_pub(d, "PubSuccess", strbuf("abc")));
|
||||||
deno_delete(d);
|
deno_delete(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(MockRuntimeTest, PubByteLength) {
|
TEST(MockRuntimeTest, PubByteLength) {
|
||||||
Deno* d = deno_new(NULL, NULL);
|
Deno* d = deno_new(nullptr, nullptr);
|
||||||
EXPECT_TRUE(deno_execute(d, "a.js", "PubByteLength()"));
|
EXPECT_TRUE(deno_execute(d, "a.js", "PubByteLength()"));
|
||||||
// We pub the wrong sized message, it should throw.
|
// We pub the wrong sized message, it should throw.
|
||||||
EXPECT_FALSE(deno_pub(d, "PubByteLength", strbuf("abcd")));
|
EXPECT_FALSE(deno_pub(d, "PubByteLength", strbuf("abcd")));
|
||||||
|
@ -41,7 +41,7 @@ TEST(MockRuntimeTest, PubByteLength) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(MockRuntimeTest, PubNoCallback) {
|
TEST(MockRuntimeTest, PubNoCallback) {
|
||||||
Deno* d = deno_new(NULL, NULL);
|
Deno* d = deno_new(nullptr, nullptr);
|
||||||
// We didn't call deno_sub(), pubing should fail.
|
// We didn't call deno_sub(), pubing should fail.
|
||||||
EXPECT_FALSE(deno_pub(d, "PubNoCallback", strbuf("abc")));
|
EXPECT_FALSE(deno_pub(d, "PubNoCallback", strbuf("abc")));
|
||||||
deno_delete(d);
|
deno_delete(d);
|
||||||
|
@ -49,14 +49,13 @@ TEST(MockRuntimeTest, PubNoCallback) {
|
||||||
|
|
||||||
TEST(MockRuntimeTest, SubReturnEmpty) {
|
TEST(MockRuntimeTest, SubReturnEmpty) {
|
||||||
static int count = 0;
|
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++;
|
count++;
|
||||||
EXPECT_STREQ(channel, "SubReturnEmpty");
|
EXPECT_STREQ(channel, "SubReturnEmpty");
|
||||||
EXPECT_EQ(static_cast<size_t>(3), buf.len);
|
EXPECT_EQ(static_cast<size_t>(3), buf.len);
|
||||||
EXPECT_EQ(buf.data[0], 'a');
|
EXPECT_EQ(buf.data[0], 'a');
|
||||||
EXPECT_EQ(buf.data[1], 'b');
|
EXPECT_EQ(buf.data[1], 'b');
|
||||||
EXPECT_EQ(buf.data[2], 'c');
|
EXPECT_EQ(buf.data[2], 'c');
|
||||||
return deno_buf{nullptr, 0};
|
|
||||||
});
|
});
|
||||||
EXPECT_TRUE(deno_execute(d, "a.js", "SubReturnEmpty()"));
|
EXPECT_TRUE(deno_execute(d, "a.js", "SubReturnEmpty()"));
|
||||||
EXPECT_EQ(count, 2);
|
EXPECT_EQ(count, 2);
|
||||||
|
@ -65,14 +64,14 @@ TEST(MockRuntimeTest, SubReturnEmpty) {
|
||||||
|
|
||||||
TEST(MockRuntimeTest, SubReturnBar) {
|
TEST(MockRuntimeTest, SubReturnBar) {
|
||||||
static int count = 0;
|
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++;
|
count++;
|
||||||
EXPECT_STREQ(channel, "SubReturnBar");
|
EXPECT_STREQ(channel, "SubReturnBar");
|
||||||
EXPECT_EQ(static_cast<size_t>(3), buf.len);
|
EXPECT_EQ(static_cast<size_t>(3), buf.len);
|
||||||
EXPECT_EQ(buf.data[0], 'a');
|
EXPECT_EQ(buf.data[0], 'a');
|
||||||
EXPECT_EQ(buf.data[1], 'b');
|
EXPECT_EQ(buf.data[1], 'b');
|
||||||
EXPECT_EQ(buf.data[2], 'c');
|
EXPECT_EQ(buf.data[2], 'c');
|
||||||
return strbuf("bar");
|
deno_set_response(deno, strbuf("bar"));
|
||||||
});
|
});
|
||||||
EXPECT_TRUE(deno_execute(d, "a.js", "SubReturnBar()"));
|
EXPECT_TRUE(deno_execute(d, "a.js", "SubReturnBar()"));
|
||||||
EXPECT_EQ(count, 1);
|
EXPECT_EQ(count, 1);
|
||||||
|
@ -80,13 +79,13 @@ TEST(MockRuntimeTest, SubReturnBar) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(MockRuntimeTest, DoubleSubFails) {
|
TEST(MockRuntimeTest, DoubleSubFails) {
|
||||||
Deno* d = deno_new(NULL, NULL);
|
Deno* d = deno_new(nullptr, nullptr);
|
||||||
EXPECT_FALSE(deno_execute(d, "a.js", "DoubleSubFails()"));
|
EXPECT_FALSE(deno_execute(d, "a.js", "DoubleSubFails()"));
|
||||||
deno_delete(d);
|
deno_delete(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(MockRuntimeTest, TypedArraySnapshots) {
|
TEST(MockRuntimeTest, TypedArraySnapshots) {
|
||||||
Deno* d = deno_new(NULL, NULL);
|
Deno* d = deno_new(nullptr, nullptr);
|
||||||
EXPECT_TRUE(deno_execute(d, "a.js", "TypedArraySnapshots()"));
|
EXPECT_TRUE(deno_execute(d, "a.js", "TypedArraySnapshots()"));
|
||||||
deno_delete(d);
|
deno_delete(d);
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,8 +136,8 @@ int main(int argc, char** argv) {
|
||||||
auto snapshot_in_blob = ReadFile(snapshot_in_bin);
|
auto snapshot_in_blob = ReadFile(snapshot_in_bin);
|
||||||
|
|
||||||
deno_init();
|
deno_init();
|
||||||
auto snapshot_blob =
|
auto snapshot_blob = deno::MakeSnapshot(&natives_blob, &snapshot_in_blob,
|
||||||
deno::MakeSnapshot(&natives_blob, &snapshot_in_blob, js_fn, js_source.c_str());
|
js_fn, js_source.c_str());
|
||||||
|
|
||||||
StartupDataCppWriter nativesWriter("natives", natives_out_cc, natives_blob);
|
StartupDataCppWriter nativesWriter("natives", natives_out_cc, natives_blob);
|
||||||
nativesWriter.Write();
|
nativesWriter.Write();
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
cd `dirname "$0"`/..
|
cd `dirname "$0"`/..
|
||||||
set -e -v
|
set -e -v
|
||||||
cpplint --repository=. *.cc *.h include/*.h
|
cpplint --filter=-build/include_subdir --repository=. *.cc *.h include/*.h
|
||||||
|
|
Loading…
Add table
Reference in a new issue