diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d0faed9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Rodolfo Herrera Hernandez + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/Zenda b/Zenda index 8cce099..a802885 100755 Binary files a/Zenda and b/Zenda differ diff --git a/Zenda.cxx b/Zenda.cxx index 0dc132d..7177432 100644 --- a/Zenda.cxx +++ b/Zenda.cxx @@ -1,13 +1,11 @@ #include using namespace std; -#include "src/Engine.hxx" // Import Engine +#include "src/Engine.hxx" -int main(int argc, char* argv[]){ +int main(int argc, char *argv[]){ - ZendaJS ZendaJS; // Creating instance - - ZendaJS.Initialize(argc, argv); // Initialize Zenda + Initialize(argc, argv); return 0; } \ No newline at end of file diff --git a/examples/computer.js b/examples/computer.js index cca3c87..f4d26c4 100644 --- a/examples/computer.js +++ b/examples/computer.js @@ -5,9 +5,9 @@ console.log(OperativeSystem); // Using sleep for wait and execute instructions after wait console.log('Showing network interface in next 5 seconds...'); -sleep(5); +sleep(5000); -// Executin command by OS +// Executing command by OS if(OperativeSystem.startsWith('WIN')){ // Running command diff --git a/examples/fake_data_generator.js b/examples/fake_data_generator.js index 1f661a3..806a53b 100644 --- a/examples/fake_data_generator.js +++ b/examples/fake_data_generator.js @@ -41,7 +41,7 @@ class FakerGenerator{ } // Using PythonString - DataOutput = () => pythonString(` + DataOutput = () => pythonQuickString(` from faker import Faker from faker.providers import internet diff --git a/examples/import/library.js b/examples/import/library.js index 7ee606b..ff6e63f 100644 --- a/examples/import/library.js +++ b/examples/import/library.js @@ -1,5 +1,5 @@ export const SayHelloWithPython = () => { - pythonString("print('Hello world')"); + pythonQuickString("print('Hello world')"); } export const MyVar = "Hello"; diff --git a/examples/misc.js b/examples/misc.js index 72ccfd5..b207a44 100644 --- a/examples/misc.js +++ b/examples/misc.js @@ -5,7 +5,4 @@ sleep(1000); // 1 second / 500 = 500 ms creator(); // Version -> Get Zenda version -version(); - -// Getcwd -> Get current working directory -console.log(getcwd()) \ No newline at end of file +version(); \ No newline at end of file diff --git a/examples/python_integration.js b/examples/python_integration.js index a73d20d..3e6bb0f 100644 --- a/examples/python_integration.js +++ b/examples/python_integration.js @@ -14,9 +14,12 @@ Your message is {MESSAGE} and it contains {len(MESSAGE)} characteres! `; // Calling the pythonString function for execute code -pythonString(code); +pythonQuickString(code); // Calling Python File -pythonFile('examples/PyIntegrationExample.py') +pythonQuickFile('examples/PyIntegrationExample.py') -// You need enter exact python file location :) \ No newline at end of file +// You need enter exact python file location :) + +// Use pythonFancyFile for get better perfomance, u need python in your OS. +pythonFancyFile('examples/PyIntegrationExample.py') \ No newline at end of file diff --git a/src/Engine.hxx b/src/Engine.hxx index 3ebde4f..1544198 100644 --- a/src/Engine.hxx +++ b/src/Engine.hxx @@ -1,14 +1,7 @@ #include -#include "Utility.hxx" -using namespace std; #include #include -using namespace v8; - -#include -#include -#include #ifdef __WIN32 #include @@ -19,104 +12,22 @@ using namespace v8; #define PY_SSIZE_T_CLEAN #include -#include - -namespace Modules{ - - MaybeLocal CallResolve(Local MContext, Local Specifier, Local Referrer); - - MaybeLocal Load(char Code[], char Name[], Local MContext){ - Local VMCode = String::NewFromUtf8(MContext->GetIsolate(), Code).ToLocalChecked(); - - ScriptOrigin Origin( - String::NewFromUtf8(MContext->GetIsolate(), Name).ToLocalChecked(), - - Integer::New(MContext->GetIsolate(), 0), - - Integer::New(MContext->GetIsolate(), 0), - - False(MContext->GetIsolate()), - - Local(), - - Local(), - - False(MContext->GetIsolate()), - - False(MContext->GetIsolate()), - - True(MContext->GetIsolate()) - ); - - Context::Scope ContextScope(MContext); - - ScriptCompiler::Source LSource(VMCode, Origin); - - MaybeLocal LModule; - - LModule = ScriptCompiler::CompileModule(MContext->GetIsolate(), &LSource); - - return LModule; - } - - Local Check(MaybeLocal MaybeModule, Local MContext){ - Local LModule; - - if(!MaybeModule.ToLocal(&LModule)){ - cout << "Error loading module" << endl; - - exit(EXIT_FAILURE); - } - - Maybe Result = LModule->InstantiateModule(MContext, CallResolve); - - if(Result.IsNothing()){ - cout << "Can't instantiate module." << endl; - - exit(EXIT_FAILURE); - } - - return LModule; - } - - Local Execute(Local LModule, Local MContext, bool NsObject = false){ - Local ReturnValue; - - if(!LModule->Evaluate(MContext).ToLocal(&ReturnValue)){ - cout << "Error evaluating module." << endl; - - exit(EXIT_FAILURE); - } - - if(NsObject) - return LModule->GetModuleNamespace(); - else - return ReturnValue; - } - - MaybeLocal CallResolve(Local MContext, Local Specifier, Local Referrer){ - String::Utf8Value Str(MContext->GetIsolate(), Specifier); - - return Load(ReadFile(*Str), *Str, MContext); - } - - MaybeLocal CallDynamic(Local MContext, Local Referrer, Local Specifier){ - Local Resolver = Promise::Resolver::New(MContext).ToLocalChecked(); - - MaybeLocal LPromise(Resolver->GetPromise()); - - String::Utf8Value Name(MContext->GetIsolate(), Specifier); +#include - Local LModule = Check(Load(ReadFile(*Name), *Name, MContext), MContext); +using namespace std; +using namespace v8; - Local ReturnValue = Execute(LModule, MContext, true); +#include "utils/String.hxx" +#include "utils/Shared.hxx" - Maybe MResolve = Resolver->Resolve(MContext, ReturnValue); +#include "Module.hxx" +#include "Global.hxx" - return LPromise; - } +#include "methods/Misc.hxx" +#include "methods/Python.hxx" -} +#include "objects/Console.hxx" +#include "objects/System.hxx" class ObjectCreator{ private: @@ -127,9 +38,7 @@ class ObjectCreator{ public: ObjectCreator(Isolate * isolate, const char* objectname){ this->isolate = isolate; - this->ObjectInstance = ObjectTemplate::New(this->isolate); - this->name = String::NewFromUtf8( this->isolate, objectname, NewStringType::kNormal ).ToLocalChecked(); @@ -138,10 +47,8 @@ class ObjectCreator{ ObjectCreator SetPropertyMethod(const char* propertymethod, void (*callback)(const FunctionCallbackInfo& Arguments)){ this->ObjectInstance->Set( String::NewFromUtf8(this->isolate, propertymethod, NewStringType::kNormal).ToLocalChecked(), - FunctionTemplate::New(this->isolate, callback) ); - return *this; } @@ -149,7 +56,6 @@ class ObjectCreator{ Local Instance = this->ObjectInstance->NewInstance( this->isolate->GetCurrentContext() ).ToLocalChecked(); - this->isolate->GetCurrentContext()->Global()->Set( this->isolate->GetCurrentContext(), this->name, @@ -158,546 +64,230 @@ class ObjectCreator{ } }; -class ZendaJS{ - private: - unique_ptr platform; - - Isolate::CreateParams create_params; - - Isolate* isolate; - - Local global; - - vector ZendaJSCoreFiles; - - static void Version(const FunctionCallbackInfo& Arguments){ - HandleScope Scope(Arguments.GetIsolate()); - - PrintVersion(); - } - - static void Creator(const FunctionCallbackInfo& Arguments){ - HandleScope Scope(Arguments.GetIsolate()); - - PrintCreator(); - } - - static void PythonString(const FunctionCallbackInfo& Arguments){ - Py_Initialize(); - - for(unsigned short int i = 0; i < Arguments.Length(); i++){ - HandleScope Scope(Arguments.GetIsolate()); - - String::Utf8Value Code(Arguments.GetIsolate(), Arguments[i]); - - char const* CharCode = ToCString(Code); - - PyRun_SimpleString(CharCode); - } - - Py_Finalize(); - } - - static void PythonFile(const FunctionCallbackInfo& Arguments){ - Py_Initialize(); - - for(unsigned short int i = 0; i < Arguments.Length(); i++){ - HandleScope Scope(Arguments.GetIsolate()); - - String::Utf8Value File(Arguments.GetIsolate(), Arguments[i]); - - char const* CharFile = ToCString(File); - - FILE* PyFile; +ObjectCreator CreateObject(const char* ObjectName){ + ObjectCreator ObjectCreatorInstance(ZendaIsolate, ObjectName); + return ObjectCreatorInstance; +} - PyFile = fopen(CharFile, "r"); +// By declaring the function and +// then defining them and not having order +// errors due to the use of a functional programming paradigm. +void CreatheMethod(const char* MethodName, void(*Callback)(const FunctionCallbackInfo& Arguments)); +void AddCoreJavascriptFile(string Path); +void CreatePlatform(char* argv[]); +void Initialize(int argc, char* argv[]); +bool ExecuteString(Local Source, const char* Filename); +void Shell(Local SContext, Platform* SPlatform); +void ReportException(TryCatch* try_catch); +void CreateVirtualMachine(); +void CreateGlobalEnvironment(); +void ShutdownVirtualMachine(); +void LoadCoreJavascriptFiles(); +void EngineEnvironMethods(); +void EngineEnvironObjects(); +void EngineEnvironCoreJavascriptFiles(); +Local CreateLocalContext(); + +void CreateMethod(const char* MethodName, void(*Callback)(const FunctionCallbackInfo& Arguments)){ + ZendaGlobal->Set( + String::NewFromUtf8(ZendaIsolate, MethodName, NewStringType::kNormal).ToLocalChecked(), + FunctionTemplate::New(ZendaIsolate, Callback) + ); +} - if(PyFile == NULL) - cout << "ZendaJS -> An error ocurred while trying open <" << CharFile << "> in pythonFile() function." << endl; - else - PyRun_SimpleFile(PyFile, CharFile); +Local CreateLocalContext(){ + return Context::New(ZendaIsolate, NULL, ZendaGlobal); +} - fclose(PyFile); - } +void AddCoreJavascriptFile(string Path){ + ZendaJavascriptCoreFiles.push_back(Path); +} - Py_Finalize(); - } +void CreatePlatform(char* argv[]){ + V8::InitializeICUDefaultLocation(argv[0]); + V8::InitializeExternalStartupData(argv[0]); + ZendaPlatform = platform::NewDefaultPlatform(); + V8::InitializePlatform(ZendaPlatform.get()); + V8::Initialize(); +} - static void GetCurrentWorkingDirectory(const FunctionCallbackInfo& Arguments){ - HandleScope Scope(Arguments.GetIsolate()); +void CreateVirtualMachine(){ + ZendaCreateParams.array_buffer_allocator = ArrayBuffer::Allocator::NewDefaultAllocator(); + ZendaIsolate = Isolate::New(ZendaCreateParams); + ZendaIsolate->SetHostImportModuleDynamicallyCallback(CallDynamic); +} - string Directory = CurrentWorkingDirectory(); +void ShutdownVirtualMachine(){ + ZendaIsolate->Dispose(); + V8::Dispose(); + V8::ShutdownPlatform(); + delete ZendaCreateParams.array_buffer_allocator; +} - Arguments.GetReturnValue().Set( - String::NewFromUtf8( - Arguments.GetIsolate(), - Directory.c_str(), - NewStringType::kNormal, - static_cast(Directory.length()) - ).ToLocalChecked() - ); +bool ExecuteString(Local Source, const char* Filename){ + TryCatch try_catch(ZendaIsolate); + ScriptOrigin origin( + String::NewFromUtf8(ZendaIsolate, Filename, NewStringType::kNormal).ToLocalChecked() + ); + Local