001package com.killcoding.jsplus; 002 003import com.killcoding.jsplus.JsPlusContext; 004import java.io.File; 005import com.killcoding.tool.FileTools; 006import com.killcoding.log.LoggerFactory; 007import com.killcoding.log.Logger; 008import com.killcoding.tool.CommonTools; 009import java.util.Set; 010import java.util.Iterator; 011import com.killcoding.tool.ConfigProperties; 012import java.util.Map; 013 014import org.graalvm.polyglot.Context; 015import org.graalvm.polyglot.HostAccess; 016import org.graalvm.polyglot.PolyglotAccess; 017import org.graalvm.polyglot.Value; 018import org.graalvm.polyglot.Engine; 019import org.graalvm.options.OptionDescriptors; 020import com.killcoding.tool.CipherTools; 021import com.killcoding.file.DiskFile; 022import com.killcoding.file.BaseFile; 023 024public class GraalVmContext extends JsPlusContext { 025 026 private Engine engine = null; 027 private Context context = null; 028 private Value value = null; 029 030 public GraalVmContext(String engineName) { 031 super(engineName); 032 String[] parseJsParams = engineName.split("\\.",2); 033 String useEngineName = "js"; 034 if(parseJsParams.length >= 2) { 035 useEngineName = parseJsParams[1]; 036 } 037 this.engineName = useEngineName; 038 } 039 040 @Override 041 public String getEngineName(){ 042 return engineName; 043 } 044 045 @Override 046 public void initScriptEngineManager() throws Exception { 047 Engine.Builder builder = Engine.newBuilder(); 048 ConfigProperties appenvCp = ScriptConsole.getAppenv(); 049 if(appenvCp != null){ 050 String engineNameMapKey = String.format("GraalVM.%s",engineName); 051 Map appenvMap = appenvCp.getMap(engineNameMapKey,null); 052 if(appenvMap != null){ 053 System.out.println("GraalVM options: " + appenvMap); 054 builder.options(appenvMap); 055 } 056 } 057 engine = builder.build(); 058 Set<String> languages = engine.getLanguages().keySet(); 059 System.out.println("GraalVM supported Languages: " + languages); 060 061 Context.Builder contextBuiilder = Context.newBuilder(); 062 if(allowAllAccess){ 063 contextBuiilder 064 .allowAllAccess(true) 065 .allowHostAccess(HostAccess.ALL) 066 .allowCreateThread(true); 067 } 068 context = contextBuiilder.engine(engine).build(); 069 070 value = context.getBindings(engineName); 071 value.putMember("ScriptClassLoader", context.getClass().getClassLoader()); 072 } 073 074 @Override 075 public Object getBindings() { 076 return value; 077 } 078 079 @Override 080 public Engine getEngine() { 081 return engine; 082 } 083 084 @Override 085 public Context getContext() { 086 return context; 087 } 088 089 @Override 090 public void remove(String name) { 091 value.removeMember(name); 092 } 093 094 @Override 095 public Object get(String name) { 096 return value.getMember(name); 097 } 098 099 @Override 100 public void put(String name, Object obj) { 101 value.putMember(name, obj); 102 } 103 104 @Override 105 public Object eval(String scriptPath) throws Exception { 106 return eval(new File(scriptPath)); 107 } 108 109 @Override 110 public Object eval(File scriptPath) throws Exception { 111 String script = null; 112 if(CommonTools.isBlank(scriptCipherAesKey)){ 113 script = FileTools.text(scriptPath); 114 }else{ 115 DiskFile df = new DiskFile(scriptPath); 116 byte[] encryptBytes = df.readAllBytes(); 117 byte[] decryptBytes = CipherTools.AESDecrypt(scriptCipherAesKey,encryptBytes); 118 script = new String(decryptBytes,BaseFile.CHARSET); 119 } 120 return evalScript(script); 121 } 122 123 @Override 124 public Object evalScript(String script) throws Exception { 125 synchronized (context) { 126 try { 127 context.enter(); 128 return context.eval(engineName, script); 129 } finally { 130 context.leave(); 131 } 132 } 133 } 134 135 @Override 136 public void close() { 137 context.close(true); 138 } 139 140}