🐛 add dylib find rule on mac

This commit is contained in:
ValKmjolnir 2025-01-03 01:03:13 +08:00
parent 030a3ad920
commit 77ec4b0d7c
5 changed files with 90 additions and 61 deletions

View File

@ -6,22 +6,6 @@
namespace nasal { namespace nasal {
var nas_vec::get_value(const i32 index) {
i32 size = elems.size();
if (index<-size || index>=size) {
return var::none();
}
return elems[index>=0? index:index+size];
}
var* nas_vec::get_memory(const i32 index) {
i32 size = elems.size();
if (index<-size || index>=size) {
return nullptr;
}
return &elems[index>=0? index:index+size];
}
std::ostream& operator<<(std::ostream& out, nas_vec& vec) { std::ostream& operator<<(std::ostream& out, nas_vec& vec) {
if (!vec.elems.size() || vec.printed) { if (!vec.elems.size() || vec.printed) {
out << (vec.elems.size()? "[..]":"[]"); out << (vec.elems.size()? "[..]":"[]");
@ -40,7 +24,8 @@ std::ostream& operator<<(std::ostream& out, nas_vec& vec) {
var nas_hash::get_value(const std::string& key) { var nas_hash::get_value(const std::string& key) {
if (elems.count(key)) { if (elems.count(key)) {
return elems.at(key); return elems.at(key);
} else if (!elems.count("parents")) { }
if (!elems.count("parents")) {
return var::none(); return var::none();
} }
@ -63,7 +48,8 @@ var nas_hash::get_value(const std::string& key) {
var* nas_hash::get_memory(const std::string& key) { var* nas_hash::get_memory(const std::string& key) {
if (elems.count(key)) { if (elems.count(key)) {
return &elems.at(key); return &elems.at(key);
} else if (!elems.count("parents")) { }
if (!elems.count("parents")) {
return nullptr; return nullptr;
} }
@ -279,12 +265,6 @@ void nas_val::clear() {
} }
} }
f64 var::to_num() const {
return type != vm_type::vm_str
? val.num
: util::str_to_num(str().c_str());
}
std::string var::to_str() { std::string var::to_str() {
if (type==vm_type::vm_str) { if (type==vm_type::vm_str) {
return str(); return str();

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "nasal.h" #include "nasal.h"
#include "util/util.h"
#include <cstring> #include <cstring>
#include <sstream> #include <sstream>
@ -173,8 +174,13 @@ public:
bool is_map() const { return type == vm_type::vm_map; } bool is_map() const { return type == vm_type::vm_map; }
public: public:
// number and string can be translated to each other // convert to number
f64 to_num() const; f64 to_num() const {
return type != vm_type::vm_str
? val.num
: util::str_to_num(str().c_str());
}
// convert to string
std::string to_str(); std::string to_str();
inline bool object_check(const std::string&) const; inline bool object_check(const std::string&) const;
friend std::ostream& operator<<(std::ostream&, var&); friend std::ostream& operator<<(std::ostream&, var&);
@ -187,8 +193,20 @@ struct nas_vec {
bool printed = false; bool printed = false;
auto size() const { return elems.size(); } auto size() const { return elems.size(); }
var get_value(const i32); var get_value(const i32 index) {
var* get_memory(const i32); i32 size = elems.size();
if (index < -size || index >= size) {
return var::none();
}
return elems[index >= 0 ? index : index + size];
}
var* get_memory(const i32 index) {
i32 size = elems.size();
if (index < -size || index >= size) {
return nullptr;
}
return &elems[index >= 0 ? index : index + size];
}
friend std::ostream& operator<<(std::ostream&, nas_vec&); friend std::ostream& operator<<(std::ostream&, nas_vec&);
}; };

View File

@ -97,6 +97,7 @@ protected:
protected: protected:
/* vm calculation functions*/ /* vm calculation functions*/
inline bool boolify(const var&); inline bool boolify(const var&);
inline void set_frame(const nas_func&, var*);
protected: protected:
/* vm operands */ /* vm operands */
@ -342,6 +343,15 @@ inline bool vm::boolify(const var& val) {
return false; return false;
} }
inline void vm::set_frame(const nas_func& func, var* local) {
ctx.top[0] = ctx.upvalr;
(++ctx.top)[0] = var::addr(ctx.localr);
(++ctx.top)[0] = var::ret(ctx.pc); // rewrite top with vm_ret
ctx.pc = func.entry - 1;
ctx.localr = local;
ctx.upvalr = nil;
}
inline void vm::o_repl() { inline void vm::o_repl() {
// reserved for repl mode stack top value output // reserved for repl mode stack top value output
if (allow_repl_output) { if (allow_repl_output) {
@ -935,12 +945,7 @@ inline void vm::o_callfv() {
? parameter_size + 1 ? parameter_size + 1
: func.local_size - 1] = dynamic; : func.local_size - 1] = dynamic;
ctx.top[0] = ctx.upvalr; set_frame(func, local);
(++ctx.top)[0] = var::addr(ctx.localr);
(++ctx.top)[0] = var::ret(ctx.pc);
ctx.pc = func.entry-1;
ctx.localr = local;
ctx.upvalr = nil;
} }
inline void vm::o_callfh() { inline void vm::o_callfh() {
@ -987,12 +992,7 @@ inline void vm::o_callfh() {
return; return;
} }
ctx.top[0] = ctx.upvalr; set_frame(func, local);
(++ctx.top)[0] = var::addr(ctx.localr);
(++ctx.top)[0] = var::ret(ctx.pc); // rewrite top with vm_ret
ctx.pc=func.entry-1;
ctx.localr = local;
ctx.upvalr = nil;
} }
inline void vm::o_callb() { inline void vm::o_callb() {

View File

@ -18,35 +18,64 @@ void dynamic_library_destructor(void* pointer) {
#endif #endif
} }
std::vector<std::string> possible_dylib_path() {
const auto env_path = std::string(getenv("PATH"));
const auto sep = (util::is_windows()? ";":":");
const auto path_front = util::is_windows()? "\\module\\":"/module/";
// do split string
std::vector<std::string> env_path_vec = {"."};
usize last = 0;
usize pos = env_path.find(sep, 0);
while(pos != std::string::npos) {
if (pos > last) {
env_path_vec.push_back(env_path.substr(last, pos - last));
}
last = pos + 1;
pos = env_path.find(sep, last);
}
if (last != env_path.length()) {
env_path_vec.push_back(env_path.substr(last));
}
for (auto& p : env_path_vec) {
p += path_front;
}
return env_path_vec;
}
std::string search_dynamic_library_path(const std::string& dlname) { std::string search_dynamic_library_path(const std::string& dlname) {
const auto ext = (util::is_windows()? ".dll":".so"); const auto ext = (util::is_windows()? ".dll":".so");
const auto lib_path = (util::is_windows()? ".\\":"./") + dlname + ext; const auto lib_path = (util::is_windows()? ".\\":"./") + dlname + ext;
if (fs::exists(lib_path)) { if (fs::exists(lib_path)) {
return lib_path; return lib_path;
} }
const auto env_path = std::string(getenv("PATH")); // macos may use .dylib as extension
const auto sep = (util::is_windows()? ";":":"); if (util::is_macos()) {
const auto dylib_path = "./" + dlname + ".dylib";
// do split string if (fs::exists(dylib_path)) {
std::vector<std::string> env_path_vec = {"."}; return dylib_path;
usize last = 0;
usize pos = env_path.find(sep, 0);
while(pos!=std::string::npos) {
if (pos>last) {
env_path_vec.push_back(env_path.substr(last, pos-last));
} }
last = pos + 1;
pos = env_path.find(sep, last);
}
if (last!=env_path.length()) {
env_path_vec.push_back(env_path.substr(last));
} }
const auto path_front = util::is_windows()? "\\module\\":"/module/"; // search library in PATH
for(auto& p : env_path_vec) { const auto possible_path = possible_dylib_path();
p += path_front + lib_path; for(const auto& p : possible_path) {
if (fs::exists(p)) { const auto env_p = p + lib_path;
return p; if (fs::exists(env_p)) {
return env_p;
}
}
// macos may use .dylib as extension
if (util::is_macos()) {
const auto dylib_path = "./" + dlname + ".dylib";
for(const auto& p : possible_path) {
const auto env_p = p + dylib_path;
if (fs::exists(env_p)) {
return env_p;
}
} }
} }
return ""; return "";
@ -61,7 +90,7 @@ var builtin_dlopen(context* ctx, gc* ngc) {
const auto dlname = search_dynamic_library_path(dl.str()); const auto dlname = search_dynamic_library_path(dl.str());
if (dlname.empty()) { if (dlname.empty()) {
return nas_err("dylib::dlopen", return nas_err("dylib::dlopen",
"cannot find dynamic lib <" + dl.str() + ">" "cannot find dynamic library <" + dl.str() + ">"
); );
} }

View File

@ -13,11 +13,13 @@
#include <cstring> #include <cstring>
#include <sstream> #include <sstream>
#include <vector>
namespace nasal { namespace nasal {
void dynamic_library_destructor(void*); void dynamic_library_destructor(void*);
std::vector<std::string> possible_dylib_path();
std::string search_dynamic_library_path(const std::string&); std::string search_dynamic_library_path(const std::string&);
var builtin_dlopen(context*, gc*); var builtin_dlopen(context*, gc*);