Skip to content

Commit 16da2af

Browse files
author
Mark Lam
committed
Add missing exception checks and book-keeping for exception check validation.
https://bugs.webkit.org/show_bug.cgi?id=177609 <rdar://problem/34717972> Reviewed by Keith Miller. This resolves exception check validation failures when running test262 tests and a few other tests. * API/APIUtils.h: (handleExceptionIfNeeded): * API/JSObjectRef.cpp: (JSObjectMakeFunction): (JSObjectMakeArray): (JSObjectMakeDate): (JSObjectMakeError): (JSObjectMakeRegExp): (JSObjectSetPrototype): (JSObjectGetProperty): (JSObjectSetProperty): (JSObjectGetPropertyAtIndex): (JSObjectSetPropertyAtIndex): (JSObjectDeleteProperty): (JSObjectCallAsFunction): (JSObjectCallAsConstructor): * API/JSTypedArray.cpp: (JSObjectMakeTypedArray): (JSObjectMakeTypedArrayWithBytesNoCopy): (JSObjectMakeTypedArrayWithArrayBuffer): (JSObjectMakeTypedArrayWithArrayBufferAndOffset): (JSObjectMakeArrayBufferWithBytesNoCopy): * API/JSValueRef.cpp: (JSValueIsEqual): (JSValueIsInstanceOfConstructor): (JSValueCreateJSONString): (JSValueToNumber): (JSValueToStringCopy): (JSValueToObject): * interpreter/Interpreter.cpp: (JSC::Interpreter::executeProgram): * llint/LLIntSlowPaths.cpp: (JSC::LLInt::LLINT_SLOW_PATH_DECL): * runtime/ArrayPrototype.cpp: (JSC::arrayProtoFuncIndexOf): (JSC::arrayProtoFuncLastIndexOf): * runtime/DatePrototype.cpp: (JSC::fillStructuresUsingTimeArgs): (JSC::setNewValueFromDateArgs): (JSC::dateProtoFuncSetYear): * runtime/JSGenericTypedArrayViewConstructorInlines.h: (JSC::constructGenericTypedArrayViewWithArguments): * runtime/JSModuleEnvironment.cpp: (JSC::JSModuleEnvironment::put): * runtime/ProgramExecutable.cpp: (JSC::ProgramExecutable::initializeGlobalProperties): * runtime/ProxyObject.cpp: (JSC::ProxyObject::toStringName): * runtime/StringPrototype.cpp: (JSC::stringProtoFuncCharAt): (JSC::stringProtoFuncCharCodeAt): (JSC::stringProtoFuncIndexOf): (JSC::stringProtoFuncLastIndexOf): (JSC::stringProtoFuncSlice): (JSC::stringProtoFuncSplitFast): (JSC::stringProtoFuncSubstr): Canonical link: https://commits.webkit.org/193902@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@222617 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent ce7a08f commit 16da2af

14 files changed

Lines changed: 182 additions & 48 deletions

‎Source/JavaScriptCore/API/APIUtils.h‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,8 @@ enum class ExceptionStatus {
3737
DidNotThrow
3838
};
3939

