Skip to content

Commit b8b6205

Browse files
[GR-27881] Backport: Improving the handling of termination exceptions.
PullRequest: js/1798
2 parents 26e7865 + 00769f5 commit b8b6205

File tree

5 files changed

+60
-8
lines changed

5 files changed

+60
-8
lines changed

graal-nodejs/deps/v8/src/graal/graal_isolate.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,8 +1243,9 @@ void GraalIsolate::CancelTerminateExecution() {
12431243
jvm_->AttachCurrentThread((void**) &env, nullptr);
12441244
} else {
12451245
env = current_isolate->GetJNIEnv();
1246-
// The following line breaks test-vm-timeout-rethrow
1247-
// env->ExceptionClear(); // Clear potential KillException
1246+
if (current_isolate == this) {
1247+
env->ExceptionClear(); // Clear potential termination exception in this thread
1248+
}
12481249
}
12491250
jmethodID method_id = GetJNIMethod(GraalAccessMethod::isolate_cancel_terminate_execution);
12501251
env->functions->CallVoidMethod(env, access_, method_id);

graal-nodejs/deps/v8/src/graal/v8.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -937,9 +937,9 @@ namespace v8 {
937937
TryCatch::~TryCatch() {
938938
GraalIsolate* graal_isolate = reinterpret_cast<GraalIsolate*> (isolate_);
939939
graal_isolate->TryCatchExit();
940-
if (!rethrow_ && HasCaught()) {
940+
if (!rethrow_ && HasCaught() && !HasTerminated()) {
941941
JNIEnv* env = graal_isolate->GetJNIEnv();
942-
if (is_verbose_ && !HasTerminated()) {
942+
if (is_verbose_) {
943943
jthrowable java_exception = env->ExceptionOccurred();
944944
Local<Value> exception = Exception();
945945
Local<v8::Message> message = Message();

graal-nodejs/test/graal/unit/spawn.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ describe('Spawn', function () {
9595
it('should print help when ' + option + ' option is used', function () {
9696
var result = spawnSync(process.execPath, [option]);
9797
assert.strictEqual(result.status, 0);
98-
assert.match(result.stdout.toString(), /^\n?Usage:/);
98+
assert.match(result.stdout.toString(), /Options:/);
9999
});
100100
});
101101
if (typeof java === 'object') {

graal-nodejs/test/graal/unit/try_catch.cc

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,42 @@ EXPORT_TO_JS(HasCaughtNestedBoth) {
130130

131131
EXPORT_TO_JS(HasTerminatedNoException) {
132132
TryCatch tryCatch(args.GetIsolate());
133-
//bool result = tryCatch.HasTerminated(); //TODO
134-
bool result = false;
133+
bool result = tryCatch.HasTerminated();
134+
args.GetReturnValue().Set(result);
135+
}
136+
137+
EXPORT_TO_JS(HasTerminatedNestedOuter) {
138+
Isolate* isolate = args.GetIsolate();
139+
bool result = true;
140+
TryCatch tryCatch(isolate);
141+
result &= !tryCatch.HasTerminated();
142+
TryCatch_InvokeCallback(args);
143+
result &= tryCatch.HasTerminated();
144+
isolate->CancelTerminateExecution();
145+
result &= !tryCatch.HasTerminated();
146+
args.GetReturnValue().Set(result);
147+
}
148+
149+
EXPORT_TO_JS(HasTerminatedNestedInner) {
150+
Isolate* isolate = args.GetIsolate();
151+
// The following TryCatch looks unused but we are testing
152+
// that it does not swallow the termination exception
153+
TryCatch tryCatch(isolate);
154+
isolate->TerminateExecution();
155+
TryCatch_InvokeCallback(args);
156+
}
157+
158+
EXPORT_TO_JS(HasTerminatedBasic) {
159+
Isolate* isolate = args.GetIsolate();
160+
bool result = true;
161+
TryCatch tryCatch(isolate);
162+
result &= !tryCatch.HasTerminated();
163+
isolate->TerminateExecution();
164+
result &= !tryCatch.HasTerminated();
165+
TryCatch_InvokeCallback(args);
166+
result &= tryCatch.HasTerminated();
167+
isolate->CancelTerminateExecution();
168+
result &= !tryCatch.HasTerminated();
135169
args.GetReturnValue().Set(result);
136170
}
137171

graal-nodejs/test/graal/unit/try_catch.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,26 @@ describe('TryCatch', function () {
121121
});
122122
});
123123
describe('HasTerminated', function () {
124-
it('should be callable', function () {
124+
it('should return false when the execution is not terminated', function () {
125125
assert.strictEqual(module.TryCatch_HasTerminatedNoException(), false);
126126
});
127+
it('should return true when the execution is terminated', function () {
128+
assert.strictEqual(module.TryCatch_HasTerminatedBasic(function() {
129+
while (true); // This loop should be terminated
130+
}), true);
131+
});
132+
it('should return true when the termination was not cancelled by innner TryCatch', function () {
133+
var skipped = true;
134+
assert.strictEqual(module.TryCatch_HasTerminatedNestedOuter(function() {
135+
module.TryCatch_HasTerminatedNestedInner(function() {
136+
while (true); // This loop should be terminated
137+
});
138+
// This code should be skipped
139+
skipped = false;
140+
assert.fail();
141+
}), true);
142+
assert.ok(skipped);
143+
});
127144
});
128145
describe('Fatal Error', function () {
129146
it('should not be triggered when an error is thrown from a promise job (part 1)', function (done) {

0 commit comments

Comments
 (0)