From edd60e3f9a1181a5a745426440ff091a85ddc3b9 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Thu, 23 Sep 2021 19:30:03 +0800 Subject: [PATCH] nac3embedded: compile again --- Cargo.lock | 158 ++++++++------------ nac3embedded/Cargo.toml | 5 +- nac3embedded/demo.py | 5 +- nac3embedded/language.py | 30 ++-- nac3embedded/src/lib.rs | 224 ++++++++++++++++++---------- nac3embedded/src/symbol_resolver.rs | 51 +++++++ nac3standalone/Cargo.toml | 2 +- 7 files changed, 286 insertions(+), 189 deletions(-) create mode 100644 nac3embedded/src/symbol_resolver.rs diff --git a/Cargo.lock b/Cargo.lock index f0084e6c..3720e21b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,15 +65,15 @@ checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" [[package]] name = "bitflags" -version = "1.2.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "cc" -version = "1.0.68" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787" +checksum = "d26a6ce4b6a484fa3edb70f7efa6fc430fd2b87285fe8b84304fd0936faa0dc0" [[package]] name = "cfg-if" @@ -155,16 +155,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" -[[package]] -name = "ctor" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e98e2ad1a782e33928b96fc3948e7c355e5af34ba4de7670fe8bac2a3b2006d" -dependencies = [ - "quote", - "syn", -] - [[package]] name = "diff" version = "0.1.12" @@ -224,22 +214,11 @@ dependencies = [ "wasi", ] -[[package]] -name = "ghost" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a5bcf1bbeab73aa4cf2fde60a846858dc036163c7c33bec309f8d17de785479" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "hashbrown" -version = "0.9.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" [[package]] name = "hermit-abi" @@ -252,9 +231,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.6.2" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3" +checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" dependencies = [ "autocfg", "hashbrown", @@ -295,7 +274,7 @@ dependencies = [ [[package]] name = "inkwell" version = "0.1.0" -source = "git+https://github.com/TheDan64/inkwell?branch=master#aa4de1d78471a3d2f0fda1f56801177ddf80f3bf" +source = "git+https://github.com/TheDan64/inkwell?branch=master#d018ee22e4b5241dec2bc32ca67f3d4caaecee47" dependencies = [ "either", "inkwell_internals", @@ -309,7 +288,7 @@ dependencies = [ [[package]] name = "inkwell_internals" version = "0.3.0" -source = "git+https://github.com/TheDan64/inkwell?branch=master#aa4de1d78471a3d2f0fda1f56801177ddf80f3bf" +source = "git+https://github.com/TheDan64/inkwell?branch=master#d018ee22e4b5241dec2bc32ca67f3d4caaecee47" dependencies = [ "proc-macro2", "quote", @@ -318,35 +297,13 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec" +checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d" dependencies = [ "cfg-if", ] -[[package]] -name = "inventory" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f0f7efb804ec95e33db9ad49e4252f049e37e8b0a4652e3cd61f7999f2eff7f" -dependencies = [ - "ctor", - "ghost", - "inventory-impl", -] - -[[package]] -name = "inventory-impl" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75c094e94816723ab936484666968f5b58060492e880f3c8d00489a1e244fa51" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "itertools" version = "0.10.1" @@ -396,15 +353,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.97" +version = "0.2.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6" +checksum = "a2a5ac8f984bfcf3a823267e5fde638acc3325f6496633a5da6bb6eb2171e103" [[package]] name = "llvm-sys" -version = "110.0.1" +version = "110.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21ede189444b8c78907e5d36da5dabcf153170fcff9c1dba48afc4b33c7e19f0" +checksum = "3b7cc88ba864d592f52132ed3a19a97118fe16c92a63961f54b0ab7279c5407f" dependencies = [ "cc", "lazy_static", @@ -415,9 +372,9 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0382880606dff6d15c9476c416d18690b72742aa7b605bb6dd6ec9030fbf07eb" +checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" dependencies = [ "scopeguard", ] @@ -433,9 +390,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" [[package]] name = "memoffset" @@ -454,7 +411,7 @@ dependencies = [ "indoc 1.0.3", "inkwell", "itertools", - "num-bigint 0.3.2", + "num-bigint 0.3.3", "num-traits", "parking_lot", "rayon", @@ -468,6 +425,7 @@ version = "0.1.0" dependencies = [ "inkwell", "nac3core", + "parking_lot", "pyo3", "rustpython-parser", ] @@ -490,9 +448,9 @@ checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" [[package]] name = "num-bigint" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d0a3d5e207573f948a9e5376662aa743a2ea13f7c50a554d7af443a73fbfeba" +checksum = "5f6f7833f2cbf2360a6cfd58cd41a53aa7a90bd4c202f5b1c7dd2ed73c57b2c3" dependencies = [ "autocfg", "num-integer", @@ -501,9 +459,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e0d047c1062aa51e256408c560894e5251f08925980e53cf1aa5bd00eec6512" +checksum = "74e768dff5fb39a41b3bcd30bb25cf989706c90d028d1ad71971987aa309d535" dependencies = [ "autocfg", "num-integer", @@ -547,9 +505,9 @@ checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" [[package]] name = "parking_lot" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" dependencies = [ "instant", "lock_api", @@ -558,9 +516,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018" +checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" dependencies = [ "cfg-if", "instant", @@ -687,47 +645,57 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] name = "proc-macro2" -version = "1.0.27" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038" +checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d" dependencies = [ "unicode-xid", ] [[package]] name = "pyo3" -version = "0.12.4" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf6bbbe8f70d179260b3728e5d04eb012f4f0c7988e58c11433dd689cecaa72e" +checksum = "35100f9347670a566a67aa623369293703322bb9db77d99d7df7313b575ae0c8" dependencies = [ - "ctor", + "cfg-if", "indoc 0.3.6", - "inventory", "libc", "parking_lot", "paste", - "pyo3cls", + "pyo3-build-config", + "pyo3-macros", "unindent", ] [[package]] -name = "pyo3-derive-backend" -version = "0.12.4" +name = "pyo3-build-config" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10ecd0eb6ed7b3d9965b4f4370b5b9e99e3e5e8742000e1c452c018f8c2a322f" +checksum = "d12961738cacbd7f91b7c43bc25cfeeaa2698ad07a04b3be0aa88b950865738f" dependencies = [ - "proc-macro2", + "once_cell", +] + +[[package]] +name = "pyo3-macros" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0bc5215d704824dfddddc03f93cb572e1155c68b6761c37005e1c288808ea8" +dependencies = [ + "pyo3-macros-backend", "quote", "syn", ] [[package]] -name = "pyo3cls" -version = "0.12.4" +name = "pyo3-macros-backend" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d344fdaa6a834a06dd1720ff104ea12fe101dad2e8db89345af9db74c0bb11a0" +checksum = "71623fc593224afaab918aa3afcaf86ed2f43d34f6afde7f3922608f253240df" dependencies = [ - "pyo3-derive-backend", + "proc-macro2", + "pyo3-build-config", "quote", "syn", ] @@ -808,9 +776,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ab49abadf3f9e1c4bc499e8845e152ad87d2ad2d30371841171169e9d75feee" +checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" dependencies = [ "bitflags", ] @@ -847,7 +815,7 @@ name = "rustpython-ast" version = "0.1.0" source = "git+https://github.com/pca006132/RustPython?branch=main#c6248660e33a2db8c2d745097ac4bff13598d955" dependencies = [ - "num-bigint 0.4.0", + "num-bigint 0.4.2", ] [[package]] @@ -859,7 +827,7 @@ dependencies = [ "lalrpop", "lalrpop-util", "log", - "num-bigint 0.4.0", + "num-bigint 0.4.2", "num-traits", "phf", "rustpython-ast", @@ -900,9 +868,9 @@ dependencies = [ [[package]] name = "siphasher" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbce6d4507c7e4a3962091436e56e95290cb71fa302d0d270e32130b75fbff27" +checksum = "533494a8f9b724d33625ab53c6c4800f7cc445895924a8ef649222dcb76e938b" [[package]] name = "smallvec" @@ -924,9 +892,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.73" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f71489ff30030d2ae598524f61326b902466f72a0fb1a8564c001cc63425bcc7" +checksum = "c6f107db402c2c2055242dbf4d2af0e69197202e9faacbef9571bbe47f5a1b84" dependencies = [ "proc-macro2", "quote", diff --git a/nac3embedded/Cargo.toml b/nac3embedded/Cargo.toml index f3eeaa1c..51881d31 100644 --- a/nac3embedded/Cargo.toml +++ b/nac3embedded/Cargo.toml @@ -9,7 +9,8 @@ name = "nac3embedded" crate-type = ["cdylib"] [dependencies] -pyo3 = { version = "0.12.4", features = ["extension-module"] } -inkwell = { git = "https://github.com/TheDan64/inkwell", branch = "master", features = ["llvm11-0"] } +pyo3 = { version = "0.14", features = ["extension-module"] } rustpython-parser = { git = "https://github.com/pca006132/RustPython", branch = "main" } +inkwell = { git = "https://github.com/TheDan64/inkwell", branch = "master", features = ["llvm11-0"] } +parking_lot = "0.11" nac3core = { path = "../nac3core" } diff --git a/nac3embedded/demo.py b/nac3embedded/demo.py index 58f91d27..4160f325 100644 --- a/nac3embedded/demo.py +++ b/nac3embedded/demo.py @@ -1,10 +1,11 @@ from language import * +@kernel class Demo: @kernel - def run(self: bool) -> bool: - return False + def run(self): + pass if __name__ == "__main__": diff --git a/nac3embedded/language.py b/nac3embedded/language.py index 1fdee5bf..a9ed614d 100644 --- a/nac3embedded/language.py +++ b/nac3embedded/language.py @@ -1,19 +1,29 @@ +from inspect import isclass from functools import wraps import nac3embedded -__all__ = ["kernel", "portable"] +__all__ = ["kernel"] -def kernel(function): - @wraps(function) - def run_on_core(self, *args, **kwargs): - nac3 = nac3embedded.NAC3() - nac3.register_host_object(self) - nac3.compile_method(self, function.__name__) - return run_on_core +nac3 = nac3embedded.NAC3() +allow_class_registration = True -def portable(function): - return fn +def kernel(function_or_class): + global allow_class_registration + + if isclass(function_or_class): + assert allow_class_registration + nac3.register_class(function_or_class) + return function_or_class + else: + @wraps(function_or_class) + def run_on_core(self, *args, **kwargs): + global allow_class_registration + if allow_class_registration: + nac3.analyze() + allow_class_registration = False + nac3.compile_method(self.__class__.__name__, function_or_class.__name__) + return run_on_core diff --git a/nac3embedded/src/lib.rs b/nac3embedded/src/lib.rs index 270b9e8b..cc3efc33 100644 --- a/nac3embedded/src/lib.rs +++ b/nac3embedded/src/lib.rs @@ -1,111 +1,177 @@ use std::collections::HashMap; -use std::collections::hash_map::Entry; +use std::sync::Arc; +use std::path::Path; use pyo3::prelude::*; use pyo3::exceptions; -use rustpython_parser::{ast, parser}; -use inkwell::context::Context; -use inkwell::targets::*; +use rustpython_parser::parser; +use inkwell::{ + passes::{PassManager, PassManagerBuilder}, + targets::*, + OptimizationLevel, +}; -use nac3core::CodeGen; +use nac3core::typecheck::type_inferencer::PrimitiveStore; +use nac3core::{ + codegen::{CodeGenTask, WithCall, WorkerRegistry}, + symbol_resolver::SymbolResolver, + toplevel::{composer::TopLevelComposer, TopLevelContext, TopLevelDef}, + typecheck::typedef::{FunSignature, FuncArg}, +}; -fn runs_on_core(decorator_list: &[ast::Expression]) -> bool { - for decorator in decorator_list.iter() { - if let ast::ExpressionType::Identifier { name } = &decorator.node { - if name == "kernel" || name == "portable" { - return true - } - } - } - false -} +mod symbol_resolver; +use symbol_resolver::*; -#[pyclass(name=NAC3)] +// TODO: do we really want unsendable? +// TopLevelComposer causes a lot of problems for Send. +#[pyclass(unsendable,name="NAC3")] struct Nac3 { - type_definitions: HashMap, - host_objects: HashMap, + primitive: PrimitiveStore, + internal_resolver: Arc, + resolver: Arc>, + composer: TopLevelComposer, + top_level: Option> } #[pymethods] impl Nac3 { #[new] fn new() -> Self { + let primitive: PrimitiveStore = TopLevelComposer::make_primitives().0; + let (composer, builtins_def, builtins_ty) = TopLevelComposer::new(vec![ + ("output_int".into(), FunSignature { + args: vec![FuncArg { + name: "x".into(), + ty: primitive.int32, + default_value: None, + }], + ret: primitive.none, + vars: HashMap::new(), + }), + ]); + let internal_resolver: Arc = ResolverInternal { + id_to_type: builtins_ty.into(), + id_to_def: builtins_def.into(), + class_names: Default::default(), + }.into(); + let resolver = Arc::new( + Box::new(Resolver(internal_resolver.clone())) as Box + ); Nac3 { - type_definitions: HashMap::new(), - host_objects: HashMap::new(), + primitive: primitive, + internal_resolver: internal_resolver, + resolver: resolver, + composer: composer, + top_level: None } } - fn register_host_object(&mut self, obj: PyObject) -> PyResult<()> { + fn register_class(&mut self, obj: PyObject) -> PyResult<()> { Python::with_gil(|py| -> PyResult<()> { let obj: &PyAny = obj.extract(py)?; - let obj_type = obj.get_type(); - let builtins = PyModule::import(py, "builtins")?; - let type_id = builtins.call1("id", (obj_type, ))?.extract()?; + let source = PyModule::import(py, "inspect")?.getattr("getsource")?.call1((obj, ))?.extract()?; + let parser_result = parser::parse_program(source).map_err(|e| + exceptions::PySyntaxError::new_err(format!("failed to parse host object source: {}", e)))?; - let entry = self.type_definitions.entry(type_id); - if let Entry::Vacant(entry) = entry { - let source = PyModule::import(py, "inspect")?.call1("getsource", (obj_type, ))?; - let ast = parser::parse_program(source.extract()?).map_err(|e| - exceptions::PySyntaxError::new_err(format!("failed to parse host object source: {}", e)))?; - entry.insert(ast); - // TODO: examine AST and recursively register dependencies - }; + for stmt in parser_result.into_iter() { + let (name, def_id, ty) = self.composer.register_top_level( + stmt, + Some(self.resolver.clone()), + "__main__".into(), + ).unwrap(); - let obj_id = builtins.call1("id", (obj, ))?.extract()?; - match self.host_objects.entry(obj_id) { - Entry::Vacant(entry) => entry.insert(type_id), - Entry::Occupied(_) => return Err( - exceptions::PyValueError::new_err("host object registered twice")), - }; - // TODO: collect other information about host object, e.g. value of fields - - Ok(()) - }) - } - - fn compile_method(&self, obj: PyObject, name: String) -> PyResult<()> { - Python::with_gil(|py| -> PyResult<()> { - let obj: &PyAny = obj.extract(py)?; - let builtins = PyModule::import(py, "builtins")?; - let obj_id = builtins.call1("id", (obj, ))?.extract()?; - - let type_id = self.host_objects.get(&obj_id).ok_or_else(|| - exceptions::PyKeyError::new_err("type of host object not found"))?; - let ast = self.type_definitions.get(&type_id).ok_or_else(|| - exceptions::PyKeyError::new_err("type definition not found"))?; - - if let ast::StatementType::ClassDef { - name: _, - body, - bases: _, - keywords: _, - decorator_list: _ } = &ast.statements[0].node { - for statement in body.iter() { - if let ast::StatementType::FunctionDef { - is_async: _, - name: funcdef_name, - args: _, - body: _, - decorator_list, - returns: _ } = &statement.node { - if runs_on_core(decorator_list) && funcdef_name == &name { - let context = Context::create(); - let mut codegen = CodeGen::new(&context); - codegen.compile_toplevel(&body[0]).map_err(|e| - exceptions::PyRuntimeError::new_err(format!("compilation failed: {}", e)))?; - codegen.print_ir(); - } - } + self.internal_resolver.add_id_def(name.clone(), def_id); + if let Some(ty) = ty { + self.internal_resolver.add_id_type(name, ty); } - } else { - return Err(exceptions::PyValueError::new_err("expected ClassDef for type definition")); } Ok(()) }) } + + fn analyze(&mut self) -> PyResult<()> { + self.composer.start_analysis(true).unwrap(); + self.top_level = Some(Arc::new(self.composer.make_top_level_context())); + Ok(()) + } + + fn compile_method(&mut self, class_name: String, method_name: String) -> PyResult<()> { + let top_level = self.top_level.as_ref().unwrap(); + let instance = { + let defs = top_level.definitions.read(); + let class_def = defs[self.resolver.get_identifier_def(&class_name).unwrap().0].write(); + let mut method_def = if let TopLevelDef::Class { methods, .. } = &*class_def { + if let Some((_name, _unification_key, definition_id)) = methods.iter().find(|method| method.0 == method_name) { + defs[definition_id.0].write() + } else { + return Err(exceptions::PyValueError::new_err("method not found")); + } + } else { + return Err(exceptions::PyTypeError::new_err("parent object is not a class")); + }; + + // FIXME: what is this for? What happens if the kernel is called twice? + if let TopLevelDef::Function { + instance_to_stmt, + instance_to_symbol, + .. + } = &mut *method_def + { + instance_to_symbol.insert("".to_string(), method_name.clone()); + instance_to_stmt[""].clone() + } else { + unreachable!() + } + }; + let signature = FunSignature { + args: vec![], + ret: self.primitive.none, + vars: HashMap::new(), + }; + let task = CodeGenTask { + subst: Default::default(), + symbol_name: method_name, + body: instance.body, + signature, + resolver: self.resolver.clone(), + unifier: top_level.unifiers.read()[instance.unifier_id].clone(), + calls: instance.calls, + }; + let f = Arc::new(WithCall::new(Box::new(move |module| { + let builder = PassManagerBuilder::create(); + builder.set_optimization_level(OptimizationLevel::Aggressive); + let passes = PassManager::create(()); + builder.populate_module_pass_manager(&passes); + passes.run_on(module); + + let triple = TargetMachine::get_default_triple(); + let target = + Target::from_triple(&triple).expect("couldn't create target from target triple"); + let target_machine = target + .create_target_machine( + &triple, + "", + "", + OptimizationLevel::Default, + RelocMode::Default, + CodeModel::Default, + ) + .expect("couldn't create target machine"); + target_machine + .write_to_file(module, FileType::Object, Path::new(&format!("{}.o", module.get_name().to_str().unwrap()))) + .expect("couldn't write module to file"); + + // println!("IR:\n{}", module.print_to_string().to_str().unwrap()); + }))); + let threads: Vec = (0..4).map(|i| format!("module{}", i)).collect(); + let threads: Vec<_> = threads.iter().map(|s| s.as_str()).collect(); + let (registry, handles) = WorkerRegistry::create_workers(&threads, top_level.clone(), f); + registry.add_task(task); + registry.wait_tasks_complete(handles); + Ok(()) + } } #[pymodule] diff --git a/nac3embedded/src/symbol_resolver.rs b/nac3embedded/src/symbol_resolver.rs new file mode 100644 index 00000000..f8fe760e --- /dev/null +++ b/nac3embedded/src/symbol_resolver.rs @@ -0,0 +1,51 @@ +use nac3core::{ + location::Location, + symbol_resolver::{SymbolResolver, SymbolValue}, + toplevel::DefinitionId, + typecheck::{ + type_inferencer::PrimitiveStore, + typedef::{Type, Unifier}, + }, +}; +use parking_lot::Mutex; +use std::{collections::HashMap, sync::Arc}; + +pub struct ResolverInternal { + pub id_to_type: Mutex>, + pub id_to_def: Mutex>, + pub class_names: Mutex>, +} + +impl ResolverInternal { + pub fn add_id_def(&self, id: String, def: DefinitionId) { + self.id_to_def.lock().insert(id, def); + } + + pub fn add_id_type(&self, id: String, ty: Type) { + self.id_to_type.lock().insert(id, ty); + } +} + +pub struct Resolver(pub Arc); + +impl SymbolResolver for Resolver { + fn get_symbol_type(&self, _: &mut Unifier, _: &PrimitiveStore, str: &str) -> Option { + let ret = self.0.id_to_type.lock().get(str).cloned(); + if ret.is_none() { + // println!("unknown here resolver {}", str); + } + ret + } + + fn get_symbol_value(&self, _: &str) -> Option { + unimplemented!() + } + + fn get_symbol_location(&self, _: &str) -> Option { + unimplemented!() + } + + fn get_identifier_def(&self, id: &str) -> Option { + self.0.id_to_def.lock().get(id).cloned() + } +} diff --git a/nac3standalone/Cargo.toml b/nac3standalone/Cargo.toml index a22ba57e..fa816ed4 100644 --- a/nac3standalone/Cargo.toml +++ b/nac3standalone/Cargo.toml @@ -7,5 +7,5 @@ edition = "2018" [dependencies] inkwell = { git = "https://github.com/TheDan64/inkwell", branch = "master", features = ["llvm11-0"] } rustpython-parser = { git = "https://github.com/pca006132/RustPython", branch = "main" } -parking_lot = "0.11.1" +parking_lot = "0.11" nac3core = { path = "../nac3core" }