fholm / ironjs Goto Github PK
View Code? Open in Web Editor NEWIronJS - A JavaScript implementation for .NET
Home Page: http://ironjs.wordpress.com
License: Apache License 2.0
IronJS - A JavaScript implementation for .NET
Home Page: http://ironjs.wordpress.com
License: Apache License 2.0
This affects the V8 Raytrace test.
Here is the minimum repro case:
var foo = function(a, b, c, d, e) {
print(a + ", " + b + ", " + c + ", " + d + ", " + e);
};
var callFoo = function () {
foo.apply(foo, arguments);
};
foo("1", "2", "3", "4", "5");
callFoo("A", "B", "C", "D", "E");
When compiling IronJS on Mono 2.10, the F# compiler reports the following error:
typecheck error FS0501: The member or object constructor 'TryParse' takes 2 argument(s) but is here given 4. The required signature is 'Numerics.BigInteger.TryParse(value: string, result: byref<Numerics.BigInteger>) : bool'.
at these locations:
\IronJS\Src\IronJS\Runtime.fs(2385,14,2385,66)
\IronJS\Src\IronJS\Compiler.Parser.fs(216,12,216,77)
\IronJS\Src\IronJS\Compiler.Parser.fs(235,12,235,77)
Looks like the mono implementation of BigInteger doesn't have the BigInteger.TryParse(string, NumberStyles, IFormatProvider, out BigInteger)
overload, although it does have BigInteger.TryParse(string, out BigInteger)
.
When executing UglifyJS with IronJS (which I do in Uglify.NET), I get the following exception:
IronJS.UserError: TypeError: 64
at IronJS.Hosting.FSharp.run(Delegate compiled, T t) in D:\AUL\Dev\Misc\IronJS\Src\IronJS\Hosting.fs:line 152
at IronJS.Hosting.CSharp.Context.Execute(String source) in D:\AUL\Dev\Misc\IronJS\Src\IronJS\Hosting.fs:line 240
at Uglify.Uglifier.Uglify(String code) in D:\AUL\Dev\Misc\Uglify.NET\src\app\Uglify\Uglifier.cs:line 28
at Uglify.Terminal.Terminal.Main() in D:\AUL\Dev\Misc\Uglify.NET\src\tests\Terminal\Terminal.cs:line 12
It occurs while executing the parse-js.js
file, which doesn't look that special to me, but I'm unaware of IronJS' limitations, so there might be some bits in there that aren't supported. Either way, I'd love to know why it doesn't work and how and where I might be able to contribute code to make it work.
Since pure function calls need an IObj for the 'this' parameter (which should be the global object) maybe the Global object should be a WithFrame containing a normal IObj object.
NuGet, the defacto standard package management app for .NET, is a great place to distribute IronJS.
In order to get IronJS onto NuGet's official package source, we need to package up the IronJS binaries according to the ".nuspec" format.
Specification Section 15.4
Hi, I just followed the instructions in README.markdown, then loaded CLR4.sln and got a compile error. The output window has this:
C:\Users\Dell\My Dropbox\Work\Sandbox\Third Party\IronJS\Src\IronJS\Native.Utils.fs(39,20): error FS0039: The value, constructor, namespace or type 'isSameTypeT' is not defined
The error window has this:
Error 1 Assembly reference 'C:\xxxxxxxxxxx\IronJS\Src\IronJS\bin\Debug\IronJS.dll' was not found or is invalid FSC 1 1 REPL
Specification Section 15.2
A Directive Prologue is the longest sequence of ExpressionStatement productions occurring as the initial
SourceElement productions of a Program or FunctionBody and where each ExpressionStatement in the sequence
consists entirely of a StringLiteral token followed a semicolon. The semicolon may appear explicitly or may be
inserted by automatic semicolon insertion. A Directive Prologue may be an empty sequence.
An immutable set of directive prologues should be available to the currently executing code. This will be used to support strict mode code.
Possible Implementations
We need breakpoint support in the DebugConsole utility application to debug some of the more complex issues. This will not be full visual studio integration but will lay the groundwork for VS integration later.
IronJS needs to be able to run on SL4
The syntax for consuming .NET namespaces and classes inside of JavaScript source code needs to be picked.
We support both early (compile) and late (runtime) bindings of .NET integration, we do so because early bound gives major performance benefits but also requires a syntax extension to the JavaScript language while late bound requires no extension and is more flexible as .NET types can be treated as JS objects but is also slower.
The current plan is to implement the late bound method first, because it requires no changes to the compiler.
Early bound extesions introduces a new compiler switch in the same way that ES5 introduced "use strict";
. This forces the users to make a concious descision about using early bound CLR integration since it introduces a new, contextual, keyword called clr
which is put infront of the new
keyword to allow the compiler to do an early bound call to the class constructor.
"use clr-early";
import System
import System.Collections.Generic
var lst = clr new List<String>()
var clr = true; // clr is contextual, just a keyword infront of "new"
Late bound makes use of the commonjs-esque require
function which creates a native JS object which wraps the import namespace and it's types as properties on this object.
var system = require("clr ..."); // whatever syntax we end up using there
var collections = require("clr ...");
var lst = new collections.List([system.String], [])
JS Code:
show(Add(123,4));
C# code:
static void Print(object value)
{
MessageBox.Show(value.ToString());
}
static double Add(double x, double y)
{
return x + y;
}
And..... I changed the source with this:
[Serializable]
public class TestClass : IronJS.Hosting.CSharp.Context
{
private static readonly Type UtilsType = typeof(IronJS.Native.Utils);
private static readonly System.Reflection.MethodInfo CreateFunctionMethod = UtilsType.GetMethod("CreateFunction", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
private delegate FunctionObject CreateFunctionHandler<T>(IronJS.Environment env, int? length, T @delegate);
public void SetFunction<T>(string name, T @delegate)
{
var d = Delegate.CreateDelegate(typeof(CreateFunctionHandler<T>), CreateFunctionMethod.MakeGenericMethod(typeof(T))) as CreateFunctionHandler<T>;
var f = d(this.Environment, null, @delegate) as FunctionObject;
this.SetGlobal(name, f);
}
}
.......
NOW.
var c = new TestClass();
context = c;
context.CreatePrintFunction();
context.Environment.BreakPoint = breakPoint;
c.SetFunction("Add", new Func<double, double, double>(Add));
c.SetFunction("show", new Action<object>(Print));
It's so easy.
If you compile the following CoffeeScript source:
id = (x) -> x
under IronJS, it compiles to this:
(function() {
var ;
id = function(x) {
return x;
};
}).call(this);
The var ; on the second line should be var id;.
(A CoffeeScript script which defines multiple functions should return in multiple identifiers e.g. var square, cube;.)
As per issue title.
Do you guys have any plans to include XML comments in the public methods? This would make it easier to figure out what some of the parameters are supposed to do. The "length" parameter of CreateFunction
has me a bit stumped. Length of what?
This is what I've tried so far and I get an exception:
class Program
{
static void Main(string[] args)
{
var ctx = new CSharp.Context();
ctx.SetGlobal("getRandom", Utils.CreateFunction<Func<int>>(ctx.Environment, 0, GetRandom));
System.Console.WriteLine(ctx.Execute("var x = getRandom();"));
}
static int GetRandom()
{
return new Random().Next(10, 20);
}
}
I listened to the Hanselminutes podcast about IronJS and you mentioned plans to streamline CLR object/function integration so that it doesn't require a whole lot of code to expose CLR code and JS code back and forth. How is that going?
When executing the file process.js
, I get an exception:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.NullReferenceException: Object reference not set to an instance of an object.
at lambda_method(Closure , FunctionObject , CommonObject )
--- End of inner exception stack trace ---
at IronJS.Hosting.FSharp.run(Delegate compiled, T t) in D:\AUL\Dev\Misc\IronJS\Src\IronJS\Hosting.fs:line 152
at IronJS.Hosting.CSharp.Context.Execute[a](String source) in D:\AUL\Dev\Misc\IronJS\Src\IronJS\Hosting.fs:line 244
at Uglify.Requirer.RequireAndAddToCache(String file) in D:\AUL\Dev\Misc\Uglify.NET\src\app\Uglify\Requirer.cs:line 92
at Uglify.Requirer.RequireInternal(String file) in D:\AUL\Dev\Misc\Uglify.NET\src\app\Uglify\Requirer.cs:line 106
at lambda_method(Closure , FunctionObject , CommonObject , String )
at lambda_method(Closure , FunctionObject , CommonObject )
--- End of inner exception stack trace ---
at IronJS.Hosting.FSharp.run(Delegate compiled, T t) in D:\AUL\Dev\Misc\IronJS\Src\IronJS\Hosting.fs:line 152
at IronJS.Hosting.CSharp.Context.Execute[a](String source) in D:\AUL\Dev\Misc\IronJS\Src\IronJS\Hosting.fs:line 244
at Uglify.Uglifier.Uglify(String code) in D:\AUL\Dev\Misc\Uglify.NET\src\app\Uglify\Uglifier.cs:line 40
at Uglify.Terminal.Terminal.Main() in D:\AUL\Dev\Misc\Uglify.NET\src\tests\Terminal\Terminal.cs:line 12
Since IronJS only fails with a NullReferenceException, I'm having difficulties figuring out what the problem with this file might be. Care to take a look at it?
IronJS needs to be verified to build on Mono and MonoDevelop
Take this for example:
"abc".substr(0, 2);
This should throw an error indicating that the String prototype does not contain a method called "substr", but rather throws an error with the message "TypeError: N", which is entirely unhelpful.
in Debug.Console paste the following snippet:
// aaaa\bb\cc\dd\utils.js
function a( ) {}
a()
the error is:
IronJS.Error+CompileError: Invalid hex digit 't'
On line 2, column 19 in <unknown>
1:
2: // aaaa\bb\cc\dd\utils.js
---------------------^
at IronJS.Error.CompileError.Raise[a](String msg, Tuple`2 pos, String source, String path) in IronJS\Src\IronJS\Error.fs:line 93
at IronJS.Compiler.Lexer.Input.error[a](T t, String msg) in IronJS\Src\IronJS\Compiler.Lexer.fs:line 437
at IronJS.Compiler.Lexer.readUnicodeEscape(T s) in IronJS\Src\IronJS\Compiler.Lexer.fs:line 526
at IronJS.Compiler.Lexer.singlelineComment(T s) in IronJS\Src\IronJS\Compiler.Lexer.fs:line 663
at IronJS.Compiler.Lexer.lexer@954(T s, Unit unitVar0) in IronJS\Src\IronJS\Compiler.Lexer.fs:line 985
at IronJS.Compiler.Parser.consume(State p) in IronJS\Src\IronJS\Compiler.Parser.fs:line 255
at [email protected](State p) in IronJS\Src\IronJS\Compiler.Parser.fs:line 462
at IronJS.Compiler.Parser.statementList(State p) in IronJS\Src\IronJS\Compiler.Parser.fs:line 381
at IronJS.Compiler.Parser.parse(String source, Environment env) in IronJS\Src\IronJS\Compiler.Parser.fs:line 1399
at IronJS.Hosting.FSharp.compile(String source, T t) in IronJS\Src\IronJS\Hosting.fs:line 152
at IronJS.Hosting.CSharp.Context.Execute(String source) in IronJS\Src\IronJS\Hosting.fs:line 224
at DebugConsole.MainWindow.<>c__DisplayClass27.<runSources>b__1f() in IronJS\Src\Tools\DebugConsole\MainWindow.xaml.cs:line 385
This case fails:
true ? foo="a" : foo="b"; print(foo);
This case passes:
true ? (foo="a") : (foo="b"); print(foo);
Several of the files referenced in the mono build script are not currently in the repository. Src/IronJS/Core.fs for example.
The last line in the code block is the failure point. In the Jasmine library itself it is lines 62-65 that are failing. Please let me know if you need anymore information.
StackTrace:
Exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> IronJS.UserError: Error:
at Microsoft.FSharp.Core.Operators.Raise[T](Exception exn)
at IronJS.Environment.RaiseError[g](CommonObject prototype, String message) in C:\cygwin\home\scitess\code\IronJS\Src\IronJS\Core.fs:line 419
at IronJS.Environment.RaiseTypeError[c](String message) in C:\cygwin\home\scitess\code\IronJS\Src\IronJS\Core.fs:line 431
at IronJS.Environment.RaiseTypeErrorc in C:\cygwin\home\scitess\code\IronJS\Src\IronJS\Core.fs:line 430
at IronJS.TypeConverter.ToObject(Environment env, BoxedValue v) in C:\cygwin\home\scitess\code\IronJS\Src\IronJS\Core.fs:line 2040
at lambda_method(Closure , FunctionObject , CommonObject , BoxedValue , String )
at IronJS.FunctionObject.Call[a,b](CommonObject this, a a, b b) in C:\cygwin\home\scitess\code\IronJS\Src\IronJS\Core.fs:line 1604
at lambda_method(Closure , FunctionObject , CommonObject )
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle._InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeType typeOwner)
Code:
var jasmine = {};
jasmine.getGlobal = function() {
function getGlobal() {
return this;
}
return getGlobal();
};
jasmine.bindOriginal_ = function(base, name) {
var original = base[name];
if (original.apply) {
return function() {
return original.apply(base, arguments);
};
} else {
return jasmine.getGlobal()[name];
}
};
jasmine.setTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'setTimeout');
No property attributes are set at all currently.
ReadOnly is checked
DontDelete and DontEnum are ignored
With IronPython, I can do this:
var script = @"
def inc(x):
return x+1
";
var pythonEngine = Python.CreateEngine();
var scope = pythonEngine.CreateScope();
pythonEngine.Execute(script, scope);
var inc = (Func<int, int>)scope.GetVariable("inc");
var three = inc(2);
I'm trying to do something similar with IronJS:
var script = @"
function inc(x) {
return x+1;
}
";
var context = new IronJS.Hosting.CSharp.Context();
context.Execute(script);
var inc = context.GetGlobalAs<Func<int, int>>("inc");
var three = inc(2);
However, I get the following exception:
System.InvalidCastException: Unable to cast object of type 'IronJS.FunctionObject' to type 'System.Func`2[System.Int32,System.Int32]'.
at Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicFunctions.UnboxGeneric[T](Object source)
at IronJS.Hosting.CSharp.Context.GetGlobalAs[a](String name)
Is there a better way to export script as an executable delegate? Or if not, is this something you think IronJS could/should support? I'd be glad to help, but am unsure exactly where to start...maybe TypeConverter.ConvertTo()
?
Relevant Sections of the Specification
Attributes of a Data Descriptor
Value - The value retrieved by reading the property.
Writable - If false, attempts by ECMAScript code to change the
property‘s [[Value]] attribute using [[Put]] will not succeed.
Enumerable - If true, the property will be enumerated by a for-in
enumeration (see 12.6.4). Otherwise, the property is said
to be non-enumerable.
Configurable - If false, attempts to delete the property, change the
property to be an accessor property, or change its
attributes (other than [[Value]]) will fail.
Attributes of an Accessor Descriptor
Get - If the value is an Object it must be a function Object. The
function‘s [[Call]] internal method (8.6.2) is called with an
empty arguments list to return the property value each time
a get access of the property is performed.
Set - If the value is an Object it must be a function Object. The
function‘s [[Call]] internal method (8.6.2) is called with an
arguments list containing the assigned value as its sole
argument each time a set access of the property is
performed. The effect of a property's [[Set]] internal method
may, but is not required to, have an effect on the value
returned by subsequent calls to the property's [[Get]]
internal method.
Enumerable - If true, the property is to be enumerated by a for-in
enumeration (see 12.6.4). Otherwise, the property is said to
be non-enumerable.
Configurable - If false, attempts to delete the property, change the
property to be a data property, or change its attributes will
fail.
The specific code for each node type should go in the Ast.Node.Walk() method instead of the EtGenerator.
Support for AnyCPU can be enabled by
module BoxedValueOffsets =
#if X64
let [] ValueType = 8
let [] Tag = 12
let [] Marker = 14
#else
#if X86
let [] ValueType = 4
let [] Tag = 8
let [] Marker = 10
#else
let [] ValueType = 8
let [] Tag = 12
let [] Marker = 14
#endif
#endif
When using Array.prototype.slice on a non-array object and slicing on values larger then Int32.MaxValue an invalid result is returned, example:
var obj = {};
obj.slice = Array.prototype.slice;
obj[4294967294] = "x";
obj.length = -1;
var arr = obj.slice(4294967294,4294967295);
Specification Section 15.8
Go through the code and put the right access modifiers on all methods, properties and fields. Also name all fields appropriately (_private, Public, etc.)
Specification Section 15.3
.NET doesn't allow break, continue and return inside a finally block which causes compilation to fail with the message "Control cannot leave a finally block" if any of the violating statements are put inside a finally block.
function a() {
return new not_defined_yet();
}
a();
While running the script above the valid error raises (ReferenceError: not_defined_yet is not defined). There are two problems:
The full source code is the following:
using System;
using IronJS;
namespace isronjs.test
{
public class test
{
public static string run()
{
try {
const string script = @"function a () {
return new not_defined_yet();
}
a();
";
var context = new IronJS.Hosting.CSharp.Context();
var result = context.Execute( script );
return TypeConverter.ToString(BoxingUtils.JsBox(result));
}
catch ( Exception e )
{
if ( e.InnerException != null && e.InnerException is UserError )
{
var user_error = e.InnerException as UserError;
Console.WriteLine( "USER ERROR (line:{0},column:{1}): {2}", user_error.Line, user_error.Column, e );
}
else
Console.WriteLine( "ERROR:{0}", e );
}
return null;
}
}
}
Right now the property name parameter in Obj is named key at some places and name at some other
Specification Section 15.5
I'm trying to execute the Coffee-Script compiler ( https://raw.github.com/jashkenas/coffee-script/master/extras/coffee-script.js ) to bring it into scope and then use it to compile coffee-script into javascript
var ctx = new IronJS.Hosting.CSharp.Context();
ctx.ExecuteFile("coffee-script.js");
However the ExecuteFile call maxes out a CPU and never seems to stop. I left it running for over a minute. Any ideas what's going wrong, is the execution engine getting stuck in a tight loop?
I'm using IronJS v0.2
9 conformance tests are currently failing because of a faulty splice implementation.
Delete operator at the moment returns object(null) when it should be boolean(true/false), this has to do with DeleteIndex and DeleteMember binders returning void.
Specification Section 15.7
Change all fields that are available outside the IronJS.dll to properties instead of fields.
See if it's possible to replace the IFrame interface/concept with the IObj interface to get more unified handling of values.
The fix lets the code run w/o errors, that said, the results aren't correct yet.
Compiling this CoffeeScript fragment foo -> 1
with IronJS gives:
var ;
foo(function() {
var ;
return 1;
});
but the correct result should look like
foo(function() {
return 1;
});
I used the following code to test
#light
#r @"C:\Users\Scott\Documents\d\GitHub\IronJS\Src\IronJS\bin\Release\IronJS.dll"
open System.Net
open IronJS
open IronJS.Hosting.FSharp
let cssrcUri = System.Uri "http://jashkenas.github.com/coffee-script/extras/coffee-script.js"
let cssrcPath = "C:\Users\Scott\Documents\d\GitHub\CoffeeScriptIronJS\FSCoffeeScriptIronJS\coffee-script.js"
let coffeescriptCompilerSrc =
if System.IO.File.Exists(cssrcPath) then
System.IO.File.ReadAllText(cssrcPath)
else
let wc = new WebClient()
wc.DownloadString cssrcUri
let ctx = IronJS.Hosting.FSharp.createContext()
let ret1 = ctx |> execute(coffeescriptCompilerSrc)
let ret2 = ctx |> execute("CoffeeScript.compile('foo -> 1', {bare: true});")
printf "%s", ret2
The inline property cache is causing issues with supporting .NET interop, and will probably cause issues down the line when we start supporting ES5's __defineGetter__
and __defineSetter__
.
At this point, I need to override Get and Put primarily for lazy-loading, but also to support Properties and fields that can change.
Hi,
first, thank you for this awesome code :)
I have found an annoying limitation. If the delegate at createHostFunction is casted to a Delegate it throws a NullReferenceException.
Utils.createHostFunction(env, (Delegate)new Action(this.test));
A quick fix from this:
ArgTypes = FSKit.Reflection.getDelegateArgTypesT<'a>
ReturnType = FSKit.Reflection.getDelegateReturnTypeT<'a>
to this:
ArgTypes = FSKit.Reflection.getDelegateArgTypes(delegate'.GetType())
ReturnType = FSKit.Reflection.getDelegateReturnType(delegate'.GetType())
doesn't help.
I am trying to bind dynamically methods of an object to js functions with Delegate.CreateDelegate like so:
List args = new List(method.GetParameters().Select(p => p.ParameterType));
Type delegateType;
if(method.ReturnType == typeof(void))
{
delegateType = Expression.GetActionType(args.ToArray());
}
else
{
args.Add(method.ReturnType);
delegateType = Expression.GetFuncType(args.ToArray());
}
var del = Delegate.CreateDelegate(delegateType, target, method);
Utils.createHostFunction(env, del);
This is blocking the V8 test regexp.js
.
Here is the minimum repro case:
var re89 = /\s+$/;
'Oyvpxchaxg\x0a'.replace(re89, '');
'Svanamra\x0a'.replace(re89, '');
It doesn't appear that the if not search.Global
and search.Put
stuff is correct for String.prototype.replace.
Native.String.fs lines 213-247
For regular expressions such as this:
((a+)?(b+)?c+)*
There are 3 capturing groups (one for each left-parenthesis).
If this is matched against a string like the following:
bbbccaac
The .NET implementation will list the following capture groups:
((a+)?(b+)?c) = "aac"
(a+) = "aa"
(b+) = "bbb"
Whereas the ECMAScript spec specifies the following capturing behavior:
((a+)?(b+)?c) = "aac"
(a+) = "aa"
(b+) = undefined
The .NET implementation gives no indication that the (b+)
capturing group did not participate in its most recent match attempt.
Specification Section 15.6
Specification Section 15.1
The strict mode restriction and exceptions
It might be too early for this to work, but I was playing w/ the idea of using CoffeeScript from IronJS.
So I have the following minimal snippet
open System.Net
open IronJS
open IronJS.Hosting.FSharp
let cssrcUri = System.Uri "https://github.com/jashkenas/coffee-script/raw/master/extras/coffee-script.js"
let wc = new WebClient()
let ctx = IronJS.Hosting.FSharp.createContext()
let ret1 = ctx |> execute(wc.DownloadString cssrcUri)
let ret2 = ctx |> execute("CoffeeScript.compile('foo -> 1', {bare: true});")
but I get the following error on the last line:
System.Reflection.TargetInvocationException was unhandled
Message: Exception has been thrown by the target of an invocation.
at IronJS.Hosting.FSharp.run(Delegate compiled, T t) in GitHub\IronJS\Src\IronJS\Hosting.fs:line 178
at IronJS.Hosting.FSharp.execute(String source, T t) in GitHub\IronJS\Src\IronJS\Hosting.fs:line 200
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.