Browse Source

[eval] check null on method calls

closes #10825
Simon Krajewski 2 years ago
parent
commit
6e189c6dce

+ 4 - 0
src/macro/eval/evalEmitter.ml

@@ -89,6 +89,10 @@ let emit_capture_declaration i exec env =
 
 
 let emit_const v _ = v
 let emit_const v _ = v
 
 
+let emit_null_check exec p env = match exec env with
+	| VNull -> throw_string "Null Access" p
+	| v -> v
+
 let emit_new_array env =
 let emit_new_array env =
 	encode_array_instance (EvalArray.create [||])
 	encode_array_instance (EvalArray.create [||])
 
 

+ 7 - 3
src/macro/eval/evalJit.ml

@@ -429,14 +429,18 @@ and jit_expr jit return e =
 				let i = get_proto_field_index proto name in
 				let i = get_proto_field_index proto name in
 				lazy (match proto.pfields.(i) with VFunction (f,_) -> f | v -> cannot_call v e.epos)
 				lazy (match proto.pfields.(i) with VFunction (f,_) -> f | v -> cannot_call v e.epos)
 			in
 			in
-			let instance_call c =
+			let jit_with_null_check ef =
 				let exec = jit_expr jit false ef in
 				let exec = jit_expr jit false ef in
+				emit_null_check exec ef.epos
+			in
+			let instance_call c =
+				let exec = jit_with_null_check ef in
 				let proto = get_instance_prototype ctx (path_hash c.cl_path) ef.epos in
 				let proto = get_instance_prototype ctx (path_hash c.cl_path) ef.epos in
 				let v = lazy_proto_field proto in
 				let v = lazy_proto_field proto in
 				emit_proto_field_call v (exec :: execs) e.epos
 				emit_proto_field_call v (exec :: execs) e.epos
 			in
 			in
 			let default () =
 			let default () =
-				let exec = jit_expr jit false ef in
+				let exec = jit_with_null_check ef in
 				emit_method_call exec name execs e.epos
 				emit_method_call exec name execs e.epos
 			in
 			in
 			begin match fa with
 			begin match fa with
@@ -472,7 +476,7 @@ and jit_expr jit return e =
 					end else
 					end else
 						default()
 						default()
 				| _ ->
 				| _ ->
-					let exec = jit_expr jit false ef in
+					let exec = jit_with_null_check ef in
 					emit_field_call exec name execs e.epos
 					emit_field_call exec name execs e.epos
 			end
 			end
 		| TConst TSuper ->
 		| TConst TSuper ->

+ 14 - 0
tests/misc/projects/Issue10825/Main.hx

@@ -0,0 +1,14 @@
+class A {
+	public function new() {}
+
+	public final function run() {
+		trace("running");
+	}
+}
+
+class Main {
+	static function main() {
+		final a:A = null;
+		a.run();
+	}
+}

+ 2 - 0
tests/misc/projects/Issue10825/compile-fail.hxml

@@ -0,0 +1,2 @@
+--main Main
+--interp

+ 1 - 0
tests/misc/projects/Issue10825/compile-fail.hxml.stderr

@@ -0,0 +1 @@
+Main.hx:12: characters 3-4 : Uncaught exception Null Access