aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/src/runtime
diff options
context:
space:
mode:
authorMichaël Zasso <targos@protonmail.com>2017-02-14 11:27:26 +0100
committerMichaël Zasso <targos@protonmail.com>2017-02-22 15:55:42 +0100
commit7a77daf24344db7942e34c962b0f1ee729ab7af5 (patch)
treee7cbe7bf4e2f4b802a8f5bc18336c546cd6a0d7f /deps/v8/src/runtime
parent5f08871ee93ea739148cc49e0f7679e33c70295a (diff)
downloadandroid-node-v8-7a77daf24344db7942e34c962b0f1ee729ab7af5.tar.gz
android-node-v8-7a77daf24344db7942e34c962b0f1ee729ab7af5.tar.bz2
android-node-v8-7a77daf24344db7942e34c962b0f1ee729ab7af5.zip
deps: update V8 to 5.6.326.55
PR-URL: https://github.com/nodejs/node/pull/10992 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Diffstat (limited to 'deps/v8/src/runtime')
-rw-r--r--deps/v8/src/runtime/runtime-array.cc90
-rw-r--r--deps/v8/src/runtime/runtime-collections.cc4
-rw-r--r--deps/v8/src/runtime/runtime-compiler.cc2
-rw-r--r--deps/v8/src/runtime/runtime-debug.cc199
-rw-r--r--deps/v8/src/runtime/runtime-function.cc16
-rw-r--r--deps/v8/src/runtime/runtime-i18n.cc59
-rw-r--r--deps/v8/src/runtime/runtime-internal.cc119
-rw-r--r--deps/v8/src/runtime/runtime-interpreter.cc14
-rw-r--r--deps/v8/src/runtime/runtime-literals.cc2
-rw-r--r--deps/v8/src/runtime/runtime-maths.cc75
-rw-r--r--deps/v8/src/runtime/runtime-module.cc39
-rw-r--r--deps/v8/src/runtime/runtime-numbers.cc34
-rw-r--r--deps/v8/src/runtime/runtime-object.cc185
-rw-r--r--deps/v8/src/runtime/runtime-promise.cc193
-rw-r--r--deps/v8/src/runtime/runtime-regexp.cc668
-rw-r--r--deps/v8/src/runtime/runtime-scopes.cc2
-rw-r--r--deps/v8/src/runtime/runtime-strings.cc80
-rw-r--r--deps/v8/src/runtime/runtime-test.cc33
-rw-r--r--deps/v8/src/runtime/runtime-typedarray.cc8
-rw-r--r--deps/v8/src/runtime/runtime.h75
20 files changed, 1249 insertions, 648 deletions
diff --git a/deps/v8/src/runtime/runtime-array.cc b/deps/v8/src/runtime/runtime-array.cc
index cbde8f372e..1a2d957caf 100644
--- a/deps/v8/src/runtime/runtime-array.cc
+++ b/deps/v8/src/runtime/runtime-array.cc
@@ -28,11 +28,13 @@ RUNTIME_FUNCTION(Runtime_FinishArrayPrototypeSetup) {
// This is necessary to enable fast checks for absence of elements
// on Array.prototype and below.
prototype->set_elements(isolate->heap()->empty_fixed_array());
- return Smi::FromInt(0);
+ return Smi::kZero;
}
-static void InstallCode(Isolate* isolate, Handle<JSObject> holder,
- const char* name, Handle<Code> code, int argc = -1) {
+static void InstallCode(
+ Isolate* isolate, Handle<JSObject> holder, const char* name,
+ Handle<Code> code, int argc = -1,
+ BuiltinFunctionId id = static_cast<BuiltinFunctionId>(-1)) {
Handle<String> key = isolate->factory()->InternalizeUtf8String(name);
Handle<JSFunction> optimized =
isolate->factory()->NewFunctionWithoutPrototype(key, code);
@@ -41,15 +43,19 @@ static void InstallCode(Isolate* isolate, Handle<JSObject> holder,
} else {
optimized->shared()->set_internal_formal_parameter_count(argc);
}
+ if (id >= 0) {
+ optimized->shared()->set_builtin_function_id(id);
+ }
JSObject::AddProperty(holder, key, optimized, NONE);
}
-static void InstallBuiltin(Isolate* isolate, Handle<JSObject> holder,
- const char* name, Builtins::Name builtin_name,
- int argc = -1) {
+static void InstallBuiltin(
+ Isolate* isolate, Handle<JSObject> holder, const char* name,
+ Builtins::Name builtin_name, int argc = -1,
+ BuiltinFunctionId id = static_cast<BuiltinFunctionId>(-1)) {
InstallCode(isolate, holder, name,
- handle(isolate->builtins()->builtin(builtin_name), isolate),
- argc);
+ handle(isolate->builtins()->builtin(builtin_name), isolate), argc,
+ id);
}
RUNTIME_FUNCTION(Runtime_SpecialArrayFunctions) {
@@ -71,6 +77,12 @@ RUNTIME_FUNCTION(Runtime_SpecialArrayFunctions) {
InstallBuiltin(isolate, holder, "splice", Builtins::kArraySplice);
InstallBuiltin(isolate, holder, "includes", Builtins::kArrayIncludes, 2);
InstallBuiltin(isolate, holder, "indexOf", Builtins::kArrayIndexOf, 2);
+ InstallBuiltin(isolate, holder, "keys", Builtins::kArrayPrototypeKeys, 0,
+ kArrayKeys);
+ InstallBuiltin(isolate, holder, "values", Builtins::kArrayPrototypeValues, 0,
+ kArrayValues);
+ InstallBuiltin(isolate, holder, "entries", Builtins::kArrayPrototypeEntries,
+ 0, kArrayEntries);
return *holder;
}
@@ -140,7 +152,7 @@ RUNTIME_FUNCTION(Runtime_MoveArrayContents) {
to->set_length(from->length());
JSObject::ResetElements(from);
- from->set_length(Smi::FromInt(0));
+ from->set_length(Smi::kZero);
JSObject::ValidateElements(to);
return *to;
@@ -376,7 +388,7 @@ RUNTIME_FUNCTION(Runtime_GrowArrayElements) {
if (index >= capacity) {
if (!object->GetElementsAccessor()->GrowCapacity(object, index)) {
- return Smi::FromInt(0);
+ return Smi::kZero;
}
}
@@ -423,21 +435,6 @@ RUNTIME_FUNCTION(Runtime_IsArray) {
return isolate->heap()->ToBoolean(obj->IsJSArray());
}
-RUNTIME_FUNCTION(Runtime_HasCachedArrayIndex) {
- SealHandleScope shs(isolate);
- DCHECK(args.length() == 1);
- return isolate->heap()->false_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetCachedArrayIndex) {
- // This can never be reached, because Runtime_HasCachedArrayIndex always
- // returns false.
- UNIMPLEMENTED();
- return nullptr;
-}
-
-
RUNTIME_FUNCTION(Runtime_ArraySpeciesConstructor) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
@@ -639,5 +636,48 @@ RUNTIME_FUNCTION(Runtime_ArrayIndexOf) {
return Smi::FromInt(-1);
}
+RUNTIME_FUNCTION(Runtime_SpreadIterablePrepare) {
+ HandleScope scope(isolate);
+ DCHECK_EQ(1, args.length());
+ CONVERT_ARG_HANDLE_CHECKED(Object, spread, 0);
+
+ if (spread->IsJSArray()) {
+ // Check that the spread arg has fast elements
+ Handle<JSArray> spread_array = Handle<JSArray>::cast(spread);
+ ElementsKind array_kind = spread_array->GetElementsKind();
+
+ // And that it has the orignal ArrayPrototype
+ JSObject* array_proto = JSObject::cast(spread_array->map()->prototype());
+ Map* iterator_map = isolate->initial_array_iterator_prototype()->map();
+
+ // Check that the iterator acts as expected.
+ // If IsArrayIteratorLookupChainIntact(), then we know that the initial
+ // ArrayIterator is being used. If the map of the prototype has changed,
+ // then take the slow path.
+
+ if (isolate->is_initial_array_prototype(array_proto) &&
+ isolate->IsArrayIteratorLookupChainIntact() &&
+ isolate->is_initial_array_iterator_prototype_map(iterator_map)) {
+ if (IsFastPackedElementsKind(array_kind)) {
+ return *spread;
+ }
+ if (IsFastHoleyElementsKind(array_kind) &&
+ isolate->IsFastArrayConstructorPrototypeChainIntact()) {
+ return *spread;
+ }
+ }
+ }
+
+ Handle<JSFunction> spread_iterable_function = isolate->spread_iterable();
+
+ Handle<Object> spreaded;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, spreaded,
+ Execution::Call(isolate, spread_iterable_function,
+ isolate->factory()->undefined_value(), 1, &spread));
+
+ return *spreaded;
+}
+
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/runtime/runtime-collections.cc b/deps/v8/src/runtime/runtime-collections.cc
index b25a5ef5c2..57e5d98532 100644
--- a/deps/v8/src/runtime/runtime-collections.cc
+++ b/deps/v8/src/runtime/runtime-collections.cc
@@ -95,7 +95,7 @@ RUNTIME_FUNCTION(Runtime_SetIteratorInitialize) {
kind == JSSetIterator::kKindEntries);
Handle<OrderedHashSet> table(OrderedHashSet::cast(set->table()));
holder->set_table(*table);
- holder->set_index(Smi::FromInt(0));
+ holder->set_index(Smi::kZero);
holder->set_kind(Smi::FromInt(kind));
return isolate->heap()->undefined_value();
}
@@ -191,7 +191,7 @@ RUNTIME_FUNCTION(Runtime_MapIteratorInitialize) {
kind == JSMapIterator::kKindEntries);
Handle<OrderedHashMap> table(OrderedHashMap::cast(map->table()));
holder->set_table(*table);
- holder->set_index(Smi::FromInt(0));
+ holder->set_index(Smi::kZero);
holder->set_kind(Smi::FromInt(kind));
return isolate->heap()->undefined_value();
}
diff --git a/deps/v8/src/runtime/runtime-compiler.cc b/deps/v8/src/runtime/runtime-compiler.cc
index 01ec73d427..472e076de4 100644
--- a/deps/v8/src/runtime/runtime-compiler.cc
+++ b/deps/v8/src/runtime/runtime-compiler.cc
@@ -123,7 +123,7 @@ RUNTIME_FUNCTION(Runtime_InstantiateAsmJs) {
function->shared()->ReplaceCode(
isolate->builtins()->builtin(Builtins::kCompileLazy));
}
- return Smi::FromInt(0);
+ return Smi::kZero;
}
RUNTIME_FUNCTION(Runtime_NotifyStubFailure) {
diff --git a/deps/v8/src/runtime/runtime-debug.cc b/deps/v8/src/runtime/runtime-debug.cc
index 2d217b83f7..824ea92a0f 100644
--- a/deps/v8/src/runtime/runtime-debug.cc
+++ b/deps/v8/src/runtime/runtime-debug.cc
@@ -16,8 +16,8 @@
#include "src/interpreter/interpreter.h"
#include "src/isolate-inl.h"
#include "src/runtime/runtime.h"
-#include "src/wasm/wasm-debug.h"
#include "src/wasm/wasm-module.h"
+#include "src/wasm/wasm-objects.h"
namespace v8 {
namespace internal {
@@ -47,7 +47,7 @@ RUNTIME_FUNCTION(Runtime_DebugBreakOnBytecode) {
isolate->debug()->Break(it.frame());
// If live-edit has dropped frames, we are not going back to dispatch.
- if (LiveEdit::SetAfterBreakTarget(isolate->debug())) return Smi::FromInt(0);
+ if (LiveEdit::SetAfterBreakTarget(isolate->debug())) return Smi::kZero;
// Return the handler from the original bytecode array.
DCHECK(it.frame()->is_interpreted());
@@ -256,14 +256,14 @@ MaybeHandle<JSArray> Runtime::GetInternalProperties(Isolate* isolate,
const char* status = "rejected";
int status_val = Handle<Smi>::cast(status_obj)->value();
switch (status_val) {
- case +1:
+ case kPromiseFulfilled:
status = "resolved";
break;
- case 0:
+ case kPromisePending:
status = "pending";
break;
default:
- DCHECK_EQ(-1, status_val);
+ DCHECK_EQ(kPromiseRejected, status_val);
}
Handle<FixedArray> result = factory->NewFixedArray(2 * 2);
@@ -457,7 +457,7 @@ RUNTIME_FUNCTION(Runtime_GetFrameCount) {
StackFrame::Id id = isolate->debug()->break_frame_id();
if (id == StackFrame::NO_ID) {
// If there is no JavaScript stack frame count is 0.
- return Smi::FromInt(0);
+ return Smi::kZero;
}
for (StackTraceFrameIterator it(isolate, id); !it.done(); it.Advance()) {
@@ -551,10 +551,10 @@ RUNTIME_FUNCTION(Runtime_GetFrameDetails) {
details->set(kFrameDetailsFrameIdIndex, *frame_id);
// Add the function name.
- Handle<Object> wasm_obj(it.wasm_frame()->wasm_obj(), isolate);
+ Handle<Object> wasm_instance(it.wasm_frame()->wasm_instance(), isolate);
int func_index = it.wasm_frame()->function_index();
Handle<String> func_name =
- wasm::GetWasmFunctionName(isolate, wasm_obj, func_index);
+ wasm::GetWasmFunctionName(isolate, wasm_instance, func_index);
details->set(kFrameDetailsFunctionIndex, *func_name);
// Add the script wrapper
@@ -563,14 +563,26 @@ RUNTIME_FUNCTION(Runtime_GetFrameDetails) {
details->set(kFrameDetailsScriptIndex, *script_wrapper);
// Add the arguments count.
- details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(0));
+ details->set(kFrameDetailsArgumentCountIndex, Smi::kZero);
// Add the locals count
- details->set(kFrameDetailsLocalCountIndex, Smi::FromInt(0));
+ details->set(kFrameDetailsLocalCountIndex, Smi::kZero);
// Add the source position.
+ // For wasm, it is function-local, so translate it to a module-relative
+ // position, such that together with the script it uniquely identifies the
+ // position.
+ Handle<Object> positionValue;
if (position != kNoSourcePosition) {
- details->set(kFrameDetailsSourcePositionIndex, Smi::FromInt(position));
+ int translated_position = position;
+ if (!wasm::WasmIsAsmJs(*wasm_instance, isolate)) {
+ Handle<WasmCompiledModule> compiled_module(
+ wasm::GetCompiledModule(JSObject::cast(*wasm_instance)), isolate);
+ translated_position +=
+ wasm::GetFunctionCodeOffset(compiled_module, func_index);
+ }
+ details->set(kFrameDetailsSourcePositionIndex,
+ Smi::FromInt(translated_position));
}
// Add the constructor information.
@@ -929,7 +941,7 @@ RUNTIME_FUNCTION(Runtime_GetGeneratorScopeCount) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
- if (!args[0]->IsJSGeneratorObject()) return Smi::FromInt(0);
+ if (!args[0]->IsJSGeneratorObject()) return Smi::kZero;
// Check arguments.
CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, gen, 0);
@@ -948,7 +960,7 @@ RUNTIME_FUNCTION(Runtime_GetGeneratorScopeDetails) {
DCHECK(args.length() == 2);
if (!args[0]->IsJSGeneratorObject()) {
- return *isolate->factory()->undefined_value();
+ return isolate->heap()->undefined_value();
}
// Check arguments.
@@ -1429,6 +1441,7 @@ RUNTIME_FUNCTION(Runtime_DebugGetPrototype) {
// Patches script source (should be called upon BeforeCompile event).
+// TODO(5530): Remove once uses in debug.js are gone.
RUNTIME_FUNCTION(Runtime_DebugSetScriptSource) {
HandleScope scope(isolate);
DCHECK(args.length() == 2);
@@ -1569,6 +1582,7 @@ RUNTIME_FUNCTION(Runtime_GetScript) {
return *Script::GetWrapper(found);
}
+// TODO(5530): Remove once uses in debug.js are gone.
RUNTIME_FUNCTION(Runtime_ScriptLineCount) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
@@ -1583,6 +1597,7 @@ RUNTIME_FUNCTION(Runtime_ScriptLineCount) {
return Smi::FromInt(line_ends_array->length());
}
+// TODO(5530): Remove once uses in debug.js are gone.
RUNTIME_FUNCTION(Runtime_ScriptLineStartPosition) {
HandleScope scope(isolate);
DCHECK(args.length() == 2);
@@ -1601,7 +1616,7 @@ RUNTIME_FUNCTION(Runtime_ScriptLineStartPosition) {
if (line < 0 || line > line_count) {
return Smi::FromInt(-1);
} else if (line == 0) {
- return Smi::FromInt(0);
+ return Smi::kZero;
} else {
DCHECK(0 < line && line <= line_count);
const int pos = Smi::cast(line_ends_array->get(line - 1))->value() + 1;
@@ -1609,6 +1624,7 @@ RUNTIME_FUNCTION(Runtime_ScriptLineStartPosition) {
}
}
+// TODO(5530): Remove once uses in debug.js are gone.
RUNTIME_FUNCTION(Runtime_ScriptLineEndPosition) {
HandleScope scope(isolate);
DCHECK(args.length() == 2);
@@ -1634,7 +1650,7 @@ static Handle<Object> GetJSPositionInfo(Handle<Script> script, int position,
Script::OffsetFlag offset_flag,
Isolate* isolate) {
Script::PositionInfo info;
- if (!script->GetPositionInfo(position, &info, offset_flag)) {
+ if (!Script::GetPositionInfo(script, position, &info, offset_flag)) {
return isolate->factory()->null_value();
}
@@ -1661,62 +1677,49 @@ static Handle<Object> GetJSPositionInfo(Handle<Script> script, int position,
return jsinfo;
}
-// Get information on a specific source line and column possibly offset by a
-// fixed source position. This function is used to find a source position from
-// a line and column position. The fixed source position offset is typically
-// used to find a source position in a function based on a line and column in
-// the source for the function alone. The offset passed will then be the
-// start position of the source for the function within the full script source.
-// Note that incoming line and column parameters may be undefined, and are
-// assumed to be passed *with* offsets.
-RUNTIME_FUNCTION(Runtime_ScriptLocationFromLine) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 4);
- CONVERT_ARG_CHECKED(JSValue, script, 0);
-
- CHECK(script->value()->IsScript());
- Handle<Script> script_handle = Handle<Script>(Script::cast(script->value()));
+namespace {
+Handle<Object> ScriptLocationFromLine(Isolate* isolate, Handle<Script> script,
+ Handle<Object> opt_line,
+ Handle<Object> opt_column,
+ int32_t offset) {
// Line and column are possibly undefined and we need to handle these cases,
// additionally subtracting corresponding offsets.
int32_t line;
- if (args[1]->IsNull(isolate) || args[1]->IsUndefined(isolate)) {
+ if (opt_line->IsNull(isolate) || opt_line->IsUndefined(isolate)) {
line = 0;
} else {
- CHECK(args[1]->IsNumber());
- line = NumberToInt32(args[1]) - script_handle->line_offset();
+ CHECK(opt_line->IsNumber());
+ line = NumberToInt32(*opt_line) - script->line_offset();
}
int32_t column;
- if (args[2]->IsNull(isolate) || args[2]->IsUndefined(isolate)) {
+ if (opt_column->IsNull(isolate) || opt_column->IsUndefined(isolate)) {
column = 0;
} else {
- CHECK(args[2]->IsNumber());
- column = NumberToInt32(args[2]);
- if (line == 0) column -= script_handle->column_offset();
+ CHECK(opt_column->IsNumber());
+ column = NumberToInt32(*opt_column);
+ if (line == 0) column -= script->column_offset();
}
- CONVERT_NUMBER_CHECKED(int32_t, offset_position, Int32, args[3]);
-
- if (line < 0 || column < 0 || offset_position < 0) {
- return isolate->heap()->null_value();
+ if (line < 0 || column < 0 || offset < 0) {
+ return isolate->factory()->null_value();
}
- Script::InitLineEnds(script_handle);
+ Script::InitLineEnds(script);
- FixedArray* line_ends_array = FixedArray::cast(script_handle->line_ends());
+ FixedArray* line_ends_array = FixedArray::cast(script->line_ends());
const int line_count = line_ends_array->length();
int position;
if (line == 0) {
- position = offset_position + column;
+ position = offset + column;
} else {
Script::PositionInfo info;
- if (!script_handle->GetPositionInfo(offset_position, &info,
- Script::NO_OFFSET) ||
+ if (!Script::GetPositionInfo(script, offset, &info, Script::NO_OFFSET) ||
info.line + line >= line_count) {
- return isolate->heap()->null_value();
+ return isolate->factory()->null_value();
}
const int offset_line = info.line + line;
@@ -1727,10 +1730,65 @@ RUNTIME_FUNCTION(Runtime_ScriptLocationFromLine) {
position = offset_line_position + column;
}
- return *GetJSPositionInfo(script_handle, position, Script::NO_OFFSET,
- isolate);
+ return GetJSPositionInfo(script, position, Script::NO_OFFSET, isolate);
+}
+
+// Slow traversal over all scripts on the heap.
+bool GetScriptById(Isolate* isolate, int needle, Handle<Script>* result) {
+ Script::Iterator iterator(isolate);
+ Script* script = NULL;
+ while ((script = iterator.Next()) != NULL) {
+ if (script->id() == needle) {
+ *result = handle(script);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+} // namespace
+
+// Get information on a specific source line and column possibly offset by a
+// fixed source position. This function is used to find a source position from
+// a line and column position. The fixed source position offset is typically
+// used to find a source position in a function based on a line and column in
+// the source for the function alone. The offset passed will then be the
+// start position of the source for the function within the full script source.
+// Note that incoming line and column parameters may be undefined, and are
+// assumed to be passed *with* offsets.
+// TODO(5530): Remove once uses in debug.js are gone.
+RUNTIME_FUNCTION(Runtime_ScriptLocationFromLine) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 4);
+ CONVERT_ARG_HANDLE_CHECKED(JSValue, script, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, opt_line, 1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, opt_column, 2);
+ CONVERT_NUMBER_CHECKED(int32_t, offset, Int32, args[3]);
+
+ CHECK(script->value()->IsScript());
+ Handle<Script> script_handle = Handle<Script>(Script::cast(script->value()));
+
+ return *ScriptLocationFromLine(isolate, script_handle, opt_line, opt_column,
+ offset);
+}
+
+// TODO(5530): Rename once conflicting function has been deleted.
+RUNTIME_FUNCTION(Runtime_ScriptLocationFromLine2) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 4);
+ CONVERT_NUMBER_CHECKED(int32_t, scriptid, Int32, args[0]);
+ CONVERT_ARG_HANDLE_CHECKED(Object, opt_line, 1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, opt_column, 2);
+ CONVERT_NUMBER_CHECKED(int32_t, offset, Int32, args[3]);
+
+ Handle<Script> script;
+ CHECK(GetScriptById(isolate, scriptid, &script));
+
+ return *ScriptLocationFromLine(isolate, script, opt_line, opt_column, offset);
}
+// TODO(5530): Remove once uses in debug.js are gone.
RUNTIME_FUNCTION(Runtime_ScriptPositionInfo) {
HandleScope scope(isolate);
DCHECK(args.length() == 3);
@@ -1748,6 +1806,7 @@ RUNTIME_FUNCTION(Runtime_ScriptPositionInfo) {
// Returns the given line as a string, or null if line is out of bounds.
// The parameter line is expected to include the script's line offset.
+// TODO(5530): Remove once uses in debug.js are gone.
RUNTIME_FUNCTION(Runtime_ScriptSourceLine) {
HandleScope scope(isolate);
DCHECK(args.length() == 2);
@@ -1822,12 +1881,19 @@ RUNTIME_FUNCTION(Runtime_DebugPopPromise) {
return isolate->heap()->undefined_value();
}
+RUNTIME_FUNCTION(Runtime_DebugNextMicrotaskId) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 0);
+ return Smi::FromInt(isolate->GetNextDebugMicrotaskId());
+}
RUNTIME_FUNCTION(Runtime_DebugAsyncTaskEvent) {
- DCHECK(args.length() == 1);
+ DCHECK(args.length() == 3);
HandleScope scope(isolate);
- CONVERT_ARG_HANDLE_CHECKED(JSObject, data, 0);
- isolate->debug()->OnAsyncTaskEvent(data);
+ CONVERT_ARG_HANDLE_CHECKED(String, type, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, id, 1);
+ CONVERT_ARG_HANDLE_CHECKED(String, name, 2);
+ isolate->debug()->OnAsyncTaskEvent(type, id, name);
return isolate->heap()->undefined_value();
}
@@ -1843,34 +1909,5 @@ RUNTIME_FUNCTION(Runtime_DebugBreakInOptimizedCode) {
return NULL;
}
-RUNTIME_FUNCTION(Runtime_GetWasmFunctionOffsetTable) {
- DCHECK(args.length() == 1);
- HandleScope scope(isolate);
- CONVERT_ARG_CHECKED(JSValue, script_val, 0);
-
- CHECK(script_val->value()->IsScript());
- Handle<Script> script = Handle<Script>(Script::cast(script_val->value()));
-
- Handle<wasm::WasmDebugInfo> debug_info =
- wasm::GetDebugInfo(handle(script->wasm_object(), isolate));
- Handle<FixedArray> elements = wasm::WasmDebugInfo::GetFunctionOffsetTable(
- debug_info, script->wasm_function_index());
- return *isolate->factory()->NewJSArrayWithElements(elements);
-}
-
-RUNTIME_FUNCTION(Runtime_DisassembleWasmFunction) {
- DCHECK(args.length() == 1);
- HandleScope scope(isolate);
- CONVERT_ARG_CHECKED(JSValue, script_val, 0);
-
- CHECK(script_val->value()->IsScript());
- Handle<Script> script = Handle<Script>(Script::cast(script_val->value()));
-
- Handle<wasm::WasmDebugInfo> debug_info =
- wasm::GetDebugInfo(handle(script->wasm_object(), isolate));
- return *wasm::WasmDebugInfo::DisassembleFunction(
- debug_info, script->wasm_function_index());
-}
-
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/runtime/runtime-function.cc b/deps/v8/src/runtime/runtime-function.cc
index fa50941925..a91ab28cc6 100644
--- a/deps/v8/src/runtime/runtime-function.cc
+++ b/deps/v8/src/runtime/runtime-function.cc
@@ -55,7 +55,7 @@ RUNTIME_FUNCTION(Runtime_FunctionRemovePrototype) {
return isolate->heap()->undefined_value();
}
-
+// TODO(5530): Remove once uses in debug.js are gone.
RUNTIME_FUNCTION(Runtime_FunctionGetScript) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
@@ -71,6 +71,20 @@ RUNTIME_FUNCTION(Runtime_FunctionGetScript) {
return isolate->heap()->undefined_value();
}
+RUNTIME_FUNCTION(Runtime_FunctionGetScriptId) {
+ HandleScope scope(isolate);
+ DCHECK_EQ(1, args.length());
+ CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0);
+
+ if (function->IsJSFunction()) {
+ Handle<Object> script(
+ Handle<JSFunction>::cast(function)->shared()->script(), isolate);
+ if (script->IsScript()) {
+ return Smi::FromInt(Handle<Script>::cast(script)->id());
+ }
+ }
+ return Smi::FromInt(-1);
+}
RUNTIME_FUNCTION(Runtime_FunctionGetSourceCode) {
HandleScope scope(isolate);
diff --git a/deps/v8/src/runtime/runtime-i18n.cc b/deps/v8/src/runtime/runtime-i18n.cc
index cac403baca..75e0952581 100644
--- a/deps/v8/src/runtime/runtime-i18n.cc
+++ b/deps/v8/src/runtime/runtime-i18n.cc
@@ -926,7 +926,7 @@ RUNTIME_FUNCTION(Runtime_BreakIteratorBreakType) {
if (status >= UBRK_WORD_NONE && status < UBRK_WORD_NONE_LIMIT) {
return *isolate->factory()->NewStringFromStaticChars("none");
} else if (status >= UBRK_WORD_NUMBER && status < UBRK_WORD_NUMBER_LIMIT) {
- return *isolate->factory()->number_string();
+ return isolate->heap()->number_string();
} else if (status >= UBRK_WORD_LETTER && status < UBRK_WORD_LETTER_LIMIT) {
return *isolate->factory()->NewStringFromStaticChars("letter");
} else if (status >= UBRK_WORD_KANA && status < UBRK_WORD_KANA_LIMIT) {
@@ -939,55 +939,10 @@ RUNTIME_FUNCTION(Runtime_BreakIteratorBreakType) {
}
namespace {
-void ConvertCaseWithTransliterator(icu::UnicodeString* input,
- const char* transliterator_id) {
- UErrorCode status = U_ZERO_ERROR;
- std::unique_ptr<icu::Transliterator> translit(
- icu::Transliterator::createInstance(
- icu::UnicodeString(transliterator_id, -1, US_INV), UTRANS_FORWARD,
- status));
- if (U_FAILURE(status)) return;
- translit->transliterate(*input);
-}
-
MUST_USE_RESULT Object* LocaleConvertCase(Handle<String> s, Isolate* isolate,
bool is_to_upper, const char* lang) {
- int32_t src_length = s->length();
-
- // Greek uppercasing has to be done via transliteration.
- // TODO(jshin): Drop this special-casing once ICU's regular case conversion
- // API supports Greek uppercasing. See
- // http://bugs.icu-project.org/trac/ticket/10582 .
- // In the meantime, if there's no Greek character in |s|, call this
- // function again with the root locale (lang="").
- // ICU's C API for transliteration is nasty and we just use C++ API.
- if (V8_UNLIKELY(is_to_upper && lang[0] == 'e' && lang[1] == 'l')) {
- icu::UnicodeString converted;
- std::unique_ptr<uc16[]> sap;
- {
- DisallowHeapAllocation no_gc;
- String::FlatContent flat = s->GetFlatContent();
- const UChar* src = GetUCharBufferFromFlat(flat, &sap, src_length);
- // Starts with the source string (read-only alias with copy-on-write
- // semantics) and will be modified to contain the converted result.
- // Using read-only alias at first saves one copy operation if
- // transliteration does not change the input, which is rather rare.
- // Moreover, transliteration takes rather long so that saving one copy
- // helps only a little bit.
- converted.setTo(false, src, src_length);
- ConvertCaseWithTransliterator(&converted, "el-Upper");
- // If no change is made, just return |s|.
- if (converted.getBuffer() == src) return *s;
- }
- RETURN_RESULT_OR_FAILURE(
- isolate,
- isolate->factory()->NewStringFromTwoByte(Vector<const uint16_t>(
- reinterpret_cast<const uint16_t*>(converted.getBuffer()),
- converted.length())));
- }
-
auto case_converter = is_to_upper ? u_strToUpper : u_strToLower;
-
+ int32_t src_length = s->length();
int32_t dest_length = src_length;
UErrorCode status;
Handle<SeqTwoByteString> result;
@@ -1138,7 +1093,7 @@ RUNTIME_FUNCTION(Runtime_StringToLowerCaseI18N) {
s = String::Flatten(s);
// First scan the string for uppercase and non-ASCII characters:
if (s->HasOnlyOneByteChars()) {
- unsigned first_index_to_lower = length;
+ int first_index_to_lower = length;
for (int index = 0; index < length; ++index) {
// Blink specializes this path for one-byte strings, so it
// does not need to do a generic get, but can do the equivalent
@@ -1165,14 +1120,16 @@ RUNTIME_FUNCTION(Runtime_StringToLowerCaseI18N) {
String::FlatContent flat = s->GetFlatContent();
if (flat.IsOneByte()) {
const uint8_t* src = flat.ToOneByteVector().start();
- CopyChars(result->GetChars(), src, first_index_to_lower);
+ CopyChars(result->GetChars(), src,
+ static_cast<size_t>(first_index_to_lower));
for (int index = first_index_to_lower; index < length; ++index) {
uint16_t ch = static_cast<uint16_t>(src[index]);
result->SeqOneByteStringSet(index, ToLatin1Lower(ch));
}
} else {
const uint16_t* src = flat.ToUC16Vector().start();
- CopyChars(result->GetChars(), src, first_index_to_lower);
+ CopyChars(result->GetChars(), src,
+ static_cast<size_t>(first_index_to_lower));
for (int index = first_index_to_lower; index < length; ++index) {
uint16_t ch = src[index];
result->SeqOneByteStringSet(index, ToLatin1Lower(ch));
@@ -1283,7 +1240,7 @@ RUNTIME_FUNCTION(Runtime_DateCacheVersion) {
if (!isolate->eternal_handles()->Exists(EternalHandles::DATE_CACHE_VERSION)) {
Handle<FixedArray> date_cache_version =
isolate->factory()->NewFixedArray(1, TENURED);
- date_cache_version->set(0, Smi::FromInt(0));
+ date_cache_version->set(0, Smi::kZero);
isolate->eternal_handles()->CreateSingleton(
isolate, *date_cache_version, EternalHandles::DATE_CACHE_VERSION);
}
diff --git a/deps/v8/src/runtime/runtime-internal.cc b/deps/v8/src/runtime/runtime-internal.cc
index 26882b5c83..621f33547e 100644
--- a/deps/v8/src/runtime/runtime-internal.cc
+++ b/deps/v8/src/runtime/runtime-internal.cc
@@ -100,12 +100,29 @@ RUNTIME_FUNCTION(Runtime_ThrowStackOverflow) {
return isolate->StackOverflow();
}
+RUNTIME_FUNCTION(Runtime_ThrowTypeError) {
+ HandleScope scope(isolate);
+ DCHECK_LE(1, args.length());
+ CONVERT_SMI_ARG_CHECKED(message_id_smi, 0);
+
+ Handle<Object> undefined = isolate->factory()->undefined_value();
+ Handle<Object> arg0 = (args.length() > 1) ? args.at<Object>(1) : undefined;
+ Handle<Object> arg1 = (args.length() > 2) ? args.at<Object>(2) : undefined;
+ Handle<Object> arg2 = (args.length() > 3) ? args.at<Object>(3) : undefined;
+
+ MessageTemplate::Template message_id =
+ static_cast<MessageTemplate::Template>(message_id_smi);
+
+ THROW_NEW_ERROR_RETURN_FAILURE(isolate,
+ NewTypeError(message_id, arg0, arg1, arg2));
+}
+
RUNTIME_FUNCTION(Runtime_ThrowWasmError) {
HandleScope scope(isolate);
DCHECK_EQ(2, args.length());
CONVERT_SMI_ARG_CHECKED(message_id, 0);
CONVERT_SMI_ARG_CHECKED(byte_offset, 1);
- Handle<Object> error_obj = isolate->factory()->NewError(
+ Handle<Object> error_obj = isolate->factory()->NewWasmRuntimeError(
static_cast<MessageTemplate::Template>(message_id));
// For wasm traps, the byte offset (a.k.a source position) can not be
@@ -270,64 +287,6 @@ RUNTIME_FUNCTION(Runtime_ThrowApplyNonFunction) {
isolate, NewTypeError(MessageTemplate::kApplyNonFunction, object, type));
}
-namespace {
-
-void PromiseRejectEvent(Isolate* isolate, Handle<JSObject> promise,
- Handle<Object> rejected_promise, Handle<Object> value,
- bool debug_event) {
- if (isolate->debug()->is_active() && debug_event) {
- isolate->debug()->OnPromiseReject(rejected_promise, value);
- }
- Handle<Symbol> key = isolate->factory()->promise_has_handler_symbol();
- // Do not report if we actually have a handler.
- if (JSReceiver::GetDataProperty(promise, key)->IsUndefined(isolate)) {
- isolate->ReportPromiseReject(promise, value,
- v8::kPromiseRejectWithNoHandler);
- }
-}
-
-} // namespace
-
-RUNTIME_FUNCTION(Runtime_PromiseRejectEvent) {
- DCHECK(args.length() == 3);
- HandleScope scope(isolate);
- CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
- CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
- CONVERT_BOOLEAN_ARG_CHECKED(debug_event, 2);
-
- PromiseRejectEvent(isolate, promise, promise, value, debug_event);
- return isolate->heap()->undefined_value();
-}
-
-RUNTIME_FUNCTION(Runtime_PromiseRejectEventFromStack) {
- DCHECK(args.length() == 2);
- HandleScope scope(isolate);
- CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
- CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
-
- Handle<Object> rejected_promise = promise;
- if (isolate->debug()->is_active()) {
- // If the Promise.reject call is caught, then this will return
- // undefined, which will be interpreted by PromiseRejectEvent
- // as being a caught exception event.
- rejected_promise = isolate->GetPromiseOnStackOnThrow();
- }
- PromiseRejectEvent(isolate, promise, rejected_promise, value, true);
- return isolate->heap()->undefined_value();
-}
-
-RUNTIME_FUNCTION(Runtime_PromiseRevokeReject) {
- DCHECK(args.length() == 1);
- HandleScope scope(isolate);
- CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
- Handle<Symbol> key = isolate->factory()->promise_has_handler_symbol();
- // At this point, no revocation has been issued before
- CHECK(JSReceiver::GetDataProperty(promise, key)->IsUndefined(isolate));
- isolate->ReportPromiseReject(promise, Handle<Object>(),
- v8::kPromiseHandlerAddedAfterReject);
- return isolate->heap()->undefined_value();
-}
-
RUNTIME_FUNCTION(Runtime_StackGuard) {
SealHandleScope shs(isolate);
@@ -430,10 +389,10 @@ bool ComputeLocation(Isolate* isolate, MessageLocation* target) {
Handle<String> RenderCallSite(Isolate* isolate, Handle<Object> object) {
MessageLocation location;
if (ComputeLocation(isolate, &location)) {
- Zone zone(isolate->allocator());
+ Zone zone(isolate->allocator(), ZONE_NAME);
std::unique_ptr<ParseInfo> info(
location.function()->shared()->is_function()
- ? new ParseInfo(&zone, location.function())
+ ? new ParseInfo(&zone, handle(location.function()->shared()))
: new ParseInfo(&zone, location.script()));
if (Parser::ParseStatic(info.get())) {
CallPrinter printer(isolate, location.function()->shared()->IsBuiltin());
@@ -554,36 +513,6 @@ RUNTIME_FUNCTION(Runtime_GetAndResetRuntimeCallStats) {
}
}
-RUNTIME_FUNCTION(Runtime_EnqueuePromiseResolveThenableJob) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 6);
- CONVERT_ARG_HANDLE_CHECKED(JSReceiver, resolution, 0);
- CONVERT_ARG_HANDLE_CHECKED(JSReceiver, then, 1);
- CONVERT_ARG_HANDLE_CHECKED(JSFunction, resolve, 2);
- CONVERT_ARG_HANDLE_CHECKED(JSFunction, reject, 3);
- CONVERT_ARG_HANDLE_CHECKED(Object, before_debug_event, 4);
- CONVERT_ARG_HANDLE_CHECKED(Object, after_debug_event, 5);
- Handle<PromiseContainer> container = isolate->factory()->NewPromiseContainer(
- resolution, then, resolve, reject, before_debug_event, after_debug_event);
- isolate->EnqueueMicrotask(container);
- return isolate->heap()->undefined_value();
-}
-
-RUNTIME_FUNCTION(Runtime_EnqueueMicrotask) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 1);
- CONVERT_ARG_HANDLE_CHECKED(JSFunction, microtask, 0);
- isolate->EnqueueMicrotask(microtask);
- return isolate->heap()->undefined_value();
-}
-
-RUNTIME_FUNCTION(Runtime_RunMicrotasks) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 0);
- isolate->RunMicrotasks();
- return isolate->heap()->undefined_value();
-}
-
RUNTIME_FUNCTION(Runtime_OrdinaryHasInstance) {
HandleScope scope(isolate);
DCHECK_EQ(2, args.length());
@@ -593,13 +522,13 @@ RUNTIME_FUNCTION(Runtime_OrdinaryHasInstance) {
isolate, Object::OrdinaryHasInstance(isolate, callable, object));
}
-RUNTIME_FUNCTION(Runtime_IsWasmObject) {
+RUNTIME_FUNCTION(Runtime_IsWasmInstance) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
CONVERT_ARG_CHECKED(Object, object, 0);
- bool is_wasm_object =
- object->IsJSObject() && wasm::IsWasmObject(JSObject::cast(object));
- return *isolate->factory()->ToBoolean(is_wasm_object);
+ bool is_wasm_instance =
+ object->IsJSObject() && wasm::IsWasmInstance(JSObject::cast(object));
+ return *isolate->factory()->ToBoolean(is_wasm_instance);
}
RUNTIME_FUNCTION(Runtime_Typeof) {
diff --git a/deps/v8/src/runtime/runtime-interpreter.cc b/deps/v8/src/runtime/runtime-interpreter.cc
index ce71e2c52d..62eee1744f 100644
--- a/deps/v8/src/runtime/runtime-interpreter.cc
+++ b/deps/v8/src/runtime/runtime-interpreter.cc
@@ -171,5 +171,19 @@ RUNTIME_FUNCTION(Runtime_InterpreterSetPendingMessage) {
return isolate->heap()->undefined_value();
}
+RUNTIME_FUNCTION(Runtime_InterpreterAdvanceBytecodeOffset) {
+ SealHandleScope shs(isolate);
+ DCHECK_EQ(2, args.length());
+ CONVERT_ARG_HANDLE_CHECKED(BytecodeArray, bytecode_array, 0);
+ CONVERT_SMI_ARG_CHECKED(bytecode_offset, 1);
+ interpreter::BytecodeArrayIterator it(bytecode_array);
+ int offset = bytecode_offset - BytecodeArray::kHeaderSize + kHeapObjectTag;
+ while (it.current_offset() < offset) it.Advance();
+ DCHECK_EQ(offset, it.current_offset());
+ it.Advance(); // Advance by one bytecode.
+ offset = it.current_offset() + BytecodeArray::kHeaderSize - kHeapObjectTag;
+ return Smi::FromInt(offset);
+}
+
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/runtime/runtime-literals.cc b/deps/v8/src/runtime/runtime-literals.cc
index ebdf04ccae..8bb4522a98 100644
--- a/deps/v8/src/runtime/runtime-literals.cc
+++ b/deps/v8/src/runtime/runtime-literals.cc
@@ -86,7 +86,7 @@ MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate(
if (key->ToArrayIndex(&element_index)) {
// Array index (uint32).
if (value->IsUninitialized(isolate)) {
- value = handle(Smi::FromInt(0), isolate);
+ value = handle(Smi::kZero, isolate);
}
maybe_result = JSObject::SetOwnElementIgnoreAttributes(
boilerplate, element_index, value, NONE);
diff --git a/deps/v8/src/runtime/runtime-maths.cc b/deps/v8/src/runtime/runtime-maths.cc
index 47e560d022..404305a150 100644
--- a/deps/v8/src/runtime/runtime-maths.cc
+++ b/deps/v8/src/runtime/runtime-maths.cc
@@ -15,58 +15,49 @@ namespace internal {
RUNTIME_FUNCTION(Runtime_GenerateRandomNumbers) {
HandleScope scope(isolate);
- DCHECK(args.length() == 1);
- if (isolate->serializer_enabled()) {
- // Random numbers in the snapshot are not really that random. And we cannot
- // return a typed array as it cannot be serialized. To make calling
- // Math.random possible when creating a custom startup snapshot, we simply
- // return a normal array with a single random number.
- Handle<HeapNumber> random_number = isolate->factory()->NewHeapNumber(
- isolate->random_number_generator()->NextDouble());
- Handle<FixedArray> array_backing = isolate->factory()->NewFixedArray(1);
- array_backing->set(0, *random_number);
- return *isolate->factory()->NewJSArrayWithElements(array_backing);
- }
+ DCHECK(args.length() == 0);
+
+ Handle<Context> native_context = isolate->native_context();
+ DCHECK_EQ(0, native_context->math_random_index()->value());
+
+ static const int kCacheSize = 64;
+ static const int kState0Offset = kCacheSize - 1;
+ static const int kState1Offset = kState0Offset - 1;
+ // The index is decremented before used to access the cache.
+ static const int kInitialIndex = kState1Offset;
- static const int kState0Offset = 0;
- static const int kState1Offset = 1;
- static const int kRandomBatchSize = 64;
- CONVERT_ARG_HANDLE_CHECKED(Object, maybe_typed_array, 0);
- Handle<JSTypedArray> typed_array;
- // Allocate typed array if it does not yet exist.
- if (maybe_typed_array->IsJSTypedArray()) {
- typed_array = Handle<JSTypedArray>::cast(maybe_typed_array);
+ Handle<FixedDoubleArray> cache;
+ uint64_t state0 = 0;
+ uint64_t state1 = 0;
+ if (native_context->math_random_cache()->IsFixedDoubleArray()) {
+ cache = Handle<FixedDoubleArray>(
+ FixedDoubleArray::cast(native_context->math_random_cache()), isolate);
+ state0 = double_to_uint64(cache->get_scalar(kState0Offset));
+ state1 = double_to_uint64(cache->get_scalar(kState1Offset));
} else {
- static const int kByteLength = kRandomBatchSize * kDoubleSize;
- Handle<JSArrayBuffer> buffer =
- isolate->factory()->NewJSArrayBuffer(SharedFlag::kNotShared, TENURED);
- JSArrayBuffer::SetupAllocatingData(buffer, isolate, kByteLength, true,
- SharedFlag::kNotShared);
- typed_array = isolate->factory()->NewJSTypedArray(
- kExternalFloat64Array, buffer, 0, kRandomBatchSize);
+ cache = Handle<FixedDoubleArray>::cast(
+ isolate->factory()->NewFixedDoubleArray(kCacheSize, TENURED));
+ native_context->set_math_random_cache(*cache);
+ // Initialize state if not yet initialized.
+ while (state0 == 0 || state1 == 0) {
+ isolate->random_number_generator()->NextBytes(&state0, sizeof(state0));
+ isolate->random_number_generator()->NextBytes(&state1, sizeof(state1));
+ }
}
DisallowHeapAllocation no_gc;
- double* array =
- reinterpret_cast<double*>(typed_array->GetBuffer()->backing_store());
- // Fetch existing state.
- uint64_t state0 = double_to_uint64(array[kState0Offset]);
- uint64_t state1 = double_to_uint64(array[kState1Offset]);
- // Initialize state if not yet initialized.
- while (state0 == 0 || state1 == 0) {
- isolate->random_number_generator()->NextBytes(&state0, sizeof(state0));
- isolate->random_number_generator()->NextBytes(&state1, sizeof(state1));
- }
+ FixedDoubleArray* raw_cache = *cache;
// Create random numbers.
- for (int i = kState1Offset + 1; i < kRandomBatchSize; i++) {
+ for (int i = 0; i < kInitialIndex; i++) {
// Generate random numbers using xorshift128+.
base::RandomNumberGenerator::XorShift128(&state0, &state1);
- array[i] = base::RandomNumberGenerator::ToDouble(state0, state1);
+ raw_cache->set(i, base::RandomNumberGenerator::ToDouble(state0, state1));
}
+
// Persist current state.
- array[kState0Offset] = uint64_to_double(state0);
- array[kState1Offset] = uint64_to_double(state1);
- return *typed_array;
+ raw_cache->set(kState0Offset, uint64_to_double(state0));
+ raw_cache->set(kState1Offset, uint64_to_double(state1));
+ return Smi::FromInt(kInitialIndex);
}
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/runtime/runtime-module.cc b/deps/v8/src/runtime/runtime-module.cc
new file mode 100644
index 0000000000..2b813430e0
--- /dev/null
+++ b/deps/v8/src/runtime/runtime-module.cc
@@ -0,0 +1,39 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/runtime/runtime-utils.h"
+
+#include "src/arguments.h"
+
+namespace v8 {
+namespace internal {
+
+RUNTIME_FUNCTION(Runtime_GetModuleNamespace) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_SMI_ARG_CHECKED(module_request, 0);
+ Handle<Module> module(isolate->context()->module());
+ return *Module::GetModuleNamespace(module, module_request);
+}
+
+RUNTIME_FUNCTION(Runtime_LoadModuleVariable) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_SMI_ARG_CHECKED(index, 0);
+ Handle<Module> module(isolate->context()->module());
+ return *Module::LoadVariable(module, index);
+}
+
+RUNTIME_FUNCTION(Runtime_StoreModuleVariable) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 2);
+ CONVERT_SMI_ARG_CHECKED(index, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
+ Handle<Module> module(isolate->context()->module());
+ Module::StoreVariable(module, index, value);
+ return isolate->heap()->undefined_value();
+}
+
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/src/runtime/runtime-numbers.cc b/deps/v8/src/runtime/runtime-numbers.cc
index 9f43c0acfc..bfe8763e99 100644
--- a/deps/v8/src/runtime/runtime-numbers.cc
+++ b/deps/v8/src/runtime/runtime-numbers.cc
@@ -33,28 +33,40 @@ RUNTIME_FUNCTION(Runtime_StringToNumber) {
// ES6 18.2.5 parseInt(string, radix) slow path
RUNTIME_FUNCTION(Runtime_StringParseInt) {
HandleScope handle_scope(isolate);
- DCHECK(args.length() == 2);
- CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
- CONVERT_NUMBER_CHECKED(int, radix, Int32, args[1]);
- // Step 8.a. is already handled in the JS function.
- CHECK(radix == 0 || (2 <= radix && radix <= 36));
-
+ DCHECK_EQ(2, args.length());
+ CONVERT_ARG_HANDLE_CHECKED(Object, string, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, radix, 1);
+
+ // Convert {string} to a String first, and flatten it.
+ Handle<String> subject;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, subject,
+ Object::ToString(isolate, string));
subject = String::Flatten(subject);
- double value;
+ // Convert {radix} to Int32.
+ if (!radix->IsNumber()) {
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, radix, Object::ToNumber(radix));
+ }
+ int radix32 = DoubleToInt32(radix->Number());
+ if (radix32 != 0 && (radix32 < 2 || radix32 > 36)) {
+ return isolate->heap()->nan_value();
+ }
+
+ double result;
{
DisallowHeapAllocation no_gc;
String::FlatContent flat = subject->GetFlatContent();
if (flat.IsOneByte()) {
- value =
- StringToInt(isolate->unicode_cache(), flat.ToOneByteVector(), radix);
+ result = StringToInt(isolate->unicode_cache(), flat.ToOneByteVector(),
+ radix32);
} else {
- value = StringToInt(isolate->unicode_cache(), flat.ToUC16Vector(), radix);
+ result =
+ StringToInt(isolate->unicode_cache(), flat.ToUC16Vector(), radix32);
}
}
- return *isolate->factory()->NewNumber(value);
+ return *isolate->factory()->NewNumber(result);
}
diff --git a/deps/v8/src/runtime/runtime-object.cc b/deps/v8/src/runtime/runtime-object.cc
index 70ed23ba61..c7e9cf3c92 100644
--- a/deps/v8/src/runtime/runtime-object.cc
+++ b/deps/v8/src/runtime/runtime-object.cc
@@ -207,6 +207,70 @@ RUNTIME_FUNCTION(Runtime_ObjectHasOwnProperty) {
return isolate->heap()->false_value();
}
+// ES6 section 19.1.2.2 Object.create ( O [ , Properties ] )
+// TODO(verwaest): Support the common cases with precached map directly in
+// an Object.create stub.
+RUNTIME_FUNCTION(Runtime_ObjectCreate) {
+ HandleScope scope(isolate);
+ Handle<Object> prototype = args.at<Object>(0);
+ if (!prototype->IsNull(isolate) && !prototype->IsJSReceiver()) {
+ THROW_NEW_ERROR_RETURN_FAILURE(
+ isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, prototype));
+ }
+
+ // Generate the map with the specified {prototype} based on the Object
+ // function's initial map from the current native context.
+ // TODO(bmeurer): Use a dedicated cache for Object.create; think about
+ // slack tracking for Object.create.
+ Handle<Map> map(isolate->native_context()->object_function()->initial_map(),
+ isolate);
+ if (map->prototype() != *prototype) {
+ if (prototype->IsNull(isolate)) {
+ map = isolate->slow_object_with_null_prototype_map();
+ } else if (prototype->IsJSObject()) {
+ Handle<JSObject> js_prototype = Handle<JSObject>::cast(prototype);
+ if (!js_prototype->map()->is_prototype_map()) {
+ JSObject::OptimizeAsPrototype(js_prototype, FAST_PROTOTYPE);
+ }
+ Handle<PrototypeInfo> info =
+ Map::GetOrCreatePrototypeInfo(js_prototype, isolate);
+ // TODO(verwaest): Use inobject slack tracking for this map.
+ if (info->HasObjectCreateMap()) {
+ map = handle(info->ObjectCreateMap(), isolate);
+ } else {
+ map = Map::CopyInitialMap(map);
+ Map::SetPrototype(map, prototype, FAST_PROTOTYPE);
+ PrototypeInfo::SetObjectCreateMap(info, map);
+ }
+ } else {
+ map = Map::TransitionToPrototype(map, prototype, REGULAR_PROTOTYPE);
+ }
+ }
+
+ bool is_dictionary_map = map->is_dictionary_map();
+ Handle<FixedArray> object_properties;
+ if (is_dictionary_map) {
+ // Allocate the actual properties dictionay up front to avoid invalid object
+ // state.
+ object_properties =
+ NameDictionary::New(isolate, NameDictionary::kInitialCapacity);
+ }
+ // Actually allocate the object.
+ Handle<JSObject> object = isolate->factory()->NewJSObjectFromMap(map);
+ if (is_dictionary_map) {
+ object->set_properties(*object_properties);
+ }
+
+ // Define the properties if properties was specified and is not undefined.
+ Handle<Object> properties = args.at<Object>(1);
+ if (!properties->IsUndefined(isolate)) {
+ RETURN_FAILURE_ON_EXCEPTION(
+ isolate, JSReceiver::DefineProperties(isolate, object, properties));
+ }
+
+ return *object;
+}
+
MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate,
Handle<Object> object,
Handle<Object> key,
@@ -250,18 +314,6 @@ RUNTIME_FUNCTION(Runtime_InternalSetPrototype) {
return *obj;
}
-
-RUNTIME_FUNCTION(Runtime_SetPrototype) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 2);
- CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0);
- CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
- MAYBE_RETURN(
- JSReceiver::SetPrototype(obj, prototype, true, Object::THROW_ON_ERROR),
- isolate->heap()->exception());
- return *obj;
-}
-
RUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties) {
HandleScope scope(isolate);
DCHECK(args.length() == 2);
@@ -277,64 +329,6 @@ RUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties) {
}
-namespace {
-
-Object* StoreGlobalViaContext(Isolate* isolate, int slot, Handle<Object> value,
- LanguageMode language_mode) {
- // Go up context chain to the script context.
- Handle<Context> script_context(isolate->context()->script_context(), isolate);
- DCHECK(script_context->IsScriptContext());
- DCHECK(script_context->get(slot)->IsPropertyCell());
-
- // Lookup the named property on the global object.
- Handle<ScopeInfo> scope_info(script_context->scope_info(), isolate);
- Handle<Name> name(scope_info->ContextSlotName(slot), isolate);
- Handle<JSGlobalObject> global_object(script_context->global_object(),
- isolate);
- LookupIterator it(global_object, name, global_object, LookupIterator::OWN);
-
- // Switch to fast mode only if there is a data property and it's not on
- // a hidden prototype.
- if (it.state() == LookupIterator::DATA &&
- it.GetHolder<Object>().is_identical_to(global_object)) {
- // Now update cell in the script context.
- Handle<PropertyCell> cell = it.GetPropertyCell();
- script_context->set(slot, *cell);
- } else {
- // This is not a fast case, so keep this access in a slow mode.
- // Store empty_property_cell here to release the outdated property cell.
- script_context->set(slot, isolate->heap()->empty_property_cell());
- }
-
- MAYBE_RETURN(Object::SetProperty(&it, value, language_mode,
- Object::CERTAINLY_NOT_STORE_FROM_KEYED),
- isolate->heap()->exception());
- return *value;
-}
-
-} // namespace
-
-
-RUNTIME_FUNCTION(Runtime_StoreGlobalViaContext_Sloppy) {
- HandleScope scope(isolate);
- DCHECK_EQ(2, args.length());
- CONVERT_SMI_ARG_CHECKED(slot, 0);
- CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
-
- return StoreGlobalViaContext(isolate, slot, value, SLOPPY);
-}
-
-
-RUNTIME_FUNCTION(Runtime_StoreGlobalViaContext_Strict) {
- HandleScope scope(isolate);
- DCHECK_EQ(2, args.length());
- CONVERT_SMI_ARG_CHECKED(slot, 0);
- CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
-
- return StoreGlobalViaContext(isolate, slot, value, STRICT);
-}
-
-
RUNTIME_FUNCTION(Runtime_GetProperty) {
HandleScope scope(isolate);
DCHECK(args.length() == 2);
@@ -530,7 +524,7 @@ RUNTIME_FUNCTION(Runtime_GetInterceptorInfo) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
if (!args[0]->IsJSObject()) {
- return Smi::FromInt(0);
+ return Smi::kZero;
}
CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
@@ -604,14 +598,14 @@ RUNTIME_FUNCTION(Runtime_TryMigrateInstance) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
- if (!object->IsJSObject()) return Smi::FromInt(0);
+ if (!object->IsJSObject()) return Smi::kZero;
Handle<JSObject> js_object = Handle<JSObject>::cast(object);
- if (!js_object->map()->is_deprecated()) return Smi::FromInt(0);
+ if (!js_object->map()->is_deprecated()) return Smi::kZero;
// This call must not cause lazy deopts, because it's called from deferred
// code where we can't handle lazy deopts for lack of a suitable bailout
// ID. So we just try migration and signal failure if necessary,
// which will also trigger a deopt.
- if (!JSObject::TryMigrateInstance(js_object)) return Smi::FromInt(0);
+ if (!JSObject::TryMigrateInstance(js_object)) return Smi::kZero;
return *object;
}
@@ -928,13 +922,20 @@ RUNTIME_FUNCTION(Runtime_CreateIterResultObject) {
DCHECK_EQ(2, args.length());
CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, done, 1);
- Handle<JSObject> result =
- isolate->factory()->NewJSObjectFromMap(isolate->iterator_result_map());
- result->InObjectPropertyAtPut(JSIteratorResult::kValueIndex, *value);
- result->InObjectPropertyAtPut(JSIteratorResult::kDoneIndex, *done);
- return *result;
+ return *isolate->factory()->NewJSIteratorResult(value, done->BooleanValue());
}
+RUNTIME_FUNCTION(Runtime_CreateKeyValueArray) {
+ HandleScope scope(isolate);
+ DCHECK_EQ(2, args.length());
+ CONVERT_ARG_HANDLE_CHECKED(Object, key, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
+ Handle<FixedArray> elements = isolate->factory()->NewFixedArray(2);
+ elements->set(0, *key);
+ elements->set(1, *value);
+ return *isolate->factory()->NewJSArrayWithElements(elements, FAST_ELEMENTS,
+ 2);
+}
RUNTIME_FUNCTION(Runtime_IsAccessCheckNeeded) {
SealHandleScope shs(isolate);
@@ -960,32 +961,6 @@ RUNTIME_FUNCTION(Runtime_CreateDataProperty) {
return *value;
}
-RUNTIME_FUNCTION(Runtime_LoadModuleExport) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 1);
- CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
- Handle<Module> module(isolate->context()->module());
- return *Module::LoadExport(module, name);
-}
-
-RUNTIME_FUNCTION(Runtime_LoadModuleImport) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 2);
- CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
- CONVERT_ARG_HANDLE_CHECKED(Smi, module_request, 1);
- Handle<Module> module(isolate->context()->module());
- return *Module::LoadImport(module, name, module_request->value());
-}
-
-RUNTIME_FUNCTION(Runtime_StoreModuleExport) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 2);
- CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
- CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
- Handle<Module> module(isolate->context()->module());
- Module::StoreExport(module, name, value);
- return isolate->heap()->undefined_value();
-}
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/runtime/runtime-promise.cc b/deps/v8/src/runtime/runtime-promise.cc
new file mode 100644
index 0000000000..226993a50e
--- /dev/null
+++ b/deps/v8/src/runtime/runtime-promise.cc
@@ -0,0 +1,193 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/runtime/runtime-utils.h"
+
+#include "src/debug/debug.h"
+#include "src/elements.h"
+#include "src/promise-utils.h"
+
+namespace v8 {
+namespace internal {
+
+namespace {
+
+void PromiseRejectEvent(Isolate* isolate, Handle<JSReceiver> promise,
+ Handle<Object> rejected_promise, Handle<Object> value,
+ bool debug_event) {
+ if (isolate->debug()->is_active() && debug_event) {
+ isolate->debug()->OnPromiseReject(rejected_promise, value);
+ }
+ Handle<Symbol> key = isolate->factory()->promise_has_handler_symbol();
+ // Do not report if we actually have a handler.
+ if (JSReceiver::GetDataProperty(promise, key)->IsUndefined(isolate)) {
+ isolate->ReportPromiseReject(Handle<JSObject>::cast(promise), value,
+ v8::kPromiseRejectWithNoHandler);
+ }
+}
+
+} // namespace
+
+RUNTIME_FUNCTION(Runtime_PromiseRejectEventFromStack) {
+ DCHECK(args.length() == 2);
+ HandleScope scope(isolate);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
+
+ Handle<Object> rejected_promise = promise;
+ if (isolate->debug()->is_active()) {
+ // If the Promise.reject call is caught, then this will return
+ // undefined, which will be interpreted by PromiseRejectEvent
+ // as being a caught exception event.
+ rejected_promise = isolate->GetPromiseOnStackOnThrow();
+ }
+ PromiseRejectEvent(isolate, promise, rejected_promise, value, true);
+ return isolate->heap()->undefined_value();
+}
+
+RUNTIME_FUNCTION(Runtime_PromiseRevokeReject) {
+ DCHECK(args.length() == 1);
+ HandleScope scope(isolate);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
+ Handle<Symbol> key = isolate->factory()->promise_has_handler_symbol();
+ // At this point, no revocation has been issued before
+ CHECK(JSReceiver::GetDataProperty(promise, key)->IsUndefined(isolate));
+ isolate->ReportPromiseReject(promise, Handle<Object>(),
+ v8::kPromiseHandlerAddedAfterReject);
+ return isolate->heap()->undefined_value();
+}
+
+namespace {
+void EnqueuePromiseReactionJob(Isolate* isolate, Handle<Object> value,
+ Handle<Object> tasks, Handle<Object> deferred,
+ Handle<Object> status) {
+ Handle<Object> debug_id = isolate->factory()->undefined_value();
+ Handle<Object> debug_name = isolate->factory()->undefined_value();
+ if (isolate->debug()->is_active()) {
+ MaybeHandle<Object> maybe_result;
+ Handle<Object> argv[] = {deferred, status};
+ maybe_result = Execution::TryCall(
+ isolate, isolate->promise_debug_get_info(),
+ isolate->factory()->undefined_value(), arraysize(argv), argv);
+ Handle<Object> result;
+ if ((maybe_result).ToHandle(&result)) {
+ CHECK(result->IsJSArray());
+ Handle<JSArray> array = Handle<JSArray>::cast(result);
+ ElementsAccessor* accessor = array->GetElementsAccessor();
+ DCHECK(accessor->HasElement(array, 0));
+ DCHECK(accessor->HasElement(array, 1));
+ debug_id = accessor->Get(array, 0);
+ debug_name = accessor->Get(array, 1);
+ }
+ }
+ Handle<PromiseReactionJobInfo> info =
+ isolate->factory()->NewPromiseReactionJobInfo(value, tasks, deferred,
+ debug_id, debug_name,
+ isolate->native_context());
+ isolate->EnqueueMicrotask(info);
+}
+
+void PromiseFulfill(Isolate* isolate, Handle<JSReceiver> promise,
+ Handle<Smi> status, Handle<Object> value,
+ Handle<Symbol> reaction) {
+ Handle<Object> tasks = JSReceiver::GetDataProperty(promise, reaction);
+ if (!tasks->IsUndefined(isolate)) {
+ Handle<Object> deferred = JSReceiver::GetDataProperty(
+ promise, isolate->factory()->promise_deferred_reaction_symbol());
+ EnqueuePromiseReactionJob(isolate, value, tasks, deferred, status);
+ }
+}
+} // namespace
+
+RUNTIME_FUNCTION(Runtime_PromiseReject) {
+ DCHECK(args.length() == 3);
+ HandleScope scope(isolate);
+ CONVERT_ARG_HANDLE_CHECKED(JSReceiver, promise, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, reason, 1);
+ CONVERT_BOOLEAN_ARG_CHECKED(debug_event, 2);
+
+ PromiseRejectEvent(isolate, promise, promise, reason, debug_event);
+
+ Handle<Smi> status = handle(Smi::FromInt(kPromiseRejected), isolate);
+ Handle<Symbol> reaction =
+ isolate->factory()->promise_reject_reactions_symbol();
+ PromiseFulfill(isolate, promise, status, reason, reaction);
+ return isolate->heap()->undefined_value();
+}
+
+RUNTIME_FUNCTION(Runtime_PromiseFulfill) {
+ DCHECK(args.length() == 4);
+ HandleScope scope(isolate);
+ CONVERT_ARG_HANDLE_CHECKED(JSReceiver, promise, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Smi, status, 1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
+ CONVERT_ARG_HANDLE_CHECKED(Symbol, reaction, 3);
+ PromiseFulfill(isolate, promise, status, value, reaction);
+ return isolate->heap()->undefined_value();
+}
+
+RUNTIME_FUNCTION(Runtime_EnqueuePromiseReactionJob) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 4);
+ CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, tasks, 1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, deferred, 2);
+ CONVERT_ARG_HANDLE_CHECKED(Object, status, 3);
+ EnqueuePromiseReactionJob(isolate, value, tasks, deferred, status);
+ return isolate->heap()->undefined_value();
+}
+
+RUNTIME_FUNCTION(Runtime_EnqueuePromiseResolveThenableJob) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 3);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSReceiver, resolution, 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSReceiver, then, 2);
+
+ // TODO(gsathya): Add fast path for native promises with unmodified
+ // PromiseThen (which don't need these resolving functions, but
+ // instead can just call resolve/reject directly).
+ Handle<JSFunction> resolve, reject;
+ PromiseUtils::CreateResolvingFunctions(
+ isolate, promise, isolate->factory()->false_value(), &resolve, &reject);
+
+ Handle<Object> debug_id, debug_name;
+ if (isolate->debug()->is_active()) {
+ debug_id =
+ handle(Smi::FromInt(isolate->GetNextDebugMicrotaskId()), isolate);
+ debug_name = isolate->factory()->PromiseResolveThenableJob_string();
+ isolate->debug()->OnAsyncTaskEvent(isolate->factory()->enqueue_string(),
+ debug_id,
+ Handle<String>::cast(debug_name));
+ } else {
+ debug_id = isolate->factory()->undefined_value();
+ debug_name = isolate->factory()->undefined_value();
+ }
+
+ Handle<PromiseResolveThenableJobInfo> info =
+ isolate->factory()->NewPromiseResolveThenableJobInfo(
+ resolution, then, resolve, reject, debug_id, debug_name,
+ isolate->native_context());
+ isolate->EnqueueMicrotask(info);
+
+ return isolate->heap()->undefined_value();
+}
+
+RUNTIME_FUNCTION(Runtime_EnqueueMicrotask) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, microtask, 0);
+ isolate->EnqueueMicrotask(microtask);
+ return isolate->heap()->undefined_value();
+}
+
+RUNTIME_FUNCTION(Runtime_RunMicrotasks) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 0);
+ isolate->RunMicrotasks();
+ return isolate->heap()->undefined_value();
+}
+
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/src/runtime/runtime-regexp.cc b/deps/v8/src/runtime/runtime-regexp.cc
index 977e6bc48f..d572eedd31 100644
--- a/deps/v8/src/runtime/runtime-regexp.cc
+++ b/deps/v8/src/runtime/runtime-regexp.cc
@@ -10,6 +10,7 @@
#include "src/messages.h"
#include "src/regexp/jsregexp-inl.h"
#include "src/regexp/jsregexp.h"
+#include "src/regexp/regexp-utils.h"
#include "src/string-builder.h"
#include "src/string-search.h"
@@ -279,10 +280,8 @@ void CompiledReplacement::Apply(ReplacementStringBuilder* builder,
}
}
-
void FindOneByteStringIndices(Vector<const uint8_t> subject, uint8_t pattern,
- ZoneList<int>* indices, unsigned int limit,
- Zone* zone) {
+ List<int>* indices, unsigned int limit) {
DCHECK(limit > 0);
// Collect indices of pattern in subject using memchr.
// Stop after finding at most limit values.
@@ -293,32 +292,29 @@ void FindOneByteStringIndices(Vector<const uint8_t> subject, uint8_t pattern,
pos = reinterpret_cast<const uint8_t*>(
memchr(pos, pattern, subject_end - pos));
if (pos == NULL) return;
- indices->Add(static_cast<int>(pos - subject_start), zone);
+ indices->Add(static_cast<int>(pos - subject_start));
pos++;
limit--;
}
}
-
void FindTwoByteStringIndices(const Vector<const uc16> subject, uc16 pattern,
- ZoneList<int>* indices, unsigned int limit,
- Zone* zone) {
+ List<int>* indices, unsigned int limit) {
DCHECK(limit > 0);
const uc16* subject_start = subject.start();
const uc16* subject_end = subject_start + subject.length();
for (const uc16* pos = subject_start; pos < subject_end && limit > 0; pos++) {
if (*pos == pattern) {
- indices->Add(static_cast<int>(pos - subject_start), zone);
+ indices->Add(static_cast<int>(pos - subject_start));
limit--;
}
}
}
-
template <typename SubjectChar, typename PatternChar>
void FindStringIndices(Isolate* isolate, Vector<const SubjectChar> subject,
- Vector<const PatternChar> pattern,
- ZoneList<int>* indices, unsigned int limit, Zone* zone) {
+ Vector<const PatternChar> pattern, List<int>* indices,
+ unsigned int limit) {
DCHECK(limit > 0);
// Collect indices of pattern in subject.
// Stop after finding at most limit values.
@@ -328,16 +324,15 @@ void FindStringIndices(Isolate* isolate, Vector<const SubjectChar> subject,
while (limit > 0) {
index = search.Search(subject, index);
if (index < 0) return;
- indices->Add(index, zone);
+ indices->Add(index);
index += pattern_length;
limit--;
}
}
-
void FindStringIndicesDispatch(Isolate* isolate, String* subject,
- String* pattern, ZoneList<int>* indices,
- unsigned int limit, Zone* zone) {
+ String* pattern, List<int>* indices,
+ unsigned int limit) {
{
DisallowHeapAllocation no_gc;
String::FlatContent subject_content = subject->GetFlatContent();
@@ -351,14 +346,14 @@ void FindStringIndicesDispatch(Isolate* isolate, String* subject,
pattern_content.ToOneByteVector();
if (pattern_vector.length() == 1) {
FindOneByteStringIndices(subject_vector, pattern_vector[0], indices,
- limit, zone);
+ limit);
} else {
FindStringIndices(isolate, subject_vector, pattern_vector, indices,
- limit, zone);
+ limit);
}
} else {
FindStringIndices(isolate, subject_vector,
- pattern_content.ToUC16Vector(), indices, limit, zone);
+ pattern_content.ToUC16Vector(), indices, limit);
}
} else {
Vector<const uc16> subject_vector = subject_content.ToUC16Vector();
@@ -367,34 +362,51 @@ void FindStringIndicesDispatch(Isolate* isolate, String* subject,
pattern_content.ToOneByteVector();
if (pattern_vector.length() == 1) {
FindTwoByteStringIndices(subject_vector, pattern_vector[0], indices,
- limit, zone);
+ limit);
} else {
FindStringIndices(isolate, subject_vector, pattern_vector, indices,
- limit, zone);
+ limit);
}
} else {
Vector<const uc16> pattern_vector = pattern_content.ToUC16Vector();
if (pattern_vector.length() == 1) {
FindTwoByteStringIndices(subject_vector, pattern_vector[0], indices,
- limit, zone);
+ limit);
} else {
FindStringIndices(isolate, subject_vector, pattern_vector, indices,
- limit, zone);
+ limit);
}
}
}
}
}
+namespace {
+List<int>* GetRewoundRegexpIndicesList(Isolate* isolate) {
+ List<int>* list = isolate->regexp_indices();
+ list->Rewind(0);
+ return list;
+}
+
+void TruncateRegexpIndicesList(Isolate* isolate) {
+ // Same size as smallest zone segment, preserving behavior from the
+ // runtime zone.
+ static const int kMaxRegexpIndicesListCapacity = 8 * KB;
+ if (isolate->regexp_indices()->capacity() > kMaxRegexpIndicesListCapacity) {
+ isolate->regexp_indices()->Clear(); // Throw away backing storage
+ }
+}
+} // namespace
+
template <typename ResultSeqString>
MUST_USE_RESULT static Object* StringReplaceGlobalAtomRegExpWithString(
Isolate* isolate, Handle<String> subject, Handle<JSRegExp> pattern_regexp,
- Handle<String> replacement, Handle<JSObject> last_match_info) {
+ Handle<String> replacement, Handle<RegExpMatchInfo> last_match_info) {
DCHECK(subject->IsFlat());
DCHECK(replacement->IsFlat());
- ZoneScope zone_scope(isolate->runtime_zone());
- ZoneList<int> indices(8, zone_scope.zone());
+ List<int>* indices = GetRewoundRegexpIndicesList(isolate);
+
DCHECK_EQ(JSRegExp::ATOM, pattern_regexp->TypeTag());
String* pattern =
String::cast(pattern_regexp->DataAt(JSRegExp::kAtomPatternIndex));
@@ -402,10 +414,9 @@ MUST_USE_RESULT static Object* StringReplaceGlobalAtomRegExpWithString(
int pattern_len = pattern->length();
int replacement_len = replacement->length();
- FindStringIndicesDispatch(isolate, *subject, pattern, &indices, 0xffffffff,
- zone_scope.zone());
+ FindStringIndicesDispatch(isolate, *subject, pattern, indices, 0xffffffff);
- int matches = indices.length();
+ int matches = indices->length();
if (matches == 0) return *subject;
// Detect integer overflow.
@@ -436,10 +447,10 @@ MUST_USE_RESULT static Object* StringReplaceGlobalAtomRegExpWithString(
for (int i = 0; i < matches; i++) {
// Copy non-matched subject content.
- if (subject_pos < indices.at(i)) {
+ if (subject_pos < indices->at(i)) {
String::WriteToFlat(*subject, result->GetChars() + result_pos,
- subject_pos, indices.at(i));
- result_pos += indices.at(i) - subject_pos;
+ subject_pos, indices->at(i));
+ result_pos += indices->at(i) - subject_pos;
}
// Replace match.
@@ -449,7 +460,7 @@ MUST_USE_RESULT static Object* StringReplaceGlobalAtomRegExpWithString(
result_pos += replacement_len;
}
- subject_pos = indices.at(i) + pattern_len;
+ subject_pos = indices->at(i) + pattern_len;
}
// Add remaining subject content at the end.
if (subject_pos < subject_len) {
@@ -457,16 +468,18 @@ MUST_USE_RESULT static Object* StringReplaceGlobalAtomRegExpWithString(
subject_len);
}
- int32_t match_indices[] = {indices.at(matches - 1),
- indices.at(matches - 1) + pattern_len};
+ int32_t match_indices[] = {indices->at(matches - 1),
+ indices->at(matches - 1) + pattern_len};
RegExpImpl::SetLastMatchInfo(last_match_info, subject, 0, match_indices);
+ TruncateRegexpIndicesList(isolate);
+
return *result;
}
MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithString(
Isolate* isolate, Handle<String> subject, Handle<JSRegExp> regexp,
- Handle<String> replacement, Handle<JSObject> last_match_info) {
+ Handle<String> replacement, Handle<RegExpMatchInfo> last_match_info) {
DCHECK(subject->IsFlat());
DCHECK(replacement->IsFlat());
@@ -474,8 +487,8 @@ MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithString(
int subject_length = subject->length();
// CompiledReplacement uses zone allocation.
- ZoneScope zone_scope(isolate->runtime_zone());
- CompiledReplacement compiled_replacement(zone_scope.zone());
+ Zone zone(isolate->allocator(), ZONE_NAME);
+ CompiledReplacement compiled_replacement(&zone);
bool simple_replace =
compiled_replacement.Compile(replacement, capture_count, subject_length);
@@ -548,7 +561,7 @@ MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithString(
template <typename ResultSeqString>
MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithEmptyString(
Isolate* isolate, Handle<String> subject, Handle<JSRegExp> regexp,
- Handle<JSObject> last_match_info) {
+ Handle<RegExpMatchInfo> last_match_info) {
DCHECK(subject->IsFlat());
// Shortcut for simple non-regexp global replacements
@@ -643,18 +656,12 @@ MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithEmptyString(
return *answer;
}
+namespace {
-RUNTIME_FUNCTION(Runtime_StringReplaceGlobalRegExpWithString) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 4);
-
- CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
- CONVERT_ARG_HANDLE_CHECKED(String, replacement, 2);
- CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
- CONVERT_ARG_HANDLE_CHECKED(JSObject, last_match_info, 3);
-
+Object* StringReplaceGlobalRegExpWithStringHelper(
+ Isolate* isolate, Handle<JSRegExp> regexp, Handle<String> subject,
+ Handle<String> replacement, Handle<RegExpMatchInfo> last_match_info) {
CHECK(regexp->GetFlags() & JSRegExp::kGlobal);
- CHECK(last_match_info->HasFastObjectElements());
subject = String::Flatten(subject);
@@ -674,6 +681,20 @@ RUNTIME_FUNCTION(Runtime_StringReplaceGlobalRegExpWithString) {
replacement, last_match_info);
}
+} // namespace
+
+RUNTIME_FUNCTION(Runtime_StringReplaceGlobalRegExpWithString) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 4);
+
+ CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, replacement, 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
+ CONVERT_ARG_HANDLE_CHECKED(RegExpMatchInfo, last_match_info, 3);
+
+ return StringReplaceGlobalRegExpWithStringHelper(
+ isolate, regexp, subject, replacement, last_match_info);
+}
RUNTIME_FUNCTION(Runtime_StringSplit) {
HandleScope handle_scope(isolate);
@@ -694,7 +715,7 @@ RUNTIME_FUNCTION(Runtime_StringSplit) {
&last_match_cache_unused,
RegExpResultsCache::STRING_SPLIT_SUBSTRINGS),
isolate);
- if (*cached_answer != Smi::FromInt(0)) {
+ if (*cached_answer != Smi::kZero) {
// The cache FixedArray is a COW-array and can therefore be reused.
Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(
Handle<FixedArray>::cast(cached_answer));
@@ -709,25 +730,18 @@ RUNTIME_FUNCTION(Runtime_StringSplit) {
subject = String::Flatten(subject);
pattern = String::Flatten(pattern);
- static const int kMaxInitialListCapacity = 16;
+ List<int>* indices = GetRewoundRegexpIndicesList(isolate);
- ZoneScope zone_scope(isolate->runtime_zone());
+ FindStringIndicesDispatch(isolate, *subject, *pattern, indices, limit);
- // Find (up to limit) indices of separator and end-of-string in subject
- int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit);
- ZoneList<int> indices(initial_capacity, zone_scope.zone());
-
- FindStringIndicesDispatch(isolate, *subject, *pattern, &indices, limit,
- zone_scope.zone());
-
- if (static_cast<uint32_t>(indices.length()) < limit) {
- indices.Add(subject_length, zone_scope.zone());
+ if (static_cast<uint32_t>(indices->length()) < limit) {
+ indices->Add(subject_length);
}
// The list indices now contains the end of each part to create.
// Create JSArray of substrings separated by separator.
- int part_count = indices.length();
+ int part_count = indices->length();
Handle<JSArray> result =
isolate->factory()->NewJSArray(FAST_ELEMENTS, part_count, part_count,
@@ -737,12 +751,12 @@ RUNTIME_FUNCTION(Runtime_StringSplit) {
Handle<FixedArray> elements(FixedArray::cast(result->elements()));
- if (part_count == 1 && indices.at(0) == subject_length) {
+ if (part_count == 1 && indices->at(0) == subject_length) {
elements->set(0, *subject);
} else {
int part_start = 0;
FOR_WITH_HANDLE_SCOPE(isolate, int, i = 0, i, i < part_count, i++, {
- int part_end = indices.at(i);
+ int part_end = indices->at(i);
Handle<String> substring =
isolate->factory()->NewProperSubString(subject, part_start, part_end);
elements->set(i, *substring);
@@ -758,9 +772,37 @@ RUNTIME_FUNCTION(Runtime_StringSplit) {
}
}
+ TruncateRegexpIndicesList(isolate);
+
return *result;
}
+// ES##sec-regexpcreate
+// RegExpCreate ( P, F )
+RUNTIME_FUNCTION(Runtime_RegExpCreate) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, source_object, 0);
+
+ Handle<String> source;
+ if (source_object->IsUndefined(isolate)) {
+ source = isolate->factory()->empty_string();
+ } else {
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, source, Object::ToString(isolate, source_object));
+ }
+
+ Handle<Map> map(isolate->regexp_function()->initial_map());
+ Handle<JSRegExp> regexp =
+ Handle<JSRegExp>::cast(isolate->factory()->NewJSObjectFromMap(map));
+
+ JSRegExp::Flags flags = JSRegExp::kNone;
+
+ RETURN_FAILURE_ON_EXCEPTION(isolate,
+ JSRegExp::Initialize(regexp, source, flags));
+
+ return *regexp;
+}
RUNTIME_FUNCTION(Runtime_RegExpExec) {
HandleScope scope(isolate);
@@ -768,7 +810,7 @@ RUNTIME_FUNCTION(Runtime_RegExpExec) {
CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
CONVERT_INT32_ARG_CHECKED(index, 2);
- CONVERT_ARG_HANDLE_CHECKED(JSObject, last_match_info, 3);
+ CONVERT_ARG_HANDLE_CHECKED(RegExpMatchInfo, last_match_info, 3);
// Due to the way the JS calls are constructed this must be less than the
// length of a string, i.e. it is always a Smi. We check anyway for security.
CHECK(index >= 0);
@@ -778,64 +820,116 @@ RUNTIME_FUNCTION(Runtime_RegExpExec) {
isolate, RegExpImpl::Exec(regexp, subject, index, last_match_info));
}
+RUNTIME_FUNCTION(Runtime_RegExpInternalReplace) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 3);
+ CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
+ CONVERT_ARG_HANDLE_CHECKED(String, replacement, 2);
-RUNTIME_FUNCTION(Runtime_RegExpFlags) {
- SealHandleScope shs(isolate);
- DCHECK(args.length() == 1);
- CONVERT_ARG_CHECKED(JSRegExp, regexp, 0);
- return regexp->flags();
+ Handle<RegExpMatchInfo> internal_match_info =
+ isolate->regexp_internal_match_info();
+
+ return StringReplaceGlobalRegExpWithStringHelper(
+ isolate, regexp, subject, replacement, internal_match_info);
}
+namespace {
-RUNTIME_FUNCTION(Runtime_RegExpSource) {
- SealHandleScope shs(isolate);
- DCHECK(args.length() == 1);
- CONVERT_ARG_CHECKED(JSRegExp, regexp, 0);
- return regexp->source();
-}
+class MatchInfoBackedMatch : public String::Match {
+ public:
+ MatchInfoBackedMatch(Isolate* isolate, Handle<String> subject,
+ Handle<RegExpMatchInfo> match_info)
+ : isolate_(isolate), match_info_(match_info) {
+ subject_ = String::Flatten(subject);
+ }
-// TODO(jgruber): Remove this once all uses in regexp.js have been removed.
-RUNTIME_FUNCTION(Runtime_RegExpConstructResult) {
- HandleScope handle_scope(isolate);
- DCHECK(args.length() == 3);
- CONVERT_SMI_ARG_CHECKED(size, 0);
- CHECK(size >= 0 && size <= FixedArray::kMaxLength);
- CONVERT_ARG_HANDLE_CHECKED(Object, index, 1);
- CONVERT_ARG_HANDLE_CHECKED(Object, input, 2);
- Handle<FixedArray> elements = isolate->factory()->NewFixedArray(size);
- Handle<Map> regexp_map(isolate->native_context()->regexp_result_map());
- Handle<JSObject> object =
- isolate->factory()->NewJSObjectFromMap(regexp_map, NOT_TENURED);
- Handle<JSArray> array = Handle<JSArray>::cast(object);
- array->set_elements(*elements);
- array->set_length(Smi::FromInt(size));
- // Write in-object properties after the length of the array.
- array->InObjectPropertyAtPut(JSRegExpResult::kIndexIndex, *index);
- array->InObjectPropertyAtPut(JSRegExpResult::kInputIndex, *input);
- return *array;
-}
+ Handle<String> GetMatch() override {
+ return RegExpUtils::GenericCaptureGetter(isolate_, match_info_, 0, nullptr);
+ }
+ MaybeHandle<String> GetCapture(int i, bool* capture_exists) override {
+ Handle<Object> capture_obj = RegExpUtils::GenericCaptureGetter(
+ isolate_, match_info_, i, capture_exists);
+ return (*capture_exists) ? Object::ToString(isolate_, capture_obj)
+ : isolate_->factory()->empty_string();
+ }
-RUNTIME_FUNCTION(Runtime_RegExpInitializeAndCompile) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 3);
- CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
- CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
- CONVERT_ARG_HANDLE_CHECKED(String, flags, 2);
+ Handle<String> GetPrefix() override {
+ const int match_start = match_info_->Capture(0);
+ return isolate_->factory()->NewSubString(subject_, 0, match_start);
+ }
- RETURN_FAILURE_ON_EXCEPTION(isolate,
- JSRegExp::Initialize(regexp, source, flags));
+ Handle<String> GetSuffix() override {
+ const int match_end = match_info_->Capture(1);
+ return isolate_->factory()->NewSubString(subject_, match_end,
+ subject_->length());
+ }
- return *regexp;
-}
+ int CaptureCount() override {
+ return match_info_->NumberOfCaptureRegisters() / 2;
+ }
+
+ virtual ~MatchInfoBackedMatch() {}
+
+ private:
+ Isolate* isolate_;
+ Handle<String> subject_;
+ Handle<RegExpMatchInfo> match_info_;
+};
+
+class VectorBackedMatch : public String::Match {
+ public:
+ VectorBackedMatch(Isolate* isolate, Handle<String> subject,
+ Handle<String> match, int match_position,
+ ZoneVector<Handle<Object>>* captures)
+ : isolate_(isolate),
+ match_(match),
+ match_position_(match_position),
+ captures_(captures) {
+ subject_ = String::Flatten(subject);
+ }
+
+ Handle<String> GetMatch() override { return match_; }
+
+ MaybeHandle<String> GetCapture(int i, bool* capture_exists) override {
+ Handle<Object> capture_obj = captures_->at(i);
+ if (capture_obj->IsUndefined(isolate_)) {
+ *capture_exists = false;
+ return isolate_->factory()->empty_string();
+ }
+ *capture_exists = true;
+ return Object::ToString(isolate_, capture_obj);
+ }
+ Handle<String> GetPrefix() override {
+ return isolate_->factory()->NewSubString(subject_, 0, match_position_);
+ }
+
+ Handle<String> GetSuffix() override {
+ const int match_end_position = match_position_ + match_->length();
+ return isolate_->factory()->NewSubString(subject_, match_end_position,
+ subject_->length());
+ }
+
+ int CaptureCount() override { return static_cast<int>(captures_->size()); }
+
+ virtual ~VectorBackedMatch() {}
+
+ private:
+ Isolate* isolate_;
+ Handle<String> subject_;
+ Handle<String> match_;
+ const int match_position_;
+ ZoneVector<Handle<Object>>* captures_;
+};
// Only called from Runtime_RegExpExecMultiple so it doesn't need to maintain
// separate last match info. See comment on that function.
template <bool has_capture>
static Object* SearchRegExpMultiple(Isolate* isolate, Handle<String> subject,
Handle<JSRegExp> regexp,
- Handle<JSObject> last_match_array,
+ Handle<RegExpMatchInfo> last_match_array,
Handle<JSArray> result_array) {
DCHECK(subject->IsFlat());
DCHECK_NE(has_capture, regexp->CaptureCount() == 0);
@@ -858,8 +952,11 @@ static Object* SearchRegExpMultiple(Isolate* isolate, Handle<String> subject,
}
Handle<FixedArray> cached_fixed_array =
Handle<FixedArray>(FixedArray::cast(cached_answer));
- // The cache FixedArray is a COW-array and can therefore be reused.
- JSArray::SetContent(result_array, cached_fixed_array);
+ // The cache FixedArray is a COW-array and we need to return a copy.
+ Handle<FixedArray> copied_fixed_array =
+ isolate->factory()->CopyFixedArrayWithMap(
+ cached_fixed_array, isolate->factory()->fixed_array_map());
+ JSArray::SetContent(result_array, copied_fixed_array);
RegExpImpl::SetLastMatchInfo(last_match_array, subject, capture_count,
last_match);
DeleteArray(last_match);
@@ -964,9 +1061,12 @@ static Object* SearchRegExpMultiple(Isolate* isolate, Handle<String> subject,
}
Handle<FixedArray> result_fixed_array = builder.array();
result_fixed_array->Shrink(builder.length());
- // Cache the result and turn the FixedArray into a COW array.
+ // Cache the result and copy the FixedArray into a COW array.
+ Handle<FixedArray> copied_fixed_array =
+ isolate->factory()->CopyFixedArrayWithMap(
+ result_fixed_array, isolate->factory()->fixed_array_map());
RegExpResultsCache::Enter(
- isolate, subject, handle(regexp->data(), isolate), result_fixed_array,
+ isolate, subject, handle(regexp->data(), isolate), copied_fixed_array,
last_match_cache, RegExpResultsCache::REGEXP_MULTIPLE_INDICES);
}
return *builder.ToJSArray(result_array);
@@ -975,19 +1075,174 @@ static Object* SearchRegExpMultiple(Isolate* isolate, Handle<String> subject,
}
}
+MUST_USE_RESULT MaybeHandle<String> StringReplaceNonGlobalRegExpWithFunction(
+ Isolate* isolate, Handle<String> subject, Handle<JSRegExp> regexp,
+ Handle<Object> replace_obj) {
+ Factory* factory = isolate->factory();
+ Handle<RegExpMatchInfo> last_match_info = isolate->regexp_last_match_info();
+
+ // TODO(jgruber): This is a pattern we could refactor.
+ Handle<Object> match_indices_obj;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, match_indices_obj,
+ RegExpImpl::Exec(regexp, subject, 0, last_match_info), String);
+
+ if (match_indices_obj->IsNull(isolate)) {
+ RETURN_ON_EXCEPTION(isolate, RegExpUtils::SetLastIndex(isolate, regexp, 0),
+ String);
+ return subject;
+ }
+
+ Handle<RegExpMatchInfo> match_indices =
+ Handle<RegExpMatchInfo>::cast(match_indices_obj);
+
+ const int index = match_indices->Capture(0);
+ const int end_of_match = match_indices->Capture(1);
+
+ IncrementalStringBuilder builder(isolate);
+ builder.AppendString(factory->NewSubString(subject, 0, index));
+
+ // Compute the parameter list consisting of the match, captures, index,
+ // and subject for the replace function invocation.
+ // The number of captures plus one for the match.
+ const int m = match_indices->NumberOfCaptureRegisters() / 2;
+
+ const int argc = m + 2;
+ ScopedVector<Handle<Object>> argv(argc);
+
+ for (int j = 0; j < m; j++) {
+ bool ok;
+ Handle<String> capture =
+ RegExpUtils::GenericCaptureGetter(isolate, match_indices, j, &ok);
+ if (ok) {
+ argv[j] = capture;
+ } else {
+ argv[j] = factory->undefined_value();
+ }
+ }
+
+ argv[argc - 2] = handle(Smi::FromInt(index), isolate);
+ argv[argc - 1] = subject;
+
+ Handle<Object> replacement_obj;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, replacement_obj,
+ Execution::Call(isolate, replace_obj, factory->undefined_value(), argc,
+ argv.start()),
+ String);
+
+ Handle<String> replacement;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, replacement, Object::ToString(isolate, replacement_obj), String);
+
+ builder.AppendString(replacement);
+ builder.AppendString(
+ factory->NewSubString(subject, end_of_match, subject->length()));
+
+ return builder.Finish();
+}
+
+// Legacy implementation of RegExp.prototype[Symbol.replace] which
+// doesn't properly call the underlying exec method.
+MUST_USE_RESULT MaybeHandle<String> RegExpReplace(Isolate* isolate,
+ Handle<JSRegExp> regexp,
+ Handle<String> string,
+ Handle<Object> replace_obj) {
+ Factory* factory = isolate->factory();
+
+ // TODO(jgruber): We need the even stricter guarantee of an unmodified
+ // JSRegExp map here for access to GetFlags to be legal.
+ const int flags = regexp->GetFlags();
+ const bool global = (flags & JSRegExp::kGlobal) != 0;
+
+ // Functional fast-paths are dispatched directly by replace builtin.
+ DCHECK(!replace_obj->IsCallable());
+
+ Handle<String> replace;
+ ASSIGN_RETURN_ON_EXCEPTION(isolate, replace,
+ Object::ToString(isolate, replace_obj), String);
+ replace = String::Flatten(replace);
+
+ Handle<RegExpMatchInfo> last_match_info = isolate->regexp_last_match_info();
+
+ if (!global) {
+ // Non-global regexp search, string replace.
+
+ Handle<Object> match_indices_obj;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, match_indices_obj,
+ RegExpImpl::Exec(regexp, string, 0, last_match_info), String);
+
+ if (match_indices_obj->IsNull(isolate)) {
+ RETURN_ON_EXCEPTION(
+ isolate, RegExpUtils::SetLastIndex(isolate, regexp, 0), String);
+ return string;
+ }
+
+ auto match_indices = Handle<RegExpMatchInfo>::cast(match_indices_obj);
-// This is only called for StringReplaceGlobalRegExpWithFunction. This sets
-// lastMatchInfoOverride to maintain the last match info, so we don't need to
-// set any other last match array info.
+ const int start_index = match_indices->Capture(0);
+ const int end_index = match_indices->Capture(1);
+
+ IncrementalStringBuilder builder(isolate);
+ builder.AppendString(factory->NewSubString(string, 0, start_index));
+
+ if (replace->length() > 0) {
+ MatchInfoBackedMatch m(isolate, string, match_indices);
+ Handle<String> replacement;
+ ASSIGN_RETURN_ON_EXCEPTION(isolate, replacement,
+ String::GetSubstitution(isolate, &m, replace),
+ String);
+ builder.AppendString(replacement);
+ }
+
+ builder.AppendString(
+ factory->NewSubString(string, end_index, string->length()));
+ return builder.Finish();
+ } else {
+ // Global regexp search, string replace.
+ DCHECK(global);
+ RETURN_ON_EXCEPTION(isolate, RegExpUtils::SetLastIndex(isolate, regexp, 0),
+ String);
+
+ if (replace->length() == 0) {
+ if (string->HasOnlyOneByteChars()) {
+ Object* result =
+ StringReplaceGlobalRegExpWithEmptyString<SeqOneByteString>(
+ isolate, string, regexp, last_match_info);
+ return handle(String::cast(result), isolate);
+ } else {
+ Object* result =
+ StringReplaceGlobalRegExpWithEmptyString<SeqTwoByteString>(
+ isolate, string, regexp, last_match_info);
+ return handle(String::cast(result), isolate);
+ }
+ }
+
+ Object* result = StringReplaceGlobalRegExpWithString(
+ isolate, string, regexp, replace, last_match_info);
+ if (result->IsString()) {
+ return handle(String::cast(result), isolate);
+ } else {
+ return MaybeHandle<String>();
+ }
+ }
+
+ UNREACHABLE();
+ return MaybeHandle<String>();
+}
+
+} // namespace
+
+// This is only called for StringReplaceGlobalRegExpWithFunction.
RUNTIME_FUNCTION(Runtime_RegExpExecMultiple) {
HandleScope handles(isolate);
DCHECK(args.length() == 4);
CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
- CONVERT_ARG_HANDLE_CHECKED(JSObject, last_match_info, 2);
+ CONVERT_ARG_HANDLE_CHECKED(RegExpMatchInfo, last_match_info, 2);
CONVERT_ARG_HANDLE_CHECKED(JSArray, result_array, 3);
- CHECK(last_match_info->HasFastObjectElements());
CHECK(result_array->HasFastObjectElements());
subject = String::Flatten(subject);
@@ -1002,6 +1257,188 @@ RUNTIME_FUNCTION(Runtime_RegExpExecMultiple) {
}
}
+RUNTIME_FUNCTION(Runtime_StringReplaceNonGlobalRegExpWithFunction) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 3);
+
+ CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, replace, 2);
+
+ RETURN_RESULT_OR_FAILURE(isolate, StringReplaceNonGlobalRegExpWithFunction(
+ isolate, subject, regexp, replace));
+}
+
+// Slow path for:
+// ES#sec-regexp.prototype-@@replace
+// RegExp.prototype [ @@replace ] ( string, replaceValue )
+RUNTIME_FUNCTION(Runtime_RegExpReplace) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 3);
+
+ CONVERT_ARG_HANDLE_CHECKED(JSReceiver, recv, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, string, 1);
+ Handle<Object> replace_obj = args.at<Object>(2);
+
+ Factory* factory = isolate->factory();
+
+ string = String::Flatten(string);
+
+ // Fast-path for unmodified JSRegExps.
+ if (RegExpUtils::IsUnmodifiedRegExp(isolate, recv)) {
+ RETURN_RESULT_OR_FAILURE(
+ isolate, RegExpReplace(isolate, Handle<JSRegExp>::cast(recv), string,
+ replace_obj));
+ }
+
+ const int length = string->length();
+ const bool functional_replace = replace_obj->IsCallable();
+
+ Handle<String> replace;
+ if (!functional_replace) {
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, replace,
+ Object::ToString(isolate, replace_obj));
+ }
+
+ Handle<Object> global_obj;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, global_obj,
+ JSReceiver::GetProperty(recv, factory->global_string()));
+ const bool global = global_obj->BooleanValue();
+
+ bool unicode = false;
+ if (global) {
+ Handle<Object> unicode_obj;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, unicode_obj,
+ JSReceiver::GetProperty(recv, factory->unicode_string()));
+ unicode = unicode_obj->BooleanValue();
+
+ RETURN_FAILURE_ON_EXCEPTION(isolate,
+ RegExpUtils::SetLastIndex(isolate, recv, 0));
+ }
+
+ Zone zone(isolate->allocator(), ZONE_NAME);
+ ZoneVector<Handle<Object>> results(&zone);
+
+ while (true) {
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result, RegExpUtils::RegExpExec(isolate, recv, string,
+ factory->undefined_value()));
+
+ if (result->IsNull(isolate)) break;
+
+ results.push_back(result);
+ if (!global) break;
+
+ Handle<Object> match_obj;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, match_obj,
+ Object::GetElement(isolate, result, 0));
+
+ Handle<String> match;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, match,
+ Object::ToString(isolate, match_obj));
+
+ if (match->length() == 0) {
+ RETURN_FAILURE_ON_EXCEPTION(isolate, RegExpUtils::SetAdvancedStringIndex(
+ isolate, recv, string, unicode));
+ }
+ }
+
+ // TODO(jgruber): Look into ReplacementStringBuilder instead.
+ IncrementalStringBuilder builder(isolate);
+ int next_source_position = 0;
+
+ for (const auto& result : results) {
+ Handle<Object> captures_length_obj;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, captures_length_obj,
+ Object::GetProperty(result, factory->length_string()));
+
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, captures_length_obj,
+ Object::ToLength(isolate, captures_length_obj));
+ const int captures_length =
+ std::max(Handle<Smi>::cast(captures_length_obj)->value(), 0);
+
+ Handle<Object> match_obj;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, match_obj,
+ Object::GetElement(isolate, result, 0));
+
+ Handle<String> match;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, match,
+ Object::ToString(isolate, match_obj));
+
+ const int match_length = match->length();
+
+ Handle<Object> position_obj;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, position_obj,
+ Object::GetProperty(result, factory->index_string()));
+
+ // TODO(jgruber): Extract and correct error handling. Since we can go up to
+ // 2^53 - 1 (at least for ToLength), we might actually need uint64_t here?
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, position_obj, Object::ToInteger(isolate, position_obj));
+ const int position =
+ std::max(std::min(Handle<Smi>::cast(position_obj)->value(), length), 0);
+
+ ZoneVector<Handle<Object>> captures(&zone);
+ for (int n = 0; n < captures_length; n++) {
+ Handle<Object> capture;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, capture, Object::GetElement(isolate, result, n));
+
+ if (!capture->IsUndefined(isolate)) {
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, capture,
+ Object::ToString(isolate, capture));
+ }
+ captures.push_back(capture);
+ }
+
+ Handle<String> replacement;
+ if (functional_replace) {
+ const int argc = captures_length + 2;
+ ScopedVector<Handle<Object>> argv(argc);
+
+ for (int j = 0; j < captures_length; j++) {
+ argv[j] = captures[j];
+ }
+
+ argv[captures_length] = handle(Smi::FromInt(position), isolate);
+ argv[captures_length + 1] = string;
+
+ Handle<Object> replacement_obj;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, replacement_obj,
+ Execution::Call(isolate, replace_obj, factory->undefined_value(),
+ argc, argv.start()));
+
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, replacement, Object::ToString(isolate, replacement_obj));
+ } else {
+ VectorBackedMatch m(isolate, string, match, position, &captures);
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, replacement, String::GetSubstitution(isolate, &m, replace));
+ }
+
+ if (position >= next_source_position) {
+ builder.AppendString(
+ factory->NewSubString(string, next_source_position, position));
+ builder.AppendString(replacement);
+
+ next_source_position = position + match_length;
+ }
+ }
+
+ if (next_source_position < length) {
+ builder.AppendString(
+ factory->NewSubString(string, next_source_position, length));
+ }
+
+ RETURN_RESULT_OR_FAILURE(isolate, builder.Finish());
+}
RUNTIME_FUNCTION(Runtime_RegExpExecReThrow) {
SealHandleScope shs(isolate);
@@ -1018,5 +1455,6 @@ RUNTIME_FUNCTION(Runtime_IsRegExp) {
CONVERT_ARG_CHECKED(Object, obj, 0);
return isolate->heap()->ToBoolean(obj->IsJSRegExp());
}
+
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/runtime/runtime-scopes.cc b/deps/v8/src/runtime/runtime-scopes.cc
index 0c037db307..377799fe04 100644
--- a/deps/v8/src/runtime/runtime-scopes.cc
+++ b/deps/v8/src/runtime/runtime-scopes.cc
@@ -903,7 +903,7 @@ MaybeHandle<Object> StoreLookupSlot(Handle<String> name, Handle<Object> value,
// The property was found in a context slot.
if (index != Context::kNotFound) {
if (flag == kNeedsInitialization &&
- Handle<Context>::cast(holder)->is_the_hole(index)) {
+ Handle<Context>::cast(holder)->is_the_hole(isolate, index)) {
THROW_NEW_ERROR(isolate,
NewReferenceError(MessageTemplate::kNotDefined, name),
Object);
diff --git a/deps/v8/src/runtime/runtime-strings.cc b/deps/v8/src/runtime/runtime-strings.cc
index f5bda59b26..328bdceb37 100644
--- a/deps/v8/src/runtime/runtime-strings.cc
+++ b/deps/v8/src/runtime/runtime-strings.cc
@@ -90,17 +90,8 @@ RUNTIME_FUNCTION(Runtime_StringReplaceOneCharWithString) {
RUNTIME_FUNCTION(Runtime_StringIndexOf) {
HandleScope scope(isolate);
DCHECK(args.length() == 3);
-
- CONVERT_ARG_HANDLE_CHECKED(String, sub, 0);
- CONVERT_ARG_HANDLE_CHECKED(String, pat, 1);
- CONVERT_ARG_HANDLE_CHECKED(Object, index, 2);
-
- uint32_t start_index = 0;
- if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1);
-
- CHECK(start_index <= static_cast<uint32_t>(sub->length()));
- int position = String::IndexOf(isolate, sub, pat, start_index);
- return Smi::FromInt(position);
+ return String::IndexOf(isolate, args.at<Object>(0), args.at<Object>(1),
+ args.at<Object>(2));
}
RUNTIME_FUNCTION(Runtime_StringLastIndexOf) {
@@ -166,59 +157,6 @@ RUNTIME_FUNCTION(Runtime_InternalizeString) {
}
-RUNTIME_FUNCTION(Runtime_StringMatch) {
- HandleScope handles(isolate);
- DCHECK(args.length() == 3);
-
- CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
- CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
- CONVERT_ARG_HANDLE_CHECKED(JSArray, regexp_info, 2);
-
- CHECK(regexp_info->HasFastObjectElements());
-
- RegExpImpl::GlobalCache global_cache(regexp, subject, isolate);
- if (global_cache.HasException()) return isolate->heap()->exception();
-
- int capture_count = regexp->CaptureCount();
-
- ZoneScope zone_scope(isolate->runtime_zone());
- ZoneList<int> offsets(8, zone_scope.zone());
-
- while (true) {
- int32_t* match = global_cache.FetchNext();
- if (match == NULL) break;
- offsets.Add(match[0], zone_scope.zone()); // start
- offsets.Add(match[1], zone_scope.zone()); // end
- }
-
- if (global_cache.HasException()) return isolate->heap()->exception();
-
- if (offsets.length() == 0) {
- // Not a single match.
- return isolate->heap()->null_value();
- }
-
- RegExpImpl::SetLastMatchInfo(regexp_info, subject, capture_count,
- global_cache.LastSuccessfulMatch());
-
- int matches = offsets.length() / 2;
- Handle<FixedArray> elements = isolate->factory()->NewFixedArray(matches);
- Handle<String> substring =
- isolate->factory()->NewSubString(subject, offsets.at(0), offsets.at(1));
- elements->set(0, *substring);
- FOR_WITH_HANDLE_SCOPE(isolate, int, i = 1, i, i < matches, i++, {
- int from = offsets.at(i * 2);
- int to = offsets.at(i * 2 + 1);
- Handle<String> substring =
- isolate->factory()->NewProperSubString(subject, from, to);
- elements->set(i, *substring);
- });
- Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(elements);
- result->set_length(Smi::FromInt(matches));
- return *result;
-}
-
-
RUNTIME_FUNCTION(Runtime_StringCharCodeAtRT) {
HandleScope handle_scope(isolate);
DCHECK(args.length() == 2);
@@ -256,7 +194,7 @@ RUNTIME_FUNCTION(Runtime_StringCompare) {
break;
}
UNREACHABLE();
- return Smi::FromInt(0);
+ return Smi::kZero;
}
@@ -573,13 +511,13 @@ static int CopyCachedOneByteCharsToArray(Heap* heap, const uint8_t* chars,
elements->set(i, value, mode);
}
if (i < length) {
- DCHECK(Smi::FromInt(0) == 0);
+ DCHECK(Smi::kZero == 0);
memset(elements->data_start() + i, 0, kPointerSize * (length - i));
}
#ifdef DEBUG
for (int j = 0; j < length; ++j) {
Object* element = elements->get(j);
- DCHECK(element == Smi::FromInt(0) ||
+ DCHECK(element == Smi::kZero ||
(element->IsString() && String::cast(element)->LooksValid()));
}
#endif
@@ -942,7 +880,7 @@ RUNTIME_FUNCTION(Runtime_StringLessThan) {
break;
}
UNREACHABLE();
- return Smi::FromInt(0);
+ return Smi::kZero;
}
RUNTIME_FUNCTION(Runtime_StringLessThanOrEqual) {
@@ -960,7 +898,7 @@ RUNTIME_FUNCTION(Runtime_StringLessThanOrEqual) {
break;
}
UNREACHABLE();
- return Smi::FromInt(0);
+ return Smi::kZero;
}
RUNTIME_FUNCTION(Runtime_StringGreaterThan) {
@@ -978,7 +916,7 @@ RUNTIME_FUNCTION(Runtime_StringGreaterThan) {
break;
}
UNREACHABLE();
- return Smi::FromInt(0);
+ return Smi::kZero;
}
RUNTIME_FUNCTION(Runtime_StringGreaterThanOrEqual) {
@@ -996,7 +934,7 @@ RUNTIME_FUNCTION(Runtime_StringGreaterThanOrEqual) {
break;
}
UNREACHABLE();
- return Smi::FromInt(0);
+ return Smi::kZero;
}
RUNTIME_FUNCTION(Runtime_StringEqual) {
diff --git a/deps/v8/src/runtime/runtime-test.cc b/deps/v8/src/runtime/runtime-test.cc
index 8100d2c759..7054192a0f 100644
--- a/deps/v8/src/runtime/runtime-test.cc
+++ b/deps/v8/src/runtime/runtime-test.cc
@@ -17,6 +17,7 @@
#include "src/snapshot/code-serializer.h"
#include "src/snapshot/natives.h"
#include "src/wasm/wasm-module.h"
+#include "src/wasm/wasm-objects.h"
namespace v8 {
namespace internal {
@@ -267,6 +268,9 @@ RUNTIME_FUNCTION(Runtime_GetOptimizationStatus) {
if (function->IsOptimized() && function->code()->is_turbofanned()) {
return Smi::FromInt(7); // 7 == "TurboFan compiler".
}
+ if (function->IsInterpreted()) {
+ return Smi::FromInt(8); // 8 == "Interpreted".
+ }
return function->IsOptimized() ? Smi::FromInt(1) // 1 == "yes".
: Smi::FromInt(2); // 2 == "no".
}
@@ -444,7 +448,7 @@ RUNTIME_FUNCTION(Runtime_DebugPrint) {
OFStream os(stdout);
#ifdef DEBUG
- if (args[0]->IsString()) {
+ if (args[0]->IsString() && isolate->context() != nullptr) {
// If we have a string, assume it's a code "marker"
// and print some interesting cpu debugging info.
JavaScriptFrameIterator it(isolate);
@@ -546,8 +550,7 @@ RUNTIME_FUNCTION(Runtime_NativeScriptsCount) {
return Smi::FromInt(Natives::GetBuiltinsCount());
}
-
-// Returns V8 version as a string.
+// TODO(5510): remove this.
RUNTIME_FUNCTION(Runtime_GetV8Version) {
HandleScope scope(isolate);
DCHECK(args.length() == 0);
@@ -755,21 +758,37 @@ RUNTIME_FUNCTION(Runtime_SerializeWasmModule) {
// Return undefined if unsuccessful.
RUNTIME_FUNCTION(Runtime_DeserializeWasmModule) {
HandleScope shs(isolate);
- DCHECK(args.length() == 1);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, wire_bytes, 1);
Address mem_start = static_cast<Address>(buffer->backing_store());
int mem_size = static_cast<int>(buffer->byte_length()->Number());
+ // DeserializeWasmModule will allocate. We assume JSArrayBuffer doesn't
+ // get relocated.
ScriptData sc(mem_start, mem_size);
+ bool already_external = wire_bytes->is_external();
+ if (!already_external) {
+ wire_bytes->set_is_external(true);
+ isolate->heap()->UnregisterArrayBuffer(*wire_bytes);
+ }
MaybeHandle<FixedArray> maybe_compiled_module =
- WasmCompiledModuleSerializer::DeserializeWasmModule(isolate, &sc);
+ WasmCompiledModuleSerializer::DeserializeWasmModule(
+ isolate, &sc,
+ Vector<const uint8_t>(
+ reinterpret_cast<uint8_t*>(wire_bytes->backing_store()),
+ static_cast<int>(wire_bytes->byte_length()->Number())));
+ if (!already_external) {
+ wire_bytes->set_is_external(false);
+ isolate->heap()->RegisterNewArrayBuffer(*wire_bytes);
+ }
Handle<FixedArray> compiled_module;
if (!maybe_compiled_module.ToHandle(&compiled_module)) {
return isolate->heap()->undefined_value();
}
- return *wasm::CreateCompiledModuleObject(isolate, compiled_module,
- wasm::ModuleOrigin::kWasmOrigin);
+ return *WasmModuleObject::New(
+ isolate, Handle<WasmCompiledModule>::cast(compiled_module));
}
RUNTIME_FUNCTION(Runtime_ValidateWasmInstancesChain) {
diff --git a/deps/v8/src/runtime/runtime-typedarray.cc b/deps/v8/src/runtime/runtime-typedarray.cc
index ba422bf01e..cb0e062d14 100644
--- a/deps/v8/src/runtime/runtime-typedarray.cc
+++ b/deps/v8/src/runtime/runtime-typedarray.cc
@@ -59,7 +59,7 @@ RUNTIME_FUNCTION(Runtime_ArrayBufferNeuter) {
DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, array_buffer, 0);
if (array_buffer->backing_store() == NULL) {
- CHECK(Smi::FromInt(0) == array_buffer->byte_length());
+ CHECK(Smi::kZero == array_buffer->byte_length());
return isolate->heap()->undefined_value();
}
// Shared array buffers should never be neutered.
@@ -142,7 +142,7 @@ RUNTIME_FUNCTION(Runtime_TypedArrayInitialize) {
DCHECK_EQ(v8::ArrayBufferView::kInternalFieldCount,
holder->GetInternalFieldCount());
for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
- holder->SetInternalField(i, Smi::FromInt(0));
+ holder->SetInternalField(i, Smi::kZero);
}
Handle<Object> length_obj = isolate->factory()->NewNumberFromSize(length);
holder->set_length(*length_obj);
@@ -215,7 +215,7 @@ RUNTIME_FUNCTION(Runtime_TypedArrayInitializeFromArrayLike) {
DCHECK_EQ(v8::ArrayBufferView::kInternalFieldCount,
holder->GetInternalFieldCount());
for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
- holder->SetInternalField(i, Smi::FromInt(0));
+ holder->SetInternalField(i, Smi::kZero);
}
// NOTE: not initializing backing store.
@@ -241,7 +241,7 @@ RUNTIME_FUNCTION(Runtime_TypedArrayInitializeFromArrayLike) {
}
holder->set_buffer(*buffer);
- holder->set_byte_offset(Smi::FromInt(0));
+ holder->set_byte_offset(Smi::kZero);
Handle<Object> byte_length_obj(
isolate->factory()->NewNumberFromSize(byte_length));
holder->set_byte_length(*byte_length_obj);
diff --git a/deps/v8/src/runtime/runtime.h b/deps/v8/src/runtime/runtime.h
index cbdaf0f033..8e2e83c37e 100644
--- a/deps/v8/src/runtime/runtime.h
+++ b/deps/v8/src/runtime/runtime.h
@@ -9,6 +9,7 @@
#include "src/allocation.h"
#include "src/base/platform/time.h"
+#include "src/globals.h"
#include "src/objects.h"
#include "src/unicode.h"
#include "src/zone/zone.h"
@@ -51,13 +52,12 @@ namespace internal {
F(HasComplexElements, 1, 1) \
F(IsArray, 1, 1) \
F(ArrayIsArray, 1, 1) \
- F(HasCachedArrayIndex, 1, 1) \
- F(GetCachedArrayIndex, 1, 1) \
F(FixedArrayGet, 2, 1) \
F(FixedArraySet, 3, 1) \
F(ArraySpeciesConstructor, 1, 1) \
F(ArrayIncludes_Slow, 3, 1) \
- F(ArrayIndexOf, 3, 1)
+ F(ArrayIndexOf, 3, 1) \
+ F(SpreadIterablePrepare, 1, 1)
#define FOR_EACH_INTRINSIC_ATOMICS(F) \
F(ThrowNotIntegerSharedTypedArrayError, 1, 1) \
@@ -188,6 +188,7 @@ namespace internal {
F(ScriptLineStartPosition, 2, 1) \
F(ScriptLineEndPosition, 2, 1) \
F(ScriptLocationFromLine, 4, 1) \
+ F(ScriptLocationFromLine2, 4, 1) \
F(ScriptPositionInfo, 3, 1) \
F(ScriptSourceLine, 2, 1) \
F(DebugPrepareStepInIfStepping, 1, 1) \
@@ -195,11 +196,10 @@ namespace internal {
F(DebugRecordAsyncFunction, 1, 1) \
F(DebugPushPromise, 1, 1) \
F(DebugPopPromise, 0, 1) \
- F(DebugAsyncTaskEvent, 1, 1) \
+ F(DebugNextMicrotaskId, 0, 1) \
+ F(DebugAsyncTaskEvent, 3, 1) \
F(DebugIsActive, 0, 1) \
- F(DebugBreakInOptimizedCode, 0, 1) \
- F(GetWasmFunctionOffsetTable, 1, 1) \
- F(DisassembleWasmFunction, 1, 1)
+ F(DebugBreakInOptimizedCode, 0, 1)
#define FOR_EACH_INTRINSIC_ERROR(F) F(ErrorToString, 1, 1)
@@ -214,13 +214,15 @@ namespace internal {
F(InterpreterTraceBytecodeEntry, 3, 1) \
F(InterpreterTraceBytecodeExit, 3, 1) \
F(InterpreterClearPendingMessage, 0, 1) \
- F(InterpreterSetPendingMessage, 1, 1)
+ F(InterpreterSetPendingMessage, 1, 1) \
+ F(InterpreterAdvanceBytecodeOffset, 2, 1)
#define FOR_EACH_INTRINSIC_FUNCTION(F) \
F(FunctionGetName, 1, 1) \
F(FunctionSetName, 2, 1) \
F(FunctionRemovePrototype, 1, 1) \
F(FunctionGetScript, 1, 1) \
+ F(FunctionGetScriptId, 1, 1) \
F(FunctionGetSourceCode, 1, 1) \
F(FunctionGetScriptSourcePosition, 1, 1) \
F(FunctionGetContextData, 1, 1) \
@@ -290,7 +292,8 @@ namespace internal {
F(CheckIsBootstrapping, 0, 1) \
F(CreateListFromArrayLike, 1, 1) \
F(EnqueueMicrotask, 1, 1) \
- F(EnqueuePromiseResolveThenableJob, 6, 1) \
+ F(EnqueuePromiseReactionJob, 4, 1) \
+ F(EnqueuePromiseResolveThenableJob, 3, 1) \
F(GetAndResetRuntimeCallStats, -1 /* <= 2 */, 1) \
F(ExportExperimentalFromRuntime, 1, 1) \
F(ExportFromRuntime, 1, 1) \
@@ -298,12 +301,13 @@ namespace internal {
F(InstallToContext, 1, 1) \
F(Interrupt, 0, 1) \
F(IS_VAR, 1, 1) \
- F(IsWasmObject, 1, 1) \
+ F(IsWasmInstance, 1, 1) \
F(NewReferenceError, 2, 1) \
F(NewSyntaxError, 2, 1) \
F(NewTypeError, 2, 1) \
F(OrdinaryHasInstance, 2, 1) \
- F(PromiseRejectEvent, 3, 1) \
+ F(PromiseReject, 3, 1) \
+ F(PromiseFulfill, 4, 1) \
F(PromiseRejectEventFromStack, 2, 1) \
F(PromiseRevokeReject, 1, 1) \
F(PromoteScheduledException, 0, 1) \
@@ -325,6 +329,7 @@ namespace internal {
F(ThrowNotGeneric, 1, 1) \
F(ThrowReferenceError, 1, 1) \
F(ThrowStackOverflow, 0, 1) \
+ F(ThrowTypeError, -1 /* >= 1 */, 1) \
F(ThrowWasmError, 2, 1) \
F(ThrowUndefinedOrNullToObject, 1, 1) \
F(Typeof, 1, 1) \
@@ -350,7 +355,12 @@ namespace internal {
F(LiveEditCompareStrings, 2, 1) \
F(LiveEditRestartFrame, 2, 1)
-#define FOR_EACH_INTRINSIC_MATHS(F) F(GenerateRandomNumbers, 1, 1)
+#define FOR_EACH_INTRINSIC_MATHS(F) F(GenerateRandomNumbers, 0, 1)
+
+#define FOR_EACH_INTRINSIC_MODULE(F) \
+ F(GetModuleNamespace, 1, 1) \
+ F(LoadModuleVariable, 1, 1) \
+ F(StoreModuleVariable, 2, 1)
#define FOR_EACH_INTRINSIC_NUMBERS(F) \
F(IsValidSmi, 1, 1) \
@@ -370,13 +380,11 @@ namespace internal {
#define FOR_EACH_INTRINSIC_OBJECT(F) \
F(GetPrototype, 1, 1) \
F(ObjectHasOwnProperty, 2, 1) \
+ F(ObjectCreate, 2, 1) \
F(InternalSetPrototype, 2, 1) \
- F(SetPrototype, 2, 1) \
F(OptimizeObjectForAddingMultipleProperties, 2, 1) \
F(GetProperty, 2, 1) \
F(KeyedGetProperty, 2, 1) \
- F(StoreGlobalViaContext_Sloppy, 2, 1) \
- F(StoreGlobalViaContext_Strict, 2, 1) \
F(AddNamedProperty, 4, 1) \
F(SetProperty, 4, 1) \
F(AddElement, 3, 1) \
@@ -417,11 +425,9 @@ namespace internal {
F(Compare, 3, 1) \
F(HasInPrototypeChain, 2, 1) \
F(CreateIterResultObject, 2, 1) \
+ F(CreateKeyValueArray, 2, 1) \
F(IsAccessCheckNeeded, 1, 1) \
- F(CreateDataProperty, 3, 1) \
- F(LoadModuleExport, 1, 1) \
- F(LoadModuleImport, 2, 1) \
- F(StoreModuleExport, 2, 1)
+ F(CreateDataProperty, 3, 1)
#define FOR_EACH_INTRINSIC_OPERATORS(F) \
F(Multiply, 2, 1) \
@@ -453,17 +459,17 @@ namespace internal {
F(JSProxyGetHandler, 1, 1) \
F(JSProxyRevoke, 1, 1)
-#define FOR_EACH_INTRINSIC_REGEXP(F) \
- F(StringReplaceGlobalRegExpWithString, 4, 1) \
- F(StringSplit, 3, 1) \
- F(RegExpExec, 4, 1) \
- F(RegExpFlags, 1, 1) \
- F(RegExpSource, 1, 1) \
- F(RegExpConstructResult, 3, 1) \
- F(RegExpInitializeAndCompile, 3, 1) \
- F(RegExpExecMultiple, 4, 1) \
- F(RegExpExecReThrow, 4, 1) \
- F(IsRegExp, 1, 1)
+#define FOR_EACH_INTRINSIC_REGEXP(F) \
+ F(IsRegExp, 1, 1) \
+ F(RegExpCreate, 1, 1) \
+ F(RegExpExec, 4, 1) \
+ F(RegExpExecMultiple, 4, 1) \
+ F(RegExpExecReThrow, 4, 1) \
+ F(RegExpInternalReplace, 3, 1) \
+ F(RegExpReplace, 3, 1) \
+ F(StringReplaceGlobalRegExpWithString, 4, 1) \
+ F(StringReplaceNonGlobalRegExpWithFunction, 3, 1) \
+ F(StringSplit, 3, 1)
#define FOR_EACH_INTRINSIC_SCOPES(F) \
F(ThrowConstAssignError, 0, 1) \
@@ -807,7 +813,6 @@ namespace internal {
F(SubString, 3, 1) \
F(StringAdd, 2, 1) \
F(InternalizeString, 1, 1) \
- F(StringMatch, 3, 1) \
F(StringCharCodeAtRT, 2, 1) \
F(StringCompare, 2, 1) \
F(StringBuilderConcat, 3, 1) \
@@ -891,7 +896,7 @@ namespace internal {
F(HasFixedUint8ClampedElements, 1, 1) \
F(SpeciesProtector, 0, 1) \
F(SerializeWasmModule, 1, 1) \
- F(DeserializeWasmModule, 1, 1) \
+ F(DeserializeWasmModule, 2, 1) \
F(IsAsmWasmCode, 1, 1) \
F(IsNotAsmWasmCode, 1, 1) \
F(ValidateWasmInstancesChain, 2, 1) \
@@ -971,6 +976,7 @@ namespace internal {
FOR_EACH_INTRINSIC_LITERALS(F) \
FOR_EACH_INTRINSIC_LIVEEDIT(F) \
FOR_EACH_INTRINSIC_MATHS(F) \
+ FOR_EACH_INTRINSIC_MODULE(F) \
FOR_EACH_INTRINSIC_NUMBERS(F) \
FOR_EACH_INTRINSIC_OBJECT(F) \
FOR_EACH_INTRINSIC_OPERATORS(F) \
@@ -1039,7 +1045,7 @@ class Runtime : public AllStatic {
static const Function* FunctionForName(const unsigned char* name, int length);
// Get the intrinsic function with the given FunctionId.
- static const Function* FunctionForId(FunctionId id);
+ V8_EXPORT_PRIVATE static const Function* FunctionForId(FunctionId id);
// Get the intrinsic function with the given function entry address.
static const Function* FunctionForEntry(Address ref);
@@ -1114,8 +1120,7 @@ class RuntimeState {
DISALLOW_COPY_AND_ASSIGN(RuntimeState);
};
-
-std::ostream& operator<<(std::ostream&, Runtime::FunctionId);
+V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, Runtime::FunctionId);
//---------------------------------------------------------------------------
// Constants used by interface to runtime functions.