Giter Club home page Giter Club logo

hxcpp's Introduction

hxcpp

Build Status

hxcpp is the runtime support for the c++ backend of the haxe compiler. This contains the headers, libraries and support code required to generate a fully compiled executable from haxe code.

building the tools

REPO=$(pwd)
cd ${REPO}/tools/run
haxe compile.hxml
cd ${REPO}/tools/hxcpp
haxe compile.hxml
cd $REPO

cppia

You first need to build the cppia host.

REPO=$(pwd)
cd ${REPO}/project
haxe compile-cppia.hxml
cd $REPO

Then you can do haxelib run hxcpp file.cppia.

hxcpp's People

Contributors

aidan63 avatar alanvf avatar andyli avatar apprentice-alchemist avatar aurel300 avatar bji avatar codeservice avatar delahee avatar gama11 avatar haxiomic avatar hughsando avatar james4k avatar jcward avatar jgranick avatar jobs-git avatar jonasmalacofilho avatar justin-espedal avatar m0rkeulv avatar madrazo avatar ncannasse avatar player-03 avatar pperidont avatar realyuniquename avatar robdangerous avatar robocoder avatar simn avatar tanis2000 avatar thomasuster avatar tobil4sk avatar waneck avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hxcpp's Issues

Float output loses precision

var f:Float = 1399571912674;
trace(haxe.Json.stringify({'float':f}));

Results in:
{"float":1.399571913e+12}

Which loses precision.

'<::' template-argument issue

Hello,

using latest haxe/hxcpp I'm getting this issue.

The original code doesn't do anything in particular from what I can say...

src/ui/view/MainView.cpp: In member function 'virtual Void ui::view::MainView_obj::update()':
./src/ui/view/MainView.cpp:707: error: '<::' cannot begin a template-argument list
./src/ui/view/MainView.cpp:707: note: '<:' is an alternate spelling for '['. Insert whitespace between '<' and '::'
./src/ui/view/MainView.cpp:707: note: (if you use '-fpermissive' G++ will accept your code)
./src/ui/view/MainView.cpp: In member function 'virtual Void ui::view::MainView_obj::onLetterDrag(ui::Letter)':
./src/ui/view/MainView.cpp:1118: error: '<::' cannot begin a template-argument list
./src/ui/view/MainView.cpp:1118: note: '<:' is an alternate spelling for '['. Insert whitespace between '<' and '::'
./src/ui/view/MainView.cpp:1132: error: '<::' cannot begin a template-argument list
./src/ui/view/MainView.cpp:1132: note: '<:' is an alternate spelling for '['. Insert whitespace between '<' and '::'

Feelings on directory structure?

Again, I apologize for using GitHub issues for starting a conversation, if you don't mind, we can talk about it here, otherwise we can take it elsewhere.

I was wondering how you guys felt about directory structure. As you may know, the lime-tools work with "include.xml" files that allow libraries to extend the functionality of an application. Under hxlibc, the "include.xml" brings the std, regexp and zlib libraries into the project. As a result, all a project needs is and it brings the dependency libraries in automatically.

This system is standardized as "ndll", I know this seems a little funny when this is not used for Neko, but I would prefer not to hard-code special conditions.

Similarly, the "lime rebuild " command works with a standard expectation of "project/Build.xml" in the library. As you know, this is "runtime/BuildLibs.xml" under HXCPP. I wasn't sure if it would be sensible to adjust this path/location, or if you have suggestions for how a "rebuild" command could be more aware of the internal structure of a library, perhaps through an "include.xml" file.

The value of this command becomes clear especially for targets like iOS, which require armv6, armv7 and i386 builds of both debug and release libraries. A single build command is much simpler than hunting down six separate commands, and the best part is that "lime rebuild" works from any directory, so its simple to run real quick when something may need to be updated (or "-clean", too, if you want a clean rebuild)

Memory overflow

Hi,

Seing how sophisticated hxcpp debugging is getting, this one would end many of my miseries. If there is already a way to do that, I would be grateful...

AFAIK there is no way to detect memory overflow like this one : openfl/openfl-native#126

Can you please add a way to add memory fences like this :

1- Add 4 bytes at the begining and the end of each allocated chunk by malloc/gcalloc
2- mark them with some hex tag (like 0xdeadb00t )
3- offset allocated buffer and return it from malloc.
4- expose a define and a function to enable all this. (like debuggerOverflowCheck) The function will check for tag integrity.
5- document the whole thing :)

This was a technique I successfully implemented and used on machines ranging from ps2 to iphone. It would be lovely to have such a powerful tool.

Thanks !

Merging tool behavior?

I am comparing hxlibc and hxcpp, to see if the improvements from hxlibc can be merged into hxcpp.

In hxlibc, the tools were refactored into separate class files, and the common functions such as running a process or making a directory were made to share the helpers from lime-tools. From a maintenance perspective, this helps the hxlibc tools be more resilient, while also allowing us to make fixes in one place. For an official Haxe dependency library, this obviously does not make sense.

Unless there is an objection, I would like to help bring the improvements into HXCPP, but in the process, I would like to ask if it is alright to separate the run tool into multiple classes, and if these common functions can be expanded. Being your project, I can respect if there's a specific code format style you would prefer, etc.

For example, if you try to run a command on an exe that has a space in it, the current HXCPP run tool will split the exe on the space, using the first result as the executable, and the others as the beginning of the argument array.

In hxlibc, it checks for an escaped space, such as "\ ", and ignores this. It then escapes spaces it finds, based on the platform (you might be calling "my tool.exe") and it also expands ~/ to $HOME if encountered.

When creating a directory in the HXCPP tool, it splits the directory by the "/" character, and I believe it may also be picky about trailing slashes.

