Explorar o código

Fixed #4490.
* Add `js.Lib.global`.
* Avoid the use of `eval`/`Function`, instead use `js.Lib.global` to get the top-level defined type/var.

Andy Li %!s(int64=10) %!d(string=hai) anos
pai
achega
c6597aff78

+ 17 - 1
genjs.ml

@@ -1300,7 +1300,17 @@ let generate com =
 		| _ -> ()
 	) include_files;
 
+	let var_global = (
+		"$global",
+		"typeof window != \"undefined\" ? window : typeof global != \"undefined\" ? global : typeof self != \"undefined\" ? self : this"
+	) in
+
 	let closureArgs = [] in
+	let closureArgs = if has_feature ctx "js.Lib.global" then
+		var_global :: closureArgs
+	else
+		closureArgs
+	in
 	let closureArgs = if (anyExposed && not (Common.defined com Define.ShallowExpose)) then
 		(
 			"$hx_exports",
@@ -1360,7 +1370,13 @@ let generate com =
 
 	(* If ctx.js_modern, console is defined in closureArgs. *)
 	if (not ctx.js_modern) && (not (Common.defined com Define.JsEs5)) then
-		spr ctx "var console = Function(\"return typeof console != 'undefined' ? console : {log:function(){}}\")();\n";
+		add_feature ctx "js.Lib.global"; (* console polyfill will check console from $global *)
+
+	if (not ctx.js_modern) && (has_feature ctx "js.Lib.global") then
+		print ctx "var %s = %s;\n" (fst var_global) (snd var_global);
+
+	if (not ctx.js_modern) && (not (Common.defined com Define.JsEs5)) then
+		spr ctx "var console = $global.console || {log:function(){}};\n";
 
 	(* TODO: fix $estr *)
 	let vars = [] in

+ 2 - 2
std/js/Boot.hx

@@ -243,8 +243,8 @@ class Boot {
 	}
 
 	// resolve native JS class in the global scope:
-	static function __resolveNativeClass(name:String) untyped {
-		return untyped Function('return typeof $name != "undefined" ? $name : null')();
+	static function __resolveNativeClass(name:String) {
+		return untyped js.Lib.global[name];
 	}
 
 }

+ 18 - 0
std/js/Lib.hx

@@ -82,4 +82,22 @@ class Lib {
 	@:extern static inline function get_nativeThis() : Dynamic {
 		return untyped __js__("this");
 	}
+
+
+	/**
+		An alias of the JS "global" object.
+
+		Concretely, it is set as the first defined value in the list of
+		`window`, `global`, `self`, and `this` in the top-level of the compiled output.
+	**/
+	#if (haxe_ver >= 3.3)
+		public
+	#else
+		// hide it since we should not add new feature in 3.2.1
+		@:allow(js) private
+	#end
+	static var global(get,never) : Dynamic;
+	@:extern static inline function get_global() : Dynamic {
+		return untyped __define_feature__("js.Lib.global", __js__("$global")); // $global is generated by the compiler
+	}
 }

+ 1 - 1
std/js/html/compat/ArrayBuffer.hx

@@ -53,7 +53,7 @@ class ArrayBuffer {
 	}
 
 	static function __init__() untyped {
-		var ArrayBuffer = Function("return typeof ArrayBuffer != 'undefined' ? ArrayBuffer : null")() || js.html.compat.ArrayBuffer;
+		var ArrayBuffer = js.Lib.global.ArrayBuffer || js.html.compat.ArrayBuffer;
 		if( ArrayBuffer.prototype.slice == null ) ArrayBuffer.prototype.slice = sliceImpl; // IE10
 	}
 }

+ 1 - 1
std/js/html/compat/DataView.hx

@@ -138,7 +138,7 @@ class DataView {
 	}
 
 	static function __init__() {
-		var DataView = untyped Function("return typeof DataView != 'undefined' ? DataView : null")() || js.html.compat.DataView;
+		var DataView = untyped js.Lib.global.DataView || js.html.compat.DataView;
 	}
 
 }

+ 1 - 1
std/js/html/compat/Float32Array.hx

@@ -103,7 +103,7 @@ class Float32Array {
 	}
 
 	static function __init__() {
-		var Float32Array = untyped Function("return typeof Float32Array != 'undefined' ? Float32Array : null")() || _new;
+		var Float32Array = untyped js.Lib.global.Float32Array || _new;
 	}
 
 }

+ 1 - 1
std/js/html/compat/Float64Array.hx

@@ -110,7 +110,7 @@ class Float64Array {
 	}
 
 	static function __init__() {
-		var Float64Array = untyped Function("return typeof Float64Array != 'undefined' ? Float64Array : (typeof Float32Array != 'undefined' ? 'notsupported' : null)")() || _new;
+		var Float64Array = untyped js.Lib.global.Float64Array || (js.Lib.global.Float32Array ? 'notsupported' : null) || _new;
 	}
 
 }

+ 1 - 1
std/js/html/compat/Uint8Array.hx

@@ -94,7 +94,7 @@ class Uint8Array {
 	}
 
 	static function __init__() {
-		var Uint8Array = untyped Function("return typeof Uint8Array != 'undefined' ? Uint8Array : null")() || _new;
+		var Uint8Array = untyped js.Lib.global.Uint8Array || _new;
 	}
 
 }