aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/cases/emptystruct.ll2
-rw-r--r--tests/cases/muli33.ll114
-rw-r--r--tests/cases/muli33.txt1
-rw-r--r--tests/cases/oob_ta2.ll25
-rw-r--r--tests/cases/philoop.ll305
-rw-r--r--tests/cases/philoop.txt1
-rw-r--r--tests/embind/build_benchmark2
-rw-r--r--tests/embind/embind.benchmark.js35
-rw-r--r--tests/embind/embind.test.js153
-rw-r--r--tests/embind/embind_benchmark.cpp71
-rw-r--r--tests/embind/embind_test.cpp65
-rw-r--r--tests/linpack.c1153
-rwxr-xr-xtests/runner.py492
-rw-r--r--tests/sdl_audio.c4
-rw-r--r--tests/time/src.c5
-rw-r--r--tests/websockets.c2
16 files changed, 2399 insertions, 31 deletions
diff --git a/tests/cases/emptystruct.ll b/tests/cases/emptystruct.ll
index 67967e65..ecf0e295 100644
--- a/tests/cases/emptystruct.ll
+++ b/tests/cases/emptystruct.ll
@@ -6,6 +6,8 @@ target triple = "i386-pc-linux-gnu"
@.str = private constant [14 x i8] c"hello, world!\00", align 1 ; [#uses=1]
+@.waka = extern_weak global i8* ; no initializer!
+
define i32 @main() nounwind {
entry:
%z = alloca %struct.s, align 4
diff --git a/tests/cases/muli33.ll b/tests/cases/muli33.ll
new file mode 100644
index 00000000..b33b04f7
--- /dev/null
+++ b/tests/cases/muli33.ll
@@ -0,0 +1,114 @@
+; ModuleID = '/tmp/tmpt0JpDh/a.out.bc'
+target datalayout = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-p:32:32:32-v128:32:32"
+target triple = "le32-unknown-nacl"
+
+@.str = private unnamed_addr constant [7 x i8] c"20\0A91\0A\00", align 1
+@.str1 = private unnamed_addr constant [6 x i8] c"%u %u\00", align 1
+@.str2 = private unnamed_addr constant [10 x i8] c"res = %u\0A\00", align 1
+
+define i32 @main() nounwind {
+ %j = alloca i32, align 4
+ %k4 = alloca i32, align 4
+ %t = alloca [100 x [100 x i32]], align 4
+ store i32 20, i32* %j, align 4
+ store i32 91, i32* %k4, align 4
+ br label %.lr.ph.i
+
+.lr.ph.i: ; preds = %.lr.ph.i, %0
+ %j.07.i = phi i32 [ %7, %.lr.ph.i ], [ 0, %0 ]
+ %1 = and i32 %j.07.i, 1
+ %2 = icmp eq i32 %1, 0
+ %3 = sub i32 0, %j.07.i
+ %.p.i = select i1 %2, i32 %j.07.i, i32 %3
+ %4 = add i32 %.p.i, 8
+ %5 = urem i32 %4, 101
+ %6 = getelementptr inbounds [100 x [100 x i32]]* %t, i32 0, i32 0, i32 %j.07.i
+ store i32 %5, i32* %6, align 4
+ %7 = add i32 %j.07.i, 1
+ %8 = icmp ult i32 %7, 10000
+ br i1 %8, label %.lr.ph.i, label %init.exit
+
+init.exit: ; preds = %.lr.ph.i
+ %9 = call i32 (i8*, i8*, ...)* @sscanf(i8* getelementptr inbounds ([7 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8]* @.str1, i32 0, i32 0), i32* %j, i32* %k4) nounwind
+ store i32 53, i32* %j, align 4
+ br label %.preheader
+
+.preheader: ; preds = %29, %init.exit
+ %indvars.iv23 = phi i32 [ -29, %init.exit ], [ %indvars.iv.next24, %29 ]
+ %indvars.iv21 = phi i32 [ -28, %init.exit ], [ %indvars.iv.next22, %29 ]
+ %indvars.iv19 = phi i32 [ -27, %init.exit ], [ %indvars.iv.next20, %29 ]
+ %indvars.iv17 = phi i32 [ 109, %init.exit ], [ %indvars.iv.next18, %29 ]
+ %indvars.iv15 = phi i32 [ -75923, %init.exit ], [ %indvars.iv.next16, %29 ]
+ %indvars.iv13 = phi i32 [ 5593, %init.exit ], [ %indvars.iv.next14, %29 ]
+ %indvars.iv = phi i32 [ -262, %init.exit ], [ %indvars.iv.next, %29 ]
+ %10 = phi i32 [ 53, %init.exit ], [ %.pre-phi, %29 ]
+ %11 = zext i32 %indvars.iv19 to i33
+ %12 = zext i32 %indvars.iv21 to i33
+ %13 = mul i33 %11, %12
+ %14 = icmp ult i32 %10, 27
+ br i1 %14, label %.lr.ph, label %.preheader._crit_edge
+
+.preheader._crit_edge: ; preds = %.preheader
+ %.pre = add i32 %10, -1
+ br label %29
+
+.lr.ph: ; preds = %.preheader
+ %15 = zext i32 %indvars.iv23 to i33
+ %16 = mul i33 %13, %15
+ %17 = lshr i33 %16, 1
+ %18 = lshr i33 %13, 1
+ %19 = trunc i33 %17 to i32
+ %20 = trunc i33 %18 to i32
+ %21 = mul i32 %19, 1431655766
+ %22 = mul i32 %indvars.iv17, %20
+ %23 = add i32 %10, -1
+ %24 = add i32 %10, 1
+ %25 = getelementptr inbounds [100 x [100 x i32]]* %t, i32 0, i32 %24, i32 %23
+ %.promoted = load i32* %25, align 4
+ %26 = add i32 %.promoted, %indvars.iv15
+ %27 = add i32 %26, %22
+ %28 = add i32 %27, %21
+ store i32 %28, i32* %25, align 4
+ br label %29
+
+.lr.ph.i3.preheader: ; preds = %29
+ store i32 2, i32* %j, align 4
+ store i32 %.lcssa69, i32* %k4, align 4
+ br label %.lr.ph.i3
+
+; <label>:29 ; preds = %.lr.ph, %.preheader._crit_edge
+ %.pre-phi = phi i32 [ %.pre, %.preheader._crit_edge ], [ %23, %.lr.ph ]
+ %.lcssa69 = phi i32 [ %10, %.preheader._crit_edge ], [ 27, %.lr.ph ]
+ %30 = icmp ugt i32 %.pre-phi, 2
+ %indvars.iv.next = add i32 %indvars.iv, 6
+ %indvars.iv.next14 = add i32 %indvars.iv13, %indvars.iv
+ %indvars.iv.next16 = add i32 %indvars.iv15, %indvars.iv13
+ %indvars.iv.next18 = add i32 %indvars.iv17, -2
+ %indvars.iv.next20 = add i32 %indvars.iv19, 1
+ %indvars.iv.next22 = add i32 %indvars.iv21, 1
+ %indvars.iv.next24 = add i32 %indvars.iv23, 1
+ br i1 %30, label %.preheader, label %.lr.ph.i3.preheader
+
+.lr.ph.i3: ; preds = %.lr.ph.i3, %.lr.ph.i3.preheader
+ %sum.07.i = phi i32 [ %37, %.lr.ph.i3 ], [ 0, %.lr.ph.i3.preheader ]
+ %j.06.i = phi i32 [ %38, %.lr.ph.i3 ], [ 0, %.lr.ph.i3.preheader ]
+ %31 = and i32 %j.06.i, 1
+ %32 = icmp eq i32 %31, 0
+ %33 = getelementptr inbounds [100 x [100 x i32]]* %t, i32 0, i32 0, i32 %j.06.i
+ %34 = load i32* %33, align 4
+ %35 = sub i32 0, %34
+ %36 = select i1 %32, i32 %34, i32 %35
+ %37 = add i32 %36, %sum.07.i
+ %38 = add i32 %j.06.i, 1
+ %39 = icmp ult i32 %38, 10000
+ br i1 %39, label %.lr.ph.i3, label %checkSum.exit
+
+checkSum.exit: ; preds = %.lr.ph.i3
+ %40 = add i32 %37, 2
+ %41 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str2, i32 0, i32 0), i32 %40) nounwind
+ ret i32 0
+}
+
+declare i32 @sscanf(i8* nocapture, i8* nocapture, ...) nounwind
+
+declare i32 @printf(i8* nocapture, ...) nounwind
diff --git a/tests/cases/muli33.txt b/tests/cases/muli33.txt
new file mode 100644
index 00000000..21e0231f
--- /dev/null
+++ b/tests/cases/muli33.txt
@@ -0,0 +1 @@
+res = 3164
diff --git a/tests/cases/oob_ta2.ll b/tests/cases/oob_ta2.ll
new file mode 100644
index 00000000..3c94c13c
--- /dev/null
+++ b/tests/cases/oob_ta2.ll
@@ -0,0 +1,25 @@
+; ModuleID = 'tests/hello_world.bc'
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128"
+target triple = "i386-pc-linux-gnu"
+
+%structy = type { [2 x [10 x i8]] }
+
+@.str1 = private unnamed_addr constant [10 x i8] c"1234567890", align 1
+@.str2 = private unnamed_addr constant [10 x i8] c"wakawaka\0A\00", align 1
+@.stry = private unnamed_addr constant [2 x %structy] { %structy { [10 x i8] @.str1, [10 x i8] @.str2 }, %structy { [10 x i8] @.str1, [10 x i8] @.str2 } }
+
+@.str = private unnamed_addr constant [15 x i8] c"hello, world!\0A\00", align 1 ; [#uses=1 type=[15 x i8]*]
+
+; [#uses=0]
+define i32 @main(i32 %argc, i8** %argv) {
+entry:
+ %retval = alloca i32, align 4 ; [#uses=1 type=i32*]
+ store i32 0, i32* %retval
+ %ind = add i32 %argc, 13
+ %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([2 x %structy]* @.stry, i32 0, i32 2, i32 0, i32 %ind))
+ %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str, i32 0, i32 0)) ; [#uses=0 type=i32]
+ ret i32 1 ret i32 1
+}
+
+; [#uses=1]
+declare i32 @printf(i8*, ...)
diff --git a/tests/cases/philoop.ll b/tests/cases/philoop.ll
new file mode 100644
index 00000000..5036c7ba
--- /dev/null
+++ b/tests/cases/philoop.ll
@@ -0,0 +1,305 @@
+; ModuleID = '/tmp/tmpVIBz29/a.out.bc'
+target datalayout = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-p:32:32:32-v128:32:32"
+target triple = "le32-unknown-nacl"
+
+@.str = private unnamed_addr constant [13 x i8] c"99\0A70\0A26\0A97\0A\00", align 1
+@.str1 = private unnamed_addr constant [12 x i8] c"%u %u %u %u\00", align 1
+@.str2 = private unnamed_addr constant [10 x i8] c"res = %u\0A\00", align 1
+
+define i32 @main() nounwind {
+ %jp0 = alloca i32, align 4
+ %i1 = alloca i32, align 4
+ %jq3 = alloca i32, align 4
+ %i = alloca i32, align 4
+ %cq = alloca [100 x i32], align 4
+ %ye = alloca [100 x i32], align 4
+ %g = alloca [100 x i32], align 4
+ %z = alloca [100 x i32], align 4
+ %za = alloca [100 x [100 x i32]], align 4
+ %a0 = alloca [100 x i32], align 4
+ store i32 99, i32* %jp0, align 4
+ store i32 70, i32* %i1, align 4
+ store i32 26, i32* %jq3, align 4
+ store i32 97, i32* %i, align 4
+ br label %.lr.ph.i
+
+.lr.ph.i: ; preds = %.lr.ph.i, %0
+ %j.07.i = phi i32 [ %7, %.lr.ph.i ], [ 0, %0 ]
+ %1 = and i32 %j.07.i, 1
+ %2 = icmp eq i32 %1, 0
+ %3 = sub i32 0, %j.07.i
+ %.p.i = select i1 %2, i32 %j.07.i, i32 %3
+ %4 = add i32 %.p.i, 2
+ %5 = urem i32 %4, 101
+ %6 = getelementptr inbounds [100 x i32]* %cq, i32 0, i32 %j.07.i
+ store i32 %5, i32* %6, align 4
+ %7 = add i32 %j.07.i, 1
+ %8 = icmp ult i32 %7, 100
+ br i1 %8, label %.lr.ph.i, label %.lr.ph.i44.preheader
+
+.lr.ph.i44.preheader: ; preds = %.lr.ph.i
+ %9 = getelementptr inbounds [100 x i32]* %a0, i32 0, i32 0
+ br label %.lr.ph.i44
+
+.lr.ph.i44: ; preds = %.lr.ph.i44, %.lr.ph.i44.preheader
+ %j.07.i42 = phi i32 [ %16, %.lr.ph.i44 ], [ 0, %.lr.ph.i44.preheader ]
+ %10 = and i32 %j.07.i42, 1
+ %11 = icmp eq i32 %10, 0
+ %12 = sub i32 0, %j.07.i42
+ %.p.i43 = select i1 %11, i32 %j.07.i42, i32 %12
+ %13 = add i32 %.p.i43, 90
+ %14 = urem i32 %13, 101
+ %15 = getelementptr inbounds [100 x i32]* %ye, i32 0, i32 %j.07.i42
+ store i32 %14, i32* %15, align 4
+ %16 = add i32 %j.07.i42, 1
+ %17 = icmp ult i32 %16, 100
+ br i1 %17, label %.lr.ph.i44, label %.lr.ph.i40
+
+.lr.ph.i40: ; preds = %.lr.ph.i40, %.lr.ph.i44
+ %j.07.i38 = phi i32 [ %24, %.lr.ph.i40 ], [ 0, %.lr.ph.i44 ]
+ %18 = and i32 %j.07.i38, 1
+ %19 = icmp eq i32 %18, 0
+ %20 = sub i32 0, %j.07.i38
+ %.p.i39 = select i1 %19, i32 %j.07.i38, i32 %20
+ %21 = add i32 %.p.i39, 73
+ %22 = urem i32 %21, 101
+ %23 = getelementptr inbounds [100 x i32]* %g, i32 0, i32 %j.07.i38
+ store i32 %22, i32* %23, align 4
+ %24 = add i32 %j.07.i38, 1
+ %25 = icmp ult i32 %24, 100
+ br i1 %25, label %.lr.ph.i40, label %.lr.ph.i36
+
+.lr.ph.i36: ; preds = %.lr.ph.i36, %.lr.ph.i40
+ %j.07.i34 = phi i32 [ %32, %.lr.ph.i36 ], [ 0, %.lr.ph.i40 ]
+ %26 = and i32 %j.07.i34, 1
+ %27 = icmp eq i32 %26, 0
+ %28 = sub i32 0, %j.07.i34
+ %.p.i35 = select i1 %27, i32 %j.07.i34, i32 %28
+ %29 = add i32 %.p.i35, 54
+ %30 = urem i32 %29, 101
+ %31 = getelementptr inbounds [100 x i32]* %z, i32 0, i32 %j.07.i34
+ store i32 %30, i32* %31, align 4
+ %32 = add i32 %j.07.i34, 1
+ %33 = icmp ult i32 %32, 100
+ br i1 %33, label %.lr.ph.i36, label %.lr.ph.i32
+
+.lr.ph.i32: ; preds = %.lr.ph.i32, %.lr.ph.i36
+ %j.07.i30 = phi i32 [ %40, %.lr.ph.i32 ], [ 0, %.lr.ph.i36 ]
+ %34 = and i32 %j.07.i30, 1
+ %35 = icmp eq i32 %34, 0
+ %36 = sub i32 0, %j.07.i30
+ %.p.i31 = select i1 %35, i32 %j.07.i30, i32 %36
+ %37 = add i32 %.p.i31, 66
+ %38 = urem i32 %37, 101
+ %39 = getelementptr inbounds [100 x [100 x i32]]* %za, i32 0, i32 0, i32 %j.07.i30
+ store i32 %38, i32* %39, align 4
+ %40 = add i32 %j.07.i30, 1
+ %41 = icmp ult i32 %40, 10000
+ br i1 %41, label %.lr.ph.i32, label %.lr.ph.i28
+
+.lr.ph.i28: ; preds = %.lr.ph.i28, %.lr.ph.i32
+ %j.07.i26 = phi i32 [ %48, %.lr.ph.i28 ], [ 0, %.lr.ph.i32 ]
+ %42 = and i32 %j.07.i26, 1
+ %43 = icmp eq i32 %42, 0
+ %44 = sub i32 0, %j.07.i26
+ %.p.i27 = select i1 %43, i32 %j.07.i26, i32 %44
+ %45 = add i32 %.p.i27, 71
+ %46 = urem i32 %45, 101
+ %47 = getelementptr inbounds [100 x i32]* %a0, i32 0, i32 %j.07.i26
+ store i32 %46, i32* %47, align 4
+ %48 = add i32 %j.07.i26, 1
+ %49 = icmp ult i32 %48, 100
+ br i1 %49, label %.lr.ph.i28, label %init.exit29
+
+init.exit29: ; preds = %.lr.ph.i28
+ %50 = call i32 (i8*, i8*, ...)* @sscanf(i8* getelementptr inbounds ([13 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([12 x i8]* @.str1, i32 0, i32 0), i32* %jp0, i32* %i1, i32* %jq3, i32* %i) nounwind
+ %51 = getelementptr inbounds [100 x i32]* %cq, i32 0, i32 46
+ %52 = load i32* %51, align 4
+ %53 = getelementptr inbounds [100 x i32]* %cq, i32 0, i32 20
+ %54 = load i32* %53, align 4
+ %55 = icmp ult i32 %52, %54
+ br i1 %55, label %.preheader61, label %56
+
+; <label>:56 ; preds = %init.exit29
+ %57 = load i32* %9, align 4
+ %58 = getelementptr inbounds [100 x i32]* %ye, i32 0, i32 24
+ %59 = load i32* %58, align 4
+ %60 = sub i32 %59, %57
+ store i32 %60, i32* %58, align 4
+ br label %.preheader61
+
+.preheader61: ; preds = %56, %init.exit29
+ store i32 2, i32* %jp0, align 4
+ %.phi.trans.insert = getelementptr inbounds [100 x i32]* %cq, i32 0, i32 1
+ %.pre = load i32* %.phi.trans.insert, align 4
+ br label %61
+
+.preheader58: ; preds = %61
+ store i32 80, i32* %jp0, align 4
+ store i32 94, i32* %i1, align 4
+ br label %76
+
+; <label>:61 ; preds = %61, %.preheader61
+ %62 = phi i32 [ %.pre, %.preheader61 ], [ %66, %61 ]
+ %63 = phi i32 [ 2, %.preheader61 ], [ %71, %61 ]
+ %64 = getelementptr inbounds [100 x i32]* %cq, i32 0, i32 %63
+ %65 = load i32* %64, align 4
+ %66 = add i32 %65, -4
+ store i32 %66, i32* %64, align 4
+ %67 = add i32 %63, -1
+ %68 = getelementptr inbounds [100 x i32]* %ye, i32 0, i32 %67
+ %69 = load i32* %68, align 4
+ %70 = mul i32 %62, %69
+ %71 = add i32 %63, 1
+ %72 = getelementptr inbounds [100 x i32]* %g, i32 0, i32 %71
+ %73 = load i32* %72, align 4
+ %74 = sub i32 %73, %70
+ store i32 %74, i32* %72, align 4
+ %75 = icmp ult i32 %71, 80
+ br i1 %75, label %61, label %.preheader58
+
+.preheader55: ; preds = %76
+ store i32 2, i32* %i1, align 4
+ store i32 44, i32* %jq3, align 4
+ br label %.preheader
+
+; <label>:76 ; preds = %76, %.preheader58
+ %77 = phi i32 [ 94, %.preheader58 ], [ %80, %76 ]
+ %78 = getelementptr inbounds [100 x i32]* %ye, i32 0, i32 %77
+ %79 = load i32* %78, align 4
+ %80 = add i32 %77, -1
+ %81 = getelementptr inbounds [100 x i32]* %z, i32 0, i32 %80
+ store i32 %79, i32* %81, align 4
+ %82 = icmp ugt i32 %80, 2
+ br i1 %82, label %76, label %.preheader55
+
+.preheader: ; preds = %95, %.preheader55
+ %83 = phi i32 [ 44, %.preheader55 ], [ %84, %95 ]
+ %84 = add i32 %83, -1
+ %85 = getelementptr inbounds [100 x [100 x i32]]* %za, i32 0, i32 %84, i32 %83
+ %.promoted = load i32* %85, align 4
+ %.pre75 = load i32* %9, align 4
+ %.phi.trans.insert76 = getelementptr inbounds [100 x i32]* %a0, i32 0, i32 1
+ %.pre77 = load i32* %.phi.trans.insert76, align 4
+ br label %86
+
+; <label>:86 ; preds = %86, %.preheader
+ %87 = phi i32 [ %.pre77, %.preheader ], [ %88, %86 ]
+ %88 = phi i32 [ %.pre75, %.preheader ], [ %87, %86 ]
+ %89 = phi i32 [ 1, %.preheader ], [ %92, %86 ]
+ %90 = phi i32 [ %.promoted, %.preheader ], [ %91, %86 ]
+ %91 = mul i32 %90, %87
+ %92 = add i32 %89, 1
+ %93 = getelementptr inbounds [100 x i32]* %a0, i32 0, i32 %92
+ store i32 %88, i32* %93, align 4
+ %94 = icmp ult i32 %92, 46
+ br i1 %94, label %86, label %95
+
+; <label>:95 ; preds = %86
+ store i32 %91, i32* %85, align 4
+ %96 = icmp ugt i32 %84, 1
+ br i1 %96, label %.preheader, label %97
+
+; <label>:97 ; preds = %95
+ store i32 1, i32* %jq3, align 4
+ store i32 46, i32* %i, align 4
+ br label %.lr.ph.i24
+
+.lr.ph.i24: ; preds = %.lr.ph.i24, %97
+ %sum.07.i22 = phi i32 [ %104, %.lr.ph.i24 ], [ 0, %97 ]
+ %j.06.i23 = phi i32 [ %105, %.lr.ph.i24 ], [ 0, %97 ]
+ %98 = and i32 %j.06.i23, 1
+ %99 = icmp eq i32 %98, 0
+ %100 = getelementptr inbounds [100 x i32]* %cq, i32 0, i32 %j.06.i23
+ %101 = load i32* %100, align 4
+ %102 = sub i32 0, %101
+ %103 = select i1 %99, i32 %101, i32 %102
+ %104 = add i32 %103, %sum.07.i22
+ %105 = add i32 %j.06.i23, 1
+ %106 = icmp ult i32 %105, 100
+ br i1 %106, label %.lr.ph.i24, label %.lr.ph.i20
+
+.lr.ph.i20: ; preds = %.lr.ph.i20, %.lr.ph.i24
+ %sum.07.i18 = phi i32 [ %113, %.lr.ph.i20 ], [ 0, %.lr.ph.i24 ]
+ %j.06.i19 = phi i32 [ %114, %.lr.ph.i20 ], [ 0, %.lr.ph.i24 ]
+ %107 = and i32 %j.06.i19, 1
+ %108 = icmp eq i32 %107, 0
+ %109 = getelementptr inbounds [100 x i32]* %ye, i32 0, i32 %j.06.i19
+ %110 = load i32* %109, align 4
+ %111 = sub i32 0, %110
+ %112 = select i1 %108, i32 %110, i32 %111
+ %113 = add i32 %112, %sum.07.i18
+ %114 = add i32 %j.06.i19, 1
+ %115 = icmp ult i32 %114, 100
+ br i1 %115, label %.lr.ph.i20, label %.lr.ph.i16
+
+.lr.ph.i16: ; preds = %.lr.ph.i16, %.lr.ph.i20
+ %sum.07.i14 = phi i32 [ %122, %.lr.ph.i16 ], [ 0, %.lr.ph.i20 ]
+ %j.06.i15 = phi i32 [ %123, %.lr.ph.i16 ], [ 0, %.lr.ph.i20 ]
+ %116 = and i32 %j.06.i15, 1
+ %117 = icmp eq i32 %116, 0
+ %118 = getelementptr inbounds [100 x i32]* %g, i32 0, i32 %j.06.i15
+ %119 = load i32* %118, align 4
+ %120 = sub i32 0, %119
+ %121 = select i1 %117, i32 %119, i32 %120
+ %122 = add i32 %121, %sum.07.i14
+ %123 = add i32 %j.06.i15, 1
+ %124 = icmp ult i32 %123, 100
+ br i1 %124, label %.lr.ph.i16, label %.lr.ph.i12
+
+.lr.ph.i12: ; preds = %.lr.ph.i12, %.lr.ph.i16
+ %sum.07.i10 = phi i32 [ %131, %.lr.ph.i12 ], [ 0, %.lr.ph.i16 ]
+ %j.06.i11 = phi i32 [ %132, %.lr.ph.i12 ], [ 0, %.lr.ph.i16 ]
+ %125 = and i32 %j.06.i11, 1
+ %126 = icmp eq i32 %125, 0
+ %127 = getelementptr inbounds [100 x i32]* %z, i32 0, i32 %j.06.i11
+ %128 = load i32* %127, align 4
+ %129 = sub i32 0, %128
+ %130 = select i1 %126, i32 %128, i32 %129
+ %131 = add i32 %130, %sum.07.i10
+ %132 = add i32 %j.06.i11, 1
+ %133 = icmp ult i32 %132, 100
+ br i1 %133, label %.lr.ph.i12, label %.lr.ph.i8
+
+.lr.ph.i8: ; preds = %.lr.ph.i8, %.lr.ph.i12
+ %sum.07.i6 = phi i32 [ %140, %.lr.ph.i8 ], [ 0, %.lr.ph.i12 ]
+ %j.06.i7 = phi i32 [ %141, %.lr.ph.i8 ], [ 0, %.lr.ph.i12 ]
+ %134 = and i32 %j.06.i7, 1
+ %135 = icmp eq i32 %134, 0
+ %136 = getelementptr inbounds [100 x [100 x i32]]* %za, i32 0, i32 0, i32 %j.06.i7
+ %137 = load i32* %136, align 4
+ %138 = sub i32 0, %137
+ %139 = select i1 %135, i32 %137, i32 %138
+ %140 = add i32 %139, %sum.07.i6
+ %141 = add i32 %j.06.i7, 1
+ %142 = icmp ult i32 %141, 10000
+ br i1 %142, label %.lr.ph.i8, label %.lr.ph.i5
+
+.lr.ph.i5: ; preds = %.lr.ph.i5, %.lr.ph.i8
+ %sum.07.i = phi i32 [ %149, %.lr.ph.i5 ], [ 0, %.lr.ph.i8 ]
+ %j.06.i = phi i32 [ %150, %.lr.ph.i5 ], [ 0, %.lr.ph.i8 ]
+ %143 = and i32 %j.06.i, 1
+ %144 = icmp eq i32 %143, 0
+ %145 = getelementptr inbounds [100 x i32]* %a0, i32 0, i32 %j.06.i
+ %146 = load i32* %145, align 4
+ %147 = sub i32 0, %146
+ %148 = select i1 %144, i32 %146, i32 %147
+ %149 = add i32 %148, %sum.07.i
+ %150 = add i32 %j.06.i, 1
+ %151 = icmp ult i32 %150, 100
+ br i1 %151, label %.lr.ph.i5, label %checkSum.exit
+
+checkSum.exit: ; preds = %.lr.ph.i5
+ %152 = add i32 %104, 82
+ %153 = add i32 %152, %113
+ %154 = sub i32 %153, %122
+ %155 = add i32 %154, %131
+ %156 = sub i32 %155, %140
+ %157 = add i32 %156, %149
+ %158 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str2, i32 0, i32 0), i32 %157) nounwind
+ ret i32 0
+}
+
+declare i32 @sscanf(i8* nocapture, i8* nocapture, ...) nounwind
+
+declare i32 @printf(i8* nocapture, ...) nounwind
diff --git a/tests/cases/philoop.txt b/tests/cases/philoop.txt
new file mode 100644
index 00000000..d5117fe8
--- /dev/null
+++ b/tests/cases/philoop.txt
@@ -0,0 +1 @@
+res = 1962923669
diff --git a/tests/embind/build_benchmark b/tests/embind/build_benchmark
index 6faad18b..3d5d816b 100644
--- a/tests/embind/build_benchmark
+++ b/tests/embind/build_benchmark
@@ -1,2 +1,2 @@
#!/bin/bash
-EMCC_LLVM_TARGET=le32-unknown-nacl ~/projects/emscripten/emcc --minify 0 --bind --post-js embind.benchmark.js -O2 --shell-file shell.html -o embind_benchmark.html embind_benchmark.cpp
+EMCC_LLVM_TARGET=le32-unknown-nacl ../../emcc --minify 0 --bind --post-js embind.benchmark.js -O2 --shell-file shell.html -o embind_benchmark.html embind_benchmark.cpp
diff --git a/tests/embind/embind.benchmark.js b/tests/embind/embind.benchmark.js
index 7b20db88..3669bc28 100644
--- a/tests/embind/embind.benchmark.js
+++ b/tests/embind/embind.benchmark.js
@@ -248,3 +248,38 @@ function _call_through_interface1() {
Module.print("C++ -> JS std::wstring through interface " + N + " iters: " + elapsed + " msecs.");
obj.delete();
}
+
+function _call_through_interface2() {
+ var N = 1000000;
+ var total = 0;
+ var obj = Module['Interface'].implement({
+ call_with_typed_array: function(ta) {
+ total += ta.length;
+ },
+ call_with_memory_view: function(ta) {
+ total += ta.length;
+ },
+ });
+
+ var start = _emscripten_get_now();
+ Module['callInterface2'](N, obj);
+ var elapsed = _emscripten_get_now() - start;
+ Module.print("C++ -> JS typed array instantiation " + N + " iters: " + elapsed + " msecs.");
+
+ var start = _emscripten_get_now();
+ Module['callInterface3'](N, obj);
+ var elapsed = _emscripten_get_now() - start;
+ Module.print("C++ -> JS memory_view instantiation" + N + " iters: " + elapsed + " msecs.");
+ obj.delete();
+}
+
+function _returns_val_benchmark() {
+ var N = 1000000;
+ var v = 1;
+ var start = _emscripten_get_now();
+ for(var i = 0; i < N; ++i) {
+ v = Module['returns_val'](v);
+ }
+ var elapsed = _emscripten_get_now() - start;
+ Module.print("returns_val " + N + " iters: " + elapsed + " msecs");
+}
diff --git a/tests/embind/embind.test.js b/tests/embind/embind.test.js
index 52b2cad8..e60e1ab3 100644
--- a/tests/embind/embind.test.js
+++ b/tests/embind/embind.test.js
@@ -5,6 +5,8 @@ module({
var CheckForLeaks = fixture("check for leaks", function() {
this.setUp(function() {
+ cm.setDelayFunction(undefined);
+
if (typeof INVOKED_FROM_EMSCRIPTEN_TEST_RUNNER === "undefined") { // TODO: Enable this to work in Emscripten runner as well!
cm._mallocDebug(2);
assert.equal(0, cm.count_emval_handles());
@@ -12,6 +14,7 @@ module({
}
});
this.tearDown(function() {
+ cm.flushPendingDeletes();
if (typeof INVOKED_FROM_EMSCRIPTEN_TEST_RUNNER === "undefined") { // TODO: Enable this to work in Emscripten runner as well!
cm._mallocAssertAllMemoryFree();
assert.equal(0, cm.count_emval_handles());
@@ -490,6 +493,15 @@ module({
assert.equal(true, cm.emval_test_not(false));
});
+ test("can pass booleans as integers", function() {
+ assert.equal(1, cm.emval_test_as_unsigned(true));
+ assert.equal(0, cm.emval_test_as_unsigned(false));
+ });
+
+ test("can pass booleans as floats", function() {
+ assert.equal(2, cm.const_ref_adder(true, true));
+ });
+
test("convert double to unsigned", function() {
var rv = cm.emval_test_as_unsigned(1.5);
assert.equal('number', typeof rv);
@@ -672,6 +684,15 @@ module({
c.delete();
});
+ test("access multiple smart ptr ctors", function() {
+ var a = new cm.MultipleSmartCtors(10);
+ assert.equal(a.WhichCtorCalled(), 1);
+ var b = new cm.MultipleCtors(20, 20);
+ assert.equal(b.WhichCtorCalled(), 2);
+ a.delete();
+ b.delete();
+ });
+
test("wrong number of constructor arguments throws", function() {
assert.throws(cm.BindingError, function() { new cm.MultipleCtors(); });
assert.throws(cm.BindingError, function() { new cm.MultipleCtors(1,2,3,4); });
@@ -1559,6 +1580,28 @@ module({
impl.delete();
});
+ test("returning null shared pointer from interfaces implemented in JS code does not leak", function() {
+ var impl = cm.AbstractClass.implement({
+ returnsSharedPtr: function() {
+ return null;
+ }
+ });
+ cm.callReturnsSharedPtrMethod(impl);
+ impl.delete();
+ // Let the memory leak test superfixture check that no leaks occurred.
+ });
+
+ test("returning a new shared pointer from interfaces implemented in JS code does not leak", function() {
+ var impl = cm.AbstractClass.implement({
+ returnsSharedPtr: function() {
+ return cm.embind_test_return_smart_derived_ptr();
+ }
+ });
+ cm.callReturnsSharedPtrMethod(impl);
+ impl.delete();
+ // Let the memory leak test superfixture check that no leaks occurred.
+ });
+
test("void methods work", function() {
var saved = {};
var impl = cm.AbstractClass.implement({
@@ -1728,6 +1771,116 @@ module({
e.delete();
f.delete();
});
+
+ BaseFixture.extend("memory view", function() {
+ test("can pass memory view from C++ to JS", function() {
+ var views = [];
+ cm.callWithMemoryView(function(view) {
+ views.push(view);
+ });
+ assert.equal(3, views.length);
+
+ assert.instanceof(views[0], Uint8Array);
+ assert.equal(8, views[0].length);
+ assert.deepEqual([0, 1, 2, 3, 4, 5, 6, 7], [].slice.call(new Uint8Array(views[0])));
+
+ assert.instanceof(views[1], Float32Array);
+ assert.equal(4, views[1].length);
+ assert.deepEqual([1.5, 2.5, 3.5, 4.5], [].slice.call(views[1]));
+
+ assert.instanceof(views[2], Int16Array);
+ assert.equal(4, views[2].length);
+ assert.deepEqual([1000, 100, 10, 1], [].slice.call(views[2]));
+ });
+ });
+
+ BaseFixture.extend("delete pool", function() {
+ test("can delete objects later", function() {
+ var v = new cm.ValHolder({});
+ v.deleteLater();
+ assert.deepEqual({}, v.getVal());
+ cm.flushPendingDeletes();
+ assert.throws(cm.BindingError, function() {
+ v.getVal();
+ });
+ });
+
+ test("calling deleteLater twice is an error", function() {
+ var v = new cm.ValHolder({});
+ v.deleteLater();
+ assert.throws(cm.BindingError, function() {
+ v.deleteLater();
+ });
+ });
+
+ test("deleteLater returns the object", function() {
+ var v = (new cm.ValHolder({})).deleteLater();
+ assert.deepEqual({}, v.getVal());
+ });
+
+ test("deleteLater throws if object is already deleted", function() {
+ var v = new cm.ValHolder({});
+ v.delete();
+ assert.throws(cm.BindingError, function() {
+ v.deleteLater();
+ });
+ });
+
+ test("delete throws if object is already scheduled for deletion", function() {
+ var v = new cm.ValHolder({});
+ v.deleteLater();
+ assert.throws(cm.BindingError, function() {
+ v.delete();
+ });
+ });
+
+ test("deleteLater invokes delay function", function() {
+ var runLater;
+ cm.setDelayFunction(function(fn) {
+ runLater = fn;
+ });
+
+ var v = new cm.ValHolder({});
+ assert.false(runLater);
+ v.deleteLater();
+ assert.true(runLater);
+ assert.false(v.isDeleted());
+ runLater();
+ assert.true(v.isDeleted());
+ });
+
+ test("deleteLater twice invokes delay function once", function() {
+ var count = 0;
+ var runLater;
+ cm.setDelayFunction(function(fn) {
+ ++count;
+ runLater = fn;
+ });
+
+ (new cm.ValHolder({})).deleteLater();
+ (new cm.ValHolder({})).deleteLater();
+ assert.equal(1, count);
+ runLater();
+ (new cm.ValHolder({})).deleteLater();
+ assert.equal(2, count);
+ });
+
+ test('The delay function is immediately invoked if the deletion queue is not empty', function() {
+ (new cm.ValHolder({})).deleteLater();
+ var count = 0;
+ cm.setDelayFunction(function(fn) {
+ ++count;
+ });
+ assert.equal(1, count);
+ });
+
+ // The idea is that an interactive application would
+ // periodically flush the deleteLater queue by calling
+ //
+ // setDelayFunction(function(fn) {
+ // setTimeout(fn, 0);
+ // });
+ });
});
/* global run_all_tests */
diff --git a/tests/embind/embind_benchmark.cpp b/tests/embind/embind_benchmark.cpp
index b6a834c9..5ae9a6be 100644
--- a/tests/embind/embind_benchmark.cpp
+++ b/tests/embind/embind_benchmark.cpp
@@ -50,6 +50,14 @@ extern void pass_gameobject_ptr_benchmark_embind_js();
extern void call_through_interface0();
extern void call_through_interface1();
+extern void call_through_interface2();
+
+extern void returns_val_benchmark();
+}
+
+emscripten::val returns_val(emscripten::val value)
+{
+ return emscripten::val(value.as<unsigned>() + 1);
}
class Vec3
@@ -135,19 +143,45 @@ class Interface
public:
virtual void call0() = 0;
virtual std::wstring call1(const std::wstring& str1, const std::wstring& str2) = 0;
+ virtual void call_with_typed_array(size_t size, const void*) = 0;
+ virtual void call_with_memory_view(size_t size, const void*) = 0;
};
+EMSCRIPTEN_SYMBOL(HEAP8);
+EMSCRIPTEN_SYMBOL(buffer);
+
+EMSCRIPTEN_SYMBOL(call0);
+EMSCRIPTEN_SYMBOL(call1);
+EMSCRIPTEN_SYMBOL(call_with_typed_array);
+EMSCRIPTEN_SYMBOL(call_with_memory_view);
+EMSCRIPTEN_SYMBOL(Uint8Array);
+
class InterfaceWrapper : public emscripten::wrapper<Interface>
{
public:
EMSCRIPTEN_WRAPPER(InterfaceWrapper);
void call0() override {
- return call<void>("call0");
+ return call<void>(call0_symbol);
}
std::wstring call1(const std::wstring& str1, const std::wstring& str2) {
- return call<std::wstring>("call1", str1, str2);
+ return call<std::wstring>(call1_symbol, str1, str2);
+ }
+
+ void call_with_typed_array(size_t size, const void* data) {
+ return call<void>(
+ call_with_typed_array_symbol,
+ emscripten::val::global(Uint8Array_symbol).new_(
+ emscripten::val::module_property(HEAP8_symbol)[buffer_symbol],
+ reinterpret_cast<uintptr_t>(data),
+ size));
+ }
+
+ void call_with_memory_view(size_t size, const void* data) {
+ return call<void>(
+ call_with_memory_view_symbol,
+ emscripten::memory_view(size, data));
}
};
@@ -180,6 +214,33 @@ void callInterface1(unsigned N, Interface& o) {
}
}
+void callInterface2(unsigned N, Interface& o) {
+ int i = 0;
+ for (unsigned i = 0; i < N; i += 8) {
+ o.call_with_typed_array(sizeof(int), &i);
+ o.call_with_typed_array(sizeof(int), &i);
+ o.call_with_typed_array(sizeof(int), &i);
+ o.call_with_typed_array(sizeof(int), &i);
+ o.call_with_typed_array(sizeof(int), &i);
+ o.call_with_typed_array(sizeof(int), &i);
+ o.call_with_typed_array(sizeof(int), &i);
+ o.call_with_typed_array(sizeof(int), &i);
+ }
+}
+
+void callInterface3(unsigned N, Interface& o) {
+ for (unsigned i = 0; i < N; i += 8) {
+ o.call_with_memory_view(sizeof(int), &i);
+ o.call_with_memory_view(sizeof(int), &i);
+ o.call_with_memory_view(sizeof(int), &i);
+ o.call_with_memory_view(sizeof(int), &i);
+ o.call_with_memory_view(sizeof(int), &i);
+ o.call_with_memory_view(sizeof(int), &i);
+ o.call_with_memory_view(sizeof(int), &i);
+ o.call_with_memory_view(sizeof(int), &i);
+ }
+}
+
EMSCRIPTEN_BINDINGS(benchmark)
{
using namespace emscripten;
@@ -225,6 +286,10 @@ EMSCRIPTEN_BINDINGS(benchmark)
function("callInterface0", &callInterface0);
fun