In hxlibc, it converts backslashes "" to forward slashes "/", it splits the path but it is also sensitive to absolute paths, trailing slashes and some other considerations.

The hxlibc tool also allows for -verbose output, I believe, and can colorize when supported by the target, for example, "Error: " in red and the message in white. The error messages have also been cleaned to try to be more helpful, and attention has been paid to throw stack traces only when an error is truly within the tools. If you have an error calling "g++" the error lies there, not within the tool, so sharing a stack trace is more confusing/messy than helpful.

Interested in your feelings on this, thanks!

Calling class methods inside of dynamic objects in overridden methods produces compilation error

The following code

class Test
{
  public function new()
    {}


  public dynamic function test(): Dynamic
    { return null; }


  public static function main()
    {
      var t = new Test2();
      trace(t.test());
    }
}

class Test2 extends Test
{
  public function test2(): Int
    { return 3; }

  public override function test()
    {
      var a = { c: test2() };
      return a;
    }

  function new()
    { super(); }
}

results in compilation error:

g++ -Iinclude -c -fvisibility=hidden -O2 -fpic -fPIC -DHX_LINUX -DHXCPP_M64 -DHXCPP_VISIT_ALLOCS -m64 -DHXCPP_M64 -I/usr/lib/haxe/lib/hxcpp/3,0,2//include -x c++ -frtti -Iobj/linux64//__pch/haxe ./src/Test.cpp -oobj/linux64//src/Test.o
./src/Test2.cpp: In member function ‘Dynamic {anonymous}::__default_test::run()’:
./src/Test2.cpp:50:41: error: no matching function for call to ‘{anonymous}::__default_test::run()::_Function_1_1::Block(hx::ObjectPtr<Test2_obj>&)’
./src/Test2.cpp:50:41: note: candidate is:
./src/Test2.cpp:39:25: note: static Dynamic {anonymous}::__default_test::run()::_Function_1_1::Block(Test2_obj*)
./src/Test2.cpp:39:25: note:   no known conversion for argument 1 from ‘hx::ObjectPtr<Test2_obj>’ to ‘Test2_obj*’

Changing the line

var a = { c: test2() };

into

var b = test2();
var a = { c: b };

is a workaround I found.

GC collects and frees live objects

Example:


class Main
{   
    public static function main() 
    {
        var t = new Test();
        t.test();
        trace("FINISHED");
    }
}

class Test
{
    public function new()
    {
        
    }
    
    public function test(depth : Int = 0)
    {
        if ((depth == 0) || (depth == 1000))
        {
            trace(depth);
            var b = new haxe.io.BytesBuffer();
            var bufsize = 5 << 20;
            var tmp = haxe.io.Bytes.alloc(bufsize);
            b.addBytes(tmp, 0, bufsize);
        }
        
        if (depth < 1000)
        {
            var t = new Test();
            t.test(depth + 1);
        }
    }
}

Expected output (works in flash):
Main.hx:22: 0
Main.hx:22: 1000
Main.hx:7: FINISHED

Windows output (haxe -main Main -cpp bin):
Main.hx:22: 0
Main.hx:22: 1000
APPLICATION CRASHED

Haxe 3.0.1, hxcpp git (11.12.2013)

should exit with non-0 when a dynamic lib is not found

When using haxelib git hxcpp https://github.com/HaxeFoundation/hxcpp.git, since the runtime libs are not yet build, any cpp targeted haxe code will result in runtime error: Error : Could not load module regexp@regexp_new_options__2, which is correct. However, the program still exit with code 0, which is wrong.

Tested with hxcpp 0ad5784 and haxe 523393405350b9bf74ca413d8e3142e64549649a. On Mac 10.9.

Strange for loop bug

After upgrading to hxcpp 3.1.30, I run into weird issue using hxtea library.
Here is the test code : https://gist.github.com/musanek/11333726

I did track it down to the following loop

   for (i in 0...32)
    {
        v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
        v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
        sum -= delta;
    }

in
static public function decrypt(v:Array, k:Array):Array

This loop translated to while in cpp goes forever. If I add trace as first statement in the loop it works. No problem on neko and swf.

gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3

Building on linux64 broken

Hey,
I am using linux mint 64 bit, haxe nightly builds and hxcpp from git.
I upgrade hxcpp and now when I try to compile, I get:

haxelib run hxcpp Build.xml haxe -Dhaxe3="1" -Dhaxe_ver="3.01" -Dhxmpp="1" -Dhxssl="1" -Dxspf="1"
Creating obj/linux//__pch/haxe/hxcpp.h.gch...
g++ -Iinclude -c -fvisibility=hidden -O2 -fpic -fPIC -DHX_LINUX -DHXCPP_VISIT_ALLOCS -DHXCPP_API_LEVEL=1 -m32 -I/usr/lib/haxe/lib/hxcpp/git//include -frtti -o obj/linux//__pch/haxe/hxcpp.h.gch obj/linux//__pch/haxe//hxcpp.h
g++: error: obj/linux//__pch/haxe//hxcpp.h: No such file or directory
g++: fatal error: no input files
compilation terminated.
Called from sys.io.Process::$statics line 1
Called from BuildTool::main line 2016
Called from BuildTool::$init line 863
Called from a C function
Called from BuildTool::new line 954
Called from BuildTool::buildTarget line 1281
Called from Compiler::precompile line 262
Uncaught exception - Error creating pch: 4 - build cancelled
Error: Build failed

array.sort loses GC references

It appears that doing a gc collect from within array.sort may prematurely collect some objects. Maybe:

  • use scratch area
  • std::allocator
  • non-std solution
    Also, maybe allow cpp.Function for non-dynamic sorting

__unsafe_set has no return

