-
Notifications
You must be signed in to change notification settings - Fork 127
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Compilation to a dll #15
Comments
If you just want to compile some javascript once, and then run it multiple times, you can use the |
I am looking for something that persists across application restarts, so compiling to a dll would be preferred. Using the code you mentioned above I have managed to save a DLL. Am I right in saying I do have a problem using the generated DLL. What seems to be generated is a number of JavaScriptClass classes, which I assume correspond to each of the definitions in the source JavaScript. What would probably be most helpful is to return a ScriptEngine preloaded with the compiled JavaScript. Would this be possible? |
You can get a populated ScriptEngine by creating a new ScriptEngine and then running the generated class method that corresponds to the global code in your script ( |
Now I think about how else it could work, neither am I. I looked around in public static object global_(ScriptEngine scriptEngine, Scope scope, object obj) Obviously What I have at the moment gives an exception. I am trying to run a simple test where the following: var test = function() { return "test"; }; is compiled using the Doing this gives me the exception shown below Unhandled Exception: System.InvalidOperationException: Internal error: no generated method cache available. Any ideas? From what I can see from peaking in the code is that the In case its of any use, the decompiled IL looks like this: using Jurassic;
using Jurassic.Compiler;
using Jurassic.Library;
using System;
public class JavaScriptClass0
{
public JavaScriptClass0()
{
}
public static object global_(ScriptEngine scriptEngine, Scope scope, object obj)
{
object obj1 = null;
int num = 0;
((ObjectScope)scope).ScopeObject.DefineProperty("test", new PropertyDescriptor(Undefined.Value, PropertyAttributes.Writable | PropertyAttributes.Enumerable), false);
UserDefinedFunction userDefinedFunction = new UserDefinedFunction(scriptEngine.Function.InstancePrototype, "", new string[0], scope, " return \"test\"; ", GeneratedMethod.Load(0L), false);
userDefinedFunction.SetPropertyValue("displayName", "test", false);
object obj2 = userDefinedFunction;
ObjectInstance scopeObject = ((ObjectScope)scope).ScopeObject;
if (obj1 == scopeObject.InlineCacheKey)
{
scopeObject.InlinePropertyValues[num] = obj2;
}
else
{
scopeObject.InlineSetPropertyValue("test", obj2, false, out num, out obj1);
}
return Undefined.Value;
}
} |
Ugh, I told you this was hacky :-/ The The |
I've tried this and the same exception comes up. It seems to me that not all the information in the original |
It's likely the code is assuming that you can't run any compiled JS code without first compiling it. As a workaround, you could try compiling something prior to running the DLL code e.g. |
I am still getting the same exception. This maybe harder than we first thought. |
I had a play around and got a little further. It appears that the method cache private static void JurassicCompileTest()
{
var sw = new Stopwatch();
// Create an engine.
var compiler = new ScriptCompiler();
// Create a Javscript object using Javscript object initializer.
sw.Restart();
compiler.IncludeInput("var test = { 'foo' : 'bar', 'bar':'foo' };");
compiler.IncludeInput("var helloWorldAndTest = function() { return JSON.stringify(test); };");
Console.WriteLine(sw.ElapsedMilliseconds / 1000.0);
compiler.Save("Test.dll");
} I've had some success when I try to repopulate manually using the code below which uses the private static void CompiledJurassicTest()
{
var sw = new Stopwatch();
// Create an engine.
var compiler = new ScriptCompiler();
var engine = compiler.Load(
new Func<ScriptEngine, Scope, object, object>[] { JavaScriptClass0.global_, JavaScriptClass1.global_ },
new[] { new FunctionDelegate((a, b, c, d, e) => JavaScriptClass2.anonymous(a, b, c, d, e)) });
engine.SetGlobalFunction("log", new Action<string>(Console.WriteLine));
Console.WriteLine(engine.CallGlobalFunction("helloWorldAndTest"));
} Does this seem a reasonable thing to do? I am thinking of
|
Hi, I have managed to get something working by recreating the method cache. Compiling a DLL using |
Hi, from what I understand Jurassic creates IL code from the JavaScript code and then runs the IL. This creates some overhead in the first calls of functions. Of course, this is necessary if you want to run scripts at runtime from C#. However, I am interested in using some JavaScript libraries from C# and so the Javascript code would remain the same from one run to the next. So I was wondering, is there some way to save the generated IL as a dll to effectively remove the startup overhead? Cheers
The text was updated successfully, but these errors were encountered: