Skip to content

Commit 7fb128d

Browse files
targosofrobots
authored andcommitted
deps: cherry-pick backports to V8
Included acb6779 4e028bd 75fe773 c22bcd3 49dec1a Not included (cannot be applied cleanly) 31450fc 2b8a06b PR-URL: #3351 Reviewed-By: indutny - Fedor Indutny <[email protected]> Reviewed-By: bnoordhuis - Ben Noordhuis <[email protected]>
1 parent d8011d1 commit 7fb128d

File tree

9 files changed

+155
-22
lines changed

9 files changed

+155
-22
lines changed

deps/v8/include/v8.h

+13
Original file line numberDiff line numberDiff line change
@@ -5370,6 +5370,19 @@ class V8_EXPORT Isolate {
53705370
*/
53715371
static Isolate* GetCurrent();
53725372

5373+
/**
5374+
* Custom callback used by embedders to help V8 determine if it should abort
5375+
* when it throws and no internal handler is predicted to catch the
5376+
* exception. If --abort-on-uncaught-exception is used on the command line,
5377+
* then V8 will abort if either:
5378+
* - no custom callback is set.
5379+
* - the custom callback set returns true.
5380+
* Otherwise, the custom callback will not be called and V8 will not abort.
5381+
*/
5382+
typedef bool (*AbortOnUncaughtExceptionCallback)(Isolate*);
5383+
void SetAbortOnUncaughtExceptionCallback(
5384+
AbortOnUncaughtExceptionCallback callback);
5385+
53735386
/**
53745387
* Methods below this point require holding a lock (using Locker) in
53755388
* a multi-threaded environment.

deps/v8/src/accessors.cc

+28-13
Original file line numberDiff line numberDiff line change
@@ -99,22 +99,37 @@ bool Accessors::IsJSArrayBufferViewFieldAccessor(Handle<Map> map,
9999
Isolate* isolate = name->GetIsolate();
100100

101101
switch (map->instance_type()) {
102-
case JS_TYPED_ARRAY_TYPE:
103-
// %TypedArray%.prototype is non-configurable, and so are the following
104-
// named properties on %TypedArray%.prototype, so we can directly inline
105-
// the field-load for typed array maps that still use their
106-
// %TypedArray%.prototype.
107-
if (JSFunction::cast(map->GetConstructor())->prototype() !=
108-
map->prototype()) {
102+
case JS_TYPED_ARRAY_TYPE: {
103+
if (!CheckForName(name, isolate->factory()->length_string(),
104+
JSTypedArray::kLengthOffset, object_offset) &&
105+
!CheckForName(name, isolate->factory()->byte_length_string(),
106+
JSTypedArray::kByteLengthOffset, object_offset) &&
107+
!CheckForName(name, isolate->factory()->byte_offset_string(),
108+
JSTypedArray::kByteOffsetOffset, object_offset)) {
109109
return false;
110110
}
111-
return CheckForName(name, isolate->factory()->length_string(),
112-
JSTypedArray::kLengthOffset, object_offset) ||
113-
CheckForName(name, isolate->factory()->byte_length_string(),
114-
JSTypedArray::kByteLengthOffset, object_offset) ||
115-
CheckForName(name, isolate->factory()->byte_offset_string(),
116-
JSTypedArray::kByteOffsetOffset, object_offset);
117111

112+
if (map->is_dictionary_map()) return false;
113+
114+
// Check if the property is overridden on the instance.
115+
DescriptorArray* descriptors = map->instance_descriptors();
116+
int descriptor = descriptors->SearchWithCache(*name, *map);
117+
if (descriptor != DescriptorArray::kNotFound) return false;
118+
119+
Handle<Object> proto = Handle<Object>(map->prototype(), isolate);
120+
if (!proto->IsJSReceiver()) return false;
121+
122+
// Check if the property is defined in the prototype chain.
123+
LookupIterator it(proto, name);
124+
if (!it.IsFound()) return false;
125+
126+
Object* original_proto =
127+
JSFunction::cast(map->GetConstructor())->prototype();
128+
129+
// Property is not configurable. It is enough to verify that
130+
// the holder is the same.
131+
return *it.GetHolder<Object>() == original_proto;
132+
}
118133
case JS_DATA_VIEW_TYPE:
119134
return CheckForName(name, isolate->factory()->byte_length_string(),
120135
JSDataView::kByteLengthOffset, object_offset) ||

deps/v8/src/api.cc

+7
Original file line numberDiff line numberDiff line change
@@ -7160,6 +7160,13 @@ void Isolate::Exit() {
71607160
}
71617161

71627162

7163+
void Isolate::SetAbortOnUncaughtExceptionCallback(
7164+
AbortOnUncaughtExceptionCallback callback) {
7165+
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7166+
isolate->SetAbortOnUncaughtExceptionCallback(callback);
7167+
}
7168+
7169+
71637170
Isolate::DisallowJavascriptExecutionScope::DisallowJavascriptExecutionScope(
71647171
Isolate* isolate,
71657172
Isolate::DisallowJavascriptExecutionScope::OnFailure on_failure)

deps/v8/src/isolate.cc

+22-7
Original file line numberDiff line numberDiff line change
@@ -1013,13 +1013,21 @@ Object* Isolate::Throw(Object* exception, MessageLocation* location) {
10131013
Handle<Object> message_obj = CreateMessage(exception_handle, location);
10141014
thread_local_top()->pending_message_obj_ = *message_obj;
10151015

1016-
// If the abort-on-uncaught-exception flag is specified, abort on any
1017-
// exception not caught by JavaScript, even when an external handler is
1018-
// present. This flag is intended for use by JavaScript developers, so
1019-
// print a user-friendly stack trace (not an internal one).
1016+
// For any exception not caught by JavaScript, even when an external
1017+
// handler is present:
1018+
// If the abort-on-uncaught-exception flag is specified, and if the
1019+
// embedder didn't specify a custom uncaught exception callback,
1020+
// or if the custom callback determined that V8 should abort, then
1021+
// abort.
10201022
if (FLAG_abort_on_uncaught_exception &&
1021-
PredictExceptionCatcher() != CAUGHT_BY_JAVASCRIPT) {
1022-
FLAG_abort_on_uncaught_exception = false; // Prevent endless recursion.
1023+
PredictExceptionCatcher() != CAUGHT_BY_JAVASCRIPT &&
1024+
(!abort_on_uncaught_exception_callback_ ||
1025+
abort_on_uncaught_exception_callback_(
1026+
reinterpret_cast<v8::Isolate*>(this)))) {
1027+
// Prevent endless recursion.
1028+
FLAG_abort_on_uncaught_exception = false;
1029+
// This flag is intended for use by JavaScript developers, so
1030+
// print a user-friendly stack trace (not an internal one).
10231031
PrintF(stderr, "%s\n\nFROM\n",
10241032
MessageHandler::GetLocalizedMessage(this, message_obj).get());
10251033
PrintCurrentStackTrace(stderr);
@@ -1607,6 +1615,12 @@ void Isolate::SetCaptureStackTraceForUncaughtExceptions(
16071615
}
16081616

16091617

1618+
void Isolate::SetAbortOnUncaughtExceptionCallback(
1619+
v8::Isolate::AbortOnUncaughtExceptionCallback callback) {
1620+
abort_on_uncaught_exception_callback_ = callback;
1621+
}
1622+
1623+
16101624
Handle<Context> Isolate::native_context() {
16111625
return handle(context()->native_context());
16121626
}
@@ -1774,7 +1788,8 @@ Isolate::Isolate(bool enable_serializer)
17741788
next_unique_sfi_id_(0),
17751789
#endif
17761790
use_counter_callback_(NULL),
1777-
basic_block_profiler_(NULL) {
1791+
basic_block_profiler_(NULL),
1792+
abort_on_uncaught_exception_callback_(NULL) {
17781793
{
17791794
base::LockGuard<base::Mutex> lock_guard(thread_data_table_mutex_.Pointer());
17801795
CHECK(thread_data_table_);

deps/v8/src/isolate.h

+6
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,9 @@ class Isolate {
698698
int frame_limit,
699699
StackTrace::StackTraceOptions options);
700700

701+
void SetAbortOnUncaughtExceptionCallback(
702+
v8::Isolate::AbortOnUncaughtExceptionCallback callback);
703+
701704
enum PrintStackMode { kPrintStackConcise, kPrintStackVerbose };
702705
void PrintCurrentStackTrace(FILE* out);
703706
void PrintStack(StringStream* accumulator,
@@ -1366,6 +1369,9 @@ class Isolate {
13661369

13671370
std::set<Cancelable*> cancelable_tasks_;
13681371

1372+
v8::Isolate::AbortOnUncaughtExceptionCallback
1373+
abort_on_uncaught_exception_callback_;
1374+
13691375
friend class ExecutionAccess;
13701376
friend class HandleScopeImplementer;
13711377
friend class OptimizingCompileDispatcher;

deps/v8/src/objects.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -3932,14 +3932,14 @@ class ScopeInfo : public FixedArray {
39323932
FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(FIELD_ACCESSORS)
39333933
#undef FIELD_ACCESSORS
39343934

3935-
private:
39363935
enum {
39373936
#define DECL_INDEX(name) k##name,
39383937
FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(DECL_INDEX)
39393938
#undef DECL_INDEX
39403939
kVariablePartIndex
39413940
};
39423941

3942+
private:
39433943
// The layout of the variable part of a ScopeInfo is as follows:
39443944
// 1. ParameterEntries:
39453945
// This part stores the names of the parameters for function scopes. One

deps/v8/test/cctest/test-api.cc

+30
Original file line numberDiff line numberDiff line change
@@ -21826,4 +21826,34 @@ TEST(EstimatedContextSize) {
2182621826
v8::HandleScope scope(isolate);
2182721827
LocalContext env;
2182821828
CHECK(50000 < env->EstimatedSize());
21829+
21830+
21831+
static int nb_uncaught_exception_callback_calls = 0;
21832+
21833+
21834+
bool NoAbortOnUncaughtException(v8::Isolate* isolate) {
21835+
++nb_uncaught_exception_callback_calls;
21836+
return false;
21837+
}
21838+
21839+
21840+
TEST(AbortOnUncaughtExceptionNoAbort) {
21841+
v8::Isolate* isolate = CcTest::isolate();
21842+
v8::HandleScope handle_scope(isolate);
21843+
v8::Handle<v8::ObjectTemplate> global_template =
21844+
v8::ObjectTemplate::New(isolate);
21845+
LocalContext env(NULL, global_template);
21846+
21847+
i::FLAG_abort_on_uncaught_exception = true;
21848+
isolate->SetAbortOnUncaughtExceptionCallback(NoAbortOnUncaughtException);
21849+
21850+
CompileRun("function boom() { throw new Error(\"boom\") }");
21851+
21852+
v8::Local<v8::Object> global_object = env->Global();
21853+
v8::Local<v8::Function> foo =
21854+
v8::Local<v8::Function>::Cast(global_object->Get(v8_str("boom")));
21855+
21856+
foo->Call(global_object, 0, NULL);
21857+
21858+
CHECK_EQ(1, nb_uncaught_exception_callback_calls);
2182921859
}

deps/v8/test/mjsunit/regress/regress-typedarray-length.js

+37
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,43 @@ assertEquals(undefined, get(a));
7171
assertEquals(undefined, get(a));
7272
})();
7373

74+
(function() {
75+
"use strict";
76+
77+
class MyTypedArray extends Int32Array {
78+
constructor(length) {
79+
super(length);
80+
}
81+
}
82+
83+
a = new MyTypedArray(1024);
84+
85+
get = function(a) {
86+
return a.length;
87+
}
88+
89+
assertEquals(1024, get(a));
90+
assertEquals(1024, get(a));
91+
assertEquals(1024, get(a));
92+
%OptimizeFunctionOnNextCall(get);
93+
assertEquals(1024, get(a));
94+
})();
95+
96+
(function() {
97+
"use strict";
98+
var a = new Uint8Array(4);
99+
Object.defineProperty(a, "length", {get: function() { return "blah"; }});
100+
get = function(a) {
101+
return a.length;
102+
}
103+
104+
assertEquals("blah", get(a));
105+
assertEquals("blah", get(a));
106+
assertEquals("blah", get(a));
107+
%OptimizeFunctionOnNextCall(get);
108+
assertEquals("blah", get(a));
109+
})();
110+
74111
// Ensure we cannot delete length, byteOffset, byteLength.
75112
assertTrue(Int32Array.prototype.hasOwnProperty("length"));
76113
assertTrue(Int32Array.prototype.hasOwnProperty("byteOffset"));

deps/v8/tools/gen-postmortem-metadata.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,15 @@
132132
'value': 'JavaScriptFrameConstants::kFunctionOffset' },
133133
{ 'name': 'off_fp_args',
134134
'value': 'JavaScriptFrameConstants::kLastParameterOffset' },
135+
136+
{ 'name': 'scopeinfo_idx_nparams',
137+
'value': 'ScopeInfo::kParameterCount' },
138+
{ 'name': 'scopeinfo_idx_nstacklocals',
139+
'value': 'ScopeInfo::kStackLocalCount' },
140+
{ 'name': 'scopeinfo_idx_ncontextlocals',
141+
'value': 'ScopeInfo::kContextLocalCount' },
142+
{ 'name': 'scopeinfo_idx_first_vars',
143+
'value': 'ScopeInfo::kVariablePartIndex' },
135144
];
136145

137146
#
@@ -141,12 +150,13 @@
141150
'HeapObject, map, Map, kMapOffset',
142151
'JSObject, elements, Object, kElementsOffset',
143152
'FixedArray, data, uintptr_t, kHeaderSize',
153+
'JSTypedArray, length, Object, kLengthOffset',
144154
'Map, instance_attributes, int, kInstanceAttributesOffset',
145155
'Map, inobject_properties_of_constructor_function_index_offset, int, kInObjectPropertiesOrConstructorFunctionIndexOffset',
146156
'Map, instance_size, int, kInstanceSizeOffset',
147157
'Map, bit_field, char, kBitFieldOffset',
148158
'Map, bit_field2, char, kBitField2Offset',
149-
'Map, bit_field3, SMI, kBitField3Offset',
159+
'Map, bit_field3, int, kBitField3Offset',
150160
'Map, prototype, Object, kPrototypeOffset',
151161
'NameDictionaryShape, prefix_size, int, kPrefixSize',
152162
'NameDictionaryShape, entry_size, int, kEntrySize',

0 commit comments

Comments
 (0)