We should fix it to this which is more standard :

inline ELEM_ & __unsafe_set(int inIndex, const ELEM_ &inValue)
   {
      return (* (ELEM_ *)(mBase + inIndex*sizeof(ELEM_)) = inValue);
   }

[MotionTwin] HowTo rebuild ndlls from sources ?

Hi,

seems that the process of rebuilding Ndlls has changed a bit, and I don't see any documentation.

cd project
neko build.n android/windows ...

Seems to be fine so far...
Is that the correct way ?

Runtime error Gc with BitmapData

This will explode...

var leak:BitmapData = new BitmapData(1,1);
Gc.doNotKill(leak); //boom

This will also explode...

var leak:BitmapData;

somewhereElse {
leak = new BitmapData(1,1);
Gc.doNotKill(leak);
leak = null;//boom
}

===== Try it =====
git clone [email protected]:thomasuster/limeGCError.git
cd limeGCError
lime test cpp

minor bug: assigning variable named NAN with Math.NaN fails compilation

package ;
class Main {
    static function main() {
        var NAN:Float = Math.NaN;
        trace(NAN);
    }
}

build fails with the following error:
g++ -Iobj/linux//__pch/haxe -Iinclude -c -fvisibility=hidden -O2 -fpic -fPIC -DHX_LINUX -DHXCPP_VISIT_ALLOCS -DHXCPP_API_LEVEL=0 -m32 -I/usr/lib/haxe/lib/hxcpp/3,1,37/include -x c++ -frtti ./src/Main.cpp -oobj/linux/ae7b103b_Main.o
Error: ./src/Main.cpp: In static member function ‘static Void Main_obj::main()’:
./src/Main.cpp:33: error: lvalue required as left operand of assignment
Error: Build failed

Regexp library does not have UTF8 support compiled in