40-
inline ExceptionStatus handleExceptionIfNeeded(JSC::ExecState* exec, JSValueRef* returnedExceptionRef)
40+
inline ExceptionStatus handleExceptionIfNeeded(JSC::CatchScope& scope, JSC::ExecState* exec, JSValueRef* returnedExceptionRef)
4141
{
42-
JSC::VM& vm = exec->vm();
43-
auto scope = DECLARE_CATCH_SCOPE(vm);
4442
if (UNLIKELY(scope.exception())) {
4543
JSC::Exception* exception = scope.exception();
4644
if (returnedExceptionRef)

‎Source/JavaScriptCore/API/JSObjectRef.cpp‎

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ JSObjectRef JSObjectMakeFunction(JSContextRef ctx, JSStringRef name, unsigned pa
142142
ExecState* exec = toJS(ctx);
143143
VM& vm = exec->vm();
144144
JSLockHolder locker(vm);
145+
auto scope = DECLARE_CATCH_SCOPE(vm);
145146

146147
startingLineNumber = std::max(1, startingLineNumber);
147148
Identifier nameID = name ? name->identifier(&vm) : Identifier::fromString(exec, "anonymous");
@@ -153,7 +154,7 @@ JSObjectRef JSObjectMakeFunction(JSContextRef ctx, JSStringRef name, unsigned pa
153154

154155
auto sourceURLString = sourceURL ? sourceURL->string() : String();
155156
JSObject* result = constructFunction(exec, exec->lexicalGlobalObject(), args, nameID, SourceOrigin { sourceURLString }, sourceURLString, TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber()));
156-
if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow)
157+
if (handleExceptionIfNeeded(scope, exec, exception) == ExceptionStatus::DidThrow)
157158
result = 0;
158159
return toRef(result);
159160
}
@@ -165,7 +166,9 @@ JSObjectRef JSObjectMakeArray(JSContextRef ctx, size_t argumentCount, const JSVa
165166
return 0;
166167
}
167168
ExecState* exec = toJS(ctx);
168-
JSLockHolder locker(exec);
169+
VM& vm = exec->vm();
170+
JSLockHolder locker(vm);
171+
auto scope = DECLARE_CATCH_SCOPE(vm);
169172

170173
JSObject* result;
171174
if (argumentCount) {
@@ -177,7 +180,7 @@ JSObjectRef JSObjectMakeArray(JSContextRef ctx, size_t argumentCount, const JSVa
177180
} else
178181
result = constructEmptyArray(exec, 0);
179182

180-
if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow)
183+
if (handleExceptionIfNeeded(scope, exec, exception) == ExceptionStatus::DidThrow)
181184
result = 0;
182185

183186
return toRef(result);
@@ -190,14 +193,16 @@ JSObjectRef JSObjectMakeDate(JSContextRef ctx, size_t argumentCount, const JSVal
190193
return 0;
191194
}
192195
ExecState* exec = toJS(ctx);
193-
JSLockHolder locker(exec);
196+
VM& vm = exec->vm();
197+
JSLockHolder locker(vm);
198+
auto scope = DECLARE_CATCH_SCOPE(vm);
194199

195200
MarkedArgumentBuffer argList;
196201
for (size_t i = 0; i < argumentCount; ++i)
197202
argList.append(toJS(exec, arguments[i]));
198203

199204
JSObject* result = constructDate(exec, exec->lexicalGlobalObject(), JSValue(), argList);
200-
if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow)
205+
if (handleExceptionIfNeeded(scope, exec, exception) == ExceptionStatus::DidThrow)
201206
result = 0;
202207

203208
return toRef(result);
@@ -210,13 +215,15 @@ JSObjectRef JSObjectMakeError(JSContextRef ctx, size_t argumentCount, const JSVa
210215
return 0;
211216
}
212217
ExecState* exec = toJS(ctx);
213-
JSLockHolder locker(exec);
218+
VM& vm = exec->vm();
219+
JSLockHolder locker(vm);
220+
auto scope = DECLARE_CATCH_SCOPE(vm);
214221

215222
JSValue message = argumentCount ? toJS(exec, arguments[0]) : jsUndefined();
216223
Structure* errorStructure = exec->lexicalGlobalObject()->errorStructure();
217224
JSObject* result = ErrorInstance::create(exec, errorStructure, message);
218225

219-
if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow)
226+
if (handleExceptionIfNeeded(scope, exec, exception) == ExceptionStatus::DidThrow)
220227
result = 0;
221228

222229
return toRef(result);
@@ -229,14 +236,16 @@ JSObjectRef JSObjectMakeRegExp(JSContextRef ctx, size_t argumentCount, const JSV
229236
return 0;
230237
}
231238
ExecState* exec = toJS(ctx);
232-
JSLockHolder locker(exec);
239+
VM& vm = exec->vm();
240+
JSLockHolder locker(vm);
241+
auto scope = DECLARE_CATCH_SCOPE(vm);
233242

