Skip to content

Commit

Permalink
[cpp] Use cpp::Int64 for haxe.Int64 instead of a class (#9935)
Browse files Browse the repository at this point in the history
* Generate variables, functions, and ClassOf with ::cpp::Int64 for haxe.Int64

* cpp haxe.Int64 abstract implements functions required by the api

* Use standard maths operators where possible

* Disallow type checks using the haxe.Int64 abstract

* Add functions for getting and setting Int64 values in map types

* Use maths helper functions for bitwise ops

* Increase hxcpp api version

* Remove earlier gencpp changes as they're not needed when abstracting around cpp.Int64

* Bump api version

* Add a new cpp specific Int64Map type

* use extern functions for Int64 operators

* Add implicit from for cpp Int64Map

* Add Int64Map check for cppia get and set calls

* Intercept Class<cpp.Int64> calls and insert the correct path

* Add cpp.Int64Map to cppia host classes array

* Fix incorrect signature from copy and pasting

* add int64 get and set functions for map specialisations on cppia

* Prevent enums with Int64s being boxed or down casted to ints
  • Loading branch information
Aidan63 authored Nov 8, 2022
1 parent 186ac62 commit bc50a04
Show file tree
Hide file tree
Showing 10 changed files with 453 additions and 51 deletions.
2 changes: 1 addition & 1 deletion src/compiler/haxe.ml
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,4 @@ set_binary_mode_out stdout true;
set_binary_mode_out stderr true;
let sctx = ServerCompilationContext.create false in
Server.process sctx (Communication.create_stdio ()) args;
other()
other()
12 changes: 11 additions & 1 deletion src/generators/gencpp.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2083,6 +2083,7 @@ let cpp_variant_type_of t = match t with
| TCppScalar "Int"
| TCppScalar "bool"
| TCppScalar "Float" -> t
| TCppScalar "::cpp::Int64" -> TCppScalar("Int64")
| TCppScalar "double"
| TCppScalar "float" -> TCppScalar("Float")
| TCppScalar _ -> TCppScalar("int")
Expand Down Expand Up @@ -2273,6 +2274,7 @@ let is_array_splice_call obj member =
let is_map_get_call obj member =
member.cf_name="get" &&
(match obj.cpptype with
| TCppInst({cl_path=(["cpp"],"Int64Map")}, _) -> true
| TCppInst({cl_path=(["haxe";"ds"],"IntMap")}, _) -> true
| TCppInst({cl_path=(["haxe";"ds"],"StringMap")}, _) -> true
| TCppInst({cl_path=(["haxe";"ds"],"ObjectMap")}, _) -> true
Expand All @@ -2283,6 +2285,7 @@ let is_map_get_call obj member =
let is_map_set_call obj member =
member.cf_name="set" &&
(match obj.cpptype with
| TCppInst({cl_path=(["cpp"],"Int64Map")}, _) -> true
| TCppInst({cl_path=(["haxe";"ds"],"IntMap")}, _) -> true
| TCppInst({cl_path=(["haxe";"ds"],"StringMap")}, _) -> true
| TCppInst({cl_path=(["haxe";"ds"],"ObjectMap")}, _) -> true
Expand Down Expand Up @@ -2767,6 +2770,7 @@ let retype_expression ctx request_type function_args function_type expression_tr
let fname, cppType = match return_type with
| TCppVoid | TCppScalar("bool") -> (if forCppia then "getBool" else "get_bool"), return_type
| TCppScalar("int") -> (if forCppia then "getInt" else "get_int"), return_type
| TCppScalar("::cpp::Int64") -> (if forCppia then "getInt64" else "get_int64"), return_type
| TCppScalar("Float") -> (if forCppia then "getFloat" else "get_float"), return_type
| TCppString -> (if forCppia then "getString" else "get_string"), return_type
| _ -> "get", TCppDynamic
Expand All @@ -2786,6 +2790,7 @@ let retype_expression ctx request_type function_args function_type expression_tr
let fname = match retypedArgs with
| [_;{cpptype=TCppScalar("bool")}] -> "setBool"
| [_;{cpptype=TCppScalar("int")}] -> "setInt"
| [_;{cpptype=TCppScalar("::cpp::Int64")}] -> "setInt64"
| [_;{cpptype=TCppScalar("Float")}] -> "setFloat"
| [_;{cpptype=TCppString}] -> "setString"
| _ -> "set"
Expand Down Expand Up @@ -2947,7 +2952,12 @@ let retype_expression ctx request_type function_args function_type expression_tr
arrayExpr, elemType

| TTypeExpr module_type ->
let path = t_path module_type in
(* If we try and use the coreType / runtimeValue cpp.Int64 abstract with Class<T> then we get a class decl of the abstract *)
(* as that abstract has functions in its declaration *)
(* Intercept it and replace it with the path of the actual int64 type so the generated cpp is correct *)
let path = match module_type with
| TClassDecl ({ cl_path = ["cpp";"_Int64"],"Int64_Impl_" }) -> ["cpp"],"Int64"
| _ -> t_path module_type in
CppClassOf(path, is_native_gen_module module_type), TCppClass

| TBinop (op,left,right) ->
Expand Down
154 changes: 154 additions & 0 deletions std/cpp/Int64Map.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
/*
* Copyright (C)2005-2019 Haxe Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/

package cpp;

import haxe.Int64;

@:headerClassCode("
inline void set(cpp::Int64 key, ::null value) { __int64_hash_set(HX_MAP_THIS,key,value); }
inline void set(cpp::Int64 key, bool value) { __int64_hash_set(HX_MAP_THIS,key,value); }
inline void set(cpp::Int64 key, char value) { __int64_hash_set_int(HX_MAP_THIS,key,value); }
inline void set(cpp::Int64 key, unsigned char value) { __int64_hash_set_int(HX_MAP_THIS,key,value); }
inline void set(cpp::Int64 key, signed char value) { __int64_hash_set_int(HX_MAP_THIS,key,value); }
inline void set(cpp::Int64 key, short value) { __int64_hash_set_int(HX_MAP_THIS,key,value); }
inline void set(cpp::Int64 key, unsigned short value) { __int64_hash_set_int(HX_MAP_THIS,key,value); }
inline void set(cpp::Int64 key, int value) { __int64_hash_set_int(HX_MAP_THIS,key,value); }
inline void set(cpp::Int64 key, unsigned int value) { __int64_hash_set_int(HX_MAP_THIS,key,value); }
inline void set(cpp::Int64 key, float value) { __int64_hash_set_float(HX_MAP_THIS,key,value); }
inline void set(cpp::Int64 key, double value) { __int64_hash_set_float(HX_MAP_THIS,key,value); }
inline void set(cpp::Int64 key, ::String value) { __int64_hash_set_string(HX_MAP_THIS,key,value); }
inline void set(cpp::Int64 key, cpp::Int64 value) { __int64_hash_set_int64(HX_MAP_THIS,key,value); }
template<typename V, typename H>
inline void set(cpp::Int64 key, const ::cpp::Struct<V,H> &value) {__int64_hash_set(HX_MAP_THIS,key,value); }
template<typename F>
inline void set(cpp::Int64 key, const ::cpp::Function<F> &value) {__int64_hash_set(HX_MAP_THIS,key,value); }
template<typename V>
inline void set(cpp::Int64 key, const ::cpp::Pointer<V> &value) {__int64_hash_set(HX_MAP_THIS,key,(Dynamic)value ); }
template<typename VALUE>
inline void set(Dynamic &key, const VALUE &value) { set( (cpp::Int64)key, value ); }
inline bool get_bool(cpp::Int64 key) { return __int64_hash_get_bool(h,key); }
inline int get_int(cpp::Int64 key) { return __int64_hash_get_int(h,key); }
inline Float get_float(cpp::Int64 key) { return __int64_hash_get_float(h,key); }
inline String get_string(cpp::Int64 key) { return __int64_hash_get_string(h,key); }
inline cpp::Int64 get_int64(cpp::Int64 key) { return __int64_hash_get_int64(h,key); }
")
@:coreApi class Int64Map<T> implements haxe.Constraints.IMap<Int64, T> {
@:ifFeature("cpp.Int64Map.*")
private var h:Dynamic;

public function new():Void {}

public function set(key:Int64, value:T):Void {
untyped __global__.__int64_hash_set(__cpp__("HX_MAP_THIS"), key, value);
}

public function get(key:Int64):Null<T> {
return untyped __global__.__int64_hash_get(h, key);
}

public function exists(key:Int64):Bool {
return untyped __global__.__int64_hash_exists(h, key);
}

public function remove(key:Int64):Bool {
return untyped __global__.__int64_hash_remove(h, key);
}

public function keys():Iterator<Int64> {
var a:Array<Int64> = untyped __global__.__int64_hash_keys(h);
return a.iterator();
}

public function iterator():Iterator<T> {
var a:Array<Dynamic> = untyped __global__.__int64_hash_values(h);
return a.iterator();
}

@:runtime public inline function keyValueIterator():KeyValueIterator<Int64, T> {
return new haxe.iterators.MapKeyValueIterator(this);
}

public function copy():Int64Map<T> {
var copied = new Int64Map();
for (key in keys())
copied.set(key, get(key));
return copied;
}

public function toString():String {
return untyped __global__.__int64_hash_to_string(h);
}

public function clear():Void {
#if (hxcpp_api_level >= 400)
return untyped __global__.__int64_hash_clear(h);
#else
h = null;
#end
}

#if (scriptable)
private function setString(key:Int64, val:String):Void {
untyped __int64_hash_set_string(__cpp__("HX_MAP_THIS"), key, val);
}

private function setInt(key:Int64, val:Int):Void {
untyped __int64_hash_set_int(__cpp__("HX_MAP_THIS"), key, val);
}

private function setBool(key:Int64, val:Bool):Void {
untyped __int64_hash_set_int(__cpp__("HX_MAP_THIS"), key, val);
}

private function setFloat(key:Int64, val:Float):Void {
untyped __int64_hash_set_float(__cpp__("HX_MAP_THIS"), key, val);
}

private function setInt64(key:Int64, val:Int64):Void {
untyped __int64_hash_set_int64(__cpp__("HX_MAP_THIS"), key, val);
}

private function getString(key:Int64):String {
return untyped __int64_hash_get_string(h, key);
}

private function getInt(key:Int64):Int {
return untyped __int64_hash_get_int(h, key);
}

private function getBool(key:Int64):Bool {
return untyped __int64_hash_get_bool(h, key);
}

private function getFloat(key:Int64):Float {
return untyped __int64_hash_get_float(h, key);
}

private function getInt64(key:Int64):Int64 {
return untyped __int64_hash_get_int64(h, key);
}
#end
}
Loading

0 comments on commit bc50a04

Please sign in to comment.