Selaa lähdekoodia

[php] cache closures created of static and instance methods

Alexander Kuzmenko 7 vuotta sitten
vanhempi
commit
57528372fd
3 muutettua tiedostoa jossa 33 lisäystä ja 4 poistoa
  1. 4 2
      src/generators/genphp7.ml
  2. 28 1
      std/php/Boot.hx
  3. 1 1
      std/php/_std/Type.hx

+ 4 - 2
src/generators/genphp7.ml

@@ -2319,7 +2319,8 @@ class code_writer (ctx:Common.context) hx_type_path php_name =
 		*)
 		method write_static_method_closure expr field_name =
 			let expr = reveal_expr expr in
-			self#write ("new " ^ (self#use hxclosure_type_path) ^ "(");
+			self#write ((self#use boot_type_path) ^ "::getStaticClosure(");
+			(* self#write ("new " ^ (self#use hxclosure_type_path) ^ "("); *)
 			(match (reveal_expr expr).eexpr with
 				| TTypeExpr (TClassDecl { cl_path = ([], "String") }) ->
 					self#write ((self#use hxstring_type_path) ^ "::class")
@@ -2344,7 +2345,8 @@ class code_writer (ctx:Common.context) hx_type_path php_name =
 						self#write_expr expr;
 						self#write ("->" ^ (field_name field))
 			else
-				let new_closure = "new " ^ (self#use hxclosure_type_path) in
+				(* let new_closure = "new " ^ (self#use hxclosure_type_path) in *)
+				let new_closure = ((self#use boot_type_path) ^ "::getInstanceClosure") in
 				match expr.eexpr with
 					| TTypeExpr mtype ->
 						let class_name = self#use_t (type_of_module_type mtype) in

+ 28 - 1
std/php/Boot.hx

@@ -42,6 +42,8 @@ class Boot {
 	@:protected static var setters = new NativeAssocArray<NativeAssocArray<Bool>>();
 	/** Metadata storage */
 	@:protected static var meta = new NativeAssocArray<{}>();
+	/** Cache for closures created of static methods */
+	@:protected static var staticClosures = new NativeAssocArray<NativeAssocArray<HxClosure>>();
 
 	/**
 		Initialization stuff.
@@ -534,8 +536,33 @@ class Boot {
 		var chars = Global.preg_split('//u', str, -1, Const.PREG_SPLIT_NO_EMPTY);
 		return chars == false ? null : (chars:NativeArray)[index];
 	}
-}
 
+	public static function getInstanceClosure(obj:{?__hx_closureCache:NativeAssocArray<HxClosure>}, methodName:String) {
+		var result = Syntax.coalesce(obj.__hx_closureCache[methodName], null);
+		if(result != null) {
+			return result;
+		}
+		result = new HxClosure(obj, methodName);
+		if(!Global.property_exists(obj, '__hx_closureCache')) {
+			obj.__hx_closureCache = new NativeAssocArray();
+		}
+		obj.__hx_closureCache[methodName] = result;
+		return result;
+	}
+
+	public static function getStaticClosure(phpClassName:String, methodName:String) {
+		var result = Syntax.coalesce(staticClosures[phpClassName][methodName], null);
+		if(result != null) {
+			return result;
+		}
+		result = new HxClosure(phpClassName, methodName);
+		if(!Global.array_key_exists(phpClassName, staticClosures)) {
+			staticClosures[phpClassName] = new NativeAssocArray();
+		}
+		staticClosures[phpClassName][methodName] = result;
+		return result;
+	}
+}
 
 /**
 	Class<T> implementation for Haxe->PHP internals.

+ 1 - 1
std/php/_std/Type.hx

@@ -328,7 +328,7 @@ enum ValueType {
 		check if specified `name` is a special field name generated by compiler.
 	 **/
 	static inline function isServiceFieldName(name:String) : Bool {
-		return (name == '__construct' || name.indexOf('__hx__') == 0);
+		return (name == '__construct' || name.indexOf('__hx_') == 0);
 	}
 }