234243
MarkedArgumentBuffer argList;
235244
for (size_t i = 0; i < argumentCount; ++i)
236245
argList.append(toJS(exec, arguments[i]));
237246

238247
JSObject* result = constructRegExp(exec, exec->lexicalGlobalObject(), argList);
239-
if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow)
248+
if (handleExceptionIfNeeded(scope, exec, exception) == ExceptionStatus::DidThrow)
240249
result = 0;
241250

242251
return toRef(result);
@@ -264,11 +273,12 @@ void JSObjectSetPrototype(JSContextRef ctx, JSObjectRef object, JSValueRef value
264273
ExecState* exec = toJS(ctx);
265274
VM& vm = exec->vm();
266275
JSLockHolder locker(vm);
276+
auto scope = DECLARE_CATCH_SCOPE(vm);
267277

268278
JSObject* jsObject = toJS(object);
269279
JSValue jsValue = toJS(exec, value);
270280
jsObject->setPrototype(vm, exec, jsValue.isObject() ? jsValue : jsNull());
271-
handleExceptionIfNeeded(exec, nullptr);
281+
handleExceptionIfNeeded(scope, exec, nullptr);
272282
}
273283

274284
bool JSObjectHasProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName)
@@ -295,11 +305,12 @@ JSValueRef JSObjectGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef
295305
ExecState* exec = toJS(ctx);
296306
VM& vm = exec->vm();
297307
JSLockHolder locker(vm);
308+
auto scope = DECLARE_CATCH_SCOPE(vm);
298309

299310
JSObject* jsObject = toJS(object);
300311

301312
JSValue jsValue = jsObject->get(exec, propertyName->identifier(&vm));
302-
handleExceptionIfNeeded(exec, exception);
313+
handleExceptionIfNeeded(scope, exec, exception);
303314
return toRef(exec, jsValue);
304315
}
305316

@@ -328,7 +339,7 @@ void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef prope
328339
jsObject->methodTable(vm)->put(jsObject, exec, name, jsValue, slot);
329340
}
330341
}
331-
handleExceptionIfNeeded(exec, exception);
342+
handleExceptionIfNeeded(scope, exec, exception);
332343
}
333344

334345
JSValueRef JSObjectGetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned propertyIndex, JSValueRef* exception)
@@ -338,12 +349,14 @@ JSValueRef JSObjectGetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsi
338349
return 0;
339350
}
340351
ExecState* exec = toJS(ctx);
341-
JSLockHolder locker(exec);
352+
VM& vm = exec->vm();
353+
JSLockHolder locker(vm);
354+
auto scope = DECLARE_CATCH_SCOPE(vm);
342355

343356
JSObject* jsObject = toJS(object);
344357

345358
JSValue jsValue = jsObject->get(exec, propertyIndex);
346-
handleExceptionIfNeeded(exec, exception);
359+
handleExceptionIfNeeded(scope, exec, exception);
347360
return toRef(exec, jsValue);
348361
}
349362

@@ -357,12 +370,13 @@ void JSObjectSetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned p
357370
ExecState* exec = toJS(ctx);
358371
VM& vm = exec->vm();
359372
JSLockHolder locker(vm);
373+
auto scope = DECLARE_CATCH_SCOPE(vm);
360374

361375
JSObject* jsObject = toJS(object);
362376
JSValue jsValue = toJS(exec, value);
363377

364378
jsObject->methodTable(vm)->putByIndex(jsObject, exec, propertyIndex, jsValue, false);
365-
handleExceptionIfNeeded(exec, exception);
379+
handleExceptionIfNeeded(scope, exec, exception);
366380
}
367381

