Bläddra i källkod

changed cast code generation (use Std.is instead of try/catch), better for F9

Nicolas Cannasse 19 år sedan
förälder
incheckning
959a4c3ddb
2 ändrade filer med 30 tillägg och 10 borttagningar
  1. 1 0
      doc/CHANGES.txt
  2. 29 10
      typer.ml

+ 1 - 0
doc/CHANGES.txt

@@ -14,6 +14,7 @@
 	added neko.net.ThreadServer, ThreadRemotingServer and Poll
 	removed neko.net.RemotingBuffer
 	relaxed enums switchs (allow value in first case)
+	changed "cast" codegeneration (fix some F9 usages)
 
 2006-10-29: 1.08
 	fixed bug in flash -debug

+ 29 - 10
typer.ml

@@ -1824,16 +1824,35 @@ and type_expr ctx ?(need_val=true) (e,p) =
 			etype = mk_mono();
 			epos = e.epos;
 		}
-	| ECast (e,t) ->
-		match t with
-		| None ->
-			let e = type_expr ctx e in
-			{ e with etype = mk_mono() }
-		| Some t ->
-			type_expr ctx (ETry ((EThrow e,p),[
-				("e",t,(EConst (Ident "e"),p));
-				("e",TPNormal { tpackage = []; tname = "Dynamic"; tparams = [] },(EThrow (EConst (String "Class cast error"),p),p))
-			]),p)
+	| ECast (e,None) ->
+		let e = type_expr ctx e in
+		{ e with etype = mk_mono() }
+	| ECast (e, Some t) ->
+		(* // if( Std.is(tmp,T) ) tmp else throw "Class cast error" *)
+		let etmp = (EConst (Ident "tmp"),p) in
+		let t = load_type ctx (pos e) t in
+		let tname = (match follow t with
+		| TInst (_,params) | TEnum (_,params) ->
+			List.iter (fun (_,pt) ->
+				if pt != t_dynamic then error "Cast class parameter must be Dynamic" p;
+			) params;
+			(match follow t with
+			| TInst (c,_) -> c.cl_path
+			| TEnum (e,_) -> e.e_path
+			| _ -> assert false);
+		| _ -> 
+			error "Cast type must be a class" p
+		) in
+		let make_type (path,name) =
+			match path with
+			| [] -> (EConst (Type name),p)
+			| x :: path -> (EType (List.fold_left (fun acc x -> (EField (acc,x),p)) (EConst (Ident x),p) path,name),p)
+		in
+		let cond = (ECall ((EField ((EConst (Type "Std"),p),"is"),p),[etmp;make_type tname]),p) in
+		type_expr ctx (EBlock [
+			(EVars [("tmp",None,Some e)],p);
+			(EIf (cond,etmp,Some (EThrow (EConst (String "Class cast error"),p),p)),p);
+		],p)
 
 and type_function ctx t static constr f p =
 	let locals = save_locals ctx in