瀏覽代碼

cancel array inlining when there's a implementation field access (closes #5747)

Dan Korostelev 9 年之前
父節點
當前提交
6febe85215
共有 2 個文件被更改,包括 20 次插入1 次删除
  1. 10 1
      src/optimization/optimizer.ml
  2. 10 0
      tests/unit/src/unit/issues/Issue5747.hx

+ 10 - 1
src/optimization/optimizer.ml

@@ -1278,7 +1278,16 @@ let inline_constructors ctx e =
 			find_locals e2
 		| TField({eexpr = TLocal v},fa) when v.v_id < 0 ->
 			begin match extract_field fa with
-			| Some {cf_kind = Var _} -> ()
+			| Some ({cf_kind = Var _} as cf) ->
+				(* Arrays are not supposed to have public var fields, besides "length" (which we handle when inlining),
+				   however, its inlined methods may generate access to private implementation fields (such as internal
+				   native array), in this case we have to cancel inlining.
+				*)
+				if cf.cf_name <> "length" then
+					begin match (IntMap.find v.v_id !vars).ii_kind with
+					| IKArray _ -> cancel v e.epos
+					| _ -> ()
+					end
 			| _ -> cancel v e.epos
 			end
 		| TArray({eexpr = TLocal v},{eexpr = TConst (TInt i)}) when v.v_id < 0 ->

+ 10 - 0
tests/unit/src/unit/issues/Issue5747.hx

@@ -0,0 +1,10 @@
+package unit.issues;
+
+class Issue5747 extends Test {
+    #if cs
+    function test() {
+        var a = [1,2,3];
+        eq(@:privateAccess a.__a[0], 1);
+    }
+    #end
+}