368382
bool JSObjectDeleteProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
@@ -374,11 +388,12 @@ bool JSObjectDeleteProperty(JSContextRef ctx, JSObjectRef object, JSStringRef pr
374388
ExecState* exec = toJS(ctx);
375389
VM& vm = exec->vm();
376390
JSLockHolder locker(vm);
391+
auto scope = DECLARE_CATCH_SCOPE(vm);
377392

378393
JSObject* jsObject = toJS(object);
379394

380395
bool result = jsObject->methodTable(vm)->deleteProperty(jsObject, exec, propertyName->identifier(&vm));
381-
handleExceptionIfNeeded(exec, exception);
396+
handleExceptionIfNeeded(scope, exec, exception);
382397
return result;
383398
}
384399

@@ -552,6 +567,7 @@ JSValueRef JSObjectCallAsFunction(JSContextRef ctx, JSObjectRef object, JSObject
552567
ExecState* exec = toJS(ctx);
553568
VM& vm = exec->vm();
554569
JSLockHolder locker(vm);
570+
auto scope = DECLARE_CATCH_SCOPE(vm);
555571

556572
if (!object)
557573
return 0;
@@ -572,7 +588,7 @@ JSValueRef JSObjectCallAsFunction(JSContextRef ctx, JSObjectRef object, JSObject
572588
return 0;
573589

574590
JSValueRef result = toRef(exec, profiledCall(exec, ProfilingReason::API, jsObject, callType, callData, jsThisObject, argList));
575-
if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow)
591+
if (handleExceptionIfNeeded(scope, exec, exception) == ExceptionStatus::DidThrow)
576592
result = 0;
577593
return result;
578594
}
@@ -591,6 +607,7 @@ JSObjectRef JSObjectCallAsConstructor(JSContextRef ctx, JSObjectRef object, size
591607
ExecState* exec = toJS(ctx);
592608
VM& vm = exec->vm();
593609
JSLockHolder locker(vm);
610+
auto scope = DECLARE_CATCH_SCOPE(vm);
594611

595612
if (!object)
596613
return 0;
@@ -607,7 +624,7 @@ JSObjectRef JSObjectCallAsConstructor(JSContextRef ctx, JSObjectRef object, size
607624
argList.append(toJS(exec, arguments[i]));
608625

609626
JSObjectRef result = toRef(profiledConstruct(exec, ProfilingReason::API, jsObject, constructType, constructData, argList));
610-
if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow)
627+
if (handleExceptionIfNeeded(scope, exec, exception) == ExceptionStatus::DidThrow)
611628
result = 0;
612629
return result;
613630
}

