Simon Krajewski 8 年 前
コミット
f998a6f9f1

+ 2 - 0
extra/ImportAll.hx

@@ -53,6 +53,8 @@ class ImportAll {
 			if( !Context.defined("hl") ) return;
 		case "lua":
 			if( !Context.defined("lua") ) return;
+		case "eval":
+			if( !Context.defined("eval") ) return;
 		case "tools":
 			return;
 		case "build-tool":

+ 4 - 0
extra/all.hxml

@@ -54,6 +54,10 @@
 -hl all_hl
 -xml hl.xml
 
+--next
+--interp
+-xml interp.xml
+
 --next
 
 -xml cross.xml

+ 1 - 1
libs

@@ -1 +1 @@
-Subproject commit d30bbac6476dbafee41cb6265e7ab5b61c4ce5dc
+Subproject commit 5396ed3306f5a10be138d309d3f9dbf90b8ee07f

+ 3 - 0
src/compiler/globals.ml

@@ -19,6 +19,7 @@ type platform =
 	| Java
 	| Python
 	| Hl
+	| Eval
 
 let version = 4000
 let version_major = version / 1000
@@ -40,6 +41,7 @@ let platforms = [
 	Java;
 	Python;
 	Hl;
+	Eval;
 ]
 
 let platform_name = function
@@ -54,6 +56,7 @@ let platform_name = function
 	| Java -> "java"
 	| Python -> "python"
 	| Hl -> "hl"
+	| Eval -> "eval"
 
 let null_pos = { pfile = "?"; pmin = -1; pmax = -1 }
 

+ 6 - 1
src/compiler/main.ml

@@ -280,6 +280,9 @@ module Initialize = struct
 			| Hl ->
 				add_std "hl";
 				"hl"
+			| Eval ->
+				add_std "eval";
+				"eval"
 end
 
 let generate tctx ext xml_out interp swf_header =
@@ -296,7 +299,7 @@ let generate tctx ext xml_out interp swf_header =
 			| Some(_,ctx) -> print_endline "generate"; Codegen.Dump.dump_dependencies ~target_override:(Some "macro") ctx.Typecore.com
 	end;
 	begin match com.platform with
-		| Neko | Hl when interp -> ()
+		| Neko | Hl | Eval when interp -> ()
 		| Cpp when Common.defined com Define.Cppia -> ()
 		| Cpp | Cs | Java | Php -> Common.mkdir_from_path (com.file ^ "/.")
 		| _ -> Common.mkdir_from_path com.file
@@ -332,6 +335,8 @@ let generate tctx ext xml_out interp swf_header =
 			Genpy.generate,"python"
 		| Hl ->
 			Genhl.generate,"hl"
+		| Eval ->
+			(fun _ -> MacroContext.interpret tctx),"eval"
 		| Cross ->
 			assert false
 		in

+ 4 - 2
src/compiler/server.ml

@@ -108,8 +108,10 @@ let report_times print =
 		let l = (String.length node.name) + 2 * depth in
 		if l > !max_name then max_name := l;
 		List.iter (fun child ->
-			node.num_calls <- node.num_calls + child.num_calls;
-			node.time <- node.time +. child.time;
+			if depth = 0 then begin
+				node.num_calls <- node.num_calls + child.num_calls;
+				node.time <- node.time +. child.time;
+			end;
 			loop (depth + 1) child;
 		) node.children;
 		node.children <- List.sort (fun node1 node2 -> compare node2.time node1.time) node.children;

+ 7 - 0
src/context/common.ml

@@ -656,6 +656,7 @@ let short_platform_name = function
 	| Java -> "jav"
 	| Python -> "py"
 	| Hl -> "hl"
+	| Eval -> "evl"
 
 let stats =
 	{
@@ -764,6 +765,12 @@ let get_config com =
 			pf_pad_nulls = true;
 			pf_can_skip_non_nullable_argument = false;
 		}
+	| Eval ->
+		{
+			default_config with
+			pf_static = false;
+			pf_pad_nulls = true;
+		}
 
 let memory_marker = [|Unix.time()|]
 

+ 9 - 0
src/optimization/analyzer.ml

@@ -420,6 +420,15 @@ module ConstPropagation = DataFlow(struct
 					| EnumValue(_,el) -> (try List.nth el i with Failure _ -> raise Exit)
 					| _ -> raise Exit
 				end;
+			| TCall ({ eexpr = TField (_,FStatic({cl_path=[],"Type"} as c,({cf_name="enumIndex"} as cf)))},[e1]) when ctx.com.platform = Eval ->
+				begin match follow e1.etype,eval bb e1 with
+					| TEnum _,EnumValue(i,_) -> Const (TInt (Int32.of_int i))
+					| _,e1 ->
+						begin match Optimizer.api_inline2 ctx.com c cf.cf_name [wrap e1] e.epos with
+							| None -> raise Exit
+							| Some e -> eval bb e
+						end
+				end
 			| TCall ({ eexpr = TField (_,FStatic(c,cf))},el) ->
 				let el = List.map (eval bb) el in
 				let el = List.map wrap el in

+ 6 - 0
src/optimization/analyzerTexpr.ml

@@ -530,6 +530,12 @@ module Fusion = struct
 			false
 
 	let use_assign_op com op e1 e2 =
+		let skip e = match com.platform with
+			| Eval -> Texpr.skip e
+			| _ -> e
+		in
+		let e1 = skip e1 in
+		let e2 = skip e2 in
 		is_assign_op op && target_handles_assign_ops com && Texpr.equal e1 e2 && not (has_side_effect e1) && match com.platform with
 			| Cs when is_null e1.etype || is_null e2.etype -> false (* C# hates OpAssignOp on Null<T> *)
 			| _ -> true

+ 3 - 1
std/Math.hx

@@ -235,7 +235,7 @@ extern class Math
 	**/
 	static function random() : Float;
 
-	#if ((flash && !as3) || cpp)
+	#if ((flash && !as3) || cpp || eval)
 	/**
 		Returns the largest integer value that is not greater than `v`, as a `Float`.
 
@@ -296,6 +296,7 @@ extern class Math
 	**/
 	static function isNaN( f : Float ) : Bool;
 
+	#if !eval
 	private static function __init__() : Void untyped {
 	#if flash
 		NaN = __global__["Number"].NaN;
@@ -324,5 +325,6 @@ extern class Math
 			#end
 		};
 	}
+	#end
 
 }

+ 1 - 1
std/Std.hx

@@ -19,7 +19,7 @@
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
-#if !(core_api || cross)
+#if !(core_api || cross || eval)
 #error "Please don't add haxe/std to your classpath, instead set HAXE_STD_PATH env var"
 #end
 

+ 4 - 4
std/StringTools.hx

@@ -34,7 +34,7 @@ class StringTools {
 	/**
 		Encode an URL by using the standard format.
 	**/
-	#if (!java && !cpp && !lua) inline #end public static function urlEncode( s : String ) : String {
+	#if (!java && !cpp && !lua && !eval) inline #end public static function urlEncode( s : String ) : String {
 		#if flash
 			return untyped __global__["encodeURIComponent"](s);
 		#elseif neko
@@ -104,7 +104,7 @@ class StringTools {
 	/**
 		Decode an URL using the standard format.
 	**/
-	#if (!java && !cpp && !lua) inline #end public static function urlDecode( s : String ) : String {
+	#if (!java && !cpp && !lua && !eval) inline #end public static function urlDecode( s : String ) : String {
 		#if flash
 			return untyped __global__["decodeURIComponent"](s.split("+").join(" "));
 		#elseif neko
@@ -439,7 +439,7 @@ class StringTools {
 		This operation is not guaranteed to work if `s` contains the `\0`
 		character.
 	**/
-	public static inline function fastCodeAt( s : String, index : Int ) : Int {
+	public static #if !eval inline #end function fastCodeAt( s : String, index : Int ) : Int {
 		#if neko
 		return untyped __dollar__sget(s.__s, index);
 		#elseif cpp
@@ -471,7 +471,7 @@ class StringTools {
 		return c == 0;
 		#elseif js
 		return c != c; // fast NaN
-		#elseif (neko || lua)
+		#elseif (neko || lua || eval)
 		return c == null;
 		#elseif cs
 		return c == -1;

+ 9 - 0
std/haxe/CallStack.hx

@@ -71,6 +71,11 @@ class CallStack {
 	public static var wrapCallSite:Dynamic->Dynamic;
 	#end
 
+	#if eval
+	static function getCallStack() { return []; }
+	static function getExceptionStack() { return []; }
+	#end
+
 	/**
 		Return the call stack elements, or an empty array if not available.
 	**/
@@ -145,6 +150,8 @@ class CallStack {
 				var st = _getExceptionStack();
 				return makeStack(st.length > 2 ? st.sub(2,st.length - 2) : st);
 			}
+		#elseif eval
+			return getCallStack();
 		#else
 			return []; // Unsupported
 		#end
@@ -220,6 +227,8 @@ class CallStack {
 			return stack;
 		#elseif js
 			return untyped __define_feature__("haxe.CallStack.exceptionStack", getStack(lastException));
+		#elseif eval
+			return getExceptionStack();
 		#else
 			return []; // Unsupported
 		#end

+ 2 - 2
std/haxe/Serializer.hx

@@ -262,7 +262,7 @@ class Serializer {
 				#if (flash || python || hl)
 				var v : Array<Dynamic> = v;
 				#end
-				var l = #if (neko || flash || php || cs || java || python || hl || lua) v.length #elseif cpp v.__length() #else __getField(v, "length") #end;
+				var l = #if (neko || flash || php || cs || java || python || hl || lua || eval) v.length #elseif cpp v.__length() #else __getField(v, "length") #end;
 				for( i in 0...l ) {
 					if( v[i] == null )
 						ucount++;
@@ -484,7 +484,7 @@ class Serializer {
 					#end
 				}
 			}
-			#elseif (java || cs || python || hl)
+			#elseif (java || cs || python || hl || eval)
 			if( useEnumIndex ) {
 				buf.add(":");
 				buf.add(Type.enumIndex(v));

+ 1 - 1
std/haxe/crypto/Md5.hx

@@ -145,7 +145,7 @@ class Md5 {
 
 		//preallocate size
 		var blksSize = nblk * 16;
-		#if (neko || cs || cpp || java || hl)
+		#if (neko || eval || cs || cpp || java || hl)
 		blks[blksSize - 1] = 0;
 		#end
 

+ 1 - 1
std/haxe/format/JsonParser.hx

@@ -158,7 +158,7 @@ class JsonParser {
 				case 'u'.code:
 					var uc = Std.parseInt("0x" + str.substr(pos, 4));
 					pos += 4;
-					#if (neko || php || cpp || lua)
+					#if (neko || php || cpp || lua || eval)
 					if( uc <= 0x7F )
 						buf.addChar(uc);
 					else if( uc <= 0x7FF ) {

+ 16 - 16
std/haxe/macro/Compiler.hx

@@ -47,13 +47,13 @@ class Compiler {
 		return macro $v{haxe.macro.Context.definedValue(key)};
 	}
 
-#if (neko || (macro && hl))
+#if (neko || (macro && hl) || (macro && eval))
 
 	static var ident = ~/^[A-Za-z_][A-Za-z0-9_]*$/;
 	static var path = ~/^[A-Za-z_][A-Za-z0-9_.]*$/;
 
 	public static function allowPackage( v : String ) {
-		#if neko
+		#if (neko || eval)
 		load("allow_package", 1)(v);
 		#end
 	}
@@ -62,12 +62,12 @@ class Compiler {
 		Set a conditional compiler flag.
 	**/
 	public static function define( flag : String, ?value : String ) {
-		#if neko
+		#if (neko || eval)
 		load("define", 2)(flag,value);
 		#end
 	}
 
-	#if !neko
+	#if (!neko && !eval)
 	private static function typePatch( cl : String, f : String, stat : Bool, t : String ) {
 	}
 	private static function metaPatch( meta : String, cl : String, f : String, stat : Bool ) {
@@ -83,7 +83,7 @@ class Compiler {
 	public static function removeField( className : String, field : String, ?isStatic : Bool ) {
 		if( !path.match(className) ) throw "Invalid "+className;
 		if( !ident.match(field) ) throw "Invalid " + field;
-		#if neko
+		#if (neko || eval)
 		load("type_patch", 4)(className, field, isStatic == true, null);
 		#else
 		typePatch(className, field, isStatic == true, null);
@@ -97,7 +97,7 @@ class Compiler {
 	public static function setFieldType( className : String, field : String, type : String, ?isStatic : Bool ) {
 		if( !path.match(className) ) throw "Invalid "+className;
 		if( !ident.match((field.charAt(0) == "$") ? field.substr(1) : field) ) throw "Invalid "+field;
-		#if neko
+		#if (neko || eval)
 		load("type_patch", 4)(className, field, isStatic == true, type);
 		#else
 		typePatch(className, field, isStatic == true, type);
@@ -111,7 +111,7 @@ class Compiler {
 	public static function addMetadata( meta : String, className : String, ?field : String, ?isStatic : Bool ) {
 		if( !path.match(className) ) throw "Invalid "+className;
 		if( field != null && !ident.match(field) ) throw "Invalid "+field;
-		#if neko
+		#if (neko || eval)
 		load("meta_patch", 4)(meta, className, field, isStatic == true);
 		#else
 		metaPatch(meta, className, field, isStatic == true);
@@ -119,13 +119,13 @@ class Compiler {
 	}
 
 	public static function addClassPath( path : String ) {
-		#if neko
+		#if (neko || eval)
 		load("add_class_path", 1)(path);
 		#end
 	}
 
 	public static function getOutput() : String {
-		#if neko
+		#if (neko || eval)
 		return load("get_output", 0)();
 		#else
 		return null;
@@ -133,13 +133,13 @@ class Compiler {
 	}
 
 	public static function setOutput( fileOrDir : String ) {
-		#if neko
+		#if (neko || eval)
 		load("set_output", 1)(fileOrDir);
 		#end
 	}
 
 	public static function getDisplayPos() : Null<{ file : String, pos : Int }> {
-		#if neko
+		#if (neko || eval)
 		return load("get_display_pos", 0)();
 		#else
 		return null;
@@ -150,7 +150,7 @@ class Compiler {
 		Adds a native library depending on the platform (e.g. `-swf-lib` for Flash).
 	**/
 	public static function addNativeLib( name : String ) {
-		#if neko
+		#if (neko || eval)
 		load("add_native_lib", 1)(name);
 		#end
 	}
@@ -159,7 +159,7 @@ class Compiler {
 		Adds an argument to be passed to the native compiler (e.g. `-javac-arg` for Java).
 	 **/
 	public static function addNativeArg( argument : String ) {
-		#if neko
+		#if (neko || eval)
 		load("add_native_arg", 1)(argument);
 		#end
 	}
@@ -384,7 +384,7 @@ class Compiler {
 		through `Context.getType`.
 	**/
 	public static function addGlobalMetadata(pathFilter:String, meta:String, ?recursive:Bool = true, ?toTypes:Bool = true, ?toFields:Bool = false) {
-		#if neko
+		#if (neko || eval)
 		load("add_global_metadata_impl", 5)(pathFilter, meta, recursive, toTypes, toFields);
 		#else
 		addGlobalMetadataImpl(pathFilter, meta, recursive, toTypes, toFields);
@@ -395,12 +395,12 @@ class Compiler {
 		Change the default JS output by using a custom generator callback
 	**/
 	public static function setCustomJSGenerator( callb : JSGenApi -> Void ) {
-		#if neko
+		#if (neko || eval)
 		load("set_custom_js_generator", 1)(callb);
 		#end
 	}
 
-	#if neko
+	#if (neko || eval)
 	static inline function load( f, nargs ) : Dynamic {
 		return @:privateAccess Context.load(f, nargs);
 	}

+ 4 - 2
std/haxe/macro/Context.hx

@@ -38,7 +38,7 @@ import haxe.macro.Type.TypedExpr;
 #if !neko @:noDoc #end
 class Context {
 
-#if neko
+#if (neko || eval)
 	/**
 		Displays a compilation error `msg` at the given `Position` `pos`
 		and aborts the current macro call.
@@ -607,8 +607,10 @@ class Context {
 	@:allow(haxe.macro.MacroStringTools)
 	@:allow(haxe.macro.TypedExprTools)
 	static function load( f, nargs ) : Dynamic {
-		#if macro
+		#if neko
 		return neko.Lib.load("macro", f, nargs);
+		#elseif eval
+		return eval.vm.Context.callMacroApi(f);
 		#else
 		return Reflect.makeVarArgs(function(_) return throw "Can't be called outside of macro");
 		#end

+ 2 - 2
std/haxe/macro/MacroStringTools.hx

@@ -40,7 +40,7 @@ class MacroStringTools {
 		elements.
 	**/
 	static public function formatString(s:String, pos:Position) {
-		#if neko
+		#if (neko || eval)
 		return Context.load("format_string", 2)(s, pos);
 		#end
 	}
@@ -56,7 +56,7 @@ class MacroStringTools {
 		This operation depends on the position of `e`.
 	**/
 	static public function isFormatExpr(e:ExprOf<String>) : Bool {
-		#if neko
+		#if (neko || eval)
 		return Context.load("is_fmt_string", 1)(e.pos);
 		#else
 		return isFmtString(e.pos);

+ 2 - 2
std/haxe/macro/TypeTools.hx

@@ -246,7 +246,7 @@ class TypeTools {
 			throw 'Incompatible arguments: ${typeParameters.length} type parameters and ${concreteTypes.length} concrete types';
 		else if (typeParameters.length == 0)
 			return t;
-		#if neko
+		#if (neko || eval)
 		return Context.load("apply_params", 3)(typeParameters, concreteTypes, t);
 		#else
 		return applyParams(typeParameters, concreteTypes, t);
@@ -343,7 +343,7 @@ class TypeTools {
 		Converts type `t` to a human-readable String representation.
 	**/
 	static public function toString( t : Type ) : String {
-		#if neko
+		#if (neko || eval)
 		return Context.load("s_type", 1)(t);
 		#else
 		return null;

+ 6 - 6
std/haxe/unit/TestRunner.hx

@@ -24,16 +24,16 @@ import Reflect;
 
 /**
 	This class runs unit test cases and prints the result.
-	
+
 	```haxe
 	var r = new haxe.unit.TestRunner();
 	r.add(new MyTestCase());
 	// add other TestCases here
-	
+
 	// finally, run the tests
 	r.run();
 	```
-	
+
 	@see <https://haxe.org/manual/std-unit-testing.html>
 **/
 class TestRunner {
@@ -50,7 +50,7 @@ class TestRunner {
 
 	/**
 		Prints the given object/value.
-		
+
 		 * Flash outputs the result in a new `TextField` on stage.
 		 * JavaScript outputs the result using `console.log`.
 		 * Other targets use native `print` to output the result.
@@ -96,7 +96,7 @@ class TestRunner {
 			untyped __java__("java.lang.System.out.print(str)");
 		#elseif python
 			python.Lib.print(v);
-		#elseif (hl || lua)
+		#elseif (hl || lua || eval)
 			Sys.print(Std.string(v));
 		#end
 	}
@@ -119,7 +119,7 @@ class TestRunner {
 
 	/**
 		Runs the unit tests and prints the results.
-		
+
 		@return `true` if the unit test succesfully executed the test cases.
 	**/
 	public function run() : Bool {

+ 1 - 1
std/haxe/xml/Parser.hx

@@ -378,7 +378,7 @@ class Parser
 							var c = s.fastCodeAt(1) == 'x'.code
 								? Std.parseInt("0" +s.substr(1, s.length - 1))
 								: Std.parseInt(s.substr(1, s.length - 1));
-							#if (neko || cpp || php || lua)
+							#if (neko || cpp || php || lua || eval)
 							if( c >= 128 ) {
 								// UTF8-encode it
 								if( c <= 0x7FF ) {

+ 3 - 1
tests/sys/src/ExitCode.hx

@@ -7,7 +7,9 @@ import haxe.io.*;
 */
 class ExitCode {
 	static public var bin:String =
-	#if neko
+	#if interp
+		"bin/interp/ExitCode";
+	#elseif neko
 		"bin/neko/ExitCode.n";
 	#elseif hl
 		"bin/hl/ExitCode.hl";

+ 1 - 1
tests/sys/src/FileNames.hx

@@ -18,7 +18,7 @@ class FileNames {
 		"[two words]",
 
 		// Chinese, Japanese
-		#if !(cs || python || php || neko || cpp || java || lua)
+		#if !(cs || python || php || neko || cpp || java || lua || eval)
 		"中文,にほんご",
 		#end
 

+ 3 - 1
tests/sys/src/TestArguments.hx

@@ -64,7 +64,9 @@ class TestArguments extends haxe.unit.TestCase {
 	});
 
 	static public var bin:String =
-	#if neko
+	#if interp
+		"TestArguments.hx";
+	#elseif neko
 		"bin/neko/TestArguments.n";
 	#elseif hl
 		"bin/hl/TestArguments.hl";

+ 1 - 1
tests/unit/src/unitstd/StringTools.unit.hx

@@ -133,7 +133,7 @@ StringTools.isEof(StringTools.fastCodeAt(str, 3)) == true;
 StringTools.isEof(StringTools.fastCodeAt("", 0)) == true;
 
 // isEOF
-#if (neko || lua)
+#if (neko || lua || eval)
 StringTools.isEof(null) == true;
 #elseif (cs || java || python)
 StringTools.isEof( -1) == true;

+ 1 - 1
tests/unit/src/unitstd/Type.unit.hx

@@ -104,7 +104,7 @@ var requiredFields = ["func", "v", "prop"];
 for (f in fields)
 	t(requiredFields.remove(f));
 requiredFields == [];
-#if !hl // no support for implements Dynamic yet
+#if (!hl && !eval) // no support for implements Dynamic yet
 var cdyn = new CDyn();
 cdyn.foo = "1";
 Reflect.setField(cdyn, "bar", 1);