Forráskód Böngészése

array subtyping ok.

Nicolas Cannasse 19 éve
szülő
commit
9637474e99
3 módosított fájl, 111 hozzáadás és 12 törlés
  1. 60 10
      genswf9.ml
  2. 3 2
      std/flash9/Boot.hx
  3. 48 0
      std/flash9/FlashArray__.hx

+ 60 - 10
genswf9.ml

@@ -73,6 +73,8 @@ type context = {
 let error p = Typer.error "Invalid expression" p
 let error p = Typer.error "Invalid expression" p
 let stack_error p = Typer.error "Stack error" p
 let stack_error p = Typer.error "Stack error" p
 
 
+let tarray = ["flash"] , "FlashArray__"
+
 let stack_delta = function
 let stack_delta = function
 	| A3Throw -> -1
 	| A3Throw -> -1
 	| A3GetSuper _ -> 1
 	| A3GetSuper _ -> 1
@@ -219,13 +221,17 @@ let jump_back ctx =
 		write ctx (A3Jump (cond,delta))
 		write ctx (A3Jump (cond,delta))
 	)
 	)
 
 
-let type_path ctx ?(getclass=false) (pack,name) =
+let real_type_path ctx getclass (pack,name) =	
 	let pid = string ctx (String.concat "." pack) in
 	let pid = string ctx (String.concat "." pack) in
 	let nameid = string ctx name in
 	let nameid = string ctx name in
 	let pid = lookup (A3RPublic (Some pid)) ctx.brights in
 	let pid = lookup (A3RPublic (Some pid)) ctx.brights in
 	let tid = lookup (if getclass then A3TClassInterface (Some nameid,lookup [pid] ctx.rights) else A3TMethodVar (nameid,pid)) ctx.types in
 	let tid = lookup (if getclass then A3TClassInterface (Some nameid,lookup [pid] ctx.rights) else A3TMethodVar (nameid,pid)) ctx.types in
 	tid
 	tid
 
 
+let type_path ctx ?(getclass=false) path =
+	let path = (match path with [] , "Array" -> tarray | _ -> path) in
+	real_type_path ctx getclass path
+
 let ident ctx i = type_path ctx ([],i)
 let ident ctx i = type_path ctx ([],i)
 
 
 let default_infos() =
 let default_infos() =
@@ -261,12 +267,12 @@ let open_block ctx =
 		ctx.infos.iregs <- old_regs
 		ctx.infos.iregs <- old_regs
 	)
 	)
 
 
-let begin_fun ctx args =
+let begin_fun ctx ?(varargs=false) args =
 	let mt = {
 	let mt = {
 		mt3_ret = None;
 		mt3_ret = None;
 		mt3_args = List.map (fun _ -> None) args;
 		mt3_args = List.map (fun _ -> None) args;
 		mt3_native = false;
 		mt3_native = false;
-		mt3_var_args = false;
+		mt3_var_args = varargs;
 		mt3_debug_name = None;
 		mt3_debug_name = None;
 		mt3_dparams = None;
 		mt3_dparams = None;
 		mt3_pnames = None;
 		mt3_pnames = None;
@@ -426,8 +432,10 @@ let rec gen_expr_content ctx retval e =
 		) fl;
 		) fl;
 		write ctx (A3Object (List.length fl))
 		write ctx (A3Object (List.length fl))
 	| TArrayDecl el ->
 	| TArrayDecl el ->
+		let id = type_path ctx tarray in
+		write ctx (A3GetInf id);
 		List.iter (gen_expr ctx true) el;
 		List.iter (gen_expr ctx true) el;
-		write ctx (A3Array (List.length el))
+		write ctx (A3New (id,List.length el))
 	| TBlock el ->
 	| TBlock el ->
 		let rec loop = function
 		let rec loop = function
 			| [] -> if retval then write ctx A3Null
 			| [] -> if retval then write ctx A3Null
@@ -611,6 +619,13 @@ and gen_access ctx e =
 		VReg (try PMap.find i ctx.locals with Not_found -> error e.epos)
 		VReg (try PMap.find i ctx.locals with Not_found -> error e.epos)
 	| TField ({ eexpr = TLocal "__global__" },f) ->
 	| TField ({ eexpr = TLocal "__global__" },f) ->
 		VGlobal (ident ctx f)
 		VGlobal (ident ctx f)
+	| TField ({ eexpr = TLocal "__native__" },f) ->
+		let nameid = string ctx f in
+		let adobeid = string ctx "http://adobe.com/AS3/2006/builtin" in
+		let pid = lookup (A3RUnknown1 adobeid) ctx.brights in
+		let id = lookup (A3TMethodVar (nameid,pid)) ctx.types in
+		write ctx (A3GetInf id);
+		VId id
 	| TField (e,f) ->
 	| TField (e,f) ->
 		let id = ident ctx f in
 		let id = ident ctx f in
 		(match e.eexpr with
 		(match e.eexpr with
@@ -761,9 +776,9 @@ let generate_class_init ctx c slot =
 		write ctx A3Null
 		write ctx A3Null
 	else begin
 	else begin
 		let path = (match c.cl_super with None -> ([],"Object") | Some (sup,_) -> sup.cl_path) in
 		let path = (match c.cl_super with None -> ([],"Object") | Some (sup,_) -> sup.cl_path) in
-		write ctx (A3GetProp (type_path ctx path));
+		write ctx (A3GetProp (real_type_path ctx false path));
 		write ctx A3Scope;
 		write ctx A3Scope;
-		write ctx (A3GetProp (type_path ~getclass:true ctx path));
+		write ctx (A3GetProp (real_type_path ctx true path));
 	end;
 	end;
 	write ctx (A3ClassDef slot);
 	write ctx (A3ClassDef slot);
 	if not c.cl_interface then write ctx A3PopScope;
 	if not c.cl_interface then write ctx A3PopScope;
@@ -830,7 +845,7 @@ let generate_field_kind ctx f c stat =
 		Some (A3FMethod {
 		Some (A3FMethod {
 			m3_type = generate_function ctx fdata stat;
 			m3_type = generate_function ctx fdata stat;
 			m3_final = false;
 			m3_final = false;
-			m3_override = not stat && loop c;
+			m3_override = not stat && (if c.cl_path = tarray then false else loop c);
 			m3_kind = MK3Normal;
 			m3_kind = MK3Normal;
 		})
 		})
 	| _ when c.cl_interface && not stat ->
 	| _ when c.cl_interface && not stat ->
@@ -842,6 +857,39 @@ let generate_field_kind ctx f c stat =
 			v3_const = false;
 			v3_const = false;
 		})
 		})
 
 