‎Source/JavaScriptCore/API/JSTypedArray.cpp‎

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,9 @@ JSTypedArrayType JSValueGetTypedArrayType(JSContextRef ctx, JSValueRef valueRef,
157157
JSObjectRef JSObjectMakeTypedArray(JSContextRef ctx, JSTypedArrayType arrayType, size_t length, JSValueRef* exception)
158158
{
159159
ExecState* exec = toJS(ctx);
160-
JSLockHolder locker(exec);
160+
VM& vm = exec->vm();
161+
JSLockHolder locker(vm);
162+
auto scope = DECLARE_CATCH_SCOPE(vm);
161163

162164
if (arrayType == kJSTypedArrayTypeNone || arrayType == kJSTypedArrayTypeArrayBuffer)
163165
return nullptr;
@@ -166,15 +168,17 @@ JSObjectRef JSObjectMakeTypedArray(JSContextRef ctx, JSTypedArrayType arrayType,
166168

167169
auto buffer = ArrayBuffer::tryCreate(length, elementByteSize);
168170
JSObject* result = createTypedArray(exec, arrayType, WTFMove(buffer), 0, length);
169-
if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow)
171+
if (handleExceptionIfNeeded(scope, exec, exception) == ExceptionStatus::DidThrow)
170172
return nullptr;
171173
return toRef(result);
172174
}
173175

174176
JSObjectRef JSObjectMakeTypedArrayWithBytesNoCopy(JSContextRef ctx, JSTypedArrayType arrayType, void* bytes, size_t length, JSTypedArrayBytesDeallocator destructor, void* destructorContext, JSValueRef* exception)
175177
{
176178
ExecState* exec = toJS(ctx);
177-
JSLockHolder locker(exec);
179+
VM& vm = exec->vm();
180+
JSLockHolder locker(vm);
181+
auto scope = DECLARE_CATCH_SCOPE(vm);
178182

179183
if (arrayType == kJSTypedArrayTypeNone || arrayType == kJSTypedArrayTypeArrayBuffer)
180184
return nullptr;
@@ -186,7 +190,7 @@ JSObjectRef JSObjectMakeTypedArrayWithBytesNoCopy(JSContextRef ctx, JSTypedArray
186190
destructor(p, destructorContext);
187191
});
188192
JSObject* result = createTypedArray(exec, arrayType, WTFMove(buffer), 0, length / elementByteSize);
189-
if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow)
193+
if (handleExceptionIfNeeded(scope, exec, exception) == ExceptionStatus::DidThrow)
190194
return nullptr;
191195
return toRef(result);
192196
}
@@ -196,6 +200,7 @@ JSObjectRef JSObjectMakeTypedArrayWithArrayBuffer(JSContextRef ctx, JSTypedArray
196200
ExecState* exec = toJS(ctx);
197201
VM& vm = exec->vm();
198202
JSLockHolder locker(vm);
203+
auto scope = DECLARE_CATCH_SCOPE(vm);
199204

200205
if (arrayType == kJSTypedArrayTypeNone || arrayType == kJSTypedArrayTypeArrayBuffer)
201206
return nullptr;
@@ -210,7 +215,7 @@ JSObjectRef JSObjectMakeTypedArrayWithArrayBuffer(JSContextRef ctx, JSTypedArray
210215
unsigned elementByteSize = elementSize(toTypedArrayType(arrayType));
211216

212217
JSObject* result = createTypedArray(exec, arrayType, WTFMove(buffer), 0, buffer->byteLength() / elementByteSize);
213-
if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow)
218+
if (handleExceptionIfNeeded(scope, exec, exception) == ExceptionStatus::DidThrow)
214219
return nullptr;
215220
return toRef(result);
216221
}
@@ -220,6 +225,7 @@ JSObjectRef JSObjectMakeTypedArrayWithArrayBufferAndOffset(JSContextRef ctx, JST
220225
ExecState* exec = toJS(ctx);
221226
VM& vm = exec->vm();
222227
JSLockHolder locker(vm);
228+
auto scope = DECLARE_CATCH_SCOPE(vm);
223229

224230
if (arrayType == kJSTypedArrayTypeNone || arrayType == kJSTypedArrayTypeArrayBuffer)
225231
return nullptr;
@@ -231,7 +237,7 @@ JSObjectRef JSObjectMakeTypedArrayWithArrayBufferAndOffset(JSContextRef ctx, JST
231237
}
232238

233239
JSObject* result = createTypedArray(exec, arrayType, jsBuffer->impl(), offset, length);
234-
if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow)
240+
if (handleExceptionIfNeeded(scope, exec, exception) == ExceptionStatus::DidThrow)
235241
return nullptr;
236242
return toRef(result);
237243
}
@@ -305,14 +311,15 @@ JSObjectRef JSObjectMakeArrayBufferWithBytesNoCopy(JSContextRef ctx, void* bytes
305311
ExecState* exec = toJS(ctx);
306312
VM& vm = exec->vm();
307313
JSLockHolder locker(vm);
314+
auto scope = DECLARE_CATCH_SCOPE(vm);
308315

309316
auto buffer = ArrayBuffer::createFromBytes(bytes, byteLength, [=](void* p) {
310317
if (bytesDeallocator)
311318
bytesDeallocator(p, deallocatorContext);
312319
});
313320

314321
JSArrayBuffer* jsBuffer = JSArrayBuffer::create(vm, exec->lexicalGlobalObject()->arrayBufferStructure(ArrayBufferSharingMode::Default), WTFMove(buffer));
315-
if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow)
322+
if (handleExceptionIfNeeded(scope, exec, exception) == ExceptionStatus::DidThrow)
316323
return nullptr;
317324

318325
return toRef(jsBuffer);

0 commit comments

Comments
 (0)