-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Only accessible from Rust currently. fixes wip wip test_rs passes
- Loading branch information
Showing
13 changed files
with
639 additions
and
69 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import * as dispatch from "./dispatch"; | ||
import * as msg from "gen/msg_generated"; | ||
import * as flatbuffers from "./flatbuffers"; | ||
import { libdeno } from "./libdeno"; | ||
import { assert, log, setLogDebug } from "./util"; | ||
import { globalEval } from "./global_eval"; | ||
|
||
export async function postMessage(data: Uint8Array): Promise<void> { | ||
const builder = flatbuffers.createBuilder(); | ||
msg.WorkerPostMessage.startWorkerPostMessage(builder); | ||
const inner = msg.WorkerPostMessage.endWorkerPostMessage(builder); | ||
const baseRes = await dispatch.sendAsync( | ||
builder, | ||
msg.Any.WorkerPostMessage, | ||
inner, | ||
data | ||
); | ||
assert(baseRes != null); | ||
} | ||
|
||
export async function getMessage(): Promise<null | Uint8Array> { | ||
log("getMessage"); | ||
// Send CodeFetch message | ||
const builder = flatbuffers.createBuilder(); | ||
msg.WorkerGetMessage.startWorkerGetMessage(builder); | ||
const inner = msg.WorkerGetMessage.endWorkerGetMessage(builder); | ||
const baseRes = await dispatch.sendAsync( | ||
builder, | ||
msg.Any.WorkerGetMessage, | ||
inner | ||
); | ||
assert(baseRes != null); | ||
assert( | ||
msg.Any.WorkerGetMessageRes === baseRes!.innerType(), | ||
`base.innerType() unexpectedly is ${baseRes!.innerType()}` | ||
); | ||
const res = new msg.WorkerGetMessageRes(); | ||
assert(baseRes!.inner(res) != null); | ||
|
||
const dataArray = res.dataArray(); | ||
if (dataArray == null) { | ||
return null; | ||
} else { | ||
return new Uint8Array(dataArray!); | ||
} | ||
} | ||
|
||
let isClosing = false; | ||
|
||
export function workerClose(): void { | ||
isClosing = true; | ||
} | ||
|
||
export async function workerMain() { | ||
libdeno.recv(dispatch.handleAsyncMsgFromRust); | ||
setLogDebug(true); | ||
log("workerMain"); | ||
|
||
// TODO avoid using globalEval to get Window. But circular imports if getting | ||
// it from globals.ts | ||
const window = globalEval("this"); | ||
|
||
while (!isClosing) { | ||
const data = await getMessage(); | ||
if (data == null) { | ||
log("workerMain got null message. quitting."); | ||
break; | ||
} | ||
if (window["onmessage"]) { | ||
const event = { data }; | ||
window.onmessage(event); | ||
} else { | ||
break; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
#![allow(dead_code)] | ||
#![allow(unused_imports)] | ||
#![allow(unused_variables)] | ||
|
||
use isolate::Buf; | ||
use isolate::WorkerChannels; | ||
use msg; | ||
use resources; | ||
use resources::add_worker; | ||
use resources::Resource; | ||
use resources::ResourceId; | ||
use workers::spawn_worker; | ||
use workers::Worker; | ||
|
||
use futures::Future; | ||
use serde_json; | ||
use std::cell::Cell; | ||
use std::cell::RefCell; | ||
use std::sync::Arc; | ||
use std::sync::Mutex; | ||
|
||
lazy_static! { | ||
static ref c_rid: Mutex<Option<ResourceId>> = Mutex::new(None); | ||
} | ||
|
||
// This corresponds to JS ModuleMetaData. | ||
// TODO Rename one or the other so they correspond. | ||
#[derive(Debug)] | ||
pub struct CodeFetchOutput { | ||
pub module_name: String, | ||
pub filename: String, | ||
pub media_type: msg::MediaType, | ||
pub source_code: Vec<u8>, | ||
pub maybe_output_code: Option<Vec<u8>>, | ||
pub maybe_source_map: Option<Vec<u8>>, | ||
} | ||
|
||
impl CodeFetchOutput { | ||
// TODO Use serde_derive? Use flatbuffers? | ||
fn from_json(json_str: &str) -> Option<Self> { | ||
match serde_json::from_str::<serde_json::Value>(json_str) { | ||
Ok(serde_json::Value::Object(map)) => { | ||
let module_name = match map["moduleId"].as_str() { | ||
None => return None, | ||
Some(s) => s.to_string(), | ||
}; | ||
|
||
let filename = match map["fileName"].as_str() { | ||
None => return None, | ||
Some(s) => s.to_string(), | ||
}; | ||
|
||
let source_code = match map["sourceCode"].as_str() { | ||
None => return None, | ||
Some(s) => s.to_string(), | ||
}; | ||
|
||
let maybe_output_code = | ||
map["outputCode"].as_str().map(|s| s.as_bytes().to_vec()); | ||
|
||
let maybe_source_map = | ||
map["sourceMap"].as_str().map(|s| s.as_bytes().to_vec()); | ||
|
||
Some(CodeFetchOutput { | ||
module_name, | ||
filename, | ||
media_type: msg::MediaType::JavaScript, // TODO | ||
source_code: source_code.as_bytes().to_vec(), | ||
maybe_output_code, | ||
maybe_source_map, | ||
}) | ||
} | ||
_ => None, | ||
} | ||
} | ||
} | ||
|
||
fn lazy_start() -> Resource { | ||
let mut cell = c_rid.lock().unwrap(); | ||
let rid = cell.get_or_insert_with(|| { | ||
let (_t, c) = spawn_worker("compilerMain()".to_string()); | ||
let resource = add_worker(c); | ||
resource.rid | ||
}); | ||
Resource { rid: *rid } | ||
} | ||
|
||
fn stop() { | ||
/* | ||
if let Some(rid) = c_rid.lock().unwrap() { | ||
println!("kill compiler"); | ||
} | ||
*/ | ||
} | ||
|
||
fn req(specifier: &str, referrer: &str) -> Buf { | ||
String::from(format!( | ||
r#"{{"specifier": "{}", "referrer": "{}"}}"#, | ||
specifier, referrer | ||
)).into_boxed_str() | ||
.into_boxed_bytes() | ||
} | ||
|
||
fn compile_sync(specifier: &str, referrer: &str) -> Option<CodeFetchOutput> { | ||
let req_msg = req(specifier, referrer); | ||
|
||
let compiler = lazy_start(); | ||
|
||
let send_future = resources::worker_post_message(compiler.rid, req_msg); | ||
send_future.wait().unwrap(); | ||
|
||
let recv_future = resources::worker_recv_message(compiler.rid); | ||
let res_msg = recv_future.wait().unwrap().unwrap(); | ||
|
||
let res_json = std::str::from_utf8(&res_msg).unwrap(); | ||
CodeFetchOutput::from_json(res_json) | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
use futures::Sink; | ||
|
||
#[test] | ||
fn test_compile_sync() { | ||
let cwd = std::env::current_dir().unwrap(); | ||
let cwd_string = cwd.to_str().unwrap().to_owned(); | ||
|
||
let specifier = "./tests/002_hello.ts"; | ||
let referrer = cwd_string + "/"; | ||
|
||
let cfo = compile_sync(specifier, &referrer); | ||
println!("compile_sync {:?}", cfo); | ||
|
||
stop(); | ||
} | ||
|
||
#[test] | ||
fn code_fetch_output_from_json() { | ||
let json = r#"{ | ||
"moduleId":"/Users/rld/src/deno/tests/002_hello.ts", | ||
"fileName":"/Users/rld/src/deno/tests/002_hello.ts", | ||
"mediaType":1, | ||
"sourceCode":"console.log(\"Hello World\");\n", | ||
"outputCode":"yyy", | ||
"sourceMap":"xxx", | ||
"scriptVersion":"1" | ||
}"#; | ||
let actual = CodeFetchOutput::from_json(json).unwrap(); | ||
assert_eq!(actual.filename, "/Users/rld/src/deno/tests/002_hello.ts"); | ||
assert_eq!(actual.module_name, "/Users/rld/src/deno/tests/002_hello.ts"); | ||
assert_eq!( | ||
actual.source_code, | ||
"console.log(\"Hello World\");\n".as_bytes().to_vec() | ||
); | ||
assert_eq!(actual.maybe_output_code, Some("yyy".as_bytes().to_vec())); | ||
assert_eq!(actual.maybe_source_map, Some("xxx".as_bytes().to_vec())); | ||
} | ||
} |
Oops, something went wrong.