1// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#include "vm/allocation.h"
6#include "platform/assert.h"
7#include "vm/longjump.h"
8#include "vm/unit_test.h"
9
10namespace dart {
11
12class TestValueObject : public ValueObject {
13 public:
14 explicit TestValueObject(int* ptr) : ptr_(ptr) {
15 EXPECT_EQ(1, *ptr_);
16 *ptr_ = 2;
17 }
18
19 virtual ~TestValueObject() {
20 EXPECT_EQ(3, *ptr_);
21 *ptr_ = 4;
22 }
23
24 int value() const { return *ptr_; }
25 virtual int GetId() const { return 3; }
26
27 private:
28 int* ptr_;
29};
30
31class TestStackResource : public StackResource {
32 public:
33 explicit TestStackResource(int* ptr)
34 : StackResource(Thread::Current()), ptr_(ptr) {
35 EXPECT_EQ(1, *ptr_);
36 *ptr_ = 2;
37 }
38
39 ~TestStackResource() {
40 EXPECT_EQ(6, *ptr_);
41 *ptr_ = 7;
42 }
43
44 int value() const { return *ptr_; }
45 virtual int GetId() const { return 3; }
46
47 private:
48 int* ptr_;
49};
50
51class TestStackedStackResource : public StackResource {
52 public:
53 explicit TestStackedStackResource(int* ptr)
54 : StackResource(Thread::Current()), ptr_(ptr) {
55 EXPECT_EQ(3, *ptr_);
56 *ptr_ = 4;
57 }
58
59 ~TestStackedStackResource() {
60 EXPECT_EQ(5, *ptr_);
61 *ptr_ = 6;
62 }
63
64 int value() const { return *ptr_; }
65
66 private:
67 int* ptr_;
68};
69
70static void StackAllocatedDestructionHelper(int* ptr) {
71 TestValueObject stacked(ptr);
72 EXPECT_EQ(2, *ptr);
73 *ptr = 3;
74}
75
76ISOLATE_UNIT_TEST_CASE(StackAllocatedDestruction) {
77 int data = 1;
78 StackAllocatedDestructionHelper(&data);
79 EXPECT_EQ(4, data);
80}
81
82static void StackAllocatedLongJumpHelper(int* ptr, LongJumpScope* jump) {
83 TestValueObject stacked(ptr);
84 EXPECT_EQ(2, *ptr);
85 *ptr = 3;
86 const Error& error = Error::Handle(LanguageError::New(
87 String::Handle(String::New("StackAllocatedLongJump"))));
88 jump->Jump(1, error);
89 UNREACHABLE();
90}
91
92ISOLATE_UNIT_TEST_CASE(StackAllocatedLongJump) {
93 LongJumpScope jump;
94 int data = 1;
95 if (setjmp(*jump.Set()) == 0) {
96 StackAllocatedLongJumpHelper(&data, &jump);
97 UNREACHABLE();
98 }
99 EXPECT_EQ(3, data);
100}
101
102static void StackedStackResourceDestructionHelper(int* ptr) {
103 TestStackedStackResource stacked(ptr);
104 EXPECT_EQ(4, *ptr);
105 *ptr = 5;
106}
107
108static void StackResourceDestructionHelper(int* ptr) {
109 TestStackResource stacked(ptr);
110 EXPECT_EQ(2, *ptr);
111 *ptr = 3;
112 StackedStackResourceDestructionHelper(ptr);
113 EXPECT_EQ(6, *ptr);
114 // Do not set data because the LongJump version does not return control here.
115}
116
117ISOLATE_UNIT_TEST_CASE(StackResourceDestruction) {
118 int data = 1;
119 StackResourceDestructionHelper(&data);
120 EXPECT_EQ(7, data);
121}
122
123static void StackedStackResourceLongJumpHelper(int* ptr, LongJumpScope* jump) {
124 TestStackedStackResource stacked(ptr);
125 EXPECT_EQ(4, *ptr);
126 *ptr = 5;
127 const Error& error = Error::Handle(LanguageError::New(
128 String::Handle(String::New("StackedStackResourceLongJump"))));
129 jump->Jump(1, error);
130 UNREACHABLE();
131}
132
133static void StackResourceLongJumpHelper(int* ptr, LongJumpScope* jump) {
134 TestStackResource stacked(ptr);
135 EXPECT_EQ(2, *ptr);
136 *ptr = 3;
137 StackedStackResourceLongJumpHelper(ptr, jump);
138 UNREACHABLE();
139}
140
141ISOLATE_UNIT_TEST_CASE(StackResourceLongJump) {
142 LongJumpScope* base = Thread::Current()->long_jump_base();
143 {
144 LongJumpScope jump;
145 int data = 1;
146 if (setjmp(*jump.Set()) == 0) {
147 StackResourceLongJumpHelper(&data, &jump);
148 UNREACHABLE();
149 }
150 EXPECT_EQ(7, data);
151 }
152 ASSERT(base == Thread::Current()->long_jump_base());
153}
154
155} // namespace dart
156