It looks like this bug from here (http://code.google.com/p/hxcpp/issues/detail?id=246) was either missed during moving the repository or was created after the latest HXCPP release.

Since (https://github.com/HaxeFoundation/hxcpp/blob/master/runtime/BuildLibs.xml) still misses the line to compile UTF8 support in, I'll create an issue here.

Somewhere near line 39 of BuildLibs.xml there should be this to have UTF8 support in regular expressions.

<compilerflag value="-DSUPPORT_UTF8"/>

<flag value="-stdlib=libstdc++" unless="HXCPP_GCC" /> breaks on Lion

please revert or find alternative for change

d0fc29b#diff-15e66de6f57c543a27161a3adbc163ab

Since on Lion for atleast two users it breaks compile, it results in the following compile error.

cc1plus: error: unrecognized command line option "-stdlib=libstdc++"

If I comment out line 15 in mac-toolchain.xml eg:
flag value="-stdlib=libstdc++" unless="HXCPP_GCC"
( see googlecode submitted bug for clarity )

code will now compile this was verified by another user who following my instruction and was able to use the c++ target.

The user with problems suggested we could look at Travis for mac to avoid these regression issues, but the link only seems to have 10.8.

http://docs.travis-ci.com/user/osx-ci-environment/

But maybe we can run over how travis works at wwx and I can do tests on each new hxcpp release if that is possible I have not read up on what exactly Travis is just seem to hear a lot about it.

( just reported on googlecode as well but just realized that repository is probably dead now http://code.google.com/p/hxcpp/issues/detail?id=268 )

Compilation error

https://travis-ci.org/HaxeFoundation/haxe/jobs/21505329#L782

Error: ./../../thirdparty/zlib-1.2.3/adler32.c:57:23: error: ‘uLong adler32’ redeclared as different kind of symbol
./../../thirdparty/zlib-1.2.3/zlib.h:1260:23: error: previous declaration of ‘uLong adler32(uLong, const Bytef*, uInt)’
./../../thirdparty/zlib-1.2.3/adler32.c:57:23: error: ‘adler’ was not declared in this scope
./../../thirdparty/zlib-1.2.3/adler32.c:57:30: error: ‘buf’ was not declared in this scope
./../../thirdparty/zlib-1.2.3/adler32.c:57:35: error: ‘len’ was not declared in this scope
./../../thirdparty/zlib-1.2.3/adler32.c:61:1: error: expected unqualified-id before ‘{’ token

Should the C++ debugger be integrated into this library?

First, I apologize for using GitHub issues to raise a discussion, but I figured this should happen openly, and that perhaps this is the best place to do it. I'm addressing some of the differences in hxlibc and hxcpp.

HXCPP cannot use the debugger code with Haxe 3.0, only because a couple small things are not emitted by the generated C++ source. With a couple minor adjustments, it can be used with the release version of Haxe 3. I was wondering if there should be a HAXE or Haxe version define, or some other method, of making it so that HXCPP can have conditional code based on the Haxe version, in order to preserve backward compatibility for features like these?

Also, the Haxe-based code for running the HXCPP debugger, may be interesting to include in the same library. This could be under a "cpp" directory, so including the "hxcpp" haxelib could give access to using this debugger. Perhaps this goes against the grain of the way core Haxe elements work right now, where this would be located in "haxe" proper, but I thought this was specific to HXCPP, can be updated more often than Haxe updates are released, and may be valuable.

Interested in your feelings about this, thanks!

Sys.time() returning 0

It has been confirmed by two other persons by just tracing Sys.time() on the smallest snippet.

Windows
Haxe 3.1.0
hxcpp 3.1.21/3.1.22

Works on hxcpp 3.0.2

Call chains with objects that implement Dynamic...

I believe that the following code should be able to work in HXCPP. It doesn't...
Pretend the classes below have proper resolve functions...

(whose resolve of "b" returns a B)
public class A implements Dynamic
{}

public class B implements Dynamic
{}

Now if I have code that does:
var a : A;
a.b.c()

This turns into:
a->resolve("b")->_Field("c")
Which won't work because c isn't a field on B -- B implements Dynamic...

Ideally it would do this:
a->resolve("b")->resolve("c")

Although I'm fine with making it so that __Field returns a resolve_dyn if it didn't match any field on the object (or some such logic). It will be slower, but at least it won't null function pointer.
I can do this change in gencpp pretty easily, but it will wipe out the call to super._Field if the object implements Dynamic... So I think it will work if its an object that implements Dynamic, but maybe not an interface...

Weak references to class functions being prematurely garbage collected

Hello,

We are seeing weak references to class functions being garbage collected even when the containing class still exists.

To give some context to this issue, we are using nme's EventDispatcher class, whose addEventListener method accepts a "useWeakReference" parameter, where specifying true causes EventDispatcher to keep a WeakRef of the listener function.

In the case of hxcpp, when passing a reference to a function as a parameter, the WeakRef is applied to an intermediate function wrapper object, not the containing class. Since there may be no other "hard" references to the intermediate function object, it is free to be garbage collected, even though the containing class may still exist.

As a result, it appears that no weakly-referenced listeners given to nme.events.EventDispatcher get called back after a garbage collection run, even though the class instance containing the function still exists.

I figure the best way to demonstrate this is with a sample program. When I run this, I see the following output...

TestWeakRefOfFunction.hx:38: Some class function called
TestWeakRefOfFunction.hx:64: mListener is null!

...where we would hope that someClassFunction would be called twice in a row.

Thanks,
Paul Schlegel

import nme.utils.WeakRef;
import nme.system.System;

class TestWeakRefOfFunction
{
    static function main()
    {
        var ed : EventDispatcher = new EventDispatcher();
        var sc : SomeClass = new SomeClass(ed);

        // "Some class function called" is printed.
        ed.dispatchEvent();

        var usedMemory : Array<String> = [];
        for (i in 0...1024)
        {
            usedMemory.push("USE SOME MEMORY");
        }

        System.gc();

        // "mListener is null!" is printed.
        // Even though sc is still in scope and exists, the reference to its
        // someClassFunction was garbage collected.
        ed.dispatchEvent();
    }
}

class SomeClass
{
    public function new(ed : EventDispatcher)
    {
        ed.addEventListener(someClassFunction);
    }

    public function someClassFunction()
    {
        trace("Some class function called");
    }
}

class EventDispatcher
{
    var mListener : WeakRef<Void -> Void>;

    public function new()
    {
    }

    public function addEventListener(listener : Void -> Void)
    {
        mListener = new WeakRef<Void -> Void>(listener);
    }

    public function dispatchEvent()
    {
        if (mListener.get() != null)
        {
            var listener : Void -> Void = mListener.get();
            listener();
        }
        else
        {
            trace("mListener is null!");
        }
    }
}

Windows problem with class paths that have spaces

C:\GitHub\haxe>haxe -main Test -cpp cpp -cp "C:\Program Files\Haxe"
haxelib run hxcpp Build.xml haxe -Dhaxe3="1" -Dhaxe_ver="3.103" -Dhxcpp_api_level="311" -IC:\\Program Files\\Haxe/ -IC:\\GitHub\\haxe\\extraLibs/ -I -IC:\\GitHu
b\\haxe\\std/cpp/_std/ -IC:\\GitHub\\haxe\\std/
Error: Could not find build target "Files\\Haxe/"
Error: Build failed

This affects all users who have Haxe installed in a path with spaces because extraLibs is part of the class path by default.

dynamic field lookup where direct call should be possible (when using function constraints)

take a look at this code:

class Test {

    public static function bar <M:Foo1>(m:M)
    {
        // this creates the following c++ code, although cpp knows that M is of type Foo1
        // m->__Field(HX_CSTRING("doIt"),true)()->__Field(HX_CSTRING("doIt"),true)();
        m.doIt().doIt();
    }
    public static function main () {
        bar(new Foo2());
    }
}

class Foo2 implements Foo1 {
    public function new () {}
    public function doIt():Foo2 {
        return this;
    }
}

interface Foo1 {
    public function doIt():Foo1;
}

cffi methods crash on @:functionCode in dynamically linked platforms.

Here is a simple test file:

@:headerCode("
#include <hx/CFFI.h>
")


class Tester
{
    public function new() {}

    @:functionCode('

        ///CRASH
        value a = alloc_int(1);
    ') 
    public function testMethod() { }

}

class Test {
        static function main() {
            trace("Hello World !");

            var tester = new Tester();
            tester.testMethod();
        }
}

Why does this crash on the alloc_int part? I get a segmentation fault. I noticed that when it is statically linked, like ios, it doesn't crash.

If this has no solution, maybe you can help me another way. What I'm trying to do somewhere else is to get a c pointer which was sent into haxe through "alloc_abstract" via cpp inlining.

Example code:

private var nativedata_createNativeData = Lib.load ("nativedata", "nativedata_createNativeData", 0);

private var nativeData : Dynamic;
@:functionCode("
    nativeData = nativedata_createNativeData();
            value nativeDataValue = nativedata.GetPtr();

             /// crashes on dynamically linked platforms
            NativeData* ptr = (NativeData *)val_data(nativeDataValue);
") 
private function doNativeStuff() : Void {}

Is there any way to achieve this?

Thanks!!!

Looks like cpp.vm.Gc.enable(false) does not actually do anything

As far as I can tell the only thing it does is setting the sgInternalEnable internal variable. This variable is also set to true in SetTopOfStack(). But I don't see any place in code where it is actually being checked.

After some checking in code history it looks like the 2.09 release had a function called CheckCollect() which did check for sgInternalEnable value. In 2.10 it disappeared. If that is intended then it's probably better to remove the enable() call from the Haxe class and documentation.

Full file path in debugger

Can you print absolute path in debugger stack trace output.
It's important when using openfl, for example.
in stack trace i haxe lines like "123 line in flash/Lib.hx", but there are few Lib.hx files (one in haxe std lib, one in openf, one in openfl-native) and openfl-native not even in class path.

Setting different fields of anonymous object from separate threads

The following example while technically does not have any racing conditions, produces segfault in HXCPP on Linux 64-bit. It works fine in Neko environment.

#if neko
import neko.vm.Thread;
#elseif cpp
import cpp.vm.Thread;
#end


class Test
{
  var anon: { v1: Int, v2: Int };

  public function new()
    {
      anon = { v1: 0, v2: 0 };
      var t1 = Thread.create(t1run);
      var t2 = Thread.create(t2run);
    }

  function t1run()
    {
      while (true)
          anon.v1++;
    }

  function t2run()
    {
      while (true)
          anon.v2++;
    }

  public static function main()
    {
      var t = new Test();
      while (true)
    Sys.sleep(1);
    }
}

Running it through GDB shows that the segfault is in one of the lines in RBTree implementation (I'm using the latest git version currently, switched over from using 3.0.2 because of another bug):

0x0000000000477aa6 in RBTree<String, Dynamic>::Insert (this=0x7ffff7ee5a44, inKey=..., inValue=...) at /home/maxless/svn/hxcpp/src/hx/RedBlack.h:159
159       root->red = 0;
0x0000000000477a35 in RBTree<String, Dynamic>::Insert (this=0x7ffff7ee5a44, inKey=..., inValue=...) at /home/maxless/svn/hxcpp/src/hx/RedBlack.h:155
155         root = tmp_head->link[1];

Changing anon object into a full new class is a workaround that I've found.

Now I understand what happens here - each anon object only has a one RBTree of fields and the implementation is not thread-safe. That code is probably considered a bad practice but it should work nonetheless. Or at least it should be documented somewhere.

cpp.vm.Lock wait() call eats up cpu cycles hard on Linux

The following code does not use any cpu when ran in neko mode, but uses 100% of a single core in sys when compiled and ran as a native application in Linux.

class Test
{
  public function new()
    {}

  public static function main()
    {
#if neko
      var lock = new neko.vm.Lock();
#elseif cpp
      var lock = new cpp.vm.Lock();
#end
      while (true)
        lock.wait(1);
    }
}

Comparing object to integer zero

Comparing object to a numeric zero equals to true in case of HXCPP. The same thing produces false in Neko target.

class Test
{
  public function new()
    {}


  public static function main()
    {
      var o: Dynamic = { test: 1 };
      trace(o == 0);
    }
}

On Neko:

Test.hx:10: false

On c++:

Test.hx:10: true

C++ version can be traced to the following lines in Object.h:

   virtual int __ToInt() const { return 0; }
   virtual double __ToDouble() const { return 0.0; } // this one but the one above is probably used for something

IMHO it's better to have the same code produce the same result in both Neko and HXCPP. Maybe this can be changed to return a NaN? Or to produce an exception?

[Mac] Crash with threads handling?

A rare crash. Application died with this message on command line:

NameOfApp(3139,0x138299000) malloc: *** error for object 0x101e43260: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug

Here is the full crash report, if that is of any help:

Crashed Thread: 6

Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000

Application Specific Information:
abort() called
*** error for object 0x101e43260: incorrect checksum for freed object - object was probably modified after being freed.

Thread 0:: Dispatch queue: com.apple.main-thread
0 libsystem_kernel.dylib 0x00007fff8ecd1716 __psynch_cvwait + 10
1 libsystem_pthread.dylib 0x00007fff89569c3b _pthread_cond_wait + 727
2 com.puzzl.yummycircus 0x000000010034baf5 0x100000000 + 3455733
3 com.puzzl.yummycircus 0x000000010034c05a 0x100000000 + 3457114
4 com.puzzl.yummycircus 0x000000010035aa56 0x100000000 + 3517014
5 com.puzzl.yummycircus 0x00000001003470b1 0x100000000 + 3436721
6 com.puzzl.yummycircus 0x0000000100351f87 0x100000000 + 3481479
7 com.puzzl.yummycircus 0x00000001000672e9 0x100000000 + 422633
8 com.puzzl.yummycircus 0x00000001000bcd59 0x100000000 + 773465
9 com.puzzl.yummycircus 0x00000001000c18f0 0x100000000 + 792816
10 com.puzzl.yummycircus 0x00000001000c0bb6 0x100000000 + 789430
11 com.puzzl.yummycircus 0x00000001000c0bf0 0x100000000 + 789488
12 com.puzzl.yummycircus 0x000000010035f713 0x100000000 + 3536659
13 com.puzzl.yummycircus 0x00000001003479c6 0x100000000 + 3439046
14 lime.ndll 0x00000001010417bc 0x101000000 + 268220
15 lime.ndll 0x000000010102d0ee 0x101000000 + 184558
16 lime.ndll 0x00000001011535f3 0x101000000 + 1390067
17 lime.ndll 0x0000000101153451 0x101000000 + 1389649
18 lime.ndll 0x00000001010413a7 0x101000000 + 267175
19 com.puzzl.yummycircus 0x0000000100351efe 0x100000000 + 3481342
20 com.puzzl.yummycircus 0x000000010035b8de 0x100000000 + 3520734
21 com.puzzl.yummycircus 0x00000001003380ac 0x100000000 + 3375276
22 com.puzzl.yummycircus 0x00000001003446ce 0x100000000 + 3425998
23 com.puzzl.yummycircus 0x0000000100345c0c 0x100000000 + 3431436
24 com.puzzl.yummycircus 0x00000001000011c4 start + 52

Thread 1:: Dispatch queue: com.apple.libdispatch-manager
0 libsystem_kernel.dylib 0x00007fff8ecd2662 kevent64 + 10
1 libdispatch.dylib 0x00007fff8eca443d _dispatch_mgr_invoke + 239
2 libdispatch.dylib 0x00007fff8eca4152 _dispatch_mgr_thread + 52

Thread 2:
0 libsystem_kernel.dylib 0x00007fff8eccda1a mach_msg_trap + 10
1 libsystem_kernel.dylib 0x00007fff8ecccd18 mach_msg + 64
2 com.apple.CoreFoundation 0x00007fff92cc4fc5 __CFRunLoopServiceMachPort + 181
3 com.apple.CoreFoundation 0x00007fff92cc45e9 __CFRunLoopRun + 1161
4 com.apple.CoreFoundation 0x00007fff92cc3f25 CFRunLoopRunSpecific + 309
5 com.apple.AppKit 0x00007fff8d2f216e _NSEventThread + 144
6 libsystem_pthread.dylib 0x00007fff89567899 _pthread_body + 138
7 libsystem_pthread.dylib 0x00007fff8956772a _pthread_start + 137
8 libsystem_pthread.dylib 0x00007fff8956bfc9 thread_start + 13

Thread 3:: SDLTimer
0 libsystem_kernel.dylib 0x00007fff8ecd1716 __psynch_cvwait + 10
1 libsystem_pthread.dylib 0x00007fff89569c3b _pthread_cond_wait + 727
2 lime.ndll 0x00000001012750be SDL_CondWaitTimeout + 158
3 lime.ndll 0x0000000101275390 SDL_SemWaitTimeout + 80
4 lime.ndll 0x0000000101230e24 0x101000000 + 2297380
5 lime.ndll 0x0000000101230ab0 SDL_RunThread + 64
6 lime.ndll 0x0000000101274c99 0x101000000 + 2575513
7 libsystem_pthread.dylib 0x00007fff89567899 _pthread_body + 138
8 libsystem_pthread.dylib 0x00007fff8956772a _pthread_start + 137
9 libsystem_pthread.dylib 0x00007fff8956bfc9 thread_start + 13

Thread 4:: com.apple.audio.IOThread.client
0 libsystem_kernel.dylib 0x00007fff8eccda1a mach_msg_trap + 10
1 libsystem_kernel.dylib 0x00007fff8ecccd18 mach_msg + 64
2 com.apple.audio.CoreAudio 0x00007fff90831918 HALB_MachPort::SendMessageWithReply(unsigned int, unsigned int, unsigned int, unsigned int, mach_msg_header_t_, bool, unsigned int) + 98
3 com.apple.audio.CoreAudio 0x00007fff908318a6 HALB_MachPort::SendSimpleMessageWithSimpleReply(unsigned int, unsigned int, int, int&, bool, unsigned int) + 42
4 com.apple.audio.CoreAudio 0x00007fff9083002e HALC_ProxyIOContext::IOWorkLoop() + 950
5 com.apple.audio.CoreAudio 0x00007fff9082fbcd HALC_ProxyIOContext::IOThreadEntry(void_) + 97
6 com.apple.audio.CoreAudio 0x00007fff9082fa8d HALB_IOThread::Entry(void*) + 75
7 libsystem_pthread.dylib 0x00007fff89567899 _pthread_body + 138
8 libsystem_pthread.dylib 0x00007fff8956772a _pthread_start + 137
9 libsystem_pthread.dylib 0x00007fff8956bfc9 thread_start + 13

Thread 5:
0 libsystem_kernel.dylib 0x00007fff8ecd1716 __psynch_cvwait + 10
1 libsystem_pthread.dylib 0x00007fff89569c3b _pthread_cond_wait + 727
2 com.puzzl.yummycircus 0x000000010034baf5 0x100000000 + 3455733
3 com.puzzl.yummycircus 0x000000010034c05a 0x100000000 + 3457114
4 com.puzzl.yummycircus 0x000000010035aa56 0x100000000 + 3517014
5 com.puzzl.yummycircus 0x0000000100340d11 0x100000000 + 3411217
6 com.puzzl.yummycircus 0x000000010009145d 0x100000000 + 595037
7 com.puzzl.yummycircus 0x000000010035f7ec 0x100000000 + 3536876
8 com.puzzl.yummycircus 0x00000001003559d3 0x100000000 + 3496403
9 libsystem_pthread.dylib 0x00007fff89567899 _pthread_body + 138
10 libsystem_pthread.dylib 0x00007fff8956772a _pthread_start + 137
11 libsystem_pthread.dylib 0x00007fff8956bfc9 thread_start + 13

Thread 6 Crashed:
0 libsystem_kernel.dylib 0x00007fff8ecd1866 __pthread_kill + 10
1 libsystem_pthread.dylib 0x00007fff8956835c pthread_kill + 92
2 libsystem_c.dylib 0x00007fff877b0b1a abort + 125
3 libsystem_malloc.dylib 0x00007fff9341d690 szone_error + 587
4 libsystem_malloc.dylib 0x00007fff9341f19c tiny_free_list_remove_ptr + 294
5 libsystem_malloc.dylib 0x00007fff9341b127 szone_free_definite_size + 1877
6 com.puzzl.yummycircus 0x000000010034db08 0x100000000 + 3463944
7 com.puzzl.yummycircus 0x000000010034dafc 0x100000000 + 3463932
8 com.puzzl.yummycircus 0x000000010034dafc 0x100000000 + 3463932
9 com.puzzl.yummycircus 0x000000010034dafc 0x100000000 + 3463932
10 com.puzzl.yummycircus 0x000000010034dafc 0x100000000 + 3463932
11 com.puzzl.yummycircus 0x000000010034c4c2 0x100000000 + 3458242
12 com.puzzl.yummycircus 0x000000010034e3e2 0x100000000 + 3466210
13 com.puzzl.yummycircus 0x000000010034e339 0x100000000 + 3466041
14 com.puzzl.yummycircus 0x000000010034c1d9 0x100000000 + 3457497
15 com.puzzl.yummycircus 0x000000010034b694 0x100000000 + 3454612
16 com.puzzl.yummycircus 0x0000000100356f0a 0x100000000 + 3501834
17 com.puzzl.yummycircus 0x00000001001c3b6a 0x100000000 + 1850218
18 com.puzzl.yummycircus 0x00000001001c2481 0x100000000 + 1844353
19 com.puzzl.yummycircus 0x00000001001c2fb5 0x100000000 + 1847221
20 com.puzzl.yummycircus 0x000000010035f933 0x100000000 + 3537203
21 com.puzzl.yummycircus 0x00000001003559d3 0x100000000 + 3496403
22 libsystem_pthread.dylib 0x00007fff89567899 _pthread_body + 138
23 libsystem_pthread.dylib 0x00007fff8956772a _pthread_start + 137
24 libsystem_pthread.dylib 0x00007fff8956bfc9 thread_start + 13

Thread 6 crashed with X86 Thread State (64-bit):
rax: 0x0000000000000000 rbx: 0x0000000138299000 rcx: 0x00000001382984b8 rdx: 0x0000000000000000
rdi: 0x0000000000012bd3 rsi: 0x0000000000000006 rbp: 0x00000001382984e0 rsp: 0x00000001382984b8
r8: 0x0000000000000010 r9: 0x00000000fffffff0 r10: 0x0000000008000000 r11: 0x0000000000000206
r12: 0x00000001004a0000 r13: 0x00000001013eb000 r14: 0x0000000000000006 r15: 0x0000000000000000
rip: 0x00007fff8ecd1866 rfl: 0x0000000000000206 cr2: 0x00000001013fb000

Logical CPU: 0
Error Code: 0x02000148
Trap Number: 133

Thank you for your attention.

Windows 64bit ndll

I'm trying to compile a Windows 64bit ndll using the hxcpp build tool, but it gave me this error:

PS C:\HaxeToolkit\haxe\lib\hxudp\git\project> haxelib run hxcpp .\build.xml -DHXCPP_M64

C:\HaxeToolkit\haxe\lib\hxudp\git\project>setlocal enabledelayedexpansion
"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\"
The specified configuration type is missing.  The tools for the
configuration might not be installed.
Called from sys.io.Process::$statics line 1
Called from BuildTool::main line 2080
Called from BuildTool::$init line 916
Called from BuildTool::new line 965
Called from BuildTool::parseXML line 1127
Called from BuildTool::parseXML line 1127
Called from BuildTool::parseXML line 1079
Called from Setup::setup line 227
Called from Setup::setupMSVC line 394
Uncaught exception - Could not automatically setup MSVC

I can however compile a 32bit ndll without problem.
I'm using haxe 3.1.0, hxcpp 3.1.21 on Windows 8.1 64bit. Have Express 2013 for Windows Desktop installed.

[MotionTwin] Weird null() code generation...

package;
class Main
{
static function main() { new Main(); }

function new() {
    var v = Main.frand();
}

inline public static function frand(?rnd:Void->Float):Float
{
    return
        if ( rnd == null )
            Math.random();
        else
            rnd();
}

}

Error:
Error: ./src/Main.cpp:24:7: error: type 'null' does not provide a call operator
v = null()().Cast< Float >();
^~~~~~
./src/Main.cpp:24:22: error: unexpected type name 'Float': expected expression
v = null()().Cast< Float >();
^
./src/Main.cpp:24:30: error: expected expression
v = null()().Cast< Float >();

[MotionTwin] NativeArray::memcmp issue

Hi,

I'm experimenting the following error.
I saw a very recent change about that (yesterday), any idea of what is going on ?

Error: ./src/cpp/NativeArray.cpp: In member function 'virtual Dynamic cpp::NativeArray_obj::__Field(const String&, bool)':
./src/cpp/NativeArray.cpp:112: error: no matching function for call to 'cpp::NativeArray_obj::memcmp(const HX_CHAR* const&, const char [5], unsigned int)'

Thanks
Thomas

cpp.Int64/UInt64 issues

var i : cpp.Int64 = 1;
trace( i ); // Error because Dynamic.cpp doesn't define the appropriate constructor -- can't box Int64?
i = i << 33; // Error because gencpp casts both operands to an `int`

@:functionCode does not work in haxe inline methods

Here's a simple test file:

class Printer
{
    public function new() {}

    @:functionCode('
        printf("something inline!\\n");
    ') 
    public inline function printSomethingInline() { }

    @:functionCode('
        printf("something not inline!\\n");
    ') 
    public function printSomethingNotInline() { }
}
class Test {
    static function main() {
        trace("Hello World !");

        var printer = new Printer();
        printer.printSomethingInline();
        printer.printSomethingNotInline();
    }
}

It will not print anything on the inline method.

I think this is probably a known issue as from what I understand the haxe code generation for the inline method happens before the inlining of the c++, still I couldn't find any documentation on it...

accessing undefined property in a Dynamic class via "this" generates incorrect and/or broken cpp code

Greetings. The following Haxe code generates incorrect and/or broken cpp:

class Test implements Dynamic
{
    public function new() { }
    public function resolve(d:Dynamic):Dynamic { return "resolved " + d; }
    public function foo1() { return this.bar; } // OK
    public function foo2() { this.bar = 1; } // XXX
    public function foo3() { var obj:Test = this; obj.bar = 1; } // XXX
    public static function main() { var t = new Test(); }
}

foo() above generates return this->resolve(HX_CSTRING("bar")); which is expected ; however foo2() generates this->bar = (int)1; which fails to compile the native cpp code. foo3() generates obj->__FieldRef(HX_CSTRING("bar")) = (int)1; which is not correct either - I would expect the resolve() as in foo1.

Inconsistent inline behaviour. Can cause Null Object Reference

If you compile the minimal test case below with the latest hxcpp library released in haxelib and with Haxe 3.0.1 and Haxe 3.1.1 the results are different (note that the variable root.right isn't initialized):

  • The expected result in both:
Main.hx:37: Check1 false
Main.hx:39: Check2 false
Main.hx:43: Both false
  • In Haxe 3.0.1 the result is:
Main.hx:37: Check1 false
Main.hx:39: Check2 false
Main.hx:43: Both false
  • In Haxe 3.1.1 the result is:
Called from Main::main::Main.hx::36
Critical Error: Null Object Reference

The problem when compiling with Haxe 3.1.1 is that it creates the following code:

bool _g;        HX_STACK_VAR(_g,"_g");
HX_STACK_LINE(36)
{
   HX_STACK_LINE(36)
   ::Node _this = root->right;      HX_STACK_VAR(_this,"_this");
   HX_STACK_LINE(36)
   _g = (bool((_this->obj->w == (int)0)) && bool((_this->obj->h == (int)0)));
}
HX_STACK_LINE(36)
bool check1;        HX_STACK_VAR(check1,"check1");
struct _Function_1_1{
   inline static bool Block( ::Root &root){
      HX_STACK_FRAME("*","closure",0x5bdab937,"*.closure","Main.hx",36,0x087e5c05)
      {
         HX_STACK_LINE(36)
         ::Node _this = root->left;     HX_STACK_VAR(_this,"_this");
         HX_STACK_LINE(36)
         return (bool((_this->obj->w == (int)0)) && bool((_this->obj->h == (int)0)));
      }
      return null();
   }
};
HX_STACK_LINE(36)
check1 = (bool((bool((root->right != null())) && bool(_g))) && bool(((bool((root->left != null())) && bool(_Function_1_1::Block(root))))));

The var _g isn't checking that root->right is null and, as far as I can tell, it should be creating a struct _Function_x_x for that check as it does for root->left

You will note that, if check1 in the minimal test case is commented out, the program will work, but it will create the same _g variable for root->left in check2.

Also, if you comment out both check1 and check2, the created code uses struct _Function_x_x for both inlines.

In Haxe 3.0.1 it does and works as expected.

Minimal test case:

class Obj {
    public var w:Float;
    public var h:Float;
    public function new(w:Float = 0, h:Float = 0) {
        this.w = w;
        this.h = h;
    }
}

class Node {
    public var obj:Obj;

    public function new() { }

    public inline function canPlace(w:Float, h:Float):Bool {
        return (obj.w == w && obj.h == h);
    }
}


class Root {
    public var left:Node;
    public var right:Node;

    public function new() {}
}

class Main {

    static function main() {
        var root:Root = new Root();
        root.left = new Node();
        root.left.obj = new Obj();
        var check1:Bool = (root.right != null && root.right.canPlace(0, 0)) && (root.left != null && root.left.canPlace(0, 0));
        trace("Check1 " + check1);
        var check2:Bool = (root.left != null && root.left.canPlace(0, 0)) && (root.right != null && root.right.canPlace(0, 0));
        trace("Check2 " + check2);
        var right:Bool = (root.right != null && root.right.canPlace(0, 0));
        var left:Bool = (root.left != null && root.left.canPlace(0, 0));
        var both:Bool = right && left;
        trace("Both " + both);
    }

}

Lock release() synchronization

Hi there

I am not sure if this is a bug or I'm just to unaware of how Locks work/common problems with multi-threading are, but having the following code:

import cpp.vm.Lock;

class Runner
{
    public static function main():Void
    {
        var lock = new Lock();

        cpp.vm.Thread.create(function():Void {
            lock.wait();
            trace("Unlocked 1st thread");
        });
        cpp.vm.Thread.create(function():Void {
            lock.wait();
            trace("Unlocked 2nd thread");
        });

        Sys.sleep(1);

        lock.release();
        // Sys.sleep(1); // works with this
        lock.release();

        Sys.sleep(1);
    }
}

only the first Thread is unlocked. As you can see, putting a timeout in between the two release() solves the problem.

Is this "normal" (e.g. never assumable that such inter-thread operations work 1:1 as expected..because of delay etc.) or really a bug?

Thanks,
Michel

Problem with automatic type casting of anonymous object fields

When I define an anonymous object with an array field and then mistakenly cast it later as a list, I receive a "null" pointer in new variable without any errors.

class Test
{
  public function new()
    {}


  public static function main()
    {
      var arr = [ 1, 2, 3 ]; // array
      var a: Dynamic = { test: 1, l: arr };
      var l: List<Dynamic> = a.l; // bug: casting as list
      trace(l);
    }
}

This code produces this result in neko:

Test.hx:12: [1,2,3]

and in hxcpp:

Test.hx:12: null

I understand that this is my mistake - casting an array as a list. But I didn't receive any meaningful errors during runtime even in debug mode and just making it null feels wrong. I'm not sure if you can do anything with that but that is pretty confusing for someone who didn't stumble on this before. Maybe there is a way to make that cast show some "type casting wrong" error?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.