+let generate_array_constructor ctx =
+	let f = begin_fun ~varargs:true ctx [] in
+	write ctx A3This;
+	write ctx A3Scope;
+	let args = alloc_reg ctx in
+	let len = alloc_reg ctx in
+	let i = alloc_reg ctx in
+	let id_length = ident ctx "length" in
+	let id_array = lookup (A3TArrayAccess ctx.gpublic) ctx.types in
+	write ctx (A3SetInf id_length);
+	write ctx (A3Reg args);
+	write ctx (A3Get id_length);
+	write ctx A3Dup;
+	write ctx (A3SetReg len);
+	write ctx (A3Set id_length);
+	write ctx (A3SmallInt 0);
+	write ctx (A3SetReg i);
+	let loop = jump_back ctx in	
+	write ctx (A3Reg i);
+	write ctx (A3Reg len);
+	let exit = jump ctx J3Gte in
+	write ctx A3This;
+	write ctx (A3Reg i);
+	write ctx (A3Reg args);
+	write ctx (A3Reg i);
+	write ctx (A3Get id_array);
+	write ctx (A3Set id_array);
+	write ctx (A3IncrReg i);
+	loop J3Always;
+	exit();
+	write ctx A3RetVoid;
+	f()
+
 let generate_class ctx c =
 let generate_class ctx c =
 	let name_id = type_path ctx c.cl_path in
 	let name_id = type_path ctx c.cl_path in
 	let st_id = empty_method ctx in
 	let st_id = empty_method ctx in
@@ -876,7 +924,9 @@ let generate_class ctx c =
 			in
 			in
 			loop c
 			loop c
 		| Some f ->
 		| Some f ->
-			match f.cf_expr with
+			if c.cl_path = tarray then
+				generate_array_constructor ctx
+			else match f.cf_expr with
 			| Some { eexpr = TFunction f } -> generate_function ctx f false
 			| Some { eexpr = TFunction f } -> generate_function ctx f false
 			| _ -> assert false
 			| _ -> assert false
 	) in
 	) in
@@ -893,8 +943,8 @@ let generate_class ctx c =
 	) c.cl_fields []) in
 	) c.cl_fields []) in
 	let sc = {
 	let sc = {
 		cl3_name = name_id;
 		cl3_name = name_id;
-		cl3_super = (if c.cl_interface then None else Some (type_path ctx (match c.cl_super with None -> [],"Object" | Some (c,_) -> c.cl_path)));
-		cl3_sealed = true;
+		cl3_super = (if c.cl_interface then None else Some (real_type_path ctx false (match c.cl_super with None -> [],"Object" | Some (c,_) -> c.cl_path)));
+		cl3_sealed = c.cl_path <> tarray;
 		cl3_final = false;
 		cl3_final = false;
 		cl3_interface = c.cl_interface;
 		cl3_interface = c.cl_interface;
 		cl3_rights = None;
 		cl3_rights = None;

+ 3 - 2
std/flash9/Boot.hx

@@ -2,12 +2,13 @@ package flash;
 
 
 class Boot extends flash.display.MovieClip {
 class Boot extends flash.display.MovieClip {
 
 
-	static var init;
-	static var tf;
+	static var init : Void -> Void;
+	static var tf : flash.text.TextField;
 	static var lines : Array<String>;
 	static var lines : Array<String>;
 
 
 	function new() {
 	function new() {
 		super();
 		super();
+		var ref = FlashArray__;
 		lines = new Array();
 		lines = new Array();
 		flash.Lib.current = this;
 		flash.Lib.current = this;
 		init();
 		init();

+ 48 - 0
std/flash9/FlashArray__.hx

@@ -0,0 +1,48 @@
+package flash;
+
+private class ArrayIterator<T> {
+
+	var arr : Array<T>;
+	var cur : Int;
+
+	public function new(a) {
+		arr = a;
+		cur = 0;
+	}
+
+	public function hasNext() {
+		return cur < arr.length;
+	}
+
+	public function next() {
+		return arr[cur++];
+	}
+
+}
+
+class FlashArray__<T> extends Array<T> {
+
+	public override function insert(i,x) {
+		untyped (__native__.splice)(i,0,x);
+	}
+
+	public override function copy() {
+		return untyped (__native__.slice)();
+	}
+
+	public override function remove(obj) untyped {
+		for( i in 0...length ) {
+			if( this[i] == obj ) {
+				(__native__.splice)(i,1);
+				return true;
+			}
+		}
+		return false;
+	}
+
+	public override function iterator() : Iterator<T> untyped {
+		return new ArrayIterator(this);
+	}
+
+}
+