optimization (#13) #15
164
Cargo.lock
generated
164
Cargo.lock
generated
@ -65,9 +65,9 @@ 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 = "byteorder"
|
||||
@ -77,9 +77,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[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"
|
||||
@ -161,16 +161,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"
|
||||
@ -239,23 +229,6 @@ 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"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.11.2"
|
||||
@ -276,12 +249,12 @@ 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 0.9.1",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -319,7 +292,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",
|
||||
@ -333,7 +306,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",
|
||||
@ -342,35 +315,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"
|
||||
@ -420,15 +371,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",
|
||||
@ -439,9 +390,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",
|
||||
]
|
||||
@ -457,9 +408,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"
|
||||
@ -478,7 +429,7 @@ dependencies = [
|
||||
"indoc 1.0.3",
|
||||
"inkwell",
|
||||
"itertools",
|
||||
"num-bigint 0.3.2",
|
||||
"num-bigint 0.3.3",
|
||||
"num-traits",
|
||||
"parking_lot",
|
||||
"rayon",
|
||||
@ -492,6 +443,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"inkwell",
|
||||
"nac3core",
|
||||
"parking_lot",
|
||||
"pyo3",
|
||||
"rustpython-parser",
|
||||
]
|
||||
@ -514,9 +466,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",
|
||||
@ -525,9 +477,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",
|
||||
@ -571,9 +523,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",
|
||||
@ -582,9 +534,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",
|
||||
@ -711,47 +663,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",
|
||||
]
|
||||
@ -832,9 +794,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",
|
||||
]
|
||||
@ -873,7 +835,7 @@ source = "git+https://github.com/m-labs/RustPython?branch=parser-mod#efdf7829ba1
|
||||
dependencies = [
|
||||
"fxhash",
|
||||
"lazy_static",
|
||||
"num-bigint 0.4.0",
|
||||
"num-bigint 0.4.2",
|
||||
"parking_lot",
|
||||
"string-interner",
|
||||
]
|
||||
@ -887,7 +849,7 @@ dependencies = [
|
||||
"lalrpop",
|
||||
"lalrpop-util",
|
||||
"log",
|
||||
"num-bigint 0.4.0",
|
||||
"num-bigint 0.4.2",
|
||||
"num-traits",
|
||||
"phf",
|
||||
"rustpython-ast",
|
||||
@ -934,9 +896,9 @@ checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913"
|
||||
|
||||
[[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"
|
||||
@ -951,7 +913,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ecc77d3a5728ef82235df1f9b9430507f555c7404797f42b49c2403d4c1d8c6c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"hashbrown 0.11.2",
|
||||
"hashbrown",
|
||||
"serde",
|
||||
]
|
||||
|
||||
@ -969,9 +931,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",
|
||||
|
@ -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/m-labs/RustPython", branch = "parser-mod" }
|
||||
inkwell = { git = "https://github.com/TheDan64/inkwell", branch = "master", features = ["llvm11-0"] }
|
||||
parking_lot = "0.11"
|
||||
nac3core = { path = "../nac3core" }
|
||||
|
@ -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__":
|
||||
|
@ -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
|
||||
|
@ -1,111 +1,175 @@
|
||||
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<i64, ast::Program>,
|
||||
host_objects: HashMap<i64, i64>,
|
||||
primitive: PrimitiveStore,
|
||||
internal_resolver: Arc<ResolverInternal>,
|
||||
resolver: Arc<Box<dyn SymbolResolver + Send + Sync>>,
|
||||
composer: TopLevelComposer,
|
||||
top_level: Option<Arc<TopLevelContext>>
|
||||
}
|
||||
|
||||
#[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> = 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<dyn SymbolResolver + Send + Sync>
|
||||
);
|
||||
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 = TargetTriple::create("riscv32-unknown-linux");
|
||||
let target =
|
||||
Target::from_triple(&triple).expect("couldn't create target from target triple");
|
||||
let target_machine = target
|
||||
.create_target_machine(
|
||||
&triple,
|
||||
"",
|
||||
"+a,+m",
|
||||
OptimizationLevel::Default,
|
||||
RelocMode::PIC,
|
||||
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");
|
||||
})));
|
||||
let threads: Vec<String> = (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]
|
||||
|
51
nac3embedded/src/symbol_resolver.rs
Normal file
51
nac3embedded/src/symbol_resolver.rs
Normal file
@ -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<HashMap<String, Type>>,
|
||||
pub id_to_def: Mutex<HashMap<String, DefinitionId>>,
|
||||
pub class_names: Mutex<HashMap<String, Type>>,
|
||||
}
|
||||
|
||||
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<ResolverInternal>);
|
||||
|
||||
impl SymbolResolver for Resolver {
|
||||
fn get_symbol_type(&self, _: &mut Unifier, _: &PrimitiveStore, str: &str) -> Option<Type> {
|
||||
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<SymbolValue> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn get_symbol_location(&self, _: &str) -> Option<Location> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn get_identifier_def(&self, id: &str) -> Option<DefinitionId> {
|
||||
self.0.id_to_def.lock().get(id).cloned()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user