File: Active.cpp

package info (click to toggle)
storm-lang 0.7.4-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 52,004 kB
  • sloc: ansic: 261,462; cpp: 140,405; sh: 14,891; perl: 9,846; python: 2,525; lisp: 2,504; asm: 860; makefile: 678; pascal: 70; java: 52; xml: 37; awk: 12
file content (131 lines) | stat: -rw-r--r-- 3,430 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include "stdafx.h"
#include "Util.h"
#include "Compiler/Debug.h"

BEGIN_TEST(ActiveBasic, Reload) {
	// Check basic reloading of active functions:
	Package *reload = gEngine().package(S("tests.reload"));

	const char contents[] =
		"Nat activeBasic(Nat times) {\n"
		"  Nat sum = beforeItem();\n"
		"  for (Nat i = 0; i < times; i++) {\n"
		"    sum *= 10;\n"
		"    sum += nextItem();\n"
		"  }\n"
		"  sum += afterItem();\n"
		"  return sum;\n"
		"}\n"
		"\n"
		"Nat nextItem() {\n"
		"  yield();\n"
		"  5;\n"
		"}\n"
		"\n"
		"Nat beforeItem() { 5; }\n"
		"\n"
		"Nat afterItem() { 10000; }\n";

	// Note: This both verifies that the original code is run, but also that it is compiled before
	// we start. If it is not compiled, it invalidates our timing-based assumptions.
	CHECK_EQ(runFn<Nat>(S("tests.reload.activeBasic"), Nat(4)), 9);

	os::Future<Nat> result;
	spawnFn(result, S("tests.reload.activeBasic"), Nat(4));

	// Let the function run until its first 'yield':
	os::UThread::leave();

	// Replace everything:
	reloadFile(reload, S("active_basic.bs"), contents);

	// Now, let it run to completion and see what we get!
	// Note: Without replacing active functions, we should get 10017, with it we should get 2555.
	CHECK_EQ(result.result(), 15555);

} END_TEST


BEGIN_TEST(ActiveException, Reload) {
	// Check so that we can throw exceptions through an updated function:
	Package *reload = gEngine().package(S("tests.reload"));

	const char contents[] =
		"use core:debug;\n"
		"\n"
		"Int activeException() {\n"
		"  DbgVal val(10);\n"
		"  exceptionHelper();\n"
		"  val.v;\n"
		"}\n"
		"\n"
		"void exceptionHelper() {\n"
		"  yield();\n"
		"  throw NotSupported(\"test\");\n"
		"}\n";

	debug::DbgVal::clear();
	CHECK_ERROR(runFn<Int>(S("tests.reload.activeException")), NotSupported);
	CHECK(debug::DbgVal::clear());

	os::Future<Int> result;
	spawnFn(result, S("tests.reload.activeException"));

	os::UThread::leave();

	// Replace!
	reloadFile(reload, S("active_exception.bs"), contents);

	// Make sure that it still throws, that the exception is propagated properly, and that we can clean up as expected.
	CHECK_ERROR(result.result(), NotSupported);
	CHECK(debug::DbgVal::clear());

} END_TEST


BEGIN_TEST(ActiveNewVars, Reload) {
	// Check so that we can re-shuffle the stack frame of a function.
	Package *reload = gEngine().package(S("tests.reload"));

	const char contents[] =
		"use core:debug;\n"
		"\n"
		"Nat activeNewVars(Nat max) {\n"
		"  Nat result = 0;\n"
		"  Nat times = 0;\n"
		"  DbgVal val(0);\n"
		"  while (result < max) {\n"
		"    Nat v = newVarsNext();\n"
		"    result += v;\n"
		"    if (++times >= 4)\n"
		"      break;\n"
		"  }\n"
		"  result;\n"
		"}\n"
		"\n"
		"Nat newVarsNext() {\n"
		"  yield();\n"
		"  10;\n"
		"}\n";

	debug::DbgVal::clear();
	CHECK_EQ(runFn<Nat>(S("tests.reload.activeNewVars"), Nat(100)), 100);
	CHECK(debug::DbgVal::clear());

	os::Future<Nat> result;
	spawnFn(result, S("tests.reload.activeNewVars"), Nat(100));

	// Let it run for a bit, so that we see a difference from just starting the function from zero.
	for (Nat i = 0; i < 2; i++)
		os::UThread::leave();

	reloadFile(reload, S("active_newvars.bs"), contents);

	CHECK_EQ(result.result(), 50);
	CHECK(debug::DbgVal::clear());

	// Running it from scratch should give zero.
	CHECK_EQ(runFn<Nat>(S("tests.reload.activeNewVars"), Nat(100)), 40);
	CHECK(debug::DbgVal::clear());

} END_TEST